/*
 * QEMU Cocoa display driver
 * 
 * Copyright (c) 2005 Pierre d'Herbemont
 *                    many code/inspiration from SDL 1.2 code (LGPL)
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
/*
    Todo :    x  miniaturize window 
              x  center the window
              -  save window position
              -  handle keyboard event
              -  handle mouse event
              -  non 32 bpp support
              -  full screen
              -  mouse focus
              x  simple graphical prompt to demo
              -  better graphical prompt
*/

#import <Cocoa/Cocoa.h>

#include "vl.h"

NSWindow *window = NULL;
NSQuickDrawView *qd_view = NULL;


int gArgc;
char **gArgv;
DisplayState current_ds;

int grab = 0;
int modifiers_state[256];

/* main defined in qemu/vl.c */
int qemu_main(int argc, char **argv);

/* To deal with miniaturization */
@interface QemuWindow : NSWindow
{ }
@end


/*
 ------------------------------------------------------
    Qemu Video Driver
 ------------------------------------------------------
*/

/*
 ------------------------------------------------------
    cocoa_update
 ------------------------------------------------------
*/
static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
{
    //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);
}

/*
 ------------------------------------------------------
    cocoa_resize
 ------------------------------------------------------
*/
static void cocoa_resize(DisplayState *ds, int w, int h)
{
    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;
}

/*
 ------------------------------------------------------
    keymap conversion
 ------------------------------------------------------
*/

int keymap[] =
{
//  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    0x02            1       QZ_1
    3,  //  19      0x13    0x03            2       QZ_2
    4,  //  20      0x14    0x04            3       QZ_3
    5,  //  21      0x15    0x05            4       QZ_4
    7,  //  22      0x16    0x07            6       QZ_6
    6,  //  23      0x17    0x06            5       QZ_5
    13, //  24      0x18    0x0d            =       QZ_EQUALS
    10, //  25      0x19    0x0a            9       QZ_9
    8,  //  26      0x1A    0x08            7       QZ_7
    12, //  27      0x1B    0x0c            -       QZ_MINUS
    9,  //  28      0x1C    0x09            8       QZ_8
    11, //  29      0x1D    0x0b            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    0x0f            TAB     QZ_TAB
    57, //  49      0x31    0x39            SPACE   QZ_SPACE
    41, //  50      0x32    0x29            `       QZ_BACKQUOTE
    14, //  51      0x33    0x0e            BKSP    QZ_BACKSPACE
    0,  //  52      0x34    Undefined
    1,  //  53      0x35    0x01            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   
*/
};

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];
}

/*
 ------------------------------------------------------
    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) {
            switch ([event type]) {
                case NSFlagsChanged:
                    {
                        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);
                        }
                            
                        /* release Mouse grab when pressing ctrl+alt */
                        if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask))
                            [window setTitle: @"QEMU"];
                            [NSCursor unhide];
                            CGAssociateMouseAndMouseCursorPosition ( TRUE );
                            grab = 0;
                    }
                    break;
                    
                case NSKeyDown:
                    {
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);               
                        
                        /* handle command Key Combos */
                        if ([event modifierFlags] & NSCommandKeyMask) {
                            switch ([event keyCode]) {
                                /* quit */
                                case 12: /* q key */
                                    /* switch to windowed View */
                                    exit(0);
                                    return;
                            }
                        }
                        
                        /* handle control + alt Key Combos */
                        if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
                            switch (keycode) {
                                /* toggle Monitor */
                                case 0x02 ... 0x0a: /* '1' to '9' keys */
                                    console_select(keycode - 0x02);
                                    if (is_active_console(vga_console)) {
                                        /* tell the vga console to redisplay itself */
                                        vga_invalidate_display();
                                    break;
                                }
                            }
                        } else {
                            /* handle standard key events */
                            if (is_active_console(vga_console)) {
                                if (keycode & 0x80) //check bit for e0 in front
                                    kbd_put_keycode(0xe0);
                                kbd_put_keycode(keycode & 0x7f); //remove e0 bit in front
                            /* handle monitor key events */
                            } else {
                                switch([event keyCode]) {
                                    case 123:
                                        kbd_put_keysym(QEMU_KEY_LEFT);
                                        break;
                                    case 124:
                                        kbd_put_keysym(QEMU_KEY_RIGHT);
                                        break;
                                    case 125:
                                        kbd_put_keysym(QEMU_KEY_DOWN);
                                        break;
                                    case 126:
                                        kbd_put_keysym(QEMU_KEY_UP);
                                        break;
                                    default:
                                        kbd_put_keysym([[event characters] characterAtIndex:0]);
                                        break;
                                }
                            }
                        }
                    }
                    break;
                    
                case NSKeyUp:
                    {
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);   
                        if (is_active_console(vga_console)) {
                            if (keycode & 0x80)
                                kbd_put_keycode(0xe0);
                            kbd_put_keycode(keycode | 0x80); //add 128 to signal release of key
                        }
                    }
                    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 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 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;
                        
                case NSLeftMouseUp:
                    if (grab) {
                        kbd_mouse_event(0, 0, 0, 0);
                    } else {
                        [window setTitle: @"QEMU (Press ctrl + alt to release Mouse)"];
                        [NSCursor hide];
                        CGAssociateMouseAndMouseCursorPosition ( FALSE );
                        grab = 1;
                        //[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 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 NSRightMouseUp:
                    if (grab) {
                        kbd_mouse_event(0, 0, 0, 0);
                    } else {
                        [NSApp sendEvent: event];
                    }
                    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 NSOtherMouseDown:
                    if (grab) {
                        int buttons = 0;
                        buttons |= MOUSE_EVENT_MBUTTON;
                        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 NSScrollWheel:
                    if (grab) {
                        int dz = [event deltaY];
                        kbd_mouse_event(0, 0, -dz, 0);
                    }
                    break;
                
                default: [NSApp sendEvent:event];
            }
        }
    } while(event != nil);
}

/*
 ------------------------------------------------------
    cocoa_cleanup
 ------------------------------------------------------
*/

static void cocoa_cleanup(void) 
{

}

/*
 ------------------------------------------------------
    cocoa_display_init
 ------------------------------------------------------
*/

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
 ------------------------------------------------------
*/


/*
 ------------------------------------------------------
    QemuWindow
    Some trick from SDL to use miniwindow
 ------------------------------------------------------
*/
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++) {
        
                pixels[ (i * rowPixels) + j ] |= 0xFF000000;
            }
    }
}

@implementation QemuWindow
- (void)miniaturize:(id)sender
{
        
    /* make the alpha channel opaque so anim won't have holes in it */
    QZ_SetPortAlphaOpaque ();
    
    [ super miniaturize:sender ];
    
}
- (void)display
{    
    /* 
        This method fires just before the window deminaturizes from the Dock.
        
        We'll save the current visible surface, let the window manager redraw any
        UI elements, and restore the SDL surface. This way, no expose event 
        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 ] ];
    
    /* let the window manager redraw controls, border, etc */
    [ super display ];
    
    /* restore visible SDL surface */
    [ self restoreCachedImage ];
}

@end


/*
 ------------------------------------------------------
    QemuCocoaGUIController
    NSApp's delegate - indeed main object
 ------------------------------------------------------
*/

@interface QemuCocoaGUIController : NSObject
{
}
- (void)applicationDidFinishLaunching: (NSNotification *) note;
- (void)applicationWillTerminate:(NSNotification *)aNotification;

- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo;

- (void)startEmulationWithArgc:(int)argc argv:(char**)argv;
@end

@implementation QemuCocoaGUIController
/* Called when the internal event loop has just started running */
- (void)applicationDidFinishLaunching: (NSNotification *) note
{

    /* Display an open dialog box 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)
    {
        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];
    }
}

- (void)applicationWillTerminate:(NSNotification *)aNotification
{
    printf("Application will terminate\n");
    qemu_system_shutdown_request();
    /* In order to avoid a crash */
    exit(0);
}

- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
    if(returnCode == NSCancelButton)
    {
        exit(0);
    }
    
    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];
    }
}

- (void)startEmulationWithArgc:(int)argc argv:(char**)argv
{
    int status;
    /* Launch Qemu */
    printf("starting qemu...\n");
    status = qemu_main (argc, argv);
    exit(status);
}
@end

/*
 ------------------------------------------------------
    Application Creation
 ------------------------------------------------------
*/

/* 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);

/* Menu Creation */
static void setApplicationMenu(void)
{
    /* warning: this code is very odd */
    NSMenu *appleMenu;
    NSMenuItem *menuItem;
    NSString *title;
    NSString *appName;
    
    appName = @"Qemu";
    appleMenu = [[NSMenu alloc] initWithTitle:@""];
    
    /* Add menu items */
    title = [@"About " stringByAppendingString:appName];
    [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];

    [appleMenu addItem:[NSMenuItem separatorItem]];

    title = [@"Hide " stringByAppendingString:appName];
    [appleMenu addItemWithTitle:title 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]];

    title = [@"Quit " stringByAppendingString:appName];
    [appleMenu addItemWithTitle:title 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];
}

/* Create a window menu */
static void setupWindowMenu(void)
{
    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];
 
}

static void CustomApplicationMain (argc, argv)
{
    NSAutoreleasePool   *pool = [[NSAutoreleasePool alloc] init];
    QemuCocoaGUIController *gui_controller;
    CPSProcessSerNum PSN;
    
    [NSApplication sharedApplication];
    
    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];
    
    /* Start the main event loop */
    [NSApp run];
    
    [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;
}
