Skip to content

Commit 069e50d

Browse files
committed
gfxlib/darwin: post cocoa events to fb
1 parent 236893a commit 069e50d

File tree

2 files changed

+231
-6
lines changed

2 files changed

+231
-6
lines changed

src/gfxlib2/darwin/gfx_driver_opengl_cocoa.m

Lines changed: 125 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
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

196197
static OpenGLDriver driver;
197-
static int mouse_wheel = 0;
198+
static int mouse_wheel, mouse_hwheel = 0;
199+
static bool has_focus = false;
198200
static void* gl_lib = NULL;
199201
static 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

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#include "../fb.h"
2+
3+
static const int fb_cocoakeycode_to_scancode[] = {
4+
[0x35] = SC_ESCAPE,
5+
[0x7A] = SC_F1,
6+
[0x78] = SC_F2,
7+
[0x63] = SC_F3,
8+
[0x76] = SC_F4,
9+
[0x60] = SC_F5,
10+
[0x61] = SC_F6,
11+
[0x62] = SC_F7,
12+
[0x64] = SC_F8,
13+
[0x65] = SC_F9,
14+
[0x6D] = SC_F10,
15+
[0x67] = SC_F11,
16+
[0x6F] = SC_F12,
17+
[0x32] = SC_TILDE,
18+
[0x12] = SC_1,
19+
[0x13] = SC_2,
20+
[0x14] = SC_3,
21+
[0x15] = SC_4,
22+
[0x17] = SC_5,
23+
[0x16] = SC_6,
24+
[0x1A] = SC_7,
25+
[0x1C] = SC_8,
26+
[0x19] = SC_9,
27+
[0x1D] = SC_0,
28+
[0x1B] = SC_MINUS,
29+
[0x18] = SC_EQUALS,
30+
[0x2A] = SC_BACKSLASH,
31+
[0x33] = SC_BACKSPACE,
32+
[0x30] = SC_TAB,
33+
[0x0C] = SC_Q,
34+
[0x0D] = SC_W,
35+
[0x0E] = SC_E,
36+
[0x0F] = SC_R,
37+
[0x11] = SC_T,
38+
[0x10] = SC_Y,
39+
[0x20] = SC_U,
40+
[0x22] = SC_I,
41+
[0x1F] = SC_O,
42+
[0x23] = SC_P,
43+
[0x21] = SC_LEFTBRACKET,
44+
[0x1E] = SC_RIGHTBRACKET,
45+
[0x39] = SC_CAPSLOCK,
46+
[0x00] = SC_A,
47+
[0x01] = SC_S,
48+
[0x02] = SC_D,
49+
[0x03] = SC_F,
50+
[0x05] = SC_G,
51+
[0x04] = SC_H,
52+
[0x26] = SC_J,
53+
[0x28] = SC_K,
54+
[0x25] = SC_L,
55+
[0x29] = SC_SEMICOLON,
56+
[0x27] = SC_QUOTE,
57+
[0x38] = SC_LSHIFT,
58+
[0x06] = SC_Z,
59+
[0x07] = SC_X,
60+
[0x08] = SC_C,
61+
[0x09] = SC_V,
62+
[0x0B] = SC_B,
63+
[0x2D] = SC_N,
64+
[0x2E] = SC_M,
65+
[0x2B] = SC_COMMA,
66+
[0x2F] = SC_PERIOD,
67+
[0x2C] = SC_SLASH,
68+
[0x3C] = SC_RSHIFT,
69+
[0x3B] = SC_CONTROL,
70+
[0x37] = SC_LWIN,
71+
[0x3A] = SC_ALT,
72+
[0x31] = SC_SPACE,
73+
[0x3D] = SC_ALT,
74+
[0x36] = SC_RWIN,
75+
[0x6E] = SC_MENU,
76+
[0x3E] = SC_CONTROL,
77+
[0x73] = SC_HOME,
78+
[0x74] = SC_PAGEUP,
79+
[0x75] = SC_DELETE,
80+
[0x77] = SC_END,
81+
[0x79] = SC_PAGEDOWN,
82+
[0x7E] = SC_UP,
83+
[0x7B] = SC_LEFT,
84+
[0x7D] = SC_DOWN,
85+
[0x7C] = SC_RIGHT,
86+
// Keypad
87+
[0x4B] = SC_SLASH,
88+
[0x43] = SC_MULTIPLY,
89+
[0x4E] = SC_MINUS,
90+
[0x45] = SC_PLUS,
91+
[0x47] = SC_CLEAR,
92+
[0x24] = SC_ENTER,
93+
[0x41] = SC_PERIOD,
94+
[0x4C] = SC_ENTER,
95+
[0x51] = SC_EQUALS,
96+
[0x52] = SC_0,
97+
[0x53] = SC_1,
98+
[0x54] = SC_2,
99+
[0x55] = SC_3,
100+
[0x56] = SC_4,
101+
[0x57] = SC_5,
102+
[0x58] = SC_6,
103+
[0x59] = SC_7,
104+
[0x5B] = SC_8,
105+
[0x5C] = SC_9
106+
};

0 commit comments

Comments
 (0)