Search
lxdream.org :: lxdream/src/drivers/video_osx.m
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/video_osx.m
changeset 1251:b8ab59d39756
prev1236:d93175c36387
author nkeynes
date Mon Mar 05 22:20:33 2012 +1000 (12 years ago)
permissions -rw-r--r--
last change Fix boundary of the first vertical gap in view
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * The OS/X side of the video support (responsible for actually displaying / 
     5  * rendering frames)
     6  *
     7  * Copyright (c) 2008 Nathan Keynes.
     8  *
     9  * This program is free software; you can redistribute it and/or modify
    10  * it under the terms of the GNU General Public License as published by
    11  * the Free Software Foundation; either version 2 of the License, or
    12  * (at your option) any later version.
    13  *
    14  * This program is distributed in the hope that it will be useful,
    15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17  * GNU General Public License for more details.
    18  */
    20 #include <stdlib.h>
    21 #include <string.h>
    22 #include "lxdream.h"
    23 #include "display.h"
    24 #include "dckeysyms.h"
    25 #include "cocoaui/cocoaui.h"
    26 #include "drivers/video_nsgl.h"
    27 #include "drivers/video_gl.h"
    28 #include "pvr2/pvr2.h"
    29 #import <AppKit/AppKit.h>
    31 #include "drivers/mac_keymap.h"
    33 #define MOUSE_X_SCALE 5
    34 #define MOUSE_Y_SCALE 5
    36 static gboolean video_osx_init();
    37 static void video_osx_shutdown();
    38 static void video_osx_display_blank( uint32_t colour );
    39 static uint16_t video_osx_resolve_keysym( const gchar *keysym );
    40 static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode);
    41 static gchar *video_osx_keycode_to_keysym(uint16_t keycode);
    43 struct display_driver display_osx_driver = { 
    44         "osx",
    45         N_("OS X Cocoa GUI-based OpenGL driver"),
    46         video_osx_init, video_osx_shutdown,
    47         video_osx_resolve_keysym,
    48         video_osx_keycode_to_dckeysym,
    49         video_osx_keycode_to_keysym,
    50         NULL, NULL, NULL, NULL, NULL,
    51         NULL,
    52         video_osx_display_blank, NULL };
    55 static NSView *video_view = NULL;
    57 #define MAX_MASK_KEYCODE 128
    59 @interface LxdreamOSXView : LxdreamVideoView
    60 {
    61     int flagsMask[MAX_MASK_KEYCODE];
    62 }
    63 @end
    65 @implementation LxdreamVideoView
    66 - (void)setIsGrabbed: (BOOL)grabbed
    67 {
    68     isGrabbed = grabbed;
    69 }
    70 - (void) setDelegate: (id)other
    71 {
    72     delegate = other;
    73 }
    74 - (id)delegate 
    75 {
    76     return delegate;
    77 }
    78 @end
    80 @implementation LxdreamOSXView
    81 //--------------------------------------------------------------------
    82 - (id)initWithFrame: (NSRect)contentRect
    83 {
    84     if( [super initWithFrame: contentRect] != nil ) {
    85         int i;
    86         isGrabbed = NO;
    87         for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
    88             flagsMask[i] = 0;
    89         }
    90         return self;
    91     }
    92     return nil;
    93 }
    94 - (BOOL)requestGrab
    95 {
    96     if( delegate && [delegate respondsToSelector: @selector(viewRequestedGrab:)] )
    97         return [delegate performSelector: @selector(viewRequestedGrab:) withObject: self] != nil;
    98     return NO;
    99 }
   100 - (BOOL)requestUngrab
   101 {
   102     if( delegate && [delegate respondsToSelector: @selector(viewRequestedUngrab:)] )
   103         return [delegate performSelector: @selector(viewRequestedUngrab:) withObject: self] != nil;
   104     return NO;
   105 }
   106 - (BOOL)isOpaque
   107 {
   108     return YES;
   109 }
   110 - (BOOL)acceptsFirstResponder
   111 {
   112     return YES;
   113 }
   114 - (BOOL)isFlipped
   115 {
   116     return YES;
   117 }
   118 //--------------------------------------------------------------------
   119 - (void)drawRect: (NSRect) rect
   120 {
   121     NSSize size = [self frame].size;
   122     if( video_width != size.width || video_height != size.height ) {
   123         gl_set_video_size(size.width, size.height, 0);
   124         video_nsgl_update();
   125     }
   126     pvr2_draw_frame();
   127 }
   128 - (void)keyDown: (NSEvent *) event
   129 {
   130     if( ![event isARepeat] ) {
   131         input_event_keydown( NULL, [event keyCode]+1, MAX_PRESSURE );
   132     }
   133 }
   134 - (void)keyUp: (NSEvent *) event
   135 {
   136     input_event_keyup( NULL, [event keyCode]+1 );
   137 }
   138 - (void)flagsChanged: (NSEvent *) event
   139 {
   140     int keycode = [event keyCode];
   141     if( ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
   142         [self requestUngrab];
   143     }
   145     if( flagsMask[keycode] == 0 ) {
   146         input_event_keydown( NULL, keycode+1, MAX_PRESSURE );
   147         flagsMask[keycode] = 1;
   148     } else {
   149         input_event_keyup( NULL, keycode+1 );
   150         flagsMask[keycode] = 0;
   151     }
   152 }
   153 - (void)emitMouseDownEvent: (NSEvent *)event button: (int)button
   154 {
   155     if( isGrabbed ) {
   156         input_event_mousedown( button, 0, 0, FALSE );
   157     } else {
   158         NSPoint pt = [event locationInWindow];
   159         int x = (int)pt.x;
   160         int y = video_height - (int)pt.y;
   161         gl_window_to_system_coords(&x,&y);
   162         input_event_mousedown( button, x, y, TRUE ); 
   163     }
   164 }
   165 - (void)emitMouseUpEvent: (NSEvent *)event button: (int)button
   166 {
   167     if( isGrabbed ) {
   168         input_event_mouseup( button, 0, 0, FALSE );
   169     } else {
   170         NSPoint pt = [event locationInWindow];
   171         int x = (int)pt.x;
   172         int y = video_height - (int)pt.y;
   173         gl_window_to_system_coords(&x,&y);
   174         input_event_mouseup( button, x, y, TRUE ); 
   175     }
   176 }
   177 - (void)emitMouseMoveEvent: (NSEvent *)event
   178 {
   179     if( isGrabbed ) {
   180         input_event_mousemove( [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
   181     } else {
   182         NSPoint pt = [event locationInWindow];
   183         int x = (int)pt.x;
   184         int y = video_height - (int)pt.y;
   185         gl_window_to_system_coords(&x,&y);
   186         input_event_mousemove( x, y, TRUE ); 
   187     }    
   188 }
   189 - (void)mouseExited: (NSEvent *)event
   190 {
   191     if( !isGrabbed ) {
   192         input_event_mousemove( -1, -1, TRUE );
   193     }
   194 }
   196 - (void)mouseDown: (NSEvent *) event
   197 {
   198     // If using grab but not grabbed yet, the first click should be consumed
   199     // by the grabber. In all other circumstances we process normally.
   200     if( isGrabbed || ![self requestGrab] ) {
   201         [self emitMouseDownEvent: event button: 0];
   202     }
   203 }
   204 - (void)mouseUp: (NSEvent *)event
   205 {
   206     [self emitMouseUpEvent: event button: 0];
   207 }
   209 - (void)rightMouseDown: (NSEvent *) event
   210 {
   211     [self emitMouseDownEvent: event button: 1];
   212 }
   213 - (void)rightMouseUp: (NSEvent *)event
   214 {
   215     [self emitMouseUpEvent: event button: 1];
   216 }
   217 - (void)otherMouseDown: (NSEvent *) event
   218 {
   219     [self emitMouseDownEvent: event button: [event buttonNumber]];
   220 }
   221 - (void)otherMouseUp: (NSEvent *) event
   222 {
   223     [self emitMouseUpEvent: event button: [event buttonNumber]];
   224 }
   225 - (void)mouseMoved: (NSEvent *) event
   226 {
   227     [self emitMouseMoveEvent: event];
   228 }
   229 - (void)mouseDragged: (NSEvent *) event
   230 {
   231     [self emitMouseMoveEvent: event];
   232 }
   233 - (void)rightMouseDragged: (NSEvent *) event
   234 {
   235     [self emitMouseMoveEvent: event];
   236 }
   237 - (void)otherMouseDragged: (NSEvent *) event
   238 {
   239     [self emitMouseMoveEvent: event];
   240 }
   242 @end
   244 NSView *video_osx_create_drawable()
   245 {
   246     NSRect contentRect = {{0,0},{640,480}};
   247     video_view = [[LxdreamOSXView alloc] initWithFrame: contentRect];
   248     [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
   249     return video_view;
   250 }
   252 static gboolean video_osx_init()
   253 {
   254     if( video_view == NULL ) {
   255         return FALSE;
   256     }
   257     if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
   258         return FALSE;
   259     }
   260     pvr2_setup_gl_context();
   261     return TRUE;
   262 }
   264 static void video_osx_shutdown()
   265 {
   266 }
   268 static void video_osx_display_blank( uint32_t colour )
   269 {
   270 }
   272 static int mac_keymap_cmp(const void *a, const void *b)
   273 {
   274     const gchar *key = a;
   275     const struct mac_keymap_struct *kb = b;
   276     return strcasecmp(key, kb->name);
   277 }
   279 static uint16_t video_osx_resolve_keysym( const gchar *keysym )
   280 {
   281     struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
   282     if( result == NULL ) {
   283         return 0;
   284     } else {
   285         return result->keycode + 1;
   286     }
   287 }
   289 static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
   290 {
   291     if( keycode < 1 || keycode > 128 ) {
   292         return DCKB_NONE;
   293     } else {
   294         return mac_keycode_to_dckeysym[keycode-1];
   295     }
   296 }
   298 static gchar *video_osx_keycode_to_keysym(uint16_t keycode)
   299 {
   300     if( keycode < 1 || keycode > 128 ) {
   301         return NULL;
   302     } else {
   303         return g_strdup(mac_keysyms_by_keycode[keycode-1]);
   304     }
.