11#ifdef DISABLE_X11
22
3+ #include " ../../rtlib/darwin/fb_private_scancodes_cocoa.h"
34#include " ../fb_gfx.h"
45#include " ../fb_gfx_gl.h"
56#include " fb_gfx_cocoa.h"
@@ -194,7 +195,8 @@ @interface OpenGLWindow : NSWindow
194195} OpenGLDriver;
195196
196197static OpenGLDriver driver;
197- static int mouse_wheel = 0 ;
198+ static int mouse_wheel, mouse_hwheel = 0 ;
199+ static bool has_focus = false ;
198200static void * gl_lib = NULL ;
199201static NSRecursiveLock * lock = nil ;
200202
@@ -219,9 +221,26 @@ - (void)applicationWillTerminate:(NSNotification *)notification
219221@implementation WindowDelegate
220222- (BOOL )windowShouldClose : (NSWindow *)sender
221223{
224+ EVENT e;
225+ e.type = EVENT_WINDOW_CLOSE;
226+ fb_hPostEvent (&e);
222227 driver.closed = YES ;
223228 return YES ;
224229}
230+ - (void )windowDidBecomeKey : (NSNotification *)notification
231+ {
232+ EVENT e;
233+ e.type = EVENT_WINDOW_GOT_FOCUS;
234+ fb_hPostEvent (&e);
235+ has_focus = true ;
236+ }
237+
238+ - (void )windowDidResignKey : (NSNotification *)notification {
239+ EVENT e;
240+ e.type = EVENT_WINDOW_LOST_FOCUS;
241+ fb_hPostEvent (&e);
242+ has_focus = false ;
243+ }
225244@end
226245
227246@implementation OpenGLWindow
@@ -286,6 +305,7 @@ static int driver_init(char *title, int w, int h, int depth, int refresh_rate,
286305
287306 NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc ] initWithAttributes: attribs];
288307 driver.context = [[NSOpenGLContext alloc ] initWithFormat: format shareContext: nil ];
308+ [format release ];
289309 if (!driver.context ) return -1 ;
290310 driver.view = [[OpenGLView alloc ] initWithFrame: driver.frame];
291311 if (!driver.view ) return -1 ;
@@ -313,6 +333,7 @@ static int driver_init(char *title, int w, int h, int depth, int refresh_rate,
313333
314334 [NSApp activateIgnoringOtherApps: YES ];
315335 [driver.window makeKeyAndOrderFront: nil ];
336+ has_focus = true ;
316337 if (![[NSRunningApplication currentApplication ] isFinishedLaunching ])
317338 [NSApp run ];
318339
@@ -351,6 +372,7 @@ static void driver_exit(void) {
351372 [driver.view release ];
352373 [driver.window close ];
353374 [driver.window release ];
375+ [lock release ];
354376 if (gl_lib) dlclose (gl_lib);
355377 if ([NSApp isRunning ]) {
356378 [NSApp terminate: nil ];
@@ -378,16 +400,112 @@ void fb_hCocoaWaitVSync() {
378400 dispatch_semaphore_wait (vsyncSema, DISPATCH_TIME_FOREVER);
379401}
380402
381- void driver_poll_events () {
403+ static inline int translate_key (unsigned char key, int scancode) {
404+ if (key == 0 ) {
405+ return scancode;
406+ } else {
407+ return fb_hScancodeToExtendedKey (scancode);
408+ }
409+ }
410+
411+ static void driver_poll_events () {
382412 @autoreleasepool {
383413 NSEvent *event;
414+ EVENT e;
415+ unsigned char key;
416+
384417 while ((event = [NSApp nextEventMatchingMask: NSEventMaskAny
385418 untilDate: [NSDate distantPast ]
386419 inMode: NSDefaultRunLoopMode
387420 dequeue: YES ]) != nil ) {
388- if ([event type ] == NSEventTypeScrollWheel) {
389- mouse_wheel += [event deltaY ];
421+ e.type = 0 ;
422+ switch (event.type ) {
423+ case NSEventTypeKeyDown:
424+ e.type = event.isARepeat ? EVENT_KEY_REPEAT : EVENT_KEY_PRESS;
425+ e.scancode = fb_cocoakeycode_to_scancode[event.keyCode];
426+ __fb_gfx->key [e.scancode] = TRUE ;
427+
428+ key = translate_key ([event charactersIgnoringModifiers ].UTF8String [0 ], e.scancode );
429+ if (key) {
430+ fb_hPostKey (key);
431+ e.ascii = (key > 0 && key < 0xFF ) ? key : 0 ;
432+ }
433+ break ;
434+ case NSEventTypeKeyUp:
435+ e.type = EVENT_KEY_RELEASE;
436+ e.scancode = fb_cocoakeycode_to_scancode[event.keyCode];
437+ __fb_gfx->key [e.scancode] = FALSE ;
438+
439+ key = [event charactersIgnoringModifiers ].UTF8String [0 ];
440+ e.ascii = (key > 0 && key < 0xFF ) ? key : 0 ;
441+ break ;
442+ case NSEventTypeScrollWheel:
443+ mouse_wheel += [event scrollingDeltaY ];
444+ mouse_hwheel += [event scrollingDeltaX ];
445+
446+ if ([event scrollingDeltaX ] != 0 ) {
447+ e.type = EVENT_MOUSE_HWHEEL;
448+ e.z = mouse_hwheel;
449+ } else {
450+ e.type = EVENT_MOUSE_WHEEL;
451+ e.z = mouse_wheel;
452+ }
453+ break ;
454+ case NSEventTypeMouseEntered:
455+ e.type = EVENT_MOUSE_ENTER;
456+ has_focus = true ;
457+ break ;
458+ case NSEventTypeMouseExited:
459+ e.type = EVENT_MOUSE_EXIT;
460+ has_focus = false ;
461+ break ;
462+ case NSEventTypeMouseMoved:
463+ case NSEventTypeLeftMouseDragged:
464+ case NSEventTypeRightMouseDragged:
465+ case NSEventTypeOtherMouseDragged:
466+ if (has_focus) {
467+ e.type = EVENT_MOUSE_MOVE;
468+ e.x = [event locationInWindow ].x ;
469+ e.y = [event locationInWindow ].y ;
470+ e.dx = [event deltaX ];
471+ e.dy = [event deltaY ];
472+
473+ if ( __fb_gfx->scanline_size != 1 ) {
474+ e.y /= __fb_gfx->scanline_size ;
475+ e.dy /= __fb_gfx->scanline_size ;
476+ }
477+ }
478+ break ;
479+ case NSEventTypeLeftMouseDown:
480+ e.type = event.clickCount == 1 ? EVENT_MOUSE_BUTTON_PRESS : EVENT_MOUSE_DOUBLE_CLICK;
481+ e.button = 1 ;
482+ break ;
483+ case NSEventTypeLeftMouseUp:
484+ e.type = EVENT_MOUSE_BUTTON_RELEASE;
485+ e.button = BUTTON_LEFT;
486+ break ;
487+ case NSEventTypeRightMouseDown:
488+ e.type = event.clickCount == 1 ? EVENT_MOUSE_BUTTON_PRESS : EVENT_MOUSE_DOUBLE_CLICK;
489+ e.button = 2 ;
490+ break ;
491+ case NSEventTypeRightMouseUp:
492+ e.type = EVENT_MOUSE_BUTTON_RELEASE;
493+ e.button = BUTTON_RIGHT;
494+ break ;
495+ case NSEventTypeOtherMouseDown:
496+ e.type = event.clickCount == 1 ? EVENT_MOUSE_BUTTON_PRESS : EVENT_MOUSE_DOUBLE_CLICK;
497+ e.button = 1 << [event buttonNumber ];
498+ break ;
499+ case NSEventTypeOtherMouseUp:
500+ e.type = EVENT_MOUSE_BUTTON_RELEASE;
501+ e.button = 1 << [event buttonNumber ];
502+ break ;
503+ default :
504+ break ;
390505 }
506+ if (e.type )
507+ fb_hPostEvent (&e);
508+
391509 [NSApp sendEvent: event];
392510 }
393511 }
@@ -448,15 +566,16 @@ int fb_hCocoaSetWindowPos(int x, int y) {
448566 return NULL ;
449567
450568 CGDirectDisplayID mainDisplay = CGMainDisplayID ();
451- NSArray *modes = (__bridge NSArray *)CGDisplayCopyAllDisplayModes (mainDisplay, NULL );
569+ CFArrayRef modesRef = CGDisplayCopyAllDisplayModes (mainDisplay, NULL );
570+ NSArray *modes = (__bridge NSArray *)modesRef;
452571 *size = modes.count ;
453572 int * modesArray = (int *)malloc (sizeof (int ) * modes.count );
454573 for (size_t i = 0 ; i < modes.count ; i++) {
455574 CGDisplayModeRef mode = (__bridge CGDisplayModeRef)modes[i];
456575 modesArray[i] = (CGDisplayModeGetWidth (mode) << 16 ) | CGDisplayModeGetHeight (mode);
457576 }
458577
459- CFRelease (modes );
578+ CFRelease (modesRef );
460579 return modesArray;
461580}
462581
0 commit comments