[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] cocoa.m
From: |
Mike Kronenberg |
Subject: |
[Qemu-devel] [PATCH] cocoa.m |
Date: |
Fri, 27 May 2005 13:42:32 +0200 |
User-agent: |
Mozilla Thunderbird 1.0.2 (Macintosh/20050317) |
Hello Fabrice, hello List
we are heavily working on cocoa.m.
according to yesterdays post from pierre I post my patch.
This patch consists of the following changes/additions:
from Peter Stewart:
- openGL instead of QD
leaves more cpu power to qemu as windowdrawing is done by the gpu.
Yes, I posted a Benchmark last week, 3.5% on a 1.5ghz. :)
Maybe less on a highend... but you can get quite a overproportional
speedbump on a lower end Machine!
from Guillaume Outers:
- fix for wrong limitation of keymap
from me
- full keyboard support
- full mousesupport
- toolbar for fda, cdrom, shutdown, reset
- new commandline switches (all handled by cocoa.m)
-cocoaname NAME => sets name of the running guestPC (for saving VM's
and thumbnails)
-cocoapath PATH => sets the path to where WM's and thumnails are saved
-cocoalivethumbnail => qemu produces a 100x75 PNG thumbnail every
10 sec
-cocoawindowname NAME => sets the name on the qemu window (for branding)
These switches allow Apps like qemuX or Q (atm known as cocoaqemu)
to take control over qemu
Mike
Index: cocoa.m
===================================================================
RCS file: /cvsroot/qemu/qemu/cocoa.m,v
retrieving revision 1.4
diff -u -r1.4 cocoa.m
--- cocoa.m 7 Apr 2005 20:36:50 -0000 1.4
+++ cocoa.m 27 May 2005 10:49:13 -0000
@@ -25,24 +25,24 @@
/*
Todo : x miniaturize window
x center the window
- - save window position
- - handle keyboard event
- - handle mouse event
+ / save window position
+ / handle keyboard event
+ / handle mouse event
- non 32 bpp support
- full screen
- - mouse focus
+ / mouse focus
x simple graphical prompt to demo
- - better graphical prompt
+ / better graphical prompt
*/
#import <Cocoa/Cocoa.h>
-#include "vl.h"
-
-NSWindow *window = NULL;
-NSQuickDrawView *qd_view = NULL;
+#include <OpenGL/CGLCurrent.h>
+#include <OpenGL/CGLContext.h>
+#include "vl.h"
+/* for main */
int gArgc;
char **gArgv;
DisplayState current_ds;
@@ -50,325 +50,828 @@
/* main defined in qemu/vl.c */
int qemu_main(int argc, char **argv);
-/* To deal with miniaturization */
address@hidden QemuWindow : NSWindow
-{ }
address@hidden
-
+/* pc Model */
+id pcModel;
+NSString *pcStatus;
+NSArray *fileTypes; //set allowed filetypes
+
+/* pc View */
+id pcWindowView;
+id pcWindow;
+id progressWindow;
+id configWindow;
+
+/* openGL */
+id ogl_view = NULL;
+#define SCREEN_BPP 32
+GLint screen_tex = 0;
+GLuint display_list_tex = 0;
+
+/* NSApp controller */
+id gui_controller;
+int grab = 0;
+int modifiers_state[256];
/*
------------------------------------------------------
- Qemu Video Driver
+ Headers
+
------------------------------------------------------
*/
+
/*
------------------------------------------------------
- cocoa_update
+ QemuCocoaPcWindowView
------------------------------------------------------
*/
-static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
address@hidden QemuCocoaPcWindowView : NSObject
{
- //printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
-
- /* Use QDFlushPortBuffer() to flush content to display */
- RgnHandle dirty = NewRgn ();
- RgnHandle temp = NewRgn ();
-
- SetEmptyRgn (dirty);
-
- /* Build the region of dirty rectangles */
- MacSetRectRgn (temp, x, y,
- x + w, y + h);
- MacUnionRgn (dirty, temp, dirty);
-
- /* Flush the dirty region */
- QDFlushPortBuffer ( [ qd_view qdPort ], dirty );
- DisposeRgn (dirty);
- DisposeRgn (temp);
+ /* pcWindow */
+ NSToolbar *pcWindowToolbar;
+
+ /* progressWindow */
+ NSTextField *progressText;
+ NSProgressIndicator *progressIndicator;
+
+ /* configWindow */
+ NSWindow *configWindow;
+ NSTextField *pcname;
+ NSTextField *pcram;
+ NSTextField *pcfda;
+ NSTextField *pchda;
+ NSTextField *pccdrom;
+ NSTextField *pcoptions;
}
+/* pcWindow */
+- (void) pcWindowSetup: (int)w height:(int)h;
+
+/* pcWindow toolbar selectors */
+- (void) changeDevice: (id)sender;
+- (void) changeDeviceSheetDidEnd: (NSOpenPanel *)sheet
returnCode:(int)returnCode contextInfo:(NSString *)contextInfo;
+- (void) shutdownPC;
+- (void) shutdownPCSheetDidEnd: (NSWindow *)sheet returnCode: (int)returnCode
contextInfo: (void *)contextInfo;
+- (void) shutdownPC2SheetDidEnd: (NSWindow *)sheet returnCode: (int)returnCode
contextInfo: (void *)contextInfo;
+- (void) resetPC;
+
+/* pcWindow toolbar delegates */
+- (NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier:
(NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted;
+- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar;
+- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar;
+- (BOOL) validateToolbarItem:(NSToolbarItem *)theItem;
+
+/* pcWindow window delegates */
+- (void) windowDidBecomeKey:(NSNotification *)aNotification;
+- (void) windowDidResignKey:(NSNotification *)aNotification;
+
+/* progressWindow */
+- (void) progressWindowSetup;
+- (void) showProgressWindow: (NSString *)text;
+- (void) hideProgressWindow;
+
+/* config Window */
+- (void) configWindowSetup;
+- (void) closeConfigWindowQuit;
+- (void) closeConfigWindowStart;
+- (void) chooseFile:(id)sender;
+- (void) chooseFileSheetDidEnd: (NSOpenPanel *)sheet
returnCode:(int)returnCode contextInfo:(NSString *)contextInfo;
address@hidden
+
/*
------------------------------------------------------
- cocoa_resize
+ QemuWindow (subclass of NSWindow)
------------------------------------------------------
*/
-static void cocoa_resize(DisplayState *ds, int w, int h)
address@hidden QemuWindow : NSWindow
{
- const int device_bpp = 32;
- static void *screen_pixels;
- static int screen_pitch;
- NSRect contentRect;
-
- //printf("resizing to %d %d\n", w, h);
-
- contentRect = NSMakeRect (0, 0, w, h);
- if(window)
- {
- [window close];
- [window release];
- }
- window = [ [ QemuWindow alloc ] initWithContentRect:contentRect
-
styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
- backing:NSBackingStoreBuffered defer:NO];
- if(!window)
- {
- fprintf(stderr, "(cocoa) can't create window\n");
- exit(1);
- }
-
- if(qd_view)
- [qd_view release];
-
- qd_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
-
- if(!qd_view)
- {
- fprintf(stderr, "(cocoa) can't create qd_view\n");
- exit(1);
- }
-
- [ window setAcceptsMouseMovedEvents:YES ];
- [ window setTitle:@"Qemu" ];
- [ window setReleasedWhenClosed:NO ];
-
- /* Set screen to black */
- [ window setBackgroundColor: [NSColor blackColor] ];
-
- /* set window position */
- [ window center ];
-
- [ qd_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
- [ [ window contentView ] addSubview:qd_view ];
- [ qd_view release ];
- [ window makeKeyAndOrderFront:nil ];
-
- /* Careful here, the window seems to have to be onscreen to do that */
- LockPortBits ( [ qd_view qdPort ] );
- screen_pixels = GetPixBaseAddr ( GetPortPixMap ( [ qd_view qdPort ] ) );
- screen_pitch = GetPixRowBytes ( GetPortPixMap ( [ qd_view qdPort ] ) );
- UnlockPortBits ( [ qd_view qdPort ] );
- {
- int vOffset = [ window frame ].size.height -
- [ qd_view frame ].size.height - [ qd_view frame ].origin.y;
-
- int hOffset = [ qd_view frame ].origin.x;
-
- screen_pixels += (vOffset * screen_pitch) + hOffset *
(device_bpp/8);
- }
- ds->data = screen_pixels;
- ds->linesize = screen_pitch;
- ds->depth = device_bpp;
- ds->width = w;
- ds->height = h;
-
- current_ds = *ds;
}
+- (void) miniaturize:(id)sender;
+- (void) display;
+- (BOOL) windowShouldClose:(id)sender;
address@hidden
+
/*
------------------------------------------------------
- keymap conversion
+ QemuCocoaQuickDrawView (subclass of NSQuickDrawView)
------------------------------------------------------
*/
-
-static int keymap[] =
-{
- 30, //'a' 0x0
- 31, //'s'
- 32, //'d'
- 33, //'f'
- 35, //'h'
- 34, //'g'
- 44, //'z'
- 45, //'x'
- 46, //'c'
- 47, //'v'
- 0, // 0 0x0a
- 48, //'b'
- 16, //'q'
- 17, //'w'
- 18, //'e'
- 19, //'r'
- 21, //'y' 0x10
- 20, //'t'
- 2, //'1'
- 3, //'2'
- 4, //'3'
- 5, //'4'
- 7, //'6'
- 6, //'5'
- 0, //'='
- 10, //'9'
- 8, //'7' 0x1A
- 0, //'-'
- 9, //'8'
- 11, //'0'
- 27, //']'
- 24, //'o'
- 22, //'u' 0x20
- 26, //'['
- 23, //'i'
- 25, //'p'
- 28, //'\n'
- 38, //'l'
- 36, //'j'
- 40, //'"'
- 37, //'k'
- 39, //';'
- 15, //'\t' 0x30
- 0, //' '
- 0, //'`'
- 14, //'<backspace>'
- 0, //'' 0x34
- 0, //'<esc>'
- 0, //'<esc>'
- /* Not completed to finish see
http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup
*/
-};
-
-static int cocoa_keycode_to_qemu(int keycode)
address@hidden QemuCocoaOpenGLView : NSOpenGLView
{
- if(sizeof(keymap) <= keycode)
- {
- printf("(cocoa) warning unknow keycode 0x%x\n", keycode);
- return 0;
- }
- return keymap[keycode];
}
+- (void)mouseDown:(NSEvent *)theEvent;
address@hidden
+
/*
------------------------------------------------------
- cocoa_refresh
+ QemuCocoaPcModel
------------------------------------------------------
*/
-static void cocoa_refresh(DisplayState *ds)
address@hidden QemuCocoaPcModel : NSObject
{
- //printf("cocoa_refresh \n");
- NSDate *distantPast;
- NSEvent *event;
- NSAutoreleasePool *pool;
- int grab = 1;
-
- pool = [ [ NSAutoreleasePool alloc ] init ];
- distantPast = [ NSDate distantPast ];
-
- if (is_active_console(vga_console))
- vga_update_display();
- do {
- event = [ NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:distantPast
- inMode: NSDefaultRunLoopMode dequeue:YES ];
- if (event != nil) {
- switch ([event type]) {
- case NSKeyDown:
- if(grab)
- {
- int keycode = cocoa_keycode_to_qemu([event keyCode]);
-
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode & 0x7f);
- }
- break;
- case NSKeyUp:
- if(grab)
- {
- int keycode = cocoa_keycode_to_qemu([event keyCode]);
-
- if (keycode & 0x80)
- kbd_put_keycode(0xe0);
- kbd_put_keycode(keycode | 0x80);
- }
- break;
- case NSScrollWheel:
-
- case NSLeftMouseDown:
- case NSLeftMouseUp:
-
- case NSOtherMouseDown:
- case NSRightMouseDown:
-
- case NSOtherMouseUp:
- case NSRightMouseUp:
-
- case NSMouseMoved:
- case NSOtherMouseDragged:
- case NSRightMouseDragged:
- case NSLeftMouseDragged:
-
- default: [NSApp sendEvent:event];
- }
- }
- } while(event != nil);
+ NSString *pcWindowName;
+ NSString *pcName;
+ NSString *pcPath;
+ int pcLiveThumbnail;
+ NSTimer *timer;
}
+- (NSString *) pcName;
+- (NSString *) pcWindowName;
+- (NSImage *) thumbnailFast;
+- (NSImage *) thumbnailQuality;
+
+- (void) liveThumbnail;
+- (void) saveVM;
+- (int) ejectDevice: (BlockDriverState *) bs withForce: (int) force;
+- (void) ejectImage:(const char *) filename withForce: (int) force;
+- (void) changeDeviceImage: (const char *) device filename: (const char *)
filename withForce: (int) force;
+- (void) startPC:(int)argc withArgs:(char**)argv;
+- (void) resetPC;
+- (void) shutdownPC;
address@hidden
+
/*
------------------------------------------------------
- cocoa_cleanup
+ NSApp
------------------------------------------------------
*/
-
-static void cocoa_cleanup(void)
address@hidden QemuCocoaGUIController : NSObject
{
-
}
+/* NSApp methods */
+- (void) applicationMenuSetup;
+- (void) windowMenuSetup;
+
+/* NSApp delegates*/
+- (void) applicationWillFinishLaunching: (NSNotification *) note;
+- (void) applicationDidFinishLaunching: (NSNotification *) note;
+- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication
*)sender;
address@hidden
+
/*
------------------------------------------------------
- cocoa_display_init
+ QemuCocoa Video Driver
------------------------------------------------------
*/
+static void cocoa_update(DisplayState *ds, int x, int y, int w, int h);
+static void cocoa_resize(DisplayState *ds, int w, int h);
+static int cocoa_keycode_to_qemu(int keycode);
+static void cocoa_refresh(DisplayState *ds);
+static void cocoa_cleanup(void) ;
+void cocoa_display_init(DisplayState *ds, int full_screen);
+
-void cocoa_display_init(DisplayState *ds, int full_screen)
-{
- ds->dpy_update = cocoa_update;
- ds->dpy_resize = cocoa_resize;
- ds->dpy_refresh = cocoa_refresh;
-
- cocoa_resize(ds, 640, 400);
-
- atexit(cocoa_cleanup);
-}
/*
------------------------------------------------------
- Interface with Cocoa
+ Implementations
+
------------------------------------------------------
*/
-
-
/*
------------------------------------------------------
- QemuWindow
- Some trick from SDL to use miniwindow
+ QemuCocoaPcWindowView
------------------------------------------------------
*/
-static void QZ_SetPortAlphaOpaque ()
-{
- /* Assume 32 bit if( bpp == 32 )*/
- if ( 1 ) {
-
- uint32_t *pixels = (uint32_t*) current_ds.data;
- uint32_t rowPixels = current_ds.linesize / 4;
- uint32_t i, j;
-
- for (i = 0; i < current_ds.height; i++)
- for (j = 0; j < current_ds.width; j++) {
address@hidden QemuCocoaPcWindowView
+/* creating pcWindow */
+- (void) pcWindowSetup: (int)w height:(int)h
+{
+ /* Init pixel format attribs */
+ NSOpenGLPixelFormatAttribute attrs[] =
+ {
+ NSOpenGLPFAAccelerated,
+ NSOpenGLPFANoRecovery,
+ NSOpenGLPFADoubleBuffer,
+ 0
+ };
+
+ NSRect contentRect = NSMakeRect (0, 0, w, h);
+
+ /* Get pixel format from OpenGL */
+ NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc]
initWithAttributes:attrs];
+ if (!pixFmt)
+ {
+ fprintf(stderr, "No pixel format -- exiting");
+ exit(1);
+ }
+
+ pcWindow = [ [ QemuWindow alloc ] initWithContentRect:NSMakeRect (0, 0,
w, h)
+
styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
+ backing:NSBackingStoreBuffered defer:NO];
+
+ if(!pcWindow)
+ {
+ fprintf(stderr, "(cocoa) can't create pcWindow\n");
+ exit(1);
+ }
+
+ ogl_view = [ [ QemuCocoaOpenGLView alloc ] initWithFrame:contentRect
pixelFormat:pixFmt ];
+
+ if(!ogl_view)
+ {
+ fprintf(stderr, "(cocoa) can't create ogl_view\n");
+ exit(1);
+ }
+
+ [ pcWindow center ];
+ [ pcWindow setFrameAutosaveName: [ NSString stringWithFormat:@"%@ -
%@", [ pcModel pcWindowName ], [ pcModel pcName ] ] ];
+ [ pcWindow setAcceptsMouseMovedEvents:YES ];
+ [ pcWindow setTitle: [ NSString stringWithFormat:@"%@ - %@", [ pcModel
pcWindowName ], [ pcModel pcName ] ] ];
+ [ pcWindow setReleasedWhenClosed:NO ];
+ [ pcWindow setDelegate: self ];
+
+ //Toolbar
+ pcWindowToolbar = [ [ [ NSToolbar alloc ] initWithIdentifier:
@"pcWindowToolbarIdentifier" ] autorelease ];
+ [ pcWindowToolbar setAllowsUserCustomization: YES ]; //allow
customisation
+ [ pcWindowToolbar setAutosavesConfiguration: YES ]; //autosave changes
+// [ pcWindowToolbar setDisplayMode: NSToolbarDisplayModeLabelOnly ];
//what is shown
+ [ pcWindowToolbar setDisplayMode: NSToolbarDisplayModeIconOnly ];
//what is shown
+ [ pcWindowToolbar setSizeMode:NSToolbarSizeModeSmall ]; //default
Toolbar Size
+ [ pcWindowToolbar setDelegate: self ]; // We are the delegate
+ [ pcWindow setToolbar: pcWindowToolbar ]; // Attach the toolbar to the
document window
+
+ [ ogl_view setAutoresizingMask: NSViewWidthSizable |
NSViewHeightSizable ];
+ [ [ pcWindow contentView ] addSubview:ogl_view ];
+ [ ogl_view release ];
+
+ [ pcWindow makeKeyAndOrderFront:nil ];
+}
+
+/* Toolbar Delegates*/
+- (NSToolbarItem *) toolbar: (NSToolbar *)toolbar itemForItemIdentifier:
(NSString *) itemIdent willBeInsertedIntoToolbar:(BOOL) willBeInserted
+{
+ NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc]
initWithItemIdentifier: itemIdent] autorelease ];
+ if ([itemIdent isEqual: @"fdaChangeIdentifier"]) {
+ [toolbarItem setLabel: @"Floppy A"];
+ [toolbarItem setPaletteLabel: @"Floppy A"];
+ [toolbarItem setToolTip: @"Change Floppy Drive A Image"];
+ [toolbarItem setImage: [NSImage imageNamed:
@"cocoa_tb_dmg_32_a.png"]];
+ [toolbarItem setTarget: self];
+ [toolbarItem setAction: @selector( changeDevice: )];
+ } else if([itemIdent isEqual: @"fdbChangeIdentifier"]) {
+ [toolbarItem setLabel: @"Floppy B"];
+ [toolbarItem setPaletteLabel: @"Floppy B"];
+ [toolbarItem setToolTip: @"Change Floppy Drive B Image"];
+ [toolbarItem setImage: [NSImage imageNamed:
@"cocoa_tb_dmg_32_b.png"]];
+ [toolbarItem setTarget: self];
+ [toolbarItem setAction: @selector( changeDevice: )];
+ } else if([itemIdent isEqual: @"cdromChangeIdentifier"]) {
+ [toolbarItem setLabel: @"CD-ROM"];
+ [toolbarItem setPaletteLabel: @"CD-ROM"];
+ [toolbarItem setToolTip: @"Change CD-ROM Image"];
+ [toolbarItem setImage: [NSImage imageNamed:
@"cocoa_tb_cdrom_32.png"]];
+ [toolbarItem setTarget: self];
+ [toolbarItem setAction: @selector( changeDevice: )];
+ } else if([itemIdent isEqual: @"systemResetIdentifier"]) {
+ [toolbarItem setLabel: @"Reset PC"];
+ [toolbarItem setPaletteLabel: @"Reset PC"];
+ [toolbarItem setToolTip: @"Reset PC"];
+ [toolbarItem setImage: [NSImage imageNamed:
@"cocoa_tb_reset_32.png"]];
+ [toolbarItem setTarget: self];
+ [toolbarItem setAction: @selector( resetPC )];
+ } else if ([itemIdent isEqual: @"shutdownPCIdentifier"]) {
+ [toolbarItem setLabel: @"Shutdown PC"];
+ [toolbarItem setPaletteLabel: @"Shutdown PC"];
+ [toolbarItem setToolTip: @"Shutdown PC"];
+ [toolbarItem setImage: [NSImage imageNamed:
@"cocoa_tb_shutdown_32.png"]];
+ [toolbarItem setTarget: self];
+ [toolbarItem setAction: @selector( shutdownPC )];
+ } else {
+ toolbarItem = nil;
+ }
+
+ return toolbarItem;
+}
+
+- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
+{
+ return [NSArray arrayWithObjects:
+ @"fdaChangeIdentifier",
+ @"fdbChangeIdentifier",
+ @"cdromChangeIdentifier",
+ @"systemResetIdentifier",
+ @"shutdownPCIdentifier",
+ NSToolbarCustomizeToolbarItemIdentifier,
+ NSToolbarFlexibleSpaceItemIdentifier,
+ NSToolbarSpaceItemIdentifier,
+ NSToolbarSeparatorItemIdentifier,
+ nil];
+}
+
+- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
+{
+ return [NSArray arrayWithObjects:
+ @"fdaChangeIdentifier",
+ @"cdromChangeIdentifier",
+ NSToolbarSeparatorItemIdentifier,
+ @"shutdownPCIdentifier",
+ NSToolbarFlexibleSpaceItemIdentifier,
+ @"systemResetIdentifier",
+ nil];
+}
+
+- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
+{
+ return YES;
+}
+
+/* creating progressWindow */
+- (void)progressWindowSetup
+{
+ progressWindow = [ [ NSWindow alloc ] initWithContentRect:NSMakeRect
(0, 0, 250, 50)
+
styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
+ backing:NSBackingStoreBuffered defer:NO ];
+ if(!progressWindow)
+ {
+ fprintf(stderr, "(cocoa) can't create progressWindow\n");
+ exit(1);
+ }
+ [ progressWindow setDelegate: self ];
+ [ progressWindow setMinSize:NSMakeRect (0, 0, 250, 50).size ];
+
+ /* creating NSprogressbarIndicator */
+ progressIndicator = [ [ NSProgressIndicator alloc ]
+ initWithFrame:NSMakeRect(100, 20, 128,
NSProgressIndicatorPreferredThickness) ];
+ [ progressIndicator setIndeterminate:YES ];
+ [ progressIndicator setUsesThreadedAnimation: YES ];
+ [ [ progressWindow contentView ] addSubview:progressIndicator ];
+
+ /* creating NSTextField */
+ progressText = [ [ NSTextField alloc ] initWithFrame: NSMakeRect(20,
20, 80, 17) ];
+ [ progressText setDrawsBackground: NO ];
+ [ progressText setBordered: NO ];
+ [ progressText setStringValue: [ [ [ NSAttributedString alloc]
initWithString:@"Saving PC" attributes:[ NSDictionary dictionaryWithObject: [
NSFont boldSystemFontOfSize:[ NSFont systemFontSize] ]
forKey:NSFontAttributeName ] ] autorelease ] ];
+ [ progressText setSelectable:NO ];
+ [ progressText setEditable:NO ];
+ [ [ progressWindow contentView ] addSubview: progressText ];
+ [ progressText release ];
+}
+
+- (void) showProgressWindow: (NSString *)text
+{
+ [ progressText setStringValue: [ [ [ NSAttributedString alloc]
initWithString:text attributes:[ NSDictionary dictionaryWithObject: [ NSFont
boldSystemFontOfSize:[ NSFont systemFontSize] ] forKey:NSFontAttributeName ] ]
autorelease ] ];
+ [ progressIndicator startAnimation:nil ];
+ [ NSApp beginSheet:progressWindow
+ modalForWindow:pcWindow
+ modalDelegate:nil
+ didEndSelector:nil
+ contextInfo:nil ];
+}
+
+- (void) hideProgressWindow
+{
+ [ NSApp endSheet:progressWindow ];
+ [ progressWindow orderOut: [ progressWindow self ] ];
+ [ progressIndicator stopAnimation:nil ];
+}
+
+- (void) changeDevice:(id)sender
+{
+ NSString *description;
+ NSString *context;
+
+ if ([ [ sender itemIdentifier ] isEqualTo: @"fdaChangeIdentifier" ]) {
+ description = @"Floppy A";
+ context = @"fda";
+ } else if ([ [ sender itemIdentifier ] isEqualTo:
@"fdbChangeIdentifier" ]) {
+ description = @"Floppy B";
+ context = @"fdb";
+ } else if ([ [ sender itemIdentifier ] isEqualTo:
@"cdromChangeIdentifier" ]) {
+ description = @"CD-Rom";
+ context = @"cdrom";
+ } else {
+ description = @"";
+ context = @"";
+ }
+
+ NSOpenPanel *op = [[NSOpenPanel alloc] init];
+ [op setPrompt: [ NSString stringWithFormat:@"choose Image for %@",
description ] ];
+ [op setMessage: [ NSString stringWithFormat:@"Select the diskimage you
want to use as address@hidden the \"Cancel\" button to quit", description ] ];
+ [op beginSheetForDirectory:nil
+ file:nil
+ types:fileTypes
+ modalForWindow:pcWindow
+ modalDelegate:self
+
didEndSelector:@selector(changeDeviceSheetDidEnd:returnCode:contextInfo:)
+ contextInfo:context ];
+}
+
+- (void)changeDeviceSheetDidEnd: (NSOpenPanel *)sheet
+ returnCode:(int)returnCode
+ contextInfo:(NSString *)contextInfo
+{
+ if(returnCode == NSOKButton)
+ [ pcModel changeDeviceImage:[ contextInfo cString] filename:[ [
sheet filename ] cString ] withForce:1 ];
+}
+
+- (void) shutdownPC
+{
+ if ( [ [ pcModel pcName ] isEqual:@"" ]) {
+ NSAlert *alert = [ NSAlert alertWithMessageText:@"Shutting down
Guest PC"
+ defaultButton:@"Cancel"
+ alternateButton:@"Shutdown"
+ otherButton:@""
+ informativeTextWithFormat:@"The Guest OS is still
running. If you shutdown the Guest PC, you may loose Data." ];
+ [ alert beginSheetModalForWindow:pcWindow
+ modalDelegate:self
+
didEndSelector:@selector(shutdownPC2SheetDidEnd:returnCode:contextInfo:)
+ contextInfo:nil];
+ } else {
+ NSAlert *alert = [ NSAlert alertWithMessageText:@"Shutting down
Guest PC"
+ defaultButton:@"Save PC"
+ alternateButton:@"Cancel"
+ otherButton:@"Don't save PC"
+ informativeTextWithFormat:@"The Guest OS is still
running. If you don't save the PC, you may loose Data." ];
+ [ alert beginSheetModalForWindow:pcWindow
+ modalDelegate:self
+
didEndSelector:@selector(shutdownPCSheetDidEnd:returnCode:contextInfo:)
+ contextInfo:nil];
+ }
+}
+
+- (void) shutdownPCSheetDidEnd: (NSWindow *)sheet
+ returnCode: (int)returnCode
+ contextInfo: (void *)contextInfo
+{
+ [ [ sheet window ] orderOut:self ];
+ if (returnCode == NSAlertDefaultReturn)
+ {
+ [ pcModel saveVM ];
+ [ pcModel shutdownPC ];
+ exit(2); //return 2 => saved
+ }
+ else if (returnCode == NSAlertOtherReturn)
+ {
+ [ pcModel shutdownPC ];
+ exit(0); //return 0 => shutdown
+ }
+}
+
+- (void) shutdownPC2SheetDidEnd: (NSWindow *)sheet
+ returnCode: (int)returnCode
+ contextInfo: (void *)contextInfo
+{
+ [ [ sheet window ] orderOut:self ];
+ if (returnCode == NSAlertDefaultReturn)
+ {
+ }
+ else
+ {
+ [ pcModel shutdownPC ];
+ exit(0); //return 0 => shutdown
+ }
+}
+- (void) resetPC
+{
+ qemu_system_reset_request();
+}
+
+/* Window delegates */
+- (void) windowDidBecomeKey:(NSNotification *)aNotification
+{
+}
+
+- (void) windowDidResignKey:(NSNotification *)aNotification
+{
+ /* ungrab Mouse */
+ grab = 0;
+ [ pcWindow setTitle: [ NSString stringWithFormat: @"%@ - %@",[ pcModel
pcWindowName ], [ pcModel pcName ] ] ];
+ [ NSCursor unhide ];
+ CGAssociateMouseAndMouseCursorPosition ( TRUE );
+
+ /* reset Key Modifiers */
+ int i;
+ for(i = 0; i < 256; i++) {
+ if (modifiers_state[i]) {
+ if (i & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(i | 0x80);
+ modifiers_state[i] = 0;
+ }
+ }
+}
+
+/* create configWindow */
+- (void)configWindowSetup
+{
+ configWindow = [ [ NSWindow alloc ] initWithContentRect:NSMakeRect (0,
0, 400, 358)
+
styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
+ backing:NSBackingStoreBuffered defer:NO];
+ if(!configWindow)
+ {
+ fprintf(stderr, "(cocoa) can't create configWindow\n");
+ exit(1);
+ }
+ [ configWindow setMinSize:NSMakeRect (0, 0, 400, 358).size ];
+ [ configWindow setTitle:@"cocoaqemu - PC Setup" ];
+ [ configWindow setReleasedWhenClosed:YES ];
+ [ configWindow setDelegate: self ];
+
+ //Title
+ NSTextField *pctitle = [ [ NSTextField alloc ] initWithFrame:
NSMakeRect(20, 326, 360, 17) ];
+ [ pctitle setDrawsBackground: NO ];
+ [ pctitle setBordered: NO ];
+ [ pctitle setStringValue: [ [ [ NSAttributedString alloc]
initWithString:@"Configure your qemu PC" attributes:[ NSDictionary
dictionaryWithObject: [ NSFont boldSystemFontOfSize:[ NSFont systemFontSize] ]
forKey:NSFontAttributeName ] ] autorelease ] ];
+ [ pctitle setSelectable:NO ];
+ [ pctitle setEditable:NO ];
+ [ [ configWindow contentView ] addSubview: pctitle ];
+ [ pctitle release ];
+
+ NSTextField *pcramlabel = [[NSTextField alloc] initWithFrame:
NSMakeRect(20, 223, 100, 17) ];
+ [ pcramlabel setDrawsBackground: NO ];
+ [ pcramlabel setBordered: NO ];
+ [ pcramlabel setAlignment: NSRightTextAlignment ];
+ [ pcramlabel setStringValue: @"Ram" ];
+ [ pcramlabel setEditable:NO ];
+ [ pcramlabel setSelectable:NO ];
+ [ [ configWindow contentView ] addSubview: pcramlabel ];
+ [ pcramlabel release ];
+
+ NSTextField *pcdriveslabel = [[NSTextField alloc] initWithFrame:
NSMakeRect(20, 176, 100, 17) ];
+ [ pcdriveslabel setDrawsBackground: NO ];
+ [ pcdriveslabel setBordered: NO ];
+ [ pcdriveslabel setAlignment: NSRightTextAlignment ];
+ [ pcdriveslabel setStringValue: @"Drives" ];
+ [ pcdriveslabel setEditable:NO ];
+ [ pcdriveslabel setSelectable:NO ];
+ [ [ configWindow contentView ] addSubview: pcdriveslabel ];
+ [ pcdriveslabel release ];
+
+ NSTextField *pcdrivesAlabel = [[NSTextField alloc] initWithFrame:
NSMakeRect(108, 176, 100, 17) ];
+ [ pcdrivesAlabel setDrawsBackground: NO ];
+ [ pcdrivesAlabel setBordered: NO ];
+ [ pcdrivesAlabel setAlignment: NSRightTextAlignment ];
+ [ pcdrivesAlabel setStringValue: @"Floppy A" ];
+ [ pcdrivesAlabel setEditable:NO ];
+ [ pcdrivesAlabel setSelectable:NO ];
+ [ [ configWindow contentView ] addSubview: pcdrivesAlabel ];
+ [ pcdrivesAlabel release ];
+
+ NSTextField *pcdrivesClabel = [[NSTextField alloc] initWithFrame:
NSMakeRect(108, 142, 100, 17) ];
+ [ pcdrivesClabel setDrawsBackground: NO ];
+ [ pcdrivesClabel setBordered: NO ];
+ [ pcdrivesClabel setAlignment: NSRightTextAlignment ];
+ [ pcdrivesClabel setStringValue: @"Harddisk" ];
+ [ pcdrivesClabel setEditable:NO ];
+ [ pcdrivesClabel setSelectable:NO ];
+ [ [ configWindow contentView ] addSubview: pcdrivesClabel ];
+ [ pcdrivesClabel release ];
+
+ NSTextField *pcdrivesDlabel = [[NSTextField alloc] initWithFrame:
NSMakeRect(108, 108, 100, 17) ];
+ [ pcdrivesDlabel setDrawsBackground: NO ];
+ [ pcdrivesDlabel setBordered: NO ];
+ [ pcdrivesDlabel setAlignment: NSRightTextAlignment ];
+ [ pcdrivesDlabel setStringValue: @"CD-ROM" ];
+ [ pcdrivesDlabel setEditable:NO ];
+ [ pcdrivesDlabel setSelectable:NO ];
+ [ [ configWindow contentView ] addSubview: pcdrivesDlabel ];
+ [ pcdrivesDlabel release ];
+
+ NSTextField *pcoptionslabel = [[NSTextField alloc] initWithFrame:
NSMakeRect(20, 63, 100, 17) ];
+ [ pcoptionslabel setDrawsBackground: NO ];
+ [ pcoptionslabel setBordered: NO ];
+ [ pcoptionslabel setAlignment: NSRightTextAlignment ];
+ [ pcoptionslabel setStringValue: @"Options" ];
+ [ pcoptionslabel setEditable:NO ];
+ [ pcoptionslabel setSelectable:NO ];
+ [ [ configWindow contentView ] addSubview: pcoptionslabel ];
+ [ pcoptionslabel release ];
+
+ pcram = [ [ NSTextField alloc ] initWithFrame: NSMakeRect(128, 220, 50,
22) ];
+ [ pcram setBezelStyle: 1 ];
+ [ pcram setBezeled: YES ];
+ [ pcram setEditable: YES ];
+ [ pcram setSelectable:YES ];
+ [ [ pcram cell ] setScrollable: YES ];
+ [ [ pcram cell ] setWraps: NO ];
+ [ pcram setStringValue: @"" ];
+ [ [ configWindow contentView ] addSubview: pcram ];
+ [ pcram release ];
+
+ pcfda = [ [ NSTextField alloc ] initWithFrame: NSMakeRect(211, 175,
136, 22) ];
+ [ pcfda setBezelStyle: 1 ];
+ [ pcfda setBezeled: YES ];
+ [ pcfda setEditable: YES ];
+ [ pcfda setSelectable:YES ];
+ [ [ pcfda cell ] setScrollable: YES ];
+ [ [ pcfda cell ] setWraps: NO ];
+ [ pcfda setStringValue: @"" ];
+ [ [ configWindow contentView ] addSubview: pcfda ];
+ [ pcfda release ];
+
+ pchda = [ [ NSTextField alloc ] initWithFrame: NSMakeRect(211, 141,
136, 22) ];
+ [ pchda setBezelStyle: 1 ];
+ [ pchda setBezeled: YES ];
+ [ pchda setEditable: YES ];
+ [ pchda setSelectable:YES ];
+ [ [ pchda cell ] setScrollable: YES ];
+ [ [ pchda cell ] setWraps: NO ];
+ [ pchda setStringValue: @"" ];
+ [ [ configWindow contentView ] addSubview: pchda ];
+ [ pchda release ];
+
+ pccdrom = [ [ NSTextField alloc ] initWithFrame: NSMakeRect(211, 107,
136, 22) ];
+ [ pccdrom setBezelStyle: 1 ];
+ [ pccdrom setBezeled: YES ];
+ [ pccdrom setEditable: YES ];
+ [ pccdrom setSelectable:YES ];
+ [ [ pccdrom cell ] setScrollable: YES ];
+ [ [ pccdrom cell ] setWraps: NO ];
+ [ pccdrom setStringValue: @"" ];
+ [ [ configWindow contentView ] addSubview: pccdrom ];
+ [ pccdrom release ];
+
+ pcoptions = [ [ NSTextField alloc ] initWithFrame: NSMakeRect(128, 62,
250, 22) ];
+ [ pcoptions setBezelStyle: 1 ];
+ [ pcoptions setBezeled: YES ];
+ [ pcoptions setEditable: YES ];
+ [ pcoptions setSelectable:YES ];
+ [ pcoptions setStringValue: @"" ];
+ [ [ pcoptions cell ] setScrollable: YES ];
+ [ [ pcoptions cell ] setWraps: NO ];
+ [ [ configWindow contentView ] addSubview: pcoptions ];
+ [ pcoptions release ];
+
+ NSButton *fdabutton = [ [ [ NSButton alloc ] initWithFrame:
NSMakeRect(355,167,30,30) ] autorelease ];
+ [ fdabutton setButtonType: NSMomentaryPushButton ];
+ [ fdabutton setBezelStyle: NSCircularBezelStyle ];
+ [ fdabutton setTitle: @"..." ];
+ [ fdabutton setTarget: self ];
+ [ fdabutton setTag:1 ];
+ [ fdabutton setAction: @selector( chooseFile: ) ];
+ [ [ configWindow contentView ] addSubview: fdabutton ];
+
+ NSButton *hdabutton = [ [ [ NSButton alloc ] initWithFrame:
NSMakeRect(355,132,30,30) ] autorelease ];
+ [ hdabutton setButtonType: NSMomentaryPushButton ];
+ [ hdabutton setBezelStyle: NSCircularBezelStyle ];
+ [ hdabutton setTitle: @"..." ];
+ [ hdabutton setTarget: self ];
+ [ hdabutton setTag:2 ];
+ [ hdabutton setAction: @selector( chooseFile: ) ];
+ [ [ configWindow contentView ] addSubview: hdabutton ];
+
+ NSButton *cdrombutton = [ [ [ NSButton alloc ] initWithFrame:
NSMakeRect(355,98,30,30) ] autorelease ];
+ [ cdrombutton setButtonType: NSMomentaryPushButton ];
+ [ cdrombutton setBezelStyle: NSCircularBezelStyle ];
+ [ cdrombutton setTitle: @"..." ];
+ [ cdrombutton setTarget: self ];
+ [ cdrombutton setTag:3 ];
+ [ cdrombutton setAction: @selector( chooseFile: ) ];
+ [ [ configWindow contentView ] addSubview: cdrombutton ];
+
+ NSButton *cancelbutton = [ [ [ NSButton alloc ] initWithFrame:
NSMakeRect(188,22,100,30) ] autorelease ];
+ [ cancelbutton setButtonType: NSMomentaryPushButton ];
+ [ cancelbutton setBezelStyle: NSRoundedBezelStyle ];
+ [ cancelbutton setKeyEquivalent: @"\E" ];
+ [ cancelbutton setTitle: @"Quit qemu" ];
+ [ cancelbutton setTarget: self ];
+ [ cancelbutton setAction: @selector( closeConfigWindowQuit ) ];
+ [ [ configWindow contentView ] addSubview: cancelbutton ];
+
+ NSButton *okbutton = [ [ [ NSButton alloc ] initWithFrame:
NSMakeRect(288,22,100,30) ] autorelease ];
+ [ okbutton setButtonType: NSMomentaryPushButton ];
+ [ okbutton setBezelStyle: NSRoundedBezelStyle ];
+ [ okbutton setKeyEquivalent: @"\r" ];
+ [ okbutton setTitle: @"Start PC" ];
+ [ okbutton setTarget: self ];
+ [ okbutton setAction: @selector( closeConfigWindowStart ) ];
+ [ [ configWindow contentView ] addSubview: okbutton ];
+
+ /* default values */
+ [ pcram setStringValue: @"64" ];
+ [ pcfda setStringValue: @"" ];
+ [ pchda setStringValue: @"" ];
+ [ pccdrom setStringValue: @"" ];
+ [ pcoptions setStringValue: @"" ];
+
+ /* show configWindow */
+ [ configWindow center ];
+ [ configWindow makeKeyAndOrderFront:nil ];
+}
+
+/* Methods of configWindow */
+- (void) chooseFile:(id)sender
+{
+ NSString *description;
+ NSString *contextInfo;
+
+ if ( [ sender tag ] == 1 ) {
+ contextInfo = @"fda";
+ description = @"Floppy A";
+ } else if ( [ sender tag ] == 2 ) {
+ contextInfo = @"hda";
+ description = @"Harddisk";
+ } else if ( [ sender tag ] == 3 ) {
+ contextInfo = @"cdrom";
+ description = @"CD-Rom";
+ } else {
+ contextInfo = @"";
+ description = @"";
+ }
+
+ NSOpenPanel *op = [[NSOpenPanel alloc] init];
+ [op setPrompt: [ NSString stringWithFormat:@"choose Image for %@",
description ] ];
+ [op setMessage: [ NSString stringWithFormat:@"Select the diskimage you
want to use as address@hidden the \"Cancel\" button to quit", description ] ];
+ [op beginSheetForDirectory:nil
+ file:nil
+ types:fileTypes
+ modalForWindow:configWindow
+ modalDelegate:self
+
didEndSelector:@selector(chooseFileSheetDidEnd:returnCode:contextInfo:)
+ contextInfo:contextInfo ];
+}
+
+- (void)chooseFileSheetDidEnd: (NSOpenPanel *)sheet
+ returnCode:(int)returnCode
+ contextInfo:(NSString *)contextInfo
+{
+ if(returnCode == NSOKButton) {
+ if ( [ contextInfo isEqual: @"fda" ] )
+ [ pchda setStringValue:[ sheet filename ] ];
+ if ( [ contextInfo isEqual: @"hda" ] )
+ [ pchda setStringValue:[ sheet filename ] ];
+ if ( [ contextInfo isEqual: @"cdrom" ] )
+ [ pchda setStringValue:[ sheet filename ] ];
+ }
+}
+
+- (void)closeConfigWindowQuit
+{
+ [ configWindow close ];
+ [ configWindow release ];
+ exit(0); //return 0 => pc shutdown
+}
+
+- (void)closeConfigWindowStart
+{
+ /* get Values from configWindow */
+ NSArray *options;
+ int i = 3;
+ int j;
+ char **argv = (char**)malloc( sizeof(char*)*3 );
- pixels[ (i * rowPixels) + j ] |= 0xFF000000;
- }
- }
+ asprintf(&argv[0], "qemu");
+ asprintf(&argv[1], "-m");
+ asprintf(&argv[2], "%s",[ [ pcram stringValue ] cString ]);
+
+ if (![ [ pcfda stringValue ] isEqual:@"" ]) {
+ asprintf(&argv[i], "-fda");
+ i++;
+ asprintf(&argv[i], [ [ pcfda stringValue ] cString ]);
+ i++;
+ }
+
+ if (![ [ pchda stringValue ] isEqual:@"" ]) {
+ asprintf(&argv[i], "-hda");
+ i++;
+ asprintf(&argv[i], [ [ pchda stringValue ] cString ]);
+ i++;
+ }
+
+ if (![ [ pccdrom stringValue ] isEqual:@"" ]) {
+ asprintf(&argv[i], "-cdrom");
+ i++;
+ asprintf(&argv[i], [ [ pccdrom stringValue ] cString ]);
+ i++;
+ }
+
+ options = [ [ pcoptions stringValue ] componentsSeparatedByString:@" "
];
+ for (j = 0; j < [ options count ]; j++) {
+ asprintf(&argv[i], [ [ options objectAtIndex:j ] cString ]);
+ i++;
+ }
+
+ /* cleanup */
+ [ configWindow close ];
+ [ configWindow release ];
+
+ /* start PC */
+ [ pcModel startPC:(i-1) withArgs:argv ];
}
address@hidden
+
+/*
+ ------------------------------------------------------
+ QemuWindow
+ ------------------------------------------------------
+*/
@implementation QemuWindow
-- (void)miniaturize:(id)sender
+- (void) miniaturize:(id)sender
{
/* make the alpha channel opaque so anim won't have holes in it */
- QZ_SetPortAlphaOpaque ();
-
[ super miniaturize:sender ];
+ /* there is no mini image of the openGL View */
}
-- (void)display
+
+- (void) display
{
/*
This method fires just before the window deminaturizes from the Dock.
@@ -378,237 +881,1024 @@
is required, and the deminiaturize works perfectly.
*/
- /* make sure pixels are fully opaque */
- QZ_SetPortAlphaOpaque ();
-
/* save current visible SDL surface */
- [ self cacheImageInRect:[ qd_view frame ] ];
-
+ [ self cacheImageInRect:[ ogl_view frame ] ];
+
/* let the window manager redraw controls, border, etc */
[ super display ];
-
+
/* restore visible SDL surface */
[ self restoreCachedImage ];
}
+- (BOOL) windowShouldClose:(id)sender
+{
+ [ pcWindowView shutdownPC ];
+ return NO;
+}
@end
/*
------------------------------------------------------
- QemuCocoaGUIController
- NSApp's delegate - indeed main object
+ QemuCocoaQuickDrawView
------------------------------------------------------
*/
address@hidden QemuCocoaOpenGLView
+- (void)mouseDown:(NSEvent *)theEvent
+{
+ /* Mouse-grab is activatet by clicks in View only,
+ so we can handle clicks on other GUI Items */
+ grab = 1;
+ [ pcWindow setTitle: [ NSString stringWithFormat:@"%@ - %@ (Press ctrl
+ alt to release Mouse)",[ pcModel pcWindowName ], [ pcModel pcName ] ] ];
+ [ NSCursor hide ];
+ CGAssociateMouseAndMouseCursorPosition ( FALSE );
+ return;
+}
address@hidden
address@hidden QemuCocoaGUIController : NSObject
+
+
+/*
+ ------------------------------------------------------
+ QemuCocoaPcModel
+ ------------------------------------------------------
+*/
address@hidden QemuCocoaPcModel
+- (NSString *) pcName
{
+ return pcName;
}
-- (void)applicationDidFinishLaunching: (NSNotification *) note;
-- (void)applicationWillTerminate:(NSNotification *)aNotification;
-- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode
contextInfo:(void *)contextInfo;
+- (NSString *) pcWindowName
+{
+ return pcWindowName;
+}
-- (void)startEmulationWithArgc:(int)argc argv:(char**)argv;
address@hidden
+- (NSImage *) thumbnailFast
+{
+ /* thumnailFast is broken atm => second half of image is garbled */
+ uint8_t buffer[22500];
+ uint8_t *d, *d1, *b;
+ int x,y;
+ float dx = current_ds.width / 100.0;
+ float dy = current_ds.height / 75.0;
+ b = buffer;
+
+ for (y = 0; y < 75 ; y++) {
+ d1 = ¤t_ds.data[ 1 + (int)( y * dy ) *
current_ds.linesize ]; // offset 1 to save 100 Additions per Line
+ d = d1;
+ for (x = 0; x < 100; x ++) {
+ d = d1 + (int)( x * dx ) * 4;
+ *b = *d; //red
+ b++;
+ d++;
+ *b = *d; //green
+ b++;
+ d++;
+ *b = *d; //blue
+ b++;
+ }
+ }
+
+ b = buffer;
+ NSBitmapImageRep *rawBitmapRep;
+ rawBitmapRep = [ [ NSBitmapImageRep alloc ] initWithBitmapDataPlanes:&b
+ pixelsWide:100
+ pixelsHigh:75
+ bitsPerSample:8
+ samplesPerPixel:3
+ hasAlpha:NO
+ isPlanar:NO
+ colorSpaceName:NSCalibratedRGBColorSpace
+ bytesPerRow:300
+ bitsPerPixel:24 ];
+ NSImage *image = [ [ [ NSImage alloc ] init ] autorelease ];
+ [ image addRepresentation:rawBitmapRep ];
+ [ rawBitmapRep release ];
+
+ return image;
+}
address@hidden QemuCocoaGUIController
-/* Called when the internal event loop has just started running */
-- (void)applicationDidFinishLaunching: (NSNotification *) note
+- (NSImage *) thumbnailQuality
{
+ uint8_t buffer[current_ds.width * current_ds.height * 3];
+ uint8_t *d, *b;
+ int p;
+ d = current_ds.data;
+ b = buffer;
+ for (p = 0; p < current_ds.width * current_ds.height ; p++) {
+ d++; //jump empty byte
+ *b = *d; //red
+ d++;
+ b++;
+ *b = *d; //green
+ d++;
+ b++;
+ *b = *d; //blue
+ d++;
+ b++;
+ }
+ b = buffer;
+ NSBitmapImageRep *rawBitmapRep = [ [ NSBitmapImageRep alloc ]
initWithBitmapDataPlanes:&b
+ pixelsWide:current_ds.width
+ pixelsHigh:current_ds.height
+ bitsPerSample:8
+ samplesPerPixel:3
+ hasAlpha:NO
+ isPlanar:NO
+ colorSpaceName:NSCalibratedRGBColorSpace
+ bytesPerRow:current_ds.width * 3
+ bitsPerPixel:24 ];
+ NSImage *sourceImage = [ [ NSImage alloc ] init ];
+ [ sourceImage addRepresentation:rawBitmapRep ];
+ [ sourceImage setScalesWhenResized:YES ];
+ [ rawBitmapRep release ];
+ NSImage *smallImage = [ [ [ NSImage alloc ]
initWithSize:NSMakeSize(100, 75) ] autorelease ];
+ [ smallImage lockFocus ];
+ [ [ NSGraphicsContext currentContext ]
setImageInterpolation:NSImageInterpolationHigh ];
+ [ sourceImage setSize:NSMakeSize(100, 75) ];
+ [ sourceImage compositeToPoint:NSZeroPoint operation:NSCompositeCopy ];
+ [ smallImage unlockFocus ];
+
+ return smallImage;
+}
- /* Display an open dialog box if no argument were passed or
- if qemu was launched from the finder ( the Finder passes "-psn" ) */
+- (void) liveThumbnail
+{
+ /* create liveThumbnail */
+ NSBitmapImageRep *bitmapImageRep = [ NSBitmapImageRep imageRepWithData:
[ [ self thumbnailQuality ] TIFFRepresentation ] ];
+ NSData *data = [ bitmapImageRep representationUsingType: NSPNGFileType
properties: nil ];
+ [ data writeToFile: [ NSString stringWithFormat: @"%@/address@hidden",
pcPath, pcName ] atomically: YES ];
+}
- if( gArgc <= 1 || strncmp (gArgv[1], "-psn", 4) == 0)
- {
- NSOpenPanel *op = [[NSOpenPanel alloc] init];
-
- cocoa_resize(¤t_ds, 640, 400);
-
- [op setPrompt:@"Boot image"];
-
- [op setMessage:@"Select the disk image you want to boot.\n\nHit the
\"Cancel\" button to quit"];
-
- [op beginSheetForDirectory:nil file:nil types:[NSArray
arrayWithObjects:@"img",@"iso",@"dmg",@"qcow",@"cow",@"cloop",@"vmdk",nil]
- modalForWindow:window modalDelegate:self
-
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)
contextInfo:NULL];
- }
- else
- {
- /* or Launch Qemu, with the global args */
- [self startEmulationWithArgc:gArgc argv:gArgv];
+/* copied and adapted from monitor.c */
+- (int) ejectDevice: (BlockDriverState *) bs
+ withForce: (int) force
+{
+ if (bdrv_is_inserted(bs)) {
+ if (!force) {
+ if (!bdrv_is_removable(bs)) {
+ printf("device is not removable\n");
+ return -1;
+ }
+ if (bdrv_is_locked(bs)) {
+ printf("device is locked\n");
+ return -1;
+ }
+ }
+ bdrv_close(bs);
}
+ return 0;
}
-- (void)applicationWillTerminate:(NSNotification *)aNotification
+- (void) ejectImage:(const char *) filename
+ withForce: (int) force
{
- printf("Application will terminate\n");
- qemu_system_shutdown_request();
- /* In order to avoid a crash */
- exit(0);
+ BlockDriverState *bs;
+
+ bs = bdrv_find(filename);
+ if (!bs) {
+ printf("device not found\n");
+ return;
+ }
+ [ self ejectDevice:bs withForce:force ];
}
-- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode
contextInfo:(void *)contextInfo
+- (void) changeDeviceImage: (const char *) device
+ filename: (const char *) filename
+ withForce: (int) force
{
- if(returnCode == NSCancelButton)
- {
- exit(0);
+ BlockDriverState *bs;
+ int i;
+ char password[256];
+
+ bs = bdrv_find(device);
+ if (!bs) {
+ printf("device not found\n");
+ return;
}
-
- if(returnCode == NSOKButton)
- {
- char *bin = "qemu";
- char *img = (char*)[ [ sheet filename ] cString];
-
- char **argv = (char**)malloc( sizeof(char*)*3 );
-
- asprintf(&argv[0], "%s", bin);
- asprintf(&argv[1], "-hda");
- asprintf(&argv[2], "%s", img);
-
- printf("Using argc %d argv %s -hda %s\n", 3, bin, img);
-
- [self startEmulationWithArgc:3 argv:(char**)argv];
+ if ([ self ejectDevice:bs withForce:force ] < 0)
+ return;
+ bdrv_open(bs, filename, 0);
+ if (bdrv_is_encrypted(bs)) {
+ printf("%s is encrypted.\n", device);
+ for(i = 0; i < 3; i++) {
+ monitor_readline("Password: ", 1, password, sizeof(password));
+ if (bdrv_set_key(bs, password) == 0)
+ break;
+ printf("invalid password\n");
+ }
}
}
-- (void)startEmulationWithArgc:(int)argc argv:(char**)argv
+- (void) saveVM
+{
+ /* show progressWindow */
+ [ pcWindowView showProgressWindow:@"Saving PC" ];
+
+ /* generate Preview */
+ NSBitmapImageRep *bitmapImageRep = [ NSBitmapImageRep imageRepWithData:
[ [ self thumbnailQuality ] TIFFRepresentation ] ];
+ NSData *data = [ bitmapImageRep representationUsingType: NSPNGFileType
properties: nil ];
+ [ data writeToFile: [ NSString stringWithFormat: @"%@/address@hidden",
pcPath, pcName ] atomically: YES ];
+ vm_stop(0); //stop PC
+ qemu_savevm( [ [ NSString stringWithFormat: @"%@/address@hidden",
pcPath, pcName ] cString ]);
+
+ /* hide progressWindow */
+ [ pcWindowView hideProgressWindow ];
+
+ /* set status */
+ pcStatus = @"saved";
+}
+
+- (void) startPC:(int)argc withArgs:(char**)argv
+{
+ /* filter cocoa arguments */
+ pcWindowName = @"qemu";
+ pcName = @"";
+ pcPath = [ @"~/Library/Application Support/cocoaqemu"
stringByExpandingTildeInPath];
+ pcLiveThumbnail = 0;
+
+ int i;
+ for (i = 0; i < argc; i++) {
+ if ( strcmp(argv[i], "-cocoawindowname" ) == 0 ) {
+ pcWindowName = [ NSString stringWithFormat:@"%s",
argv[i+1] ];
+ argv[i] = "";
+ argv[i+1] = "";
+ }
+ if ( strcmp(argv[i], "-cocoaname" ) == 0 ) {
+ pcName = [ NSString stringWithFormat:@"%s", argv[i+1] ];
+ argv[i] = "";
+ argv[i+1] = "";
+ }
+ if ( strcmp(argv[i], "-cocoapath" ) == 0 ) {
+ pcPath = [ NSString stringWithFormat:@"%s", argv[i+1]
];
+ argv[i] = "";
+ argv[i+1] = "";
+ }
+ if ( strcmp(argv[i], "-cocoalivethumbnail" ) == 0 ) {
+ pcLiveThumbnail = 1;
+ argv[i] = "";
+ timer = [ NSTimer scheduledTimerWithTimeInterval:10
target:self selector:@selector( liveThumbnail ) userInfo:nil repeats:YES ];
+ }
+ }
+
+ /* show pcWindow */
+ [ pcWindowView pcWindowSetup: 640 height:400 ]; //create inital Window
for qemu
+
+ /* show progressWindow */
+ [ pcWindowView progressWindowSetup ]; //create Window for Progressbar
+ [ pcWindowView showProgressWindow:@"Loading PC" ];
+
+ /* set status */
+ pcStatus = @"running";
+
+ /* hide progressWindow */
+ [ pcWindowView hideProgressWindow ];
+
+ /* Launch Qemu */
+ qemu_main (argc, argv);
+}
+
+- (void) resetPC
+{
+ qemu_system_reset_request();
+}
+
+- (void) shutdownPC
{
- int status;
- /* Launch Qemu */
- printf("starting qemu...\n");
- status = qemu_main (argc, argv);
- exit(status);
+ qemu_system_shutdown_request();
+
+ if ( [ pcStatus isEqual: @"running" ] )
+ pcStatus = @"shutdown";
}
@end
+
+
/*
------------------------------------------------------
- Application Creation
+ NSApp
------------------------------------------------------
*/
address@hidden QemuCocoaGUIController
+- (void) applicationMenuSetup
+{
+
+ NSMenu *appleMenu;
+ NSMenuItem *menuItem;
+ NSString *appName;
+
+ appName = [ pcModel pcWindowName ]; //@"qemu";
+ appleMenu = [ [ NSMenu alloc ] initWithTitle:@"" ];
+
+ /* Add menu items */
+ [ appleMenu addItemWithTitle:[ @"About "
stringByAppendingString:appName ]
action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@"" ];
+ [ appleMenu addItem:[NSMenuItem separatorItem ] ];
+ [ appleMenu addItemWithTitle:[ @"Hide " stringByAppendingString:appName
] action:@selector(hide:) keyEquivalent:@"h" ];
+
+ menuItem = (NSMenuItem *)[ appleMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:) keyEquivalent:@"h" ];
+ [ menuItem
setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask) ];
+
+ [ appleMenu addItemWithTitle:@"Show All"
action:@selector(unhideAllApplications:) keyEquivalent:@"" ];
+ [ appleMenu addItem:[NSMenuItem separatorItem ] ];
+ [ appleMenu addItemWithTitle:[@"Quit " stringByAppendingString:appName
] action:@selector(terminate:) keyEquivalent:@"q" ];
+
+ /* Put menu into the menubar */
+ menuItem = [ [ NSMenuItem alloc ] initWithTitle:@"" action:nil
keyEquivalent:@"" ];
+ [ menuItem setSubmenu:appleMenu ];
+ [ [ NSApp mainMenu] addItem:menuItem ];
+
+ /* Tell the application object that this is now the application menu */
+ [ NSApp setAppleMenu:appleMenu ];
+
+ /* Finally give up our references to the objects */
+ [ appleMenu release ];
+ [ menuItem release ];
+
+}
-/* Dock Connection */
-typedef struct CPSProcessSerNum
+- (void) windowMenuSetup
{
- UInt32 lo;
- UInt32 hi;
-} CPSProcessSerNum;
+ NSMenu *windowMenu;
+ NSMenuItem *windowMenuItem;
+ NSMenuItem *menuItem;
+
+ windowMenu = [ [ NSMenu alloc ] initWithTitle:@"Window" ];
+
+ /* "Minimize" item */
+ menuItem = [ [ NSMenuItem alloc] initWithTitle:@"Minimize"
action:@selector(performMiniaturize:) keyEquivalent:@"m" ];
+ [ windowMenu addItem:menuItem ];
+ [ menuItem release ];
+
+ /* Put menu into the menubar */
+ windowMenuItem = [ [ NSMenuItem alloc ] initWithTitle:@"Window"
action:nil keyEquivalent:@"" ];
+ [ windowMenuItem setSubmenu:windowMenu ];
+ [ [ NSApp mainMenu] addItem:windowMenuItem ];
+
+ /* Tell the application object that this is now the window menu */
+ [ NSApp setWindowsMenu:windowMenu ];
+
+ /* Finally give up our references to the objects */
+ [ windowMenu release ];
+ [ windowMenuItem release ];
+}
-extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
-extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32
_arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
-extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
+/* Delegates of NSApp */
+- (void)applicationWillFinishLaunching: (NSNotification *) note
+{
+ [ NSApp setMainMenu:[ [ NSMenu alloc ] init ] ];
+ [ self applicationMenuSetup ];
+ [ self windowMenuSetup ];
+}
-/* Menu Creation */
-static void setApplicationMenu(void)
+- (void)applicationDidFinishLaunching: (NSNotification *) note
{
- /* warning: this code is very odd */
- NSMenu *appleMenu;
- NSMenuItem *menuItem;
- NSString *title;
- NSString *appName;
-
- appName = @"Qemu";
- appleMenu = [[NSMenu alloc] initWithTitle:@""];
+ /* Display config Window if no argument were passed or
+ if qemu was launched from the finder ( the Finder passes "-psn" ) */
+ if( gArgc <= 1 || strncmp (gArgv[1], "-psn", 4) == 0)
+ {
+ /* show configWindow */
+ [ pcWindowView configWindowSetup ];
+ }
+ else
+ {
+ /* start PC with cmd-line Args */
+ [ pcModel startPC:gArgc withArgs:gArgv ];
+ }
+}
+
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication
*)sender
+{
+ [ pcWindowView shutdownPC ];
+ return NO;
+}
address@hidden
+
+
+/*
+ ------------------------------------------------------
+ Qemu Video Driver
- /* Add menu items */
- title = [@"About " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title
action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+ ------------------------------------------------------
+*/
+/*
+ ------------------------------------------------------
+ cocoa_update
+ ------------------------------------------------------
+*/
+static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
+{
+ /* Make this context current */
+ [[ogl_view openGLContext] makeCurrentContext];
+
+ /* Bind, update and draw new image */
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);
+
+ /* glTexSubImage2D is faster when not using a texture range */
+ glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, (GLint)ds->width,
(GLint)ds->height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);
+
+ /* Use the compiled display list */
+ glCallList(display_list_tex);
+
+ /* Swap buffer to screen */
+ [[ogl_view openGLContext] flushBuffer];
+}
- [appleMenu addItem:[NSMenuItem separatorItem]];
+/*
+ ------------------------------------------------------
+ cocoa_resize
+ ------------------------------------------------------
+*/
+static void cocoa_resize(DisplayState *ds, int w, int h)
+{
+ NSRect contentRect;
- title = [@"Hide " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(hide:)
keyEquivalent:@"h"];
+ // printf("resizing to %d %d\n", w, h);
- menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
- [menuItem
setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
+ contentRect = NSMakeRect (0, 0, w, h);
- [appleMenu addItemWithTitle:@"Show All"
action:@selector(unhideAllApplications:) keyEquivalent:@""];
+ [pcWindow setContentSize:contentRect.size];
+ [pcWindow update];
+
+ [[ogl_view openGLContext] makeCurrentContext];
+ [[ogl_view openGLContext] update];
- [appleMenu addItem:[NSMenuItem separatorItem]];
+ glViewport(0, 0, (int) contentRect.size.width, (int)
contentRect.size.height);
- title = [@"Quit " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(terminate:)
keyEquivalent:@"q"];
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
-
- /* Put menu into the menubar */
- menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil
keyEquivalent:@""];
- [menuItem setSubmenu:appleMenu];
- [[NSApp mainMenu] addItem:menuItem];
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ /* This is used as a init'd flag as well... */
+ if(screen_tex != 0) {
+ glDeleteTextures(1, &screen_tex);
+ glDeleteLists(display_list_tex, 1);
+ }
+
+ screen_tex = 1;
+
+ if(ds->data != NULL) free(ds->data);
+ ds->data = (GLubyte *) malloc(w * h * (SCREEN_BPP >> 3));
+ assert(ds->data != NULL);
+ ds->linesize = w * (SCREEN_BPP >> 3);
+ ds->depth = SCREEN_BPP;
+ ds->width = w;
+ ds->height = h;
+
+ /* Setup some basic OpenGL stuff as from Apple */
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+ glEnable(GL_TEXTURE_RECTANGLE_EXT);
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);
+
+ glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, w * h * (SCREEN_BPP >>
3), ds->data);
+
+ /* Use CACHED for VRAM+reused tex Use SHARED for AGP+used once tex
+ Note the texture is always changing so use SHARED */
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,
GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
+ glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_EDGE);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+ glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, w, h, 0, GL_BGRA,
GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);
+
+ glFlush();
+
+ /* Setup a display list to save all the operations below */
+ display_list_tex = glGenLists(1);
+ glNewList(display_list_tex, GL_COMPILE);
+
+ glBegin(GL_QUADS);
+
+ glTexCoord2f(0.0f, 0.0f);
+ glVertex2f(-1.0f, 1.0f);
+
+ glTexCoord2f(0.0f, (GLfloat)h);
+ glVertex2f(-1.0f, -1.0f);
- /* Tell the application object that this is now the application menu */
- [NSApp setAppleMenu:appleMenu];
+ glTexCoord2f((GLfloat)w, (GLfloat)h);
+ glVertex2f(1.0f, -1.0f);
- /* Finally give up our references to the objects */
- [appleMenu release];
- [menuItem release];
+ glTexCoord2f((GLfloat)w, 0.0f);
+ glVertex2f(1.0f, 1.0f);
+
+ glEnd();
+
+ glEndList();
+
+ /* Swap buffer to screen */
+ [[ogl_view openGLContext] flushBuffer];
+
+ memcpy(¤t_ds, ds, sizeof(DisplayState));
}
-/* Create a window menu */
-static void setupWindowMenu(void)
+/*
+ ------------------------------------------------------
+ keymap conversion
+ ------------------------------------------------------
+*/
+
+static int keymap[] =
{
- NSMenu *windowMenu;
- NSMenuItem *windowMenuItem;
- NSMenuItem *menuItem;
+// SdlI macI macH SdlH 104xtH 104xtC sdl
+ 30, // 0 0x00 0x1e A QZ_a
+ 31, // 1 0x01 0x1f S QZ_s
+ 32, // 2 0x02 0x20 D QZ_d
+ 33, // 3 0x03 0x21 F QZ_f
+ 35, // 4 0x04 0x23 H QZ_h
+ 34, // 5 0x05 0x22 G QZ_g
+ 44, // 6 0x06 0x2c Z QZ_z
+ 45, // 7 0x07 0x2d X QZ_x
+ 46, // 8 0x08 0x2e C QZ_c
+ 47, // 9 0x09 0x2f V QZ_v
+ 0, // 10 0x0A Undefined
+ 48, // 11 0x0B 0x30 B QZ_b
+ 16, // 12 0x0C 0x10 Q QZ_q
+ 17, // 13 0x0D 0x11 W QZ_w
+ 18, // 14 0x0E 0x12 E QZ_e
+ 19, // 15 0x0F 0x13 R QZ_r
+ 21, // 16 0x10 0x15 Y QZ_y
+ 20, // 17 0x11 0x14 T QZ_t
+ 2, // 18 0x12 0x2 1 QZ_1
+ 3, // 19 0x13 0x3 2 QZ_2
+ 4, // 20 0x14 0x4 3 QZ_3
+ 5, // 21 0x15 0x5 4 QZ_4
+ 7, // 22 0x16 0x7 6 QZ_6
+ 6, // 23 0x17 0x6 5 QZ_5
+ 13, // 24 0x18 0xd = QZ_EQUALS
+ 10, // 25 0x19 0xa 9 QZ_9
+ 8, // 26 0x1A 0x8 7 QZ_7
+ 12, // 27 0x1B 0xc - QZ_MINUS
+ 9, // 28 0x1C 0x9 8 QZ_8
+ 11, // 29 0x1D 0xb 0 QZ_0
+ 27, // 30 0x1E 0x1b ] QZ_RIGHTBRACKET
+ 24, // 31 0x1F 0x18 O QZ_o
+ 22, // 32 0x20 0x16 U QZ_u
+ 26, // 33 0x21 0x1a [ QZ_LEFTBRACKET
+ 23, // 34 0x22 0x17 I QZ_i
+ 25, // 35 0x23 0x19 P QZ_p
+ 28, // 36 0x24 0x1c ENTER QZ_RETURN
+ 38, // 37 0x25 0x26 L QZ_l
+ 36, // 38 0x26 0x24 J QZ_j
+ 40, // 39 0x27 0x28 ' QZ_QUOTE
+ 37, // 40 0x28 0x25 K QZ_k
+ 39, // 41 0x29 0x27 ; QZ_SEMICOLON
+ 43, // 42 0x2A 0x2b \ QZ_BACKSLASH
+ 51, // 43 0x2B 0x33 , QZ_COMMA
+ 53, // 44 0x2C 0x35 / QZ_SLASH
+ 49, // 45 0x2D 0x31 N QZ_n
+ 50, // 46 0x2E 0x32 M QZ_m
+ 52, // 47 0x2F 0x34 . QZ_PERIOD
+ 15, // 48 0x30 0xf TAB QZ_TAB
+ 57, // 49 0x31 0x39 SPACE QZ_SPACE
+ 41, // 50 0x32 0x29 ` QZ_BACKQUOTE
+ 14, // 51 0x33 0xe BKSP QZ_BACKSPACE
+ 0, // 52 0x34 Undefined
+ 1, // 53 0x35 0x1 ESC QZ_ESCAPE
+ 0, // 54 0x36 QZ_RMETA
+ 0, // 55 0x37 QZ_LMETA
+ 42, // 56 0x38 0x2a L SHFT QZ_LSHIFT
+ 58, // 57 0x39 0x3a CAPS QZ_CAPSLOCK
+ 56, // 58 0x3A 0x38 L ALT QZ_LALT
+ 29, // 59 0x3B 0x1d L CTRL QZ_LCTRL
+ 54, // 60 0x3C 0x36 R SHFT QZ_RSHIFT
+ 184, // 61 0x3D 0xb8 E0,38 R ALT QZ_RALT
+ 157, // 62 0x3E 0x9d E0,1D R CTRL QZ_RCTRL
+ 0, // 63 0x3F Undefined
+ 0, // 64 0x40 Undefined
+ 0, // 65 0x41 Undefined
+ 0, // 66 0x42 Undefined
+ 55, // 67 0x43 0x37 KP * QZ_KP_MULTIPLY
+ 0, // 68 0x44 Undefined
+ 78, // 69 0x45 0x4e KP + QZ_KP_PLUS
+ 0, // 70 0x46 Undefined
+ 69, // 71 0x47 0x45 NUM QZ_NUMLOCK
+ 0, // 72 0x48 Undefined
+ 0, // 73 0x49 Undefined
+ 0, // 74 0x4A Undefined
+ 181, // 75 0x4B 0xb5 E0,35 KP / QZ_KP_DIVIDE
+ 152, // 76 0x4C 0x9c E0,1C KP EN QZ_KP_ENTER
+ 0, // 77 0x4D undefined
+ 74, // 78 0x4E 0x4a KP - QZ_KP_MINUS
+ 0, // 79 0x4F Undefined
+ 0, // 80 0x50 Undefined
+ 0, // 81 0x51 QZ_KP_EQUALS
+ 82, // 82 0x52 0x52 KP 0 QZ_KP0
+ 79, // 83 0x53 0x4f KP 1 QZ_KP1
+ 80, // 84 0x54 0x50 KP 2 QZ_KP2
+ 81, // 85 0x55 0x51 KP 3 QZ_KP3
+ 75, // 86 0x56 0x4b KP 4 QZ_KP4
+ 76, // 87 0x57 0x4c KP 5 QZ_KP5
+ 77, // 88 0x58 0x4d KP 6 QZ_KP6
+ 71, // 89 0x59 0x47 KP 7 QZ_KP7
+ 0, // 90 0x5A Undefined
+ 72, // 91 0x5B 0x48 KP 8 QZ_KP8
+ 73, // 92 0x5C 0x49 KP 9 QZ_KP9
+ 0, // 93 0x5D Undefined
+ 0, // 94 0x5E Undefined
+ 0, // 95 0x5F Undefined
+ 63, // 96 0x60 0x3f F5 QZ_F5
+ 64, // 97 0x61 0x40 F6 QZ_F6
+ 65, // 98 0x62 0x41 F7 QZ_F7
+ 61, // 99 0x63 0x3d F3 QZ_F3
+ 66, // 100 0x64 0x42 F8 QZ_F8
+ 67, // 101 0x65 0x43 F9 QZ_F9
+ 0, // 102 0x66 Undefined
+ 87, // 103 0x67 0x57 F11 QZ_F11
+ 0, // 104 0x68 Undefined
+ 183, // 105 0x69 0xb7 QZ_PRINT
+ 0, // 106 0x6A Undefined
+ 70, // 107 0x6B 0x46 SCROLL QZ_SCROLLOCK
+ 0, // 108 0x6C Undefined
+ 68, // 109 0x6D 0x44 F10 QZ_F10
+ 0, // 110 0x6E Undefined
+ 88, // 111 0x6F 0x58 F12 QZ_F12
+ 0, // 112 0x70 Undefined
+ 110, // 113 0x71 0x0 QZ_PAUSE
+ 210, // 114 0x72 0xd2 E0,52 INSERT QZ_INSERT
+ 199, // 115 0x73 0xc7 E0,47 HOME QZ_HOME
+ 201, // 116 0x74 0xc9 E0,49 PG UP QZ_PAGEUP
+ 211, // 117 0x75 0xd3 E0,53 DELETE QZ_DELETE
+ 62, // 118 0x76 0x3e F4 QZ_F4
+ 207, // 119 0x77 0xcf E0,4f END QZ_END
+ 60, // 120 0x78 0x3c F2 QZ_F2
+ 209, // 121 0x79 0xd1 E0,51 PG DN QZ_PAGEDOWN
+ 59, // 122 0x7A 0x3b F1 QZ_F1
+ 203, // 123 0x7B 0xcb e0,4B L ARROW QZ_LEFT
+ 205, // 124 0x7C 0xcd e0,4D R ARROW QZ_RIGHT
+ 208, // 125 0x7D 0xd0 E0,50 D ARROW QZ_DOWN
+ 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
*/
+
+/* Aditional 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
+ // E0,2A,E0,37 PRNT SCRN
+ // E1,1D,45,E1,9D,C5 PAUSE
+ 83 // 0x53 0x53 KP .
+// ACPI Scan Codes
+ 222 // 0xde E0, 5E Power
+ 223 // 0xdf E0, 5F Sleep
+ 227 // 0xe3 E0, 63 Wake
+// Windows Multimedia Scan Codes
+ 153 // 0x99 E0, 19 Next Track
+ 144 // 0x90 E0, 10 Previous Track
+ 164 // 0xa4 E0, 24 Stop
+ 162 // 0xa2 E0, 22 Play/Pause
+ 160 // 0xa0 E0, 20 Mute
+ 176 // 0xb0 E0, 30 Volume Up
+ 174 // 0xae E0, 2E Volume Down
+ 237 // 0xed E0, 6D Media Select
+ 236 // 0xec E0, 6C E-Mail
+ 161 // 0xa1 E0, 21 Calculator
+ 235 // 0xeb E0, 6B My Computer
+ 229 // 0xe5 E0, 65 WWW Search
+ 178 // 0xb2 E0, 32 WWW Home
+ 234 // 0xea E0, 6A WWW Back
+ 233 // 0xe9 E0, 69 WWW Forward
+ 232 // 0xe8 E0, 68 WWW Stop
+ 231 // 0xe7 E0, 67 WWW Refresh
+ 230 // 0xe6 E0, 66 WWW Favorites
+*/
+};
- windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
-
- /* "Minimize" item */
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize"
action:@selector(performMiniaturize:) keyEquivalent:@"m"];
- [windowMenu addItem:menuItem];
- [menuItem release];
-
- /* Put menu into the menubar */
- windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil
keyEquivalent:@""];
- [windowMenuItem setSubmenu:windowMenu];
- [[NSApp mainMenu] addItem:windowMenuItem];
-
- /* Tell the application object that this is now the window menu */
- [NSApp setWindowsMenu:windowMenu];
+static int cocoa_keycode_to_qemu(int keycode)
+{
+ if((sizeof(keymap)/sizeof(int)) <= keycode)
+ {
+ printf("(cocoa) warning unknow keycode 0x%x\n", keycode);
+ return 0;
+ }
+ return keymap[keycode];
+}
- /* Finally give up our references to the objects */
- [windowMenu release];
- [windowMenuItem release];
-
+/*
+ ------------------------------------------------------
+ cocoa_refresh
+ ------------------------------------------------------
+*/
+static void cocoa_refresh(DisplayState *ds)
+{
+ //printf("cocoa_refresh \n");
+ NSDate *distantPast;
+ NSEvent *event;
+ NSAutoreleasePool *pool;
+
+ pool = [ [ NSAutoreleasePool alloc ] init ];
+ distantPast = [ NSDate distantPast ];
+
+ if (is_active_console(vga_console))
+ vga_update_display();
+ do {
+ event = [ NSApp nextEventMatchingMask:NSAnyEventMask
+ untilDate:distantPast
+ inMode: NSDefaultRunLoopMode
+ dequeue:YES ];
+ if (event != nil) {
+
+ /* release Mouse grab when pressing ctrl+alt */
+ if (([ event modifierFlags ] & NSControlKeyMask) && ([ event
modifierFlags ] & NSAlternateKeyMask))
+ {
+ grab = 0;
+ [ pcWindow setTitle: [ NSString stringWithFormat: @"%@
- %@",[ pcModel pcWindowName ], [ pcModel pcName ] ] ]; //[ pcWindow
setTitle:@"Qemu" ];
+ [ NSCursor unhide ];
+ CGAssociateMouseAndMouseCursorPosition ( TRUE );
+ }
+
+ /* handle Events */
+ switch ([event type])
+ {
+
+ case NSFlagsChanged:
+ if ([ pcWindow isKeyWindow ]) {
+ int keycode =
cocoa_keycode_to_qemu([event keyCode]);
+ modifiers_state[keycode] =
(modifiers_state[keycode] == 0) ? 1 : 0;
+
+ if (modifiers_state[keycode]) { /*
Keydown */
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode & 0x7f);
+ } else { /* Keyup */
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode | 0x80);
+ }
+
+ /* emulate caps lock and num lock keyup
*/
+ if ((keycode == 58) || (keycode == 69))
+ {
+ modifiers_state[keycode] = 0;
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode | 0x80);
+ }
+ } else {
+ [NSApp sendEvent:event];
+ }
+ break;
+
+ case NSKeyDown:
+ if ([ pcWindow isKeyWindow ]) {
+ int keycode =
cocoa_keycode_to_qemu([event keyCode]);
+ if (keycode & 0x80) //check bit for e0
in front
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode & 0x7f);
//remove e0 bit in front
+ } else {
+ [NSApp sendEvent:event];
+ }
+ break;
+
+ case NSKeyUp:
+ if ([ pcWindow isKeyWindow ]) {
+ int keycode =
cocoa_keycode_to_qemu([event keyCode]);
+ if (keycode & 0x80)
+ kbd_put_keycode(0xe0);
+ kbd_put_keycode(keycode | 0x80); //add
128 to signal release of key
+ } else {
+ [NSApp sendEvent:event];
+ }
+ break;
+
+ case NSScrollWheel:
+ if (grab) {
+ int dz = [event deltaY];
+ kbd_mouse_event(0, 0, -dz, 0);
+ }
+ break;
+
+ case NSLeftMouseDown:
+ if (grab) {
+ int buttons = 0;
+
+ /* leftclick+command simulates
rightclick */
+ if ([ event modifierFlags ] &
NSCommandKeyMask) {
+ buttons |= MOUSE_EVENT_RBUTTON;
+ } else {
+ buttons |= MOUSE_EVENT_LBUTTON;
+ }
+ kbd_mouse_event(0, 0, 0, buttons);
+ } else {
+ [NSApp sendEvent:event];
+ }
+ break;
+
+ case NSLeftMouseUp:
+ if (grab) {
+ kbd_mouse_event(0, 0, 0, 0);
+ } else {
+ [NSApp sendEvent:event];
+ }
+ break;
+
+ case NSOtherMouseDown:
+ if (grab) {
+ int buttons = 0;
+ buttons |= MOUSE_EVENT_MBUTTON;
+ kbd_mouse_event(0, 0, 0, buttons);
+ } else {
+ [NSApp sendEvent:event];
+ }
+ break;
+
+ case NSRightMouseDown:
+ if (grab) {
+ int buttons = 0;
+ buttons |= MOUSE_EVENT_RBUTTON;
+ kbd_mouse_event(0, 0, 0, buttons);
+ } else {
+ [NSApp sendEvent:event];
+ }
+ break;
+
+ case NSOtherMouseUp:
+ if (grab) {
+ kbd_mouse_event(0, 0, 0, 0);
+ } else {
+ [NSApp sendEvent:event];
+ }
+ break;
+
+ case NSRightMouseUp:
+ if (grab) {
+ kbd_mouse_event(0, 0, 0, 0);
+ } else {
+ [NSApp sendEvent:event];
+ }
+ break;
+
+ case NSMouseMoved:
+ if (grab) {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+ int buttons = 0;
+ kbd_mouse_event(dx, dy, dz, buttons);
+ }
+ break;
+
+ case NSOtherMouseDragged:
+ if (grab) {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+ int buttons = 0;
+ buttons |= MOUSE_EVENT_MBUTTON;
+ kbd_mouse_event(dx, dy, dz, buttons);
+ }
+ break;
+
+ case NSRightMouseDragged:
+ if (grab) {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+ int buttons = 0;
+ buttons |= MOUSE_EVENT_RBUTTON;
+ kbd_mouse_event(dx, dy, dz, buttons);
+ }
+ break;
+
+ case NSLeftMouseDragged:
+ if (grab) {
+ int dx = [event deltaX];
+ int dy = [event deltaY];
+ int dz = [event deltaZ];
+ int buttons = 0;
+ if ([ [ NSApp currentEvent ]
modifierFlags ] & NSCommandKeyMask) { //leftclick+command simulates rightclick
+ buttons |= MOUSE_EVENT_RBUTTON;
+ } else {
+ buttons |= MOUSE_EVENT_LBUTTON;
+ }
+ kbd_mouse_event(dx, dy, dz, buttons);
+ }
+ break;
+
+ default: [NSApp sendEvent:event];
+ }
+ }
+ } while(event != nil);
}
-static void CustomApplicationMain (argc, argv)
+
+/*
+ ------------------------------------------------------
+ cocoa_cleanup
+ ------------------------------------------------------
+*/
+static void cocoa_cleanup(void)
{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- QemuCocoaGUIController *gui_controller;
- CPSProcessSerNum PSN;
-
- [NSApplication sharedApplication];
+
+}
+
+
+/*
+ ------------------------------------------------------
+ cocoa_display_init
+ ------------------------------------------------------
+*/
+void cocoa_display_init(DisplayState *ds, int full_screen)
+{
+ //printf("resizing to %d %d\n", w, h);
+
+ const int w = 640;
+ const int h = 400;
+
+ if(pcWindow == nil)
+ {
+ [ pcWindowView pcWindowSetup:w height:h ];
+ }
+
+ ds->dpy_update = cocoa_update;
+ ds->dpy_resize = cocoa_resize;
+ ds->dpy_refresh = cocoa_refresh;
+
+ cocoa_resize(ds, 640, 400);
+
+ [ pcWindow display ];
+ [ pcWindow makeMainWindow ];
+ [ pcWindow makeKeyWindow ];
+
+ atexit(cocoa_cleanup);
+}
+
+
+
+/*
+ ------------------------------------------------------
+ Application Creation
- if (!CPSGetCurrentProcess(&PSN))
- if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
- if (!CPSSetFrontProcess(&PSN))
- [NSApplication sharedApplication];
-
- /* Set up the menubar */
- [NSApp setMainMenu:[[NSMenu alloc] init]];
- setApplicationMenu();
- setupWindowMenu();
-
- /* Create SDLMain and make it the app delegate */
- gui_controller = [[QemuCocoaGUIController alloc] init];
- [NSApp setDelegate:gui_controller];
+ ------------------------------------------------------
+*/
+
+/* Dock Connection */
+typedef struct CPSProcessSerNum
+{
+ UInt32 lo;
+ UInt32 hi;
+} CPSProcessSerNum;
+
+extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
+extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32
_arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
+
+static void CustomApplicationMain (argc, argv)
+{
+ NSAutoreleasePool *pool = [ [ NSAutoreleasePool alloc ] init ];
+ CPSProcessSerNum PSN;
- /* Start the main event loop */
- [NSApp run];
+ [ NSApplication sharedApplication ];
- [gui_controller release];
- [pool release];
+ if (!CPSGetCurrentProcess(&PSN))
+ if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
+ if (!CPSSetFrontProcess(&PSN))
+ [ NSApplication sharedApplication ];
+
+ /* overrun defaults for bios_dir, so we can run qemu everywhere */
+ bios_dir = [ [ NSString stringWithFormat:@"%@/share/qemu", [ [ [
NSBundle mainBundle ] resourcePath ] stringByDeletingLastPathComponent ] ]
cString ];
+
+ /* set allowed filetypes */
+ fileTypes = [ [ NSArray
arrayWithObjects:@"img",@"iso",@"dmg",@"qcow",@"cow",@"cloop",@"vmdk",nil ]
retain ];
+
+ gui_controller = [ [ QemuCocoaGUIController alloc ] init ];
+ [NSApp setDelegate:gui_controller];
+
+ pcWindowView = [ [ QemuCocoaPcWindowView alloc ] init ]; //start the PC
View
+ pcModel = [ [ QemuCocoaPcModel alloc ] init ]; //create the PC model
+
+ [ NSApp run ]; //Start the main event loop
+
+ /* cleanup */
+ [ pcModel release ];
+ [ progressWindow release ];
+ [ pcWindow close ];
+ [ pcWindow release ];
+ [ pcWindowView release ];
+ [ gui_controller release ];
+ [ pool release ];
}
/* Real main of qemu-cocoa */
int main(int argc, char **argv)
{
- gArgc = argc;
- gArgv = argv;
-
- CustomApplicationMain (argc, argv);
-
- return 0;
+ gArgc = argc;
+ gArgv = argv;
+
+ CustomApplicationMain (argc, argv);
+
+ if ( [ pcStatus isEqual: @"shutdown" ] ) {
+ return 0; // return 0 => pc shutdown
+ } else {
+ return 2; // return 2 => pc saved
+ }
}
Index: Makefile.target
===================================================================
RCS file: /cvsroot/qemu/qemu/Makefile.target,v
retrieving revision 1.69
diff -u -r1.69 Makefile.target
--- Makefile.target 28 Apr 2005 21:15:08 -0000 1.69
+++ Makefile.target 27 May 2005 10:51:17 -0000
@@ -469,3 +469,8 @@
ifneq ($(wildcard .depend),)
include .depend
endif
+
+ifdef CONFIG_COCOA
+VL_OBJS+=cocoa.o
+COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework OpenGL
+endif
- [Qemu-devel] [PATCH] cocoa.m,
Mike Kronenberg <=