qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]