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 770:429ff505c450
prev736:a02d1475ccfd
next780:4e4ea322cb84
author nkeynes
date Mon Jul 28 03:41:25 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Implement key-binding configuration pane for Cocoa UI
Minor tweaks for consistency and static-correctness
file annotate diff log raw
nkeynes@681
     1
/**
nkeynes@681
     2
 * $Id$
nkeynes@681
     3
 *
nkeynes@681
     4
 * The OS/X side of the video support (responsible for actually displaying / 
nkeynes@681
     5
 * rendering frames)
nkeynes@681
     6
 *
nkeynes@681
     7
 * Copyright (c) 2008 Nathan Keynes.
nkeynes@681
     8
 *
nkeynes@681
     9
 * This program is free software; you can redistribute it and/or modify
nkeynes@681
    10
 * it under the terms of the GNU General Public License as published by
nkeynes@681
    11
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@681
    12
 * (at your option) any later version.
nkeynes@681
    13
 *
nkeynes@681
    14
 * This program is distributed in the hope that it will be useful,
nkeynes@681
    15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@681
    16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@681
    17
 * GNU General Public License for more details.
nkeynes@681
    18
 */
nkeynes@681
    19
nkeynes@681
    20
#include <stdlib.h>
nkeynes@681
    21
#include <string.h>
nkeynes@681
    22
#include "lxdream.h"
nkeynes@681
    23
#include "display.h"
nkeynes@681
    24
#include "dckeysyms.h"
nkeynes@681
    25
#include "cocoaui/cocoaui.h"
nkeynes@681
    26
#include "drivers/video_nsgl.h"
nkeynes@681
    27
#include "drivers/video_gl.h"
nkeynes@681
    28
#include "pvr2/pvr2.h"
nkeynes@681
    29
#import <AppKit/AppKit.h>
nkeynes@681
    30
nkeynes@681
    31
#include "mac_keymap.h"
nkeynes@681
    32
nkeynes@681
    33
static gboolean video_osx_init();
nkeynes@681
    34
static void video_osx_shutdown();
nkeynes@681
    35
static void video_osx_display_blank( uint32_t colour );
nkeynes@681
    36
static uint16_t video_osx_resolve_keysym( const gchar *keysym );
nkeynes@681
    37
static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode);
nkeynes@770
    38
static gchar *video_osx_keycode_to_keysym(uint16_t keycode);
nkeynes@681
    39
nkeynes@700
    40
struct display_driver display_osx_driver = { 
nkeynes@700
    41
        "osx",
nkeynes@700
    42
        N_("OS X Cocoa GUI-based OpenGL driver"),
nkeynes@700
    43
        video_osx_init, video_osx_shutdown,
nkeynes@700
    44
        video_osx_resolve_keysym,
nkeynes@700
    45
        video_osx_keycode_to_dckeysym,
nkeynes@770
    46
        video_osx_keycode_to_keysym,
nkeynes@700
    47
        NULL, NULL, NULL, NULL, NULL, 
nkeynes@700
    48
        video_osx_display_blank, NULL };
nkeynes@681
    49
nkeynes@681
    50
nkeynes@681
    51
static NSView *video_view = NULL;
nkeynes@681
    52
int video_width = 640;
nkeynes@681
    53
int video_height = 480;
nkeynes@681
    54
nkeynes@681
    55
#define MAX_MASK_KEYCODE 128
nkeynes@681
    56
nkeynes@681
    57
@interface LxdreamVideoView : NSView
nkeynes@681
    58
{
nkeynes@681
    59
    BOOL isGrabbed;
nkeynes@681
    60
    int buttonMask;
nkeynes@681
    61
    int flagsMask[MAX_MASK_KEYCODE];
nkeynes@681
    62
}
nkeynes@681
    63
- (BOOL)isOpaque;
nkeynes@681
    64
- (BOOL)isFlipped;
nkeynes@681
    65
- (void)drawRect: (NSRect) rect;
nkeynes@681
    66
@end
nkeynes@681
    67
nkeynes@681
    68
@implementation LxdreamVideoView
nkeynes@681
    69
//--------------------------------------------------------------------
nkeynes@681
    70
- (id)initWithFrame: (NSRect)contentRect
nkeynes@681
    71
{
nkeynes@681
    72
    if( [super initWithFrame: contentRect] != nil ) {
nkeynes@681
    73
        int i;
nkeynes@681
    74
        isGrabbed = NO;
nkeynes@681
    75
        buttonMask = 0;
nkeynes@681
    76
        for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
nkeynes@681
    77
            flagsMask[i] = 0;
nkeynes@681
    78
        }
nkeynes@681
    79
        return self;
nkeynes@681
    80
    }
nkeynes@681
    81
    return nil;
nkeynes@681
    82
}
nkeynes@681
    83
- (BOOL)isOpaque
nkeynes@681
    84
{
nkeynes@736
    85
    return YES;
nkeynes@681
    86
}
nkeynes@681
    87
- (BOOL)acceptsFirstResponder
nkeynes@681
    88
{
nkeynes@736
    89
    return YES;
nkeynes@681
    90
}
nkeynes@681
    91
- (BOOL)isFlipped
nkeynes@681
    92
{
nkeynes@736
    93
    return YES;
nkeynes@681
    94
}
nkeynes@681
    95
//--------------------------------------------------------------------
nkeynes@681
    96
- (void)drawRect: (NSRect) rect
nkeynes@681
    97
{
nkeynes@681
    98
    NSSize size = [self frame].size;
nkeynes@681
    99
    if( video_width != size.width || video_height != size.height ) {
nkeynes@681
   100
        video_width = size.width;
nkeynes@681
   101
        video_height = size.height;
nkeynes@681
   102
        video_nsgl_update();
nkeynes@681
   103
    }
nkeynes@681
   104
    pvr2_redraw_display();
nkeynes@681
   105
}
nkeynes@681
   106
- (void)keyDown: (NSEvent *) event
nkeynes@681
   107
{
nkeynes@681
   108
    if( ![event isARepeat] ) {
nkeynes@681
   109
        input_event_keydown( NULL, [event keyCode]+1, 1 );
nkeynes@681
   110
    }
nkeynes@681
   111
}
nkeynes@681
   112
- (void)keyUp: (NSEvent *) event
nkeynes@681
   113
{
nkeynes@681
   114
    input_event_keyup( NULL, [event keyCode]+1, 1 );
nkeynes@681
   115
}
nkeynes@681
   116
- (void)flagsChanged: (NSEvent *) event
nkeynes@681
   117
{
nkeynes@681
   118
    int keycode = [event keyCode];
nkeynes@681
   119
    if ( isGrabbed && ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
nkeynes@681
   120
        // Release the display grab
nkeynes@681
   121
        isGrabbed = NO;
nkeynes@681
   122
        [NSCursor unhide];
nkeynes@681
   123
        CGAssociateMouseAndMouseCursorPosition(YES);
nkeynes@681
   124
        [((LxdreamMainWindow *)[self window]) setIsGrabbed: NO];
nkeynes@681
   125
    }
nkeynes@736
   126
nkeynes@681
   127
    if( flagsMask[keycode] == 0 ) {
nkeynes@681
   128
        input_event_keydown( NULL, keycode+1, 1 );
nkeynes@681
   129
        flagsMask[keycode] = 1;
nkeynes@681
   130
    } else {
nkeynes@681
   131
        input_event_keyup( NULL, keycode+1, 1 );
nkeynes@681
   132
        flagsMask[keycode] = 0;
nkeynes@681
   133
    }
nkeynes@681
   134
}
nkeynes@681
   135
- (void)mouseDown: (NSEvent *) event
nkeynes@681
   136
{
nkeynes@681
   137
    if( isGrabbed ) { 
nkeynes@681
   138
        buttonMask |= 1;
nkeynes@681
   139
        input_event_mouse( buttonMask, 0, 0 );
nkeynes@681
   140
    } else { // take display grab
nkeynes@681
   141
        isGrabbed = YES;
nkeynes@681
   142
        [NSCursor hide];
nkeynes@681
   143
        CGAssociateMouseAndMouseCursorPosition(NO);
nkeynes@681
   144
        [((LxdreamMainWindow *)[self window]) setIsGrabbed: YES];
nkeynes@681
   145
    }
nkeynes@681
   146
}
nkeynes@681
   147
- (void)mouseUp: (NSEvent *)event
nkeynes@681
   148
{
nkeynes@681
   149
    buttonMask &= ~1;
nkeynes@681
   150
    input_event_mouse( buttonMask, 0, 0 );
nkeynes@681
   151
}
nkeynes@681
   152
nkeynes@681
   153
- (void)rightMouseDown: (NSEvent *) event
nkeynes@681
   154
{
nkeynes@681
   155
    buttonMask |= 2;
nkeynes@681
   156
    input_event_mouse( buttonMask, 0, 0 );
nkeynes@681
   157
}
nkeynes@681
   158
- (void)rightMouseUp: (NSEvent *)event
nkeynes@681
   159
{
nkeynes@681
   160
    buttonMask &= ~2;
nkeynes@681
   161
    input_event_mouse( buttonMask, 0, 0 );
nkeynes@681
   162
}
nkeynes@681
   163
- (void)otherMouseDown: (NSEvent *) event
nkeynes@681
   164
{
nkeynes@681
   165
    buttonMask |= (1<< [event buttonNumber] );
nkeynes@681
   166
    input_event_mouse( buttonMask, 0, 0 );
nkeynes@681
   167
}
nkeynes@681
   168
- (void)otherMouseUp: (NSEvent *) event
nkeynes@681
   169
{
nkeynes@681
   170
    buttonMask &= ~(1<< [event buttonNumber] );
nkeynes@681
   171
    input_event_mouse( buttonMask, 0, 0 );
nkeynes@681
   172
}
nkeynes@681
   173
- (void)mouseMoved: (NSEvent *) event
nkeynes@681
   174
{
nkeynes@681
   175
    if( isGrabbed ) {
nkeynes@681
   176
        input_event_mouse( buttonMask, [event deltaX], [event deltaY] );
nkeynes@681
   177
    }
nkeynes@681
   178
}
nkeynes@681
   179
- (void)mouseDragged: (NSEvent *) event
nkeynes@681
   180
{
nkeynes@681
   181
    if( isGrabbed ) {
nkeynes@681
   182
        input_event_mouse( buttonMask, [event deltaX], [event deltaY] );
nkeynes@681
   183
    }
nkeynes@681
   184
}
nkeynes@681
   185
- (void)rightMouseDragged: (NSEvent *) event
nkeynes@681
   186
{
nkeynes@681
   187
    if( isGrabbed ) {
nkeynes@681
   188
        input_event_mouse( buttonMask, [event deltaX], [event deltaY] );
nkeynes@681
   189
    }
nkeynes@681
   190
}
nkeynes@681
   191
- (void)otherMouseDragged: (NSEvent *) event
nkeynes@681
   192
{
nkeynes@681
   193
    if( isGrabbed ) {
nkeynes@681
   194
        input_event_mouse( buttonMask, [event deltaX], [event deltaY] );
nkeynes@681
   195
    }
nkeynes@681
   196
}
nkeynes@681
   197
nkeynes@681
   198
@end
nkeynes@681
   199
nkeynes@681
   200
NSView *video_osx_create_drawable()
nkeynes@681
   201
{
nkeynes@681
   202
    NSRect contentRect = {{0,0},{640,480}};
nkeynes@681
   203
    video_view = [[LxdreamVideoView alloc] initWithFrame: contentRect];
nkeynes@681
   204
    [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
nkeynes@681
   205
    return video_view;
nkeynes@681
   206
}
nkeynes@681
   207
nkeynes@681
   208
static gboolean video_osx_init()
nkeynes@681
   209
{
nkeynes@736
   210
    if( video_view == NULL ) {
nkeynes@736
   211
        return FALSE;
nkeynes@736
   212
    }
nkeynes@736
   213
    if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
nkeynes@736
   214
        return FALSE;
nkeynes@736
   215
    }
nkeynes@736
   216
    pvr2_setup_gl_context();
nkeynes@736
   217
    return TRUE;
nkeynes@681
   218
}
nkeynes@681
   219
nkeynes@681
   220
static void video_osx_shutdown()
nkeynes@681
   221
{
nkeynes@681
   222
}
nkeynes@681
   223
nkeynes@681
   224
static void video_osx_display_blank( uint32_t colour )
nkeynes@681
   225
{
nkeynes@681
   226
}
nkeynes@681
   227
nkeynes@681
   228
static int mac_keymap_cmp(const void *a, const void *b)
nkeynes@681
   229
{
nkeynes@681
   230
    const gchar *key = a;
nkeynes@681
   231
    const struct mac_keymap_struct *kb = b;
nkeynes@681
   232
    return strcasecmp(key, kb->name);
nkeynes@681
   233
}
nkeynes@681
   234
nkeynes@681
   235
static uint16_t video_osx_resolve_keysym( const gchar *keysym )
nkeynes@681
   236
{
nkeynes@681
   237
    struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
nkeynes@681
   238
    if( result == NULL ) {
nkeynes@681
   239
        return 0;
nkeynes@681
   240
    } else {
nkeynes@681
   241
        return result->keycode + 1;
nkeynes@681
   242
    }
nkeynes@681
   243
}
nkeynes@681
   244
nkeynes@681
   245
static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
nkeynes@681
   246
{
nkeynes@681
   247
    if( keycode < 1 || keycode > 128 ) {
nkeynes@681
   248
        return DCKB_NONE;
nkeynes@681
   249
    } else {
nkeynes@681
   250
        return mac_keycode_to_dckeysym[keycode-1];
nkeynes@681
   251
    }
nkeynes@681
   252
}
nkeynes@681
   253
nkeynes@770
   254
static gchar *video_osx_keycode_to_keysym(uint16_t keycode)
nkeynes@770
   255
{
nkeynes@770
   256
    if( keycode < 1 || keycode > 128 ) {
nkeynes@770
   257
        return NULL;
nkeynes@770
   258
    } else {
nkeynes@770
   259
        return g_strdup(mac_keysyms_by_keycode[keycode-1]);
nkeynes@770
   260
    }
nkeynes@770
   261
}
.