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 1236:d93175c36387
prev1086:29776415438d
next1251:b8ab59d39756
author nkeynes
date Tue Feb 28 18:22:52 2012 +1000 (12 years ago)
permissions -rw-r--r--
last change Add a GL-only video driver for android usage (since the Java code is
responsible for creating the context)
file annotate diff log raw
nkeynes@964
     1
/**
nkeynes@964
     2
 * $Id$
nkeynes@964
     3
 *
nkeynes@964
     4
 * The OS/X side of the video support (responsible for actually displaying / 
nkeynes@964
     5
 * rendering frames)
nkeynes@964
     6
 *
nkeynes@964
     7
 * Copyright (c) 2008 Nathan Keynes.
nkeynes@964
     8
 *
nkeynes@964
     9
 * This program is free software; you can redistribute it and/or modify
nkeynes@964
    10
 * it under the terms of the GNU General Public License as published by
nkeynes@964
    11
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@964
    12
 * (at your option) any later version.
nkeynes@964
    13
 *
nkeynes@964
    14
 * This program is distributed in the hope that it will be useful,
nkeynes@964
    15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@964
    16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@964
    17
 * GNU General Public License for more details.
nkeynes@964
    18
 */
nkeynes@964
    19
nkeynes@964
    20
#include <stdlib.h>
nkeynes@964
    21
#include <string.h>
nkeynes@964
    22
#include "lxdream.h"
nkeynes@964
    23
#include "display.h"
nkeynes@964
    24
#include "dckeysyms.h"
nkeynes@964
    25
#include "cocoaui/cocoaui.h"
nkeynes@964
    26
#include "drivers/video_nsgl.h"
nkeynes@964
    27
#include "drivers/video_gl.h"
nkeynes@964
    28
#include "pvr2/pvr2.h"
nkeynes@964
    29
#import <AppKit/AppKit.h>
nkeynes@964
    30
nkeynes@1086
    31
#include "drivers/mac_keymap.h"
nkeynes@964
    32
nkeynes@964
    33
#define MOUSE_X_SCALE 5
nkeynes@964
    34
#define MOUSE_Y_SCALE 5
nkeynes@964
    35
nkeynes@964
    36
static gboolean video_osx_init();
nkeynes@964
    37
static void video_osx_shutdown();
nkeynes@964
    38
static void video_osx_display_blank( uint32_t colour );
nkeynes@964
    39
static uint16_t video_osx_resolve_keysym( const gchar *keysym );
nkeynes@964
    40
static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode);
nkeynes@964
    41
static gchar *video_osx_keycode_to_keysym(uint16_t keycode);
nkeynes@964
    42
nkeynes@964
    43
struct display_driver display_osx_driver = { 
nkeynes@964
    44
        "osx",
nkeynes@964
    45
        N_("OS X Cocoa GUI-based OpenGL driver"),
nkeynes@964
    46
        video_osx_init, video_osx_shutdown,
nkeynes@964
    47
        video_osx_resolve_keysym,
nkeynes@964
    48
        video_osx_keycode_to_dckeysym,
nkeynes@964
    49
        video_osx_keycode_to_keysym,
nkeynes@964
    50
        NULL, NULL, NULL, NULL, NULL,
nkeynes@964
    51
        NULL,
nkeynes@964
    52
        video_osx_display_blank, NULL };
nkeynes@964
    53
nkeynes@964
    54
nkeynes@964
    55
static NSView *video_view = NULL;
nkeynes@964
    56
nkeynes@964
    57
#define MAX_MASK_KEYCODE 128
nkeynes@964
    58
nkeynes@964
    59
@interface LxdreamOSXView : LxdreamVideoView
nkeynes@964
    60
{
nkeynes@964
    61
    int flagsMask[MAX_MASK_KEYCODE];
nkeynes@964
    62
}
nkeynes@964
    63
@end
nkeynes@964
    64
nkeynes@964
    65
@implementation LxdreamVideoView
nkeynes@964
    66
- (void)setIsGrabbed: (BOOL)grabbed
nkeynes@964
    67
{
nkeynes@964
    68
    isGrabbed = grabbed;
nkeynes@964
    69
}
nkeynes@964
    70
- (void) setDelegate: (id)other
nkeynes@964
    71
{
nkeynes@964
    72
    delegate = other;
nkeynes@964
    73
}
nkeynes@964
    74
- (id)delegate 
nkeynes@964
    75
{
nkeynes@964
    76
    return delegate;
nkeynes@964
    77
}
nkeynes@964
    78
@end
nkeynes@964
    79
nkeynes@964
    80
@implementation LxdreamOSXView
nkeynes@964
    81
//--------------------------------------------------------------------
nkeynes@964
    82
- (id)initWithFrame: (NSRect)contentRect
nkeynes@964
    83
{
nkeynes@964
    84
    if( [super initWithFrame: contentRect] != nil ) {
nkeynes@964
    85
        int i;
nkeynes@964
    86
        isGrabbed = NO;
nkeynes@964
    87
        for( i=0; i<MAX_MASK_KEYCODE; i++ ) {
nkeynes@964
    88
            flagsMask[i] = 0;
nkeynes@964
    89
        }
nkeynes@964
    90
        return self;
nkeynes@964
    91
    }
nkeynes@964
    92
    return nil;
nkeynes@964
    93
}
nkeynes@964
    94
- (BOOL)requestGrab
nkeynes@964
    95
{
nkeynes@964
    96
    if( delegate && [delegate respondsToSelector: @selector(viewRequestedGrab:)] )
nkeynes@964
    97
        return [delegate performSelector: @selector(viewRequestedGrab:) withObject: self] != nil;
nkeynes@964
    98
    return NO;
nkeynes@964
    99
}
nkeynes@964
   100
- (BOOL)requestUngrab
nkeynes@964
   101
{
nkeynes@964
   102
    if( delegate && [delegate respondsToSelector: @selector(viewRequestedUngrab:)] )
nkeynes@964
   103
        return [delegate performSelector: @selector(viewRequestedUngrab:) withObject: self] != nil;
nkeynes@964
   104
    return NO;
nkeynes@964
   105
}
nkeynes@964
   106
- (BOOL)isOpaque
nkeynes@964
   107
{
nkeynes@964
   108
    return YES;
nkeynes@964
   109
}
nkeynes@964
   110
- (BOOL)acceptsFirstResponder
nkeynes@964
   111
{
nkeynes@964
   112
    return YES;
nkeynes@964
   113
}
nkeynes@964
   114
- (BOOL)isFlipped
nkeynes@964
   115
{
nkeynes@964
   116
    return YES;
nkeynes@964
   117
}
nkeynes@964
   118
//--------------------------------------------------------------------
nkeynes@964
   119
- (void)drawRect: (NSRect) rect
nkeynes@964
   120
{
nkeynes@964
   121
    NSSize size = [self frame].size;
nkeynes@964
   122
    if( video_width != size.width || video_height != size.height ) {
nkeynes@1236
   123
        gl_set_video_size(size.width, size.height);
nkeynes@964
   124
        video_nsgl_update();
nkeynes@964
   125
    }
nkeynes@1076
   126
    pvr2_draw_frame();
nkeynes@964
   127
}
nkeynes@964
   128
- (void)keyDown: (NSEvent *) event
nkeynes@964
   129
{
nkeynes@964
   130
    if( ![event isARepeat] ) {
nkeynes@1010
   131
        input_event_keydown( NULL, [event keyCode]+1, MAX_PRESSURE );
nkeynes@964
   132
    }
nkeynes@964
   133
}
nkeynes@964
   134
- (void)keyUp: (NSEvent *) event
nkeynes@964
   135
{
nkeynes@1010
   136
    input_event_keyup( NULL, [event keyCode]+1 );
nkeynes@964
   137
}
nkeynes@964
   138
- (void)flagsChanged: (NSEvent *) event
nkeynes@964
   139
{
nkeynes@964
   140
    int keycode = [event keyCode];
nkeynes@964
   141
    if( ([event modifierFlags] & NSControlKeyMask) && ([event modifierFlags] & NSAlternateKeyMask) ) {
nkeynes@964
   142
        [self requestUngrab];
nkeynes@964
   143
    }
nkeynes@964
   144
nkeynes@964
   145
    if( flagsMask[keycode] == 0 ) {
nkeynes@1010
   146
        input_event_keydown( NULL, keycode+1, MAX_PRESSURE );
nkeynes@964
   147
        flagsMask[keycode] = 1;
nkeynes@964
   148
    } else {
nkeynes@1010
   149
        input_event_keyup( NULL, keycode+1 );
nkeynes@964
   150
        flagsMask[keycode] = 0;
nkeynes@964
   151
    }
nkeynes@964
   152
}
nkeynes@964
   153
- (void)emitMouseDownEvent: (NSEvent *)event button: (int)button
nkeynes@964
   154
{
nkeynes@964
   155
    if( isGrabbed ) {
nkeynes@964
   156
        input_event_mousedown( button, 0, 0, FALSE );
nkeynes@964
   157
    } else {
nkeynes@964
   158
        NSPoint pt = [event locationInWindow];
nkeynes@964
   159
        int x = (int)pt.x;
nkeynes@964
   160
        int y = video_height - (int)pt.y;
nkeynes@964
   161
        gl_window_to_system_coords(&x,&y);
nkeynes@964
   162
        input_event_mousedown( button, x, y, TRUE ); 
nkeynes@964
   163
    }
nkeynes@964
   164
}
nkeynes@964
   165
- (void)emitMouseUpEvent: (NSEvent *)event button: (int)button
nkeynes@964
   166
{
nkeynes@964
   167
    if( isGrabbed ) {
nkeynes@964
   168
        input_event_mouseup( button, 0, 0, FALSE );
nkeynes@964
   169
    } else {
nkeynes@964
   170
        NSPoint pt = [event locationInWindow];
nkeynes@964
   171
        int x = (int)pt.x;
nkeynes@964
   172
        int y = video_height - (int)pt.y;
nkeynes@964
   173
        gl_window_to_system_coords(&x,&y);
nkeynes@964
   174
        input_event_mouseup( button, x, y, TRUE ); 
nkeynes@964
   175
    }
nkeynes@964
   176
}
nkeynes@964
   177
- (void)emitMouseMoveEvent: (NSEvent *)event
nkeynes@964
   178
{
nkeynes@964
   179
    if( isGrabbed ) {
nkeynes@964
   180
        input_event_mousemove( [event deltaX] * MOUSE_X_SCALE, [event deltaY] * MOUSE_Y_SCALE, FALSE );
nkeynes@964
   181
    } else {
nkeynes@964
   182
        NSPoint pt = [event locationInWindow];
nkeynes@964
   183
        int x = (int)pt.x;
nkeynes@964
   184
        int y = video_height - (int)pt.y;
nkeynes@964
   185
        gl_window_to_system_coords(&x,&y);
nkeynes@964
   186
        input_event_mousemove( x, y, TRUE ); 
nkeynes@964
   187
    }    
nkeynes@964
   188
}
nkeynes@964
   189
- (void)mouseExited: (NSEvent *)event
nkeynes@964
   190
{
nkeynes@964
   191
    if( !isGrabbed ) {
nkeynes@964
   192
        input_event_mousemove( -1, -1, TRUE );
nkeynes@964
   193
    }
nkeynes@964
   194
}
nkeynes@964
   195
nkeynes@964
   196
- (void)mouseDown: (NSEvent *) event
nkeynes@964
   197
{
nkeynes@964
   198
    // If using grab but not grabbed yet, the first click should be consumed
nkeynes@964
   199
    // by the grabber. In all other circumstances we process normally.
nkeynes@964
   200
    if( isGrabbed || ![self requestGrab] ) {
nkeynes@964
   201
        [self emitMouseDownEvent: event button: 0];
nkeynes@964
   202
    }
nkeynes@964
   203
}
nkeynes@964
   204
- (void)mouseUp: (NSEvent *)event
nkeynes@964
   205
{
nkeynes@964
   206
    [self emitMouseUpEvent: event button: 0];
nkeynes@964
   207
}
nkeynes@964
   208
nkeynes@964
   209
- (void)rightMouseDown: (NSEvent *) event
nkeynes@964
   210
{
nkeynes@964
   211
    [self emitMouseDownEvent: event button: 1];
nkeynes@964
   212
}
nkeynes@964
   213
- (void)rightMouseUp: (NSEvent *)event
nkeynes@964
   214
{
nkeynes@964
   215
    [self emitMouseUpEvent: event button: 1];
nkeynes@964
   216
}
nkeynes@964
   217
- (void)otherMouseDown: (NSEvent *) event
nkeynes@964
   218
{
nkeynes@964
   219
    [self emitMouseDownEvent: event button: [event buttonNumber]];
nkeynes@964
   220
}
nkeynes@964
   221
- (void)otherMouseUp: (NSEvent *) event
nkeynes@964
   222
{
nkeynes@964
   223
    [self emitMouseUpEvent: event button: [event buttonNumber]];
nkeynes@964
   224
}
nkeynes@964
   225
- (void)mouseMoved: (NSEvent *) event
nkeynes@964
   226
{
nkeynes@964
   227
    [self emitMouseMoveEvent: event];
nkeynes@964
   228
}
nkeynes@964
   229
- (void)mouseDragged: (NSEvent *) event
nkeynes@964
   230
{
nkeynes@964
   231
    [self emitMouseMoveEvent: event];
nkeynes@964
   232
}
nkeynes@964
   233
- (void)rightMouseDragged: (NSEvent *) event
nkeynes@964
   234
{
nkeynes@964
   235
    [self emitMouseMoveEvent: event];
nkeynes@964
   236
}
nkeynes@964
   237
- (void)otherMouseDragged: (NSEvent *) event
nkeynes@964
   238
{
nkeynes@964
   239
    [self emitMouseMoveEvent: event];
nkeynes@964
   240
}
nkeynes@964
   241
nkeynes@964
   242
@end
nkeynes@964
   243
nkeynes@964
   244
NSView *video_osx_create_drawable()
nkeynes@964
   245
{
nkeynes@964
   246
    NSRect contentRect = {{0,0},{640,480}};
nkeynes@964
   247
    video_view = [[LxdreamOSXView alloc] initWithFrame: contentRect];
nkeynes@964
   248
    [video_view setAutoresizingMask: (NSViewWidthSizable|NSViewHeightSizable)];
nkeynes@964
   249
    return video_view;
nkeynes@964
   250
}
nkeynes@964
   251
nkeynes@964
   252
static gboolean video_osx_init()
nkeynes@964
   253
{
nkeynes@964
   254
    if( video_view == NULL ) {
nkeynes@964
   255
        return FALSE;
nkeynes@964
   256
    }
nkeynes@964
   257
    if( !video_nsgl_init_driver(video_view, &display_osx_driver) ) {
nkeynes@964
   258
        return FALSE;
nkeynes@964
   259
    }
nkeynes@964
   260
    pvr2_setup_gl_context();
nkeynes@964
   261
    return TRUE;
nkeynes@964
   262
}
nkeynes@964
   263
nkeynes@964
   264
static void video_osx_shutdown()
nkeynes@964
   265
{
nkeynes@964
   266
}
nkeynes@964
   267
nkeynes@964
   268
static void video_osx_display_blank( uint32_t colour )
nkeynes@964
   269
{
nkeynes@964
   270
}
nkeynes@964
   271
nkeynes@964
   272
static int mac_keymap_cmp(const void *a, const void *b)
nkeynes@964
   273
{
nkeynes@964
   274
    const gchar *key = a;
nkeynes@964
   275
    const struct mac_keymap_struct *kb = b;
nkeynes@964
   276
    return strcasecmp(key, kb->name);
nkeynes@964
   277
}
nkeynes@964
   278
nkeynes@964
   279
static uint16_t video_osx_resolve_keysym( const gchar *keysym )
nkeynes@964
   280
{
nkeynes@964
   281
    struct mac_keymap_struct *result = bsearch( keysym, mac_keysyms, mac_keysym_count, sizeof(struct mac_keymap_struct), mac_keymap_cmp );
nkeynes@964
   282
    if( result == NULL ) {
nkeynes@964
   283
        return 0;
nkeynes@964
   284
    } else {
nkeynes@964
   285
        return result->keycode + 1;
nkeynes@964
   286
    }
nkeynes@964
   287
}
nkeynes@964
   288
nkeynes@964
   289
static uint16_t video_osx_keycode_to_dckeysym(uint16_t keycode)
nkeynes@964
   290
{
nkeynes@964
   291
    if( keycode < 1 || keycode > 128 ) {
nkeynes@964
   292
        return DCKB_NONE;
nkeynes@964
   293
    } else {
nkeynes@964
   294
        return mac_keycode_to_dckeysym[keycode-1];
nkeynes@964
   295
    }
nkeynes@964
   296
}
nkeynes@964
   297
nkeynes@964
   298
static gchar *video_osx_keycode_to_keysym(uint16_t keycode)
nkeynes@964
   299
{
nkeynes@964
   300
    if( keycode < 1 || keycode > 128 ) {
nkeynes@964
   301
        return NULL;
nkeynes@964
   302
    } else {
nkeynes@964
   303
        return g_strdup(mac_keysyms_by_keycode[keycode-1]);
nkeynes@964
   304
    }
nkeynes@964
   305
}
.