Cc'ing the maintainers you forgot. scripts/get_maintainer.pl is your friend.
Programmingkid <programmingk...@gmail.com> 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 <programmingk...@gmail.com> > > --- > 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)