filename | src/drivers/video_osx.m |
changeset | 1251:b8ab59d39756 |
prev | 1236:d93175c36387 |
author | nkeynes |
date | Sat Aug 04 08:46:28 2012 +1000 (11 years ago) |
permissions | -rw-r--r-- |
last change | Handle corner case in pvr2_run_slice when we've previously slightly overrun the end of the time slice |
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;
57 #define MAX_MASK_KEYCODE 128
59 @interface LxdreamOSXView : LxdreamVideoView
60 {
61 int flagsMask[MAX_MASK_KEYCODE];
62 }
63 @end
65 @implementation LxdreamVideoView
66 - (void)setIsGrabbed: (BOOL)grabbed
67 {
68 isGrabbed = grabbed;
69 }
70 - (void) setDelegate: (id)other
71 {
72 delegate = other;
73 }
74 - (id)delegate
75 {
76 return delegate;
77 }
78 @end
80 @implementation LxdreamOSXView
81 //--------------------------------------------------------------------
82 - (id)initWithFrame: (NSRect)contentRect
83 {
84 if( [super initWithFrame: contentRect] != nil ) {
85 int i;
86 isGrabbed = NO;
87 for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
88 flagsMask[i] = 0;
89 }
90 return self;
91 }
92 return nil;
93 }
94 - (BOOL)requestGrab
95 {
96 if( delegate && [delegate respondsToSelector: @selector(viewRequestedGrab:)] )
97 return [delegate performSelector: @selector(viewRequestedGrab:) withObject: self] != nil;
98 return NO;
99 }
100 - (BOOL)requestUngrab
101 {
102 if( delegate && [delegate respondsToSelector: @selector(viewRequestedUngrab:)] )
103 return [delegate performSelector: @selector(viewRequestedUngrab:) withObject: self] != nil;
104 return NO;
105 }
106 - (BOOL)isOpaque
107 {
108 return YES;
109 }
110 - (BOOL)acceptsFirstResponder
111 {
112 return YES;
113 }
114 - (BOOL)isFlipped
115 {
116 return YES;
117 }
118 //--------------------------------------------------------------------
119 - (void)drawRect: (NSRect) rect
120 {
121 NSSize size = [self frame].size;
122 if( video_width != size.width || video_height != size.height ) {
123 gl_set_video_size(size.width, size.height, 0);
124 video_nsgl_update();
125 }
126 pvr2_draw_frame();
127 }
128 - (void)keyDown: (NSEvent *) event
129 {
130 if( ![event isARepeat] ) {
131 input_event_keydown( NULL, [event keyCode]+1, MAX_PRESSURE );
132 }
133 }
134 - (void)keyUp: (NSEvent *) event
135 {
136 input_event_keyup( NULL, [event keyCode]+1 );
137 }
138 - (void)flagsChanged: (NSEvent *) event
139 {
140 int keycode = [event keyCode];
141 if( ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
142 [self requestUngrab];
143 }
145 if( flagsMask[keycode] == 0 ) {
146 input_event_keydown( NULL, keycode+1, MAX_PRESSURE );
147 flagsMask[keycode] = 1;
148 } else {
149 input_event_keyup( NULL, keycode+1 );
150 flagsMask[keycode] = 0;
151 }
152 }
153 - (void)emitMouseDownEvent: (NSEvent *)event button: (int)button
154 {
155 if( isGrabbed ) {
156 input_event_mousedown( button, 0, 0, FALSE );
157 } else {
158 NSPoint pt = [event locationInWindow];
159 int x = (int)pt.x;
160 int y = video_height - (int)pt.y;
161 gl_window_to_system_coords(&x,&y);
162 input_event_mousedown( button, x, y, TRUE );
163 }
164 }
165 - (void)emitMouseUpEvent: (NSEvent *)event button: (int)button
166 {
167 if( isGrabbed ) {
168 input_event_mouseup( button, 0, 0, FALSE );
169 } else {
170 NSPoint pt = [event locationInWindow];
171 int x = (int)pt.x;
172 int y = video_height - (int)pt.y;
173 gl_window_to_system_coords(&x,&y);
174 input_event_mouseup( button, x, y, TRUE );
175 }
176 }
177 - (void)emitMouseMoveEvent: (NSEvent *)event
178 {
179 if( isGrabbed ) {
180 input_event_mousemove( [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
181 } else {
182 NSPoint pt = [event locationInWindow];
183 int x = (int)pt.x;
184 int y = video_height - (int)pt.y;
185 gl_window_to_system_coords(&x,&y);
186 input_event_mousemove( x, y, TRUE );
187 }
188 }
189 - (void)mouseExited: (NSEvent *)event
190 {
191 if( !isGrabbed ) {
192 input_event_mousemove( -1, -1, TRUE );
193 }
194 }
196 - (void)mouseDown: (NSEvent *) event
197 {
198 // If using grab but not grabbed yet, the first click should be consumed
199 // by the grabber. In all other circumstances we process normally.
200 if( isGrabbed || ![self requestGrab] ) {
201 [self emitMouseDownEvent: event button: 0];
202 }
203 }
204 - (void)mouseUp: (NSEvent *)event
205 {
206 [self emitMouseUpEvent: event button: 0];
207 }
209 - (void)rightMouseDown: (NSEvent *) event
210 {
211 [self emitMouseDownEvent: event button: 1];
212 }
213 - (void)rightMouseUp: (NSEvent *)event
214 {
215 [self emitMouseUpEvent: event button: 1];
216 }
217 - (void)otherMouseDown: (NSEvent *) event
218 {
219 [self emitMouseDownEvent: event button: [event buttonNumber]];
220 }
221 - (void)otherMouseUp: (NSEvent *) event
222 {
223 [self emitMouseUpEvent: event button: [event buttonNumber]];
224 }
225 - (void)mouseMoved: (NSEvent *) event
226 {
227 [self emitMouseMoveEvent: event];
228 }
229 - (void)mouseDragged: (NSEvent *) event
230 {
231 [self emitMouseMoveEvent: event];
232 }
233 - (void)rightMouseDragged: (NSEvent *) event
234 {
235 [self emitMouseMoveEvent: event];
236 }
237 - (void)otherMouseDragged: (NSEvent *) event
238 {
239 [self emitMouseMoveEvent: event];
240 }
242 @end
244 NSView *video_osx_create_drawable()
245 {
246 NSRect contentRect = {{0,0},{640,480}};
247 video_view = [[LxdreamOSXView alloc] initWithFrame: contentRect];
248 [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
249 return video_view;
250 }
252 static gboolean video_osx_init()
253 {
254 if( video_view == NULL ) {
255 return FALSE;
256 }
257 if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
258 return FALSE;
259 }
260 pvr2_setup_gl_context();
261 return TRUE;
262 }
264 static void video_osx_shutdown()
265 {
266 }
268 static void video_osx_display_blank( uint32_t colour )
269 {
270 }
272 static int mac_keymap_cmp(const void *a, const void *b)
273 {
274 const gchar *key = a;
275 const struct mac_keymap_struct *kb = b;
276 return strcasecmp(key, kb->name);
277 }
279 static uint16_t video_osx_resolve_keysym( const gchar *keysym )
280 {
281 struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
282 if( result == NULL ) {
283 return 0;
284 } else {
285 return result->keycode + 1;
286 }
287 }
289 static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
290 {
291 if( keycode < 1 || keycode > 128 ) {
292 return DCKB_NONE;
293 } else {
294 return mac_keycode_to_dckeysym[keycode-1];
295 }
296 }
298 static gchar *video_osx_keycode_to_keysym(uint16_t keycode)
299 {
300 if( keycode < 1 || keycode > 128 ) {
301 return NULL;
302 } else {
303 return g_strdup(mac_keysyms_by_keycode[keycode-1]);
304 }
305 }
.