src/video/gem/SDL_gemevents.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 24 Sep 2006 15:56:55 +0000
changeset 2043 adf732f1f016
parent 2030 d774e9d7c2a8
child 2186 6fe43f7efd94
permissions -rw-r--r--
Formatting update
slouken@281
     1
/*
slouken@281
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@281
     4
slouken@281
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@281
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@281
     9
slouken@281
    10
    This library is distributed in the hope that it will be useful,
slouken@281
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@281
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@281
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@281
    18
slouken@281
    19
    Sam Lantinga
slouken@281
    20
    slouken@libsdl.org
slouken@281
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@281
    23
slouken@281
    24
/*
slouken@281
    25
 * GEM SDL video driver implementation
slouken@281
    26
 * inspired from the Dummy SDL driver
slouken@281
    27
 * 
slouken@281
    28
 * Patrice Mandin
slouken@281
    29
 * and work from
slouken@281
    30
 * Olivier Landemarre, Johan Klockars, Xavier Joubert, Claude Attard
slouken@281
    31
 */
slouken@281
    32
slouken@281
    33
#include <gem.h>
slouken@281
    34
slouken@1361
    35
#include "../../events/SDL_sysevents.h"
slouken@1361
    36
#include "../../events/SDL_events_c.h"
slouken@281
    37
#include "SDL_gemvideo.h"
slouken@281
    38
#include "SDL_gemevents_c.h"
slouken@1895
    39
#include "../ataricommon/SDL_atarikeys.h"       /* for keyboard scancodes */
patmandin@1412
    40
#include "../ataricommon/SDL_atarievents_c.h"
patmandin@1412
    41
#include "../ataricommon/SDL_xbiosevents_c.h"
patmandin@1420
    42
#include "../ataricommon/SDL_ataridevmouse_c.h"
slouken@281
    43
slouken@281
    44
/* Variables */
slouken@281
    45
slouken@281
    46
static unsigned char gem_currentkeyboard[ATARIBIOS_MAXKEYS];
slouken@281
    47
static unsigned char gem_previouskeyboard[ATARIBIOS_MAXKEYS];
slouken@281
    48
slouken@281
    49
/* Functions prototypes */
slouken@281
    50
slouken@281
    51
static int do_messages(_THIS, short *message);
slouken@281
    52
static void do_keyboard(short kc, short ks);
slouken@319
    53
static void do_mouse(_THIS, short mx, short my, short mb, short ks);
slouken@281
    54
slouken@281
    55
/* Functions */
slouken@281
    56
slouken@1895
    57
void
slouken@1895
    58
GEM_InitOSKeymap(_THIS)
slouken@281
    59
{
slouken@1895
    60
    SDL_memset(gem_currentkeyboard, 0, sizeof(gem_currentkeyboard));
slouken@1895
    61
    SDL_memset(gem_previouskeyboard, 0, sizeof(gem_previouskeyboard));
slouken@281
    62
slouken@1895
    63
    /* Mouse init */
slouken@1895
    64
    GEM_mouse_relative = SDL_FALSE;
patmandin@2030
    65
patmandin@2030
    66
    SDL_Atari_InitInternalKeymap(this);
slouken@281
    67
}
slouken@281
    68
slouken@1895
    69
void
slouken@1895
    70
GEM_PumpEvents(_THIS)
slouken@281
    71
{
slouken@1895
    72
    short mousex, mousey, mouseb, dummy;
slouken@1895
    73
    short kstate, prevkc, prevks;
slouken@1895
    74
    int i;
slouken@1895
    75
    SDL_keysym keysym;
slouken@281
    76
slouken@1895
    77
    SDL_memset(gem_currentkeyboard, 0, sizeof(gem_currentkeyboard));
slouken@1895
    78
    prevkc = prevks = 0;
slouken@281
    79
slouken@1895
    80
    for (;;) {
slouken@1895
    81
        int quit, resultat, event_mask, mouse_event;
slouken@1895
    82
        short buffer[8], kc;
slouken@1895
    83
        short x2, y2, w2, h2;
slouken@281
    84
slouken@1895
    85
        quit = mouse_event = x2 = y2 = w2 = h2 = 0;
patmandin@1067
    86
slouken@1895
    87
        event_mask = MU_MESAG | MU_TIMER | MU_KEYBD;
slouken@1895
    88
        if (!GEM_fullscreen && (GEM_handle >= 0)) {
slouken@1895
    89
            wind_get(GEM_handle, WF_WORKXYWH, &x2, &y2, &w2, &h2);
slouken@1895
    90
            event_mask |= MU_M1;
slouken@1895
    91
            if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS)) {
slouken@1895
    92
                mouse_event = MO_LEAVE;
slouken@1895
    93
            } else {
slouken@1895
    94
                mouse_event = MO_ENTER;
slouken@1895
    95
            }
slouken@1895
    96
        }
slouken@281
    97
slouken@1895
    98
        resultat = evnt_multi(event_mask,
slouken@1895
    99
                              0, 0, 0,
slouken@1895
   100
                              mouse_event, x2, y2, w2, h2,
slouken@1895
   101
                              0, 0, 0, 0, 0,
slouken@1895
   102
                              buffer,
slouken@1895
   103
                              10,
slouken@1895
   104
                              &dummy, &dummy, &dummy, &kstate, &kc, &dummy);
slouken@281
   105
slouken@1895
   106
        /* Message event ? */
slouken@1895
   107
        if (resultat & MU_MESAG)
slouken@1895
   108
            quit = do_messages(this, buffer);
slouken@281
   109
slouken@1895
   110
        /* Keyboard event ? */
slouken@1895
   111
        if (resultat & MU_KEYBD) {
slouken@1895
   112
            if ((prevkc != kc) || (prevks != kstate)) {
slouken@1895
   113
                do_keyboard(kc, kstate);
slouken@1895
   114
            } else {
slouken@1895
   115
                /* Avoid looping, if repeating same key */
slouken@1895
   116
                break;
slouken@1895
   117
            }
slouken@1895
   118
        }
patmandin@1067
   119
slouken@1895
   120
        /* Mouse entering/leaving window */
slouken@1895
   121
        if (resultat & MU_M1) {
slouken@1895
   122
            if (this->input_grab == SDL_GRAB_OFF) {
slouken@1895
   123
                if (SDL_GetAppState() & SDL_APPMOUSEFOCUS) {
slouken@1895
   124
                    SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
slouken@1895
   125
                } else {
slouken@1895
   126
                    SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
slouken@1895
   127
                }
slouken@1895
   128
            }
slouken@1895
   129
        }
slouken@281
   130
slouken@1895
   131
        /* Timer event ? */
slouken@1895
   132
        if ((resultat & MU_TIMER) || quit)
slouken@1895
   133
            break;
slouken@1895
   134
    }
slouken@281
   135
slouken@1895
   136
    /* Update mouse */
slouken@1895
   137
    graf_mkstate(&mousex, &mousey, &mouseb, &kstate);
slouken@1895
   138
    do_mouse(this, mousex, mousey, mouseb, kstate);
slouken@281
   139
slouken@1895
   140
    /* Now generate keyboard events */
slouken@1895
   141
    for (i = 0; i < ATARIBIOS_MAXKEYS; i++) {
slouken@1895
   142
        /* Key pressed ? */
slouken@1895
   143
        if (gem_currentkeyboard[i] && !gem_previouskeyboard[i])
slouken@1895
   144
            SDL_PrivateKeyboard(SDL_PRESSED,
patmandin@2030
   145
                                SDL_Atari_TranslateKey(i, &keysym, SDL_TRUE));
patmandin@996
   146
slouken@1895
   147
        /* Key unpressed ? */
slouken@1895
   148
        if (gem_previouskeyboard[i] && !gem_currentkeyboard[i])
slouken@1895
   149
            SDL_PrivateKeyboard(SDL_RELEASED,
slouken@2043
   150
                                SDL_Atari_TranslateKey(i, &keysym,
slouken@2043
   151
                                                       SDL_FALSE));
slouken@1895
   152
    }
slouken@1895
   153
slouken@1895
   154
    SDL_memcpy(gem_previouskeyboard, gem_currentkeyboard,
slouken@1895
   155
               sizeof(gem_previouskeyboard));
slouken@1895
   156
slouken@1895
   157
    /* Refresh window name ? */
slouken@1895
   158
    if (GEM_refresh_name) {
slouken@1895
   159
        if (SDL_GetAppState() & SDL_APPACTIVE) {
slouken@1895
   160
            /* Fullscreen/windowed */
slouken@1895
   161
            if (GEM_title_name) {
slouken@1895
   162
                wind_set(GEM_handle, WF_NAME,
slouken@1895
   163
                         (short) (((unsigned long) GEM_title_name) >>
slouken@1895
   164
                                  16),
slouken@1895
   165
                         (short) (((unsigned long) GEM_title_name) &
slouken@1895
   166
                                  0xffff), 0, 0);
slouken@1895
   167
            }
slouken@1895
   168
        } else {
slouken@1895
   169
            /* Iconified */
slouken@1895
   170
            if (GEM_icon_name) {
slouken@1895
   171
                wind_set(GEM_handle, WF_NAME,
slouken@1895
   172
                         (short) (((unsigned long) GEM_icon_name) >>
slouken@1895
   173
                                  16),
slouken@1895
   174
                         (short) (((unsigned long) GEM_icon_name) &
slouken@1895
   175
                                  0xffff), 0, 0);
slouken@1895
   176
            }
slouken@1895
   177
        }
slouken@1895
   178
        GEM_refresh_name = SDL_FALSE;
slouken@1895
   179
    }
slouken@281
   180
}
slouken@281
   181
slouken@1895
   182
static int
slouken@1895
   183
do_messages(_THIS, short *message)
slouken@281
   184
{
slouken@1895
   185
    int quit, posted;
slouken@1895
   186
    short x2, y2, w2, h2;
slouken@281
   187
slouken@1895
   188
    quit = 0;
slouken@1895
   189
    switch (message[0]) {
slouken@1895
   190
    case WM_CLOSED:
slouken@1895
   191
    case AP_TERM:
slouken@1895
   192
        posted = SDL_PrivateQuit();
slouken@1895
   193
        quit = 1;
slouken@1895
   194
        break;
slouken@1895
   195
    case WM_MOVED:
slouken@1895
   196
        wind_set(message[3], WF_CURRXYWH, message[4], message[5],
slouken@1895
   197
                 message[6], message[7]);
slouken@1895
   198
        break;
slouken@1895
   199
    case WM_TOPPED:
slouken@1895
   200
        wind_set(message[3], WF_TOP, message[4], 0, 0, 0);
slouken@1895
   201
        /* Continue with TOP event processing */
slouken@1895
   202
    case WM_ONTOP:
slouken@1895
   203
        SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
slouken@1895
   204
        if (VDI_setpalette) {
slouken@1895
   205
            VDI_setpalette(this, VDI_curpalette);
slouken@1895
   206
        }
slouken@1895
   207
        break;
slouken@1895
   208
    case WM_REDRAW:
slouken@1895
   209
        if (!GEM_lock_redraw) {
slouken@1895
   210
            GEM_wind_redraw(this, message[3], &message[4]);
slouken@1895
   211
        }
slouken@1895
   212
        break;
slouken@1895
   213
    case WM_ICONIFY:
slouken@1895
   214
    case WM_ALLICONIFY:
slouken@1895
   215
        wind_set(message[3], WF_ICONIFY, message[4], message[5],
slouken@1895
   216
                 message[6], message[7]);
slouken@1895
   217
        /* If we're active, make ourselves inactive */
slouken@1895
   218
        if (SDL_GetAppState() & SDL_APPACTIVE) {
slouken@1895
   219
            /* Send an internal deactivate event */
slouken@1895
   220
            SDL_PrivateAppActive(0, SDL_APPACTIVE);
slouken@1895
   221
        }
slouken@1895
   222
        /* Update window title */
slouken@1895
   223
        if (GEM_refresh_name && GEM_icon_name) {
slouken@1895
   224
            wind_set(GEM_handle, WF_NAME,
slouken@1895
   225
                     (short) (((unsigned long) GEM_icon_name) >> 16),
slouken@1895
   226
                     (short) (((unsigned long) GEM_icon_name) & 0xffff),
slouken@1895
   227
                     0, 0);
slouken@1895
   228
            GEM_refresh_name = SDL_FALSE;
slouken@1895
   229
        }
slouken@1895
   230
        break;
slouken@1895
   231
    case WM_UNICONIFY:
slouken@1895
   232
        wind_set(message[3], WF_UNICONIFY, message[4], message[5],
slouken@1895
   233
                 message[6], message[7]);
slouken@1895
   234
        /* If we're not active, make ourselves active */
slouken@1895
   235
        if (!(SDL_GetAppState() & SDL_APPACTIVE)) {
slouken@1895
   236
            /* Send an internal activate event */
slouken@1895
   237
            SDL_PrivateAppActive(1, SDL_APPACTIVE);
slouken@1895
   238
        }
slouken@1895
   239
        if (GEM_refresh_name && GEM_title_name) {
slouken@1895
   240
            wind_set(GEM_handle, WF_NAME,
slouken@1895
   241
                     (short) (((unsigned long) GEM_title_name) >> 16),
slouken@1895
   242
                     (short) (((unsigned long) GEM_title_name) & 0xffff),
slouken@1895
   243
                     0, 0);
slouken@1895
   244
            GEM_refresh_name = SDL_FALSE;
slouken@1895
   245
        }
slouken@1895
   246
        break;
slouken@1895
   247
    case WM_SIZED:
slouken@1895
   248
        wind_set(message[3], WF_CURRXYWH, message[4], message[5],
slouken@1895
   249
                 message[6], message[7]);
slouken@1895
   250
        wind_get(message[3], WF_WORKXYWH, &x2, &y2, &w2, &h2);
slouken@1895
   251
        GEM_win_fulled = SDL_FALSE;     /* Cancel maximized flag */
slouken@1895
   252
        GEM_lock_redraw = SDL_TRUE;     /* Prevent redraw till buffers resized */
slouken@1895
   253
        SDL_PrivateResize(w2, h2);
slouken@1895
   254
        break;
slouken@1895
   255
    case WM_FULLED:
slouken@1895
   256
        {
slouken@1895
   257
            short x, y, w, h;
slouken@281
   258
slouken@1895
   259
            if (GEM_win_fulled) {
slouken@1895
   260
                wind_get(message[3], WF_PREVXYWH, &x, &y, &w, &h);
slouken@1895
   261
                GEM_win_fulled = SDL_FALSE;
slouken@1895
   262
            } else {
slouken@1895
   263
                x = GEM_desk_x;
slouken@1895
   264
                y = GEM_desk_y;
slouken@1895
   265
                w = GEM_desk_w;
slouken@1895
   266
                h = GEM_desk_h;
slouken@1895
   267
                GEM_win_fulled = SDL_TRUE;
slouken@1895
   268
            }
slouken@1895
   269
            wind_set(message[3], WF_CURRXYWH, x, y, w, h);
slouken@1895
   270
            wind_get(message[3], WF_WORKXYWH, &x2, &y2, &w2, &h2);
slouken@1895
   271
            GEM_lock_redraw = SDL_TRUE; /* Prevent redraw till buffers resized */
slouken@1895
   272
            SDL_PrivateResize(w2, h2);
slouken@1895
   273
        }
slouken@1895
   274
        break;
slouken@1895
   275
    case WM_BOTTOMED:
slouken@1895
   276
        wind_set(message[3], WF_BOTTOM, 0, 0, 0, 0);
slouken@1895
   277
        /* Continue with BOTTOM event processing */
slouken@1895
   278
    case WM_UNTOPPED:
slouken@1895
   279
        SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
slouken@1895
   280
        if (VDI_setpalette) {
slouken@1895
   281
            VDI_setpalette(this, VDI_oldpalette);
slouken@1895
   282
        }
slouken@1895
   283
        break;
slouken@1895
   284
    }
slouken@1895
   285
slouken@1895
   286
    return quit;
slouken@281
   287
}
slouken@281
   288
slouken@1895
   289
static void
slouken@1895
   290
do_keyboard(short kc, short ks)
slouken@281
   291
{
slouken@1895
   292
    int scancode, asciicode;
slouken@281
   293
slouken@1895
   294
    if (kc) {
slouken@2043
   295
        scancode = (kc >> 8) & (ATARIBIOS_MAXKEYS - 1);
slouken@2043
   296
        gem_currentkeyboard[scancode] = 0xFF;
slouken@1895
   297
    }
slouken@281
   298
slouken@1895
   299
    /* Read special keys */
slouken@1895
   300
    if (ks & K_RSHIFT)
slouken@1895
   301
        gem_currentkeyboard[SCANCODE_RIGHTSHIFT] = 0xFF;
slouken@1895
   302
    if (ks & K_LSHIFT)
slouken@1895
   303
        gem_currentkeyboard[SCANCODE_LEFTSHIFT] = 0xFF;
slouken@1895
   304
    if (ks & K_CTRL)
slouken@1895
   305
        gem_currentkeyboard[SCANCODE_LEFTCONTROL] = 0xFF;
slouken@1895
   306
    if (ks & K_ALT)
slouken@1895
   307
        gem_currentkeyboard[SCANCODE_LEFTALT] = 0xFF;
slouken@281
   308
}
slouken@281
   309
slouken@1895
   310
static void
slouken@1895
   311
do_mouse(_THIS, short mx, short my, short mb, short ks)
slouken@281
   312
{
slouken@1895
   313
    static short prevmousex = 0, prevmousey = 0, prevmouseb = 0;
slouken@1895
   314
    short x2, y2, w2, h2;
patmandin@926
   315
slouken@1895
   316
    /* Don't return mouse events if out of window */
slouken@1895
   317
    if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) == 0) {
slouken@1895
   318
        return;
slouken@1895
   319
    }
patmandin@1067
   320
slouken@1895
   321
    /* Retrieve window coords, and generate mouse events accordingly */
slouken@1895
   322
    x2 = y2 = 0;
slouken@1895
   323
    w2 = VDI_w;
slouken@1895
   324
    h2 = VDI_h;
slouken@1895
   325
    if ((!GEM_fullscreen) && (GEM_handle >= 0)) {
slouken@1895
   326
        wind_get(GEM_handle, WF_WORKXYWH, &x2, &y2, &w2, &h2);
patmandin@926
   327
slouken@1895
   328
        /* Do not generate mouse button event if out of window working area */
slouken@1895
   329
        if ((mx < x2) || (mx >= x2 + w2) || (my < y2) || (my >= y2 + h2)) {
slouken@1895
   330
            mb = prevmouseb;
slouken@1895
   331
        }
slouken@1895
   332
    }
slouken@319
   333
slouken@1895
   334
    /* Mouse motion ? */
slouken@1895
   335
    if (GEM_mouse_relative) {
slouken@1895
   336
        if (GEM_usedevmouse) {
slouken@1895
   337
            SDL_AtariDevMouse_PostMouseEvents(this, SDL_FALSE);
slouken@1895
   338
        } else {
slouken@1895
   339
            SDL_AtariXbios_PostMouseEvents(this, SDL_FALSE);
slouken@1895
   340
        }
slouken@1895
   341
    } else {
slouken@1895
   342
        if ((prevmousex != mx) || (prevmousey != my)) {
slouken@1895
   343
            int posx, posy;
patmandin@926
   344
slouken@1895
   345
            /* Give mouse position relative to window position */
slouken@1895
   346
            posx = mx - x2;
slouken@1895
   347
            if (posx < 0)
slouken@1895
   348
                posx = 0;
slouken@1895
   349
            if (posx > w2)
slouken@1895
   350
                posx = w2 - 1;
slouken@1895
   351
            posy = my - y2;
slouken@1895
   352
            if (posy < 0)
slouken@1895
   353
                posy = 0;
slouken@1895
   354
            if (posy > h2)
slouken@1895
   355
                posy = h2 - 1;
patmandin@926
   356
slouken@1895
   357
            SDL_PrivateMouseMotion(0, 0, posx, posy);
slouken@1895
   358
        }
slouken@1895
   359
        prevmousex = mx;
slouken@1895
   360
        prevmousey = my;
slouken@1895
   361
    }
slouken@281
   362
slouken@1895
   363
    /* Mouse button ? */
slouken@1895
   364
    if (prevmouseb != mb) {
slouken@1895
   365
        int i;
slouken@281
   366
slouken@1895
   367
        for (i = 0; i < 2; i++) {
slouken@1895
   368
            int curbutton, prevbutton;
slouken@319
   369
slouken@1895
   370
            curbutton = mb & (1 << i);
slouken@1895
   371
            prevbutton = prevmouseb & (1 << i);
slouken@1895
   372
slouken@1895
   373
            if (curbutton && !prevbutton) {
slouken@1895
   374
                SDL_PrivateMouseButton(SDL_PRESSED, i + 1, 0, 0);
slouken@1895
   375
            }
slouken@1895
   376
            if (!curbutton && prevbutton) {
slouken@1895
   377
                SDL_PrivateMouseButton(SDL_RELEASED, i + 1, 0, 0);
slouken@1895
   378
            }
slouken@1895
   379
        }
slouken@1895
   380
        prevmouseb = mb;
slouken@1895
   381
    }
slouken@1895
   382
slouken@1895
   383
    /* Read special keys */
slouken@1895
   384
    if (ks & K_RSHIFT)
slouken@1895
   385
        gem_currentkeyboard[SCANCODE_RIGHTSHIFT] = 0xFF;
slouken@1895
   386
    if (ks & K_LSHIFT)
slouken@1895
   387
        gem_currentkeyboard[SCANCODE_LEFTSHIFT] = 0xFF;
slouken@1895
   388
    if (ks & K_CTRL)
slouken@1895
   389
        gem_currentkeyboard[SCANCODE_LEFTCONTROL] = 0xFF;
slouken@1895
   390
    if (ks & K_ALT)
slouken@1895
   391
        gem_currentkeyboard[SCANCODE_LEFTALT] = 0xFF;
slouken@281
   392
}
slouken@1895
   393
slouken@1895
   394
/* vi: set ts=4 sw=4 expandtab: */