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 854:130928a3cdcb
prev850:28782ebbd01d
author nkeynes
date Tue Sep 09 00:51:43 2008 +0000 (13 years ago)
permissions -rw-r--r--
last change Add general gl_window_to_system_coords function to convert window system coordinates
back into something in the DC range of 640x480, update mouse events to use it
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@781
    33
#define MOUSE_X_SCALE 5
nkeynes@781
    34
#define MOUSE_Y_SCALE 5
nkeynes@781
    35
nkeynes@681
    36
static gboolean video_osx_init();
nkeynes@681
    37
static void video_osx_shutdown();
nkeynes@681
    38
static void video_osx_display_blank( uint32_t colour );
nkeynes@681
    39
static uint16_t video_osx_resolve_keysym( const gchar *keysym );
nkeynes@681
    40
static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode);
nkeynes@770
    41
static gchar *video_osx_keycode_to_keysym(uint16_t keycode);
nkeynes@681
    42
nkeynes@700
    43
struct display_driver display_osx_driver = { 
nkeynes@700
    44
        "osx",
nkeynes@700
    45
        N_("OS X Cocoa GUI-based OpenGL driver"),
nkeynes@700
    46
        video_osx_init, video_osx_shutdown,
nkeynes@700
    47
        video_osx_resolve_keysym,
nkeynes@700
    48
        video_osx_keycode_to_dckeysym,
nkeynes@770
    49
        video_osx_keycode_to_keysym,
nkeynes@805
    50
        NULL, NULL, NULL, NULL, NULL,
nkeynes@805
    51
        NULL,
nkeynes@700
    52
        video_osx_display_blank, NULL };
nkeynes@681
    53
nkeynes@681
    54
nkeynes@681
    55
static NSView *video_view = NULL;
nkeynes@681
    56
int video_width = 640;
nkeynes@681
    57
int video_height = 480;
nkeynes@681
    58
nkeynes@681
    59
#define MAX_MASK_KEYCODE 128
nkeynes@681
    60
nkeynes@780
    61
@interface LxdreamOSXView : LxdreamVideoView
nkeynes@681
    62
{
nkeynes@681
    63
    int flagsMask[MAX_MASK_KEYCODE];
nkeynes@681
    64
}
nkeynes@681
    65
@end
nkeynes@681
    66
nkeynes@681
    67
@implementation LxdreamVideoView
nkeynes@780
    68
- (void)setIsGrabbed: (BOOL)grabbed
nkeynes@780
    69
{
nkeynes@780
    70
    isGrabbed = grabbed;
nkeynes@780
    71
}
nkeynes@780
    72
- (void) setDelegate: (id)other
nkeynes@780
    73
{
nkeynes@780
    74
    delegate = other;
nkeynes@780
    75
}
nkeynes@780
    76
- (id)delegate 
nkeynes@780
    77
{
nkeynes@780
    78
    return delegate;
nkeynes@780
    79
}
nkeynes@780
    80
@end
nkeynes@780
    81
nkeynes@780
    82
@implementation LxdreamOSXView
nkeynes@681
    83
//--------------------------------------------------------------------
nkeynes@681
    84
- (id)initWithFrame: (NSRect)contentRect
nkeynes@681
    85
{
nkeynes@681
    86
    if( [super initWithFrame: contentRect] != nil ) {
nkeynes@681
    87
        int i;
nkeynes@681
    88
        isGrabbed = NO;
nkeynes@681
    89
        for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
nkeynes@681
    90
            flagsMask[i] = 0;
nkeynes@681
    91
        }
nkeynes@681
    92
        return self;
nkeynes@681
    93
    }
nkeynes@681
    94
    return nil;
nkeynes@681
    95
}
nkeynes@839
    96
- (BOOL)requestGrab
nkeynes@780
    97
{
nkeynes@780
    98
    if( delegate && [delegate respondsToSelector: @selector(viewRequestedGrab:)] )
nkeynes@839
    99
        return [delegate performSelector: @selector(viewRequestedGrab:) withObject: self] != nil;
nkeynes@839
   100
    return NO;
nkeynes@780
   101
}
nkeynes@839
   102
- (BOOL)requestUngrab
nkeynes@780
   103
{
nkeynes@780
   104
    if( delegate && [delegate respondsToSelector: @selector(viewRequestedUngrab:)] )
nkeynes@839
   105
        return [delegate performSelector: @selector(viewRequestedUngrab:) withObject: self] != nil;
nkeynes@839
   106
    return NO;
nkeynes@780
   107
}
nkeynes@681
   108
- (BOOL)isOpaque
nkeynes@681
   109
{
nkeynes@736
   110
    return YES;
nkeynes@681
   111
}
nkeynes@681
   112
- (BOOL)acceptsFirstResponder
nkeynes@681
   113
{
nkeynes@736
   114
    return YES;
nkeynes@681
   115
}
nkeynes@681
   116
- (BOOL)isFlipped
nkeynes@681
   117
{
nkeynes@736
   118
    return YES;
nkeynes@681
   119
}
nkeynes@681
   120
//--------------------------------------------------------------------
nkeynes@681
   121
- (void)drawRect: (NSRect) rect
nkeynes@681
   122
{
nkeynes@681
   123
    NSSize size = [self frame].size;
nkeynes@681
   124
    if( video_width != size.width || video_height != size.height ) {
nkeynes@681
   125
        video_width = size.width;
nkeynes@681
   126
        video_height = size.height;
nkeynes@681
   127
        video_nsgl_update();
nkeynes@681
   128
    }
nkeynes@681
   129
    pvr2_redraw_display();
nkeynes@681
   130
}
nkeynes@681
   131
- (void)keyDown: (NSEvent *) event
nkeynes@681
   132
{
nkeynes@681
   133
    if( ![event isARepeat] ) {
nkeynes@681
   134
        input_event_keydown( NULL, [event keyCode]+1, 1 );
nkeynes@681
   135
    }
nkeynes@681
   136
}
nkeynes@681
   137
- (void)keyUp: (NSEvent *) event
nkeynes@681
   138
{
nkeynes@681
   139
    input_event_keyup( NULL, [event keyCode]+1, 1 );
nkeynes@681
   140
}
nkeynes@681
   141
- (void)flagsChanged: (NSEvent *) event
nkeynes@681
   142
{
nkeynes@681
   143
    int keycode = [event keyCode];
nkeynes@780
   144
    if( ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
nkeynes@780
   145
        [self requestUngrab];
nkeynes@681
   146
    }
nkeynes@736
   147
nkeynes@681
   148
    if( flagsMask[keycode] == 0 ) {
nkeynes@681
   149
        input_event_keydown( NULL, keycode+1, 1 );
nkeynes@681
   150
        flagsMask[keycode] = 1;
nkeynes@681
   151
    } else {
nkeynes@681
   152
        input_event_keyup( NULL, keycode+1, 1 );
nkeynes@681
   153
        flagsMask[keycode] = 0;
nkeynes@681
   154
    }
nkeynes@681
   155
}
nkeynes@850
   156
- (void)emitMouseDownEvent: (NSEvent *)event button: (int)button
nkeynes@839
   157
{
nkeynes@839
   158
    if( isGrabbed ) {
nkeynes@850
   159
        input_event_mousedown( button, 0, 0, FALSE );
nkeynes@839
   160
    } else {
nkeynes@839
   161
        NSPoint pt = [event locationInWindow];
nkeynes@854
   162
        int x = (int)pt.x;
nkeynes@854
   163
        int y = video_height - (int)pt.y;
nkeynes@854
   164
        gl_window_to_system_coords(&x,&y);
nkeynes@854
   165
        input_event_mousedown( button, x, y, TRUE ); 
nkeynes@850
   166
    }
nkeynes@850
   167
}
nkeynes@850
   168
- (void)emitMouseUpEvent: (NSEvent *)event button: (int)button
nkeynes@850
   169
{
nkeynes@850
   170
    if( isGrabbed ) {
nkeynes@850
   171
        input_event_mouseup( button, 0, 0, FALSE );
nkeynes@850
   172
    } else {
nkeynes@850
   173
        NSPoint pt = [event locationInWindow];
nkeynes@854
   174
        int x = (int)pt.x;
nkeynes@854
   175
        int y = video_height - (int)pt.y;
nkeynes@854
   176
        gl_window_to_system_coords(&x,&y);
nkeynes@854
   177
        input_event_mouseup( button, x, y, TRUE ); 
nkeynes@850
   178
    }
nkeynes@850
   179
}
nkeynes@850
   180
- (void)emitMouseMoveEvent: (NSEvent *)event
nkeynes@850
   181
{
nkeynes@850
   182
    if( isGrabbed ) {
nkeynes@850
   183
        input_event_mousemove( [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
nkeynes@850
   184
    } else {
nkeynes@850
   185
        NSPoint pt = [event locationInWindow];
nkeynes@854
   186
        int x = (int)pt.x;
nkeynes@854
   187
        int y = video_height - (int)pt.y;
nkeynes@854
   188
        gl_window_to_system_coords(&x,&y);
nkeynes@854
   189
        input_event_mousemove( x, y, TRUE ); 
nkeynes@850
   190
    }    
nkeynes@850
   191
}
nkeynes@850
   192
- (void)mouseExited: (NSEvent *)event
nkeynes@850
   193
{
nkeynes@850
   194
    if( !isGrabbed ) {
nkeynes@850
   195
        input_event_mousemove( -1, -1, TRUE );
nkeynes@839
   196
    }
nkeynes@839
   197
}
nkeynes@839
   198
nkeynes@681
   199
- (void)mouseDown: (NSEvent *) event
nkeynes@681
   200
{
nkeynes@839
   201
    // If using grab but not grabbed yet, the first click should be consumed
nkeynes@839
   202
    // by the grabber. In all other circumstances we process normally.
nkeynes@839
   203
    if( isGrabbed || ![self requestGrab] ) {
nkeynes@850
   204
        [self emitMouseDownEvent: event button: 0];
nkeynes@681
   205
    }
nkeynes@681
   206
}
nkeynes@681
   207
- (void)mouseUp: (NSEvent *)event
nkeynes@681
   208
{
nkeynes@850
   209
    [self emitMouseUpEvent: event button: 0];
nkeynes@681
   210
}
nkeynes@681
   211
nkeynes@681
   212
- (void)rightMouseDown: (NSEvent *) event
nkeynes@681
   213
{
nkeynes@850
   214
    [self emitMouseDownEvent: event button: 1];
nkeynes@681
   215
}
nkeynes@681
   216
- (void)rightMouseUp: (NSEvent *)event
nkeynes@681
   217
{
nkeynes@850
   218
    [self emitMouseUpEvent: event button: 1];
nkeynes@681
   219
}
nkeynes@681
   220
- (void)otherMouseDown: (NSEvent *) event
nkeynes@681
   221
{
nkeynes@850
   222
    [self emitMouseDownEvent: event button: [event buttonNumber]];
nkeynes@681
   223
}
nkeynes@681
   224
- (void)otherMouseUp: (NSEvent *) event
nkeynes@681
   225
{
nkeynes@850
   226
    [self emitMouseUpEvent: event button: [event buttonNumber]];
nkeynes@681
   227
}
nkeynes@681
   228
- (void)mouseMoved: (NSEvent *) event
nkeynes@681
   229
{
nkeynes@850
   230
    [self emitMouseMoveEvent: event];
nkeynes@681
   231
}
nkeynes@681
   232
- (void)mouseDragged: (NSEvent *) event
nkeynes@681
   233
{
nkeynes@850
   234
    [self emitMouseMoveEvent: event];
nkeynes@681
   235
}
nkeynes@681
   236
- (void)rightMouseDragged: (NSEvent *) event
nkeynes@681
   237
{
nkeynes@850
   238
    [self emitMouseMoveEvent: event];
nkeynes@681
   239
}
nkeynes@681
   240
- (void)otherMouseDragged: (NSEvent *) event
nkeynes@681
   241
{
nkeynes@850
   242
    [self emitMouseMoveEvent: event];
nkeynes@681
   243
}
nkeynes@681
   244
nkeynes@681
   245
@end
nkeynes@681
   246
nkeynes@681
   247
NSView *video_osx_create_drawable()
nkeynes@681
   248
{
nkeynes@681
   249
    NSRect contentRect = {{0,0},{640,480}};
nkeynes@780
   250
    video_view = [[LxdreamOSXView alloc] initWithFrame: contentRect];
nkeynes@681
   251
    [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
nkeynes@681
   252
    return video_view;
nkeynes@681
   253
}
nkeynes@681
   254
nkeynes@681
   255
static gboolean video_osx_init()
nkeynes@681
   256
{
nkeynes@736
   257
    if( video_view == NULL ) {
nkeynes@736
   258
        return FALSE;
nkeynes@736
   259
    }
nkeynes@736
   260
    if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
nkeynes@736
   261
        return FALSE;
nkeynes@736
   262
    }
nkeynes@736
   263
    pvr2_setup_gl_context();
nkeynes@736
   264
    return TRUE;
nkeynes@681
   265
}
nkeynes@681
   266
nkeynes@681
   267
static void video_osx_shutdown()
nkeynes@681
   268
{
nkeynes@681
   269
}
nkeynes@681
   270
nkeynes@681
   271
static void video_osx_display_blank( uint32_t colour )
nkeynes@681
   272
{
nkeynes@681
   273
}
nkeynes@681
   274
nkeynes@681
   275
static int mac_keymap_cmp(const void *a, const void *b)
nkeynes@681
   276
{
nkeynes@681
   277
    const gchar *key = a;
nkeynes@681
   278
    const struct mac_keymap_struct *kb = b;
nkeynes@681
   279
    return strcasecmp(key, kb->name);
nkeynes@681
   280
}
nkeynes@681
   281
nkeynes@681
   282
static uint16_t video_osx_resolve_keysym( const gchar *keysym )
nkeynes@681
   283
{
nkeynes@681
   284
    struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
nkeynes@681
   285
    if( result == NULL ) {
nkeynes@681
   286
        return 0;
nkeynes@681
   287
    } else {
nkeynes@681
   288
        return result->keycode + 1;
nkeynes@681
   289
    }
nkeynes@681
   290
}
nkeynes@681
   291
nkeynes@681
   292
static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
nkeynes@681
   293
{
nkeynes@681
   294
    if( keycode < 1 || keycode > 128 ) {
nkeynes@681
   295
        return DCKB_NONE;
nkeynes@681
   296
    } else {
nkeynes@681
   297
        return mac_keycode_to_dckeysym[keycode-1];
nkeynes@681
   298
    }
nkeynes@681
   299
}
nkeynes@681
   300
nkeynes@770
   301
static gchar *video_osx_keycode_to_keysym(uint16_t keycode)
nkeynes@770
   302
{
nkeynes@770
   303
    if( keycode < 1 || keycode > 128 ) {
nkeynes@770
   304
        return NULL;
nkeynes@770
   305
    } else {
nkeynes@770
   306
        return g_strdup(mac_keysyms_by_keycode[keycode-1]);
nkeynes@770
   307
    }
nkeynes@770
   308
}
.