qemu-devel
[Top][All Lists]
Advanced

[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 = &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;   
+}
 
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(&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: @"%@/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(&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
+       }
 }
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

reply via email to

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