1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/drivers/video_osx.c Sun Jun 01 00:47:45 2008 +0000
1.7 + * The OS/X side of the video support (responsible for actually displaying /
1.8 + * rendering frames)
1.10 + * Copyright (c) 2008 Nathan Keynes.
1.12 + * This program is free software; you can redistribute it and/or modify
1.13 + * it under the terms of the GNU General Public License as published by
1.14 + * the Free Software Foundation; either version 2 of the License, or
1.15 + * (at your option) any later version.
1.17 + * This program is distributed in the hope that it will be useful,
1.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.20 + * GNU General Public License for more details.
1.23 +#include <stdlib.h>
1.24 +#include <string.h>
1.25 +#include "lxdream.h"
1.26 +#include "display.h"
1.27 +#include "dckeysyms.h"
1.28 +#include "cocoaui/cocoaui.h"
1.29 +#include "drivers/video_nsgl.h"
1.30 +#include "drivers/video_gl.h"
1.31 +#include "pvr2/pvr2.h"
1.32 +#import <AppKit/AppKit.h>
1.34 +#include "mac_keymap.h"
1.36 +static gboolean video_osx_init();
1.37 +static void video_osx_shutdown();
1.38 +static void video_osx_display_blank( uint32_t colour );
1.39 +static uint16_t video_osx_resolve_keysym( const gchar *keysym );
1.40 +static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode);
1.42 +struct display_driver display_osx_driver = { "osx", video_osx_init, video_osx_shutdown,
1.43 + video_osx_resolve_keysym,
1.44 + video_osx_keycode_to_dckeysym,
1.46 + NULL, NULL, NULL, NULL, NULL,
1.47 + video_osx_display_blank, NULL };
1.50 +static NSView *video_view = NULL;
1.51 +int video_width = 640;
1.52 +int video_height = 480;
1.54 +#define MAX_MASK_KEYCODE 128
1.56 +@interface LxdreamVideoView : NSView
1.60 + int flagsMask[MAX_MASK_KEYCODE];
1.64 +- (void)drawRect: (NSRect) rect;
1.67 +@implementation LxdreamVideoView
1.68 +//--------------------------------------------------------------------
1.69 +- (id)initWithFrame: (NSRect)contentRect
1.71 + if( [super initWithFrame: contentRect] != nil ) {
1.75 + for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
1.86 +- (BOOL)acceptsFirstResponder
1.94 +//--------------------------------------------------------------------
1.95 +- (void)drawRect: (NSRect) rect
1.97 + NSSize size = [self frame].size;
1.98 + if( video_width != size.width || video_height != size.height ) {
1.99 + video_width = size.width;
1.100 + video_height = size.height;
1.101 + video_nsgl_update();
1.103 + pvr2_redraw_display();
1.105 +- (void)keyDown: (NSEvent *) event
1.107 + if( ![event isARepeat] ) {
1.108 + input_event_keydown( NULL, [event keyCode]+1, 1 );
1.111 +- (void)keyUp: (NSEvent *) event
1.113 + input_event_keyup( NULL, [event keyCode]+1, 1 );
1.115 +- (void)flagsChanged: (NSEvent *) event
1.117 + int keycode = [event keyCode];
1.118 + if ( isGrabbed && ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
1.119 + // Release the display grab
1.121 + [NSCursor unhide];
1.122 + CGAssociateMouseAndMouseCursorPosition(YES);
1.123 + [((LxdreamMainWindow *)[self window]) setIsGrabbed: NO];
1.126 + if( flagsMask[keycode] == 0 ) {
1.127 + input_event_keydown( NULL, keycode+1, 1 );
1.128 + flagsMask[keycode] = 1;
1.130 + input_event_keyup( NULL, keycode+1, 1 );
1.131 + flagsMask[keycode] = 0;
1.134 +- (void)mouseDown: (NSEvent *) event
1.136 + if( isGrabbed ) {
1.138 + input_event_mouse( buttonMask, 0, 0 );
1.139 + } else { // take display grab
1.142 + CGAssociateMouseAndMouseCursorPosition(NO);
1.143 + [((LxdreamMainWindow *)[self window]) setIsGrabbed: YES];
1.146 +- (void)mouseUp: (NSEvent *)event
1.148 + buttonMask &= ~1;
1.149 + input_event_mouse( buttonMask, 0, 0 );
1.152 +- (void)rightMouseDown: (NSEvent *) event
1.155 + input_event_mouse( buttonMask, 0, 0 );
1.157 +- (void)rightMouseUp: (NSEvent *)event
1.159 + buttonMask &= ~2;
1.160 + input_event_mouse( buttonMask, 0, 0 );
1.162 +- (void)otherMouseDown: (NSEvent *) event
1.164 + buttonMask |= (1<< [event buttonNumber] );
1.165 + input_event_mouse( buttonMask, 0, 0 );
1.167 +- (void)otherMouseUp: (NSEvent *) event
1.169 + buttonMask &= ~(1<< [event buttonNumber] );
1.170 + input_event_mouse( buttonMask, 0, 0 );
1.172 +- (void)mouseMoved: (NSEvent *) event
1.174 + if( isGrabbed ) {
1.175 + input_event_mouse( buttonMask, [event deltaX], [event deltaY] );
1.178 +- (void)mouseDragged: (NSEvent *) event
1.180 + if( isGrabbed ) {
1.181 + input_event_mouse( buttonMask, [event deltaX], [event deltaY] );
1.184 +- (void)rightMouseDragged: (NSEvent *) event
1.186 + if( isGrabbed ) {
1.187 + input_event_mouse( buttonMask, [event deltaX], [event deltaY] );
1.190 +- (void)otherMouseDragged: (NSEvent *) event
1.192 + if( isGrabbed ) {
1.193 + input_event_mouse( buttonMask, [event deltaX], [event deltaY] );
1.199 +NSView *video_osx_create_drawable()
1.201 + NSRect contentRect = {{0,0},{640,480}};
1.202 + video_view = [[LxdreamVideoView alloc] initWithFrame: contentRect];
1.203 + [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
1.204 + return video_view;
1.207 +static gboolean video_osx_init()
1.209 + if( video_view == NULL ) {
1.212 + if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
1.215 + pvr2_setup_gl_context();
1.219 +static void video_osx_shutdown()
1.223 +static void video_osx_display_blank( uint32_t colour )
1.227 +static int mac_keymap_cmp(const void *a, const void *b)
1.229 + const gchar *key = a;
1.230 + const struct mac_keymap_struct *kb = b;
1.231 + return strcasecmp(key, kb->name);
1.234 +static uint16_t video_osx_resolve_keysym( const gchar *keysym )
1.236 + struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
1.237 + if( result == NULL ) {
1.240 + return result->keycode + 1;
1.244 +static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
1.246 + if( keycode < 1 || keycode > 128 ) {
1.247 + return DCKB_NONE;
1.249 + return mac_keycode_to_dckeysym[keycode-1];