diff mbox

[v3] cocoa.m: machine menu device menu items

Message ID AFD6E26A-8D1C-4346-BD02-F28B1D30124A@gmail.com
State New
Headers show

Commit Message

Programmingkid June 15, 2015, 1:53 a.m. UTC
Adds all removable devices to the Machine menu as a Change and Eject menu
item pair. ide-cd0 would have a "Change ide-cd0..." and "Eject ide-cd0"
menu items.

Signed-off-by: John Arbuckle <programmingkidx@gmail.com>

---
Removed depreciated code from QEMU_Alert().
Unified supported image file extensions into one array.
Replaced depreciated filename method for URLs method in NSOpenPanel code.
Replaced free() with qapi_free_BlockInfoList().

 ui/cocoa.m |  156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 153 insertions(+), 3 deletions(-)

Comments

Peter Maydell June 19, 2015, 9:42 a.m. UTC | #1
On 15 June 2015 at 02:53, Programmingkid <programmingkidx@gmail.com> wrote:
> Adds all removable devices to the Machine menu as a Change and Eject menu
> item pair. ide-cd0 would have a "Change ide-cd0..." and "Eject ide-cd0"
> menu items.
>
> Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
>
> ---
> Removed depreciated code from QEMU_Alert().
> Unified supported image file extensions into one array.
> Replaced depreciated filename method for URLs method in NSOpenPanel code.
> Replaced free() with qapi_free_BlockInfoList().

Thanks, applied to cocoa.next.

PS: it would be nice if you could get your mail client to send
plain text patches (ideally, just use git format-patch/git send-email).
Something about this one seems to confuse the "patches" tooling I use
to apply patches, though I think previous patches from you have been OK.

-- PMM
Programmingkid June 19, 2015, 5:12 p.m. UTC | #2
I have noticed a bug with the serial console. If text is printed to it that is longer than the window size, the text is cut off instead of being wrapped around. I have noticed this issue on QEMU 2.3.50 (just git pull'ed today). My host operating system is Mac OS 10.6.8. Has anyone noticed this issue on Linux or Windows?
diff mbox

Patch

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 559058b..5abbea7 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -30,6 +30,7 @@ 
 #include "ui/input.h"
 #include "sysemu/sysemu.h"
 #include "qmp-commands.h"
+#include "sysemu/blockdev.h"
 
 #ifndef MAC_OS_X_VERSION_10_5
 #define MAC_OS_X_VERSION_10_5 1050
@@ -67,6 +68,7 @@  int gArgc;
 char **gArgv;
 bool stretch_video;
 NSTextField *pauseLabel;
+NSArray * supportedImageFileTypes;
 
 // keymap conversion
 int keymap[] =
@@ -242,7 +244,24 @@  static int cocoa_keycode_to_qemu(int keycode)
     return keymap[keycode];
 }

+/* Displays an alert dialog box with the specified message */
+static void QEMU_Alert(NSString *message)
+{
+    NSAlert *alert;
+    alert = [NSAlert new];
+    [alert setMessageText: message];
+    [alert runModal];
+}
 
+/* Handles any errors that happen with a device transaction */
+static void handleAnyDeviceErrors(Error * err)
+{
+    if (err) {
+        QEMU_Alert([NSString stringWithCString: error_get_pretty(err)
+                                      encoding: NSASCIIStringEncoding]);
+        error_free(err);
+    }
+}
 
 /*
  ------------------------------------------------------
@@ -808,6 +827,8 @@  QemuCocoaView *cocoaView;
 - (void)removePause;
 - (void)restartQEMU:(id)sender;
 - (void)powerDownQEMU:(id)sender;
+- (void)ejectDeviceMedia:(id)sender;
+- (void)changeDeviceMedia:(id)sender;
 @end
 
 @implementation QemuCocoaAppController
@@ -854,6 +875,10 @@  QemuCocoaView *cocoaView;
         [pauseLabel setFont: [NSFont fontWithName: @"Helvetica" size: 90]];
         [pauseLabel setTextColor: [NSColor blackColor]];
         [pauseLabel sizeToFit];
+
+        // set the supported image file types that can be opened
+        supportedImageFileTypes = [NSArray arrayWithObjects: @"img", @"iso", @"dmg",
+                                 @"qcow", @"qcow2", @"cloop", @"vmdk", nil];
     }
     return self;
 }
@@ -877,10 +902,8 @@  QemuCocoaView *cocoaView;
         NSOpenPanel *op = [[NSOpenPanel alloc] init];
         [op setPrompt:@"Boot image"];
         [op setMessage:@"Select the disk image you want to boot.\n\nHit the \"Cancel\" button to quit"];
-        NSArray *filetypes = [NSArray arrayWithObjects:@"img", @"iso", @"dmg",
-                                 @"qcow", @"qcow2", @"cloop", @"vmdk", nil];
 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
-        [op setAllowedFileTypes:filetypes];
+        [op setAllowedFileTypes:supportedImageFileTypes];
         [op beginSheetModalForWindow:normalWindow
             completionHandler:^(NSInteger returnCode)
             { [self openPanelDidEnd:op
@@ -1047,6 +1070,61 @@  QemuCocoaView *cocoaView;
     qmp_system_powerdown(NULL);
 }
 
+/* Ejects the media.
+ * Uses sender's tag to figure out the device to eject.
+ */
+- (void)ejectDeviceMedia:(id)sender
+{
+    NSString * drive;
+    drive = [sender representedObject];
+    if(drive == nil) {
+        NSBeep();
+        QEMU_Alert(@"Failed to find drive to eject!");
+        return;
+    }
+
+    Error *err = NULL;
+    qmp_eject([drive cStringUsingEncoding: NSASCIIStringEncoding], false, false, &err);
+    handleAnyDeviceErrors(err);
+}
+
+/* Displays a dialog box asking the user to select an image file to load.
+ * Uses sender's represented object value to figure out which drive to use.
+ */
+- (void)changeDeviceMedia:(id)sender
+{
+    /* Find the drive name */
+    NSString * drive;
+    drive = [sender representedObject];
+    if(drive == nil) {
+        NSBeep();
+        QEMU_Alert(@"Could not find drive!");
+        return;
+    }
+
+    /* 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;
+        }
+
+        Error *err = NULL;
+        qmp_change_blockdev([drive cStringUsingEncoding: NSASCIIStringEncoding],
+                            [file cStringUsingEncoding: NSASCIIStringEncoding],
+                            "raw",
+                            &err);
+        handleAnyDeviceErrors(err);
+    }
+}
+
 @end
 
 
@@ -1260,6 +1338,72 @@  static void add_console_menu_entries(void)
     }
 }
 
+/* Make menu items for all removable devices.
+ * Each device is given an 'Eject' and 'Change' menu item.
+ */
+static void addRemovableDevicesMenuItems()
+{
+    NSMenu *menu;
+    NSMenuItem *menuItem;
+    BlockInfoList *currentDevice, *pointerToFree;
+    NSString *deviceName;
+
+    currentDevice = qmp_query_block(NULL);
+    pointerToFree = currentDevice;
+    if(currentDevice == NULL) {
+        NSBeep();
+        QEMU_Alert(@"Failed to query for block devices!");
+        return;
+    }
+
+    menu = [[[NSApp mainMenu] itemWithTitle:@"Machine"] submenu];
+
+    // Add a separator between related groups of menu items
+    [menu addItem:[NSMenuItem separatorItem]];
+
+    // Set the attributes to the "Removable Media" menu item
+    NSString *titleString = @"Removable Media";
+    NSMutableAttributedString *attString=[[NSMutableAttributedString alloc] initWithString:titleString];
+    NSColor *newColor = [NSColor blackColor];
+    NSFontManager *fontManager = [NSFontManager sharedFontManager];
+    NSFont *font = [fontManager fontWithFamily:@"Helvetica"
+                                          traits:NSBoldFontMask|NSItalicFontMask
+                                          weight:0
+                                            size:14];
+    [attString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, [titleString length])];
+    [attString addAttribute:NSForegroundColorAttributeName value:newColor range:NSMakeRange(0, [titleString length])];
+    [attString addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInt: 1] range:NSMakeRange(0, [titleString length])];
+
+    // Add the "Removable Media" menu item
+    menuItem = [NSMenuItem new];
+    [menuItem setAttributedTitle: attString];
+    [menuItem setEnabled: NO];
+    [menu addItem: menuItem];
+
+    /* 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:)
+                                           keyEquivalent: @""];
+            [menu addItem: menuItem];
+            [menuItem setRepresentedObject: deviceName];
+            [menuItem autorelease];
+
+            menuItem = [[NSMenuItem alloc] initWithTitle: [NSString stringWithFormat: @"Eject %s", currentDevice->value->device]
+                                                  action: @selector(ejectDeviceMedia:)
+                                           keyEquivalent: @""];
+            [menu addItem: menuItem];
+            [menuItem setRepresentedObject: deviceName];
+            [menuItem autorelease];
+        }
+        currentDevice = currentDevice->next;
+    }
+    qapi_free_BlockInfoList(pointerToFree);
+}
+
 void cocoa_display_init(DisplayState *ds, int full_screen)
 {
     COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n");
@@ -1283,4 +1427,10 @@  void cocoa_display_init(DisplayState *ds, int full_screen)
      * menu entries for them.
      */
     add_console_menu_entries();
+
+    /* Give all removable devices a menu item.
+     * Has to be called after QEMU has started to
+     * find out what removable devices it has.
+     */
+    addRemovableDevicesMenuItems();
 }