Commit faa261a7 authored by Peter Maydell's avatar Peter Maydell
Browse files

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



cocoa queue:
 * fix various issues with full screen in the OSX UI
 * set an icon for our binary file
 * add entries to the View menu for QEMU consoles
 * fix various warnings that are produced when building on 10.10
   (largely deprecated interfaces)

# gpg: Signature made Tue May 19 09:17:23 2015 BST using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-cocoa-20150519:
  ui/cocoa: Add console items to the View menu
  ui/cocoa: Avoid deprecated NSOKButton/NSCancelButton constants
  ui/cocoa: Don't use NSWindow useOptimizedDrawing on OSX 10.10 and up
  ui/cocoa: Declare that QemuCocoaAppController implements NSApplicationDelegate
  ui/cocoa: openPanelDidEnd returnCode should be NSInteger, not int
  ui/cocoa: Remove compatibility ifdefs for OSX 10.4
  ui/cocoa: Drop tests for CGImageCreateWithImageInRect support
  Makefile.target: set icon for binary file on Mac OS X
  ui/cocoa: Make -full-screen option work on Mac OS X
  ui/cocoa: Fix several full screen issues on Mac OS X

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 62bf3df4 b4c6a112
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -180,6 +180,10 @@ $(QEMU_PROG_BUILD): config-devices.mak
# build either PROG or PROGW
$(QEMU_PROG_BUILD): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
	$(call LINK, $(filter-out %.mak, $^))
ifdef CONFIG_DARWIN
	$(call quiet-command,Rez -append $(SRC_PATH)/pc-bios/qemu.rsrc -o $@,"  REZ   $(TARGET_DIR)$@")
	$(call quiet-command,SetFile -a C $@,"  SETFILE $(TARGET_DIR)$@")
endif

gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
	$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES),"  GEN   $(TARGET_DIR)$@")

pc-bios/qemu.rsrc

0 → 100644
+1504 −0

File added.

Preview size limit exceeded, changes collapsed.

+126 −55
Original line number Diff line number Diff line
@@ -30,15 +30,15 @@
#include "ui/input.h"
#include "sysemu/sysemu.h"

#ifndef MAC_OS_X_VERSION_10_4
#define MAC_OS_X_VERSION_10_4 1040
#endif
#ifndef MAC_OS_X_VERSION_10_5
#define MAC_OS_X_VERSION_10_5 1050
#endif
#ifndef MAC_OS_X_VERSION_10_6
#define MAC_OS_X_VERSION_10_6 1060
#endif
#ifndef MAC_OS_X_VERSION_10_10
#define MAC_OS_X_VERSION_10_10 101000
#endif


//#define DEBUG
@@ -64,6 +64,7 @@ static int last_buttons;

int gArgc;
char **gArgv;
bool stretch_video;

// keymap conversion
int keymap[] =
@@ -373,21 +374,9 @@ QemuCocoaView *cocoaView;
            0, //interpolate
            kCGRenderingIntentDefault //intent
        );
// test if host supports "CGImageCreateWithImageInRect" at compile time
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
        if (CGImageCreateWithImageInRect == NULL) { // test if "CGImageCreateWithImageInRect" is supported on host at runtime
#endif
            // compatibility drawing code (draws everything) (OS X < 10.4)
            CGContextDrawImage (viewContextRef, CGRectMake(0, 0, [self bounds].size.width, [self bounds].size.height), imageRef);
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
        } else {
        // selective drawing code (draws only dirty rectangles) (OS X >= 10.4)
        const NSRect *rectList;
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
        NSInteger rectCount;
#else
            int rectCount;
#endif
        int i;
        CGImageRef clipImageRef;
        CGRect clipRect;
@@ -405,8 +394,6 @@ QemuCocoaView *cocoaView;
            CGContextDrawImage (viewContextRef, cgrect(rectList[i]), clipImageRef);
            CGImageRelease (clipImageRef);
        }
        }
#endif
        CGImageRelease (imageRef);
    }
}
@@ -418,6 +405,18 @@ QemuCocoaView *cocoaView;
    if (isFullscreen) {
        cdx = [[NSScreen mainScreen] frame].size.width / (float)screen.width;
        cdy = [[NSScreen mainScreen] frame].size.height / (float)screen.height;

        /* stretches video, but keeps same aspect ratio */
        if (stretch_video == true) {
            /* use smallest stretch value - prevents clipping on sides */
            if (MIN(cdx, cdy) == cdx) {
                cdy = cdx;
            } else {
                cdx = cdy;
            }
        } else {  /* No stretching */
            cdx = cdy = 1;
        }
        cw = screen.width * cdx;
        ch = screen.height * cdy;
        cx = ([[NSScreen mainScreen] frame].size.width - cw) / 2.0;
@@ -487,43 +486,37 @@ QemuCocoaView *cocoaView;
        isFullscreen = FALSE;
        [self ungrabMouse];
        [self setContentDimensions];
// test if host supports "exitFullScreenModeWithOptions" at compile time
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
        if ([NSView respondsToSelector:@selector(exitFullScreenModeWithOptions:)]) { // test if "exitFullScreenModeWithOptions" is supported on host at runtime
            [self exitFullScreenModeWithOptions:nil];
        } else {
#endif
            [fullScreenWindow close];
            [normalWindow setContentView: self];
            [normalWindow makeKeyAndOrderFront: self];
            [NSMenu setMenuBarVisible:YES];
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
        }
#endif
    } else { // switch from desktop to fullscreen
        isFullscreen = TRUE;
        [normalWindow orderOut: nil]; /* Hide the window */
        [self grabMouse];
        [self setContentDimensions];
// test if host supports "enterFullScreenMode:withOptions" at compile time
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
        if ([NSView respondsToSelector:@selector(enterFullScreenMode:withOptions:)]) { // test if "enterFullScreenMode:withOptions" is supported on host at runtime
            [self enterFullScreenMode:[NSScreen mainScreen] withOptions:[NSDictionary dictionaryWithObjectsAndKeys:
                [NSNumber numberWithBool:NO], NSFullScreenModeAllScreens,
                [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:NO], kCGDisplayModeIsStretched, nil], NSFullScreenModeSetting,
                 nil]];
        } else {
#endif
            [NSMenu setMenuBarVisible:NO];
            fullScreenWindow = [[NSWindow alloc] initWithContentRect:[[NSScreen mainScreen] frame]
                styleMask:NSBorderlessWindowMask
                backing:NSBackingStoreBuffered
                defer:NO];
            [fullScreenWindow setAcceptsMouseMovedEvents: YES];
            [fullScreenWindow setHasShadow:NO];
            [fullScreenWindow setContentView:self];
            [fullScreenWindow setBackgroundColor: [NSColor blackColor]];
            [self setFrame:NSMakeRect(cx, cy, cw, ch)];
            [[fullScreenWindow contentView] addSubview: self];
            [fullScreenWindow makeKeyAndOrderFront:self];
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
        }
#endif
    }
}

@@ -561,7 +554,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;
@@ -794,13 +787,19 @@ QemuCocoaView *cocoaView;
 ------------------------------------------------------
*/
@interface QemuCocoaAppController : NSObject
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
                                             <NSApplicationDelegate>
#endif
{
}
- (void)startEmulationWithArgc:(int)argc argv:(char**)argv;
- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo;
- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
- (void)doToggleFullScreen:(id)sender;
- (void)toggleFullScreen:(id)sender;
- (void)showQEMUDoc:(id)sender;
- (void)showQEMUTec:(id)sender;
- (void)zoomToFit:(id) sender;
- (void)displayConsole:(id)sender;
@end

@implementation QemuCocoaAppController
@@ -829,10 +828,12 @@ QemuCocoaView *cocoaView;
        [normalWindow setAcceptsMouseMovedEvents:YES];
        [normalWindow setTitle:[NSString stringWithFormat:@"QEMU"]];
        [normalWindow setContentView:cocoaView];
#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10)
        [normalWindow useOptimizedDrawing:YES];
#endif
        [normalWindow makeKeyAndOrderFront:self];
        [normalWindow center];

        stretch_video = false;
    }
    return self;
}
@@ -898,13 +899,19 @@ QemuCocoaView *cocoaView;
    exit(status);
}

- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
{
    COCOA_DEBUG("QemuCocoaAppController: openPanelDidEnd\n");

    if(returnCode == NSCancelButton) {
    /* The NSFileHandlingPanelOKButton/NSFileHandlingPanelCancelButton values for
     * returnCode strictly only apply for the 10.6-and-up beginSheetModalForWindow
     * API. For the legacy pre-10.6 beginSheetForDirectory API they are NSOKButton
     * and NSCancelButton. However conveniently the values are the same.
     * We use the non-legacy names because the others are deprecated in OSX 10.10.
     */
    if (returnCode == NSFileHandlingPanelCancelButton) {
        exit(0);
    } else if(returnCode == NSOKButton) {
    } else if (returnCode == NSFileHandlingPanelOKButton) {
        char *img = (char*)[ [ [ sheet URL ] path ] cStringUsingEncoding:NSASCIIStringEncoding];

        char **argv = g_new(char *, 4);
@@ -921,6 +928,16 @@ 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");
@@ -943,8 +960,24 @@ QemuCocoaView *cocoaView;
    [[NSWorkspace sharedWorkspace] openFile:[NSString stringWithFormat:@"%@/../doc/qemu/qemu-tech.html",
        [[NSBundle mainBundle] resourcePath]] withApplication:@"Help Viewer"];
}
@end

/* Stretches video to fit host monitor size */
- (void)zoomToFit:(id) sender
{
    stretch_video = !stretch_video;
    if (stretch_video == true) {
        [sender setState: NSOnState];
    } else {
        [sender setState: NSOffState];
    }
}

/* Displays the console on the screen */
- (void)displayConsole:(id)sender
{
    console_select([sender tag]);
}
@end


int main (int argc, const char * argv[]) {
@@ -1005,7 +1038,8 @@ 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
    [menu addItem: [[[NSMenuItem alloc] initWithTitle:@"Zoom To Fit" action:@selector(zoomToFit:) keyEquivalent:@""] autorelease]];
    menuItem = [[[NSMenuItem alloc] initWithTitle:@"View" action:nil keyEquivalent:@""] autorelease];
    [menuItem setSubmenu:menu];
    [[NSApp mainMenu] addItem:menuItem];
@@ -1116,10 +1150,42 @@ static const DisplayChangeListenerOps dcl_ops = {
    .dpy_refresh = cocoa_refresh,
};

/* Returns a name for a given console */
static NSString * getConsoleName(QemuConsole * console)
{
    return [NSString stringWithFormat: @"%s", qemu_console_get_label(console)];
}

/* Add an entry to the View menu for each console */
static void add_console_menu_entries(void)
{
    NSMenu *menu;
    NSMenuItem *menuItem;
    int index = 0;

    menu = [[[NSApp mainMenu] itemWithTitle:@"View"] submenu];

    [menu addItem:[NSMenuItem separatorItem]];

    while (qemu_console_lookup_by_index(index) != NULL) {
        menuItem = [[[NSMenuItem alloc] initWithTitle: getConsoleName(qemu_console_lookup_by_index(index))
                                               action: @selector(displayConsole:) keyEquivalent: @""] autorelease];
        [menuItem setTag: index];
        [menu addItem: menuItem];
        index++;
    }
}

void cocoa_display_init(DisplayState *ds, int full_screen)
{
    COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n");

    /* if fullscreen mode is to be used */
    if (full_screen == true) {
        [NSApp activateIgnoringOtherApps: YES];
        [(QemuCocoaAppController *)[[NSApplication sharedApplication] delegate] toggleFullScreen: nil];
    }

    dcl = g_malloc0(sizeof(DisplayChangeListener));

    // register vga output callbacks
@@ -1128,4 +1194,9 @@ void cocoa_display_init(DisplayState *ds, int full_screen)

    // register cleanup function
    atexit(cocoa_cleanup);

    /* At this point QEMU has created all the consoles, so we can add View
     * menu entries for them.
     */
    add_console_menu_entries();
}