cocoa queue:
* Add Machine menu, with entries for pause, resume, reset, power down, and media change and eject for removable drives -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABCAAGBQJVg+3LAAoJEDwlJe0UNgzeDi0P/iJQJHERVlkphT106JX5dl2L u8sOOsf/jPRYZ45zTqi0LAoC/PQ60DD8ASaiGi9Co3Gv9mr+LDqdux0v5A+5/sPb r3+6qSY7Qurgi04nA3Q8QrauDY4FTi80g6JI0kgFgmTxAySq0PJghVcDQLCbW5Cw PdzRhlJ30FfzNNUUdYH9UYdQqjrPlSPfLFR6iT96X6u01dzbGTAYLNf8Yl3BDezn rtOTihAOVZiINyM13T9L9noeGkXMfYVyDIkvtamoTL9YwnChafHg0EXYKD/VNkZw 1TfP/YnO3JIN2CirwV602P8mVjtzrVervu1UQeIIYXAYtXemryGWWLswRRLxuqRl F8LFFWw3wnXzr1A2Tp27GF4knZxjkJSDcn/lUWWFrxcMr2LnY/P0xM4yk/YdU+Qm mDCMTbLIGKuCL3nNselet0rvx9pj7TEXyrqSUd11deIlM4lXQOpD0coJO2H4enhh yLVV5gQe2bGUQOw4bz02eO75WjFYbfAcLhlwLEuqKpfBndQLSYi7QSqaxbhsN8nS //oRdke0uN+7pldWN32w1ZijJHMdo3M4HBiATzp8cEBmltI2+oiXH5sVfi5xcIet JP8yqjHPFgWfsq4GBqkcMxLw8Qxh50ZD1efky4X7xvuwh8FgPZAr2e53nQyb/0Fy PhHG3RgmfD8R39hXS9Ob =VWt+ -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/pmaydell/tags/pull-cocoa-20150619-1' into staging cocoa queue: * Add Machine menu, with entries for pause, resume, reset, power down, and media change and eject for removable drives # gpg: Signature made Fri Jun 19 11:24:11 2015 BST using RSA key ID 14360CDE # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" * remotes/pmaydell/tags/pull-cocoa-20150619-1: ui/cocoa.m: Add machine menu items to change and eject removable drive media ui/cocoa.m: Add Reset and Power Down menu items to Machine menu ui/cocoa.m: Add Machine menu with pause and resume menu items Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
ffdb1409a7
240
ui/cocoa.m
240
ui/cocoa.m
@ -29,6 +29,8 @@
|
||||
#include "ui/console.h"
|
||||
#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
|
||||
@ -65,6 +67,8 @@ static int last_buttons;
|
||||
int gArgc;
|
||||
char **gArgv;
|
||||
bool stretch_video;
|
||||
NSTextField *pauseLabel;
|
||||
NSArray * supportedImageFileTypes;
|
||||
|
||||
// keymap conversion
|
||||
int keymap[] =
|
||||
@ -240,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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------
|
||||
@ -800,6 +821,14 @@ QemuCocoaView *cocoaView;
|
||||
- (void)showQEMUTec:(id)sender;
|
||||
- (void)zoomToFit:(id) sender;
|
||||
- (void)displayConsole:(id)sender;
|
||||
- (void)pauseQEMU:(id)sender;
|
||||
- (void)resumeQEMU:(id)sender;
|
||||
- (void)displayPause;
|
||||
- (void)removePause;
|
||||
- (void)restartQEMU:(id)sender;
|
||||
- (void)powerDownQEMU:(id)sender;
|
||||
- (void)ejectDeviceMedia:(id)sender;
|
||||
- (void)changeDeviceMedia:(id)sender;
|
||||
@end
|
||||
|
||||
@implementation QemuCocoaAppController
|
||||
@ -834,6 +863,22 @@ QemuCocoaView *cocoaView;
|
||||
[normalWindow makeKeyAndOrderFront:self];
|
||||
[normalWindow center];
|
||||
stretch_video = false;
|
||||
|
||||
/* Used for displaying pause on the screen */
|
||||
pauseLabel = [NSTextField new];
|
||||
[pauseLabel setBezeled:YES];
|
||||
[pauseLabel setDrawsBackground:YES];
|
||||
[pauseLabel setBackgroundColor: [NSColor whiteColor]];
|
||||
[pauseLabel setEditable:NO];
|
||||
[pauseLabel setSelectable:NO];
|
||||
[pauseLabel setStringValue: @"Paused"];
|
||||
[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;
|
||||
}
|
||||
@ -857,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
|
||||
@ -977,6 +1020,111 @@ QemuCocoaView *cocoaView;
|
||||
{
|
||||
console_select([sender tag]);
|
||||
}
|
||||
|
||||
/* Pause the guest */
|
||||
- (void)pauseQEMU:(id)sender
|
||||
{
|
||||
qmp_stop(NULL);
|
||||
[sender setEnabled: NO];
|
||||
[[[sender menu] itemWithTitle: @"Resume"] setEnabled: YES];
|
||||
[self displayPause];
|
||||
}
|
||||
|
||||
/* Resume running the guest operating system */
|
||||
- (void)resumeQEMU:(id) sender
|
||||
{
|
||||
qmp_cont(NULL);
|
||||
[sender setEnabled: NO];
|
||||
[[[sender menu] itemWithTitle: @"Pause"] setEnabled: YES];
|
||||
[self removePause];
|
||||
}
|
||||
|
||||
/* Displays the word pause on the screen */
|
||||
- (void)displayPause
|
||||
{
|
||||
/* Coordinates have to be calculated each time because the window can change its size */
|
||||
int xCoord, yCoord, width, height;
|
||||
xCoord = ([normalWindow frame].size.width - [pauseLabel frame].size.width)/2;
|
||||
yCoord = [normalWindow frame].size.height - [pauseLabel frame].size.height - ([pauseLabel frame].size.height * .5);
|
||||
width = [pauseLabel frame].size.width;
|
||||
height = [pauseLabel frame].size.height;
|
||||
[pauseLabel setFrame: NSMakeRect(xCoord, yCoord, width, height)];
|
||||
[cocoaView addSubview: pauseLabel];
|
||||
}
|
||||
|
||||
/* Removes the word pause from the screen */
|
||||
- (void)removePause
|
||||
{
|
||||
[pauseLabel removeFromSuperview];
|
||||
}
|
||||
|
||||
/* Restarts QEMU */
|
||||
- (void)restartQEMU:(id)sender
|
||||
{
|
||||
qmp_system_reset(NULL);
|
||||
}
|
||||
|
||||
/* Powers down QEMU */
|
||||
- (void)powerDownQEMU:(id)sender
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
@ -1036,6 +1184,20 @@ int main (int argc, const char * argv[]) {
|
||||
[[NSApp mainMenu] addItem:menuItem];
|
||||
[NSApp performSelector:@selector(setAppleMenu:) withObject:menu]; // Workaround (this method is private since 10.4+)
|
||||
|
||||
// Machine menu
|
||||
menu = [[NSMenu alloc] initWithTitle: @"Machine"];
|
||||
[menu setAutoenablesItems: NO];
|
||||
[menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Pause" action: @selector(pauseQEMU:) keyEquivalent: @""] autorelease]];
|
||||
menuItem = [[[NSMenuItem alloc] initWithTitle: @"Resume" action: @selector(resumeQEMU:) keyEquivalent: @""] autorelease];
|
||||
[menu addItem: menuItem];
|
||||
[menuItem setEnabled: NO];
|
||||
[menu addItem: [NSMenuItem separatorItem]];
|
||||
[menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Reset" action: @selector(restartQEMU:) keyEquivalent: @""] autorelease]];
|
||||
[menu addItem: [[[NSMenuItem alloc] initWithTitle: @"Power Down" action: @selector(powerDownQEMU:) keyEquivalent: @""] autorelease]];
|
||||
menuItem = [[[NSMenuItem alloc] initWithTitle: @"Machine" action:nil keyEquivalent:@""] autorelease];
|
||||
[menuItem setSubmenu:menu];
|
||||
[[NSApp mainMenu] addItem:menuItem];
|
||||
|
||||
// View menu
|
||||
menu = [[NSMenu alloc] initWithTitle:@"View"];
|
||||
[menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Enter Fullscreen" action:@selector(doToggleFullScreen:) keyEquivalent:@"f"] autorelease]]; // Fullscreen
|
||||
@ -1176,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");
|
||||
@ -1199,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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user