Revision 5fafdf24 cocoa.m

b/cocoa.m
1 1
/*
2 2
 * QEMU Cocoa display driver
3
 * 
3
 *
4 4
 * Copyright (c) 2005 Pierre d'Herbemont
5 5
 *                    many code/inspiration from SDL 1.2 code (LGPL)
6
 * 
6
 *
7 7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 8
 * of this software and associated documentation files (the "Software"), to deal
9 9
 * in the Software without restriction, including without limitation the rights
......
23 23
 * THE SOFTWARE.
24 24
 */
25 25
/*
26
    Todo :    x  miniaturize window 
26
    Todo :    x  miniaturize window
27 27
              x  center the window
28 28
              -  save window position
29 29
              -  handle keyboard event
......
84 84
    MacSetRectRgn (temp, x, y,
85 85
                        x + w, y + h);
86 86
    MacUnionRgn (dirty, temp, dirty);
87
                
87
               
88 88
    /* Flush the dirty region */
89 89
    QDFlushPortBuffer ( [ qd_view  qdPort ], dirty );
90 90
    DisposeRgn (dirty);
......
102 102
    static void *screen_pixels;
103 103
    static int  screen_pitch;
104 104
    NSRect contentRect;
105
    
105
   
106 106
    //printf("resizing to %d %d\n", w, h);
107
    
107
   
108 108
    contentRect = NSMakeRect (0, 0, w, h);
109 109
    if(window)
110 110
    {
......
119 119
        fprintf(stderr, "(cocoa) can't create window\n");
120 120
        exit(1);
121 121
    }
122
    
122
   
123 123
    if(qd_view)
124 124
        [qd_view release];
125
    
125
   
126 126
    qd_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
127
    
127
   
128 128
    if(!qd_view)
129 129
    {
130 130
         fprintf(stderr, "(cocoa) can't create qd_view\n");
131 131
        exit(1);
132 132
    }
133
    
133
   
134 134
    [ window setAcceptsMouseMovedEvents:YES ];
135 135
    [ window setTitle:@"Qemu" ];
136 136
    [ window setReleasedWhenClosed:NO ];
137
    
137
   
138 138
    /* Set screen to black */
139 139
    [ window setBackgroundColor: [NSColor blackColor] ];
140
    
140
   
141 141
    /* set window position */
142 142
    [ window center ];
143
    
143
   
144 144
    [ qd_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable ];
145 145
    [ [ window contentView ] addSubview:qd_view ];
146 146
    [ qd_view release ];
147 147
    [ window makeKeyAndOrderFront:nil ];
148
    
148
   
149 149
    /* Careful here, the window seems to have to be onscreen to do that */
150 150
    LockPortBits ( [ qd_view qdPort ] );
151 151
    screen_pixels = GetPixBaseAddr ( GetPortPixMap ( [ qd_view qdPort ] ) );
152 152
    screen_pitch  = GetPixRowBytes ( GetPortPixMap ( [ qd_view qdPort ] ) );
153 153
    UnlockPortBits ( [ qd_view qdPort ] );
154
    { 
155
            int vOffset = [ window frame ].size.height - 
154
    {
155
            int vOffset = [ window frame ].size.height -
156 156
                [ qd_view frame ].size.height - [ qd_view frame ].origin.y;
157
            
157
           
158 158
            int hOffset = [ qd_view frame ].origin.x;
159
                    
159
                   
160 160
            screen_pixels += (vOffset * screen_pitch) + hOffset * (device_bpp/8);
161 161
    }
162 162
    ds->data = screen_pixels;
......
310 310
    208,//  125     0x7D    0xd0    E0,50   D ARROW QZ_DOWN
311 311
    200,//  126     0x7E    0xc8    E0,48   U ARROW QZ_UP
312 312
/* 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 */
313
  
313
 
314 314
/* Aditional 104 Key XP-Keyboard Scancodes from http://www.computer-engineering.org/ps2keyboard/scancodes1.html */
315 315
/*
316
    219 //          0xdb            e0,5b   L GUI   
317
    220 //          0xdc            e0,5c   R GUI   
318
    221 //          0xdd            e0,5d   APPS    
319
        //              E0,2A,E0,37         PRNT SCRN   
320
        //              E1,1D,45,E1,9D,C5   PAUSE   
321
    83  //          0x53    0x53            KP .    
322
// ACPI Scan Codes                              
323
    222 //          0xde            E0, 5E  Power   
324
    223 //          0xdf            E0, 5F  Sleep   
325
    227 //          0xe3            E0, 63  Wake    
326
// Windows Multimedia Scan Codes                                
327
    153 //          0x99            E0, 19  Next Track  
328
    144 //          0x90            E0, 10  Previous Track  
329
    164 //          0xa4            E0, 24  Stop    
330
    162 //          0xa2            E0, 22  Play/Pause  
331
    160 //          0xa0            E0, 20  Mute    
332
    176 //          0xb0            E0, 30  Volume Up   
333
    174 //          0xae            E0, 2E  Volume Down 
334
    237 //          0xed            E0, 6D  Media Select    
335
    236 //          0xec            E0, 6C  E-Mail  
336
    161 //          0xa1            E0, 21  Calculator  
337
    235 //          0xeb            E0, 6B  My Computer 
338
    229 //          0xe5            E0, 65  WWW Search  
339
    178 //          0xb2            E0, 32  WWW Home    
340
    234 //          0xea            E0, 6A  WWW Back    
341
    233 //          0xe9            E0, 69  WWW Forward 
342
    232 //          0xe8            E0, 68  WWW Stop    
343
    231 //          0xe7            E0, 67  WWW Refresh 
344
    230 //          0xe6            E0, 66  WWW Favorites   
316
    219 //          0xdb            e0,5b   L GUI  
317
    220 //          0xdc            e0,5c   R GUI  
318
    221 //          0xdd            e0,5d   APPS   
319
        //              E0,2A,E0,37         PRNT SCRN  
320
        //              E1,1D,45,E1,9D,C5   PAUSE  
321
    83  //          0x53    0x53            KP .   
322
// ACPI Scan Codes                             
323
    222 //          0xde            E0, 5E  Power  
324
    223 //          0xdf            E0, 5F  Sleep  
325
    227 //          0xe3            E0, 63  Wake   
326
// Windows Multimedia Scan Codes                               
327
    153 //          0x99            E0, 19  Next Track 
328
    144 //          0x90            E0, 10  Previous Track 
329
    164 //          0xa4            E0, 24  Stop   
330
    162 //          0xa2            E0, 22  Play/Pause 
331
    160 //          0xa0            E0, 20  Mute   
332
    176 //          0xb0            E0, 30  Volume Up  
333
    174 //          0xae            E0, 2E  Volume Down
334
    237 //          0xed            E0, 6D  Media Select   
335
    236 //          0xec            E0, 6C  E-Mail 
336
    161 //          0xa1            E0, 21  Calculator 
337
    235 //          0xeb            E0, 6B  My Computer
338
    229 //          0xe5            E0, 65  WWW Search 
339
    178 //          0xb2            E0, 32  WWW Home   
340
    234 //          0xea            E0, 6A  WWW Back   
341
    233 //          0xe9            E0, 69  WWW Forward
342
    232 //          0xe8            E0, 68  WWW Stop   
343
    231 //          0xe7            E0, 67  WWW Refresh
344
    230 //          0xe6            E0, 66  WWW Favorites  
345 345
*/
346 346
};
347 347

  
......
366 366
    NSDate *distantPast;
367 367
    NSEvent *event;
368 368
    NSAutoreleasePool *pool;
369
    
369
   
370 370
    pool = [ [ NSAutoreleasePool alloc ] init ];
371 371
    distantPast = [ NSDate distantPast ];
372
    
372
   
373 373
    vga_hw_update();
374 374

  
375 375
    do {
......
415 415

  
416 416
                case NSKeyDown:
417 417
                    {
418
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);               
419
                        
418
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);              
419
                       
420 420
                        /* handle command Key Combos */
421 421
                        if ([event modifierFlags] & NSCommandKeyMask) {
422 422
                            switch ([event keyCode]) {
......
427 427
                                    return;
428 428
                            }
429 429
                        }
430
                        
430
                       
431 431
                        /* handle control + alt Key Combos */
432 432
                        if (([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask)) {
433 433
                            switch (keycode) {
......
482 482
                        }
483 483
                    }
484 484
                    break;
485
                    
485
                   
486 486
                case NSKeyUp:
487 487
                    {
488
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);   
488
                        int keycode = cocoa_keycode_to_qemu([event keyCode]);  
489 489
                        if (is_graphic_console()) {
490 490
                            if (keycode & 0x80)
491 491
                                kbd_put_keycode(0xe0);
......
493 493
                        }
494 494
                    }
495 495
                    break;
496
                    
496
                   
497 497
                case NSMouseMoved:
498 498
                    if (grab) {
499 499
                        int dx = [event deltaX];
......
503 503
                        kbd_mouse_event(dx, dy, dz, buttons);
504 504
                    }
505 505
                    break;
506
                        
506
                       
507 507
                case NSLeftMouseDown:
508 508
                    if (grab) {
509 509
                        int buttons = 0;
510
                        
510
                       
511 511
                        /* leftclick+command simulates rightclick */
512 512
                        if ([event modifierFlags] & NSCommandKeyMask) {
513 513
                            buttons |= MOUSE_EVENT_RBUTTON;
......
519 519
                        [NSApp sendEvent: event];
520 520
                    }
521 521
                    break;
522
                        
522
                       
523 523
                case NSLeftMouseDragged:
524 524
                    if (grab) {
525 525
                        int dx = [event deltaX];
......
534 534
                        kbd_mouse_event(dx, dy, dz, buttons);
535 535
                    }
536 536
                    break;
537
                        
537
                       
538 538
                case NSLeftMouseUp:
539 539
                    if (grab) {
540 540
                        kbd_mouse_event(0, 0, 0, 0);
......
546 546
                        //[NSApp sendEvent: event];
547 547
                    }
548 548
                    break;
549
                        
549
                       
550 550
                case NSRightMouseDown:
551 551
                    if (grab) {
552 552
                        int buttons = 0;
553
                        
553
                       
554 554
                        buttons |= MOUSE_EVENT_RBUTTON;
555 555
                        kbd_mouse_event(0, 0, 0, buttons);
556 556
                    } else {
557 557
                        [NSApp sendEvent: event];
558 558
                    }
559 559
                    break;
560
                    
560
                   
561 561
                case NSRightMouseDragged:
562 562
                    if (grab) {
563 563
                        int dx = [event deltaX];
......
568 568
                        kbd_mouse_event(dx, dy, dz, buttons);
569 569
                    }
570 570
                    break;
571
                    
571
                   
572 572
                case NSRightMouseUp:
573 573
                    if (grab) {
574 574
                        kbd_mouse_event(0, 0, 0, 0);
......
576 576
                        [NSApp sendEvent: event];
577 577
                    }
578 578
                    break;
579
                        
579
                       
580 580
                case NSOtherMouseDragged:
581 581
                    if (grab) {
582 582
                        int dx = [event deltaX];
......
587 587
                        kbd_mouse_event(dx, dy, dz, buttons);
588 588
                    }
589 589
                    break;
590
                    
590
                   
591 591
                case NSOtherMouseDown:
592 592
                    if (grab) {
593 593
                        int buttons = 0;
......
597 597
                        [NSApp sendEvent:event];
598 598
                    }
599 599
                    break;
600
                        
600
                       
601 601
                case NSOtherMouseUp:
602 602
                    if (grab) {
603 603
                        kbd_mouse_event(0, 0, 0, 0);
......
605 605
                        [NSApp sendEvent: event];
606 606
                    }
607 607
                    break;
608
                        
608
                       
609 609
                case NSScrollWheel:
610 610
                    if (grab) {
611 611
                        int dz = [event deltaY];
612 612
                        kbd_mouse_event(0, 0, -dz, 0);
613 613
                    }
614 614
                    break;
615
                
615
               
616 616
                default: [NSApp sendEvent:event];
617 617
            }
618 618
        }
......
625 625
 ------------------------------------------------------
626 626
*/
627 627

  
628
static void cocoa_cleanup(void) 
628
static void cocoa_cleanup(void)
629 629
{
630 630

  
631 631
}
......
641 641
    ds->dpy_update = cocoa_update;
642 642
    ds->dpy_resize = cocoa_resize;
643 643
    ds->dpy_refresh = cocoa_refresh;
644
    
644
   
645 645
    cocoa_resize(ds, 640, 400);
646
    
646
   
647 647
    atexit(cocoa_cleanup);
648 648
}
649 649

  
......
661 661
 ------------------------------------------------------
662 662
*/
663 663
static void QZ_SetPortAlphaOpaque ()
664
{    
664
{   
665 665
    /* Assume 32 bit if( bpp == 32 )*/
666 666
    if ( 1 ) {
667
    
667
   
668 668
        uint32_t    *pixels = (uint32_t*) current_ds.data;
669 669
        uint32_t    rowPixels = current_ds.linesize / 4;
670 670
        uint32_t    i, j;
671
        
671
       
672 672
        for (i = 0; i < current_ds.height; i++)
673 673
            for (j = 0; j < current_ds.width; j++) {
674
        
674
       
675 675
                pixels[ (i * rowPixels) + j ] |= 0xFF000000;
676 676
            }
677 677
    }
......
680 680
@implementation QemuWindow
681 681
- (void)miniaturize:(id)sender
682 682
{
683
        
683
       
684 684
    /* make the alpha channel opaque so anim won't have holes in it */
685 685
    QZ_SetPortAlphaOpaque ();
686
    
686
   
687 687
    [ super miniaturize:sender ];
688
    
688
   
689 689
}
690 690
- (void)display
691
{    
692
    /* 
691
{   
692
    /*
693 693
        This method fires just before the window deminaturizes from the Dock.
694
        
694
       
695 695
        We'll save the current visible surface, let the window manager redraw any
696
        UI elements, and restore the SDL surface. This way, no expose event 
696
        UI elements, and restore the SDL surface. This way, no expose event
697 697
        is required, and the deminiaturize works perfectly.
698 698
    */
699
    
699
   
700 700
    /* make sure pixels are fully opaque */
701 701
    QZ_SetPortAlphaOpaque ();
702
    
702
   
703 703
    /* save current visible SDL surface */
704 704
    [ self cacheImageInRect:[ qd_view frame ] ];
705
    
705
   
706 706
    /* let the window manager redraw controls, border, etc */
707 707
    [ super display ];
708
    
708
   
709 709
    /* restore visible SDL surface */
710 710
    [ self restoreCachedImage ];
711 711
}
......
742 742
    if( gArgc <= 1 || strncmp (gArgv[1], "-psn", 4) == 0)
743 743
    {
744 744
        NSOpenPanel *op = [[NSOpenPanel alloc] init];
745
        
745
       
746 746
        cocoa_resize(&current_ds, 640, 400);
747
        
747
       
748 748
        [op setPrompt:@"Boot image"];
749
        
749
       
750 750
        [op setMessage:@"Select the disk image you want to boot.\n\nHit the \"Cancel\" button to quit"];
751
        
751
       
752 752
        [op beginSheetForDirectory:nil file:nil types:[NSArray arrayWithObjects:@"img",@"iso",@"dmg",@"qcow",@"cow",@"cloop",@"vmdk",nil]
753 753
              modalForWindow:window modalDelegate:self
754 754
              didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
......
774 774
    {
775 775
        exit(0);
776 776
    }
777
    
777
   
778 778
    if(returnCode == NSOKButton)
779 779
    {
780 780
        char *bin = "qemu";
781 781
        char *img = (char*)[ [ sheet filename ] cString];
782
        
782
       
783 783
        char **argv = (char**)malloc( sizeof(char*)*3 );
784
        
784
       
785 785
        asprintf(&argv[0], "%s", bin);
786 786
        asprintf(&argv[1], "-hda");
787 787
        asprintf(&argv[2], "%s", img);
788
        
788
       
789 789
        printf("Using argc %d argv %s -hda %s\n", 3, bin, img);
790
        
790
       
791 791
        [self startEmulationWithArgc:3 argv:(char**)argv];
792 792
    }
793 793
}
......
827 827
    NSMenuItem *menuItem;
828 828
    NSString *title;
829 829
    NSString *appName;
830
    
830
   
831 831
    appName = @"Qemu";
832 832
    appleMenu = [[NSMenu alloc] initWithTitle:@""];
833
    
833
   
834 834
    /* Add menu items */
835 835
    title = [@"About " stringByAppendingString:appName];
836 836
    [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
......
850 850
    title = [@"Quit " stringByAppendingString:appName];
851 851
    [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
852 852

  
853
    
853
   
854 854
    /* Put menu into the menubar */
855 855
    menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
856 856
    [menuItem setSubmenu:appleMenu];
......
872 872
    NSMenuItem  *menuItem;
873 873

  
874 874
    windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
875
    
875
   
876 876
    /* "Minimize" item */
877 877
    menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
878 878
    [windowMenu addItem:menuItem];
879 879
    [menuItem release];
880
    
880
   
881 881
    /* Put menu into the menubar */
882 882
    windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
883 883
    [windowMenuItem setSubmenu:windowMenu];
884 884
    [[NSApp mainMenu] addItem:windowMenuItem];
885
    
885
   
886 886
    /* Tell the application object that this is now the window menu */
887 887
    [NSApp setWindowsMenu:windowMenu];
888 888

  
......
896 896
    NSAutoreleasePool   *pool = [[NSAutoreleasePool alloc] init];
897 897
    QemuCocoaGUIController *gui_controller;
898 898
    CPSProcessSerNum PSN;
899
    
899
   
900 900
    [NSApplication sharedApplication];
901
    
901
   
902 902
    if (!CPSGetCurrentProcess(&PSN))
903 903
        if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
904 904
            if (!CPSSetFrontProcess(&PSN))
905 905
                [NSApplication sharedApplication];
906
                
906
               
907 907
    /* Set up the menubar */
908 908
    [NSApp setMainMenu:[[NSMenu alloc] init]];
909 909
    setApplicationMenu();
......
912 912
    /* Create SDLMain and make it the app delegate */
913 913
    gui_controller = [[QemuCocoaGUIController alloc] init];
914 914
    [NSApp setDelegate:gui_controller];
915
    
915
   
916 916
    /* Start the main event loop */
917 917
    [NSApp run];
918
    
918
   
919 919
    [gui_controller release];
920 920
    [pool release];
921 921
}

Also available in: Unified diff