Search
lxdream.org :: lxdream/src/drivers/video_osx.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/video_osx.c
changeset 839:51f1c4195790
prev805:b355f7b3ff2e
next850:28782ebbd01d
author nkeynes
date Sat Sep 06 05:21:57 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Disable the run actions when the system can't run (missing from cocoa ui code)
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 buttonMask;
    64     int flagsMask[MAX_MASK_KEYCODE];
    65 }
    66 @end
    68 @implementation LxdreamVideoView
    69 - (void)setIsGrabbed: (BOOL)grabbed
    70 {
    71     isGrabbed = grabbed;
    72 }
    73 - (void) setDelegate: (id)other
    74 {
    75     delegate = other;
    76 }
    77 - (id)delegate 
    78 {
    79     return delegate;
    80 }
    81 @end
    83 @implementation LxdreamOSXView
    84 //--------------------------------------------------------------------
    85 - (id)initWithFrame: (NSRect)contentRect
    86 {
    87     if( [super initWithFrame: contentRect] != nil ) {
    88         int i;
    89         isGrabbed = NO;
    90         buttonMask = 0;
    91         for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
    92             flagsMask[i] = 0;
    93         }
    94         return self;
    95     }
    96     return nil;
    97 }
    98 - (BOOL)requestGrab
    99 {
   100     if( delegate && [delegate respondsToSelector: @selector(viewRequestedGrab:)] )
   101         return [delegate performSelector: @selector(viewRequestedGrab:) withObject: self] != nil;
   102     return NO;
   103 }
   104 - (BOOL)requestUngrab
   105 {
   106     if( delegate && [delegate respondsToSelector: @selector(viewRequestedUngrab:)] )
   107         return [delegate performSelector: @selector(viewRequestedUngrab:) withObject: self] != nil;
   108     return NO;
   109 }
   110 - (BOOL)isOpaque
   111 {
   112     return YES;
   113 }
   114 - (BOOL)acceptsFirstResponder
   115 {
   116     return YES;
   117 }
   118 - (BOOL)isFlipped
   119 {
   120     return YES;
   121 }
   122 //--------------------------------------------------------------------
   123 - (void)drawRect: (NSRect) rect
   124 {
   125     NSSize size = [self frame].size;
   126     if( video_width != size.width || video_height != size.height ) {
   127         video_width = size.width;
   128         video_height = size.height;
   129         video_nsgl_update();
   130     }
   131     pvr2_redraw_display();
   132 }
   133 - (void)keyDown: (NSEvent *) event
   134 {
   135     if( ![event isARepeat] ) {
   136         input_event_keydown( NULL, [event keyCode]+1, 1 );
   137     }
   138 }
   139 - (void)keyUp: (NSEvent *) event
   140 {
   141     input_event_keyup( NULL, [event keyCode]+1, 1 );
   142 }
   143 - (void)flagsChanged: (NSEvent *) event
   144 {
   145     int keycode = [event keyCode];
   146     if( ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
   147         [self requestUngrab];
   148     }
   150     if( flagsMask[keycode] == 0 ) {
   151         input_event_keydown( NULL, keycode+1, 1 );
   152         flagsMask[keycode] = 1;
   153     } else {
   154         input_event_keyup( NULL, keycode+1, 1 );
   155         flagsMask[keycode] = 0;
   156     }
   157 }
   158 - (void)emitButtonEvent: (NSEvent *)event buttons: (int)buttons
   159 {
   160     if( isGrabbed ) {
   161         input_event_mouse( buttons, 0, 0, FALSE );
   162     } else {
   163         NSPoint pt = [event locationInWindow];
   164         input_event_mouse( buttonMask, (int)pt.x, (int)pt.y, TRUE );
   165     }
   166 }
   168 - (void)mouseDown: (NSEvent *) event
   169 {
   170     buttonMask |= 1;
   171     // If using grab but not grabbed yet, the first click should be consumed
   172     // by the grabber. In all other circumstances we process normally.
   173     if( isGrabbed || ![self requestGrab] ) {
   174         [self emitButtonEvent: event buttons: buttonMask];
   175     }
   176 }
   177 - (void)mouseUp: (NSEvent *)event
   178 {
   179     buttonMask &= ~1;
   180     [self emitButtonEvent: event buttons: buttonMask];
   181 }
   183 - (void)rightMouseDown: (NSEvent *) event
   184 {
   185     buttonMask |= 2;
   186     [self emitButtonEvent: event buttons: buttonMask];
   187 }
   188 - (void)rightMouseUp: (NSEvent *)event
   189 {
   190     buttonMask &= ~2;
   191     [self emitButtonEvent: event buttons: buttonMask];
   192 }
   193 - (void)otherMouseDown: (NSEvent *) event
   194 {
   195     buttonMask |= (1<< [event buttonNumber] );
   196     [self emitButtonEvent: event buttons: buttonMask];
   197 }
   198 - (void)otherMouseUp: (NSEvent *) event
   199 {
   200     buttonMask &= ~(1<< [event buttonNumber] );
   201     [self emitButtonEvent: event buttons: buttonMask];
   202 }
   203 - (void)mouseMoved: (NSEvent *) event
   204 {
   205     if( isGrabbed ) {
   206         input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
   207     }
   208 }
   209 - (void)mouseDragged: (NSEvent *) event
   210 {
   211     if( isGrabbed ) {
   212         input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
   213     }
   214 }
   215 - (void)rightMouseDragged: (NSEvent *) event
   216 {
   217     if( isGrabbed ) {
   218         input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
   219     }
   220 }
   221 - (void)otherMouseDragged: (NSEvent *) event
   222 {
   223     if( isGrabbed ) {
   224         input_event_mouse( buttonMask, [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
   225     }
   226 }
   228 @end
   230 NSView *video_osx_create_drawable()
   231 {
   232     NSRect contentRect = {{0,0},{640,480}};
   233     video_view = [[LxdreamOSXView alloc] initWithFrame: contentRect];
   234     [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
   235     return video_view;
   236 }
   238 static gboolean video_osx_init()
   239 {
   240     if( video_view == NULL ) {
   241         return FALSE;
   242     }
   243     if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
   244         return FALSE;
   245     }
   246     pvr2_setup_gl_context();
   247     return TRUE;
   248 }
   250 static void video_osx_shutdown()
   251 {
   252 }
   254 static void video_osx_display_blank( uint32_t colour )
   255 {
   256 }
   258 static int mac_keymap_cmp(const void *a, const void *b)
   259 {
   260     const gchar *key = a;
   261     const struct mac_keymap_struct *kb = b;
   262     return strcasecmp(key, kb->name);
   263 }
   265 static uint16_t video_osx_resolve_keysym( const gchar *keysym )
   266 {
   267     struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
   268     if( result == NULL ) {
   269         return 0;
   270     } else {
   271         return result->keycode + 1;
   272     }
   273 }
   275 static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
   276 {
   277     if( keycode < 1 || keycode > 128 ) {
   278         return DCKB_NONE;
   279     } else {
   280         return mac_keycode_to_dckeysym[keycode-1];
   281     }
   282 }
   284 static gchar *video_osx_keycode_to_keysym(uint16_t keycode)
   285 {
   286     if( keycode < 1 || keycode > 128 ) {
   287         return NULL;
   288     } else {
   289         return g_strdup(mac_keysyms_by_keycode[keycode-1]);
   290     }
.