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 1010:a506a2f66180
prev964:f2f3c7612d06
next1076:18c164e8aec4
author nkeynes
date Sun Apr 12 02:04:27 2009 +0000 (11 years ago)
permissions -rw-r--r--
last change Fix analogue joystick input
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 "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;
    56 int video_width = 640;
    57 int video_height = 480;
    59 #define MAX_MASK_KEYCODE 128
    61 @interface LxdreamOSXView : LxdreamVideoView
    62 {
    63     int flagsMask[MAX_MASK_KEYCODE];
    64 }
    65 @end
    67 @implementation LxdreamVideoView
    68 - (void)setIsGrabbed: (BOOL)grabbed
    69 {
    70     isGrabbed = grabbed;
    71 }
    72 - (void) setDelegate: (id)other
    73 {
    74     delegate = other;
    75 }
    76 - (id)delegate 
    77 {
    78     return delegate;
    79 }
    80 @end
    82 @implementation LxdreamOSXView
    83 //--------------------------------------------------------------------
    84 - (id)initWithFrame: (NSRect)contentRect
    85 {
    86     if( [super initWithFrame: contentRect] != nil ) {
    87         int i;
    88         isGrabbed = NO;
    89         for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
    90             flagsMask[i] = 0;
    91         }
    92         return self;
    93     }
    94     return nil;
    95 }
    96 - (BOOL)requestGrab
    97 {
    98     if( delegate && [delegate respondsToSelector: @selector(viewRequestedGrab:)] )
    99         return [delegate performSelector: @selector(viewRequestedGrab:) withObject: self] != nil;
   100     return NO;
   101 }
   102 - (BOOL)requestUngrab
   103 {
   104     if( delegate && [delegate respondsToSelector: @selector(viewRequestedUngrab:)] )
   105         return [delegate performSelector: @selector(viewRequestedUngrab:) withObject: self] != nil;
   106     return NO;
   107 }
   108 - (BOOL)isOpaque
   109 {
   110     return YES;
   111 }
   112 - (BOOL)acceptsFirstResponder
   113 {
   114     return YES;
   115 }
   116 - (BOOL)isFlipped
   117 {
   118     return YES;
   119 }
   120 //--------------------------------------------------------------------
   121 - (void)drawRect: (NSRect) rect
   122 {
   123     NSSize size = [self frame].size;
   124     if( video_width != size.width || video_height != size.height ) {
   125         video_width = size.width;
   126         video_height = size.height;
   127         video_nsgl_update();
   128     }
   129     pvr2_redraw_display();
   130 }
   131 - (void)keyDown: (NSEvent *) event
   132 {
   133     if( ![event isARepeat] ) {
   134         input_event_keydown( NULL, [event keyCode]+1, MAX_PRESSURE );
   135     }
   136 }
   137 - (void)keyUp: (NSEvent *) event
   138 {
   139     input_event_keyup( NULL, [event keyCode]+1 );
   140 }
   141 - (void)flagsChanged: (NSEvent *) event
   142 {
   143     int keycode = [event keyCode];
   144     if( ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
   145         [self requestUngrab];
   146     }
   148     if( flagsMask[keycode] == 0 ) {
   149         input_event_keydown( NULL, keycode+1, MAX_PRESSURE );
   150         flagsMask[keycode] = 1;
   151     } else {
   152         input_event_keyup( NULL, keycode+1 );
   153         flagsMask[keycode] = 0;
   154     }
   155 }
   156 - (void)emitMouseDownEvent: (NSEvent *)event button: (int)button
   157 {
   158     if( isGrabbed ) {
   159         input_event_mousedown( button, 0, 0, FALSE );
   160     } else {
   161         NSPoint pt = [event locationInWindow];
   162         int x = (int)pt.x;
   163         int y = video_height - (int)pt.y;
   164         gl_window_to_system_coords(&x,&y);
   165         input_event_mousedown( button, x, y, TRUE ); 
   166     }
   167 }
   168 - (void)emitMouseUpEvent: (NSEvent *)event button: (int)button
   169 {
   170     if( isGrabbed ) {
   171         input_event_mouseup( button, 0, 0, FALSE );
   172     } else {
   173         NSPoint pt = [event locationInWindow];
   174         int x = (int)pt.x;
   175         int y = video_height - (int)pt.y;
   176         gl_window_to_system_coords(&x,&y);
   177         input_event_mouseup( button, x, y, TRUE ); 
   178     }
   179 }
   180 - (void)emitMouseMoveEvent: (NSEvent *)event
   181 {
   182     if( isGrabbed ) {
   183         input_event_mousemove( [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
   184     } else {
   185         NSPoint pt = [event locationInWindow];
   186         int x = (int)pt.x;
   187         int y = video_height - (int)pt.y;
   188         gl_window_to_system_coords(&x,&y);
   189         input_event_mousemove( x, y, TRUE ); 
   190     }    
   191 }
   192 - (void)mouseExited: (NSEvent *)event
   193 {
   194     if( !isGrabbed ) {
   195         input_event_mousemove( -1, -1, TRUE );
   196     }
   197 }
   199 - (void)mouseDown: (NSEvent *) event
   200 {
   201     // If using grab but not grabbed yet, the first click should be consumed
   202     // by the grabber. In all other circumstances we process normally.
   203     if( isGrabbed || ![self requestGrab] ) {
   204         [self emitMouseDownEvent: event button: 0];
   205     }
   206 }
   207 - (void)mouseUp: (NSEvent *)event
   208 {
   209     [self emitMouseUpEvent: event button: 0];
   210 }
   212 - (void)rightMouseDown: (NSEvent *) event
   213 {
   214     [self emitMouseDownEvent: event button: 1];
   215 }
   216 - (void)rightMouseUp: (NSEvent *)event
   217 {
   218     [self emitMouseUpEvent: event button: 1];
   219 }
   220 - (void)otherMouseDown: (NSEvent *) event
   221 {
   222     [self emitMouseDownEvent: event button: [event buttonNumber]];
   223 }
   224 - (void)otherMouseUp: (NSEvent *) event
   225 {
   226     [self emitMouseUpEvent: event button: [event buttonNumber]];
   227 }
   228 - (void)mouseMoved: (NSEvent *) event
   229 {
   230     [self emitMouseMoveEvent: event];
   231 }
   232 - (void)mouseDragged: (NSEvent *) event
   233 {
   234     [self emitMouseMoveEvent: event];
   235 }
   236 - (void)rightMouseDragged: (NSEvent *) event
   237 {
   238     [self emitMouseMoveEvent: event];
   239 }
   240 - (void)otherMouseDragged: (NSEvent *) event
   241 {
   242     [self emitMouseMoveEvent: event];
   243 }
   245 @end
   247 NSView *video_osx_create_drawable()
   248 {
   249     NSRect contentRect = {{0,0},{640,480}};
   250     video_view = [[LxdreamOSXView alloc] initWithFrame: contentRect];
   251     [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
   252     return video_view;
   253 }
   255 static gboolean video_osx_init()
   256 {
   257     if( video_view == NULL ) {
   258         return FALSE;
   259     }
   260     if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
   261         return FALSE;
   262     }
   263     pvr2_setup_gl_context();
   264     return TRUE;
   265 }
   267 static void video_osx_shutdown()
   268 {
   269 }
   271 static void video_osx_display_blank( uint32_t colour )
   272 {
   273 }
   275 static int mac_keymap_cmp(const void *a, const void *b)
   276 {
   277     const gchar *key = a;
   278     const struct mac_keymap_struct *kb = b;
   279     return strcasecmp(key, kb->name);
   280 }
   282 static uint16_t video_osx_resolve_keysym( const gchar *keysym )
   283 {
   284     struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
   285     if( result == NULL ) {
   286         return 0;
   287     } else {
   288         return result->keycode + 1;
   289     }
   290 }
   292 static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
   293 {
   294     if( keycode < 1 || keycode > 128 ) {
   295         return DCKB_NONE;
   296     } else {
   297         return mac_keycode_to_dckeysym[keycode-1];
   298     }
   299 }
   301 static gchar *video_osx_keycode_to_keysym(uint16_t keycode)
   302 {
   303     if( keycode < 1 || keycode > 128 ) {
   304         return NULL;
   305     } else {
   306         return g_strdup(mac_keysyms_by_keycode[keycode-1]);
   307     }
.