4 * The OS/X side of the video support (responsible for actually displaying /
7 * Copyright (c) 2008 Nathan Keynes.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
24 #include "dckeysyms.h"
25 #include "cocoaui/cocoaui.h"
26 #include "drivers/video_nsgl.h"
27 #include "drivers/video_gl.h"
28 #include "pvr2/pvr2.h"
29 #import <AppKit/AppKit.h>
31 #include "mac_keymap.h"
33 #define MOUSE_X_SCALE 5
34 #define MOUSE_Y_SCALE 5
36 static gboolean video_osx_init();
37 static void video_osx_shutdown();
38 static void video_osx_display_blank( uint32_t colour );
39 static uint16_t video_osx_resolve_keysym( const gchar *keysym );
40 static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode);
41 static gchar *video_osx_keycode_to_keysym(uint16_t keycode);
43 struct display_driver display_osx_driver = {
45 N_("OS X Cocoa GUI-based OpenGL driver"),
46 video_osx_init, video_osx_shutdown,
47 video_osx_resolve_keysym,
48 video_osx_keycode_to_dckeysym,
49 video_osx_keycode_to_keysym,
50 NULL, NULL, NULL, NULL, NULL,
51 video_osx_display_blank, NULL };
54 static NSView *video_view = NULL;
55 int video_width = 640;
56 int video_height = 480;
58 #define MAX_MASK_KEYCODE 128
60 @interface LxdreamOSXView : LxdreamVideoView
63 int flagsMask[MAX_MASK_KEYCODE];
67 @implementation LxdreamVideoView
68 - (void)setIsGrabbed: (BOOL)grabbed
72 - (void) setDelegate: (id)other
82 @implementation LxdreamOSXView
83 //--------------------------------------------------------------------
84 - (id)initWithFrame: (NSRect)contentRect
86 if( [super initWithFrame: contentRect] != nil ) {
90 for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
99 if( delegate && [delegate respondsToSelector: @selector(viewRequestedGrab:)] )
100 [delegate performSelector: @selector(viewRequestedGrab:) withObject: self];
102 - (void)requestUngrab
104 if( delegate && [delegate respondsToSelector: @selector(viewRequestedUngrab:)] )
105 [delegate performSelector: @selector(viewRequestedUngrab:) withObject: self];
111 - (BOOL)acceptsFirstResponder
119 //--------------------------------------------------------------------
120 - (void)drawRect: (NSRect) rect
122 NSSize size = [self frame].size;
123 if( video_width != size.width || video_height != size.height ) {
124 video_width = size.width;
125 video_height = size.height;
128 pvr2_redraw_display();
130 - (void)keyDown: (NSEvent *) event
132 if( ![event isARepeat] ) {
133 input_event_keydown( NULL, [event keyCode]+1, 1 );
136 - (void)keyUp: (NSEvent *) event
138 input_event_keyup( NULL, [event keyCode]+1, 1 );
140 - (void)flagsChanged: (NSEvent *) event
142 int keycode = [event keyCode];
143 if( ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
144 [self requestUngrab];
147 if( flagsMask[keycode] == 0 ) {
148 input_event_keydown( NULL, keycode+1, 1 );
149 flagsMask[keycode] = 1;
151 input_event_keyup( NULL, keycode+1, 1 );
152 flagsMask[keycode] = 0;
155 - (void)mouseDown: (NSEvent *) event
159 input_event_mouse( buttonMask, 0, 0 );
164 - (void)mouseUp: (NSEvent *)event
167 input_event_mouse( buttonMask, 0, 0 );
170 - (void)rightMouseDown: (NSEvent *) event
173 input_event_mouse( buttonMask, 0, 0 );
175 - (void)rightMouseUp: (NSEvent *)event
178 input_event_mouse( buttonMask, 0, 0 );
180 - (void)otherMouseDown: (NSEvent *) event
182 buttonMask |= (1<< [event buttonNumber] );
183 input_event_mouse( buttonMask, 0, 0 );
185 - (void)otherMouseUp: (NSEvent *) event
187 buttonMask &= ~(1<< [event buttonNumber] );
188 input_event_mouse( buttonMask, 0, 0 );
190 - (void)mouseMoved: (NSEvent *) event
193 input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE );
196 - (void)mouseDragged: (NSEvent *) event
199 input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE );
202 - (void)rightMouseDragged: (NSEvent *) event
205 input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE );
208 - (void)otherMouseDragged: (NSEvent *) event
211 input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE );
217 NSView *video_osx_create_drawable()
219 NSRect contentRect = {{0,0},{640,480}};
220 video_view = [[LxdreamOSXView alloc] initWithFrame: contentRect];
221 [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
225 static gboolean video_osx_init()
227 if( video_view == NULL ) {
230 if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
233 pvr2_setup_gl_context();
237 static void video_osx_shutdown()
241 static void video_osx_display_blank( uint32_t colour )
245 static int mac_keymap_cmp(const void *a, const void *b)
247 const gchar *key = a;
248 const struct mac_keymap_struct *kb = b;
249 return strcasecmp(key, kb->name);
252 static uint16_t video_osx_resolve_keysym( const gchar *keysym )
254 struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
255 if( result == NULL ) {
258 return result->keycode + 1;
262 static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
264 if( keycode < 1 || keycode > 128 ) {
267 return mac_keycode_to_dckeysym[keycode-1];
271 static gchar *video_osx_keycode_to_keysym(uint16_t keycode)
273 if( keycode < 1 || keycode > 128 ) {
276 return g_strdup(mac_keysyms_by_keycode[keycode-1]);
.