qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] ui/cocoa.m: Add Mount image file menu item


From: Markus Armbruster
Subject: Re: [Qemu-devel] [PATCH] ui/cocoa.m: Add Mount image file menu item
Date: Wed, 02 Sep 2015 11:05:02 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)

Cc'ing the maintainers you forgot.  scripts/get_maintainer.pl is your
friend.

Programmingkid <address@hidden> writes:

> Add "Mount Image File..." and a "Eject Image File" menu items to
> cocoa interface. This patch makes sharing files between the
> host and the guest user-friendly.
>
> The "Mount Image File..." menu item displays a dialog box having the
> user pick an image file to use in QEMU. The image file is setup as
> a USB flash drive. The user can do the equivalent of removing the
> flash drive by selecting the file in the "Eject Image File" submenu.
>
> Signed-off-by: John Arbuckle <address@hidden>
>
> ---
>  ui/cocoa.m |  212 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 210 insertions(+), 1 deletions(-)
>
> diff --git a/ui/cocoa.m b/ui/cocoa.m
> index 334e6f6..6c0ec18 100644
> --- a/ui/cocoa.m
> +++ b/ui/cocoa.m
> @@ -52,6 +52,9 @@
>  #endif
>  
>  #define cgrect(nsrect) (*(CGRect *)&(nsrect))
> +#define USB_DISK_ID "USB_DISK"
> +#define EJECT_IMAGE_FILE_TAG 2099
>  
>  typedef struct {
>      int width;
> @@ -263,6 +266,43 @@ static void handleAnyDeviceErrors(Error * err)
>      }
>  }
>  
> +/* Sends a command to the monitor console */
> +static void sendMonitorCommand(const char * commandString)
> +{
> +    int index;
> +    char * consoleName;
> +    static QemuConsole *monitor;
> +
> +    /* If the monitor console hasn't been found yet */
> +    if(!monitor) {
> +        index = 0;
> +        /* Find the monitor console */
> +        while (qemu_console_lookup_by_index(index) != NULL) {
> +            consoleName = 
> qemu_console_get_label(qemu_console_lookup_by_index(index));
> +            if(strstr(consoleName, "monitor")) {
> +                monitor = qemu_console_lookup_by_index(index);
> +                break;
> +            }
> +            index++;
> +        }
> +    }
> +
> +    /* If the monitor console was not found */
> +    if(!monitor) {
> +        NSBeep();
> +        QEMU_Alert(@"Failed to find the monitor console!");
> +        return;
> +    }
> +
> +    /* send each letter in the commandString to the monitor */
> +    for (index = 0; index < strlen(commandString); index++) {
> +        kbd_put_keysym_console(monitor, commandString[index]);
> +    }
> +
> +    /* simulate the user pushing the return key */
> +    kbd_put_keysym_console(monitor, '\n');
> +}
> +
>  /*
>   ------------------------------------------------------
>      QemuCocoaView
> @@ -585,6 +625,7 @@ QemuCocoaView *cocoaView;
>              // forward command key combos to the host UI unless the mouse is 
> grabbed
>              if (!isMouseGrabbed && ([event modifierFlags] & 
> NSCommandKeyMask)) {
>                  [NSApp sendEvent:event];
> +                printf("Returning\n");
>                  return;
>              }
>  
> @@ -829,6 +870,9 @@ QemuCocoaView *cocoaView;
>  - (void)powerDownQEMU:(id)sender;
>  - (void)ejectDeviceMedia:(id)sender;
>  - (void)changeDeviceMedia:(id)sender;
> +- (void)mountImageFile:(id)sender;
> +- (void)ejectImageFile:(id)sender;
> +- (void)updateEjectImageMenuItems;
>  @end
>  
>  @implementation QemuCocoaAppController
> @@ -1125,6 +1169,150 @@ QemuCocoaView *cocoaView;
>      }
>  }
>  
> +/* Displays a dialog box asking the user for an image file to mount */
> +- (void)mountImageFile:(id)sender
> +{
> +    /* Display the file open dialog */
> +    NSOpenPanel * openPanel;
> +    openPanel = [NSOpenPanel openPanel];
> +    [openPanel setCanChooseFiles: YES];
> +    [openPanel setAllowsMultipleSelection: NO];
> +    [openPanel setAllowedFileTypes: supportedImageFileTypes];
> +    if([openPanel runModal] == NSFileHandlingPanelOKButton) {
> +        NSString * file = [[[openPanel URLs] objectAtIndex: 0] path];
> +        if(file == nil) {
> +            NSBeep();
> +            QEMU_Alert(@"Failed to convert URL to file path!");
> +            return;
> +        }
> +
> +        static int usbDiskCount;  // used for the ID
> +        char *commandBuffer, *fileName, *idString, *fileNameHint;
> +        NSString *buffer;
> +        const int fileNameHintSize = 10;
> +
> +        fileName = g_strdup_printf("%s",
> +                            [file cStringUsingEncoding: 
> NSASCIIStringEncoding]);
> +        buffer = [file lastPathComponent];
> +        buffer = [buffer stringByDeletingPathExtension];
> +        if([buffer length] > fileNameHintSize) {
> +            buffer = [buffer substringToIndex: fileNameHintSize];
> +        }
> +        fileNameHint = g_strdup_printf("%s",
> +                        [buffer cStringUsingEncoding: 
> NSASCIIStringEncoding]);
> +        idString = g_strdup_printf("%s_%s_%d", USB_DISK_ID, fileNameHint, 
> usbDiskCount);
> +        commandBuffer = g_strdup_printf("drive_add 0 if=none,id=%s,file=%s",
> +                                                            idString, 
> fileName);
> +        sendMonitorCommand(commandBuffer);
> +        commandBuffer = g_strdup_printf("device_add usb-storage,"
> +                                         "id=%s,drive=%s", idString, 
> idString);
> +        sendMonitorCommand(commandBuffer);
> +        [self updateEjectImageMenuItems];
> +        usbDiskCount++;
> +        g_free(fileName);
> +        g_free(fileNameHint);
> +        g_free(idString);
> +        g_free(commandBuffer);
> +    }
> +}
> +
> +/* Removes an image file from QEMU */
> +- (void)ejectImageFile:(id) sender
> +{
> +    char *commandBuffer;
> +    NSString *imageFileID;
> +
> +    imageFileID = [sender representedObject];
> +    if (imageFileID == nil) {
> +        NSBeep();
> +        QEMU_Alert(@"Could not find image file's ID!");
> +        return;
> +    }
> +
> +    commandBuffer = g_strdup_printf("drive_del %s",
> +                    [imageFileID cStringUsingEncoding: 
> NSASCIIStringEncoding]);
> +    sendMonitorCommand(commandBuffer);
> +    g_free(commandBuffer);
> +
> +    commandBuffer = g_strdup_printf("device_del %s",
> +                        [imageFileID cStringUsingEncoding: 
> NSASCIIStringEncoding]);
> +    sendMonitorCommand(commandBuffer);
> +    g_free(commandBuffer);
> +
> +    [self updateEjectImageMenuItems];
> +}
> +
> +/* Gives each mounted image file an eject menu item */
> +- (void) updateEjectImageMenuItems
> +{
> +    NSMenu *machineMenu;
> +    machineMenu = [[[NSApp mainMenu] itemWithTitle:@"Machine"] submenu];
> +
> +    /* Remove old menu items*/
> +    NSMenu * ejectSubmenu;
> +    ejectSubmenu = [[machineMenu itemWithTag: EJECT_IMAGE_FILE_TAG] submenu];
> +    if(!ejectSubmenu) {
> +        NSBeep();
> +        QEMU_Alert(@"Failed to find eject submenu!");
> +        return;
> +    }
> +    int index;
> +    for (index = 0; index < [ejectSubmenu numberOfItems]; index++) {
> +        [ejectSubmenu removeItemAtIndex: 0];
> +    }
> +     /* Needed probably because of a bug with cocoa */
> +    if ([ejectSubmenu numberOfItems] > 0) {
> +        [ejectSubmenu removeItemAtIndex: 0];
> +    }
> +
> +    BlockInfoList *currentDevice;
> +    currentDevice = qmp_query_block(NULL);
> +
> +    NSString *fileName, *deviceName;
> +    NSMenuItem *ejectFileMenuItem;  /* Used with each mounted image file */
> +
> +    /* Look for mounted image files */
> +    while(currentDevice) {
> +        if (!currentDevice->value || !currentDevice->value->inserted
> +                                  || !currentDevice->value->inserted->file) {
> +            currentDevice = currentDevice->next;
> +            continue;
> +        }
> +
> +        /* if the device's name is the generated ID */
> +        if (!strstr(currentDevice->value->device, USB_DISK_ID)) {
> +            currentDevice = currentDevice->next;
> +            continue;
> +        }
> +
> +        fileName = [NSString stringWithFormat: @"%s", 
> currentDevice->value->inserted->file];
> +        fileName = [fileName lastPathComponent]; /* To obtain only the file 
> name */
> +
> +        ejectFileMenuItem = [[NSMenuItem alloc] initWithTitle: [NSString 
> stringWithFormat: @"Eject %@", fileName]
> +                                                  action: 
> @selector(ejectImageFile:)
> +                                           keyEquivalent: @""];
> +        [ejectSubmenu addItem: ejectFileMenuItem];
> +        deviceName = [NSString stringWithFormat: @"%s", 
> currentDevice->value->device];
> +        [ejectFileMenuItem setRepresentedObject: deviceName];
> +        [ejectFileMenuItem autorelease];
> +        currentDevice = currentDevice->next;
> +    }
> +
> +    /* Add default menu item if submenu is empty */
> +    if([ejectSubmenu numberOfItems] == 0) {
> +
> +        /* Create the default menu item */
> +        NSMenuItem *emptyMenuItem;
> +        emptyMenuItem = [NSMenuItem new];
> +        [emptyMenuItem setTitle: @"No items available"];
> +        [emptyMenuItem setEnabled: NO];
> +
> +        /* Add the default menu item to the submenu */
> +        [ejectSubmenu addItem: emptyMenuItem];
> +        [emptyMenuItem release];
> +    }
> +}
> +
>  @end
>  
>  
> @@ -1383,7 +1571,6 @@ static void addRemovableDevicesMenuItems()
>      /* Loop thru all the block devices in the emulator */
>      while (currentDevice) {
>          deviceName = [[NSString stringWithFormat: @"%s", 
> currentDevice->value->device] retain];
> -
>          if(currentDevice->value->removable) {
>              menuItem = [[NSMenuItem alloc] initWithTitle: [NSString 
> stringWithFormat: @"Change %s...", currentDevice->value->device]
>                                                    action: 
> @selector(changeDeviceMedia:)
> @@ -1402,6 +1589,29 @@ static void addRemovableDevicesMenuItems()
>          currentDevice = currentDevice->next;
>      }
>      qapi_free_BlockInfoList(pointerToFree);
> +    [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Mount Image 
> File..." action: @selector(mountImageFile:) keyEquivalent: @""] autorelease]];
> +
> +    /* Create the eject menu item */
> +    NSMenuItem *ejectMenuItem;
> +    ejectMenuItem = [NSMenuItem new];
> +    [ejectMenuItem setTitle: @"Eject Image File"];
> +    [ejectMenuItem setTag: EJECT_IMAGE_FILE_TAG];
> +    [menu addItem: ejectMenuItem];
> +    [ejectMenuItem autorelease];
> +
> +    /* Create the default menu item for the eject menu item's submenu*/
> +    NSMenuItem *emptyMenuItem;
> +    emptyMenuItem = [NSMenuItem new];
> +    [emptyMenuItem setTitle: @"No items available"];
> +    [emptyMenuItem setEnabled: NO];
> +    [emptyMenuItem autorelease];
> +
> +    /* Add the default menu item to the submenu */
> +    NSMenu *submenu;
> +    submenu = [NSMenu new];
> +    [ejectMenuItem setSubmenu: submenu];
> +    [submenu addItem: emptyMenuItem];
> +    [submenu autorelease];
>  }
>  
>  void cocoa_display_init(DisplayState *ds, int full_screen)



reply via email to

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