qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] cocoa.m
@ 2005-05-27 11:42 Mike Kronenberg
  2005-05-27 14:09 ` Natalia Portillo
  2005-05-27 14:51 ` Mike Kronenberg
  0 siblings, 2 replies; 8+ messages in thread
From: Mike Kronenberg @ 2005-05-27 11:42 UTC (permalink / raw)
  To: Qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1084 bytes --]

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


[-- Attachment #2: cocoa.m_1.4_20050527.diff --]
[-- Type: text/plain, Size: 72417 bytes --]

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 */
-@interface QemuWindow : NSWindow
-{ }
-@end
-
+/* 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)
+@interface 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;
+@end
+
 
 /*
  ------------------------------------------------------
-    cocoa_resize
+	QemuWindow (subclass of NSWindow)
  ------------------------------------------------------
 */
-static void cocoa_resize(DisplayState *ds, int w, int h)
+@interface 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;
+@end
+
 
 /*
  ------------------------------------------------------
-    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)
+@interface QemuCocoaOpenGLView : NSOpenGLView
 {
-    if(sizeof(keymap) <= keycode)
-    {
-        printf("(cocoa) warning unknow keycode 0x%x\n", keycode);
-        return 0;
-    }
-    return keymap[keycode];
 }
+- (void)mouseDown:(NSEvent *)theEvent;
+@end
+
 
 /*
  ------------------------------------------------------
-    cocoa_refresh
+ 	QemuCocoaPcModel
  ------------------------------------------------------
 */
-static void cocoa_refresh(DisplayState *ds)
+@interface 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;
+@end
+
 
 /*
  ------------------------------------------------------
-    cocoa_cleanup
+	NSApp
  ------------------------------------------------------
 */
-
-static void cocoa_cleanup(void) 
+@interface QemuCocoaGUIController : NSObject
 {
-
 }
+/* NSApp methods */
+- (void) applicationMenuSetup;
+- (void) windowMenuSetup;
+
+/* NSApp delegates*/
+- (void) applicationWillFinishLaunching: (NSNotification *) note;
+- (void) applicationDidFinishLaunching: (NSNotification *) note;
+- (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender;
+@end
+
 
 /*
  ------------------------------------------------------
-    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++) {
+@implementation 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 %@.\n\nHit 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 %@.\n\nHit 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 ];
 }
+@end
+
 
+/*
+ ------------------------------------------------------
+    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
  ------------------------------------------------------
 */
+@implementation 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;
+}
+@end
 
-@interface QemuCocoaGUIController : NSObject
+
+
+/*
+ ------------------------------------------------------
+ 	QemuCocoaPcModel
+ ------------------------------------------------------
+*/
+@implementation 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;
-@end
+- (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 = &current_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;	
+}
 
-@implementation 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: @"%@/%@.png", pcPath, pcName ] atomically: YES ];
+}
 
-    if( gArgc <= 1 || strncmp (gArgv[1], "-psn", 4) == 0)
-    {
-        NSOpenPanel *op = [[NSOpenPanel alloc] init];
-        
-        cocoa_resize(&current_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: @"%@/%@.png", pcPath, pcName ] atomically: YES ];
+	vm_stop(0); //stop PC
+	qemu_savevm( [ [ NSString stringWithFormat: @"%@/%@.vm", 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
  ------------------------------------------------------
 */
+@implementation 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;
+}
+@end
+
+
+/*
+ ------------------------------------------------------
+    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(&current_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
+	}
 }

[-- Attachment #3: Makefile.target_1.69_20050527.diff --]
[-- Type: text/plain, Size: 491 bytes --]

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

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2005-05-30  8:44 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-27 11:42 [Qemu-devel] [PATCH] cocoa.m Mike Kronenberg
2005-05-27 14:09 ` Natalia Portillo
2005-05-27 14:24   ` Mike Kronenberg
2005-05-27 14:51 ` Mike Kronenberg
2005-05-27 15:04   ` Pierre d'Herbemont
2005-05-28 18:36     ` Mike Kronenberg
2005-05-29 14:44       ` Pierre d'Herbemont
2005-05-30  8:39         ` Mike Kronenberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).