diff mbox

Machine menu patch for Mac OS X

Message ID 1B8AA8D9-61F0-4FE2-A0DF-A3321FBD72AB@gmail.com
State New
Headers show

Commit Message

Programmingkid Jan. 13, 2015, 1:49 a.m. UTC
This patch adds a Machine menu to QEMU. This menu gives the user the ability to easily work with floppy and CD image files.

Features:
Menu items to switch floppy and CD image files.
Menu items to eject floppy and CD image files.
Menu item to use /dev/cdrom. 
Verifies with the user before quitting QEMU by displaying a dialog box. 

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

---
 ui/cocoa.m |  129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 127 insertions(+), 2 deletions(-)

Comments

Peter Maydell Jan. 14, 2015, 5:42 p.m. UTC | #1
On 13 January 2015 at 01:49, Programmingkid <programmingkidx@gmail.com> wrote:
> This patch adds a Machine menu to QEMU. This menu gives the user the ability to easily work with floppy and CD image files.
>
> Features:
> Menu items to switch floppy and CD image files.
> Menu items to eject floppy and CD image files.
> Menu item to use /dev/cdrom.
> Verifies with the user before quitting QEMU by displaying a dialog box.
>
> Signed-off-by: John Arbuckle <programmingkidx@gmail.com>

Hi. I'm afraid I couldn't get this patch to apply -- is it dependent
on one of your other patches?

Some comments below, anyway.

> +/* Pause the guest */
> +- (void)pauseQemu:(id)sender
> +{
> +    qmp_stop(NULL);
> +    [sender setEnabled: NO];
> +    [[[sender menu] itemWithTitle: @"Resume"] setEnabled: YES];
> +    [normalWindow setTitle: @"*** Paused ***"];
> +}
> +
> +/* Resume running the guest operating system */
> +- (void)resumeQemu: (id) sender
> +{
> +    qmp_cont(NULL);
> +    [sender setEnabled: NO];
> +    [[[sender menu] itemWithTitle: @"Pause"] setEnabled: YES];
> +    [normalWindow setTitle: @"QEMU"];

Isn't this changing of the title string going to conflict with the
changes that we make for mouse grab/ungrab?

> +}
> +
> +/* Eject the floppy0 disk */
> +- (void)ejectFloppy:(id)sender
> +{
> +    Error *err = NULL;
> +    qmp_eject("floppy0", false, false, &err);
> +    handleAnyDeviceErrors(err);
> +}
> +
> +/* Displays a dialog box asking the user to select a floppy image to load */
> +- (void)changeFloppy:(id)sender
> +{
> +    NSOpenPanel * open_panel;
> +    open_panel = [NSOpenPanel openPanel];
> +    [open_panel setCanChooseFiles: YES];
> +    [open_panel setAllowsMultipleSelection: NO];
> +    if([open_panel runModalForDirectory: nil file: nil] == NSOKButton) {
> +        Error *err = NULL;
> +        NSString * file = [[open_panel filenames] objectAtIndex: 0];
> +        qmp_change_blockdev("floppy0", [file cString], "raw", &err);
> +        handleAnyDeviceErrors(err);
> +    }
> +}

You don't know that the machine being emulated has a floppy drive
at all, or that it's called "floppy0"...

> +
> +// Ejects the cdrom
> +- (void)ejectCdrom:(id)sender
> +{
> +    Error *err = NULL;
> +    qmp_eject("ide1-cd0", false, false, &err);
> +    handleAnyDeviceErrors(err);
> +}
> +
> +/* Displays a dialog box asking the user to select a CD image to load */
> +- (void)changeCdrom:(id)sender
> +{
> +    NSOpenPanel * open_panel;
> +    open_panel = [NSOpenPanel openPanel];
> +    [open_panel setCanChooseFiles: YES];
> +    [open_panel setAllowsMultipleSelection: NO];
> +    if([open_panel runModalForDirectory: nil file: nil] == NSOKButton) {
> +        NSString * file = [[open_panel filenames] objectAtIndex: 0];
> +        Error *err = NULL;
> +        qmp_change_blockdev("ide1-cd0", [file cString], "raw", &err);
> +        handleAnyDeviceErrors(err);
> +    }
> +}

Similarly, the CD may not exist in the guest machine or may
not be called "ide1-cd0".

> +
> +/* Restarts QEMU */
> +- (void)restartQemu: (id) sender
> +{
> +    qemu_system_reset_request();
> +}
> +
> +/* Switches QEMU to use the real cdrom drive */
> +- (void)useRealCdrom: (id) sender
> +{
> +    Error *err = NULL;
> +    qmp_change_blockdev("ide1-cd0", "/dev/cdrom", "raw", &err);
> +    handleAnyDeviceErrors(err);
> +}
> +
> +/* Verifies if the user really wants to quit */
> +- (void)verifyQuit: (id) sender
> +{
> +    NSInteger response;
> +    response = NSRunAlertPanel(@"Quit?", @"Are you sure you want to quit?", @"Cancel", @"Quit", nil);

We don't have an are-you-sure prompt for closing the QEMU window via
the red button, and we don't for the Quit menu option in the GTK UI either...

> +    if(response == NSAlertAlternateReturn)
> +        exit(EXIT_SUCCESS);

You should use qmp_quit(NULL) rather than just exit().

> +}
> +
>  @end
>
>
> @@ -1046,7 +1153,7 @@ int main (int argc, const char * argv[]) {
>      [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
>      [menu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; // Show All
>      [menu addItem:[NSMenuItem separatorItem]]; //Separator
> -    [menu addItemWithTitle:@"Quit QEMU" action:@selector(terminate:) keyEquivalent:@"q"];
> +    [menu addItemWithTitle:@"Quit QEMU" action:@selector(verifyQuit:) keyEquivalent:@"q"];
>      menuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" action:nil keyEquivalent:@""];
>      [menuItem setSubmenu:menu];
>      [[NSApp mainMenu] addItem:menuItem];
> @@ -1059,6 +1166,24 @@ int main (int argc, const char * argv[]) {
>      [menuItem setSubmenu:menu];
>      [[NSApp mainMenu] addItem:menuItem];
>
> +    /* Machine menu */
> +     menu = [[NSMenu alloc] initWithTitle: @"Machine"];
> +     [menu setAutoenablesItems: NO];
> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Pause" action: @selector(pauseQemu:) keyEquivalent: @""] autorelease]];
> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Resume" action: @selector(resumeQemu:) keyEquivalent: @""] autorelease]];
> +     [menu addItem: [NSMenuItem separatorItem]];
> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Eject Floppy" action: @selector(ejectFloppy:) keyEquivalent: @""] autorelease]];
> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Change Floppy..." action: @selector(changeFloppy:) keyEquivalent: @""] autorelease]];
> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Eject cdrom" action: @selector(ejectCdrom:) keyEquivalent: @""] autorelease]];
> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Use cdrom image..." action: @selector(changeCdrom:) keyEquivalent: @""] autorelease]];
> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Use real cdrom drive" action: @selector(useRealCdrom:) keyEquivalent: @""] autorelease]];
> +     [menu addItem: [NSMenuItem separatorItem]];
> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Restart" action: @selector(restartQemu:) keyEquivalent: @""] autorelease]];

In the GTK UI we call this "Reset". We also have a "Power Down" which would
probably be nice for consistency.

> +     menuItem = [[[NSMenuItem alloc] initWithTitle: @"Machine" action:nil keyEquivalent:@""] autorelease];
> +    [menuItem setSubmenu:menu];
> +    [[NSApp mainMenu] addItem:menuItem];
> +        [[menu itemWithTitle: @"Resume"] setEnabled: NO];
> +
>      // Window menu
>      menu = [[NSMenu alloc] initWithTitle:@"Window"];
>      [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"] autorelease]]; // Miniaturize
> @@ -1168,7 +1293,7 @@ void cocoa_display_init(DisplayState *ds, int full_screen)
>          [NSApp activateIgnoringOtherApps: YES];
>          [[[NSApplication sharedApplication] delegate] toggleFullScreen: nil];
>      }
> -
> +
>      dcl = g_malloc0(sizeof(DisplayChangeListener));
>
>      // register vga output callbacks

Stray whitespace change.

thanks
-- PMM
Programmingkid Jan. 14, 2015, 6:34 p.m. UTC | #2
On Jan 14, 2015, at 12:42 PM, Peter Maydell wrote:

> On 13 January 2015 at 01:49, Programmingkid <programmingkidx@gmail.com> wrote:
>> This patch adds a Machine menu to QEMU. This menu gives the user the ability to easily work with floppy and CD image files.
>> 
>> Features:
>> Menu items to switch floppy and CD image files.
>> Menu items to eject floppy and CD image files.
>> Menu item to use /dev/cdrom.
>> Verifies with the user before quitting QEMU by displaying a dialog box.
>> 
>> Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
> 
> Hi. I'm afraid I couldn't get this patch to apply -- is it dependent
> on one of your other patches?

I have been making a lot of changes to cocoa.m. Can you suggest a way to make these changes not interfere with each other?

> 
> Some comments below, anyway.
> 
>> +/* Pause the guest */
>> +- (void)pauseQemu:(id)sender
>> +{
>> +    qmp_stop(NULL);
>> +    [sender setEnabled: NO];
>> +    [[[sender menu] itemWithTitle: @"Resume"] setEnabled: YES];
>> +    [normalWindow setTitle: @"*** Paused ***"];
>> +}
>> +
>> +/* Resume running the guest operating system */
>> +- (void)resumeQemu: (id) sender
>> +{
>> +    qmp_cont(NULL);
>> +    [sender setEnabled: NO];
>> +    [[[sender menu] itemWithTitle: @"Pause"] setEnabled: YES];
>> +    [normalWindow setTitle: @"QEMU"];
> 
> Isn't this changing of the title string going to conflict with the
> changes that we make for mouse grab/ungrab?

Unfortunately yes, but I still need a way to alert the user that QEMU is paused. I guess I could find a way to make both messages show up in the titlebar. Or I could display a message in the main window that says "Paused". Will come up with something soon.

> 
>> +}
>> +
>> +/* Eject the floppy0 disk */
>> +- (void)ejectFloppy:(id)sender
>> +{
>> +    Error *err = NULL;
>> +    qmp_eject("floppy0", false, false, &err);
>> +    handleAnyDeviceErrors(err);
>> +}
>> +
>> +/* Displays a dialog box asking the user to select a floppy image to load */
>> +- (void)changeFloppy:(id)sender
>> +{
>> +    NSOpenPanel * open_panel;
>> +    open_panel = [NSOpenPanel openPanel];
>> +    [open_panel setCanChooseFiles: YES];
>> +    [open_panel setAllowsMultipleSelection: NO];
>> +    if([open_panel runModalForDirectory: nil file: nil] == NSOKButton) {
>> +        Error *err = NULL;
>> +        NSString * file = [[open_panel filenames] objectAtIndex: 0];
>> +        qmp_change_blockdev("floppy0", [file cString], "raw", &err);
>> +        handleAnyDeviceErrors(err);
>> +    }
>> +}
> 
> You don't know that the machine being emulated has a floppy drive
> at all, or that it's called "floppy0"...

I did only use the PC and Mac targets. I know there are others. It looks like conditionally adding some of these menu items will have to do. I guess detecting if the guest machine has a floppy and/or cdrom drive can be done - hopefully...


> 
>> +
>> +// Ejects the cdrom
>> +- (void)ejectCdrom:(id)sender
>> +{
>> +    Error *err = NULL;
>> +    qmp_eject("ide1-cd0", false, false, &err);
>> +    handleAnyDeviceErrors(err);
>> +}
>> +
>> +/* Displays a dialog box asking the user to select a CD image to load */
>> +- (void)changeCdrom:(id)sender
>> +{
>> +    NSOpenPanel * open_panel;
>> +    open_panel = [NSOpenPanel openPanel];
>> +    [open_panel setCanChooseFiles: YES];
>> +    [open_panel setAllowsMultipleSelection: NO];
>> +    if([open_panel runModalForDirectory: nil file: nil] == NSOKButton) {
>> +        NSString * file = [[open_panel filenames] objectAtIndex: 0];
>> +        Error *err = NULL;
>> +        qmp_change_blockdev("ide1-cd0", [file cString], "raw", &err);
>> +        handleAnyDeviceErrors(err);
>> +    }
>> +}
> 
> Similarly, the CD may not exist in the guest machine or may
> not be called "ide1-cd0".

Ok, will find some way to determine what the CDROM drive is called - if that is possible...

> 
>> +
>> +/* Restarts QEMU */
>> +- (void)restartQemu: (id) sender
>> +{
>> +    qemu_system_reset_request();
>> +}
>> +
>> +/* Switches QEMU to use the real cdrom drive */
>> +- (void)useRealCdrom: (id) sender
>> +{
>> +    Error *err = NULL;
>> +    qmp_change_blockdev("ide1-cd0", "/dev/cdrom", "raw", &err);
>> +    handleAnyDeviceErrors(err);
>> +}
>> +
>> +/* Verifies if the user really wants to quit */
>> +- (void)verifyQuit: (id) sender
>> +{
>> +    NSInteger response;
>> +    response = NSRunAlertPanel(@"Quit?", @"Are you sure you want to quit?", @"Cancel", @"Quit", nil);
> 
> We don't have an are-you-sure prompt for closing the QEMU window via
> the red button, and we don't for the Quit menu option in the GTK UI either...

A prompt can be added to the close "red" button. As for GTK, we are allowed to be better than them. It really stinks when I'm working on something in the guest and I push Command-Q thinking it will only quit the one application I am working on, but instead takes out the entire emulator. I'm hoping that prompt will save someone from having a really bad day. 

> 
>> +    if(response == NSAlertAlternateReturn)
>> +        exit(EXIT_SUCCESS);
> 
> You should use qmp_quit(NULL) rather than just exit().

Not a problem.

> 
>> +}
>> +
>> @end
>> 
>> 
>> @@ -1046,7 +1153,7 @@ int main (int argc, const char * argv[]) {
>>     [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
>>     [menu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; // Show All
>>     [menu addItem:[NSMenuItem separatorItem]]; //Separator
>> -    [menu addItemWithTitle:@"Quit QEMU" action:@selector(terminate:) keyEquivalent:@"q"];
>> +    [menu addItemWithTitle:@"Quit QEMU" action:@selector(verifyQuit:) keyEquivalent:@"q"];
>>     menuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" action:nil keyEquivalent:@""];
>>     [menuItem setSubmenu:menu];
>>     [[NSApp mainMenu] addItem:menuItem];
>> @@ -1059,6 +1166,24 @@ int main (int argc, const char * argv[]) {
>>     [menuItem setSubmenu:menu];
>>     [[NSApp mainMenu] addItem:menuItem];
>> 
>> +    /* Machine menu */
>> +     menu = [[NSMenu alloc] initWithTitle: @"Machine"];
>> +     [menu setAutoenablesItems: NO];
>> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Pause" action: @selector(pauseQemu:) keyEquivalent: @""] autorelease]];
>> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Resume" action: @selector(resumeQemu:) keyEquivalent: @""] autorelease]];
>> +     [menu addItem: [NSMenuItem separatorItem]];
>> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Eject Floppy" action: @selector(ejectFloppy:) keyEquivalent: @""] autorelease]];
>> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Change Floppy..." action: @selector(changeFloppy:) keyEquivalent: @""] autorelease]];
>> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Eject cdrom" action: @selector(ejectCdrom:) keyEquivalent: @""] autorelease]];
>> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Use cdrom image..." action: @selector(changeCdrom:) keyEquivalent: @""] autorelease]];
>> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Use real cdrom drive" action: @selector(useRealCdrom:) keyEquivalent: @""] autorelease]];
>> +     [menu addItem: [NSMenuItem separatorItem]];
>> +     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Restart" action: @selector(restartQemu:) keyEquivalent: @""] autorelease]];
> 
> In the GTK UI we call this "Reset". We also have a "Power Down" which would
> probably be nice for consistency.

Changing Restart to Reset will be done. I don't know how to implement "Power Down", so I'm not sure about that one.

> 
>> +     menuItem = [[[NSMenuItem alloc] initWithTitle: @"Machine" action:nil keyEquivalent:@""] autorelease];
>> +    [menuItem setSubmenu:menu];
>> +    [[NSApp mainMenu] addItem:menuItem];
>> +        [[menu itemWithTitle: @"Resume"] setEnabled: NO];
>> +
>>     // Window menu
>>     menu = [[NSMenu alloc] initWithTitle:@"Window"];
>>     [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"] autorelease]]; // Miniaturize
>> @@ -1168,7 +1293,7 @@ void cocoa_display_init(DisplayState *ds, int full_screen)
>>         [NSApp activateIgnoringOtherApps: YES];
>>         [[[NSApplication sharedApplication] delegate] toggleFullScreen: nil];
>>     }
>> -
>> +
>>     dcl = g_malloc0(sizeof(DisplayChangeListener));
>> 
>>     // register vga output callbacks
> 
> Stray whitespace change.

Sorry for that. 

Do you think anyone will ever make SDL or GTK UIs for QEMU work on Mac OS X?
Peter Maydell Jan. 14, 2015, 6:42 p.m. UTC | #3
On 14 January 2015 at 18:34, Programmingkid <programmingkidx@gmail.com> wrote:
>
> On Jan 14, 2015, at 12:42 PM, Peter Maydell wrote:
>
>> On 13 January 2015 at 01:49, Programmingkid <programmingkidx@gmail.com> wrote:
>>> This patch adds a Machine menu to QEMU. This menu gives the user the ability to easily work with floppy and CD image files.
>>>
>>> Features:
>>> Menu items to switch floppy and CD image files.
>>> Menu items to eject floppy and CD image files.
>>> Menu item to use /dev/cdrom.
>>> Verifies with the user before quitting QEMU by displaying a dialog box.
>>>
>>> Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
>>
>> Hi. I'm afraid I couldn't get this patch to apply -- is it dependent
>> on one of your other patches?
>
> I have been making a lot of changes to cocoa.m. Can you suggest a way
> to make these changes not interfere with each other?

It can be hard to avoid in that kind of situation. Sometimes the
best you can do is just to say which patches it depends on.


>> Isn't this changing of the title string going to conflict with the
>> changes that we make for mouse grab/ungrab?
>
> Unfortunately yes, but I still need a way to alert the user that QEMU
> is paused. I guess I could find a way to make both messages show up
> in the titlebar. Or I could display a message in the main window that
> says "Paused". Will come up with something soon.

ui/gtk.c has a 'gd_update_caption()' function which sets the title
string as appropriate for the current situation; that is then called
from the places which change the UI state. That's probably as good
an approach as any.

>> You don't know that the machine being emulated has a floppy drive
>> at all, or that it's called "floppy0"...
>
> I did only use the PC and Mac targets. I know there are others. It looks
> like conditionally adding some of these menu items will have to do. I
> guess detecting if the guest machine has a floppy and/or cdrom drive can
> be done - hopefully...

It's not impossible. But none of the other UIs are trying to do that
kind of thing yet; I'd suggest postponing those parts. Bringing the
OSX UI into line with features already implementing in another UI
is simpler than adding features no other UI has, because you're not
trying to break new ground.

>> In the GTK UI we call this "Reset". We also have a "Power Down" which would
>> probably be nice for consistency.
>
> Changing Restart to Reset will be done. I don't know how to
> implement "Power Down", so I'm not sure about that one.

It's easy: just call qmp_system_powerdown(NULL).

> Do you think anyone will ever make SDL or GTK UIs for QEMU work
> on Mac OS X?

Hard to say. I won't, because I don't have the GTK dependencies
available to me. And there don't really seem to be any other
developers trying to work with QEMU on OSX except you.
It should be possible in theory to get SDL or GTK UIs working,
but you'd have to fix up places where the cocoa UI assumes
it's always present, I expect.

-- PMM
Programmingkid Jan. 14, 2015, 7:06 p.m. UTC | #4
On Jan 14, 2015, at 1:42 PM, Peter Maydell wrote:

> On 14 January 2015 at 18:34, Programmingkid <programmingkidx@gmail.com> wrote:
>> 
>> On Jan 14, 2015, at 12:42 PM, Peter Maydell wrote:
>> 
>>> On 13 January 2015 at 01:49, Programmingkid <programmingkidx@gmail.com> wrote:
>>>> This patch adds a Machine menu to QEMU. This menu gives the user the ability to easily work with floppy and CD image files.
>>>> 
>>>> Features:
>>>> Menu items to switch floppy and CD image files.
>>>> Menu items to eject floppy and CD image files.
>>>> Menu item to use /dev/cdrom.
>>>> Verifies with the user before quitting QEMU by displaying a dialog box.
>>>> 
>>>> Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
>>> 
>>> Hi. I'm afraid I couldn't get this patch to apply -- is it dependent
>>> on one of your other patches?
>> 
>> I have been making a lot of changes to cocoa.m. Can you suggest a way
>> to make these changes not interfere with each other?
> 
> It can be hard to avoid in that kind of situation. Sometimes the
> best you can do is just to say which patches it depends on.

That sounds like a good idea.

> 
> 
>>> Isn't this changing of the title string going to conflict with the
>>> changes that we make for mouse grab/ungrab?
>> 
>> Unfortunately yes, but I still need a way to alert the user that QEMU
>> is paused. I guess I could find a way to make both messages show up
>> in the titlebar. Or I could display a message in the main window that
>> says "Paused". Will come up with something soon.
> 
> ui/gtk.c has a 'gd_update_caption()' function which sets the title
> string as appropriate for the current situation; that is then called
> from the places which change the UI state. That's probably as good
> an approach as any.

I was thinking about displaying the word "Paused" behind the darked QEMU window. The "Paused" will be in big letters - maybe in a red color. 

> 
>>> You don't know that the machine being emulated has a floppy drive
>>> at all, or that it's called "floppy0"...
>> 
>> I did only use the PC and Mac targets. I know there are others. It looks
>> like conditionally adding some of these menu items will have to do. I
>> guess detecting if the guest machine has a floppy and/or cdrom drive can
>> be done - hopefully...
> 
> It's not impossible. But none of the other UIs are trying to do that
> kind of thing yet; I'd suggest postponing those parts. Bringing the
> OSX UI into line with features already implementing in another UI
> is simpler than adding features no other UI has, because you're not
> trying to break new ground.

I think innovation is exactly what QEMU needs. If everyone is waiting for someone else to make the first move, we all remain stuck. 

> 
>>> In the GTK UI we call this "Reset". We also have a "Power Down" which would
>>> probably be nice for consistency.
>> 
>> Changing Restart to Reset will be done. I don't know how to
>> implement "Power Down", so I'm not sure about that one.
> 
> It's easy: just call qmp_system_powerdown(NULL).

Ok, is that something that tells the guest operating system it is to shut down?

> 
>> Do you think anyone will ever make SDL or GTK UIs for QEMU work
>> on Mac OS X?
> 
> Hard to say. I won't, because I don't have the GTK dependencies
> available to me. And there don't really seem to be any other
> developers trying to work with QEMU on OSX except you.
> It should be possible in theory to get SDL or GTK UIs working,
> but you'd have to fix up places where the cocoa UI assumes
> it's always present, I expect.

Ok, which one is better - SDL, or GTK? If someone ever decided to port one of these UIs to Mac OS X, which one should that person work on?
diff mbox

Patch

diff --git a/ui/cocoa.m b/ui/cocoa.m
index 4cb07ba..c8535a3 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -29,6 +29,8 @@ 
 #include "ui/console.h"
 #include "ui/input.h"
 #include "sysemu/sysemu.h"
+#import "qmp-commands.h"
+#import "sysemu/blockdev.h"
 
 #ifndef MAC_OS_X_VERSION_10_4
 #define MAC_OS_X_VERSION_10_4 1040
@@ -252,6 +254,15 @@  static void determineMacOSVersion()
     }
 }
 
+/* Handles any errors that happen with a device transaction */
+static void handleAnyDeviceErrors(Error * err)
+{
+    if (err) {
+        NSRunAlertPanel(@"Alert", [NSString stringWithCString: error_get_pretty(err)], @"OK", nil, nil);
+        error_free(err);
+    }
+}
+
 /*
  ------------------------------------------------------
     QemuCocoaView
@@ -841,6 +852,14 @@  QemuCocoaView *cocoaView;
 - (void)toggleFullScreen:(id)sender;
 - (void)showQEMUDoc:(id)sender;
 - (void)showQEMUTec:(id)sender;
+- (void)pauseQemu:(id)sender;
+- (void)ejectFloppy:(id)sender;
+- (void)ejectCdrom:(id)sender;
+- (void)changeCdrom:(id)sender;
+- (void)changeFloppy:(id)sender;
+- (void)restartQemu:(id)sender;
+- (void)useRealCdrom:(id)sender;
+- (void)verifyQuit:(id)sender;
 @end
 
 @implementation QemuCocoaAppController
@@ -992,6 +1011,94 @@  menu item's old selector's name toggleFullScreen: */
     [[NSWorkspace sharedWorkspace] openFile:[NSString stringWithFormat:@"%@/../doc/qemu/qemu-tech.html",
         [[NSBundle mainBundle] resourcePath]] withApplication:@"Help Viewer"];
 }
+
+/* Pause the guest */
+- (void)pauseQemu:(id)sender
+{
+    qmp_stop(NULL);
+    [sender setEnabled: NO];
+    [[[sender menu] itemWithTitle: @"Resume"] setEnabled: YES];
+    [normalWindow setTitle: @"*** Paused ***"];
+}
+
+/* Resume running the guest operating system */
+- (void)resumeQemu: (id) sender
+{
+    qmp_cont(NULL);
+    [sender setEnabled: NO];
+    [[[sender menu] itemWithTitle: @"Pause"] setEnabled: YES];
+    [normalWindow setTitle: @"QEMU"];
+}
+
+/* Eject the floppy0 disk */
+- (void)ejectFloppy:(id)sender
+{
+    Error *err = NULL;
+    qmp_eject("floppy0", false, false, &err);
+    handleAnyDeviceErrors(err);
+}
+
+/* Displays a dialog box asking the user to select a floppy image to load */
+- (void)changeFloppy:(id)sender
+{
+    NSOpenPanel * open_panel;
+    open_panel = [NSOpenPanel openPanel];
+    [open_panel setCanChooseFiles: YES];
+    [open_panel setAllowsMultipleSelection: NO];
+    if([open_panel runModalForDirectory: nil file: nil] == NSOKButton) {
+        Error *err = NULL;
+        NSString * file = [[open_panel filenames] objectAtIndex: 0];
+        qmp_change_blockdev("floppy0", [file cString], "raw", &err);
+        handleAnyDeviceErrors(err);
+    }
+}
+
+// Ejects the cdrom
+- (void)ejectCdrom:(id)sender
+{
+    Error *err = NULL;
+    qmp_eject("ide1-cd0", false, false, &err);
+    handleAnyDeviceErrors(err);
+}
+
+/* Displays a dialog box asking the user to select a CD image to load */
+- (void)changeCdrom:(id)sender
+{
+    NSOpenPanel * open_panel;
+    open_panel = [NSOpenPanel openPanel];
+    [open_panel setCanChooseFiles: YES];
+    [open_panel setAllowsMultipleSelection: NO];
+    if([open_panel runModalForDirectory: nil file: nil] == NSOKButton) {
+        NSString * file = [[open_panel filenames] objectAtIndex: 0];
+        Error *err = NULL;
+        qmp_change_blockdev("ide1-cd0", [file cString], "raw", &err);
+        handleAnyDeviceErrors(err);
+    }
+}
+
+/* Restarts QEMU */
+- (void)restartQemu: (id) sender
+{
+    qemu_system_reset_request();
+}
+
+/* Switches QEMU to use the real cdrom drive */
+- (void)useRealCdrom: (id) sender
+{
+    Error *err = NULL;
+    qmp_change_blockdev("ide1-cd0", "/dev/cdrom", "raw", &err);
+    handleAnyDeviceErrors(err);
+}
+
+/* Verifies if the user really wants to quit */
+- (void)verifyQuit: (id) sender
+{
+    NSInteger response;
+    response = NSRunAlertPanel(@"Quit?", @"Are you sure you want to quit?", @"Cancel", @"Quit", nil);
+    if(response == NSAlertAlternateReturn)
+        exit(EXIT_SUCCESS);
+}
+
 @end
 
 
@@ -1046,7 +1153,7 @@  int main (int argc, const char * argv[]) {
     [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
     [menu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; // Show All
     [menu addItem:[NSMenuItem separatorItem]]; //Separator
-    [menu addItemWithTitle:@"Quit QEMU" action:@selector(terminate:) keyEquivalent:@"q"];
+    [menu addItemWithTitle:@"Quit QEMU" action:@selector(verifyQuit:) keyEquivalent:@"q"];
     menuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" action:nil keyEquivalent:@""];
     [menuItem setSubmenu:menu];
     [[NSApp mainMenu] addItem:menuItem];
@@ -1059,6 +1166,24 @@  int main (int argc, const char * argv[]) {
     [menuItem setSubmenu:menu];
     [[NSApp mainMenu] addItem:menuItem];
 
+    /* Machine menu */
+     menu = [[NSMenu alloc] initWithTitle: @"Machine"];
+     [menu setAutoenablesItems: NO];
+     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Pause" action: @selector(pauseQemu:) keyEquivalent: @""] autorelease]];
+     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Resume" action: @selector(resumeQemu:) keyEquivalent: @""] autorelease]];
+     [menu addItem: [NSMenuItem separatorItem]];
+     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Eject Floppy" action: @selector(ejectFloppy:) keyEquivalent: @""] autorelease]];
+     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Change Floppy..." action: @selector(changeFloppy:) keyEquivalent: @""] autorelease]];
+     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Eject cdrom" action: @selector(ejectCdrom:) keyEquivalent: @""] autorelease]];
+     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Use cdrom image..." action: @selector(changeCdrom:) keyEquivalent: @""] autorelease]];
+     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Use real cdrom drive" action: @selector(useRealCdrom:) keyEquivalent: @""] autorelease]];
+     [menu addItem: [NSMenuItem separatorItem]];
+     [menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Restart" action: @selector(restartQemu:) keyEquivalent: @""] autorelease]];
+     menuItem = [[[NSMenuItem alloc] initWithTitle: @"Machine" action:nil keyEquivalent:@""] autorelease];
+    [menuItem setSubmenu:menu];
+    [[NSApp mainMenu] addItem:menuItem];
+	 [[menu itemWithTitle: @"Resume"] setEnabled: NO];
+
     // Window menu
     menu = [[NSMenu alloc] initWithTitle:@"Window"];
     [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"] autorelease]]; // Miniaturize
@@ -1168,7 +1293,7 @@  void cocoa_display_init(DisplayState *ds, int full_screen)
         [NSApp activateIgnoringOtherApps: YES];
         [[[NSApplication sharedApplication] delegate] toggleFullScreen: nil];
     }
-    
+
     dcl = g_malloc0(sizeof(DisplayChangeListener));
 
     // register vga output callbacks