cocoa queue:

* pass command key to guest when VM has mousegrab
  * add .qcow2 to extension list for image load dialog
  * fix bugs in code for starting QEMU via image load dialog
  * fix resize/redraw interaction
  * draw window black if guest hasn't sent anything to screen
  * minor style/typo fixes
  * add myself as cocoa co-maintainer
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABCAAGBQJS0xsgAAoJEDwlJe0UNgzeADIP/3qewnn2gj9HSXCuj2w8f38n
 ed7M0QRJU8btsiRFWjqUNsCpRl18O8Lm+S9DlsjNbyaUGpgRnF5KfYyfU6lPeg5S
 IzkYcKu/pKj1vFol4BamD/4AyohJZh9yHu5mvKyB7QCMIj1ulnNehwlTKL93tX92
 Nb5E9nshm9ypei6f/HRA+NU+dgZjyEUZ/20/uzw+GokdFjosEZ/cgCWGI1iKPgda
 ebfJW9reYpuWg2C7lp6PGJ4p3lLwPO3CYBqsDVertLvVT4RXduVtPcyuQWaRuIWt
 v4tu5bevKkmKI04bQYUS4dcURwPfPPufQ9nUjDLx67CYKTXgEJFoOkSzJOG8bGyo
 3uyznDEk+cbe09QM6Vnkmyb8pHWR2bWw+p6Iwd1JTZmLLb2eOJEUcfdUkjqKYw97
 uAzo2VomWT80wU2mnjjZdea8Ub+PrLeoN4ifkYlbss+3bWA2imhQoP/4/l34Sixh
 9Hw1xOE6nPvrFX0Bv8HROzlIkS5zEyzwxTiuJ3qmm6t+97Kf1YLg0Fyxz8rk4sJ1
 cz0cBbDLj9eInl6vxt7rufphBaF3qSwOt7tRHaowu1ikqJwYsxrZQ2c4bs8phg3T
 rCrsfUOz3QD8XKC0J+cIa6Zlj+bhP6tesbqmwficzT/YoRs0bqvYQ+NBjH17f3Dc
 WIG0GerJahvnP/vXsvEw
 =69oG
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'pmaydell/tags/pull-cocoa-20140112' into staging

cocoa queue:
 * pass command key to guest when VM has mousegrab
 * add .qcow2 to extension list for image load dialog
 * fix bugs in code for starting QEMU via image load dialog
 * fix resize/redraw interaction
 * draw window black if guest hasn't sent anything to screen
 * minor style/typo fixes
 * add myself as cocoa co-maintainer

# gpg: Signature made Sun 12 Jan 2014 02:45:52 PM PST using RSA key ID 14360CDE
# gpg: Can't check signature: public key not found

* pmaydell/tags/pull-cocoa-20140112:
  MAINTAINERS: add myself as cocoa UI co-maintainer
  ui/cocoa: Remove stray tabs
  ui/cocoa: Draw black rectangle if we have no data yet
  ui/cocoa: Redraw at correct size when switching surface
  ui/cocoa: Fix code for starting QEMU via image file load dialog
  ui/cocoa: Add ".qcow2" to extension list for image load dialog
  ui/cocoa: Send warning message to stderr, not stdout
  ui/cocoa: Correct typos in comments and variable names
  ui/cocoa: Pass command key through to guest when VM has mousegrab

Message-id: 1389567158-31066-1-git-send-email-peter.maydell@linaro.org
Signed-off-by: Anthony Liguori <aliguori@amazon.com>
This commit is contained in:
Anthony Liguori 2014-01-12 17:50:52 -08:00
commit dd089c0a1e
2 changed files with 64 additions and 37 deletions

View File

@ -714,6 +714,7 @@ F: ui/
Cocoa graphics Cocoa graphics
M: Andreas Färber <andreas.faerber@web.de> M: Andreas Färber <andreas.faerber@web.de>
M: Peter Maydell <peter.maydell@linaro.org>
S: Odd Fixes S: Odd Fixes
F: ui/cocoa.m F: ui/cocoa.m

View File

@ -52,7 +52,7 @@
#define COCOA_MOUSE_EVENT \ #define COCOA_MOUSE_EVENT \
if (isTabletEnabled) { \ if (isTabletEnabled) { \
kbd_mouse_event((int)(p.x * 0x7FFF / (screen.width - 1)), (int)((screen.height - p.y) * 0x7FFF / (screen.height - 1)), 0, buttons); \ kbd_mouse_event((int)(p.x * 0x7FFF / (screen.width - 1)), (int)((screen.height - p.y) * 0x7FFF / (screen.height - 1)), 0, buttons); \
} else if (isMouseGrabed) { \ } else if (isMouseGrabbed) { \
kbd_mouse_event((int)[event deltaX], (int)[event deltaY], 0, buttons); \ kbd_mouse_event((int)[event deltaX], (int)[event deltaY], 0, buttons); \
} else { \ } else { \
[NSApp sendEvent:event]; \ [NSApp sendEvent:event]; \
@ -129,8 +129,8 @@ int keymap[] =
14, // 51 0x33 0x0e BKSP QZ_BACKSPACE 14, // 51 0x33 0x0e BKSP QZ_BACKSPACE
0, // 52 0x34 Undefined 0, // 52 0x34 Undefined
1, // 53 0x35 0x01 ESC QZ_ESCAPE 1, // 53 0x35 0x01 ESC QZ_ESCAPE
0, // 54 0x36 QZ_RMETA 220, // 54 0x36 0xdc E0,5C R GUI QZ_RMETA
0, // 55 0x37 QZ_LMETA 219, // 55 0x37 0xdb E0,5B L GUI QZ_LMETA
42, // 56 0x38 0x2a L SHFT QZ_LSHIFT 42, // 56 0x38 0x2a L SHFT QZ_LSHIFT
58, // 57 0x39 0x3a CAPS QZ_CAPSLOCK 58, // 57 0x39 0x3a CAPS QZ_CAPSLOCK
56, // 58 0x3A 0x38 L ALT QZ_LALT 56, // 58 0x3A 0x38 L ALT QZ_LALT
@ -204,10 +204,8 @@ int keymap[] =
200,// 126 0x7E 0xc8 E0,48 U ARROW QZ_UP 200,// 126 0x7E 0xc8 E0,48 U ARROW QZ_UP
/* completed according to http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */ /* completed according to http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */
/* Aditional 104 Key XP-Keyboard Scancodes from http://www.computer-engineering.org/ps2keyboard/scancodes1.html */ /* Additional 104 Key XP-Keyboard Scancodes from http://www.computer-engineering.org/ps2keyboard/scancodes1.html */
/* /*
219 // 0xdb e0,5b L GUI
220 // 0xdc e0,5c R GUI
221 // 0xdd e0,5d APPS 221 // 0xdd e0,5d APPS
// E0,2A,E0,37 PRNT SCRN // E0,2A,E0,37 PRNT SCRN
// E1,1D,45,E1,9D,C5 PAUSE // E1,1D,45,E1,9D,C5 PAUSE
@ -241,7 +239,7 @@ int keymap[] =
static int cocoa_keycode_to_qemu(int keycode) static int cocoa_keycode_to_qemu(int keycode)
{ {
if (ARRAY_SIZE(keymap) <= keycode) { if (ARRAY_SIZE(keymap) <= keycode) {
printf("(cocoa) warning unknown keycode 0x%x\n", keycode); fprintf(stderr, "(cocoa) warning unknown keycode 0x%x\n", keycode);
return 0; return 0;
} }
return keymap[keycode]; return keymap[keycode];
@ -261,7 +259,7 @@ static int cocoa_keycode_to_qemu(int keycode)
float cx,cy,cw,ch,cdx,cdy; float cx,cy,cw,ch,cdx,cdy;
CGDataProviderRef dataProviderRef; CGDataProviderRef dataProviderRef;
int modifiers_state[256]; int modifiers_state[256];
BOOL isMouseGrabed; BOOL isMouseGrabbed;
BOOL isFullscreen; BOOL isFullscreen;
BOOL isAbsoluteEnabled; BOOL isAbsoluteEnabled;
BOOL isTabletEnabled; BOOL isTabletEnabled;
@ -272,7 +270,7 @@ static int cocoa_keycode_to_qemu(int keycode)
- (void) toggleFullScreen:(id)sender; - (void) toggleFullScreen:(id)sender;
- (void) handleEvent:(NSEvent *)event; - (void) handleEvent:(NSEvent *)event;
- (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled; - (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled;
- (BOOL) isMouseGrabed; - (BOOL) isMouseGrabbed;
- (BOOL) isAbsoluteEnabled; - (BOOL) isAbsoluteEnabled;
- (float) cdx; - (float) cdx;
- (float) cdy; - (float) cdy;
@ -323,7 +321,12 @@ QemuCocoaView *cocoaView;
CGContextSetShouldAntialias (viewContextRef, NO); CGContextSetShouldAntialias (viewContextRef, NO);
// draw screen bitmap directly to Core Graphics context // draw screen bitmap directly to Core Graphics context
if (dataProviderRef) { if (!dataProviderRef) {
// Draw request before any guest device has set up a framebuffer:
// just draw an opaque black rectangle
CGContextSetRGBFillColor(viewContextRef, 0, 0, 0, 1.0);
CGContextFillRect(viewContextRef, NSRectToCGRect(rect));
} else {
CGImageRef imageRef = CGImageCreate( CGImageRef imageRef = CGImageCreate(
screen.width, //width screen.width, //width
screen.height, //height screen.height, //height
@ -407,31 +410,41 @@ QemuCocoaView *cocoaView;
int w = surface_width(surface); int w = surface_width(surface);
int h = surface_height(surface); int h = surface_height(surface);
bool isResize = (w != screen.width || h != screen.height);
int oldh = screen.height;
if (isResize) {
// Resize before we trigger the redraw, or we'll redraw at the wrong size
COCOA_DEBUG("switchSurface: new size %d x %d\n", w, h);
screen.width = w;
screen.height = h;
[self setContentDimensions];
[self setFrame:NSMakeRect(cx, cy, cw, ch)];
}
// update screenBuffer // update screenBuffer
if (dataProviderRef) if (dataProviderRef)
CGDataProviderRelease(dataProviderRef); CGDataProviderRelease(dataProviderRef);
//sync host window color space with guests //sync host window color space with guests
screen.bitsPerPixel = surface_bits_per_pixel(surface); screen.bitsPerPixel = surface_bits_per_pixel(surface);
screen.bitsPerComponent = surface_bytes_per_pixel(surface) * 2; screen.bitsPerComponent = surface_bytes_per_pixel(surface) * 2;
dataProviderRef = CGDataProviderCreateWithData(NULL, surface_data(surface), w * 4 * h, NULL); dataProviderRef = CGDataProviderCreateWithData(NULL, surface_data(surface), w * 4 * h, NULL);
// update windows // update windows
if (isFullscreen) { if (isFullscreen) {
[[fullScreenWindow contentView] setFrame:[[NSScreen mainScreen] frame]]; [[fullScreenWindow contentView] setFrame:[[NSScreen mainScreen] frame]];
[normalWindow setFrame:NSMakeRect([normalWindow frame].origin.x, [normalWindow frame].origin.y - h + screen.height, w, h + [normalWindow frame].size.height - screen.height) display:NO animate:NO]; [normalWindow setFrame:NSMakeRect([normalWindow frame].origin.x, [normalWindow frame].origin.y - h + oldh, w, h + [normalWindow frame].size.height - oldh) display:NO animate:NO];
} else { } else {
if (qemu_name) if (qemu_name)
[normalWindow setTitle:[NSString stringWithFormat:@"QEMU %s", qemu_name]]; [normalWindow setTitle:[NSString stringWithFormat:@"QEMU %s", qemu_name]];
[normalWindow setFrame:NSMakeRect([normalWindow frame].origin.x, [normalWindow frame].origin.y - h + screen.height, w, h + [normalWindow frame].size.height - screen.height) display:YES animate:NO]; [normalWindow setFrame:NSMakeRect([normalWindow frame].origin.x, [normalWindow frame].origin.y - h + oldh, w, h + [normalWindow frame].size.height - oldh) display:YES animate:NO];
}
if (isResize) {
[normalWindow center];
} }
screen.width = w;
screen.height = h;
[normalWindow center];
[self setContentDimensions];
[self setFrame:NSMakeRect(cx, cy, cw, ch)];
} }
- (void) toggleFullScreen:(id)sender - (void) toggleFullScreen:(id)sender
@ -493,6 +506,12 @@ QemuCocoaView *cocoaView;
switch ([event type]) { switch ([event type]) {
case NSFlagsChanged: case NSFlagsChanged:
keycode = cocoa_keycode_to_qemu([event keyCode]); keycode = cocoa_keycode_to_qemu([event keyCode]);
if ((keycode == 219 || keycode == 220) && !isMouseGrabbed) {
/* Don't pass command key changes to guest unless mouse is grabbed */
keycode = 0;
}
if (keycode) { if (keycode) {
if (keycode == 58 || keycode == 69) { // emulate caps lock and num lock keydown and keyup if (keycode == 58 || keycode == 69) { // emulate caps lock and num lock keydown and keyup
kbd_put_keycode(keycode); kbd_put_keycode(keycode);
@ -516,15 +535,15 @@ QemuCocoaView *cocoaView;
} }
break; break;
case NSKeyDown: case NSKeyDown:
keycode = cocoa_keycode_to_qemu([event keyCode]);
// forward command Key Combos // forward command key combos to the host UI unless the mouse is grabbed
if ([event modifierFlags] & NSCommandKeyMask) { if (!isMouseGrabbed && ([event modifierFlags] & NSCommandKeyMask)) {
[NSApp sendEvent:event]; [NSApp sendEvent:event];
return; return;
} }
// default // default
keycode = cocoa_keycode_to_qemu([event keyCode]);
// handle control + alt Key Combos (ctrl+alt is reserved for QEMU) // handle control + alt Key Combos (ctrl+alt is reserved for QEMU)
if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) { if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
@ -580,6 +599,13 @@ QemuCocoaView *cocoaView;
break; break;
case NSKeyUp: case NSKeyUp:
keycode = cocoa_keycode_to_qemu([event keyCode]); keycode = cocoa_keycode_to_qemu([event keyCode]);
// don't pass the guest a spurious key-up if we treated this
// command-key combo as a host UI action
if (!isMouseGrabbed && ([event modifierFlags] & NSCommandKeyMask)) {
return;
}
if (qemu_console_is_graphic(NULL)) { if (qemu_console_is_graphic(NULL)) {
if (keycode & 0x80) if (keycode & 0x80)
kbd_put_keycode(0xe0); kbd_put_keycode(0xe0);
@ -637,7 +663,7 @@ QemuCocoaView *cocoaView;
case NSLeftMouseUp: case NSLeftMouseUp:
if (isTabletEnabled) { if (isTabletEnabled) {
COCOA_MOUSE_EVENT COCOA_MOUSE_EVENT
} else if (!isMouseGrabed) { } else if (!isMouseGrabbed) {
if (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height) { if (p.x > -1 && p.x < screen.width && p.y > -1 && p.y < screen.height) {
[self grabMouse]; [self grabMouse];
} else { } else {
@ -654,7 +680,7 @@ QemuCocoaView *cocoaView;
COCOA_MOUSE_EVENT COCOA_MOUSE_EVENT
break; break;
case NSScrollWheel: case NSScrollWheel:
if (isTabletEnabled || isMouseGrabed) { if (isTabletEnabled || isMouseGrabbed) {
kbd_mouse_event(0, 0, -[event deltaY], 0); kbd_mouse_event(0, 0, -[event deltaY], 0);
} else { } else {
[NSApp sendEvent:event]; [NSApp sendEvent:event];
@ -677,7 +703,7 @@ QemuCocoaView *cocoaView;
} }
[NSCursor hide]; [NSCursor hide];
CGAssociateMouseAndMouseCursorPosition(FALSE); CGAssociateMouseAndMouseCursorPosition(FALSE);
isMouseGrabed = TRUE; // while isMouseGrabed = TRUE, QemuCocoaApp sends all events to [cocoaView handleEvent:] isMouseGrabbed = TRUE; // while isMouseGrabbed = TRUE, QemuCocoaApp sends all events to [cocoaView handleEvent:]
} }
- (void) ungrabMouse - (void) ungrabMouse
@ -692,11 +718,11 @@ QemuCocoaView *cocoaView;
} }
[NSCursor unhide]; [NSCursor unhide];
CGAssociateMouseAndMouseCursorPosition(TRUE); CGAssociateMouseAndMouseCursorPosition(TRUE);
isMouseGrabed = FALSE; isMouseGrabbed = FALSE;
} }
- (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled {isAbsoluteEnabled = tIsAbsoluteEnabled;} - (void) setAbsoluteEnabled:(BOOL)tIsAbsoluteEnabled {isAbsoluteEnabled = tIsAbsoluteEnabled;}
- (BOOL) isMouseGrabed {return isMouseGrabed;} - (BOOL) isMouseGrabbed {return isMouseGrabbed;}
- (BOOL) isAbsoluteEnabled {return isAbsoluteEnabled;} - (BOOL) isAbsoluteEnabled {return isAbsoluteEnabled;}
- (float) cdx {return cdx;} - (float) cdx {return cdx;}
- (float) cdy {return cdy;} - (float) cdy {return cdy;}
@ -748,7 +774,7 @@ QemuCocoaView *cocoaView;
[normalWindow setContentView:cocoaView]; [normalWindow setContentView:cocoaView];
[normalWindow useOptimizedDrawing:YES]; [normalWindow useOptimizedDrawing:YES];
[normalWindow makeKeyAndOrderFront:self]; [normalWindow makeKeyAndOrderFront:self];
[normalWindow center]; [normalWindow center];
} }
return self; return self;
@ -767,14 +793,14 @@ QemuCocoaView *cocoaView;
{ {
COCOA_DEBUG("QemuCocoaAppController: applicationDidFinishLaunching\n"); COCOA_DEBUG("QemuCocoaAppController: applicationDidFinishLaunching\n");
// Display an open dialog box if no argument were passed or // Display an open dialog box if no arguments were passed or
// if qemu was launched from the finder ( the Finder passes "-psn" ) // if qemu was launched from the finder ( the Finder passes "-psn" )
if( gArgc <= 1 || strncmp ((char *)gArgv[1], "-psn", 4) == 0) { if( gArgc <= 1 || strncmp ((char *)gArgv[1], "-psn", 4) == 0) {
NSOpenPanel *op = [[NSOpenPanel alloc] init]; NSOpenPanel *op = [[NSOpenPanel alloc] init];
[op setPrompt:@"Boot image"]; [op setPrompt:@"Boot image"];
[op setMessage:@"Select the disk image you want to boot.\n\nHit the \"Cancel\" button to quit"]; [op setMessage:@"Select the disk image you want to boot.\n\nHit the \"Cancel\" button to quit"];
NSArray *filetypes = [NSArray arrayWithObjects:@"img", @"iso", @"dmg", NSArray *filetypes = [NSArray arrayWithObjects:@"img", @"iso", @"dmg",
@"qcow", @"cow", @"cloop", @"vmdk", nil]; @"qcow", @"qcow2", @"cow", @"cloop", @"vmdk", nil];
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
[op setAllowedFileTypes:filetypes]; [op setAllowedFileTypes:filetypes];
[op beginSheetModalForWindow:normalWindow [op beginSheetModalForWindow:normalWindow
@ -822,18 +848,18 @@ QemuCocoaView *cocoaView;
if(returnCode == NSCancelButton) { if(returnCode == NSCancelButton) {
exit(0); exit(0);
} else if(returnCode == NSOKButton) { } else if(returnCode == NSOKButton) {
const char *bin = "qemu";
char *img = (char*)[ [ [ sheet URL ] path ] cStringUsingEncoding:NSASCIIStringEncoding]; char *img = (char*)[ [ [ sheet URL ] path ] cStringUsingEncoding:NSASCIIStringEncoding];
char **argv = (char**)malloc( sizeof(char*)*3 ); char **argv = g_new(char *, 4);
[sheet close]; [sheet close];
argv[0] = g_strdup_printf("%s", bin); argv[0] = g_strdup(gArgv[0]);
argv[1] = g_strdup_printf("-hda"); argv[1] = g_strdup("-hda");
argv[2] = g_strdup_printf("%s", img); argv[2] = g_strdup(img);
argv[3] = NULL;
printf("Using argc %d argv %s -hda %s\n", 3, bin, img); // printf("Using argc %d argv %s -hda %s\n", 3, gArgv[0], img);
[self startEmulationWithArgc:3 argv:(char**)argv]; [self startEmulationWithArgc:3 argv:(char**)argv];
} }
@ -999,7 +1025,7 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
if (kbd_mouse_is_absolute()) { if (kbd_mouse_is_absolute()) {
if (![cocoaView isAbsoluteEnabled]) { if (![cocoaView isAbsoluteEnabled]) {
if ([cocoaView isMouseGrabed]) { if ([cocoaView isMouseGrabbed]) {
[cocoaView ungrabMouse]; [cocoaView ungrabMouse];
} }
} }