src/video/quartz/SDL_QuartzEvents.m
author Sam Lantinga <slouken@libsdl.org>
Sat, 01 Jun 2002 23:05:05 +0000
changeset 390 19e73568a75c
parent 389 ca655a7a9d80
child 435 140798e1e7a6
permissions -rw-r--r--
Date: Sat, 1 Jun 2002 17:56:45 -0500
From: Darrell Walisser <dwaliss1@purdue.edu>
Subject: mac patch

In this patch:

- yuv code
- links to QuickTime
- tabs -> 4 spaces
- mouse events fix
- SDLMain path parsing fix
- BUGS updates
- some miscellaneous docs/comments/code cleanup
slouken@47
     1
/*
slouken@390
     2
    SDL - Simple DirectMedia Layer
slouken@390
     3
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002    Sam Lantinga
slouken@47
     4
slouken@390
     5
    This library is free software; you can redistribute it and/or
slouken@390
     6
    modify it under the terms of the GNU Library General Public
slouken@390
     7
    License as published by the Free Software Foundation; either
slouken@390
     8
    version 2 of the License, or (at your option) any later version.
slouken@47
     9
slouken@390
    10
    This library is distributed in the hope that it will be useful,
slouken@390
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@390
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@390
    13
    Library General Public License for more details.
slouken@47
    14
slouken@390
    15
    You should have received a copy of the GNU Library General Public
slouken@390
    16
    License along with this library; if not, write to the Free
slouken@390
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
slouken@47
    18
slouken@390
    19
    Sam Lantinga
slouken@390
    20
    slouken@libsdl.org
slouken@47
    21
*/
slouken@272
    22
#include <sys/time.h>
slouken@47
    23
slouken@47
    24
#include "SDL_QuartzKeys.h"
slouken@47
    25
slouken@172
    26
static SDLKey keymap[256];
slouken@172
    27
static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */
slouken@172
    28
static int last_virtual_button = 0; /* Last virtual mouse button pressed */
slouken@155
    29
slouken@390
    30
static void     QZ_InitOSKeymap (_THIS) {
slouken@390
    31
    const void *KCHRPtr;
slouken@390
    32
    UInt32 state;
slouken@390
    33
    UInt32 value;
slouken@390
    34
    int i;
slouken@390
    35
    int world = SDLK_WORLD_0;
slouken@47
    36
slouken@390
    37
    for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
slouken@390
    38
        keymap[i] = SDLK_UNKNOWN;
slouken@390
    39
slouken@390
    40
    /* This keymap is almost exactly the same as the OS 9 one */
slouken@390
    41
    keymap[QZ_ESCAPE] = SDLK_ESCAPE;
slouken@390
    42
    keymap[QZ_F1] = SDLK_F1;
slouken@390
    43
    keymap[QZ_F2] = SDLK_F2;
slouken@390
    44
    keymap[QZ_F3] = SDLK_F3;
slouken@390
    45
    keymap[QZ_F4] = SDLK_F4;
slouken@390
    46
    keymap[QZ_F5] = SDLK_F5;
slouken@390
    47
    keymap[QZ_F6] = SDLK_F6;
slouken@390
    48
    keymap[QZ_F7] = SDLK_F7;
slouken@390
    49
    keymap[QZ_F8] = SDLK_F8;
slouken@390
    50
    keymap[QZ_F9] = SDLK_F9;
slouken@390
    51
    keymap[QZ_F10] = SDLK_F10;
slouken@390
    52
    keymap[QZ_F11] = SDLK_F11;
slouken@390
    53
    keymap[QZ_F12] = SDLK_F12;
slouken@390
    54
    keymap[QZ_PRINT] = SDLK_PRINT;
slouken@390
    55
    keymap[QZ_SCROLLOCK] = SDLK_SCROLLOCK;
slouken@390
    56
    keymap[QZ_PAUSE] = SDLK_PAUSE;
slouken@390
    57
    keymap[QZ_POWER] = SDLK_POWER;
slouken@390
    58
    keymap[QZ_BACKQUOTE] = SDLK_BACKQUOTE;
slouken@390
    59
    keymap[QZ_1] = SDLK_1;
slouken@390
    60
    keymap[QZ_2] = SDLK_2;
slouken@390
    61
    keymap[QZ_3] = SDLK_3;
slouken@390
    62
    keymap[QZ_4] = SDLK_4;
slouken@390
    63
    keymap[QZ_5] = SDLK_5;
slouken@390
    64
    keymap[QZ_6] = SDLK_6;
slouken@390
    65
    keymap[QZ_7] = SDLK_7;
slouken@390
    66
    keymap[QZ_8] = SDLK_8;
slouken@390
    67
    keymap[QZ_9] = SDLK_9;
slouken@390
    68
    keymap[QZ_0] = SDLK_0;
slouken@390
    69
    keymap[QZ_MINUS] = SDLK_MINUS;
slouken@390
    70
    keymap[QZ_EQUALS] = SDLK_EQUALS;
slouken@390
    71
    keymap[QZ_BACKSPACE] = SDLK_BACKSPACE;
slouken@390
    72
    keymap[QZ_INSERT] = SDLK_INSERT;
slouken@390
    73
    keymap[QZ_HOME] = SDLK_HOME;
slouken@390
    74
    keymap[QZ_PAGEUP] = SDLK_PAGEUP;
slouken@390
    75
    keymap[QZ_NUMLOCK] = SDLK_NUMLOCK;
slouken@390
    76
    keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
slouken@390
    77
    keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
slouken@390
    78
    keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
slouken@390
    79
    keymap[QZ_TAB] = SDLK_TAB;
slouken@390
    80
    keymap[QZ_q] = SDLK_q;
slouken@390
    81
    keymap[QZ_w] = SDLK_w;
slouken@390
    82
    keymap[QZ_e] = SDLK_e;
slouken@390
    83
    keymap[QZ_r] = SDLK_r;
slouken@390
    84
    keymap[QZ_t] = SDLK_t;
slouken@390
    85
    keymap[QZ_y] = SDLK_y;
slouken@390
    86
    keymap[QZ_u] = SDLK_u;
slouken@390
    87
    keymap[QZ_i] = SDLK_i;
slouken@390
    88
    keymap[QZ_o] = SDLK_o;
slouken@390
    89
    keymap[QZ_p] = SDLK_p;
slouken@390
    90
    keymap[QZ_LEFTBRACKET] = SDLK_LEFTBRACKET;
slouken@390
    91
    keymap[QZ_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
slouken@390
    92
    keymap[QZ_BACKSLASH] = SDLK_BACKSLASH;
slouken@390
    93
    keymap[QZ_DELETE] = SDLK_DELETE;
slouken@390
    94
    keymap[QZ_END] = SDLK_END;
slouken@390
    95
    keymap[QZ_PAGEDOWN] = SDLK_PAGEDOWN;
slouken@390
    96
    keymap[QZ_KP7] = SDLK_KP7;
slouken@390
    97
    keymap[QZ_KP8] = SDLK_KP8;
slouken@390
    98
    keymap[QZ_KP9] = SDLK_KP9;
slouken@390
    99
    keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
slouken@390
   100
    keymap[QZ_CAPSLOCK] = SDLK_CAPSLOCK;
slouken@390
   101
    keymap[QZ_a] = SDLK_a;
slouken@390
   102
    keymap[QZ_s] = SDLK_s;
slouken@390
   103
    keymap[QZ_d] = SDLK_d;
slouken@390
   104
    keymap[QZ_f] = SDLK_f;
slouken@390
   105
    keymap[QZ_g] = SDLK_g;
slouken@390
   106
    keymap[QZ_h] = SDLK_h;
slouken@390
   107
    keymap[QZ_j] = SDLK_j;
slouken@390
   108
    keymap[QZ_k] = SDLK_k;
slouken@390
   109
    keymap[QZ_l] = SDLK_l;
slouken@390
   110
    keymap[QZ_SEMICOLON] = SDLK_SEMICOLON;
slouken@390
   111
    keymap[QZ_QUOTE] = SDLK_QUOTE;
slouken@390
   112
    keymap[QZ_RETURN] = SDLK_RETURN;
slouken@390
   113
    keymap[QZ_KP4] = SDLK_KP4;
slouken@390
   114
    keymap[QZ_KP5] = SDLK_KP5;
slouken@390
   115
    keymap[QZ_KP6] = SDLK_KP6;
slouken@390
   116
    keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
slouken@390
   117
    keymap[QZ_LSHIFT] = SDLK_LSHIFT;
slouken@390
   118
    keymap[QZ_z] = SDLK_z;
slouken@390
   119
    keymap[QZ_x] = SDLK_x;
slouken@390
   120
    keymap[QZ_c] = SDLK_c;
slouken@390
   121
    keymap[QZ_v] = SDLK_v;
slouken@390
   122
    keymap[QZ_b] = SDLK_b;
slouken@390
   123
    keymap[QZ_n] = SDLK_n;
slouken@390
   124
    keymap[QZ_m] = SDLK_m;
slouken@390
   125
    keymap[QZ_COMMA] = SDLK_COMMA;
slouken@390
   126
    keymap[QZ_PERIOD] = SDLK_PERIOD;
slouken@390
   127
    keymap[QZ_SLASH] = SDLK_SLASH;
slouken@390
   128
    keymap[QZ_UP] = SDLK_UP;
slouken@390
   129
    keymap[QZ_KP1] = SDLK_KP1;
slouken@390
   130
    keymap[QZ_KP2] = SDLK_KP2;
slouken@390
   131
    keymap[QZ_KP3] = SDLK_KP3;
slouken@390
   132
    keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
slouken@390
   133
    keymap[QZ_LCTRL] = SDLK_LCTRL;
slouken@390
   134
    keymap[QZ_LALT] = SDLK_LALT;
slouken@390
   135
    keymap[QZ_LMETA] = SDLK_LMETA;
slouken@390
   136
    keymap[QZ_SPACE] = SDLK_SPACE;
slouken@390
   137
    keymap[QZ_LEFT] = SDLK_LEFT;
slouken@390
   138
    keymap[QZ_DOWN] = SDLK_DOWN;
slouken@390
   139
    keymap[QZ_RIGHT] = SDLK_RIGHT;
slouken@390
   140
    keymap[QZ_KP0] = SDLK_KP0;
slouken@390
   141
    keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
slouken@390
   142
    keymap[QZ_IBOOK_ENTER] = SDLK_KP_ENTER;
slouken@390
   143
    keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT;
slouken@390
   144
    keymap[QZ_IBOOK_DOWN] = SDLK_DOWN;
slouken@390
   145
    keymap[QZ_IBOOK_UP]      = SDLK_UP;
slouken@390
   146
    keymap[QZ_IBOOK_LEFT] = SDLK_LEFT;
slouken@390
   147
slouken@390
   148
    /* Up there we setup a static scancode->keysym map. However, it will not
slouken@390
   149
     * work very well on international keyboard. Hence we now query MacOS
slouken@390
   150
     * for its own keymap to adjust our own mapping table. However, this is
slouken@390
   151
     * bascially only useful for ascii char keys. This is also the reason
slouken@390
   152
     * why we keep the static table, too.
slouken@390
   153
     */
slouken@390
   154
slouken@390
   155
    /* Get a pointer to the systems cached KCHR */
slouken@390
   156
    KCHRPtr = (void *)GetScriptManagerVariable(smKCHRCache);
slouken@390
   157
    if (KCHRPtr)
slouken@390
   158
    {
slouken@390
   159
        /* Loop over all 127 possible scan codes */
slouken@390
   160
        for (i = 0; i < 0x7F; i++)
slouken@390
   161
        {
slouken@390
   162
            /* We pretend a clean start to begin with (i.e. no dead keys active */
slouken@390
   163
            state = 0;
slouken@390
   164
slouken@390
   165
            /* Now translate the key code to a key value */
slouken@390
   166
            value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
slouken@390
   167
slouken@390
   168
            /* If the state become 0, it was a dead key. We need to translate again,
slouken@390
   169
                passing in the new state, to get the actual key value */
slouken@390
   170
            if (state != 0)
slouken@390
   171
                value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
slouken@390
   172
slouken@390
   173
            /* Now we should have an ascii value, or 0. Try to figure out to which SDL symbol it maps */
slouken@390
   174
            if (value >= 128)     /* Some non-ASCII char, map it to SDLK_WORLD_* */
slouken@390
   175
                keymap[i] = world++;
slouken@390
   176
            else if (value >= 32)     /* non-control ASCII char */
slouken@390
   177
                keymap[i] = value;
slouken@390
   178
        }
slouken@390
   179
    }
slouken@390
   180
slouken@390
   181
    /* The keypad codes are re-setup here, because the loop above cannot
slouken@390
   182
     * distinguish between a key on the keypad and a regular key. We maybe
slouken@390
   183
     * could get around this problem in another fashion: NSEvent's flags
slouken@390
   184
     * include a "NSNumericPadKeyMask" bit; we could check that and modify
slouken@390
   185
     * the symbol we return on the fly. However, this flag seems to exhibit
slouken@390
   186
     * some weird behaviour related to the num lock key
slouken@390
   187
     */
slouken@390
   188
    keymap[QZ_KP0] = SDLK_KP0;
slouken@390
   189
    keymap[QZ_KP1] = SDLK_KP1;
slouken@390
   190
    keymap[QZ_KP2] = SDLK_KP2;
slouken@390
   191
    keymap[QZ_KP3] = SDLK_KP3;
slouken@390
   192
    keymap[QZ_KP4] = SDLK_KP4;
slouken@390
   193
    keymap[QZ_KP5] = SDLK_KP5;
slouken@390
   194
    keymap[QZ_KP6] = SDLK_KP6;
slouken@390
   195
    keymap[QZ_KP7] = SDLK_KP7;
slouken@390
   196
    keymap[QZ_KP8] = SDLK_KP8;
slouken@390
   197
    keymap[QZ_KP9] = SDLK_KP9;
slouken@390
   198
    keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
slouken@390
   199
    keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
slouken@390
   200
    keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
slouken@390
   201
    keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
slouken@390
   202
    keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
slouken@390
   203
    keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
slouken@390
   204
    keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
slouken@47
   205
}
slouken@47
   206
slouken@47
   207
static void QZ_DoKey (int state, NSEvent *event) {
slouken@47
   208
slouken@390
   209
    NSString *chars;
slouken@390
   210
    int i;
slouken@390
   211
    SDL_keysym key;
slouken@390
   212
slouken@390
   213
    /* An event can contain multiple characters */
slouken@390
   214
    /* I'll ignore this fact for now, since there is only one virtual key code per event */
slouken@390
   215
    chars = [ event characters ];
slouken@390
   216
    for (i =0; i < 1 /*[ chars length ] */; i++) {
slouken@390
   217
slouken@390
   218
        key.scancode = [ event keyCode ];
slouken@390
   219
        key.sym         = keymap [ key.scancode ];
slouken@390
   220
        key.unicode     = [ chars characterAtIndex:i];
slouken@390
   221
        key.mod         = KMOD_NONE;
slouken@390
   222
slouken@390
   223
        SDL_PrivateKeyboard (state, &key);
slouken@390
   224
    }
slouken@47
   225
}
slouken@47
   226
slouken@47
   227
static void QZ_DoModifiers (unsigned int newMods) {
slouken@47
   228
slouken@390
   229
    const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA } ;
slouken@47
   230
slouken@390
   231
    int i;
slouken@390
   232
    int bit;
slouken@390
   233
    SDL_keysym key;
slouken@47
   234
slouken@390
   235
    key.scancode = 0;
slouken@390
   236
    key.sym         = SDLK_UNKNOWN;
slouken@390
   237
    key.unicode     = 0;
slouken@390
   238
    key.mod         = KMOD_NONE;
slouken@172
   239
slouken@390
   240
    /* Iterate through the bits, testing each against the current modifiers */
slouken@390
   241
    for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
slouken@390
   242
slouken@390
   243
        unsigned int currentMask, newMask;
slouken@390
   244
slouken@390
   245
        currentMask = currentMods & bit;
slouken@390
   246
        newMask        = newMods & bit;
slouken@390
   247
slouken@390
   248
        if ( currentMask &&
slouken@390
   249
             currentMask != newMask ) {     /* modifier up event */
slouken@390
   250
slouken@390
   251
             key.sym = mapping[i];
slouken@390
   252
             /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
slouken@390
   253
             if (bit == NSAlphaShiftKeyMask)
slouken@390
   254
             SDL_PrivateKeyboard (SDL_PRESSED, &key);
slouken@390
   255
             SDL_PrivateKeyboard (SDL_RELEASED, &key);
slouken@390
   256
        }
slouken@390
   257
        else if ( newMask &&
slouken@390
   258
                  currentMask != newMask ) {     /* modifier down event */
slouken@390
   259
        
slouken@390
   260
             key.sym = mapping[i];
slouken@390
   261
             SDL_PrivateKeyboard (SDL_PRESSED, &key);
slouken@390
   262
             /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
slouken@390
   263
             if (bit == NSAlphaShiftKeyMask)
slouken@390
   264
                  SDL_PrivateKeyboard (SDL_RELEASED, &key);
slouken@390
   265
        }
slouken@390
   266
    }
slouken@390
   267
slouken@390
   268
    currentMods = newMods;
slouken@47
   269
}
slouken@47
   270
slouken@117
   271
static void QZ_DoActivate (_THIS)
slouken@117
   272
{
slouken@390
   273
    inForeground = YES;
slouken@47
   274
slouken@390
   275
    /* Regrab the mouse */
slouken@390
   276
    if (currentGrabMode == SDL_GRAB_ON) {
slouken@390
   277
        QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
slouken@390
   278
        CGAssociateMouseAndMouseCursorPosition (0);
slouken@390
   279
    }
slouken@168
   280
slouken@390
   281
    /* Hide the mouse cursor if inside the app window */
slouken@390
   282
    if (!QZ_cursor_visible) {
slouken@390
   283
        HideCursor ();
slouken@390
   284
    }
slouken@390
   285
slouken@390
   286
    SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS);
slouken@47
   287
}
slouken@47
   288
slouken@47
   289
static void QZ_DoDeactivate (_THIS) {
slouken@47
   290
slouken@390
   291
    inForeground = NO;
slouken@168
   292
slouken@390
   293
    /* Ungrab mouse if it is grabbed */
slouken@390
   294
    if (currentGrabMode == SDL_GRAB_ON) {
slouken@390
   295
        CGAssociateMouseAndMouseCursorPosition (1);
slouken@390
   296
    }
slouken@390
   297
slouken@390
   298
    /* Show the mouse cursor */
slouken@390
   299
    if (!QZ_cursor_visible) {
slouken@390
   300
        ShowCursor ();
slouken@390
   301
    }
slouken@390
   302
slouken@390
   303
    SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS);
slouken@47
   304
}
slouken@47
   305
slouken@117
   306
static void QZ_PumpEvents (_THIS)
slouken@158
   307
{
slouken@390
   308
    static NSPoint lastMouse;
slouken@390
   309
    NSPoint mouse, saveMouse;
slouken@390
   310
    Point qdMouse;
slouken@390
   311
    CGMouseDelta dx, dy;
slouken@390
   312
slouken@390
   313
    NSDate *distantPast;
slouken@390
   314
    NSEvent *event;
slouken@390
   315
    NSRect winRect;
slouken@390
   316
    NSRect titleBarRect;
slouken@390
   317
    NSAutoreleasePool *pool;
slouken@390
   318
slouken@390
   319
    pool = [ [ NSAutoreleasePool alloc ] init ];
slouken@390
   320
    distantPast = [ NSDate distantPast ];
slouken@390
   321
slouken@390
   322
    winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
slouken@390
   323
    titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w,
slouken@390
   324
                                SDL_VideoSurface->h + 22 );
slouken@390
   325
slouken@390
   326
    if (currentGrabMode != SDL_GRAB_ON) { /* if grabbed, the cursor can't move! (see fallback below) */
slouken@390
   327
slouken@390
   328
        /* 1/2 second after a warp, the mouse cannot move (don't ask me why) */
slouken@390
   329
        /* So, approximate motion with CGGetLastMouseDelta, which still works, somehow */
slouken@390
   330
        if (! warp_flag) {
slouken@390
   331
slouken@390
   332
            GetGlobalMouse (&qdMouse);  /* use Carbon since [ NSEvent mouseLocation ] is broken */
slouken@390
   333
            mouse = NSMakePoint (qdMouse.h, qdMouse.v);
slouken@390
   334
            saveMouse = mouse;
slouken@390
   335
slouken@390
   336
            if (mouse.x != lastMouse.x || mouse.y != lastMouse.y) {
slouken@390
   337
slouken@390
   338
                QZ_PrivateCGToSDL (this, &mouse);
slouken@390
   339
                /* -note- we now generate mouse motion events if the mouse isn't over the window */
slouken@390
   340
                if (inForeground /* && NSPointInRect (mouse, winRect)*/) {
slouken@390
   341
                    //printf ("Mouse Loc: (%f, %f)\n", mouse.x, mouse.y);
slouken@390
   342
                    SDL_PrivateMouseMotion (0, 0, mouse.x, mouse.y);
slouken@390
   343
                }
slouken@390
   344
            }
slouken@390
   345
            lastMouse = saveMouse;
slouken@390
   346
        }
slouken@390
   347
    }
slouken@390
   348
slouken@390
   349
    /* accumulate any mouse events into one SDL mouse event */
slouken@390
   350
    dx = 0;
slouken@390
   351
    dy = 0;
slouken@390
   352
    
slouken@390
   353
    do {
slouken@390
   354
    
slouken@390
   355
        /* Poll for an event. This will not block */
slouken@390
   356
        event = [ NSApp nextEventMatchingMask:NSAnyEventMask
slouken@390
   357
                                    untilDate:distantPast
slouken@390
   358
                                    inMode: NSDefaultRunLoopMode dequeue:YES ];
slouken@390
   359
    
slouken@390
   360
        if (event != nil) {
slouken@390
   361
slouken@390
   362
            unsigned int type;
slouken@390
   363
            BOOL isForGameWin;
slouken@390
   364
    
slouken@390
   365
            #define DO_MOUSE_DOWN(button, sendToWindow) do {                                 \
slouken@390
   366
                            if ( inForeground ) {                                            \
slouken@390
   367
                                if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) ||           \
slouken@390
   368
                                    NSPointInRect([event locationInWindow], winRect) )       \
slouken@390
   369
                                        SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0);  \
slouken@390
   370
                            }                                                                \
slouken@390
   371
                            else {                                                           \
slouken@390
   372
                                QZ_DoActivate (this);                                        \
slouken@390
   373
                            }                                                                \
slouken@390
   374
                            [ NSApp sendEvent:event ];                                       \
slouken@390
   375
            } while(0)
slouken@272
   376
            
slouken@390
   377
            #define DO_MOUSE_UP(button, sendToWindow) do {                      \
slouken@390
   378
                            if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) ||  \
slouken@390
   379
                    !NSPointInRect([event locationInWindow], titleBarRect) )    \
slouken@390
   380
                        SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0);    \
slouken@390
   381
                            [ NSApp sendEvent:event ];                          \
slouken@390
   382
            } while(0)
slouken@390
   383
            
slouken@390
   384
            type = [ event type ];
slouken@390
   385
            isForGameWin = (qz_window == [ event window ]);
slouken@390
   386
            switch (type) {
slouken@390
   387
            
slouken@390
   388
                case NSLeftMouseDown:
slouken@390
   389
                    if ( NSCommandKeyMask & currentMods ) {
slouken@390
   390
                        last_virtual_button = 3;
slouken@390
   391
                        DO_MOUSE_DOWN (3, 0);
slouken@390
   392
                    }
slouken@390
   393
                    else if ( NSAlternateKeyMask & currentMods ) {
slouken@390
   394
                        last_virtual_button = 2;
slouken@390
   395
                        DO_MOUSE_DOWN (2, 0);
slouken@390
   396
                    }
slouken@390
   397
                    else {
slouken@390
   398
                        DO_MOUSE_DOWN (1, 1);
slouken@390
   399
                    }
slouken@390
   400
                    break;
slouken@390
   401
                case NSOtherMouseDown: DO_MOUSE_DOWN (2, 0); break;
slouken@390
   402
                case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;
slouken@390
   403
                case NSLeftMouseUp:
slouken@390
   404
                    if ( last_virtual_button != 0 ) {
slouken@390
   405
                        DO_MOUSE_UP (last_virtual_button, 0);
slouken@390
   406
                        last_virtual_button = 0;
slouken@390
   407
                    }
slouken@390
   408
                    else {
slouken@390
   409
                        DO_MOUSE_UP (1, 1);
slouken@390
   410
                    }
slouken@390
   411
                    break;
slouken@390
   412
                case NSOtherMouseUp:   DO_MOUSE_UP (2, 0);     break;
slouken@390
   413
                case NSRightMouseUp:   DO_MOUSE_UP (3, 0);     break;
slouken@390
   414
                case NSSystemDefined:
slouken@390
   415
                    //if ([event subtype] == 7) {
slouken@390
   416
                    //      unsigned int buttons;      // up to 32 mouse button states!
slouken@390
   417
                    //      buttons = [ event data2 ];
slouken@390
   418
                    //}
slouken@390
   419
                    break;
slouken@390
   420
                case NSLeftMouseDragged:
slouken@390
   421
                case NSRightMouseDragged:
slouken@390
   422
                case 27:
slouken@390
   423
                case NSMouseMoved:
slouken@390
   424
                    if (currentGrabMode == SDL_GRAB_ON) {
slouken@272
   425
                
slouken@390
   426
                        /**
slouken@390
   427
                         *  If input is grabbed, we'll wing it and try to send some mouse
slouken@390
   428
                         *  moved events with CGGetLastMouseDelta(). Not optimal, but better
slouken@390
   429
                         *  than nothing.
slouken@390
   430
                         **/
slouken@390
   431
                        CGMouseDelta dx1, dy1;
slouken@390
   432
                        CGGetLastMouseDelta (&dx1, &dy1);
slouken@390
   433
                        dx += dx1;
slouken@390
   434
                        dy += dy1;
slouken@390
   435
                    }
slouken@390
   436
                    else if (warp_flag) {
slouken@272
   437
                
slouken@390
   438
                        Uint32 ticks;
slouken@390
   439
                
slouken@390
   440
                        ticks = SDL_GetTicks();
slouken@390
   441
                        if (ticks - warp_ticks < 150) {
slouken@390
   442
                
slouken@390
   443
                            CGMouseDelta dx1, dy1;
slouken@390
   444
                            CGGetLastMouseDelta (&dx1, &dy1);
slouken@390
   445
                            dx += dx1;
slouken@390
   446
                            dy += dy1;
slouken@390
   447
                        }
slouken@390
   448
                        else {
slouken@390
   449
                
slouken@390
   450
                            warp_flag = 0;
slouken@390
   451
                        }
slouken@272
   452
                    }
slouken@390
   453
                    break;
slouken@390
   454
                case NSScrollWheel:
slouken@390
   455
                    if (NSPointInRect([ event locationInWindow ], winRect)) {
slouken@390
   456
                        float dy;
slouken@390
   457
                        dy = [ event deltaY ];
slouken@390
   458
                        if ( dy > 0.0 ) /* Scroll up */
slouken@390
   459
                            SDL_PrivateMouseButton (SDL_PRESSED, 4, 0, 0);
slouken@390
   460
                        else /* Scroll down */
slouken@390
   461
                            SDL_PrivateMouseButton (SDL_PRESSED, 5, 0, 0);
slouken@390
   462
                    }
slouken@390
   463
                    break;
slouken@390
   464
                case NSKeyUp:
slouken@390
   465
                    QZ_DoKey (SDL_RELEASED, event);
slouken@390
   466
                    break;
slouken@390
   467
                case NSKeyDown:
slouken@390
   468
                    QZ_DoKey (SDL_PRESSED, event);
slouken@390
   469
                    break;
slouken@390
   470
                case NSFlagsChanged:
slouken@390
   471
                    QZ_DoModifiers( [ event modifierFlags ] );
slouken@390
   472
                    break;
slouken@390
   473
                case NSAppKitDefined:
slouken@390
   474
                    switch ( [ event subtype ] ) {
slouken@390
   475
                        case NSApplicationActivatedEventType:
slouken@390
   476
                            QZ_DoActivate (this);
slouken@390
   477
                            break;
slouken@390
   478
                        case NSApplicationDeactivatedEventType:
slouken@390
   479
                            QZ_DoDeactivate (this);
slouken@390
   480
                            break;
slouken@390
   481
                    }
slouken@390
   482
                    [ NSApp sendEvent:event ];
slouken@390
   483
                    break;
slouken@390
   484
                    /* case NSApplicationDefined: break; */
slouken@390
   485
                    /* case NSPeriodic: break; */
slouken@390
   486
                    /* case NSCursorUpdate: break; */
slouken@390
   487
                default:
slouken@390
   488
                    [ NSApp sendEvent:event ];
slouken@272
   489
            }
slouken@272
   490
        }
slouken@390
   491
    } while (event != nil);
slouken@390
   492
    
slouken@390
   493
    /* check for accumulated mouse events */
slouken@390
   494
    if (dx != 0 || dy != 0)
slouken@390
   495
    SDL_PrivateMouseMotion (0, 1, dx, dy);
slouken@390
   496
    
slouken@390
   497
    [ pool release ];
slouken@47
   498
}
slouken@47
   499