]> Git Repo - qemu.git/blobdiff - ui/cocoa.m
ui/cocoa: Statically allocate dcl
[qemu.git] / ui / cocoa.m
index 0910b4a7166bff05a5e0abb90de34a7e9684ca58..0ef5fdf3b7a3e6d901dc134613283e9fecf3c0de 100644 (file)
@@ -35,6 +35,7 @@
 #include "sysemu/cpu-throttle.h"
 #include "qapi/error.h"
 #include "qapi/qapi-commands-block.h"
+#include "qapi/qapi-commands-machine.h"
 #include "qapi/qapi-commands-misc.h"
 #include "sysemu/blockdev.h"
 #include "qemu-version.h"
 typedef struct {
     int width;
     int height;
-    int bitsPerComponent;
-    int bitsPerPixel;
 } QEMUScreen;
 
+static void cocoa_update(DisplayChangeListener *dcl,
+                         int x, int y, int w, int h);
+
+static void cocoa_switch(DisplayChangeListener *dcl,
+                         DisplaySurface *surface);
+
+static void cocoa_refresh(DisplayChangeListener *dcl);
+
 NSWindow *normalWindow, *about_window;
-static DisplayChangeListener *dcl;
+static const DisplayChangeListenerOps dcl_ops = {
+    .dpy_name          = "cocoa",
+    .dpy_gfx_update = cocoa_update,
+    .dpy_gfx_switch = cocoa_switch,
+    .dpy_refresh = cocoa_refresh,
+};
+static DisplayChangeListener dcl = {
+    .ops = &dcl_ops,
+};
 static int last_buttons;
 static int cursor_hide = 1;
 
@@ -239,6 +254,13 @@ const int mac_to_qkeycode_map[] = {
     [kVK_F14] = Q_KEY_CODE_SCROLL_LOCK,
     [kVK_F15] = Q_KEY_CODE_PAUSE,
 
+    // JIS keyboards only
+    [kVK_JIS_Yen] = Q_KEY_CODE_YEN,
+    [kVK_JIS_Underscore] = Q_KEY_CODE_RO,
+    [kVK_JIS_KeypadComma] = Q_KEY_CODE_KP_COMMA,
+    [kVK_JIS_Eisu] = Q_KEY_CODE_MUHENKAN,
+    [kVK_JIS_Kana] = Q_KEY_CODE_HENKAN,
+
     /*
      * The eject and volume keys can't be used here because they are handled at
      * a lower level than what an Application can see.
@@ -283,7 +305,6 @@ static void handleAnyDeviceErrors(Error * err)
     QEMUScreen screen;
     NSWindow *fullScreenWindow;
     float cx,cy,cw,ch,cdx,cdy;
-    CGDataProviderRef dataProviderRef;
     pixman_image_t *pixman_image;
     BOOL modifiers_state[256];
     BOOL isMouseGrabbed;
@@ -330,8 +351,6 @@ QemuCocoaView *cocoaView;
     self = [super initWithFrame:frameRect];
     if (self) {
 
-        screen.bitsPerComponent = 8;
-        screen.bitsPerPixel = 32;
         screen.width = frameRect.size.width;
         screen.height = frameRect.size.height;
 
@@ -343,8 +362,7 @@ QemuCocoaView *cocoaView;
 {
     COCOA_DEBUG("QemuCocoaView: dealloc\n");
 
-    if (dataProviderRef) {
-        CGDataProviderRelease(dataProviderRef);
+    if (pixman_image) {
         pixman_image_unref(pixman_image);
     }
 
@@ -423,18 +441,28 @@ QemuCocoaView *cocoaView;
     CGContextSetShouldAntialias (viewContextRef, NO);
 
     // draw screen bitmap directly to Core Graphics context
-    if (!dataProviderRef) {
+    if (!pixman_image) {
         // Draw request before any guest device has set up a framebuffer:
         // just draw an opaque black rectangle
         CGContextSetRGBFillColor(viewContextRef, 0, 0, 0, 1.0);
         CGContextFillRect(viewContextRef, NSRectToCGRect(rect));
     } else {
+        int w = pixman_image_get_width(pixman_image);
+        int h = pixman_image_get_height(pixman_image);
+        int bitsPerPixel = PIXMAN_FORMAT_BPP(pixman_image_get_format(pixman_image));
+        int bitsPerComponent = DIV_ROUND_UP(bitsPerPixel, 8) * 2;
+        CGDataProviderRef dataProviderRef = CGDataProviderCreateWithData(
+            NULL,
+            pixman_image_get_data(pixman_image),
+            w * 4 * h,
+            NULL
+        );
         CGImageRef imageRef = CGImageCreate(
-            screen.width, //width
-            screen.height, //height
-            screen.bitsPerComponent, //bitsPerComponent
-            screen.bitsPerPixel, //bitsPerPixel
-            (screen.width * (screen.bitsPerComponent/2)), //bytesPerRow
+            w, //width
+            h, //height
+            bitsPerComponent, //bitsPerComponent
+            bitsPerPixel, //bitsPerPixel
+            (w * (bitsPerComponent/2)), //bytesPerRow
 #ifdef __LITTLE_ENDIAN__
             CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), //colorspace for OS X >= 10.4
             kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
@@ -457,7 +485,7 @@ QemuCocoaView *cocoaView;
         [self getRectsBeingDrawn:&rectList count:&rectCount];
         for (i = 0; i < rectCount; i++) {
             clipRect.origin.x = rectList[i].origin.x / cdx;
-            clipRect.origin.y = (float)screen.height - (rectList[i].origin.y + rectList[i].size.height) / cdy;
+            clipRect.origin.y = (float)h - (rectList[i].origin.y + rectList[i].size.height) / cdy;
             clipRect.size.width = rectList[i].size.width / cdx;
             clipRect.size.height = rectList[i].size.height / cdy;
             clipImageRef = CGImageCreateWithImageInRect(
@@ -468,6 +496,7 @@ QemuCocoaView *cocoaView;
             CGImageRelease (clipImageRef);
         }
         CGImageRelease (imageRef);
+        CGDataProviderRelease(dataProviderRef);
     }
 }
 
@@ -510,7 +539,6 @@ QemuCocoaView *cocoaView;
 
     int w = pixman_image_get_width(image);
     int h = pixman_image_get_height(image);
-    pixman_format_code_t image_format = pixman_image_get_format(image);
     /* cdx == 0 means this is our very first surface, in which case we need
      * to recalculate the content dimensions even if it happens to be the size
      * of the initial empty window.
@@ -528,17 +556,11 @@ QemuCocoaView *cocoaView;
     }
 
     // update screenBuffer
-    if (dataProviderRef) {
-        CGDataProviderRelease(dataProviderRef);
+    if (pixman_image) {
         pixman_image_unref(pixman_image);
     }
 
-    //sync host window color space with guests
-    screen.bitsPerPixel = PIXMAN_FORMAT_BPP(image_format);
-    screen.bitsPerComponent = DIV_ROUND_UP(screen.bitsPerPixel, 8) * 2;
-
     pixman_image = image;
-    dataProviderRef = CGDataProviderCreateWithData(NULL, pixman_image_get_data(image), w * 4 * h, NULL);
 
     // update windows
     if (isFullscreen) {
@@ -601,15 +623,15 @@ QemuCocoaView *cocoaView;
     // Toggle the stored state.
     modifiers_state[keycode] = !modifiers_state[keycode];
     // Send a keyup or keydown depending on the state.
-    qemu_input_event_send_key_qcode(dcl->con, keycode, modifiers_state[keycode]);
+    qemu_input_event_send_key_qcode(dcl.con, keycode, modifiers_state[keycode]);
 }
 
 - (void) toggleStatefulModifier: (int)keycode {
     // Toggle the stored state.
     modifiers_state[keycode] = !modifiers_state[keycode];
     // Generate keydown and keyup.
-    qemu_input_event_send_key_qcode(dcl->con, keycode, true);
-    qemu_input_event_send_key_qcode(dcl->con, keycode, false);
+    qemu_input_event_send_key_qcode(dcl.con, keycode, true);
+    qemu_input_event_send_key_qcode(dcl.con, keycode, false);
 }
 
 // Does the work of sending input to the monitor
@@ -793,7 +815,7 @@ QemuCocoaView *cocoaView;
             }
 
             if (qemu_console_is_graphic(NULL)) {
-                qemu_input_event_send_key_qcode(dcl->con, keycode, true);
+                qemu_input_event_send_key_qcode(dcl.con, keycode, true);
             } else {
                 [self handleMonitorInput: event];
             }
@@ -808,7 +830,7 @@ QemuCocoaView *cocoaView;
             }
 
             if (qemu_console_is_graphic(NULL)) {
-                qemu_input_event_send_key_qcode(dcl->con, keycode, false);
+                qemu_input_event_send_key_qcode(dcl.con, keycode, false);
             }
             break;
         case NSEventTypeMouseMoved:
@@ -829,11 +851,7 @@ QemuCocoaView *cocoaView;
             mouse_event = true;
             break;
         case NSEventTypeLeftMouseDown:
-            if ([event modifierFlags] & NSEventModifierFlagCommand) {
-                buttons |= MOUSE_EVENT_RBUTTON;
-            } else {
-                buttons |= MOUSE_EVENT_LBUTTON;
-            }
+            buttons |= MOUSE_EVENT_LBUTTON;
             mouse_event = true;
             break;
         case NSEventTypeRightMouseDown:
@@ -845,11 +863,7 @@ QemuCocoaView *cocoaView;
             mouse_event = true;
             break;
         case NSEventTypeLeftMouseDragged:
-            if ([event modifierFlags] & NSEventModifierFlagCommand) {
-                buttons |= MOUSE_EVENT_RBUTTON;
-            } else {
-                buttons |= MOUSE_EVENT_LBUTTON;
-            }
+            buttons |= MOUSE_EVENT_LBUTTON;
             mouse_event = true;
             break;
         case NSEventTypeRightMouseDragged:
@@ -894,9 +908,9 @@ QemuCocoaView *cocoaView;
             /* Determine if this is a scroll up or scroll down event */
                 buttons = ([event deltaY] > 0) ?
                     INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
-                qemu_input_queue_btn(dcl->con, buttons, true);
+                qemu_input_queue_btn(dcl.con, buttons, true);
                 qemu_input_event_sync();
-                qemu_input_queue_btn(dcl->con, buttons, false);
+                qemu_input_queue_btn(dcl.con, buttons, false);
                 qemu_input_event_sync();
             }
             /*
@@ -924,7 +938,7 @@ QemuCocoaView *cocoaView;
                 [INPUT_BUTTON_MIDDLE]     = MOUSE_EVENT_MBUTTON,
                 [INPUT_BUTTON_RIGHT]      = MOUSE_EVENT_RBUTTON
             };
-            qemu_input_update_buttons(dcl->con, bmap, last_buttons, buttons);
+            qemu_input_update_buttons(dcl.con, bmap, last_buttons, buttons);
             last_buttons = buttons;
         }
         if (isMouseGrabbed) {
@@ -934,12 +948,12 @@ QemuCocoaView *cocoaView;
                  * clicks in the titlebar.
                  */
                 if ([self screenContainsPoint:p]) {
-                    qemu_input_queue_abs(dcl->con, INPUT_AXIS_X, p.x, 0, screen.width);
-                    qemu_input_queue_abs(dcl->con, INPUT_AXIS_Y, screen.height - p.y, 0, screen.height);
+                    qemu_input_queue_abs(dcl.con, INPUT_AXIS_X, p.x, 0, screen.width);
+                    qemu_input_queue_abs(dcl.con, INPUT_AXIS_Y, screen.height - p.y, 0, screen.height);
                 }
             } else {
-                qemu_input_queue_rel(dcl->con, INPUT_AXIS_X, (int)[event deltaX]);
-                qemu_input_queue_rel(dcl->con, INPUT_AXIS_Y, (int)[event deltaY]);
+                qemu_input_queue_rel(dcl.con, INPUT_AXIS_X, (int)[event deltaX]);
+                qemu_input_queue_rel(dcl.con, INPUT_AXIS_Y, (int)[event deltaY]);
             }
         } else {
             return false;
@@ -1008,7 +1022,7 @@ QemuCocoaView *cocoaView;
         for (index = 0; index < max_index; index++) {
             if (modifiers_state[index]) {
                 modifiers_state[index] = 0;
-                qemu_input_event_send_key_qcode(dcl->con, index, false);
+                qemu_input_event_send_key_qcode(dcl.con, index, false);
             }
         }
     });
@@ -1175,8 +1189,9 @@ QemuCocoaView *cocoaView;
 - (void) openDocumentation: (NSString *) filename
 {
     /* Where to look for local files */
-    NSString *path_array[] = {@"../share/doc/qemu/", @"../doc/qemu/", @"../docs/"};
+    NSString *path_array[] = {@"../share/doc/qemu/", @"../doc/qemu/", @"docs/"};
     NSString *full_file_path;
+    NSURL *full_file_url;
 
     /* iterate thru the possible paths until the file is found */
     int index;
@@ -1185,7 +1200,9 @@ QemuCocoaView *cocoaView;
         full_file_path = [full_file_path stringByDeletingLastPathComponent];
         full_file_path = [NSString stringWithFormat: @"%@/%@%@", full_file_path,
                           path_array[index], filename];
-        if ([[NSWorkspace sharedWorkspace] openFile: full_file_path] == YES) {
+        full_file_url = [NSURL fileURLWithPath: full_file_path
+                                   isDirectory: false];
+        if ([[NSWorkspace sharedWorkspace] openURL: full_file_url] == YES) {
             return;
         }
     }
@@ -1832,19 +1849,6 @@ static void cocoa_refresh(DisplayChangeListener *dcl)
     [pool release];
 }
 
-static void cocoa_cleanup(void)
-{
-    COCOA_DEBUG("qemu_cocoa: cocoa_cleanup\n");
-    g_free(dcl);
-}
-
-static const DisplayChangeListenerOps dcl_ops = {
-    .dpy_name          = "cocoa",
-    .dpy_gfx_update = cocoa_update,
-    .dpy_gfx_switch = cocoa_switch,
-    .dpy_refresh = cocoa_refresh,
-};
-
 static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
 {
     COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n");
@@ -1865,14 +1869,8 @@ static void cocoa_display_init(DisplayState *ds, DisplayOptions *opts)
         cursor_hide = 0;
     }
 
-    dcl = g_malloc0(sizeof(DisplayChangeListener));
-
     // register vga output callbacks
-    dcl->ops = &dcl_ops;
-    register_displaychangelistener(dcl);
-
-    // register cleanup function
-    atexit(cocoa_cleanup);
+    register_displaychangelistener(&dcl);
 }
 
 static QemuDisplay qemu_display_cocoa = {
This page took 0.035322 seconds and 4 git commands to generate.