* [Qemu-devel] [PATCH] Adds the ability to use the command key in the guest OS.
@ 2013-07-12 20:41 Programmingkid
0 siblings, 0 replies; only message in thread
From: Programmingkid @ 2013-07-12 20:41 UTC (permalink / raw)
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.
signed-off-by: John Arbuckle <programmingkidx@gmail.com>
---
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
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2013-07-12 20:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-12 20:41 [Qemu-devel] [PATCH] Adds the ability to use the command key in the guest OS Programmingkid
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.