This patches does the following: - Allows user to select endian format of video display. This allows Mac OS X to be used as a guest and show all its colors correctly. Just add -display-endian-big to the command line to use this feature.
- Removes unneeded #ifdefs in drawRect: method. Correct method selection is done at runtime instead of compile time. This makes one binary work on more versions of Mac OS X rather than just the version that was used to compile it. It also makes the code more efficient. Rather than setting the same variables over and over again, just do it once. - Adds runtime identification code for determining which version of the Mac OS QEMU is running on. Signed-off-by: John Arbuckle <programmingk...@gmail.com> --- ui/cocoa.m | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 42 insertions(+), 7 deletions(-) diff --git a/ui/cocoa.m b/ui/cocoa.m index 704d199..562fa29 100644 --- a/ui/cocoa.m +++ b/ui/cocoa.m @@ -64,6 +64,10 @@ static int last_buttons; int gArgc; char **gArgv; +/* Used in drawRect:. Starts with little endian format. */ +static int bitmap_info = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst; +SInt32 current_mac_os_version; + // keymap conversion int keymap[] = { @@ -238,7 +242,33 @@ static int cocoa_keycode_to_qemu(int keycode) return keymap[keycode]; } +/* Looks for the -display-endian-big option being sent to QEMU. + Fixes the issue with the colors not being displayed correctly with Mac OS X as the host. + It is normally assumed that the frame buffer has data in the little endian format. + Mac OS X uses the big endian format. +*/ +static void scanForDisplayEndianOption(int argc, char * argv[]) +{ + // search for the -display-endian-big option + for(int i = 0; i < argc; i++) { + if(strcmp(argv[i], "-display-endian-big") == 0) { + bitmap_info = kCGImageAlphaNoneSkipFirst; + // remove the option from the argv array + sprintf(argv[i], "%s", "-no-frame"); // no-frame does nothing in cocoa, so it is harmless + break; + } + } +} +/* Finds out what version of the Mac OS your computer is using. */ +static void determineMacOSVersion() +{ + OSErr err_num = Gestalt(gestaltSystemVersion, ¤t_mac_os_version); + if(err_num != noErr) { + current_mac_os_version = -1; + fprintf(stderr, "\nWarning: Failed to determine Mac OS version of your system!\n"); + } +} /* ------------------------------------------------------ @@ -257,6 +287,7 @@ static int cocoa_keycode_to_qemu(int keycode) BOOL isAbsoluteEnabled; BOOL isMouseDeassociated; NSDictionary * window_mode_dict; /* keeps track of the guest' graphic settings */ + CGColorSpaceRef color_space; /* used in drawRect: */ } - (void) switchSurface:(DisplaySurface *)surface; - (void) grabMouse; @@ -299,6 +330,13 @@ QemuCocoaView *cocoaView; screen.width = frameRect.size.width; screen.height = frameRect.size.height; [self updateWindowModeSettings]; + + if (current_mac_os_version >= MAC_OS_X_VERSION_10_4) + color_space = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + else { + /* Using this in Mac OS 10.6 causes occasional crashes in drawRect:. */ + color_space = CGColorSpaceCreateDeviceRGB(); + } } return self; } @@ -361,13 +399,8 @@ QemuCocoaView *cocoaView; screen.bitsPerComponent, //bitsPerComponent screen.bitsPerPixel, //bitsPerPixel (screen.width * (screen.bitsPerComponent/2)), //bytesPerRow -#ifdef __LITTLE_ENDIAN__ - CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), //colorspace for OS X >= 10.4 - kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst, -#else - CGColorSpaceCreateDeviceRGB(), //colorspace for OS X < 10.4 (actually ppc) - kCGImageAlphaNoneSkipFirst, //bitmapInfo -#endif + color_space, + bitmap_info, dataProviderRef, //provider NULL, //decode 0, //interpolate @@ -835,6 +868,7 @@ QemuCocoaView *cocoaView; self = [super init]; if (self) { + determineMacOSVersion(); // create a view and add it to the window cocoaView = [[QemuCocoaView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 640.0, 480.0)]; @@ -918,6 +952,7 @@ QemuCocoaView *cocoaView; COCOA_DEBUG("QemuCocoaAppController: startEmulationWithArgc\n"); int status; + scanForDisplayEndianOption(argc, argv); status = qemu_main(argc, argv, *_NSGetEnviron()); exit(status); } -- 1.7.5.4