[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] Fixes several full screen issues on Mac OS X
From: |
Programmingkid |
Subject: |
[Qemu-devel] [PATCH] Fixes several full screen issues on Mac OS X |
Date: |
Sun, 4 Jan 2015 18:44:20 -0500 |
This patch makes several changes:
- Fixes issue of returning to window mode and QEMU not setting
the right graphic settings if there was a change during full screen mode.
- Eliminated distorted full screen display.
- Makes full screen mode available on Mac OS 10.7 and higher.
- Removes unneeded global variables cdx, and cdy.
- Changes a few comments to make them clearer.
Signed-off-by: John Arbuckle <address@hidden>
---
ui/cocoa.m | 106 ++++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 65 insertions(+), 41 deletions(-)
diff --git a/ui/cocoa.m b/ui/cocoa.m
index d37c29b..704d199 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -40,7 +40,6 @@
#define MAC_OS_X_VERSION_10_6 1060
#endif
-
//#define DEBUG
#ifdef DEBUG
@@ -250,13 +249,14 @@ static int cocoa_keycode_to_qemu(int keycode)
{
QEMUScreen screen;
NSWindow *fullScreenWindow;
- float cx,cy,cw,ch,cdx,cdy;
+ float cx,cy,cw,ch;
CGDataProviderRef dataProviderRef;
int modifiers_state[256];
BOOL isMouseGrabbed;
BOOL isFullscreen;
BOOL isAbsoluteEnabled;
BOOL isMouseDeassociated;
+ NSDictionary * window_mode_dict; /* keeps track of the guest' graphic
settings */
}
- (void) switchSurface:(DisplaySurface *)surface;
- (void) grabMouse;
@@ -279,9 +279,10 @@ static int cocoa_keycode_to_qemu(int keycode)
- (BOOL) isMouseGrabbed;
- (BOOL) isAbsoluteEnabled;
- (BOOL) isMouseDeassociated;
-- (float) cdx;
-- (float) cdy;
- (QEMUScreen) gscreen;
+- (void) updateWindowModeSettings;
+- (void) switchDisplayToWindowMode;
+- (void) switchDisplayToFullScreenMode;
@end
QemuCocoaView *cocoaView;
@@ -293,12 +294,11 @@ QemuCocoaView *cocoaView;
self = [super initWithFrame:frameRect];
if (self) {
-
screen.bitsPerComponent = 8;
screen.bitsPerPixel = 32;
screen.width = frameRect.size.width;
screen.height = frameRect.size.height;
-
+ [self updateWindowModeSettings];
}
return self;
}
@@ -394,10 +394,10 @@ QemuCocoaView *cocoaView;
[self getRectsBeingDrawn:&rectList count:&rectCount];
for (i = 0; i < rectCount; i++) {
- clipRect.origin.x = rectList[i].origin.x / cdx;
- clipRect.origin.y = (float)screen.height -
(rectList[i].origin.y + rectList[i].size.height) / cdy;
- clipRect.size.width = rectList[i].size.width / cdx;
- clipRect.size.height = rectList[i].size.height / cdy;
+ clipRect.origin.x = rectList[i].origin.x;
+ clipRect.origin.y = (float)screen.height -
(rectList[i].origin.y + rectList[i].size.height);
+ clipRect.size.width = rectList[i].size.width;
+ clipRect.size.height = rectList[i].size.height;
clipImageRef = CGImageCreateWithImageInRect(
imageRef,
clipRect
@@ -416,10 +416,8 @@ QemuCocoaView *cocoaView;
COCOA_DEBUG("QemuCocoaView: setContentDimensions\n");
if (isFullscreen) {
- cdx = [[NSScreen mainScreen] frame].size.width / (float)screen.width;
- cdy = [[NSScreen mainScreen] frame].size.height / (float)screen.height;
- cw = screen.width * cdx;
- ch = screen.height * cdy;
+ cw = screen.width;
+ ch = screen.height;
cx = ([[NSScreen mainScreen] frame].size.width - cw) / 2.0;
cy = ([[NSScreen mainScreen] frame].size.height - ch) / 2.0;
} else {
@@ -427,23 +425,15 @@ QemuCocoaView *cocoaView;
cy = 0;
cw = screen.width;
ch = screen.height;
- cdx = 1.0;
- cdy = 1.0;
}
}
- (void) switchSurface:(DisplaySurface *)surface
{
COCOA_DEBUG("QemuCocoaView: switchSurface\n");
-
int w = surface_width(surface);
int h = surface_height(surface);
- /* cdx == 0 means this is our very first surface, in which case we need
- * to recalculate the content dimensions even if it happens to be the size
- * of the initial empty window.
- */
- bool isResize = (w != screen.width || h != screen.height || cdx == 0.0);
-
+ 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
@@ -452,6 +442,16 @@ QemuCocoaView *cocoaView;
screen.height = h;
[self setContentDimensions];
[self setFrame:NSMakeRect(cx, cy, cw, ch)];
+
+ if (isFullscreen) {
+ /* I know, calling toggleFullScreen: looks like a mistake, but
+ it is the solution that works. I spent a long time looking
+ for another way. This way is simple and works very well. */
+ [self toggleFullScreen: nil];
+ [self toggleFullScreen: nil];
+ }
+ else /* !isFullscreen */
+ [self updateWindowModeSettings];
}
// update screenBuffer
@@ -482,8 +482,8 @@ QemuCocoaView *cocoaView;
- (void) toggleFullScreen:(id)sender
{
COCOA_DEBUG("QemuCocoaView: toggleFullScreen\n");
-
- if (isFullscreen) { // switch from fullscreen to desktop
+ if (isFullscreen) { // switch from fullscreen to window mode
+ [self switchDisplayToWindowMode];
isFullscreen = FALSE;
[self ungrabMouse];
[self setContentDimensions];
@@ -500,7 +500,8 @@ QemuCocoaView *cocoaView;
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
}
#endif
- } else { // switch from desktop to fullscreen
+ } else { // switch from window to fullscreen mode
+ [self switchDisplayToFullScreenMode];
isFullscreen = TRUE;
[self grabMouse];
[self setContentDimensions];
@@ -561,7 +562,7 @@ QemuCocoaView *cocoaView;
}
// release Mouse grab when pressing ctrl+alt
- if (!isFullscreen && ([event modifierFlags] & NSControlKeyMask) &&
([event modifierFlags] & NSAlternateKeyMask)) {
+ if (([event modifierFlags] & NSControlKeyMask) && ([event
modifierFlags] & NSAlternateKeyMask)) {
[self ungrabMouse];
}
break;
@@ -781,9 +782,33 @@ QemuCocoaView *cocoaView;
- (BOOL) isMouseGrabbed {return isMouseGrabbed;}
- (BOOL) isAbsoluteEnabled {return isAbsoluteEnabled;}
- (BOOL) isMouseDeassociated {return isMouseDeassociated;}
-- (float) cdx {return cdx;}
-- (float) cdy {return cdy;}
- (QEMUScreen) gscreen {return screen;}
+
+/* Learn the guest' graphic settings when in window mode */
+- (void) updateWindowModeSettings
+{
+ window_mode_dict = CGDisplayCurrentMode(kCGDirectMainDisplay);
+}
+
+/* Switches the monitor's display settings for using QEMU in a window mode */
+- (void) switchDisplayToWindowMode
+{
+ CGDisplaySwitchToMode(kCGDirectMainDisplay, window_mode_dict);
+}
+
+/* Switches the monitor's display settings for using QEMU in full screen mode
*/
+- (void) switchDisplayToFullScreenMode
+{
+ size_t desired_bit_depth = 32;
+ boolean_t exact_match;
+ NSDictionary * mode = CGDisplayBestModeForParameters(kCGDirectMainDisplay,
desired_bit_depth, (size_t)cw, (size_t)ch, &exact_match);
+ COCOA_DEBUG("switching to full screen: %d x %d\n", [[mode valueForKey:
@"Width"] intValue], [[mode valueForKey: @"Height"] intValue]);
+ if (mode != nil)
+ CGDisplaySwitchToMode(kCGDirectMainDisplay, mode);
+ else
+ printf("ERROR: failed to determine best mode for display!\n");
+}
+
@end
@@ -832,7 +857,6 @@ QemuCocoaView *cocoaView;
[normalWindow useOptimizedDrawing:YES];
[normalWindow makeKeyAndOrderFront:self];
[normalWindow center];
-
}
return self;
}
@@ -921,6 +945,15 @@ QemuCocoaView *cocoaView;
[self startEmulationWithArgc:3 argv:(char**)argv];
}
}
+
+/* We abstract the method called by the Enter Fullscreen menu item
+because Mac OS 10.7 and higher disables it. This is because of the
+menu item's old selector's name toggleFullScreen: */
+- (void) doToggleFullScreen:(id)sender
+{
+ [self toggleFullScreen:(id)sender];
+}
+
- (void)toggleFullScreen:(id)sender
{
COCOA_DEBUG("QemuCocoaAppController: toggleFullScreen\n");
@@ -1005,7 +1038,7 @@ int main (int argc, const char * argv[]) {
// View menu
menu = [[NSMenu alloc] initWithTitle:@"View"];
- [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Enter Fullscreen"
action:@selector(toggleFullScreen:) keyEquivalent:@"f"] autorelease]]; //
Fullscreen
+ [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Enter Fullscreen"
action:@selector(doToggleFullScreen:) keyEquivalent:@"f"] autorelease]]; //
Fullscreen
menuItem = [[[NSMenuItem alloc] initWithTitle:@"View" action:nil
keyEquivalent:@""] autorelease];
[menuItem setSubmenu:menu];
[[NSApp mainMenu] addItem:menuItem];
@@ -1050,17 +1083,8 @@ static void cocoa_update(DisplayChangeListener *dcl,
COCOA_DEBUG("qemu_cocoa: cocoa_update\n");
NSRect rect;
- if ([cocoaView cdx] == 1.0) {
- rect = NSMakeRect(x, [cocoaView gscreen].height - y - h, w, h);
- } else {
- rect = NSMakeRect(
- x * [cocoaView cdx],
- ([cocoaView gscreen].height - y - h) * [cocoaView cdy],
- w * [cocoaView cdx],
- h * [cocoaView cdy]);
- }
+ rect = NSMakeRect(x, [cocoaView gscreen].height - y - h, w, h);
[cocoaView setNeedsDisplayInRect:rect];
-
[pool release];
}
--
1.7.5.4
- [Qemu-devel] [PATCH] Fixes several full screen issues on Mac OS X,
Programmingkid <=