filename | src/drivers/video_osx.c |
changeset | 839:51f1c4195790 |
prev | 805:b355f7b3ff2e |
next | 850:28782ebbd01d |
author | nkeynes |
date | Tue Sep 02 03:34:00 2008 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Implement absolute positioning mouse mode when not grabbed enable/disable grab on dreamcast start/stop where it's requested by the controllers |
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 "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 buttonMask;
64 int flagsMask[MAX_MASK_KEYCODE];
65 }
66 @end
68 @implementation LxdreamVideoView
69 - (void)setIsGrabbed: (BOOL)grabbed
70 {
71 isGrabbed = grabbed;
72 }
73 - (void) setDelegate: (id)other
74 {
75 delegate = other;
76 }
77 - (id)delegate
78 {
79 return delegate;
80 }
81 @end
83 @implementation LxdreamOSXView
84 //--------------------------------------------------------------------
85 - (id)initWithFrame: (NSRect)contentRect
86 {
87 if( [super initWithFrame: contentRect] != nil ) {
88 int i;
89 isGrabbed = NO;
90 buttonMask = 0;
91 for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
92 flagsMask[i] = 0;
93 }
94 return self;
95 }
96 return nil;
97 }
98 - (BOOL)requestGrab
99 {
100 if( delegate && [delegate respondsToSelector: @selector(viewRequestedGrab:)] )
101 return [delegate performSelector: @selector(viewRequestedGrab:) withObject: self] != nil;
102 return NO;
103 }
104 - (BOOL)requestUngrab
105 {
106 if( delegate && [delegate respondsToSelector: @selector(viewRequestedUngrab:)] )
107 return [delegate performSelector: @selector(viewRequestedUngrab:) withObject: self] != nil;
108 return NO;
109 }
110 - (BOOL)isOpaque
111 {
112 return YES;
113 }
114 - (BOOL)acceptsFirstResponder
115 {
116 return YES;
117 }
118 - (BOOL)isFlipped
119 {
120 return YES;
121 }
122 //--------------------------------------------------------------------
123 - (void)drawRect: (NSRect) rect
124 {
125 NSSize size = [self frame].size;
126 if( video_width != size.width || video_height != size.height ) {
127 video_width = size.width;
128 video_height = size.height;
129 video_nsgl_update();
130 }
131 pvr2_redraw_display();
132 }
133 - (void)keyDown: (NSEvent *) event
134 {
135 if( ![event isARepeat] ) {
136 input_event_keydown( NULL, [event keyCode]+1, 1 );
137 }
138 }
139 - (void)keyUp: (NSEvent *) event
140 {
141 input_event_keyup( NULL, [event keyCode]+1, 1 );
142 }
143 - (void)flagsChanged: (NSEvent *) event
144 {
145 int keycode = [event keyCode];
146 if( ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
147 [self requestUngrab];
148 }
150 if( flagsMask[keycode] == 0 ) {
151 input_event_keydown( NULL, keycode+1, 1 );
152 flagsMask[keycode] = 1;
153 } else {
154 input_event_keyup( NULL, keycode+1, 1 );
155 flagsMask[keycode] = 0;
156 }
157 }
158 - (void)emitButtonEvent: (NSEvent *)event buttons: (int)buttons
159 {
160 if( isGrabbed ) {
161 input_event_mouse( buttons, 0, 0, FALSE );
162 } else {
163 NSPoint pt = [event locationInWindow];
164 input_event_mouse( buttonMask, (int)pt.x, (int)pt.y, TRUE );
165 }
166 }
168 - (void)mouseDown: (NSEvent *) event
169 {
170 buttonMask |= 1;
171 // If using grab but not grabbed yet, the first click should be consumed
172 // by the grabber. In all other circumstances we process normally.
173 if( isGrabbed || ![self requestGrab] ) {
174 [self emitButtonEvent: event buttons: buttonMask];
175 }
176 }
177 - (void)mouseUp: (NSEvent *)event
178 {
179 buttonMask &= ~1;
180 [self emitButtonEvent: event buttons: buttonMask];
181 }
183 - (void)rightMouseDown: (NSEvent *) event
184 {
185 buttonMask |= 2;
186 [self emitButtonEvent: event buttons: buttonMask];
187 }
188 - (void)rightMouseUp: (NSEvent *)event
189 {
190 buttonMask &= ~2;
191 [self emitButtonEvent: event buttons: buttonMask];
192 }
193 - (void)otherMouseDown: (NSEvent *) event
194 {
195 buttonMask |= (1<< [event buttonNumber] );
196 [self emitButtonEvent: event buttons: buttonMask];
197 }
198 - (void)otherMouseUp: (NSEvent *) event
199 {
200 buttonMask &= ~(1<< [event buttonNumber] );
201 [self emitButtonEvent: event buttons: buttonMask];
202 }
203 - (void)mouseMoved: (NSEvent *) event
204 {
205 if( isGrabbed ) {
206 input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
207 }
208 }
209 - (void)mouseDragged: (NSEvent *) event
210 {
211 if( isGrabbed ) {
212 input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
213 }
214 }
215 - (void)rightMouseDragged: (NSEvent *) event
216 {
217 if( isGrabbed ) {
218 input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
219 }
220 }
221 - (void)otherMouseDragged: (NSEvent *) event
222 {
223 if( isGrabbed ) {
224 input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
225 }
226 }
228 @end
230 NSView *video_osx_create_drawable()
231 {
232 NSRect contentRect = {{0,0},{640,480}};
233 video_view = [[LxdreamOSXView alloc] initWithFrame: contentRect];
234 [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
235 return video_view;
236 }
238 static gboolean video_osx_init()
239 {
240 if( video_view == NULL ) {
241 return FALSE;
242 }
243 if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
244 return FALSE;
245 }
246 pvr2_setup_gl_context();
247 return TRUE;
248 }
250 static void video_osx_shutdown()
251 {
252 }
254 static void video_osx_display_blank( uint32_t colour )
255 {
256 }
258 static int mac_keymap_cmp(const void *a, const void *b)
259 {
260 const gchar *key = a;
261 const struct mac_keymap_struct *kb = b;
262 return strcasecmp(key, kb->name);
263 }
265 static uint16_t video_osx_resolve_keysym( const gchar *keysym )
266 {
267 struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
268 if( result == NULL ) {
269 return 0;
270 } else {
271 return result->keycode + 1;
272 }
273 }
275 static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
276 {
277 if( keycode < 1 || keycode > 128 ) {
278 return DCKB_NONE;
279 } else {
280 return mac_keycode_to_dckeysym[keycode-1];
281 }
282 }
284 static gchar *video_osx_keycode_to_keysym(uint16_t keycode)
285 {
286 if( keycode < 1 || keycode > 128 ) {
287 return NULL;
288 } else {
289 return g_strdup(mac_keysyms_by_keycode[keycode-1]);
290 }
291 }
.