filename | src/drivers/video_osx.m |
changeset | 1086:29776415438d |
prev | 1076:18c164e8aec4 |
next | 1236:d93175c36387 |
author | nkeynes |
date | Sun Feb 12 16:30:26 2012 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Add -Werror for mregparm check, so it actually fails if mregparm isn't accepted |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * The OS/X side of the video support (responsible for actually displaying /
5 * rendering frames)
6 *
7 * Copyright (c) 2008 Nathan Keynes.
8 *
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.
13 *
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.
18 */
20 #include <stdlib.h>
21 #include <string.h>
22 #include "lxdream.h"
23 #include "display.h"
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 "drivers/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 = {
44 "osx",
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 NULL,
52 video_osx_display_blank, NULL };
55 static NSView *video_view = NULL;
56 int video_width = 640;
57 int video_height = 480;
59 #define MAX_MASK_KEYCODE 128
61 @interface LxdreamOSXView : LxdreamVideoView
62 {
63 int flagsMask[MAX_MASK_KEYCODE];
64 }
65 @end
67 @implementation LxdreamVideoView
68 - (void)setIsGrabbed: (BOOL)grabbed
69 {
70 isGrabbed = grabbed;
71 }
72 - (void) setDelegate: (id)other
73 {
74 delegate = other;
75 }
76 - (id)delegate
77 {
78 return delegate;
79 }
80 @end
82 @implementation LxdreamOSXView
83 //--------------------------------------------------------------------
84 - (id)initWithFrame: (NSRect)contentRect
85 {
86 if( [super initWithFrame: contentRect] != nil ) {
87 int i;
88 isGrabbed = NO;
89 for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
90 flagsMask[i] = 0;
91 }
92 return self;
93 }
94 return nil;
95 }
96 - (BOOL)requestGrab
97 {
98 if( delegate && [delegate respondsToSelector: @selector(viewRequestedGrab:)] )
99 return [delegate performSelector: @selector(viewRequestedGrab:) withObject: self] != nil;
100 return NO;
101 }
102 - (BOOL)requestUngrab
103 {
104 if( delegate && [delegate respondsToSelector: @selector(viewRequestedUngrab:)] )
105 return [delegate performSelector: @selector(viewRequestedUngrab:) withObject: self] != nil;
106 return NO;
107 }
108 - (BOOL)isOpaque
109 {
110 return YES;
111 }
112 - (BOOL)acceptsFirstResponder
113 {
114 return YES;
115 }
116 - (BOOL)isFlipped
117 {
118 return YES;
119 }
120 //--------------------------------------------------------------------
121 - (void)drawRect: (NSRect) rect
122 {
123 NSSize size = [self frame].size;
124 if( video_width != size.width || video_height != size.height ) {
125 video_width = size.width;
126 video_height = size.height;
127 video_nsgl_update();
128 }
129 pvr2_draw_frame();
130 }
131 - (void)keyDown: (NSEvent *) event
132 {
133 if( ![event isARepeat] ) {
134 input_event_keydown( NULL, [event keyCode]+1, MAX_PRESSURE );
135 }
136 }
137 - (void)keyUp: (NSEvent *) event
138 {
139 input_event_keyup( NULL, [event keyCode]+1 );
140 }
141 - (void)flagsChanged: (NSEvent *) event
142 {
143 int keycode = [event keyCode];
144 if( ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
145 [self requestUngrab];
146 }
148 if( flagsMask[keycode] == 0 ) {
149 input_event_keydown( NULL, keycode+1, MAX_PRESSURE );
150 flagsMask[keycode] = 1;
151 } else {
152 input_event_keyup( NULL, keycode+1 );
153 flagsMask[keycode] = 0;
154 }
155 }
156 - (void)emitMouseDownEvent: (NSEvent *)event button: (int)button
157 {
158 if( isGrabbed ) {
159 input_event_mousedown( button, 0, 0, FALSE );
160 } else {
161 NSPoint pt = [event locationInWindow];
162 int x = (int)pt.x;
163 int y = video_height - (int)pt.y;
164 gl_window_to_system_coords(&x,&y);
165 input_event_mousedown( button, x, y, TRUE );
166 }
167 }
168 - (void)emitMouseUpEvent: (NSEvent *)event button: (int)button
169 {
170 if( isGrabbed ) {
171 input_event_mouseup( button, 0, 0, FALSE );
172 } else {
173 NSPoint pt = [event locationInWindow];
174 int x = (int)pt.x;
175 int y = video_height - (int)pt.y;
176 gl_window_to_system_coords(&x,&y);
177 input_event_mouseup( button, x, y, TRUE );
178 }
179 }
180 - (void)emitMouseMoveEvent: (NSEvent *)event
181 {
182 if( isGrabbed ) {
183 input_event_mousemove( [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
184 } else {
185 NSPoint pt = [event locationInWindow];
186 int x = (int)pt.x;
187 int y = video_height - (int)pt.y;
188 gl_window_to_system_coords(&x,&y);
189 input_event_mousemove( x, y, TRUE );
190 }
191 }
192 - (void)mouseExited: (NSEvent *)event
193 {
194 if( !isGrabbed ) {
195 input_event_mousemove( -1, -1, TRUE );
196 }
197 }
199 - (void)mouseDown: (NSEvent *) event
200 {
201 // If using grab but not grabbed yet, the first click should be consumed
202 // by the grabber. In all other circumstances we process normally.
203 if( isGrabbed || ![self requestGrab] ) {
204 [self emitMouseDownEvent: event button: 0];
205 }
206 }
207 - (void)mouseUp: (NSEvent *)event
208 {
209 [self emitMouseUpEvent: event button: 0];
210 }
212 - (void)rightMouseDown: (NSEvent *) event
213 {
214 [self emitMouseDownEvent: event button: 1];
215 }
216 - (void)rightMouseUp: (NSEvent *)event
217 {
218 [self emitMouseUpEvent: event button: 1];
219 }
220 - (void)otherMouseDown: (NSEvent *) event
221 {
222 [self emitMouseDownEvent: event button: [event buttonNumber]];
223 }
224 - (void)otherMouseUp: (NSEvent *) event
225 {
226 [self emitMouseUpEvent: event button: [event buttonNumber]];
227 }
228 - (void)mouseMoved: (NSEvent *) event
229 {
230 [self emitMouseMoveEvent: event];
231 }
232 - (void)mouseDragged: (NSEvent *) event
233 {
234 [self emitMouseMoveEvent: event];
235 }
236 - (void)rightMouseDragged: (NSEvent *) event
237 {
238 [self emitMouseMoveEvent: event];
239 }
240 - (void)otherMouseDragged: (NSEvent *) event
241 {
242 [self emitMouseMoveEvent: event];
243 }
245 @end
247 NSView *video_osx_create_drawable()
248 {
249 NSRect contentRect = {{0,0},{640,480}};
250 video_view = [[LxdreamOSXView alloc] initWithFrame: contentRect];
251 [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
252 return video_view;
253 }
255 static gboolean video_osx_init()
256 {
257 if( video_view == NULL ) {
258 return FALSE;
259 }
260 if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
261 return FALSE;
262 }
263 pvr2_setup_gl_context();
264 return TRUE;
265 }
267 static void video_osx_shutdown()
268 {
269 }
271 static void video_osx_display_blank( uint32_t colour )
272 {
273 }
275 static int mac_keymap_cmp(const void *a, const void *b)
276 {
277 const gchar *key = a;
278 const struct mac_keymap_struct *kb = b;
279 return strcasecmp(key, kb->name);
280 }
282 static uint16_t video_osx_resolve_keysym( const gchar *keysym )
283 {
284 struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
285 if( result == NULL ) {
286 return 0;
287 } else {
288 return result->keycode + 1;
289 }
290 }
292 static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
293 {
294 if( keycode < 1 || keycode > 128 ) {
295 return DCKB_NONE;
296 } else {
297 return mac_keycode_to_dckeysym[keycode-1];
298 }
299 }
301 static gchar *video_osx_keycode_to_keysym(uint16_t keycode)
302 {
303 if( keycode < 1 || keycode > 128 ) {
304 return NULL;
305 } else {
306 return g_strdup(mac_keysyms_by_keycode[keycode-1]);
307 }
308 }
.