From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34685) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UxkA6-0008F2-Bw for qemu-devel@nongnu.org; Fri, 12 Jul 2013 16:41:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UxkA4-000231-QH for qemu-devel@nongnu.org; Fri, 12 Jul 2013 16:41:54 -0400 Received: from mail-qe0-x233.google.com ([2607:f8b0:400d:c02::233]:62791) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UxkA4-00022s-KE for qemu-devel@nongnu.org; Fri, 12 Jul 2013 16:41:52 -0400 Received: by mail-qe0-f51.google.com with SMTP id a11so5438267qen.10 for ; Fri, 12 Jul 2013 13:41:51 -0700 (PDT) Received: from [192.168.0.3] (d14-69-153-26.try.wideopenwest.com. [69.14.26.153]) by mx.google.com with ESMTPSA id a8sm37108375qae.11.2013.07.12.13.41.49 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 12 Jul 2013 13:41:50 -0700 (PDT) From: Programmingkid Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Date: Fri, 12 Jul 2013 16:41:48 -0400 Message-Id: Mime-Version: 1.0 (Apple Message framework v1084) Subject: [Qemu-devel] [PATCH] Adds the ability to use the command key in the guest OS. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel qemu-devel This patch adds the ability to use the command key in the guest OS. This = patch will allow you to send keyboard shortcuts to Macintosh = applications running in QEMU.=20 signed-off-by: John Arbuckle --- ui/cocoa.m | 123 = +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 110 insertions(+), 13 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index be49179..4884ccf 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -70,6 +70,7 @@ static DisplayChangeListener *dcl; =20 int gArgc; char **gArgv; +bool substitutingForCommandKey =3D false;=20 =20 // keymap conversion int keymap[] =3D @@ -129,8 +130,8 @@ int keymap[] =3D 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 + 220, // 54 0x36 QZ_RMETA + 219, // 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 @@ -249,6 +250,72 @@ static int cocoa_keycode_to_qemu(int keycode) } =20 =20 +// Used to map the guest OS's command key to a key on the host = keyboard. +// Uses the -command-key option. +static void handleCommandKeyOption(int * argc, char * argv[]) +{ + bool foundOption =3D false; + int newCommandKeyButtonValue, i;=09 + + #define BUFFER_SIZE 10 + #define LEFT_COMMAND_KEY 0x37 + #define RIGHT_COMMAND_KEY 0x36 + #define GUEST_COMMAND_KEY 219 +=09 + char keyValueString[BUFFER_SIZE]; + + for(i =3D 0; i < *argc; i++) { + if(strcmp(argv[i], "-command-key") =3D=3D 0) { + foundOption =3D true; + break; + } + } + + // if the -command-key option is found + if(foundOption =3D=3D true) + { + snprintf(keyValueString, BUFFER_SIZE, "%s", argv[i+1]);=20= + if(strlen(keyValueString) =3D=3D 0) { + printf("Usage: -command-key \n"); + printf("This page will help: = http://boredzo.org/blog/wp-content/uploads/2007/05/imtx-virtual-keycodes.p= ng\n"); + exit(-1000); + } + =09 + // if using hexadecimal notation (e.g. 0x37) + if(keyValueString[0] =3D=3D '0' && = toupper(keyValueString[1]) =3D=3D 'X') { + sscanf(keyValueString, "%x", = &newCommandKeyButtonValue); + } + =09 + // for decimal notation + else { + newCommandKeyButtonValue =3D = atoi(keyValueString); + } + =09 + //in case the key specified is a negative value + if(newCommandKeyButtonValue < 0) { + printf("\aCan't use a negative value for the = command key!\n"); + exit(-1001); + } + =09 + // if the guest OS command key is set to the host = keyboard's left or right command key + if(newCommandKeyButtonValue =3D=3D LEFT_COMMAND_KEY || = newCommandKeyButtonValue =3D=3D RIGHT_COMMAND_KEY) { + substitutingForCommandKey =3D true; + printf("\nNote: since you are using the host = command key, the ALT key can be used to send QEMU commands.\n"); + printf("Example: use ALT-q to quit QEMU.\n\n"); + } + =09 + // do the mapping + keymap[newCommandKeyButtonValue] =3D GUEST_COMMAND_KEY; + =09 + // Remove -command-key from the argument list. + // QEMU will complain if we don't. + for(int x =3D i; x < *argc - 2; x=3Dx+2) { + argv[x] =3D argv[x+2]; + argv[x+1] =3D argv[x+3]; + } + *argc =3D *argc - 2; + } +} =20 /* ------------------------------------------------------ @@ -491,20 +558,27 @@ QemuCocoaView *cocoaView; int keycode; NSPoint p =3D [event locationInWindow]; =20 + // The key used to send QEMU commands (e.g. Quit, Full Screen). + // Change this if you don't like using the ALT key. + // Possible values: NSShiftKeyMask, NSControlKeyMask, = NSFunctionKeyMask, NSAlternateKeyMask + const int substituteKeyMask =3D NSAlternateKeyMask;=20 + =20 switch ([event type]) { case NSFlagsChanged: - keycode =3D cocoa_keycode_to_qemu([event keyCode]); + keycode =3D cocoa_keycode_to_qemu([event keyCode]); = =09 if (keycode) { if (keycode =3D=3D 58 || keycode =3D=3D 69) { // = emulate caps lock and num lock keydown and keyup kbd_put_keycode(keycode); kbd_put_keycode(keycode | 0x80); } else if (qemu_console_is_graphic(NULL)) { - if (keycode & 0x80) - kbd_put_keycode(0xe0); - if (modifiers_state[keycode] =3D=3D 0) { // keydown + if (keycode & 0x80) // if keycode >=3D 0x80, for = those keycodes that need a 0xe0 sent first=20 + { + kbd_put_keycode(0xe0); + } + if (modifiers_state[keycode] =3D=3D 0) { // = keydown kbd_put_keycode(keycode & 0x7f); modifiers_state[keycode] =3D 1; - } else { // keyup + } else { // keyup kbd_put_keycode(keycode | 0x80); modifiers_state[keycode] =3D 0; } @@ -516,17 +590,37 @@ QemuCocoaView *cocoaView; [self ungrabMouse]; } break; - case NSKeyDown: + case NSKeyDown: =09 + // if substituting for the host command key and the = substitute key is being held down - have QEMU handle it + if((substitutingForCommandKey =3D=3D true) && ([event = modifierFlags] & substituteKeyMask)) {=20 + // recreate the event with the command key as the = modifier + int modifiers =3D [event modifierFlags]; + modifiers =3D modifiers | NSCommandKeyMask; // set the = command key=20 + modifiers =3D modifiers ^ substituteKeyMask; // unset = the substitute key + + event =3D [NSEvent keyEventWithType: [event type] = location: [event locationInWindow] modifierFlags: modifiers + timestamp: [event timestamp] windowNumber: = [event windowNumber] context: [event context] characters: [event = characters]=20 + charactersIgnoringModifiers: [event = charactersIgnoringModifiers] isARepeat: [event isARepeat] keyCode: = [event keyCode] ]; + [NSApp sendEvent:event]; + return; + } =20 - // forward command Key Combos - if ([event modifierFlags] & NSCommandKeyMask) { + // if the command key is held down and we want QEMU to = handle the event - not the guest OS + else if([event modifierFlags] & NSCommandKeyMask && = substitutingForCommandKey =3D=3D false) { [NSApp sendEvent:event]; return; } =20 + // if the command key is held down and we want the guest OS = to handle it + if(([event modifierFlags] & NSCommandKeyMask) && = (substitutingForCommandKey =3D=3D true)) { + kbd_put_keycode(219); // command key + kbd_put_keycode(cocoa_keycode_to_qemu([event = keyCode])); // any other keys + return; + } + // default keycode =3D cocoa_keycode_to_qemu([event keyCode]); - + =09 // handle control + alt Key Combos (ctrl+alt is reserved = for QEMU) if (([event modifierFlags] & NSControlKeyMask) && ([event = modifierFlags] & NSAlternateKeyMask)) { switch (keycode) { @@ -584,7 +678,7 @@ QemuCocoaView *cocoaView; if (qemu_console_is_graphic(NULL)) { if (keycode & 0x80) kbd_put_keycode(0xe0); - kbd_put_keycode(keycode | 0x80); //add 128 to signal = release of key + kbd_put_keycode(keycode | 0x80); //add 128 (0x80) to = signal release of key } break; case NSMouseMoved: @@ -810,8 +904,9 @@ QemuCocoaView *cocoaView; - (void)startEmulationWithArgc:(int)argc argv:(char**)argv { COCOA_DEBUG("QemuCocoaAppController: startEmulationWithArgc\n"); - +=09 int status; + handleCommandKeyOption(&argc, argv); status =3D qemu_main(argc, argv, *_NSGetEnviron()); exit(status); } @@ -1047,3 +1142,5 @@ void cocoa_display_init(DisplayState *ds, int = full_screen) // register cleanup function atexit(cocoa_cleanup); } + + --=20 1.7.5.4