diff mbox

Add support for a Send Key menu.

Message ID B84B24EF-5913-4D67-84F4-562E14E6290E@gmail.com
State New
Headers show

Commit Message

Programmingkid July 11, 2016, 10:20 p.m. UTC
Add a menu called "Send Key". It is populated with options the user supplies at
runtime. The option works like this: -sendkeymenu <title>:<key values>. The
title can be anything you want. The values are the hexadecimal values for the
keycodes. The title is added to the menu as an menu item. The keycodes are sent
to QEMU.

Example: -sendkeymenu Command-Option-Esc:0x37,0x3a,0x35:Command-Power:0x37,0x7f7f

Two menu items would be added to the "Send Key" menu with this example.

This feature could be used to send Control-Alt-Delete to a Windows guest. It can
also be used to send Command-Power keys to a Mac OS 9 guest to display Macsbugs. 
The user can decide what menu items to place in this menu. If the user doesn't
use this feature the "Send Key" menu is not displayed.

Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
---
 ui/cocoa.m | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

Comments

Peter Maydell July 11, 2016, 10:28 p.m. UTC | #1
On 11 July 2016 at 23:20, Programmingkid <programmingkidx@gmail.com> wrote:
> Add a menu called "Send Key". It is populated with options the user supplies at
> runtime. The option works like this: -sendkeymenu <title>:<key values>. The
> title can be anything you want. The values are the hexadecimal values for the
> keycodes. The title is added to the menu as an menu item. The keycodes are sent
> to QEMU.
>
> Example: -sendkeymenu Command-Option-Esc:0x37,0x3a,0x35:Command-Power:0x37,0x7f7f
>
> Two menu items would be added to the "Send Key" menu with this example.
>
> This feature could be used to send Control-Alt-Delete to a Windows guest. It can
> also be used to send Command-Power keys to a Mac OS 9 guest to display Macsbugs.
> The user can decide what menu items to place in this menu. If the user doesn't
> use this feature the "Send Key" menu is not displayed.

Do we have this feature in any of our other front end UIs?
I don't really want to get into adding features to the Cocoa
UI frontend that don't exist anywhere else. (We've had this
discussion before, I think.)

thanks
-- PMM
Programmingkid July 11, 2016, 10:31 p.m. UTC | #2
On Jul 11, 2016, at 6:28 PM, Peter Maydell wrote:

> On 11 July 2016 at 23:20, Programmingkid <programmingkidx@gmail.com> wrote:
>> Add a menu called "Send Key". It is populated with options the user supplies at
>> runtime. The option works like this: -sendkeymenu <title>:<key values>. The
>> title can be anything you want. The values are the hexadecimal values for the
>> keycodes. The title is added to the menu as an menu item. The keycodes are sent
>> to QEMU.
>> 
>> Example: -sendkeymenu Command-Option-Esc:0x37,0x3a,0x35:Command-Power:0x37,0x7f7f
>> 
>> Two menu items would be added to the "Send Key" menu with this example.
>> 
>> This feature could be used to send Control-Alt-Delete to a Windows guest. It can
>> also be used to send Command-Power keys to a Mac OS 9 guest to display Macsbugs.
>> The user can decide what menu items to place in this menu. If the user doesn't
>> use this feature the "Send Key" menu is not displayed.
> 
> Do we have this feature in any of our other front end UIs?
> I don't really want to get into adding features to the Cocoa
> UI frontend that don't exist anywhere else. (We've had this
> discussion before, I think.)

When a feature is added that doesn't exist before, it is called innovation :)

It would make things easier on the people working on Mac OS 9 support.
Peter Maydell July 11, 2016, 10:44 p.m. UTC | #3
On 11 July 2016 at 23:31, Programmingkid <programmingkidx@gmail.com> wrote:
> On Jul 11, 2016, at 6:28 PM, Peter Maydell wrote:
>> Do we have this feature in any of our other front end UIs?
>> I don't really want to get into adding features to the Cocoa
>> UI frontend that don't exist anywhere else. (We've had this
>> discussion before, I think.)
>
> When a feature is added that doesn't exist before, it is called innovation :)

http://lists.gnu.org/archive/html/qemu-devel/2015-10/msg00239.html
is our previous discussion on this.

The situation here hasn't changed at all in the
intervening nine months.

thanks
-- PMM
Programmingkid July 11, 2016, 11:20 p.m. UTC | #4
On Jul 11, 2016, at 6:44 PM, Peter Maydell wrote:

> On 11 July 2016 at 23:31, Programmingkid <programmingkidx@gmail.com> wrote:
>> On Jul 11, 2016, at 6:28 PM, Peter Maydell wrote:
>>> Do we have this feature in any of our other front end UIs?
>>> I don't really want to get into adding features to the Cocoa
>>> UI frontend that don't exist anywhere else. (We've had this
>>> discussion before, I think.)
>> 
>> When a feature is added that doesn't exist before, it is called innovation :)
> 
> http://lists.gnu.org/archive/html/qemu-devel/2015-10/msg00239.html
> is our previous discussion on this.
> 
> The situation here hasn't changed at all in the
> intervening nine months.
> 
> thanks
> -- PMM

Ok. It was worth a try.
diff mbox

Patch

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 36c6bf0..9fa9cc5 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -824,6 +824,7 @@  QemuCocoaView *cocoaView;
 - (void)changeDeviceMedia:(id)sender;
 - (BOOL)verifyQuit;
 - (void)openDocumentation:(NSString *)filename;
+- (IBAction)do_send_key_menu_item:(id)sender;
 @end
 
 @implementation QemuCocoaAppController
@@ -1138,8 +1139,110 @@  QemuCocoaView *cocoaView;
     }
 }
 
+/* The action method to the items in the Send Keys menu */
+- (IBAction)do_send_key_menu_item:(id)sender {
+    NSString *keys = [sender representedObject];
+    NSArray *key_array = [keys componentsSeparatedByString: @","];
+    #define array_size 0xff
+    int keydown_array[array_size] = {0};
+    int index, keycode;
+    NSString *hex_string;
+
+    for (index = 0; index < [key_array count]; index++) {
+        hex_string = [key_array objectAtIndex: index];
+        sscanf([hex_string cStringUsingEncoding: NSASCIIStringEncoding], "%x",
+               &keycode);
+        keycode = cocoa_keycode_to_qemu(keycode);
+        qemu_input_event_send_key_qcode(dcl->con, keycode, true);
+        keydown_array[keycode] = 1;
+    }
+
+    /* Send keyup event for all keys that were sent */
+    for (index = 0; index < array_size; index++) {
+        if (keydown_array[index] != 0) {
+            qemu_input_event_send_key_qcode(dcl->con, index, false);
+        }
+    }
+}
+
 @end
 
+/* Determines if '-sendkeymenu' is in the arguments sent to QEMU */
+static int send_key_support(void) {
+    int index;
+    for (index = 0; index < gArgc; index++) {
+        if (strcmp("-sendkeymenu", gArgv[index]) == 0) {
+            return true;
+        }
+    }
+    return false;
+}
+
+/* Remove one of the options from the global variable gArgv */
+static void remove_option(int index)
+{
+    if (index < 0) {
+        printf("Error: remove_option(): index less than zero: %d\n", index);
+        return;
+    } else if (index >= gArgc) {
+        printf("Error: remove_option(): index too big: %d\n", index);
+        return;
+    }
+    gArgc--;
+    /* copy everything from index + 1 to the end */
+    for (; index < gArgc; index++) {
+        gArgv[index] = gArgv[index+1];
+    }
+}
+
+/* Creates the Send Key menu and populates it */
+static void create_send_key_menu(void) {
+    NSMenu *menu;
+    menu = [[NSMenu alloc] initWithTitle:@"Send Key"];
+
+    /* Find the index of the sendkeymenu and its items */
+    int send_key_index = -1;
+    int index;
+    for (index = 0; index < gArgc; index++) {
+        if (strcmp("-sendkeymenu", gArgv[index]) == 0) {
+            send_key_index = index;
+            break;
+        }
+    }
+
+    /* if failed to find the -sendkeymenu argument */
+    if (send_key_index == -1) {
+        printf("Failed to find 'sendkeymenu' arguments\n");
+        exit(EXIT_FAILURE);
+    }
+
+    NSMenuItem *menu_item;
+    char *token;
+    token = strtok(gArgv[send_key_index+1], ":");
+
+    /* loop thru each set of keys */
+    while (token) {
+        menu_item = [[[NSMenuItem alloc] initWithTitle: [NSString stringWithCString: token encoding:NSASCIIStringEncoding]
+                                                action: @selector(do_send_key_menu_item:)
+                                         keyEquivalent: @""] autorelease];
+        [menu addItem: menu_item];
+        token = strtok(NULL, ":");
+
+        [menu_item setRepresentedObject: [NSString stringWithCString: token encoding: NSASCIIStringEncoding]];
+        token = strtok(NULL, ":");
+    }
+
+    /* Add the menu to QEMU's menubar */
+    menu_item = [[[NSMenuItem alloc] initWithTitle: @"Send Key"
+                                            action:nil
+                                     keyEquivalent:@""] autorelease];
+    [menu_item setSubmenu:menu];
+    [[NSApp mainMenu] addItem:menu_item];
+
+    /* Remove the -sendkeymenu and related options from the global variable */
+    remove_option(send_key_index);
+    remove_option(send_key_index);
+}
 
 int main (int argc, const char * argv[]) {
 
@@ -1212,6 +1315,11 @@  int main (int argc, const char * argv[]) {
     [menuItem setSubmenu:menu];
     [[NSApp mainMenu] addItem:menuItem];
 
+    // Send Key menu
+    if (send_key_support()) {
+        create_send_key_menu();
+    }
+
     // View menu
     menu = [[NSMenu alloc] initWithTitle:@"View"];
     [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Enter Fullscreen" action:@selector(doToggleFullScreen:) keyEquivalent:@"f"] autorelease]]; // Fullscreen