src/video/gem/SDL_gemevents.c
author Patrice Mandin <patmandin@gmail.com>
Fri, 13 Jul 2007 16:11:58 +0000
changeset 2186 6fe43f7efd94
parent 2043 adf732f1f016
child 2189 f54670a477bb
permissions -rw-r--r--
Simplify setting window title
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) {
patmandin@2186
   159
        const char *window_name = (SDL_GetAppState() & SDL_APPACTIVE) ?
patmandin@2186
   160
            GEM_title_name : GEM_icon_name;
patmandin@2186
   161
        if (window_name) {
patmandin@2186
   162
            wind_set(GEM_handle, WF_NAME,
patmandin@2186
   163
                     (short) (((unsigned long) window_name) >> 16),
patmandin@2186
   164
                     (short) (((unsigned long) window_name) & 0xffff), 0, 0);
slouken@1895
   165
        }
slouken@1895
   166
        GEM_refresh_name = SDL_FALSE;
slouken@1895
   167
    }
slouken@281
   168
}
slouken@281
   169
slouken@1895
   170
static int
slouken@1895
   171
do_messages(_THIS, short *message)
slouken@281
   172
{
slouken@1895
   173
    int quit, posted;
slouken@1895
   174
    short x2, y2, w2, h2;
slouken@281
   175
slouken@1895
   176
    quit = 0;
slouken@1895
   177
    switch (message[0]) {
slouken@1895
   178
    case WM_CLOSED:
slouken@1895
   179
    case AP_TERM:
slouken@1895
   180
        posted = SDL_PrivateQuit();
slouken@1895
   181
        quit = 1;
slouken@1895
   182
        break;
slouken@1895
   183
    case WM_MOVED:
slouken@1895
   184
        wind_set(message[3], WF_CURRXYWH, message[4], message[5],
slouken@1895
   185
                 message[6], message[7]);
slouken@1895
   186
        break;
slouken@1895
   187
    case WM_TOPPED:
slouken@1895
   188
        wind_set(message[3], WF_TOP, message[4], 0, 0, 0);
slouken@1895
   189
        /* Continue with TOP event processing */
slouken@1895
   190
    case WM_ONTOP:
slouken@1895
   191
        SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
slouken@1895
   192
        if (VDI_setpalette) {
slouken@1895
   193
            VDI_setpalette(this, VDI_curpalette);
slouken@1895
   194
        }
slouken@1895
   195
        break;
slouken@1895
   196
    case WM_REDRAW:
slouken@1895
   197
        if (!GEM_lock_redraw) {
slouken@1895
   198
            GEM_wind_redraw(this, message[3], &message[4]);
slouken@1895
   199
        }
slouken@1895
   200
        break;
slouken@1895
   201
    case WM_ICONIFY:
slouken@1895
   202
    case WM_ALLICONIFY:
slouken@1895
   203
        wind_set(message[3], WF_ICONIFY, message[4], message[5],
slouken@1895
   204
                 message[6], message[7]);
slouken@1895
   205
        /* If we're active, make ourselves inactive */
slouken@1895
   206
        if (SDL_GetAppState() & SDL_APPACTIVE) {
slouken@1895
   207
            /* Send an internal deactivate event */
slouken@1895
   208
            SDL_PrivateAppActive(0, SDL_APPACTIVE);
slouken@1895
   209
        }
slouken@1895
   210
        /* Update window title */
slouken@1895
   211
        if (GEM_refresh_name && GEM_icon_name) {
slouken@1895
   212
            wind_set(GEM_handle, WF_NAME,
slouken@1895
   213
                     (short) (((unsigned long) GEM_icon_name) >> 16),
slouken@1895
   214
                     (short) (((unsigned long) GEM_icon_name) & 0xffff),
slouken@1895
   215
                     0, 0);
slouken@1895
   216
            GEM_refresh_name = SDL_FALSE;
slouken@1895
   217
        }
slouken@1895
   218
        break;
slouken@1895
   219
    case WM_UNICONIFY:
slouken@1895
   220
        wind_set(message[3], WF_UNICONIFY, message[4], message[5],
slouken@1895
   221
                 message[6], message[7]);
slouken@1895
   222
        /* If we're not active, make ourselves active */
slouken@1895
   223
        if (!(SDL_GetAppState() & SDL_APPACTIVE)) {
slouken@1895
   224
            /* Send an internal activate event */
slouken@1895
   225
            SDL_PrivateAppActive(1, SDL_APPACTIVE);
slouken@1895
   226
        }
slouken@1895
   227
        if (GEM_refresh_name && GEM_title_name) {
slouken@1895
   228
            wind_set(GEM_handle, WF_NAME,
slouken@1895
   229
                     (short) (((unsigned long) GEM_title_name) >> 16),
slouken@1895
   230
                     (short) (((unsigned long) GEM_title_name) & 0xffff),
slouken@1895
   231
                     0, 0);
slouken@1895
   232
            GEM_refresh_name = SDL_FALSE;
slouken@1895
   233
        }
slouken@1895
   234
        break;
slouken@1895
   235
    case WM_SIZED:
slouken@1895
   236
        wind_set(message[3], WF_CURRXYWH, message[4], message[5],
slouken@1895
   237
                 message[6], message[7]);
slouken@1895
   238
        wind_get(message[3], WF_WORKXYWH, &x2, &y2, &w2, &h2);
slouken@1895
   239
        GEM_win_fulled = SDL_FALSE;     /* Cancel maximized flag */
slouken@1895
   240
        GEM_lock_redraw = SDL_TRUE;     /* Prevent redraw till buffers resized */
slouken@1895
   241
        SDL_PrivateResize(w2, h2);
slouken@1895
   242
        break;
slouken@1895
   243
    case WM_FULLED:
slouken@1895
   244
        {
slouken@1895
   245
            short x, y, w, h;
slouken@281
   246
slouken@1895
   247
            if (GEM_win_fulled) {
slouken@1895
   248
                wind_get(message[3], WF_PREVXYWH, &x, &y, &w, &h);
slouken@1895
   249
                GEM_win_fulled = SDL_FALSE;
slouken@1895
   250
            } else {
slouken@1895
   251
                x = GEM_desk_x;
slouken@1895
   252
                y = GEM_desk_y;
slouken@1895
   253
                w = GEM_desk_w;
slouken@1895
   254
                h = GEM_desk_h;
slouken@1895
   255
                GEM_win_fulled = SDL_TRUE;
slouken@1895
   256
            }
slouken@1895
   257
            wind_set(message[3], WF_CURRXYWH, x, y, w, h);
slouken@1895
   258
            wind_get(message[3], WF_WORKXYWH, &x2, &y2, &w2, &h2);
slouken@1895
   259
            GEM_lock_redraw = SDL_TRUE; /* Prevent redraw till buffers resized */
slouken@1895
   260
            SDL_PrivateResize(w2, h2);
slouken@1895
   261
        }
slouken@1895
   262
        break;
slouken@1895
   263
    case WM_BOTTOMED:
slouken@1895
   264
        wind_set(message[3], WF_BOTTOM, 0, 0, 0, 0);
slouken@1895
   265
        /* Continue with BOTTOM event processing */
slouken@1895
   266
    case WM_UNTOPPED:
slouken@1895
   267
        SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
slouken@1895
   268
        if (VDI_setpalette) {
slouken@1895
   269
            VDI_setpalette(this, VDI_oldpalette);
slouken@1895
   270
        }
slouken@1895
   271
        break;
slouken@1895
   272
    }
slouken@1895
   273
slouken@1895
   274
    return quit;
slouken@281
   275
}
slouken@281
   276
slouken@1895
   277
static void
slouken@1895
   278
do_keyboard(short kc, short ks)
slouken@281
   279
{
slouken@1895
   280
    int scancode, asciicode;
slouken@281
   281
slouken@1895
   282
    if (kc) {
slouken@2043
   283
        scancode = (kc >> 8) & (ATARIBIOS_MAXKEYS - 1);
slouken@2043
   284
        gem_currentkeyboard[scancode] = 0xFF;
slouken@1895
   285
    }
slouken@281
   286
slouken@1895
   287
    /* Read special keys */
slouken@1895
   288
    if (ks & K_RSHIFT)
slouken@1895
   289
        gem_currentkeyboard[SCANCODE_RIGHTSHIFT] = 0xFF;
slouken@1895
   290
    if (ks & K_LSHIFT)
slouken@1895
   291
        gem_currentkeyboard[SCANCODE_LEFTSHIFT] = 0xFF;
slouken@1895
   292
    if (ks & K_CTRL)
slouken@1895
   293
        gem_currentkeyboard[SCANCODE_LEFTCONTROL] = 0xFF;
slouken@1895
   294
    if (ks & K_ALT)
slouken@1895
   295
        gem_currentkeyboard[SCANCODE_LEFTALT] = 0xFF;
slouken@281
   296
}
slouken@281
   297
slouken@1895
   298
static void
slouken@1895
   299
do_mouse(_THIS, short mx, short my, short mb, short ks)
slouken@281
   300
{
slouken@1895
   301
    static short prevmousex = 0, prevmousey = 0, prevmouseb = 0;
slouken@1895
   302
    short x2, y2, w2, h2;
patmandin@926
   303
slouken@1895
   304
    /* Don't return mouse events if out of window */
slouken@1895
   305
    if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) == 0) {
slouken@1895
   306
        return;
slouken@1895
   307
    }
patmandin@1067
   308
slouken@1895
   309
    /* Retrieve window coords, and generate mouse events accordingly */
slouken@1895
   310
    x2 = y2 = 0;
slouken@1895
   311
    w2 = VDI_w;
slouken@1895
   312
    h2 = VDI_h;
slouken@1895
   313
    if ((!GEM_fullscreen) && (GEM_handle >= 0)) {
slouken@1895
   314
        wind_get(GEM_handle, WF_WORKXYWH, &x2, &y2, &w2, &h2);
patmandin@926
   315
slouken@1895
   316
        /* Do not generate mouse button event if out of window working area */
slouken@1895
   317
        if ((mx < x2) || (mx >= x2 + w2) || (my < y2) || (my >= y2 + h2)) {
slouken@1895
   318
            mb = prevmouseb;
slouken@1895
   319
        }
slouken@1895
   320
    }
slouken@319
   321
slouken@1895
   322
    /* Mouse motion ? */
slouken@1895
   323
    if (GEM_mouse_relative) {
slouken@1895
   324
        if (GEM_usedevmouse) {
slouken@1895
   325
            SDL_AtariDevMouse_PostMouseEvents(this, SDL_FALSE);
slouken@1895
   326
        } else {
slouken@1895
   327
            SDL_AtariXbios_PostMouseEvents(this, SDL_FALSE);
slouken@1895
   328
        }
slouken@1895
   329
    } else {
slouken@1895
   330
        if ((prevmousex != mx) || (prevmousey != my)) {
slouken@1895
   331
            int posx, posy;
patmandin@926
   332
slouken@1895
   333
            /* Give mouse position relative to window position */
slouken@1895
   334
            posx = mx - x2;
slouken@1895
   335
            if (posx < 0)
slouken@1895
   336
                posx = 0;
slouken@1895
   337
            if (posx > w2)
slouken@1895
   338
                posx = w2 - 1;
slouken@1895
   339
            posy = my - y2;
slouken@1895
   340
            if (posy < 0)
slouken@1895
   341
                posy = 0;
slouken@1895
   342
            if (posy > h2)
slouken@1895
   343
                posy = h2 - 1;
patmandin@926
   344
slouken@1895
   345
            SDL_PrivateMouseMotion(0, 0, posx, posy);
slouken@1895
   346
        }
slouken@1895
   347
        prevmousex = mx;
slouken@1895
   348
        prevmousey = my;
slouken@1895
   349
    }
slouken@281
   350
slouken@1895
   351
    /* Mouse button ? */
slouken@1895
   352
    if (prevmouseb != mb) {
slouken@1895
   353
        int i;
slouken@281
   354
slouken@1895
   355
        for (i = 0; i < 2; i++) {
slouken@1895
   356
            int curbutton, prevbutton;
slouken@319
   357
slouken@1895
   358
            curbutton = mb & (1 << i);
slouken@1895
   359
            prevbutton = prevmouseb & (1 << i);
slouken@1895
   360
slouken@1895
   361
            if (curbutton && !prevbutton) {
slouken@1895
   362
                SDL_PrivateMouseButton(SDL_PRESSED, i + 1, 0, 0);
slouken@1895
   363
            }
slouken@1895
   364
            if (!curbutton && prevbutton) {
slouken@1895
   365
                SDL_PrivateMouseButton(SDL_RELEASED, i + 1, 0, 0);
slouken@1895
   366
            }
slouken@1895
   367
        }
slouken@1895
   368
        prevmouseb = mb;
slouken@1895
   369
    }
slouken@1895
   370
slouken@1895
   371
    /* Read special keys */
slouken@1895
   372
    if (ks & K_RSHIFT)
slouken@1895
   373
        gem_currentkeyboard[SCANCODE_RIGHTSHIFT] = 0xFF;
slouken@1895
   374
    if (ks & K_LSHIFT)
slouken@1895
   375
        gem_currentkeyboard[SCANCODE_LEFTSHIFT] = 0xFF;
slouken@1895
   376
    if (ks & K_CTRL)
slouken@1895
   377
        gem_currentkeyboard[SCANCODE_LEFTCONTROL] = 0xFF;
slouken@1895
   378
    if (ks & K_ALT)
slouken@1895
   379
        gem_currentkeyboard[SCANCODE_LEFTALT] = 0xFF;
slouken@281
   380
}
slouken@1895
   381
slouken@1895
   382
/* vi: set ts=4 sw=4 expandtab: */