aboutsummaryrefslogtreecommitdiff
path: root/cocoa.m
diff options
context:
space:
mode:
Diffstat (limited to 'cocoa.m')
-rw-r--r--cocoa.m448
1 files changed, 373 insertions, 75 deletions
diff --git a/cocoa.m b/cocoa.m
index d41517b087..895e96f982 100644
--- a/cocoa.m
+++ b/cocoa.m
@@ -47,6 +47,9 @@ int gArgc;
char **gArgv;
DisplayState current_ds;
+int grab = 0;
+int modifiers_state[256];
+
/* main defined in qemu/vl.c */
int qemu_main(int argc, char **argv);
@@ -171,63 +174,175 @@ static void cocoa_resize(DisplayState *ds, int w, int h)
------------------------------------------------------
*/
-static int keymap[] =
+int keymap[] =
{
- 30, //'a' 0x0
- 31, //'s'
- 32, //'d'
- 33, //'f'
- 35, //'h'
- 34, //'g'
- 44, //'z'
- 45, //'x'
- 46, //'c'
- 47, //'v'
- 0, // 0 0x0a
- 48, //'b'
- 16, //'q'
- 17, //'w'
- 18, //'e'
- 19, //'r'
- 21, //'y' 0x10
- 20, //'t'
- 2, //'1'
- 3, //'2'
- 4, //'3'
- 5, //'4'
- 7, //'6'
- 6, //'5'
- 0, //'='
- 10, //'9'
- 8, //'7' 0x1A
- 0, //'-'
- 9, //'8'
- 11, //'0'
- 27, //']'
- 24, //'o'
- 22, //'u' 0x20
- 26, //'['
- 23, //'i'
- 25, //'p'
- 28, //'\n'
- 38, //'l'
- 36, //'j'
- 40, //'"'
- 37, //'k'
- 39, //';'
- 15, //'\t' 0x30
- 0, //' '
- 0, //'`'
- 14, //'<backspace>'
- 0, //'' 0x34
- 0, //'<esc>'
- 0, //'<esc>'
- /* Not completed to finish see http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */
+// SdlI macI macH SdlH 104xtH 104xtC sdl
+ 30, // 0 0x00 0x1e A QZ_a
+ 31, // 1 0x01 0x1f S QZ_s
+ 32, // 2 0x02 0x20 D QZ_d
+ 33, // 3 0x03 0x21 F QZ_f
+ 35, // 4 0x04 0x23 H QZ_h
+ 34, // 5 0x05 0x22 G QZ_g
+ 44, // 6 0x06 0x2c Z QZ_z
+ 45, // 7 0x07 0x2d X QZ_x
+ 46, // 8 0x08 0x2e C QZ_c
+ 47, // 9 0x09 0x2f V QZ_v
+ 0, // 10 0x0A Undefined
+ 48, // 11 0x0B 0x30 B QZ_b
+ 16, // 12 0x0C 0x10 Q QZ_q
+ 17, // 13 0x0D 0x11 W QZ_w
+ 18, // 14 0x0E 0x12 E QZ_e
+ 19, // 15 0x0F 0x13 R QZ_r
+ 21, // 16 0x10 0x15 Y QZ_y
+ 20, // 17 0x11 0x14 T QZ_t
+ 2, // 18 0x12 0x02 1 QZ_1
+ 3, // 19 0x13 0x03 2 QZ_2
+ 4, // 20 0x14 0x04 3 QZ_3
+ 5, // 21 0x15 0x05 4 QZ_4
+ 7, // 22 0x16 0x07 6 QZ_6
+ 6, // 23 0x17 0x06 5 QZ_5
+ 13, // 24 0x18 0x0d = QZ_EQUALS
+ 10, // 25 0x19 0x0a 9 QZ_9
+ 8, // 26 0x1A 0x08 7 QZ_7
+ 12, // 27 0x1B 0x0c - QZ_MINUS
+ 9, // 28 0x1C 0x09 8 QZ_8
+ 11, // 29 0x1D 0x0b 0 QZ_0
+ 27, // 30 0x1E 0x1b ] QZ_RIGHTBRACKET
+ 24, // 31 0x1F 0x18 O QZ_o
+ 22, // 32 0x20 0x16 U QZ_u
+ 26, // 33 0x21 0x1a [ QZ_LEFTBRACKET
+ 23, // 34 0x22 0x17 I QZ_i
+ 25, // 35 0x23 0x19 P QZ_p
+ 28, // 36 0x24 0x1c ENTER QZ_RETURN
+ 38, // 37 0x25 0x26 L QZ_l
+ 36, // 38 0x26 0x24 J QZ_j
+ 40, // 39 0x27 0x28 ' QZ_QUOTE
+ 37, // 40 0x28 0x25 K QZ_k
+ 39, // 41 0x29 0x27 ; QZ_SEMICOLON
+ 43, // 42 0x2A 0x2b \ QZ_BACKSLASH
+ 51, // 43 0x2B 0x33 , QZ_COMMA
+ 53, // 44 0x2C 0x35 / QZ_SLASH
+ 49, // 45 0x2D 0x31 N QZ_n
+ 50, // 46 0x2E 0x32 M QZ_m
+ 52, // 47 0x2F 0x34 . QZ_PERIOD
+ 15, // 48 0x30 0x0f TAB QZ_TAB
+ 57, // 49 0x31 0x39 SPACE QZ_SPACE
+ 41, // 50 0x32 0x29 ` QZ_BACKQUOTE
+ 14, // 51 0x33 0x0e BKSP QZ_BACKSPACE
+ 0, // 52 0x34 Undefined
+ 1, // 53 0x35 0x01 ESC QZ_ESCAPE
+ 0, // 54 0x36 QZ_RMETA
+ 0, // 55 0x37 QZ_LMETA
+ 42, // 56 0x38 0x2a L SHFT QZ_LSHIFT
+ 58, // 57 0x39 0x3a CAPS QZ_CAPSLOCK
+ 56, // 58 0x3A 0x38 L ALT QZ_LALT
+ 29, // 59 0x3B 0x1d L CTRL QZ_LCTRL
+ 54, // 60 0x3C 0x36 R SHFT QZ_RSHIFT
+ 184,// 61 0x3D 0xb8 E0,38 R ALT QZ_RALT
+ 157,// 62 0x3E 0x9d E0,1D R CTRL QZ_RCTRL
+ 0, // 63 0x3F Undefined
+ 0, // 64 0x40 Undefined
+ 0, // 65 0x41 Undefined
+ 0, // 66 0x42 Undefined
+ 55, // 67 0x43 0x37 KP * QZ_KP_MULTIPLY
+ 0, // 68 0x44 Undefined
+ 78, // 69 0x45 0x4e KP + QZ_KP_PLUS
+ 0, // 70 0x46 Undefined
+ 69, // 71 0x47 0x45 NUM QZ_NUMLOCK
+ 0, // 72 0x48 Undefined
+ 0, // 73 0x49 Undefined
+ 0, // 74 0x4A Undefined
+ 181,// 75 0x4B 0xb5 E0,35 KP / QZ_KP_DIVIDE
+ 152,// 76 0x4C 0x9c E0,1C KP EN QZ_KP_ENTER
+ 0, // 77 0x4D undefined
+ 74, // 78 0x4E 0x4a KP - QZ_KP_MINUS
+ 0, // 79 0x4F Undefined
+ 0, // 80 0x50 Undefined
+ 0, // 81 0x51 QZ_KP_EQUALS
+ 82, // 82 0x52 0x52 KP 0 QZ_KP0
+ 79, // 83 0x53 0x4f KP 1 QZ_KP1
+ 80, // 84 0x54 0x50 KP 2 QZ_KP2
+ 81, // 85 0x55 0x51 KP 3 QZ_KP3
+ 75, // 86 0x56 0x4b KP 4 QZ_KP4
+ 76, // 87 0x57 0x4c KP 5 QZ_KP5
+ 77, // 88 0x58 0x4d KP 6 QZ_KP6
+ 71, // 89 0x59 0x47 KP 7 QZ_KP7
+ 0, // 90 0x5A Undefined
+ 72, // 91 0x5B 0x48 KP 8 QZ_KP8
+ 73, // 92 0x5C 0x49 KP 9 QZ_KP9
+ 0, // 93 0x5D Undefined
+ 0, // 94 0x5E Undefined
+ 0, // 95 0x5F Undefined
+ 63, // 96 0x60 0x3f F5 QZ_F5
+ 64, // 97 0x61 0x40 F6 QZ_F6
+ 65, // 98 0x62 0x41 F7 QZ_F7
+ 61, // 99 0x63 0x3d F3 QZ_F3
+ 66, // 100 0x64 0x42 F8 QZ_F8
+ 67, // 101 0x65 0x43 F9 QZ_F9
+ 0, // 102 0x66 Undefined
+ 87, // 103 0x67 0x57 F11 QZ_F11
+ 0, // 104 0x68 Undefined
+ 183,// 105 0x69 0xb7 QZ_PRINT
+ 0, // 106 0x6A Undefined
+ 70, // 107 0x6B 0x46 SCROLL QZ_SCROLLOCK
+ 0, // 108 0x6C Undefined
+ 68, // 109 0x6D 0x44 F10 QZ_F10
+ 0, // 110 0x6E Undefined
+ 88, // 111 0x6F 0x58 F12 QZ_F12
+ 0, // 112 0x70 Undefined
+ 110,// 113 0x71 0x0 QZ_PAUSE
+ 210,// 114 0x72 0xd2 E0,52 INSERT QZ_INSERT
+ 199,// 115 0x73 0xc7 E0,47 HOME QZ_HOME
+ 201,// 116 0x74 0xc9 E0,49 PG UP QZ_PAGEUP
+ 211,// 117 0x75 0xd3 E0,53 DELETE QZ_DELETE
+ 62, // 118 0x76 0x3e F4 QZ_F4
+ 207,// 119 0x77 0xcf E0,4f END QZ_END
+ 60, // 120 0x78 0x3c F2 QZ_F2
+ 209,// 121 0x79 0xd1 E0,51 PG DN QZ_PAGEDOWN
+ 59, // 122 0x7A 0x3b F1 QZ_F1
+ 203,// 123 0x7B 0xcb e0,4B L ARROW QZ_LEFT
+ 205,// 124 0x7C 0xcd e0,4D R ARROW QZ_RIGHT
+ 208,// 125 0x7D 0xd0 E0,50 D ARROW QZ_DOWN
+ 200,// 126 0x7E 0xc8 E0,48 U ARROW QZ_UP
+/* completed according to http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */
+
+/* Aditional 104 Key XP-Keyboard Scancodes from http://www.computer-engineering.org/ps2keyboard/scancodes1.html */
+/*
+ 219 // 0xdb e0,5b L GUI
+ 220 // 0xdc e0,5c R GUI
+ 221 // 0xdd e0,5d APPS
+ // E0,2A,E0,37 PRNT SCRN
+ // E1,1D,45,E1,9D,C5 PAUSE
+ 83 // 0x53 0x53 KP .
+// ACPI Scan Codes
+ 222 // 0xde E0, 5E Power
+ 223 // 0xdf E0, 5F Sleep
+ 227 // 0xe3 E0, 63 Wake
+// Windows Multimedia Scan Codes
+ 153 // 0x99 E0, 19 Next Track
+ 144 // 0x90 E0, 10 Previous Track
+ 164 // 0xa4 E0, 24 Stop
+ 162 // 0xa2 E0, 22 Play/Pause
+ 160 // 0xa0 E0, 20 Mute
+ 176 // 0xb0 E0, 30 Volume Up
+ 174 // 0xae E0, 2E Volume Down
+ 237 // 0xed E0, 6D Media Select
+ 236 // 0xec E0, 6C E-Mail
+ 161 // 0xa1 E0, 21 Calculator
+ 235 // 0xeb E0, 6B My Computer
+ 229 // 0xe5 E0, 65 WWW Search
+ 178 // 0xb2 E0, 32 WWW Home
+ 234 // 0xea E0, 6A WWW Back
+ 233 // 0xe9 E0, 69 WWW Forward
+ 232 // 0xe8 E0, 68 WWW Stop
+ 231 // 0xe7 E0, 67 WWW Refresh
+ 230 // 0xe6 E0, 66 WWW Favorites
+*/
};
-static int cocoa_keycode_to_qemu(int keycode)
+int cocoa_keycode_to_qemu(int keycode)
{
- if(sizeof(keymap) <= keycode)
+ if((sizeof(keymap)/sizeof(int)) <= keycode)
{
printf("(cocoa) warning unknow keycode 0x%x\n", keycode);
return 0;
@@ -246,7 +361,6 @@ static void cocoa_refresh(DisplayState *ds)
NSDate *distantPast;
NSEvent *event;
NSAutoreleasePool *pool;
- int grab = 1;
pool = [ [ NSAutoreleasePool alloc ] init ];
distantPast = [ NSDate distantPast ];
@@ -258,41 +372,225 @@ static void cocoa_refresh(DisplayState *ds)
inMode: NSDefaultRunLoopMode dequeue:YES ];
if (event != nil) {
switch ([event type]) {
- case NSKeyDown:
- if(grab)
+ case NSFlagsChanged:
{
int keycode = cocoa_keycode_to_qemu([event keyCode]);
+ modifiers_state[keycode] = (modifiers_state[keycode] == 0) ? 1 : 0;
+
+ if ( modifiers_state[keycode] ) { /* Keydown */
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode & 0x7f);
+ } else { /* Keyup */
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode | 0x80);
+ }
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode & 0x7f);
+ /* emulate caps lock and num lock keyup */
+ if ((keycode == 58) || (keycode == 69))
+ {
+ modifiers_state[keycode] = 0;
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode | 0x80);
+ }
+
+ /* release Mouse grab when pressing ctrl+alt */
+ if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask))
+ [window setTitle: @"QEMU"];
+ [NSCursor unhide];
+ CGAssociateMouseAndMouseCursorPosition ( TRUE );
+ grab = 0;
}
break;
+
+ case NSKeyDown:
+ {
+ int keycode = cocoa_keycode_to_qemu([event keyCode]);
+
+ /* handle command Key Combos */
+ if ([event modifierFlags] & NSCommandKeyMask) {
+ switch ([event keyCode]) {
+ /* quit */
+ case 12: /* q key */
+ /* switch to windowed View */
+ exit(0);
+ return;
+ }
+ }
+
+ /* handle control + alt Key Combos */
+ if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
+ switch (keycode) {
+ /* toggle Monitor */
+ case 0x02 ... 0x0a: /* '1' to '9' keys */
+ console_select(keycode - 0x02);
+ if (is_active_console(vga_console)) {
+ /* tell the vga console to redisplay itself */
+ vga_invalidate_display();
+ break;
+ }
+ }
+ } else {
+ /* handle standard key events */
+ if (is_active_console(vga_console)) {
+ if (keycode & 0x80) //check bit for e0 in front
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode & 0x7f); //remove e0 bit in front
+ /* handle monitor key events */
+ } else {
+ switch([event keyCode]) {
+ case 123:
+ kbd_put_keysym(QEMU_KEY_LEFT);
+ break;
+ case 124:
+ kbd_put_keysym(QEMU_KEY_RIGHT);
+ break;
+ case 125:
+ kbd_put_keysym(QEMU_KEY_DOWN);
+ break;
+ case 126:
+ kbd_put_keysym(QEMU_KEY_UP);
+ break;
+ default:
+ kbd_put_keysym([[event characters] characterAtIndex:0]);
+ break;
+ }
+ }
+ }
+ }
+ break;
+
case NSKeyUp:
- if(grab)
{
- int keycode = cocoa_keycode_to_qemu([event keyCode]);
-
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode | 0x80);
+ int keycode = cocoa_keycode_to_qemu([event keyCode]);
+ if (is_active_console(vga_console)) {
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode | 0x80); //add 128 to signal release of key
+ }
}
break;
- case NSScrollWheel:
-
+
+ case NSMouseMoved:
+ if (grab) {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+ int buttons = 0;
+ kbd_mouse_event(dx, dy, dz, buttons);
+ }
+ break;
+
case NSLeftMouseDown:
+ if (grab) {
+ int buttons = 0;
+
+ /* leftclick+command simulates rightclick */
+ if ([event modifierFlags] & NSCommandKeyMask) {
+ buttons |= MOUSE_EVENT_RBUTTON;
+ } else {
+ buttons |= MOUSE_EVENT_LBUTTON;
+ }
+ kbd_mouse_event(0, 0, 0, buttons);
+ } else {
+ [NSApp sendEvent: event];
+ }
+ break;
+
+ case NSLeftMouseDragged:
+ if (grab) {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+ int buttons = 0;
+ if ([[NSApp currentEvent] modifierFlags] & NSCommandKeyMask) { //leftclick+command simulates rightclick
+ buttons |= MOUSE_EVENT_RBUTTON;
+ } else {
+ buttons |= MOUSE_EVENT_LBUTTON;
+ }
+ kbd_mouse_event(dx, dy, dz, buttons);
+ }
+ break;
+
case NSLeftMouseUp:
-
- case NSOtherMouseDown:
+ if (grab) {
+ kbd_mouse_event(0, 0, 0, 0);
+ } else {
+ [window setTitle: @"QEMU (Press ctrl + alt to release Mouse)"];
+ [NSCursor hide];
+ CGAssociateMouseAndMouseCursorPosition ( FALSE );
+ grab = 1;
+ //[NSApp sendEvent: event];
+ }
+ break;
+
case NSRightMouseDown:
-
- case NSOtherMouseUp:
+ if (grab) {
+ int buttons = 0;
+
+ buttons |= MOUSE_EVENT_RBUTTON;
+ kbd_mouse_event(0, 0, 0, buttons);
+ } else {
+ [NSApp sendEvent: event];
+ }
+ break;
+
+ case NSRightMouseDragged:
+ if (grab) {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+ int buttons = 0;
+ buttons |= MOUSE_EVENT_RBUTTON;
+ kbd_mouse_event(dx, dy, dz, buttons);
+ }
+ break;
+
case NSRightMouseUp:
-
- case NSMouseMoved:
+ if (grab) {
+ kbd_mouse_event(0, 0, 0, 0);
+ } else {
+ [NSApp sendEvent: event];
+ }
+ break;
+
case NSOtherMouseDragged:
- case NSRightMouseDragged:
- case NSLeftMouseDragged:
+ if (grab) {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+ int buttons = 0;
+ buttons |= MOUSE_EVENT_MBUTTON;
+ kbd_mouse_event(dx, dy, dz, buttons);
+ }
+ break;
+
+ case NSOtherMouseDown:
+ if (grab) {
+ int buttons = 0;
+ buttons |= MOUSE_EVENT_MBUTTON;
+ kbd_mouse_event(0, 0, 0, buttons);
+ } else {
+ [NSApp sendEvent:event];
+ }
+ break;
+
+ case NSOtherMouseUp:
+ if (grab) {
+ kbd_mouse_event(0, 0, 0, 0);
+ } else {
+ [NSApp sendEvent: event];
+ }
+ break;
+
+ case NSScrollWheel:
+ if (grab) {
+ int dz = [event deltaY];
+ kbd_mouse_event(0, 0, -dz, 0);
+ }
+ break;
default: [NSApp sendEvent:event];
}