qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] Adds the ability to use the command key in the gues


From: Programmingkid
Subject: [Qemu-devel] [PATCH] Adds the ability to use the command key in the guest OS.
Date: Fri, 12 Jul 2013 16:41:48 -0400

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. 

signed-off-by: John Arbuckle <address@hidden>

---
 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;
 
 int gArgc;
 char **gArgv;
+bool substitutingForCommandKey = false; 
 
 // keymap conversion
 int keymap[] =
@@ -129,8 +130,8 @@ int keymap[] =
     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)
 }
 
 
+// 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 = false;
+       int newCommandKeyButtonValue, i;        
+
+       #define BUFFER_SIZE 10
+       #define LEFT_COMMAND_KEY 0x37
+       #define RIGHT_COMMAND_KEY 0x36
+       #define GUEST_COMMAND_KEY 219
+       
+       char keyValueString[BUFFER_SIZE];
+
+       for(i = 0; i < *argc; i++) {
+           if(strcmp(argv[i], "-command-key") == 0) {
+               foundOption = true;
+               break;
+           }
+       }
+
+       // if the -command-key option is found
+       if(foundOption == true)
+       {
+               snprintf(keyValueString, BUFFER_SIZE, "%s", argv[i+1]); 
+               if(strlen(keyValueString) == 0) {
+                       printf("Usage: -command-key <host keyboard key 
value>\n");
+                       printf("This page will help: 
http://boredzo.org/blog/wp-content/uploads/2007/05/imtx-virtual-keycodes.png\n";);
+                       exit(-1000);
+               }
+               
+               // if using hexadecimal notation (e.g. 0x37)
+               if(keyValueString[0] == '0' && toupper(keyValueString[1]) == 
'X') {
+                       sscanf(keyValueString, "%x", &newCommandKeyButtonValue);
+               }
+               
+               // for decimal notation
+               else {
+                       newCommandKeyButtonValue = atoi(keyValueString);
+               }
+               
+               //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);
+               }
+               
+               // if the guest OS command key is set to the host keyboard's 
left or right command key
+               if(newCommandKeyButtonValue == LEFT_COMMAND_KEY || 
newCommandKeyButtonValue == RIGHT_COMMAND_KEY) {
+                       substitutingForCommandKey = 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");
+               }
+               
+               // do the mapping
+               keymap[newCommandKeyButtonValue] = GUEST_COMMAND_KEY;
+               
+               // Remove -command-key from the argument list.
+               // QEMU will complain if we don't.
+               for(int x = i; x < *argc - 2; x=x+2) {
+                       argv[x] = argv[x+2];
+                       argv[x+1] = argv[x+3];
+               }
+               *argc = *argc - 2;
+       }
+}
 
 /*
  ------------------------------------------------------
@@ -491,20 +558,27 @@ QemuCocoaView *cocoaView;
     int keycode;
     NSPoint p = [event locationInWindow];
 
+    // 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 = NSAlternateKeyMask; 
+        
     switch ([event type]) {
         case NSFlagsChanged:
-            keycode = cocoa_keycode_to_qemu([event keyCode]);
+            keycode = cocoa_keycode_to_qemu([event keyCode]);                  
             if (keycode) {
                 if (keycode == 58 || keycode == 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] == 0) { // keydown
+                   if (keycode & 0x80)  // if keycode >= 0x80, for those 
keycodes that need a 0xe0 sent first 
+                   {
+                      kbd_put_keycode(0xe0);
+                   }
+                    if (modifiers_state[keycode] == 0) {     // keydown
                         kbd_put_keycode(keycode & 0x7f);
                         modifiers_state[keycode] = 1;
-                    } else { // keyup
+                    } else {                                 // keyup
                         kbd_put_keycode(keycode | 0x80);
                         modifiers_state[keycode] = 0;
                     }
@@ -516,17 +590,37 @@ QemuCocoaView *cocoaView;
                 [self ungrabMouse];
             }
             break;
-        case NSKeyDown:
+        case NSKeyDown:                                
+            // if substituting for the host command key and the substitute key 
is being held down - have QEMU handle it
+            if((substitutingForCommandKey == true) && ([event modifierFlags] & 
substituteKeyMask)) { 
+               // recreate the event with the command key as the modifier
+               int modifiers = [event modifierFlags];
+               modifiers = modifiers | NSCommandKeyMask;  // set the command 
key 
+               modifiers = modifiers ^ substituteKeyMask; // unset the 
substitute key
+
+               event = [NSEvent keyEventWithType: [event type] location: 
[event locationInWindow] modifierFlags: modifiers
+                       timestamp: [event timestamp] windowNumber: [event 
windowNumber] context: [event context] characters: [event characters] 
+                       charactersIgnoringModifiers: [event 
charactersIgnoringModifiers] isARepeat: [event isARepeat] keyCode: [event 
keyCode] ];
+               [NSApp sendEvent:event];
+               return;
+            }
 
-            // 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 == false) {
                 [NSApp sendEvent:event];
                 return;
             }
 
+            // if the command key is held down and we want the guest OS to 
handle it
+            if(([event modifierFlags] & NSCommandKeyMask) && 
(substitutingForCommandKey == true)) {
+                kbd_put_keycode(219); // command key
+                kbd_put_keycode(cocoa_keycode_to_qemu([event keyCode])); // 
any other keys
+                return;
+            }
+
             // default
             keycode = cocoa_keycode_to_qemu([event keyCode]);
-
+                               
             // 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");
-
+       
     int status;
+    handleCommandKeyOption(&argc, argv);
     status = 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);
 }
+
+
-- 
1.7.5.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]