src/video/os2fslib/SDL_os2fslib.c
author Edgar Simo <bobbens@gmail.com>
Sun, 06 Jul 2008 17:06:37 +0000
branchgsoc2008_force_feedback
changeset 2498 ab567bd667bf
parent 1895 c121d94672cb
child 2698 e1da92da346c
child 2735 204be4fc2726
permissions -rw-r--r--
Fixed various mistakes in the doxygen.
icculus@1190
     1
/*
icculus@1190
     2
    SDL - Simple DirectMedia Layer
icculus@1190
     3
    Copyright (C) 1997-2004 Sam Lantinga
icculus@1190
     4
icculus@1190
     5
    This library is free software; you can redistribute it and/or
icculus@1190
     6
    modify it under the terms of the GNU Library General Public
icculus@1190
     7
    License as published by the Free Software Foundation; either
icculus@1190
     8
    version 2 of the License, or (at your option) any later version.
icculus@1190
     9
icculus@1190
    10
    This library is distributed in the hope that it will be useful,
icculus@1190
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
icculus@1190
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
icculus@1190
    13
    Library General Public License for more details.
icculus@1190
    14
icculus@1190
    15
    You should have received a copy of the GNU Library General Public
icculus@1190
    16
    License along with this library; if not, write to the Free
icculus@1190
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
icculus@1190
    18
icculus@1190
    19
    Sam Lantinga
icculus@1190
    20
    slouken@libsdl.org
icculus@1190
    21
*/
slouken@1402
    22
#include "SDL_config.h"
icculus@1190
    23
slouken@1442
    24
#define _ULS_CALLCONV_
slouken@1442
    25
#define CALLCONV _System
slouken@1895
    26
#include <unidef.h>             // Unicode API
slouken@1895
    27
#include <uconv.h>              // Unicode API (codepage conversion)
slouken@1442
    28
icculus@1190
    29
#include <process.h>
icculus@1190
    30
#include <time.h>
icculus@1190
    31
icculus@1190
    32
#include "SDL_video.h"
icculus@1190
    33
#include "SDL_mouse.h"
slouken@1361
    34
#include "../SDL_sysvideo.h"
slouken@1361
    35
#include "../SDL_pixels_c.h"
slouken@1361
    36
#include "../../events/SDL_events_c.h"
icculus@1190
    37
icculus@1190
    38
#include "SDL_os2fslib.h"
icculus@1190
    39
icculus@1190
    40
static ULONG ulFCFToUse =
slouken@1895
    41
    FCF_TITLEBAR |
slouken@1895
    42
    FCF_SYSMENU |
slouken@1895
    43
    FCF_MINBUTTON |
slouken@1895
    44
    FCF_MAXBUTTON | FCF_NOBYTEALIGN | FCF_SIZEBORDER | FCF_TASKLIST;
slouken@1895
    45
slouken@1895
    46
static int bMouseCaptured = 0;
icculus@1190
    47
static int bMouseCapturable = 0;
icculus@1190
    48
static HPOINTER hptrGlobalPointer = NULL;
icculus@1190
    49
static HPOINTER hptrCurrentIcon = NULL;
icculus@1190
    50
static int iWindowSizeX = 320;
icculus@1190
    51
static int iWindowSizeY = 200;
icculus@1190
    52
static int bWindowResized = 0;
icculus@1190
    53
icculus@1190
    54
#pragma pack(1)
icculus@1190
    55
typedef struct BMPINFO
icculus@1190
    56
{
slouken@1895
    57
    BITMAPINFO;
slouken@1895
    58
    RGB clr;
icculus@1190
    59
} BMPINFO, *PBMPINFO;
icculus@1190
    60
#pragma pack()
icculus@1190
    61
icculus@1190
    62
icculus@1190
    63
// Backdoors:
slouken@1895
    64
DECLSPEC void SDLCALL
slouken@1895
    65
SDL_OS2FSLIB_SetFCFToUse(ULONG ulFCF)
icculus@1190
    66
{
slouken@1895
    67
    ulFCFToUse = ulFCF;
icculus@1190
    68
}
icculus@1190
    69
icculus@1190
    70
// Configuration defines:
icculus@1190
    71
icculus@1190
    72
// We have to report empty alpha mask, otherwise SDL will select
icculus@1190
    73
// alpha blitters, and this will have unwanted results, as we don't
icculus@1190
    74
// support alpha channel in FSLib yet.
icculus@1190
    75
#define REPORT_EMPTY_ALPHA_MASK
icculus@1190
    76
icculus@1190
    77
// Experimental: Move every FSLib_BitBlt() call into window message
icculus@1190
    78
// processing function.
icculus@1190
    79
// This may fix dirt left on desktop. Or not.
icculus@1190
    80
//#define BITBLT_IN_WINMESSAGEPROC
icculus@1190
    81
icculus@1190
    82
// Experimental-2: Use WinLockWindowUpdate() in around bitblts!
icculus@1190
    83
// This is not enabled, because it seems to cause more problems
icculus@1190
    84
// than good.
icculus@1190
    85
//#define USE_WINLOCKWINDOWUPDATE_AROUND_BITBLTS
icculus@1190
    86
icculus@1190
    87
// Use the following to show resized image instead of black stuff
icculus@1190
    88
// even if the surface is resizable.
icculus@1190
    89
//#define RESIZE_EVEN_IF_RESIZABLE
icculus@1190
    90
icculus@1190
    91
/* The translation table from a VK keysym to a SDL keysym */
icculus@1190
    92
static SDLKey HWScanKeyMap[256];
slouken@1895
    93
static SDL_keysym *TranslateKey(int vkey, int chcode, int scancode,
slouken@1895
    94
                                SDL_keysym * keysym, int iPressed);
slouken@1895
    95
static int iShiftIsPressed;
icculus@1190
    96
icculus@1190
    97
#ifdef BITBLT_IN_WINMESSAGEPROC
icculus@1190
    98
#define WM_UPDATERECTSREQUEST   WM_USER+50
icculus@1190
    99
#endif
icculus@1190
   100
icculus@1190
   101
#ifdef USE_WINLOCKWINDOWUPDATE_AROUND_BITBLTS
icculus@1190
   102
#define FSLIB_BITBLT(hwnd, buffer, top, left, width, height) \
icculus@1190
   103
    { \
icculus@1190
   104
      WinLockWindowUpdate(HWND_DESKTOP, HWND_DESKTOP); \
icculus@1190
   105
      FSLib_BitBlt(hwnd, buffer, top, left, width, height); \
icculus@1190
   106
      WinLockWindowUpdate(HWND_DESKTOP, NULL); \
icculus@1190
   107
    }
icculus@1190
   108
#else
icculus@1190
   109
#define FSLIB_BITBLT(hwnd, buffer, top, left, width, height) \
icculus@1190
   110
    FSLib_BitBlt(hwnd, buffer, top, left, width, height);
icculus@1190
   111
#endif
icculus@1190
   112
icculus@1190
   113
/////////////////////////////////////////////////////////////////////
icculus@1190
   114
//
icculus@1190
   115
// SetAccessableWindowPos
icculus@1190
   116
//
icculus@1190
   117
// Same as WinSetWindowPos(), but takes care for the window to be
icculus@1190
   118
// always on the screen, the titlebar will be accessable everytime.
icculus@1190
   119
//
icculus@1190
   120
/////////////////////////////////////////////////////////////////////
slouken@1895
   121
static BOOL
slouken@1895
   122
SetAccessableWindowPos(HWND hwnd, HWND hwndInsertBehind,
slouken@1895
   123
                       LONG x, LONG y, LONG cx, LONG cy, ULONG fl)
icculus@1190
   124
{
slouken@1895
   125
    SWP swpDesktop, swp;
slouken@1895
   126
    // Get desktop area
slouken@1895
   127
    WinQueryWindowPos(HWND_DESKTOP, &swpDesktop);
slouken@1895
   128
slouken@1895
   129
    if ((fl & SWP_MOVE) && (fl & SWP_SIZE)) {
slouken@1895
   130
        // If both moving and sizing, then change size and pos now!!
slouken@1895
   131
        if (x + cx > swpDesktop.cx)
slouken@1895
   132
            x = swpDesktop.cx - cx;
slouken@1895
   133
        if (x < 0)
slouken@1895
   134
            x = 0;
slouken@1895
   135
        if (y < 0)
slouken@1895
   136
            y = 0;
slouken@1895
   137
        if (y + cy > swpDesktop.cy)
slouken@1895
   138
            y = swpDesktop.cy - cy;
slouken@1895
   139
        return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl);
slouken@1895
   140
    } else if (fl & SWP_MOVE) {
slouken@1895
   141
        // Just moving
slouken@1895
   142
        WinQueryWindowPos(hwnd, &swp);
slouken@1895
   143
        if (x + swp.cx > swpDesktop.cx)
slouken@1895
   144
            x = swpDesktop.cx - swp.cx;
slouken@1895
   145
        if (x < 0)
slouken@1895
   146
            x = 0;
slouken@1895
   147
        if (y < 0)
slouken@1895
   148
            y = 0;
slouken@1895
   149
        if (y + swp.cy > swpDesktop.cy)
slouken@1895
   150
            y = swpDesktop.cy - swp.cy;
slouken@1895
   151
        return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl);
slouken@1895
   152
    } else if (fl & SWP_SIZE) {
slouken@1895
   153
        // Just sizing
slouken@1895
   154
        WinQueryWindowPos(hwnd, &swp);
slouken@1895
   155
        x = swp.x;
slouken@1895
   156
        y = swp.y;
slouken@1895
   157
        if (x + cx > swpDesktop.cx)
slouken@1895
   158
            x = swpDesktop.cx - cx;
slouken@1895
   159
        if (x < 0)
slouken@1895
   160
            x = 0;
slouken@1895
   161
        if (y < 0)
slouken@1895
   162
            y = 0;
slouken@1895
   163
        if (y + cy > swpDesktop.cy)
slouken@1895
   164
            y = swpDesktop.cy - cy;
slouken@1895
   165
        return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy,
slouken@1895
   166
                               fl | SWP_MOVE);
slouken@1895
   167
    } else
slouken@1895
   168
        return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl);
icculus@1190
   169
}
icculus@1190
   170
slouken@1895
   171
static UniChar
slouken@1895
   172
NativeCharToUniChar(int chcode)
slouken@1442
   173
{
slouken@1895
   174
    UniChar ucResult = (UniChar) chcode;
slouken@1895
   175
    int rc;
slouken@1895
   176
    UconvObject ucoTemp;
slouken@1895
   177
    char achFrom[2];
slouken@1895
   178
    char *pchFrom;
slouken@1895
   179
    size_t iFromCount;
slouken@1895
   180
    UniChar aucTo[10];
slouken@1895
   181
    UniChar *pucTo;
slouken@1895
   182
    size_t iToCount;
slouken@1895
   183
    size_t iNonIdentical;
slouken@1895
   184
slouken@1895
   185
    // Create unicode convert object
slouken@1895
   186
    rc = UniCreateUconvObject(L"", &ucoTemp);
slouken@1895
   187
    if (rc != ULS_SUCCESS) {
slouken@1895
   188
        // Could not create convert object!
slouken@1895
   189
        return ucResult;
slouken@1895
   190
    }
slouken@1895
   191
    // Convert language code string to unicode string
slouken@1895
   192
    achFrom[0] = (char) chcode;
slouken@1895
   193
    achFrom[1] = 0;
slouken@1895
   194
    iFromCount = sizeof(char) * 2;
slouken@1895
   195
    iToCount = sizeof(UniChar) * 2;
slouken@1895
   196
    pucTo = &(aucTo[0]);
slouken@1895
   197
    pchFrom = &(achFrom[0]);
slouken@1895
   198
slouken@1895
   199
    rc = UniUconvToUcs(ucoTemp,
slouken@1895
   200
                       &pchFrom,
slouken@1895
   201
                       &iFromCount, &pucTo, &iToCount, &iNonIdentical);
slouken@1895
   202
slouken@1895
   203
    if (rc != ULS_SUCCESS) {
slouken@1895
   204
        // Could not convert language code to UCS string!
slouken@1895
   205
        UniFreeUconvObject(ucoTemp);
slouken@1895
   206
        return ucResult;
slouken@1895
   207
    }
slouken@1895
   208
slouken@1442
   209
    UniFreeUconvObject(ucoTemp);
slouken@1442
   210
slouken@1442
   211
#ifdef DEBUG_BUILD
slouken@1895
   212
    printf("%02x converted to %02x\n", (int) chcode, (int) (aucTo[0]));
slouken@1442
   213
#endif
slouken@1442
   214
slouken@1895
   215
    return aucTo[0];
slouken@1442
   216
}
slouken@1442
   217
icculus@1190
   218
/////////////////////////////////////////////////////////////////////
icculus@1190
   219
//
icculus@1190
   220
// TranslateKey
icculus@1190
   221
//
icculus@1190
   222
// This creates SDL Keycodes from VK_ and hardware scan codes
icculus@1190
   223
//
icculus@1190
   224
/////////////////////////////////////////////////////////////////////
slouken@1895
   225
static SDL_keysym *
slouken@1895
   226
TranslateKey(int vkey, int chcode, int scancode, SDL_keysym * keysym,
slouken@1895
   227
             int iPressed)
icculus@1190
   228
{
slouken@1895
   229
    keysym->scancode = (unsigned char) scancode;
slouken@1895
   230
    keysym->mod = KMOD_NONE;
slouken@1895
   231
    keysym->unicode = 0;
slouken@1895
   232
slouken@1895
   233
    if (iPressed && SDL_TranslateUNICODE) {
slouken@1895
   234
        if (chcode)
slouken@1895
   235
            keysym->unicode = NativeCharToUniChar(chcode);
slouken@1895
   236
        else
slouken@1895
   237
            keysym->unicode = vkey;
slouken@1895
   238
    }
slouken@1895
   239
slouken@1895
   240
    keysym->sym = HWScanKeyMap[scancode];
slouken@1895
   241
slouken@1895
   242
    // Now stuffs based on state of shift key(s)!
slouken@1895
   243
    if (vkey == VK_SHIFT) {
slouken@1895
   244
        iShiftIsPressed = iPressed;
icculus@1190
   245
    }
slouken@1895
   246
slouken@1895
   247
    if ((iShiftIsPressed) && (SDL_TranslateUNICODE)) {
slouken@1895
   248
        // Change syms, if Unicode stuff is required
slouken@1895
   249
        // I think it's silly, but it's SDL...
slouken@1895
   250
        switch (keysym->sym) {
slouken@1895
   251
        case SDLK_BACKQUOTE:
slouken@1895
   252
            keysym->sym = '~';
slouken@1895
   253
            break;
slouken@1895
   254
        case SDLK_1:
slouken@1895
   255
            keysym->sym = SDLK_EXCLAIM;
slouken@1895
   256
            break;
slouken@1895
   257
        case SDLK_2:
slouken@1895
   258
            keysym->sym = SDLK_AT;
slouken@1895
   259
            break;
slouken@1895
   260
        case SDLK_3:
slouken@1895
   261
            keysym->sym = SDLK_HASH;
slouken@1895
   262
            break;
slouken@1895
   263
        case SDLK_4:
slouken@1895
   264
            keysym->sym = SDLK_DOLLAR;
slouken@1895
   265
            break;
slouken@1895
   266
        case SDLK_5:
slouken@1895
   267
            keysym->sym = '%';
slouken@1895
   268
            break;
slouken@1895
   269
        case SDLK_6:
slouken@1895
   270
            keysym->sym = SDLK_CARET;
slouken@1895
   271
            break;
slouken@1895
   272
        case SDLK_7:
slouken@1895
   273
            keysym->sym = SDLK_AMPERSAND;
slouken@1895
   274
            break;
slouken@1895
   275
        case SDLK_8:
slouken@1895
   276
            keysym->sym = SDLK_ASTERISK;
slouken@1895
   277
            break;
slouken@1895
   278
        case SDLK_9:
slouken@1895
   279
            keysym->sym = SDLK_LEFTPAREN;
slouken@1895
   280
            break;
slouken@1895
   281
        case SDLK_0:
slouken@1895
   282
            keysym->sym = SDLK_RIGHTPAREN;
slouken@1895
   283
            break;
slouken@1895
   284
        case SDLK_MINUS:
slouken@1895
   285
            keysym->sym = SDLK_UNDERSCORE;
slouken@1895
   286
            break;
slouken@1895
   287
        case SDLK_PLUS:
slouken@1895
   288
            keysym->sym = SDLK_EQUALS;
slouken@1895
   289
            break;
slouken@1895
   290
slouken@1895
   291
        case SDLK_LEFTBRACKET:
slouken@1895
   292
            keysym->sym = '{';
slouken@1895
   293
            break;
slouken@1895
   294
        case SDLK_RIGHTBRACKET:
slouken@1895
   295
            keysym->sym = '}';
slouken@1895
   296
            break;
slouken@1895
   297
slouken@1895
   298
        case SDLK_SEMICOLON:
slouken@1895
   299
            keysym->sym = SDLK_COLON;
slouken@1895
   300
            break;
slouken@1895
   301
        case SDLK_QUOTE:
slouken@1895
   302
            keysym->sym = SDLK_QUOTEDBL;
slouken@1895
   303
            break;
slouken@1895
   304
        case SDLK_BACKSLASH:
slouken@1895
   305
            keysym->sym = '|';
slouken@1895
   306
            break;
slouken@1895
   307
slouken@1895
   308
        case SDLK_COMMA:
slouken@1895
   309
            keysym->sym = SDLK_LESS;
slouken@1895
   310
            break;
slouken@1895
   311
        case SDLK_PERIOD:
slouken@1895
   312
            keysym->sym = SDLK_GREATER;
slouken@1895
   313
            break;
slouken@1895
   314
        case SDLK_SLASH:
slouken@1895
   315
            keysym->sym = SDLK_QUESTION;
slouken@1895
   316
            break;
slouken@1895
   317
slouken@1895
   318
        default:
slouken@1895
   319
            break;
slouken@1895
   320
        }
slouken@1895
   321
    }
slouken@1895
   322
    return keysym;
icculus@1190
   323
}
icculus@1190
   324
icculus@1190
   325
#define CONVERTMOUSEPOSITION()  \
icculus@1190
   326
        /* We have to inverse the mouse position, because every non-os/2 system */                                                \
icculus@1190
   327
        /* has a coordinate system where the (0;0) is the top-left corner,      */                                                \
slouken@1442
   328
        /* while on os/2 it's the bottom left corner!                           */                                                \
slouken@1442
   329
        if (FSLib_QueryFSMode(hwnd))                                                                                              \
slouken@1442
   330
        {                                                                                                                         \
slouken@1442
   331
          /* We're in FS mode!                                                        */                                          \
slouken@1442
   332
          /* In FS mode our window is as big as fullscreen mode, but not necessary as */                                          \
slouken@1442
   333
          /* big as the source buffer (can be bigger)                                 */                                          \
icculus@1190
   334
          /* So, limit mouse pos to source buffer size!                               */                                          \
slouken@1442
   335
          if (ppts->x<0) ppts->x = 0;                                                                                             \
slouken@1442
   336
          if (ppts->y<0) ppts->y = 0;                                                                                             \
slouken@1442
   337
          if (ppts->x>=pVideo->hidden->SrcBufferDesc.uiXResolution) ppts->x = pVideo->hidden->SrcBufferDesc.uiXResolution-1;      \
icculus@1190
   338
          if (ppts->y>=pVideo->hidden->SrcBufferDesc.uiYResolution) ppts->y = pVideo->hidden->SrcBufferDesc.uiYResolution-1;      \
icculus@1190
   339
          pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account!  */                                   \
icculus@1190
   340
          ptl.x = ppts->x; ptl.y = ppts->y;                                                                                       \
icculus@1190
   341
          WinMapWindowPoints(pVideo->hidden->hwndClient, HWND_DESKTOP, &ptl, 1);                                                  \
slouken@1442
   342
          WinSetPointerPos(HWND_DESKTOP, ptl.x, ptl.y);                                                                           \
slouken@1442
   343
          /* Then convert OS/2 position to SDL position */                                                                        \
icculus@1190
   344
          ppts->y = pVideo->hidden->SrcBufferDesc.uiYResolution - ppts->y - 1;                                                    \
slouken@1442
   345
        } else                                                                                                                    \
slouken@1442
   346
        {                                                                                                                         \
slouken@1442
   347
          SWP swpClient;                                                                                                          \
icculus@1190
   348
          /* We're in windowed mode! */                                                                                           \
slouken@1442
   349
          WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient);                                                              \
icculus@1190
   350
          /* Convert OS/2 mouse position to SDL position, and also scale it! */                                                   \
slouken@1442
   351
          (ppts->x) = (ppts->x) * pVideo->hidden->SrcBufferDesc.uiXResolution / swpClient.cx;                                       \
slouken@1442
   352
          (ppts->y) = (ppts->y) * pVideo->hidden->SrcBufferDesc.uiYResolution / swpClient.cy;                                       \
slouken@1442
   353
          (ppts->y) = pVideo->hidden->SrcBufferDesc.uiYResolution - (ppts->y)  - 1;                                                 \
slouken@1442
   354
        }
icculus@1190
   355
icculus@1190
   356
icculus@1190
   357
icculus@1190
   358
/////////////////////////////////////////////////////////////////////
icculus@1190
   359
//
icculus@1190
   360
// WndProc
icculus@1190
   361
//
icculus@1190
   362
// This is the message processing window procedure for the
icculus@1190
   363
// SDLWindowClass, which is the client window in our application.
icculus@1190
   364
// It handles switching back and away from the app (taking care of
icculus@1190
   365
// going out and back to and from fullscreen mode), sending keystrokes
icculus@1190
   366
// and mouse events to where it has to be sent, etc...
icculus@1190
   367
//
icculus@1190
   368
/////////////////////////////////////////////////////////////////////
slouken@1895
   369
static MRESULT EXPENTRY
slouken@1895
   370
WndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
icculus@1190
   371
{
slouken@1895
   372
    HPS ps;
slouken@1895
   373
    RECTL rcl;
slouken@1895
   374
    SDL_VideoDevice *pVideo = NULL;
slouken@1895
   375
slouken@1895
   376
    switch (msg) {
slouken@1895
   377
    case WM_CHAR:              // Keypress notification
icculus@1190
   378
#ifdef DEBUG_BUILD
icculus@1190
   379
//      printf("WM_CHAR\n"); fflush(stdout);
icculus@1190
   380
#endif
slouken@1895
   381
        pVideo = WinQueryWindowPtr(hwnd, 0);
slouken@1895
   382
        if (pVideo) {
slouken@1895
   383
            /*
slouken@1895
   384
               // We skip repeated keys:
slouken@1895
   385
               if (CHARMSG(&msg)->cRepeat>1)
slouken@1895
   386
               {
slouken@1895
   387
               #ifdef DEBUG_BUILD
slouken@1895
   388
               //          printf("Repeated key (%d), skipping...\n", CHARMSG(&msg)->cRepeat); fflush(stdout);
slouken@1895
   389
               #endif
slouken@1895
   390
               return (MRESULT) TRUE;
slouken@1895
   391
               }
slouken@1895
   392
             */
slouken@1895
   393
slouken@1895
   394
            // If it's not repeated, then let's see if its pressed or released!
slouken@1895
   395
            if (SHORT1FROMMP(mp1) & KC_KEYUP) {
slouken@1895
   396
                // A key has been released
slouken@1895
   397
                SDL_keysym keysym;
icculus@1190
   398
icculus@1190
   399
#ifdef DEBUG_BUILD
icculus@1190
   400
//          printf("WM_CHAR, keyup, code is [0x%0x]\n", CHAR4FROMMP(mp1)); // HW scan code
icculus@1190
   401
#endif
icculus@1190
   402
slouken@1895
   403
                // One problem is with F1, which gets only the keyup message because
slouken@1895
   404
                // it is a system key.
slouken@1895
   405
                // So, when we get keyup message, we simulate keydown too!
slouken@1895
   406
                // UPDATE:
slouken@1895
   407
                //  This problem should be solved now, that the accelerator keys are
slouken@1895
   408
                //  disabled for this window!
slouken@1895
   409
                /*
slouken@1895
   410
                   if (SHORT2FROMMP(mp2)==VK_F1)
slouken@1895
   411
                   {
slouken@1895
   412
                   SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code
slouken@1895
   413
                   SHORT1FROMMP(mp2), // Character code
slouken@1895
   414
                   CHAR4FROMMP(mp1),  // HW Scan code
slouken@1895
   415
                   &keysym,0));
slouken@1895
   416
                   } */
slouken@1895
   417
slouken@1895
   418
                SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(SHORT2FROMMP(mp2),       // VK_ code
slouken@1895
   419
                                                               SHORT1FROMMP(mp2),       // Character code
slouken@1895
   420
                                                               CHAR4FROMMP(mp1),        // HW Scan code
slouken@1895
   421
                                                               &keysym, 0));
slouken@1895
   422
slouken@1895
   423
            } else {
slouken@1895
   424
                // A key has been pressed
slouken@1895
   425
                SDL_keysym keysym;
icculus@1190
   426
icculus@1190
   427
#ifdef DEBUG_BUILD
icculus@1190
   428
//          printf("WM_CHAR, keydown, code is [0x%0x]\n", CHAR4FROMMP(mp1)); // HW scan code
icculus@1190
   429
#endif
slouken@1895
   430
                // Check for fastkeys: ALT+HOME to toggle FS mode
slouken@1895
   431
                //                     ALT+END to close app
slouken@1895
   432
                if ((SHORT1FROMMP(mp1) & KC_ALT) &&
slouken@1895
   433
                    (SHORT2FROMMP(mp2) == VK_HOME)) {
icculus@1190
   434
#ifdef DEBUG_BUILD
slouken@1895
   435
                    printf(" Pressed ALT+HOME!\n");
slouken@1895
   436
                    fflush(stdout);
icculus@1190
   437
#endif
slouken@1895
   438
                    // Only switch between fullscreen and back if it's not
slouken@1895
   439
                    // a resizable mode!
slouken@1895
   440
                    if ((!pVideo->hidden->pSDLSurface) ||
slouken@1895
   441
                        ((pVideo->hidden->pSDLSurface)
slouken@1895
   442
                         &&
slouken@1895
   443
                         ((pVideo->hidden->pSDLSurface->
slouken@1895
   444
                           flags & SDL_RESIZABLE) == 0)))
slouken@1895
   445
                        FSLib_ToggleFSMode(hwnd, !FSLib_QueryFSMode(hwnd));
icculus@1190
   446
#ifdef DEBUG_BUILD
slouken@1895
   447
                    else
slouken@1895
   448
                        printf(" Resizable mode, so discarding ALT+HOME!\n");
slouken@1895
   449
                    fflush(stdout);
icculus@1190
   450
#endif
slouken@1895
   451
                } else if ((SHORT1FROMMP(mp1) & KC_ALT) &&
slouken@1895
   452
                           (SHORT2FROMMP(mp2) == VK_END)) {
icculus@1190
   453
#ifdef DEBUG_BUILD
slouken@1895
   454
                    printf(" Pressed ALT+END!\n");
slouken@1895
   455
                    fflush(stdout);
icculus@1190
   456
#endif
slouken@1895
   457
                    // Close window, and get out of loop!
slouken@1895
   458
                    // Also send event to SDL application, but we won't
slouken@1895
   459
                    // wait for it to be processed!
slouken@1895
   460
                    SDL_PrivateQuit();
slouken@1895
   461
                    WinPostMsg(hwnd, WM_QUIT, 0, 0);
slouken@1895
   462
                } else {
slouken@1895
   463
slouken@1895
   464
                    SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(SHORT2FROMMP(mp2),    // VK_ code
slouken@1895
   465
                                                                  SHORT1FROMMP(mp2),    // Character code
slouken@1895
   466
                                                                  CHAR4FROMMP(mp1),     // HW Scan code
slouken@1895
   467
                                                                  &keysym,
slouken@1895
   468
                                                                  1));
slouken@1895
   469
slouken@1895
   470
                }
slouken@1895
   471
            }
slouken@1442
   472
        }
slouken@1895
   473
        return (MRESULT) TRUE;
icculus@1190
   474
icculus@1190
   475
    case WM_TRANSLATEACCEL:
slouken@1442
   476
        {
slouken@1895
   477
            PQMSG pqmsg;
slouken@1895
   478
            pqmsg = (PQMSG) mp1;
slouken@1895
   479
            if (mp1) {
slouken@1895
   480
                if (pqmsg->msg == WM_CHAR) {
slouken@1895
   481
                    // WM_CHAR message!
slouken@1895
   482
                    // Let's filter the ALT keypress and all other acceleration keys!
slouken@1895
   483
                    return (MRESULT) FALSE;
slouken@1895
   484
                }
slouken@1895
   485
            }
slouken@1895
   486
            break;              // Default processing (pass to parent until frame control)
slouken@1442
   487
        }
slouken@1895
   488
slouken@1895
   489
    case WM_PAINT:             // Window redraw!
icculus@1190
   490
#ifdef DEBUG_BUILD
slouken@1895
   491
        printf("WM_PAINT (0x%x)\n", hwnd);
slouken@1895
   492
        fflush(stdout);
icculus@1190
   493
#endif
slouken@1895
   494
        ps = WinBeginPaint(hwnd, 0, &rcl);
slouken@1895
   495
        pVideo = FSLib_GetUserParm(hwnd);
slouken@1895
   496
        if (pVideo) {
slouken@1895
   497
            if (!pVideo->hidden->pSDLSurface) {
slouken@1895
   498
                RECTL rclRect;
slouken@1895
   499
                // So, don't blit now!
icculus@1190
   500
#ifdef DEBUG_BUILD
slouken@1895
   501
                printf("WM_PAINT : Skipping blit while resizing (Pre!)!\n");
slouken@1895
   502
                fflush(stdout);
icculus@1190
   503
#endif
slouken@1895
   504
                WinQueryWindowRect(hwnd, &rclRect);
slouken@1895
   505
                // Fill with black
slouken@1895
   506
                WinFillRect(ps, &rclRect, CLR_BLACK);
slouken@1895
   507
            } else {
slouken@1895
   508
                if (DosRequestMutexSem
slouken@1895
   509
                    (pVideo->hidden->hmtxUseSrcBuffer, 1000) == NO_ERROR) {
slouken@1895
   510
                    int iTop, iLeft, iWidth, iHeight;
slouken@1895
   511
                    int iXScaleError, iYScaleError;
slouken@1895
   512
                    int iXScaleError2, iYScaleError2;
slouken@1895
   513
                    SWP swp;
slouken@1895
   514
slouken@1895
   515
                    // Re-blit the modified area!
slouken@1895
   516
                    // For this, we have to calculate the points, scaled!
slouken@1895
   517
                    WinQueryWindowPos(hwnd, &swp);
icculus@1190
   518
#ifdef DEBUG_BUILD
slouken@1895
   519
                    printf
slouken@1895
   520
                        ("WM_PAINT : WinSize: %d %d, BufSize: %d %d\n",
slouken@1895
   521
                         swp.cx, swp.cy,
slouken@1895
   522
                         pVideo->hidden->SrcBufferDesc.uiXResolution,
slouken@1895
   523
                         pVideo->hidden->SrcBufferDesc.uiYResolution);
slouken@1895
   524
                    fflush(stdout);
icculus@1190
   525
#endif
icculus@1190
   526
icculus@1190
   527
#ifndef RESIZE_EVEN_IF_RESIZABLE
slouken@1895
   528
                    // But only blit if the window is not resizable, or if
slouken@1895
   529
                    // the window is resizable and the source buffer size is the
slouken@1895
   530
                    // same as the destination buffer size!
slouken@1895
   531
                    if ((!pVideo->hidden->pSDLSurface) ||
slouken@1895
   532
                        ((pVideo->hidden->pSDLSurface) &&
slouken@1895
   533
                         (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE)
slouken@1895
   534
                         &&
slouken@1895
   535
                         ((swp.cx !=
slouken@1895
   536
                           pVideo->hidden->SrcBufferDesc.uiXResolution)
slouken@1895
   537
                          || (swp.cy !=
slouken@1895
   538
                              pVideo->hidden->SrcBufferDesc.uiYResolution))
slouken@1895
   539
                         && (!FSLib_QueryFSMode(hwnd)))) {
slouken@1895
   540
                        RECTL rclRect;
slouken@1895
   541
                        // Resizable surface and in resizing!
slouken@1895
   542
                        // So, don't blit now!
icculus@1190
   543
#ifdef DEBUG_BUILD
slouken@1895
   544
                        printf("WM_PAINT : Skipping blit while resizing!\n");
slouken@1895
   545
                        fflush(stdout);
icculus@1190
   546
#endif
slouken@1895
   547
                        WinQueryWindowRect(hwnd, &rclRect);
slouken@1895
   548
                        // Fill with black
slouken@1895
   549
                        WinFillRect(ps, &rclRect, CLR_BLACK);
slouken@1895
   550
                    } else
icculus@1190
   551
#endif
slouken@1895
   552
                    {
slouken@1895
   553
slouken@1895
   554
                        iXScaleError =
slouken@1895
   555
                            (pVideo->hidden->SrcBufferDesc.
slouken@1895
   556
                             uiXResolution - 1) / swp.cx;
slouken@1895
   557
                        iYScaleError =
slouken@1895
   558
                            (pVideo->hidden->SrcBufferDesc.
slouken@1895
   559
                             uiYResolution - 1) / swp.cy;
slouken@1895
   560
                        if (iXScaleError < 0)
slouken@1895
   561
                            iXScaleError = 0;
slouken@1895
   562
                        if (iYScaleError < 0)
slouken@1895
   563
                            iYScaleError = 0;
slouken@1895
   564
                        iXScaleError2 =
slouken@1895
   565
                            (swp.cx -
slouken@1895
   566
                             1) /
slouken@1895
   567
                            (pVideo->hidden->SrcBufferDesc.uiXResolution);
slouken@1895
   568
                        iYScaleError2 =
slouken@1895
   569
                            (swp.cy -
slouken@1895
   570
                             1) /
slouken@1895
   571
                            (pVideo->hidden->SrcBufferDesc.uiYResolution);
slouken@1895
   572
                        if (iXScaleError2 < 0)
slouken@1895
   573
                            iXScaleError2 = 0;
slouken@1895
   574
                        if (iYScaleError2 < 0)
slouken@1895
   575
                            iYScaleError2 = 0;
slouken@1895
   576
slouken@1895
   577
                        iTop =
slouken@1895
   578
                            (swp.cy -
slouken@1895
   579
                             rcl.yTop) *
slouken@1895
   580
                            pVideo->hidden->SrcBufferDesc.
slouken@1895
   581
                            uiYResolution / swp.cy - iYScaleError;
slouken@1895
   582
                        iLeft =
slouken@1895
   583
                            rcl.xLeft *
slouken@1895
   584
                            pVideo->hidden->SrcBufferDesc.
slouken@1895
   585
                            uiXResolution / swp.cx - iXScaleError;
slouken@1895
   586
                        iWidth =
slouken@1895
   587
                            ((rcl.xRight -
slouken@1895
   588
                              rcl.xLeft) *
slouken@1895
   589
                             pVideo->hidden->SrcBufferDesc.
slouken@1895
   590
                             uiXResolution + swp.cx - 1) / swp.cx +
slouken@1895
   591
                            2 * iXScaleError;
slouken@1895
   592
                        iHeight =
slouken@1895
   593
                            ((rcl.yTop -
slouken@1895
   594
                              rcl.yBottom) *
slouken@1895
   595
                             pVideo->hidden->SrcBufferDesc.
slouken@1895
   596
                             uiYResolution + swp.cy - 1) / swp.cy +
slouken@1895
   597
                            2 * iYScaleError;
slouken@1895
   598
slouken@1895
   599
                        iWidth += iXScaleError2;
slouken@1895
   600
                        iHeight += iYScaleError2;
slouken@1895
   601
slouken@1895
   602
                        if (iTop < 0)
slouken@1895
   603
                            iTop = 0;
slouken@1895
   604
                        if (iLeft < 0)
slouken@1895
   605
                            iLeft = 0;
slouken@1895
   606
                        if (iTop + iHeight >
slouken@1895
   607
                            pVideo->hidden->SrcBufferDesc.uiYResolution)
slouken@1895
   608
                            iHeight =
slouken@1895
   609
                                pVideo->hidden->SrcBufferDesc.
slouken@1895
   610
                                uiYResolution - iTop;
slouken@1895
   611
                        if (iLeft + iWidth >
slouken@1895
   612
                            pVideo->hidden->SrcBufferDesc.uiXResolution)
slouken@1895
   613
                            iWidth =
slouken@1895
   614
                                pVideo->hidden->SrcBufferDesc.
slouken@1895
   615
                                uiXResolution - iLeft;
slouken@1895
   616
icculus@1190
   617
#ifdef DEBUG_BUILD
slouken@1895
   618
                        printf
slouken@1895
   619
                            ("WM_PAINT : BitBlt: %d %d -> %d %d (Buf %d x %d)\n",
slouken@1895
   620
                             iTop, iLeft, iWidth, iHeight,
slouken@1895
   621
                             pVideo->hidden->SrcBufferDesc.
slouken@1895
   622
                             uiXResolution,
slouken@1895
   623
                             pVideo->hidden->SrcBufferDesc.uiYResolution);
slouken@1895
   624
                        fflush(stdout);
icculus@1190
   625
#endif
slouken@1895
   626
slouken@1895
   627
                        FSLIB_BITBLT(hwnd,
slouken@1895
   628
                                     pVideo->hidden->pchSrcBuffer,
slouken@1895
   629
                                     iTop, iLeft, iWidth, iHeight);
slouken@1895
   630
                    }
slouken@1895
   631
slouken@1895
   632
                    DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer);
slouken@1895
   633
                }
icculus@1190
   634
            }
icculus@1190
   635
        }
icculus@1190
   636
#ifdef DEBUG_BUILD
slouken@1895
   637
        else {
slouken@1895
   638
            printf("WM_PAINT : No pVideo!\n");
slouken@1895
   639
            fflush(stdout);
slouken@1895
   640
        }
icculus@1190
   641
#endif
slouken@1895
   642
        WinEndPaint(ps);
icculus@1190
   643
#ifdef DEBUG_BUILD
slouken@1895
   644
        printf("WM_PAINT : Done.\n");
slouken@1895
   645
        fflush(stdout);
icculus@1190
   646
#endif
slouken@1895
   647
        return 0;
icculus@1190
   648
icculus@1190
   649
    case WM_SIZE:
slouken@1895
   650
        {
icculus@1190
   651
#ifdef DEBUG_BUILD
slouken@1895
   652
            printf("WM_SIZE : (%d %d)\n",
slouken@1895
   653
                   SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
slouken@1895
   654
            fflush(stdout);
icculus@1190
   655
#endif
slouken@1895
   656
            iWindowSizeX = SHORT1FROMMP(mp2);
slouken@1895
   657
            iWindowSizeY = SHORT2FROMMP(mp2);
slouken@1895
   658
            bWindowResized = 1;
slouken@1895
   659
slouken@1895
   660
            // Make sure the window will be redrawn
slouken@1895
   661
            WinInvalidateRegion(hwnd, NULL, TRUE);
slouken@1895
   662
        }
slouken@1895
   663
        break;
icculus@1190
   664
icculus@1190
   665
    case WM_FSLIBNOTIFICATION:
icculus@1190
   666
#ifdef DEBUG_BUILD
slouken@1895
   667
        printf("WM_FSLIBNOTIFICATION\n");
slouken@1895
   668
        fflush(stdout);
icculus@1190
   669
#endif
slouken@1895
   670
        if ((int) mp1 == FSLN_TOGGLEFSMODE) {
slouken@1895
   671
            // FS mode changed, reblit image!
slouken@1895
   672
            pVideo = FSLib_GetUserParm(hwnd);
slouken@1895
   673
            if (pVideo) {
slouken@1895
   674
                if (!pVideo->hidden->pSDLSurface) {
slouken@1895
   675
                    // Resizable surface and in resizing!
slouken@1895
   676
                    // So, don't blit now!
icculus@1190
   677
#ifdef DEBUG_BUILD
slouken@1895
   678
                    printf
slouken@1895
   679
                        ("WM_FSLIBNOTIFICATION : Can not blit if there is no surface, doing nothing.\n");
slouken@1895
   680
                    fflush(stdout);
icculus@1190
   681
#endif
slouken@1895
   682
                } else {
slouken@1895
   683
                    if (DosRequestMutexSem
slouken@1895
   684
                        (pVideo->hidden->hmtxUseSrcBuffer,
slouken@1895
   685
                         1000) == NO_ERROR) {
slouken@1895
   686
                        if (pVideo->hidden->pSDLSurface) {
icculus@1190
   687
#ifndef RESIZE_EVEN_IF_RESIZABLE
slouken@1895
   688
                            SWP swp;
slouken@1895
   689
slouken@1895
   690
                            // But only blit if the window is not resizable, or if
slouken@1895
   691
                            // the window is resizable and the source buffer size is the
slouken@1895
   692
                            // same as the destination buffer size!
slouken@1895
   693
                            WinQueryWindowPos(hwnd, &swp);
slouken@1895
   694
                            if ((!pVideo->hidden->pSDLSurface) ||
slouken@1895
   695
                                ((pVideo->hidden->pSDLSurface) &&
slouken@1895
   696
                                 (pVideo->hidden->pSDLSurface->
slouken@1895
   697
                                  flags & SDL_RESIZABLE)
slouken@1895
   698
                                 &&
slouken@1895
   699
                                 ((swp.cx !=
slouken@1895
   700
                                   pVideo->hidden->SrcBufferDesc.
slouken@1895
   701
                                   uiXResolution)
slouken@1895
   702
                                  || (swp.cy !=
slouken@1895
   703
                                      pVideo->hidden->
slouken@1895
   704
                                      SrcBufferDesc.uiYResolution))
slouken@1895
   705
                                 && (!FSLib_QueryFSMode(hwnd)))) {
slouken@1895
   706
                                // Resizable surface and in resizing!
slouken@1895
   707
                                // So, don't blit now!
slouken@1895
   708
#ifdef DEBUG_BUILD
slouken@1895
   709
                                printf
slouken@1895
   710
                                    ("WM_FSLIBNOTIFICATION : Cannot blit while resizing, doing nothing.\n");
slouken@1895
   711
                                fflush(stdout);
slouken@1895
   712
#endif
slouken@1895
   713
                            } else
slouken@1895
   714
#endif
slouken@1895
   715
                            {
slouken@1895
   716
#ifdef DEBUG_BUILD
slouken@1895
   717
                                printf("WM_FSLIBNOTIFICATION : Blitting!\n");
slouken@1895
   718
                                fflush(stdout);
slouken@1895
   719
#endif
slouken@1895
   720
                                FSLIB_BITBLT(hwnd,
slouken@1895
   721
                                             pVideo->hidden->
slouken@1895
   722
                                             pchSrcBuffer, 0,
slouken@1895
   723
                                             0,
slouken@1895
   724
                                             pVideo->hidden->
slouken@1895
   725
                                             SrcBufferDesc.
slouken@1895
   726
                                             uiXResolution,
slouken@1895
   727
                                             pVideo->hidden->
slouken@1895
   728
                                             SrcBufferDesc.uiYResolution);
slouken@1895
   729
                            }
slouken@1895
   730
                        }
slouken@1895
   731
#ifdef DEBUG_BUILD
slouken@1895
   732
                        else
slouken@1895
   733
                            printf
slouken@1895
   734
                                ("WM_FSLIBNOTIFICATION : No public surface!\n");
slouken@1895
   735
                        fflush(stdout);
slouken@1895
   736
#endif
slouken@1895
   737
slouken@1895
   738
                        DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer);
slouken@1895
   739
                    }
slouken@1895
   740
                }
slouken@1895
   741
            }
slouken@1895
   742
        }
slouken@1895
   743
        return (MPARAM) 1;
slouken@1895
   744
slouken@1895
   745
    case WM_ACTIVATE:
slouken@1895
   746
#ifdef DEBUG_BUILD
slouken@1895
   747
        printf("WM_ACTIVATE\n");
slouken@1895
   748
        fflush(stdout);
slouken@1895
   749
#endif
slouken@1895
   750
slouken@1895
   751
        pVideo = FSLib_GetUserParm(hwnd);
slouken@1895
   752
        if (pVideo) {
slouken@1895
   753
            pVideo->hidden->fInFocus = (int) mp1;
slouken@1895
   754
            if (pVideo->hidden->fInFocus) {
slouken@1895
   755
                // Went into focus
slouken@1895
   756
                if ((pVideo->hidden->iMouseVisible)
slouken@1895
   757
                    && (!bMouseCaptured))
slouken@1895
   758
                    WinSetPointer(HWND_DESKTOP,
slouken@1895
   759
                                  WinQuerySysPointer(HWND_DESKTOP,
slouken@1895
   760
                                                     SPTR_ARROW, FALSE));
slouken@1895
   761
                else
slouken@1895
   762
                    WinSetPointer(HWND_DESKTOP, NULL);
slouken@1895
   763
slouken@1895
   764
                if (bMouseCapturable) {
slouken@1895
   765
                    // Re-capture the mouse, if we captured it before!
slouken@1895
   766
                    WinSetCapture(HWND_DESKTOP, hwnd);
slouken@1895
   767
                    bMouseCaptured = 1;
slouken@1895
   768
                    {
slouken@1895
   769
                        SWP swpClient;
slouken@1895
   770
                        POINTL ptl;
slouken@1895
   771
                        // Center the mouse to the middle of the window!
slouken@1895
   772
                        WinQueryWindowPos(pVideo->hidden->hwndClient,
slouken@1895
   773
                                          &swpClient);
slouken@1895
   774
                        ptl.x = 0;
slouken@1895
   775
                        ptl.y = 0;
slouken@1895
   776
                        WinMapWindowPoints(pVideo->hidden->
slouken@1895
   777
                                           hwndClient, HWND_DESKTOP, &ptl, 1);
slouken@1895
   778
                        pVideo->hidden->iSkipWMMOUSEMOVE++;     /* Don't take next WM_MOUSEMOVE into account!  */
slouken@1895
   779
                        WinSetPointerPos(HWND_DESKTOP,
slouken@1895
   780
                                         ptl.x + swpClient.cx / 2,
slouken@1895
   781
                                         ptl.y + swpClient.cy / 2);
slouken@1895
   782
                    }
slouken@1895
   783
                }
slouken@1895
   784
            } else {
slouken@1895
   785
                // Went out of focus
slouken@1895
   786
                WinSetPointer(HWND_DESKTOP,
slouken@1895
   787
                              WinQuerySysPointer(HWND_DESKTOP,
slouken@1895
   788
                                                 SPTR_ARROW, FALSE));
slouken@1895
   789
slouken@1895
   790
                if (bMouseCaptured) {
slouken@1895
   791
                    // Release the mouse
slouken@1895
   792
                    WinSetCapture(HWND_DESKTOP, hwnd);
slouken@1895
   793
                    bMouseCaptured = 0;
slouken@1895
   794
                }
slouken@1895
   795
            }
slouken@1895
   796
        }
slouken@1895
   797
#ifdef DEBUG_BUILD
slouken@1895
   798
        printf("WM_ACTIVATE done\n");
slouken@1895
   799
        fflush(stdout);
slouken@1895
   800
#endif
slouken@1895
   801
slouken@1895
   802
        break;
slouken@1895
   803
slouken@1895
   804
    case WM_BUTTON1DOWN:
slouken@1895
   805
#ifdef DEBUG_BUILD
slouken@1895
   806
        printf("WM_BUTTON1DOWN\n");
slouken@1895
   807
        fflush(stdout);
slouken@1895
   808
#endif
slouken@1895
   809
slouken@1895
   810
        pVideo = FSLib_GetUserParm(hwnd);
slouken@1895
   811
        if (pVideo) {
slouken@1895
   812
            SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0); // Don't report mouse movement!
slouken@1895
   813
slouken@1895
   814
            if (bMouseCapturable) {
slouken@1895
   815
                // We should capture the mouse!
slouken@1895
   816
                if (!bMouseCaptured) {
slouken@1895
   817
                    WinSetCapture(HWND_DESKTOP, hwnd);
slouken@1895
   818
                    WinSetPointer(HWND_DESKTOP, NULL);
slouken@1895
   819
                    bMouseCaptured = 1;
slouken@1895
   820
                    {
slouken@1895
   821
                        SWP swpClient;
slouken@1895
   822
                        POINTL ptl;
slouken@1895
   823
                        // Center the mouse to the middle of the window!
slouken@1895
   824
                        WinQueryWindowPos(pVideo->hidden->hwndClient,
slouken@1895
   825
                                          &swpClient);
slouken@1895
   826
                        ptl.x = 0;
slouken@1895
   827
                        ptl.y = 0;
slouken@1895
   828
                        WinMapWindowPoints(pVideo->hidden->
slouken@1895
   829
                                           hwndClient, HWND_DESKTOP, &ptl, 1);
slouken@1895
   830
                        pVideo->hidden->iSkipWMMOUSEMOVE++;     /* Don't take next WM_MOUSEMOVE into account!  */
slouken@1895
   831
                        WinSetPointerPos(HWND_DESKTOP,
slouken@1895
   832
                                         ptl.x + swpClient.cx / 2,
slouken@1895
   833
                                         ptl.y + swpClient.cy / 2);
slouken@1895
   834
                    }
slouken@1895
   835
                }
slouken@1895
   836
            }
slouken@1895
   837
        }
slouken@1895
   838
        break;
slouken@1895
   839
    case WM_BUTTON1UP:
slouken@1895
   840
#ifdef DEBUG_BUILD
slouken@1895
   841
        printf("WM_BUTTON1UP\n");
slouken@1895
   842
        fflush(stdout);
slouken@1895
   843
#endif
slouken@1895
   844
        SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);    // Don't report mouse movement!
slouken@1895
   845
        break;
slouken@1895
   846
    case WM_BUTTON2DOWN:
slouken@1895
   847
#ifdef DEBUG_BUILD
slouken@1895
   848
        printf("WM_BUTTON2DOWN\n");
slouken@1895
   849
        fflush(stdout);
slouken@1895
   850
#endif
slouken@1895
   851
slouken@1895
   852
        pVideo = FSLib_GetUserParm(hwnd);
slouken@1895
   853
        if (pVideo) {
slouken@1895
   854
            SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);        // Don't report mouse movement!
slouken@1895
   855
slouken@1895
   856
            if (bMouseCapturable) {
slouken@1895
   857
                // We should capture the mouse!
slouken@1895
   858
                if (!bMouseCaptured) {
slouken@1895
   859
                    WinSetCapture(HWND_DESKTOP, hwnd);
slouken@1895
   860
                    WinSetPointer(HWND_DESKTOP, NULL);
slouken@1895
   861
                    bMouseCaptured = 1;
slouken@1895
   862
                    {
slouken@1895
   863
                        SWP swpClient;
slouken@1895
   864
                        POINTL ptl;
slouken@1895
   865
                        // Center the mouse to the middle of the window!
slouken@1895
   866
                        WinQueryWindowPos(pVideo->hidden->hwndClient,
slouken@1895
   867
                                          &swpClient);
slouken@1895
   868
                        ptl.x = 0;
slouken@1895
   869
                        ptl.y = 0;
slouken@1895
   870
                        WinMapWindowPoints(pVideo->hidden->
slouken@1895
   871
                                           hwndClient, HWND_DESKTOP, &ptl, 1);
slouken@1895
   872
                        pVideo->hidden->iSkipWMMOUSEMOVE++;     /* Don't take next WM_MOUSEMOVE into account!  */
slouken@1895
   873
                        WinSetPointerPos(HWND_DESKTOP,
slouken@1895
   874
                                         ptl.x + swpClient.cx / 2,
slouken@1895
   875
                                         ptl.y + swpClient.cy / 2);
slouken@1895
   876
                    }
slouken@1895
   877
                }
slouken@1895
   878
            }
slouken@1895
   879
slouken@1895
   880
        }
slouken@1895
   881
        break;
slouken@1895
   882
    case WM_BUTTON2UP:
slouken@1895
   883
#ifdef DEBUG_BUILD
slouken@1895
   884
        printf("WM_BUTTON2UP\n");
slouken@1895
   885
        fflush(stdout);
slouken@1895
   886
#endif
slouken@1895
   887
        SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);   // Don't report mouse movement!
slouken@1895
   888
        break;
slouken@1895
   889
    case WM_BUTTON3DOWN:
slouken@1895
   890
#ifdef DEBUG_BUILD
slouken@1895
   891
        printf("WM_BUTTON3DOWN\n");
slouken@1895
   892
        fflush(stdout);
slouken@1895
   893
#endif
slouken@1895
   894
slouken@1895
   895
        pVideo = FSLib_GetUserParm(hwnd);
slouken@1895
   896
        if (pVideo) {
slouken@1895
   897
            SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0);       // Don't report mouse movement!
slouken@1895
   898
slouken@1895
   899
            if (bMouseCapturable) {
slouken@1895
   900
                // We should capture the mouse!
slouken@1895
   901
                if (!bMouseCaptured) {
slouken@1895
   902
                    WinSetCapture(HWND_DESKTOP, hwnd);
slouken@1895
   903
                    WinSetPointer(HWND_DESKTOP, NULL);
slouken@1895
   904
                    bMouseCaptured = 1;
slouken@1895
   905
                    {
slouken@1895
   906
                        SWP swpClient;
slouken@1895
   907
                        POINTL ptl;
slouken@1895
   908
                        // Center the mouse to the middle of the window!
slouken@1895
   909
                        WinQueryWindowPos(pVideo->hidden->hwndClient,
slouken@1895
   910
                                          &swpClient);
slouken@1895
   911
                        ptl.x = 0;
slouken@1895
   912
                        ptl.y = 0;
slouken@1895
   913
                        WinMapWindowPoints(pVideo->hidden->
slouken@1895
   914
                                           hwndClient, HWND_DESKTOP, &ptl, 1);
slouken@1895
   915
                        pVideo->hidden->iSkipWMMOUSEMOVE++;     /* Don't take next WM_MOUSEMOVE into account!  */
slouken@1895
   916
                        WinSetPointerPos(HWND_DESKTOP,
slouken@1895
   917
                                         ptl.x + swpClient.cx / 2,
slouken@1895
   918
                                         ptl.y + swpClient.cy / 2);
slouken@1895
   919
                    }
slouken@1895
   920
                }
slouken@1895
   921
            }
slouken@1895
   922
        }
slouken@1895
   923
        break;
slouken@1895
   924
    case WM_BUTTON3UP:
slouken@1895
   925
#ifdef DEBUG_BUILD
slouken@1895
   926
        printf("WM_BUTTON3UP\n");
slouken@1895
   927
        fflush(stdout);
slouken@1895
   928
#endif
slouken@1895
   929
        SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);  // Don't report mouse movement!
slouken@1895
   930
        break;
slouken@1895
   931
    case WM_MOUSEMOVE:
slouken@1895
   932
#ifdef DEBUG_BUILD
slouken@1895
   933
//      printf("WM_MOUSEMOVE\n"); fflush(stdout);
slouken@1895
   934
#endif
slouken@1895
   935
slouken@1895
   936
        pVideo = FSLib_GetUserParm(hwnd);
slouken@1895
   937
        if (pVideo) {
slouken@1895
   938
            if (pVideo->hidden->iSkipWMMOUSEMOVE) {
slouken@1895
   939
                pVideo->hidden->iSkipWMMOUSEMOVE--;
slouken@1895
   940
            } else {
slouken@1895
   941
                POINTS *ppts = (POINTS *) (&mp1);
slouken@1895
   942
                POINTL ptl;
slouken@1895
   943
slouken@1895
   944
                if (bMouseCaptured) {
slouken@1895
   945
                    SWP swpClient;
slouken@1895
   946
slouken@1895
   947
                    WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient);
slouken@1895
   948
slouken@1895
   949
                    // Send relative mouse position, and re-center the mouse
slouken@1895
   950
                    // Reposition the mouse to the center of the screen/window
slouken@1895
   951
                    SDL_PrivateMouseMotion(0,   // Buttons not changed
slouken@1895
   952
                                           1,   // Relative position
slouken@1895
   953
                                           ppts->x -
slouken@1895
   954
                                           (swpClient.cx / 2),
slouken@1895
   955
                                           (swpClient.cy / 2) - ppts->y);
slouken@1895
   956
slouken@1895
   957
                    ptl.x = 0;
slouken@1895
   958
                    ptl.y = 0;
slouken@1895
   959
                    WinMapWindowPoints(pVideo->hidden->hwndClient,
slouken@1895
   960
                                       HWND_DESKTOP, &ptl, 1);
slouken@1895
   961
                    pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account!  */
slouken@1895
   962
                    // Center the mouse to the middle of the window!
slouken@1895
   963
                    WinSetPointerPos(HWND_DESKTOP,
slouken@1895
   964
                                     ptl.x + swpClient.cx / 2,
slouken@1895
   965
                                     ptl.y + swpClient.cy / 2);
slouken@1895
   966
                } else {
slouken@1895
   967
                    CONVERTMOUSEPOSITION();
slouken@1895
   968
slouken@1895
   969
                    // Send absolute mouse position
slouken@1895
   970
                    SDL_PrivateMouseMotion(0,   // Buttons not changed
slouken@1895
   971
                                           0,   // Absolute position
slouken@1895
   972
                                           ppts->x, ppts->y);
slouken@1895
   973
                }
slouken@1895
   974
            }
slouken@1895
   975
            if ((pVideo->hidden->iMouseVisible) && (!bMouseCaptured)) {
slouken@1895
   976
#ifdef DEBUG_BUILD
slouken@1895
   977
//          printf("WM_MOUSEMOVE : ptr = %p\n", hptrGlobalPointer); fflush(stdout);
slouken@1895
   978
#endif
slouken@1895
   979
slouken@1895
   980
                if (hptrGlobalPointer)
slouken@1895
   981
                    WinSetPointer(HWND_DESKTOP, hptrGlobalPointer);
slouken@1895
   982
                else
slouken@1895
   983
                    WinSetPointer(HWND_DESKTOP,
slouken@1895
   984
                                  WinQuerySysPointer(HWND_DESKTOP,
slouken@1895
   985
                                                     SPTR_ARROW, FALSE));
slouken@1895
   986
            } else {
slouken@1895
   987
                WinSetPointer(HWND_DESKTOP, NULL);
slouken@1895
   988
            }
slouken@1895
   989
        }
slouken@1895
   990
#ifdef DEBUG_BUILD
slouken@1895
   991
//      printf("WM_MOUSEMOVE done\n"); fflush(stdout);
slouken@1895
   992
#endif
slouken@1895
   993
slouken@1895
   994
        return (MRESULT) FALSE;
slouken@1895
   995
    case WM_CLOSE:             // Window close
slouken@1895
   996
#ifdef DEBUG_BUILD
slouken@1895
   997
        printf("WM_CLOSE\n");
slouken@1895
   998
        fflush(stdout);
slouken@1895
   999
#endif
slouken@1895
  1000
slouken@1895
  1001
        pVideo = FSLib_GetUserParm(hwnd);
slouken@1895
  1002
        if (pVideo) {
slouken@1895
  1003
            // Send Quit message to the SDL application!
slouken@1895
  1004
            SDL_PrivateQuit();
slouken@1895
  1005
            return 0;
slouken@1895
  1006
        }
slouken@1895
  1007
        break;
slouken@1895
  1008
slouken@1895
  1009
#ifdef BITBLT_IN_WINMESSAGEPROC
slouken@1895
  1010
    case WM_UPDATERECTSREQUEST:
slouken@1895
  1011
        pVideo = FSLib_GetUserParm(hwnd);
slouken@1895
  1012
        if ((pVideo) && (pVideo->hidden->pSDLSurface)) {
slouken@1895
  1013
            if (DosRequestMutexSem
slouken@1895
  1014
                (pVideo->hidden->hmtxUseSrcBuffer,
slouken@1895
  1015
                 SEM_INDEFINITE_WAIT) == NO_ERROR) {
slouken@1895
  1016
                int numrects;
slouken@1895
  1017
                SDL_Rect *rects;
slouken@1895
  1018
                int i;
icculus@1190
  1019
                SWP swp;
icculus@1190
  1020
slouken@1895
  1021
                numrects = (int) mp1;
slouken@1895
  1022
                rects = (SDL_Rect *) mp2;
slouken@1895
  1023
icculus@1190
  1024
                WinQueryWindowPos(hwnd, &swp);
slouken@1895
  1025
#ifndef RESIZE_EVEN_IF_RESIZABLE
icculus@1190
  1026
                if ((!pVideo->hidden->pSDLSurface) ||
slouken@1895
  1027
                    ((pVideo->hidden->pSDLSurface) &&
slouken@1895
  1028
                     (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE)
slouken@1895
  1029
                     &&
slouken@1895
  1030
                     ((swp.cx != pVideo->hidden->SrcBufferDesc.uiXResolution)
slouken@1895
  1031
                      || (swp.cy !=
slouken@1895
  1032
                          pVideo->hidden->SrcBufferDesc.uiYResolution))
slouken@1895
  1033
                     && (!FSLib_QueryFSMode(hwnd)))) {
slouken@1895
  1034
                    // Resizable surface and in resizing!
slouken@1895
  1035
                    // So, don't blit now!
icculus@1190
  1036
#ifdef DEBUG_BUILD
slouken@1895
  1037
                    printf
slouken@1895
  1038
                        ("[WM_UPDATERECTSREQUEST] : Skipping blit while resizing!\n");
slouken@1895
  1039
                    fflush(stdout);
icculus@1190
  1040
#endif
icculus@1190
  1041
                } else
icculus@1190
  1042
#endif
icculus@1190
  1043
                {
icculus@1190
  1044
#ifdef DEBUG_BUILD
slouken@1895
  1045
                    printf("[WM_UPDATERECTSREQUEST] : Blitting!\n");
slouken@1895
  1046
                    fflush(stdout);
icculus@1190
  1047
#endif
icculus@1190
  1048
slouken@1895
  1049
                    // Blit the changed areas
slouken@1895
  1050
                    for (i = 0; i < numrects; i++)
slouken@1895
  1051
                        FSLIB_BITBLT(hwnd,
slouken@1895
  1052
                                     pVideo->hidden->pchSrcBuffer,
slouken@1895
  1053
                                     rects[i].y, rects[i].x,
slouken@1895
  1054
                                     rects[i].w, rects[i].h);
slouken@1895
  1055
                }
slouken@1895
  1056
                DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer);
icculus@1190
  1057
            }
slouken@1442
  1058
        }
icculus@1190
  1059
        return 0;
icculus@1190
  1060
#endif
icculus@1190
  1061
icculus@1190
  1062
    default:
icculus@1190
  1063
#ifdef DEBUG_BUILD
slouken@1895
  1064
        printf("Unhandled: %x\n", msg);
slouken@1895
  1065
        fflush(stdout);
icculus@1190
  1066
#endif
icculus@1190
  1067
slouken@1895
  1068
        break;
slouken@1895
  1069
    }
slouken@1895
  1070
    // Run the default window procedure for unhandled stuffs
slouken@1895
  1071
    return WinDefWindowProc(hwnd, msg, mp1, mp2);
icculus@1190
  1072
}
icculus@1190
  1073
icculus@1190
  1074
/////////////////////////////////////////////////////////////////////
icculus@1190
  1075
//
slouken@1442
  1076
// FrameWndProc
slouken@1442
  1077
//
slouken@1442
  1078
// This is the message processing window procedure for the
slouken@1442
  1079
// frame window of SDLWindowClass.
slouken@1442
  1080
//
slouken@1442
  1081
/////////////////////////////////////////////////////////////////////
slouken@1895
  1082
static MRESULT EXPENTRY
slouken@1895
  1083
FrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
slouken@1442
  1084
{
slouken@1895
  1085
    PFNWP pOldFrameProc;
slouken@1895
  1086
    MRESULT result;
slouken@1895
  1087
    PTRACKINFO ti;
slouken@1895
  1088
    int cx, cy, ncx, ncy;
slouken@1895
  1089
    RECTL rclTemp;
slouken@1895
  1090
    PSWP pswpTemp;
slouken@1895
  1091
slouken@1895
  1092
    SDL_VideoDevice *pVideo = NULL;
slouken@1895
  1093
slouken@1895
  1094
    pVideo = (SDL_VideoDevice *) WinQueryWindowULong(hwnd, QWL_USER);
slouken@1895
  1095
slouken@1895
  1096
    pOldFrameProc = pVideo->hidden->pfnOldFrameProc;
slouken@1895
  1097
slouken@1895
  1098
    if ((pVideo->hidden->bProportionalResize) &&
slouken@1895
  1099
        (msg == WM_ADJUSTWINDOWPOS) &&
slouken@1895
  1100
        (!FSLib_QueryFSMode(pVideo->hidden->hwndClient))) {
slouken@1895
  1101
        pswpTemp = (PSWP) mp1;
slouken@1895
  1102
slouken@1895
  1103
        /* Resizing? */
slouken@1895
  1104
        if (pswpTemp->fl & SWP_SIZE) {
slouken@1895
  1105
            /* Calculate client size */
slouken@1895
  1106
            rclTemp.xLeft = pswpTemp->x;
slouken@1895
  1107
            rclTemp.xRight = pswpTemp->x + pswpTemp->cx;
slouken@1895
  1108
            rclTemp.yBottom = pswpTemp->y;
slouken@1895
  1109
            rclTemp.yTop = pswpTemp->y + pswpTemp->cy;
slouken@1895
  1110
            WinCalcFrameRect(hwnd, &rclTemp, TRUE);
slouken@1895
  1111
slouken@1895
  1112
            ncx = cx = rclTemp.xRight - rclTemp.xLeft;
slouken@1895
  1113
            ncy = cy = rclTemp.yTop - rclTemp.yBottom;
slouken@1895
  1114
slouken@1895
  1115
            /* Calculate new size to keep it proportional */
slouken@1895
  1116
slouken@1895
  1117
            if ((pVideo->hidden->ulResizingFlag & TF_LEFT)
slouken@1895
  1118
                || (pVideo->hidden->ulResizingFlag & TF_RIGHT)) {
slouken@1895
  1119
                /* The window is resized horizontally */
slouken@1895
  1120
                ncy =
slouken@1895
  1121
                    pVideo->hidden->SrcBufferDesc.uiYResolution * cx /
slouken@1895
  1122
                    pVideo->hidden->SrcBufferDesc.uiXResolution;
slouken@1895
  1123
            } else if ((pVideo->hidden->ulResizingFlag & TF_TOP)
slouken@1895
  1124
                       || (pVideo->hidden->ulResizingFlag & TF_BOTTOM)) {
slouken@1895
  1125
                /* The window is resized vertically */
slouken@1895
  1126
                ncx =
slouken@1895
  1127
                    pVideo->hidden->SrcBufferDesc.uiXResolution * cy /
slouken@1895
  1128
                    pVideo->hidden->SrcBufferDesc.uiYResolution;
slouken@1895
  1129
            }
slouken@1895
  1130
slouken@1895
  1131
            /* Calculate back frame coordinates */
slouken@1895
  1132
            rclTemp.xLeft = pswpTemp->x;
slouken@1895
  1133
            rclTemp.xRight = pswpTemp->x + ncx;
slouken@1895
  1134
            rclTemp.yBottom = pswpTemp->y;
slouken@1895
  1135
            rclTemp.yTop = pswpTemp->y + ncy;
slouken@1895
  1136
            WinCalcFrameRect(hwnd, &rclTemp, FALSE);
slouken@1895
  1137
slouken@1895
  1138
            /* Store new size/position info */
slouken@1895
  1139
            pswpTemp->cx = rclTemp.xRight - rclTemp.xLeft;
slouken@1895
  1140
slouken@1895
  1141
            if (!(pVideo->hidden->ulResizingFlag & TF_TOP)) {
slouken@1895
  1142
                pswpTemp->y =
slouken@1895
  1143
                    pswpTemp->y + pswpTemp->cy - (rclTemp.yTop -
slouken@1895
  1144
                                                  rclTemp.yBottom);
slouken@1895
  1145
                pswpTemp->cy = rclTemp.yTop - rclTemp.yBottom;
slouken@1895
  1146
            } else {
slouken@1895
  1147
                pswpTemp->cy = rclTemp.yTop - rclTemp.yBottom;
slouken@1895
  1148
            }
slouken@1895
  1149
        }
slouken@1442
  1150
    }
slouken@1895
  1151
slouken@1895
  1152
    result = (*pOldFrameProc) (hwnd, msg, mp1, mp2);
slouken@1895
  1153
slouken@1895
  1154
    if ((pVideo->hidden->bProportionalResize) && (msg == WM_QUERYTRACKINFO)) {
slouken@1895
  1155
        ti = (PTRACKINFO) mp2;
slouken@1895
  1156
slouken@1895
  1157
        /* Store the direction of resizing */
slouken@1895
  1158
        if ((ti->fs & TF_LEFT) || (ti->fs & TF_RIGHT) ||
slouken@1895
  1159
            (ti->fs & TF_TOP) || (ti->fs & TF_BOTTOM))
slouken@1895
  1160
            pVideo->hidden->ulResizingFlag = ti->fs;
slouken@1895
  1161
    }
slouken@1895
  1162
slouken@1895
  1163
    return result;
slouken@1442
  1164
}
slouken@1442
  1165
slouken@1442
  1166
/////////////////////////////////////////////////////////////////////
slouken@1442
  1167
//
icculus@1190
  1168
// PMThreadFunc
icculus@1190
  1169
//
icculus@1190
  1170
// This function implements the PM-Thread, which initializes the
icculus@1190
  1171
// application window itself, the DIVE, and start message processing.
icculus@1190
  1172
//
icculus@1190
  1173
/////////////////////////////////////////////////////////////////////
slouken@1895
  1174
int iNumOfPMThreadInstances = 0;        // Global!
slouken@1895
  1175
static void
slouken@1895
  1176
PMThreadFunc(void *pParm)
icculus@1190
  1177
{
slouken@1895
  1178
    SDL_VideoDevice *pVideo = pParm;
slouken@1895
  1179
    HAB hab;
slouken@1895
  1180
    HMQ hmq;
slouken@1895
  1181
    QMSG msg;
slouken@1895
  1182
    ULONG fcf;
icculus@1190
  1183
icculus@1190
  1184
#ifdef DEBUG_BUILD
slouken@1895
  1185
    printf("[PMThreadFunc] : Starting\n");
icculus@1190
  1186
    fflush(stdout);
icculus@1190
  1187
#endif
icculus@1190
  1188
slouken@1895
  1189
    iNumOfPMThreadInstances++;
slouken@1895
  1190
slouken@1895
  1191
    // Initialize PM, create a message queue.
slouken@1895
  1192
slouken@1895
  1193
    hab = WinInitialize(0);
slouken@1895
  1194
    hmq = WinCreateMsgQueue(hab, 0);
slouken@1895
  1195
    if (hmq == 0) {
icculus@1190
  1196
#ifdef DEBUG_BUILD
slouken@1895
  1197
        printf("[PMThreadFunc] : Could not create message queue!\n");
slouken@1895
  1198
        printf
slouken@1895
  1199
            ("                 It might be that the application using SDL is not a PM app!\n");
slouken@1895
  1200
        fflush(stdout);
icculus@1190
  1201
#endif
slouken@1895
  1202
        pVideo->hidden->iPMThreadStatus = 2;
slouken@1895
  1203
    } else {
slouken@1895
  1204
        int rc;
slouken@1895
  1205
        RECTL rectl;
slouken@1895
  1206
slouken@1895
  1207
        fcf = ulFCFToUse;       // Get from global setting
slouken@1442
  1208
icculus@1190
  1209
#ifdef DEBUG_BUILD
slouken@1895
  1210
        printf("[PMThreadFunc] : FSLib_CreateWindow()!\n");
slouken@1895
  1211
        fflush(stdout);
icculus@1190
  1212
#endif
slouken@1895
  1213
slouken@1895
  1214
        rc = FSLib_CreateWindow(HWND_DESKTOP, 0, &fcf,
slouken@1895
  1215
                                "SDL Application",
slouken@1895
  1216
                                NULLHANDLE, 0,
slouken@1895
  1217
                                &(pVideo->hidden->SrcBufferDesc),
slouken@1895
  1218
                                WndProc,
slouken@1895
  1219
                                &(pVideo->hidden->hwndClient),
slouken@1895
  1220
                                &(pVideo->hidden->hwndFrame));
icculus@1190
  1221
icculus@1190
  1222
#ifdef DEBUG_BUILD
slouken@1895
  1223
        printf("[PMThreadFunc] : FSLib_CreateWindow() rc = %d\n", rc);
slouken@1895
  1224
        fflush(stdout);
slouken@1895
  1225
#endif
slouken@1895
  1226
slouken@1895
  1227
        if (!rc) {
slouken@1895
  1228
#ifdef DEBUG_BUILD
slouken@1895
  1229
            printf("[PMThreadFunc] : Could not create FSLib window!\n");
slouken@1895
  1230
            fflush(stdout);
slouken@1895
  1231
#endif
slouken@1895
  1232
            pVideo->hidden->iPMThreadStatus = 3;
slouken@1895
  1233
        } else {
slouken@1895
  1234
#ifdef DEBUG_BUILD
slouken@1895
  1235
            printf("[PMThreadFunc] : FSLib_AddUserParm()!\n");
slouken@1895
  1236
            fflush(stdout);
slouken@1895
  1237
#endif
slouken@1895
  1238
slouken@1895
  1239
            // Store pVideo pointer in window data for client window, so
slouken@1895
  1240
            // it will know the instance to which it belongs to.
slouken@1895
  1241
            FSLib_AddUserParm(pVideo->hidden->hwndClient, pVideo);
slouken@1895
  1242
slouken@1895
  1243
            // Now set default image width height and fourcc!
slouken@1895
  1244
#ifdef DEBUG_BUILD
slouken@1895
  1245
            printf("[PMThreadFunc] : SetWindowPos()!\n");
slouken@1895
  1246
            fflush(stdout);
icculus@1190
  1247
#endif
slouken@1895
  1248
slouken@1895
  1249
            // Set the position and size of the main window,
slouken@1895
  1250
            // and make it visible!
slouken@1895
  1251
            // Calculate frame window size from client window size
slouken@1895
  1252
            rectl.xLeft = 0;
slouken@1895
  1253
            rectl.yBottom = 0;
slouken@1895
  1254
            rectl.xRight = pVideo->hidden->SrcBufferDesc.uiXResolution; // Noninclusive
slouken@1895
  1255
            rectl.yTop = pVideo->hidden->SrcBufferDesc.uiYResolution;   // Noninclusive
slouken@1895
  1256
            WinCalcFrameRect(pVideo->hidden->hwndFrame, &rectl, FALSE);
slouken@1895
  1257
slouken@1895
  1258
            SetAccessableWindowPos(pVideo->hidden->hwndFrame,
slouken@1895
  1259
                                   HWND_TOP,
slouken@1895
  1260
                                   (WinQuerySysValue
slouken@1895
  1261
                                    (HWND_DESKTOP,
slouken@1895
  1262
                                     SV_CXSCREEN) - (rectl.xRight -
slouken@1895
  1263
                                                     rectl.xLeft)) / 2,
slouken@1895
  1264
                                   (WinQuerySysValue
slouken@1895
  1265
                                    (HWND_DESKTOP,
slouken@1895
  1266
                                     SV_CYSCREEN) - (rectl.yTop -
slouken@1895
  1267
                                                     rectl.yBottom)) / 2,
slouken@1895
  1268
                                   (rectl.xRight - rectl.xLeft),
slouken@1895
  1269
                                   (rectl.yTop - rectl.yBottom),
slouken@1895
  1270
                                   SWP_SIZE | SWP_ACTIVATE | SWP_SHOW |
slouken@1895
  1271
                                   SWP_MOVE);
slouken@1895
  1272
slouken@1895
  1273
            // Subclass frame procedure and store old window proc address
slouken@1895
  1274
            pVideo->hidden->pfnOldFrameProc =
slouken@1895
  1275
                WinSubclassWindow(pVideo->hidden->hwndFrame, FrameWndProc);
slouken@1895
  1276
            WinSetWindowULong(pVideo->hidden->hwndFrame, QWL_USER,
slouken@1895
  1277
                              (ULONG) pVideo);
slouken@1895
  1278
icculus@1190
  1279
#ifdef DEBUG_BUILD
slouken@1895
  1280
            printf("[PMThreadFunc] : Entering message loop\n");
slouken@1895
  1281
            fflush(stdout);
icculus@1190
  1282
#endif
slouken@1895
  1283
            pVideo->hidden->iPMThreadStatus = 1;
slouken@1895
  1284
slouken@1895
  1285
            while (WinGetMsg(hab, (PQMSG) & msg, 0, 0, 0))
slouken@1895
  1286
                WinDispatchMsg(hab, (PQMSG) & msg);
slouken@1895
  1287
slouken@1895
  1288
#ifdef DEBUG_BUILD
slouken@1895
  1289
            printf("[PMThreadFunc] : Leaving message loop\n");
slouken@1895
  1290
            fflush(stdout);
slouken@1895
  1291
#endif
slouken@1895
  1292
            // We should release the captured the mouse!
slouken@1895
  1293
            if (bMouseCaptured) {
slouken@1895
  1294
                WinSetCapture(HWND_DESKTOP, NULLHANDLE);
slouken@1895
  1295
                bMouseCaptured = 0;
slouken@1895
  1296
            }
slouken@1895
  1297
            // Destroy our window
slouken@1895
  1298
            WinDestroyWindow(pVideo->hidden->hwndFrame);
slouken@1895
  1299
            pVideo->hidden->hwndFrame = NULL;
slouken@1895
  1300
            // Show pointer to make sure it will not be left hidden.
slouken@1895
  1301
            WinSetPointer(HWND_DESKTOP,
slouken@1895
  1302
                          WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW,
slouken@1895
  1303
                                             FALSE));
slouken@1895
  1304
            WinShowPointer(HWND_DESKTOP, TRUE);
slouken@1895
  1305
        }
slouken@1895
  1306
        // Uninitialize PM
slouken@1895
  1307
        WinDestroyMsgQueue(hmq);
slouken@1895
  1308
        // All done!
slouken@1895
  1309
        pVideo->hidden->iPMThreadStatus = 0;
slouken@1895
  1310
    }
slouken@1895
  1311
    WinTerminate(hab);
slouken@1895
  1312
    /* Commented out, should not be needed anymore, because we send it
slouken@1895
  1313
       from WM_CLOSE.
slouken@1895
  1314
       // Notify SDL that it should really die now...
slouken@1895
  1315
       SDL_PrivateQuit(); SDL_PrivateQuit(); SDL_PrivateQuit(); //... :))
slouken@1895
  1316
     */
icculus@1190
  1317
#ifdef DEBUG_BUILD
slouken@1895
  1318
    printf("[PMThreadFunc] : End, status is %d!\n",
slouken@1895
  1319
           pVideo->hidden->iPMThreadStatus);
slouken@1895
  1320
    fflush(stdout);
icculus@1190
  1321
#endif
slouken@1895
  1322
slouken@1895
  1323
    iNumOfPMThreadInstances--;
slouken@1895
  1324
slouken@1895
  1325
    // HACK to prevent zombie and hanging SDL applications, which does not take
slouken@1895
  1326
    // care of closing the window for some reason:
slouken@1895
  1327
    // There are some apps which do not process messages, so do a lot of things
slouken@1895
  1328
    // without noticing that the application should close. To close these,
slouken@1895
  1329
    // I've thought about the following:
slouken@1895
  1330
    // If the window is closed (the execution came here), I wait a bit to
slouken@1895
  1331
    // give time to the app to finish its execution. If it does not, I kill it
slouken@1895
  1332
    // using DosExit(). Brute force, but should work.
slouken@1895
  1333
    if (pVideo->hidden->iPMThreadStatus == 0) {
slouken@1895
  1334
        DosSleep(5000);         // Wait 5 secs
slouken@1895
  1335
        // If a new PM thread has been spawned (reinitializing video mode), then all right.
slouken@1895
  1336
        // Otherwise, we have a problem, the app doesn't want to stop. Kill!
slouken@1895
  1337
        if (iNumOfPMThreadInstances == 0) {
slouken@1895
  1338
#ifdef DEBUG_BUILD
slouken@1895
  1339
            printf
slouken@1895
  1340
                ("[PMThreadFunc] : It seems that the application haven't terminated itself\n");
slouken@1895
  1341
            fflush(stdout);
slouken@1895
  1342
            printf
slouken@1895
  1343
                ("[PMThreadFunc] : in the last 5 seconds, so we go berserk.\n");
slouken@1895
  1344
            fflush(stdout);
slouken@1895
  1345
            printf
slouken@1895
  1346
                ("[PMThreadFunc] : Brute force mode. :) Killing process! Dieeeee...\n");
slouken@1895
  1347
            fflush(stdout);
slouken@1895
  1348
#endif
slouken@1895
  1349
            DosExit(EXIT_PROCESS, -1);
slouken@1895
  1350
        }
icculus@1190
  1351
    }
slouken@1895
  1352
    _endthread();
icculus@1190
  1353
}
icculus@1190
  1354
icculus@1190
  1355
struct WMcursor
icculus@1190
  1356
{
slouken@1895
  1357
    HBITMAP hbm;
slouken@1895
  1358
    HPOINTER hptr;
slouken@1895
  1359
    char *pchData;
icculus@1190
  1360
};
icculus@1190
  1361
icculus@1190
  1362
/* Free a window manager cursor */
slouken@1895
  1363
void
slouken@1895
  1364
os2fslib_FreeWMCursor(_THIS, WMcursor * cursor)
icculus@1190
  1365
{
slouken@1895
  1366
    if (cursor) {
slouken@1895
  1367
        GpiDeleteBitmap(cursor->hbm);
slouken@1895
  1368
        WinDestroyPointer(cursor->hptr);
slouken@1895
  1369
        SDL_free(cursor->pchData);
slouken@1895
  1370
        SDL_free(cursor);
slouken@1895
  1371
    }
icculus@1190
  1372
}
icculus@1190
  1373
icculus@1190
  1374
/* Local functions to convert the SDL cursor mask into OS/2 format */
slouken@1895
  1375
static void
slouken@1895
  1376
memnot(Uint8 * dst, Uint8 * src, int len)
icculus@1190
  1377
{
slouken@1895
  1378
    while (len-- > 0)
slouken@1895
  1379
        *dst++ = ~*src++;
icculus@1190
  1380
}
slouken@1895
  1381
static void
slouken@1895
  1382
memxor(Uint8 * dst, Uint8 * src1, Uint8 * src2, int len)
icculus@1190
  1383
{
slouken@1895
  1384
    while (len-- > 0)
slouken@1895
  1385
        *dst++ = (*src1++) ^ (*src2++);
icculus@1190
  1386
}
icculus@1190
  1387
icculus@1190
  1388
/* Create a black/white window manager cursor */
slouken@1895
  1389
WMcursor *
slouken@1895
  1390
os2fslib_CreateWMCursor_Win(_THIS, Uint8 * data, Uint8 * mask,
slouken@1895
  1391
                            int w, int h, int hot_x, int hot_y)
icculus@1190
  1392
{
slouken@1895
  1393
    HPOINTER hptr;
slouken@1895
  1394
    HBITMAP hbm;
slouken@1895
  1395
    BITMAPINFOHEADER bmih;
slouken@1895
  1396
    BMPINFO bmi;
slouken@1895
  1397
    HPS hps;
slouken@1895
  1398
    char *pchTemp;
slouken@1895
  1399
    char *xptr, *aptr;
slouken@1895
  1400
    int maxx, maxy;
slouken@1895
  1401
    int i, run, pad;
slouken@1895
  1402
    WMcursor *pResult;
slouken@1895
  1403
slouken@1895
  1404
    maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER);
slouken@1895
  1405
    maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER);
slouken@1895
  1406
slouken@1895
  1407
    // Check for max size!
slouken@1895
  1408
    if ((w > maxx) || (h > maxy))
slouken@1895
  1409
        return (WMcursor *) NULL;
slouken@1895
  1410
slouken@1895
  1411
    pResult = (WMcursor *) SDL_malloc(sizeof(WMcursor));
slouken@1895
  1412
    if (!pResult)
slouken@1895
  1413
        return (WMcursor *) NULL;
slouken@1895
  1414
slouken@1895
  1415
    pchTemp = (char *) SDL_malloc((maxx + 7) / 8 * maxy * 2);
slouken@1895
  1416
    if (!pchTemp) {
slouken@1895
  1417
        SDL_free(pResult);
slouken@1895
  1418
        return (WMcursor *) NULL;
slouken@1895
  1419
    }
slouken@1895
  1420
slouken@1895
  1421
    SDL_memset(pchTemp, 0, (maxx + 7) / 8 * maxy * 2);
slouken@1895
  1422
slouken@1895
  1423
    hps = WinGetPS(_this->hidden->hwndClient);
slouken@1895
  1424
slouken@1895
  1425
    bmi.cbFix = sizeof(BITMAPINFOHEADER);
slouken@1895
  1426
    bmi.cx = maxx;
slouken@1895
  1427
    bmi.cy = 2 * maxy;
slouken@1895
  1428
    bmi.cPlanes = 1;
slouken@1895
  1429
    bmi.cBitCount = 1;
slouken@1895
  1430
    bmi.argbColor[0].bBlue = 0x00;
slouken@1895
  1431
    bmi.argbColor[0].bGreen = 0x00;
slouken@1895
  1432
    bmi.argbColor[0].bRed = 0x00;
slouken@1895
  1433
    bmi.argbColor[1].bBlue = 0x00;
slouken@1895
  1434
    bmi.argbColor[1].bGreen = 0x00;
slouken@1895
  1435
    bmi.argbColor[1].bRed = 0xff;
slouken@1895
  1436
slouken@1895
  1437
    SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
slouken@1895
  1438
    bmih.cbFix = sizeof(BITMAPINFOHEADER);
slouken@1895
  1439
    bmih.cx = maxx;
slouken@1895
  1440
    bmih.cy = 2 * maxy;
slouken@1895
  1441
    bmih.cPlanes = 1;
slouken@1895
  1442
    bmih.cBitCount = 1;
slouken@1895
  1443
slouken@1895
  1444
    run = (w + 7) / 8;
slouken@1895
  1445
    pad = (maxx + 7) / 8 - run;
slouken@1895
  1446
slouken@1895
  1447
    for (i = 0; i < h; i++) {
slouken@1895
  1448
        xptr = pchTemp + (maxx + 7) / 8 * (maxy - 1 - i);
slouken@1895
  1449
        aptr = pchTemp + (maxx + 7) / 8 * (maxy + maxy - 1 - i);
slouken@1895
  1450
        memxor(xptr, data, mask, run);
slouken@1895
  1451
        xptr += run;
slouken@1895
  1452
        data += run;
slouken@1895
  1453
        memnot(aptr, mask, run);
slouken@1895
  1454
        mask += run;
slouken@1895
  1455
        aptr += run;
slouken@1895
  1456
        SDL_memset(xptr, 0, pad);
slouken@1895
  1457
        xptr += pad;
slouken@1895
  1458
        SDL_memset(aptr, ~0, pad);
slouken@1895
  1459
        aptr += pad;
slouken@1895
  1460
    }
slouken@1895
  1461
    pad += run;
slouken@1895
  1462
    for (i = h; i < maxy; i++) {
slouken@1895
  1463
        xptr = pchTemp + (maxx + 7) / 8 * (maxy - 1 - i);
slouken@1895
  1464
        aptr = pchTemp + (maxx + 7) / 8 * (maxy + maxy - 1 - i);
slouken@1895
  1465
slouken@1895
  1466
        SDL_memset(xptr, 0, (maxx + 7) / 8);
slouken@1895
  1467
        xptr += (maxx + 7) / 8;
slouken@1895
  1468
        SDL_memset(aptr, ~0, (maxx + 7) / 8);
slouken@1895
  1469
        aptr += (maxx + 7) / 8;
slouken@1895
  1470
    }
slouken@1895
  1471
slouken@1895
  1472
    hbm =
slouken@1895
  1473
        GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) & bmih, CBM_INIT,
slouken@1895
  1474
                        (PBYTE) pchTemp, (PBITMAPINFO2) & bmi);
slouken@1895
  1475
    hptr = WinCreatePointer(HWND_DESKTOP, hbm, TRUE, hot_x, maxy - hot_y - 1);
icculus@1190
  1476
icculus@1190
  1477
#ifdef DEBUG_BUILD
slouken@1895
  1478
    printf("HotSpot          : %d ; %d\n", hot_x, hot_y);
slouken@1895
  1479
    printf("HPS returned     : %x\n", (ULONG) hps);
slouken@1895
  1480
    printf("HBITMAP returned : %x\n", (ULONG) hbm);
slouken@1895
  1481
    printf("HPOINTER returned: %x\n", (ULONG) hptr);
icculus@1190
  1482
#endif
icculus@1190
  1483
slouken@1895
  1484
    WinReleasePS(hps);
slouken@1895
  1485
slouken@1895
  1486
#ifdef DEBUG_BUILD
slouken@1895
  1487
    printf("[CreateWMCursor] : ptr = %p\n", hptr);
slouken@1895
  1488
    fflush(stdout);
slouken@1895
  1489
#endif
slouken@1895
  1490
slouken@1895
  1491
    pResult->hptr = hptr;
slouken@1895
  1492
    pResult->hbm = hbm;
slouken@1895
  1493
    pResult->pchData = pchTemp;
icculus@1190
  1494
icculus@1190
  1495
#ifdef DEBUG_BUILD
slouken@1895
  1496
    printf("[CreateWMCursor] : ptr = %p return.\n", hptr);
slouken@1895
  1497
    fflush(stdout);
icculus@1190
  1498
#endif
icculus@1190
  1499
slouken@1895
  1500
    return (WMcursor *) pResult;
icculus@1190
  1501
}
icculus@1190
  1502
slouken@1895
  1503
WMcursor *
slouken@1895
  1504
os2fslib_CreateWMCursor_FS(_THIS, Uint8 * data, Uint8 * mask,
slouken@1895
  1505
                           int w, int h, int hot_x, int hot_y)
icculus@1190
  1506
{
icculus@1190
  1507
#ifdef DEBUG_BUILD
slouken@1895
  1508
    printf("[CreateWMCursor_FS] : returning pointer NULL\n");
slouken@1895
  1509
    fflush(stdout);
icculus@1190
  1510
#endif
icculus@1190
  1511
slouken@1895
  1512
    // In FS mode we'll use software cursor
slouken@1895
  1513
    return (WMcursor *) NULL;
icculus@1190
  1514
}
icculus@1190
  1515
icculus@1190
  1516
/* Show the specified cursor, or hide if cursor is NULL */
slouken@1895
  1517
int
slouken@1895
  1518
os2fslib_ShowWMCursor(_THIS, WMcursor * cursor)
icculus@1190
  1519
{
icculus@1190
  1520
#ifdef DEBUG_BUILD
slouken@1895
  1521
    printf("[ShowWMCursor] : ptr = %p\n", cursor);
slouken@1895
  1522
    fflush(stdout);
icculus@1190
  1523
#endif
icculus@1190
  1524
slouken@1895
  1525
    if (cursor) {
slouken@1895
  1526
        WinSetPointer(HWND_DESKTOP, cursor->hptr);
slouken@1895
  1527
        hptrGlobalPointer = cursor->hptr;
slouken@1895
  1528
        _this->hidden->iMouseVisible = 1;
slouken@1895
  1529
    } else {
slouken@1895
  1530
        WinSetPointer(HWND_DESKTOP, FALSE);
slouken@1895
  1531
        hptrGlobalPointer = NULL;
slouken@1895
  1532
        _this->hidden->iMouseVisible = 0;
slouken@1895
  1533
    }
icculus@1190
  1534
icculus@1190
  1535
#ifdef DEBUG_BUILD
slouken@1895
  1536
    printf("[ShowWMCursor] : ptr = %p, DONE\n", cursor);
slouken@1895
  1537
    fflush(stdout);
icculus@1190
  1538
#endif
icculus@1190
  1539
slouken@1895
  1540
    return 1;
icculus@1190
  1541
}
icculus@1190
  1542
icculus@1190
  1543
/* Warp the window manager cursor to (x,y)
icculus@1190
  1544
 If NULL, a mouse motion event is posted internally.
icculus@1190
  1545
 */
slouken@1895
  1546
void
slouken@1895
  1547
os2fslib_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
icculus@1190
  1548
{
slouken@1895
  1549
    LONG lx, ly;
slouken@1895
  1550
    SWP swpClient;
slouken@1895
  1551
    POINTL ptlPoints;
slouken@1895
  1552
    WinQueryWindowPos(_this->hidden->hwndClient, &swpClient);
slouken@1895
  1553
    ptlPoints.x = swpClient.x;
slouken@1895
  1554
    ptlPoints.y = swpClient.y;
slouken@1895
  1555
    WinMapWindowPoints(_this->hidden->hwndFrame, HWND_DESKTOP, &ptlPoints, 1);
slouken@1895
  1556
    lx = ptlPoints.x +
slouken@1895
  1557
        (x * swpClient.cx) / _this->hidden->SrcBufferDesc.uiXResolution;
slouken@1895
  1558
    ly = ptlPoints.y + swpClient.cy -
slouken@1895
  1559
        ((y * swpClient.cy) / _this->hidden->SrcBufferDesc.uiYResolution) - 1;
slouken@1895
  1560
slouken@1895
  1561
    SDL_PrivateMouseMotion(0,   // Buttons not changed
slouken@1895
  1562
                           0,   // Absolute position
slouken@1895
  1563
                           x, y);
slouken@1895
  1564
slouken@1895
  1565
    WinSetPointerPos(HWND_DESKTOP, lx, ly);
icculus@1190
  1566
icculus@1190
  1567
}
icculus@1190
  1568
icculus@1190
  1569
/* If not NULL, this is called when a mouse motion event occurs */
slouken@1895
  1570
void
slouken@1895
  1571
os2fslib_MoveWMCursor(_THIS, int x, int y)
icculus@1190
  1572
{
slouken@1895
  1573
    /*
slouken@1895
  1574
       SDL_Rect rect;
slouken@1895
  1575
slouken@1895
  1576
       #ifdef DEBUG_BUILD
slouken@1895
  1577
       printf("[MoveWMCursor] : at %d ; %d\n", x, y); fflush(stdout);
slouken@1895
  1578
       #endif
slouken@1895
  1579
slouken@1895
  1580
       rect.x = x;
slouken@1895
  1581
       rect.y = y;
slouken@1895
  1582
       rect.w = 32;
slouken@1895
  1583
       rect.h = 32;
slouken@1895
  1584
       os2fslib_UpdateRects(_this, 1, &rect);
slouken@1895
  1585
       // TODO!
slouken@1895
  1586
     */
icculus@1190
  1587
}
icculus@1190
  1588
icculus@1190
  1589
/* Determine whether the mouse should be in relative mode or not.
icculus@1190
  1590
 This function is called when the input grab state or cursor
icculus@1190
  1591
 visibility state changes.
icculus@1190
  1592
 If the cursor is not visible, and the input is grabbed, the
icculus@1190
  1593
 driver can place the mouse in relative mode, which may result
icculus@1190
  1594
 in higher accuracy sampling of the pointer motion.
icculus@1190
  1595
 */
slouken@1895
  1596
void
slouken@1895
  1597
os2fslib_CheckMouseMode(_THIS)
icculus@1190
  1598
{
icculus@1190
  1599
}
icculus@1190
  1600
slouken@1895
  1601
static void
slouken@1895
  1602
os2fslib_PumpEvents(_THIS)
icculus@1190
  1603
{
slouken@1895
  1604
    // Notify SDL that if window has been resized!
slouken@1895
  1605
    if ((_this->hidden->pSDLSurface) &&
slouken@1895
  1606
        (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) &&
slouken@1895
  1607
        ((_this->hidden->SrcBufferDesc.uiXResolution != iWindowSizeX) ||
slouken@1895
  1608
         (_this->hidden->SrcBufferDesc.uiYResolution != iWindowSizeY)) &&
slouken@1895
  1609
        (iWindowSizeX > 0) && (iWindowSizeY > 0)) {
slouken@1895
  1610
        static time_t prev_time;
slouken@1895
  1611
        time_t curr_time;
slouken@1895
  1612
slouken@1895
  1613
        curr_time = time(NULL);
slouken@1895
  1614
        if ((difftime(curr_time, prev_time) >= 0.25) || (bWindowResized)) {
slouken@1895
  1615
            // Make sure we won't flood the event queue with resize events,
slouken@1895
  1616
            // only send them at 250 msecs!
slouken@1895
  1617
            // (or when the window is resized)
icculus@1190
  1618
#ifdef DEBUG_BUILD
slouken@1895
  1619
            printf
slouken@1895
  1620
                ("[os2fslib_PumpEvents] : Calling PrivateResize (%d %d).\n",
slouken@1895
  1621
                 iWindowSizeX, iWindowSizeY);
slouken@1895
  1622
            fflush(stdout);
icculus@1190
  1623
#endif
slouken@1895
  1624
            // Tell SDL the new size
slouken@1895
  1625
            SDL_PrivateResize(iWindowSizeX, iWindowSizeY);
slouken@1895
  1626
            prev_time = curr_time;
slouken@1895
  1627
            bWindowResized = 0;
slouken@1895
  1628
        }
icculus@1190
  1629
    }
icculus@1190
  1630
}
icculus@1190
  1631
icculus@1190
  1632
/* We don't actually allow hardware surfaces other than the main one */
slouken@1895
  1633
static int
slouken@1895
  1634
os2fslib_AllocHWSurface(_THIS, SDL_Surface * surface)
icculus@1190
  1635
{
slouken@1895
  1636
    return (-1);
icculus@1190
  1637
}
slouken@1895
  1638
static void
slouken@1895
  1639
os2fslib_FreeHWSurface(_THIS, SDL_Surface * surface)
icculus@1190
  1640
{
slouken@1895
  1641
    return;
icculus@1190
  1642
}
icculus@1190
  1643
icculus@1190
  1644
/* We need to wait for vertical retrace on page flipped displays */
slouken@1895
  1645
static int
slouken@1895
  1646
os2fslib_LockHWSurface(_THIS, SDL_Surface * surface)
icculus@1190
  1647
{
slouken@1895
  1648
    return (0);
icculus@1190
  1649
}
icculus@1190
  1650
slouken@1895
  1651
static void
slouken@1895
  1652
os2fslib_UnlockHWSurface(_THIS, SDL_Surface * surface)
icculus@1190
  1653
{
slouken@1895
  1654
    return;
icculus@1190
  1655
}
icculus@1190
  1656
slouken@1895
  1657
static int
slouken@1895
  1658
os2fslib_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
icculus@1190
  1659
{
slouken@1895
  1660
    printf("[os2fslib_SetColors] : TODO!\n");
slouken@1895
  1661
    fflush(stdout);
slouken@1895
  1662
    // TODO: Implement paletted modes
slouken@1895
  1663
    return (1);
icculus@1190
  1664
}
icculus@1190
  1665
slouken@1895
  1666
static void
slouken@1895
  1667
os2fslib_DestroyIcon(HWND hwndFrame)
icculus@1190
  1668
{
slouken@1895
  1669
    if (hptrCurrentIcon) {
slouken@1895
  1670
        WinDestroyPointer(hptrCurrentIcon);
slouken@1895
  1671
        hptrCurrentIcon = NULL;
slouken@1895
  1672
slouken@1895
  1673
        WinSendMsg(hwndFrame, WM_SETICON, NULL, NULL);
slouken@1895
  1674
    }
icculus@1190
  1675
icculus@1190
  1676
}
icculus@1190
  1677
icculus@1190
  1678
/* Set the window icon image */
slouken@1895
  1679
void
slouken@1895
  1680
os2fslib_SetIcon(_THIS, SDL_Surface * icon, Uint8 * mask)
icculus@1190
  1681
{
slouken@1895
  1682
    HWND hwndFrame;
slouken@1895
  1683
    SDL_Surface *icon_rgb;
slouken@1895
  1684
    HPOINTER hptrIcon;
slouken@1895
  1685
    HBITMAP hbm;
slouken@1895
  1686
    BITMAPINFOHEADER bmih;
slouken@1895
  1687
    BMPINFO bmi;
slouken@1895
  1688
    HPS hps;
slouken@1895
  1689
    char *pchTemp;
slouken@1895
  1690
    char *pptr, *mptr, *dptr, *dmptr;
slouken@1895
  1691
    int maxx, maxy, w, h, x, y;
slouken@1895
  1692
    SDL_Rect bounds;
icculus@1190
  1693
icculus@1190
  1694
#ifdef DEBUG_BUILD
slouken@1895
  1695
    printf("[os2fslib_SetIcon] : Creating and setting new icon\n");
slouken@1895
  1696
    fflush(stdout);
icculus@1190
  1697
#endif
icculus@1190
  1698
slouken@1895
  1699
    hwndFrame = WinQueryWindow(_this->hidden->hwndClient, QW_PARENT);
slouken@1895
  1700
slouken@1895
  1701
    // Make sure the old icon resource will be free'd!
slouken@1895
  1702
    os2fslib_DestroyIcon(hwndFrame);
slouken@1895
  1703
slouken@1895
  1704
    if ((!icon) || (!mask))
slouken@1895
  1705
        return;
slouken@1895
  1706
slouken@1895
  1707
    w = icon->w;
slouken@1895
  1708
    h = icon->h;
slouken@1895
  1709
slouken@1895
  1710
    maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXICON);
slouken@1895
  1711
    maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYICON);
slouken@1895
  1712
slouken@1895
  1713
    // Check for max size!
slouken@1895
  1714
    if ((w > maxx) || (h > maxy))
slouken@1895
  1715
        return;
slouken@1895
  1716
slouken@1895
  1717
    pchTemp = (char *) SDL_malloc(w * h * 2 * 4);
slouken@1895
  1718
    if (!pchTemp)
slouken@1895
  1719
        return;
slouken@1895
  1720
slouken@1895
  1721
    SDL_memset(pchTemp, 0, w * h * 2 * 4);
slouken@1895
  1722
slouken@1895
  1723
    // Convert surface to RGB, if it's not RGB yet!
slouken@1895
  1724
    icon_rgb = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
slouken@1895
  1725
                                    32, 0, 0, 0, 0);
slouken@1895
  1726
    if (icon_rgb == NULL) {
slouken@1895
  1727
        SDL_free(pchTemp);
slouken@1895
  1728
        return;
slouken@1895
  1729
    }
slouken@1895
  1730
    bounds.x = 0;
slouken@1895
  1731
    bounds.y = 0;
slouken@1895
  1732
    bounds.w = icon->w;
slouken@1895
  1733
    bounds.h = icon->h;
slouken@1895
  1734
    if (SDL_LowerBlit(icon, &bounds, icon_rgb, &bounds) < 0) {
slouken@1895
  1735
        SDL_FreeSurface(icon_rgb);
slouken@1895
  1736
        SDL_free(pchTemp);
slouken@1895
  1737
        return;
slouken@1895
  1738
    }
slouken@1895
  1739
slouken@1895
  1740
    /* Copy pixels upside-down from RGB surface into BMP, masked with the icon mask */
slouken@1895
  1741
slouken@1895
  1742
    // Pixels
slouken@1895
  1743
    pptr = (char *) (icon_rgb->pixels);
slouken@1895
  1744
    // Mask
slouken@1895
  1745
    mptr = mask;
slouken@1895
  1746
slouken@1895
  1747
    for (y = 0; y < h; y++) {
slouken@1895
  1748
        unsigned char uchMaskByte;
slouken@1895
  1749
slouken@1895
  1750
        // Destination
slouken@1895
  1751
        dptr = pchTemp + w * 4 * (h - y - 1);
slouken@1895
  1752
        // Destination mask
slouken@1895
  1753
        dmptr = pchTemp + w * h * 4 + w * 4 * (h - y - 1);
slouken@1895
  1754
slouken@1895
  1755
        for (x = 0; x < w; x++) {
slouken@1895
  1756
            if (x % 8 == 0) {
slouken@1895
  1757
                uchMaskByte = (unsigned char) (*mptr);
slouken@1895
  1758
                mptr++;
slouken@1895
  1759
            } else
slouken@1895
  1760
                uchMaskByte <<= 1;
slouken@1895
  1761
slouken@1895
  1762
            if (uchMaskByte & 0x80) {
slouken@1895
  1763
                // Copy RGB
slouken@1895
  1764
                *dptr++ = *pptr++;
slouken@1895
  1765
                *dptr++ = *pptr++;
slouken@1895
  1766
                *dptr++ = *pptr++;
slouken@1895
  1767
                *dptr++ = *pptr++;
slouken@1895
  1768
slouken@1895
  1769
                *dmptr++ = 0;
slouken@1895
  1770
                *dmptr++ = 0;
slouken@1895
  1771
                *dmptr++ = 0;
slouken@1895
  1772
                *dmptr++ = 0;
slouken@1895
  1773
            } else {
slouken@1895
  1774
                // Set pixels to fully transparent
slouken@1895
  1775
                *dptr++ = 0;
slouken@1895
  1776
                pptr++;
slouken@1895
  1777
                *dptr++ = 0;
slouken@1895
  1778
                pptr++;
slouken@1895
  1779
                *dptr++ = 0;
slouken@1895
  1780
                pptr++;
slouken@1895
  1781
                *dptr++ = 0;
slouken@1895
  1782
                pptr++;
slouken@1895
  1783
slouken@1895
  1784
                *dmptr++ = 255;
slouken@1895
  1785
                *dmptr++ = 255;
slouken@1895
  1786
                *dmptr++ = 255;
slouken@1895
  1787
                *dmptr++ = 255;
slouken@1895
  1788
            }
slouken@1895
  1789
        }
slouken@1895
  1790
    }
slouken@1895
  1791
slouken@1895
  1792
    // There is no more need for the RGB surface
icculus@1190
  1793
    SDL_FreeSurface(icon_rgb);
slouken@1895
  1794
slouken@1895
  1795
    hps = WinGetPS(_this->hidden->hwndClient);
slouken@1895
  1796
slouken@1895
  1797
    bmi.cbFix = sizeof(BITMAPINFOHEADER);
slouken@1895
  1798
    bmi.cx = w;
slouken@1895
  1799
    bmi.cy = 2 * h;
slouken@1895
  1800
    bmi.cPlanes = 1;
slouken@1895
  1801
    bmi.cBitCount = 32;
slouken@1895
  1802
slouken@1895
  1803
    SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
slouken@1895
  1804
    bmih.cbFix = sizeof(BITMAPINFOHEADER);
slouken@1895
  1805
    bmih.cx = w;
slouken@1895
  1806
    bmih.cy = 2 * h;
slouken@1895
  1807
    bmih.cPlanes = 1;
slouken@1895
  1808
    bmih.cBitCount = 32;
slouken@1895
  1809
slouken@1895
  1810
    hbm =
slouken@1895
  1811
        GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) & bmih, CBM_INIT,
slouken@1895
  1812
                        (PBYTE) pchTemp, (PBITMAPINFO2) & bmi);
slouken@1895
  1813
    hptrIcon = WinCreatePointer(HWND_DESKTOP, hbm, FALSE, 0, 0);
slouken@1895
  1814
slouken@1895
  1815
    WinReleasePS(hps);
slouken@1895
  1816
slouken@1895
  1817
    // Free pixel array
slouken@1336
  1818
    SDL_free(pchTemp);
slouken@1895
  1819
slouken@1895
  1820
    // Change icon in frame window
slouken@1895
  1821
    WinSendMsg(hwndFrame, WM_SETICON, (MPARAM) hptrIcon, NULL);
slouken@1895
  1822
slouken@1895
  1823
    /*
slouken@1895
  1824
       // Change icon in switchlist
slouken@1895
  1825
       // Seems like it's not needed, the WM_SETICON already does it.
slouken@1895
  1826
       {
slouken@1895
  1827
       PID pidFrame;
slouken@1895
  1828
       HSWITCH hswitchFrame;
slouken@1895
  1829
       SWCNTRL swctl;
slouken@1895
  1830
slouken@1895
  1831
       WinQueryWindowProcess(hwndFrame, &pidFrame, NULL);
slouken@1895
  1832
       hswitchFrame = WinQuerySwitchHandle(hwndFrame, pidFrame);
slouken@1895
  1833
       WinQuerySwitchEntry(hswitchFrame, &swctl);
slouken@1895
  1834
slouken@1895
  1835
       swctl.hwndIcon = hptrIcon;
slouken@1895
  1836
slouken@1895
  1837
       WinChangeSwitchEntry(hswitchFrame, &swctl);
slouken@1895
  1838
       }
slouken@1895
  1839
     */
slouken@1895
  1840
slouken@1895
  1841
    // Store icon handle in global variable
slouken@1895
  1842
    hptrCurrentIcon = hptrIcon;
icculus@1190
  1843
}
icculus@1190
  1844
icculus@1190
  1845
// ------------------------ REAL FUNCTIONS -----------------
icculus@1190
  1846
icculus@1190
  1847
slouken@1895
  1848
static void
slouken@1895
  1849
os2fslib_SetCursorManagementFunctions(_THIS, int iForWindowedMode)
icculus@1190
  1850
{
slouken@1895
  1851
    if (iForWindowedMode) {
slouken@1895
  1852
        _this->FreeWMCursor = os2fslib_FreeWMCursor;
slouken@1895
  1853
        _this->CreateWMCursor = os2fslib_CreateWMCursor_Win;
slouken@1895
  1854
        _this->ShowWMCursor = os2fslib_ShowWMCursor;
slouken@1895
  1855
        _this->WarpWMCursor = os2fslib_WarpWMCursor;
slouken@1895
  1856
        _this->MoveWMCursor = os2fslib_MoveWMCursor;
slouken@1895
  1857
        _this->CheckMouseMode = NULL;   //os2fslib_CheckMouseMode;
slouken@1895
  1858
    } else {
slouken@1895
  1859
        // We'll have software mouse cursor in FS mode!
slouken@1895
  1860
        _this->FreeWMCursor = os2fslib_FreeWMCursor;
slouken@1895
  1861
        _this->CreateWMCursor = os2fslib_CreateWMCursor_FS;
slouken@1895
  1862
        _this->ShowWMCursor = os2fslib_ShowWMCursor;
slouken@1895
  1863
        _this->WarpWMCursor = os2fslib_WarpWMCursor;
slouken@1895
  1864
        _this->MoveWMCursor = os2fslib_MoveWMCursor;
slouken@1895
  1865
        _this->CheckMouseMode = NULL;   //os2fslib_CheckMouseMode;
slouken@1895
  1866
    }
icculus@1190
  1867
}
icculus@1190
  1868
slouken@1895
  1869
static void
slouken@1895
  1870
os2fslib_InitOSKeymap(_THIS)
icculus@1190
  1871
{
slouken@1895
  1872
    int i;
slouken@1895
  1873
slouken@1895
  1874
    iShiftIsPressed = 0;
slouken@1895
  1875
slouken@1895
  1876
    /* Map the VK and CH keysyms */
slouken@1895
  1877
    for (i = 0; i <= 255; ++i)
slouken@1895
  1878
        HWScanKeyMap[i] = SDLK_UNKNOWN;
slouken@1895
  1879
slouken@1895
  1880
    // First line of keyboard:
slouken@1895
  1881
    HWScanKeyMap[0x1] = SDLK_ESCAPE;
slouken@1895
  1882
    HWScanKeyMap[0x3b] = SDLK_F1;
slouken@1895
  1883
    HWScanKeyMap[0x3c] = SDLK_F2;
slouken@1895
  1884
    HWScanKeyMap[0x3d] = SDLK_F3;
slouken@1895
  1885
    HWScanKeyMap[0x3e] = SDLK_F4;
slouken@1895
  1886
    HWScanKeyMap[0x3f] = SDLK_F5;
slouken@1895
  1887
    HWScanKeyMap[0x40] = SDLK_F6;
slouken@1895
  1888
    HWScanKeyMap[0x41] = SDLK_F7;
slouken@1895
  1889
    HWScanKeyMap[0x42] = SDLK_F8;
slouken@1895
  1890
    HWScanKeyMap[0x43] = SDLK_F9;
slouken@1895
  1891
    HWScanKeyMap[0x44] = SDLK_F10;
slouken@1895
  1892
    HWScanKeyMap[0x57] = SDLK_F11;
slouken@1895
  1893
    HWScanKeyMap[0x58] = SDLK_F12;
slouken@1895
  1894
    HWScanKeyMap[0x5d] = SDLK_PRINT;
slouken@1895
  1895
    HWScanKeyMap[0x46] = SDLK_SCROLLOCK;
slouken@1895
  1896
    HWScanKeyMap[0x5f] = SDLK_PAUSE;
slouken@1895
  1897
slouken@1895
  1898
    // Second line of keyboard:
slouken@1895
  1899
    HWScanKeyMap[0x29] = SDLK_BACKQUOTE;
slouken@1895
  1900
    HWScanKeyMap[0x2] = SDLK_1;
slouken@1895
  1901
    HWScanKeyMap[0x3] = SDLK_2;
slouken@1895
  1902
    HWScanKeyMap[0x4] = SDLK_3;
slouken@1895
  1903
    HWScanKeyMap[0x5] = SDLK_4;
slouken@1895
  1904
    HWScanKeyMap[0x6] = SDLK_5;
slouken@1895
  1905
    HWScanKeyMap[0x7] = SDLK_6;
slouken@1895
  1906
    HWScanKeyMap[0x8] = SDLK_7;
slouken@1895
  1907
    HWScanKeyMap[0x9] = SDLK_8;
slouken@1895
  1908
    HWScanKeyMap[0xa] = SDLK_9;
slouken@1895
  1909
    HWScanKeyMap[0xb] = SDLK_0;
slouken@1895
  1910
    HWScanKeyMap[0xc] = SDLK_MINUS;
slouken@1895
  1911
    HWScanKeyMap[0xd] = SDLK_EQUALS;
slouken@1895
  1912
    HWScanKeyMap[0xe] = SDLK_BACKSPACE;
slouken@1895
  1913
    HWScanKeyMap[0x68] = SDLK_INSERT;
slouken@1895
  1914
    HWScanKeyMap[0x60] = SDLK_HOME;
slouken@1895
  1915
    HWScanKeyMap[0x62] = SDLK_PAGEUP;
slouken@1895
  1916
    HWScanKeyMap[0x45] = SDLK_NUMLOCK;
slouken@1895
  1917
    HWScanKeyMap[0x5c] = SDLK_KP_DIVIDE;
slouken@1895
  1918
    HWScanKeyMap[0x37] = SDLK_KP_MULTIPLY;
slouken@1895
  1919
    HWScanKeyMap[0x4a] = SDLK_KP_MINUS;
slouken@1895
  1920
slouken@1895
  1921
    // Third line of keyboard:
slouken@1895
  1922
    HWScanKeyMap[0xf] = SDLK_TAB;
slouken@1895
  1923
    HWScanKeyMap[0x10] = SDLK_q;
slouken@1895
  1924
    HWScanKeyMap[0x11] = SDLK_w;
slouken@1895
  1925
    HWScanKeyMap[0x12] = SDLK_e;
slouken@1895
  1926
    HWScanKeyMap[0x13] = SDLK_r;
slouken@1895
  1927
    HWScanKeyMap[0x14] = SDLK_t;
slouken@1895
  1928
    HWScanKeyMap[0x15] = SDLK_y;
slouken@1895
  1929
    HWScanKeyMap[0x16] = SDLK_u;
slouken@1895
  1930
    HWScanKeyMap[0x17] = SDLK_i;
slouken@1895
  1931
    HWScanKeyMap[0x18] = SDLK_o;
slouken@1895
  1932
    HWScanKeyMap[0x19] = SDLK_p;
slouken@1895
  1933
    HWScanKeyMap[0x1a] = SDLK_LEFTBRACKET;
slouken@1895
  1934
    HWScanKeyMap[0x1b] = SDLK_RIGHTBRACKET;
slouken@1895
  1935
    HWScanKeyMap[0x1c] = SDLK_RETURN;
slouken@1895
  1936
    HWScanKeyMap[0x69] = SDLK_DELETE;
slouken@1895
  1937
    HWScanKeyMap[0x65] = SDLK_END;
slouken@1895
  1938
    HWScanKeyMap[0x67] = SDLK_PAGEDOWN;
slouken@1895
  1939
    HWScanKeyMap[0x47] = SDLK_KP7;
slouken@1895
  1940
    HWScanKeyMap[0x48] = SDLK_KP8;
slouken@1895
  1941
    HWScanKeyMap[0x49] = SDLK_KP9;
slouken@1895
  1942
    HWScanKeyMap[0x4e] = SDLK_KP_PLUS;
slouken@1895
  1943
slouken@1895
  1944
    // Fourth line of keyboard:
slouken@1895
  1945
    HWScanKeyMap[0x3a] = SDLK_CAPSLOCK;
slouken@1895
  1946
    HWScanKeyMap[0x1e] = SDLK_a;
slouken@1895
  1947
    HWScanKeyMap[0x1f] = SDLK_s;
slouken@1895
  1948
    HWScanKeyMap[0x20] = SDLK_d;
slouken@1895
  1949
    HWScanKeyMap[0x21] = SDLK_f;
slouken@1895
  1950
    HWScanKeyMap[0x22] = SDLK_g;
slouken@1895
  1951
    HWScanKeyMap[0x23] = SDLK_h;
slouken@1895
  1952
    HWScanKeyMap[0x24] = SDLK_j;
slouken@1895
  1953
    HWScanKeyMap[0x25] = SDLK_k;
slouken@1895
  1954
    HWScanKeyMap[0x26] = SDLK_l;
slouken@1895
  1955
    HWScanKeyMap[0x27] = SDLK_SEMICOLON;
slouken@1895
  1956
    HWScanKeyMap[0x28] = SDLK_QUOTE;
slouken@1895
  1957
    HWScanKeyMap[0x2b] = SDLK_BACKSLASH;
slouken@1895
  1958
    HWScanKeyMap[0x4b] = SDLK_KP4;
slouken@1895
  1959
    HWScanKeyMap[0x4c] = SDLK_KP5;
slouken@1895
  1960
    HWScanKeyMap[0x4d] = SDLK_KP6;
slouken@1895
  1961
slouken@1895
  1962
    // Fifth line of keyboard:
slouken@1895
  1963
    HWScanKeyMap[0x2a] = SDLK_LSHIFT;
slouken@1895
  1964
    HWScanKeyMap[0x56] = SDLK_WORLD_1;  // Code 161, letter i' on hungarian keyboard
slouken@1895
  1965
    HWScanKeyMap[0x2c] = SDLK_z;
slouken@1895
  1966
    HWScanKeyMap[0x2d] = SDLK_x;
slouken@1895
  1967
    HWScanKeyMap[0x2e] = SDLK_c;
slouken@1895
  1968
    HWScanKeyMap[0x2f] = SDLK_v;
slouken@1895
  1969
    HWScanKeyMap[0x30] = SDLK_b;
slouken@1895
  1970
    HWScanKeyMap[0x31] = SDLK_n;
slouken@1895
  1971
    HWScanKeyMap[0x32] = SDLK_m;
slouken@1895
  1972
    HWScanKeyMap[0x33] = SDLK_COMMA;
slouken@1895
  1973
    HWScanKeyMap[0x34] = SDLK_PERIOD;
slouken@1895
  1974
    HWScanKeyMap[0x35] = SDLK_SLASH;
slouken@1895
  1975
    HWScanKeyMap[0x36] = SDLK_RSHIFT;
slouken@1895
  1976
    HWScanKeyMap[0x61] = SDLK_UP;
slouken@1895
  1977
    HWScanKeyMap[0x4f] = SDLK_KP1;
slouken@1895
  1978
    HWScanKeyMap[0x50] = SDLK_KP2;
slouken@1895
  1979
    HWScanKeyMap[0x51] = SDLK_KP3;
slouken@1895
  1980
    HWScanKeyMap[0x5a] = SDLK_KP_ENTER;
slouken@1895
  1981
slouken@1895
  1982
    // Sixth line of keyboard:
slouken@1895
  1983
    HWScanKeyMap[0x1d] = SDLK_LCTRL;
slouken@1895
  1984
    HWScanKeyMap[0x7e] = SDLK_LSUPER;   // Windows key
slouken@1895
  1985
    HWScanKeyMap[0x38] = SDLK_LALT;
slouken@1895
  1986
    HWScanKeyMap[0x39] = SDLK_SPACE;
slouken@1895
  1987
    HWScanKeyMap[0x5e] = SDLK_RALT;     // Actually, altgr on my keyboard...
slouken@1895
  1988
    HWScanKeyMap[0x7f] = SDLK_RSUPER;
slouken@1895
  1989
    HWScanKeyMap[0x7c] = SDLK_MENU;
slouken@1895
  1990
    HWScanKeyMap[0x5b] = SDLK_RCTRL;
slouken@1895
  1991
    HWScanKeyMap[0x63] = SDLK_LEFT;
slouken@1895
  1992
    HWScanKeyMap[0x66] = SDLK_DOWN;
slouken@1895
  1993
    HWScanKeyMap[0x64] = SDLK_RIGHT;
slouken@1895
  1994
    HWScanKeyMap[0x52] = SDLK_KP0;
slouken@1895
  1995
    HWScanKeyMap[0x53] = SDLK_KP_PERIOD;
icculus@1190
  1996
}
icculus@1190
  1997
icculus@1190
  1998
icculus@1190
  1999
/* Iconify the window.
icculus@1190
  2000
 This function returns 1 if there is a window manager and the
icculus@1190
  2001
 window was actually iconified, it returns 0 otherwise.
icculus@1190
  2002
 */
slouken@1895
  2003
int
slouken@1895
  2004
os2fslib_IconifyWindow(_THIS)
icculus@1190
  2005
{
slouken@1895
  2006
    HAB hab;
slouken@1895
  2007
    HMQ hmq;
slouken@1895
  2008
    ERRORID hmqerror;
slouken@1895
  2009
slouken@1895
  2010
    // If there is no more window, nothing we can do!
slouken@1895
  2011
    if (_this->hidden->iPMThreadStatus != 1)
slouken@1895
  2012
        return 0;
slouken@1895
  2013
slouken@1895
  2014
    // Cannot do anything in fullscreen mode!
slouken@1895
  2015
    if (FSLib_QueryFSMode(_this->hidden->hwndClient))
slouken@1895
  2016
        return 0;
slouken@1895
  2017
slouken@1895
  2018
    // Make sure this thread is prepared for using the Presentation Manager!
slouken@1895
  2019
    hab = WinInitialize(0);
slouken@1895
  2020
    hmq = WinCreateMsgQueue(hab, 0);
slouken@1895
  2021
    // Remember if there was an error at WinCreateMsgQueue(), because we don't
slouken@1895
  2022
    // want to destroy somebody else's queue later. :)
slouken@1895
  2023
    hmqerror = WinGetLastError(hab);
slouken@1895
  2024
slouken@1895
  2025
    WinSetWindowPos(_this->hidden->hwndFrame, HWND_TOP,
slouken@1895
  2026
                    0, 0, 0, 0, SWP_MINIMIZE);
slouken@1895
  2027
slouken@1895
  2028
    // Now destroy the message queue, if we've created it!
slouken@1895
  2029
    if (ERRORIDERROR(hmqerror) == 0)
slouken@1895
  2030
        WinDestroyMsgQueue(hmq);
slouken@1895
  2031
slouken@1895
  2032
    return 1;
icculus@1190
  2033
}
icculus@1190
  2034
slouken@1895
  2035
static SDL_GrabMode
slouken@1895
  2036
os2fslib_GrabInput(_THIS, SDL_GrabMode mode)
icculus@1190
  2037
{
slouken@1895
  2038
    HAB hab;
slouken@1895
  2039
    HMQ hmq;
slouken@1895
  2040
    ERRORID hmqerror;
slouken@1895
  2041
slouken@1895
  2042
slouken@1895
  2043
    // If there is no more window, nothing we can do!
slouken@1895
  2044
    if (_this->hidden->iPMThreadStatus != 1)
slouken@1895
  2045
        return SDL_GRAB_OFF;
slouken@1895
  2046
slouken@1895
  2047
    // Make sure this thread is prepared for using the Presentation Manager!
slouken@1895
  2048
    hab = WinInitialize(0);
slouken@1895
  2049
    hmq = WinCreateMsgQueue(hab, 0);
slouken@1895
  2050
    // Remember if there was an error at WinCreateMsgQueue(), because we don't
slouken@1895
  2051
    // want to destroy somebody else's queue later. :)
slouken@1895
  2052
    hmqerror = WinGetLastError(hab);
slouken@1895
  2053
slouken@1895
  2054
slouken@1895
  2055
    if (mode == SDL_GRAB_OFF) {
icculus@1190
  2056
#ifdef DEBUG_BUILD
slouken@1895
  2057
        printf("[os2fslib_GrabInput] : Releasing mouse\n");
slouken@1895
  2058
        fflush(stdout);
slouken@1895
  2059
#endif
slouken@1895
  2060
slouken@1895
  2061
        // Release the mouse
slouken@1895
  2062
        bMouseCapturable = 0;
slouken@1895
  2063
        if (bMouseCaptured) {
slouken@1895
  2064
            WinSetCapture(HWND_DESKTOP, NULLHANDLE);
slouken@1895
  2065
            bMouseCaptured = 0;
slouken@1895
  2066
        }
slouken@1895
  2067
    } else {
slouken@1895
  2068
#ifdef DEBUG_BUILD
slouken@1895
  2069
        printf("[os2fslib_GrabInput] : Capturing mouse\n");
slouken@1895
  2070
        fflush(stdout);
icculus@1190
  2071
#endif
icculus@1190
  2072
slouken@1895
  2073
        // Capture the mouse
slouken@1895
  2074
        bMouseCapturable = 1;
slouken@1895
  2075
        if (WinQueryFocus(HWND_DESKTOP) == _this->hidden->hwndClient) {
slouken@1895
  2076
            WinSetCapture(HWND_DESKTOP, _this->hidden->hwndClient);
slouken@1895
  2077
            bMouseCaptured = 1;
slouken@1895
  2078
            {
slouken@1895
  2079
                SWP swpClient;
slouken@1895
  2080
                POINTL ptl;
slouken@1895
  2081
                // Center the mouse to the middle of the window!
slouken@1895
  2082
                WinQueryWindowPos(_this->hidden->hwndClient, &swpClient);
slouken@1895
  2083
                ptl.x = 0;
slouken@1895
  2084
                ptl.y = 0;
slouken@1895
  2085
                WinMapWindowPoints(_this->hidden->hwndClient,
slouken@1895
  2086
                                   HWND_DESKTOP, &ptl, 1);
slouken@1895
  2087
                _this->hidden->iSkipWMMOUSEMOVE++;      /* Don't take next WM_MOUSEMOVE into account!  */
slouken@1895
  2088
                WinSetPointerPos(HWND_DESKTOP,
slouken@1895
  2089
                                 ptl.x + swpClient.cx / 2,
slouken@1895
  2090
                                 ptl.y + swpClient.cy / 2);
slouken@1895
  2091
            }
slouken@1895
  2092
        }
icculus@1190
  2093
    }
slouken@1895
  2094
slouken@1895
  2095
    // Now destroy the message queue, if we've created it!
slouken@1895
  2096
    if (ERRORIDERROR(hmqerror) == 0)
slouken@1895
  2097
        WinDestroyMsgQueue(hmq);
slouken@1895
  2098
slouken@1895
  2099
    return mode;
icculus@1190
  2100
}
icculus@1190
  2101
icculus@1190
  2102
/* Set the title and icon text */
slouken@1895
  2103
static void
slouken@1895
  2104
os2fslib_SetCaption(_THIS, const char *title, const char *icon)
icculus@1190
  2105
{
slouken@1895
  2106
    HAB hab;
slouken@1895
  2107
    HMQ hmq;
slouken@1895
  2108
    ERRORID hmqerror;
slouken@1895
  2109
slouken@1895
  2110
    // If there is no more window, nothing we can do!
slouken@1895
  2111
    if (_this->hidden->iPMThreadStatus != 1)
slouken@1895
  2112
        return;
slouken@1895
  2113
slouken@1895
  2114
    // Make sure this thread is prepared for using the Presentation Manager!
slouken@1895
  2115
    hab = WinInitialize(0);
slouken@1895
  2116
    hmq = WinCreateMsgQueue(hab, 0);
slouken@1895
  2117
    // Remember if there was an error at WinCreateMsgQueue(), because we don't
slouken@1895
  2118
    // want to destroy somebody else's queue later. :)
slouken@1895
  2119
    hmqerror = WinGetLastError(hab);
slouken@1895
  2120
slouken@1895
  2121
    WinSetWindowText(_this->hidden->hwndFrame, (char *) title);
slouken@1895
  2122
slouken@1895
  2123
    // Now destroy the message queue, if we've created it!
slouken@1895
  2124
    if (ERRORIDERROR(hmqerror) == 0)
slouken@1895
  2125
        WinDestroyMsgQueue(hmq);
icculus@1190
  2126
}
icculus@1190
  2127
slouken@1895
  2128
static int
slouken@1895
  2129
os2fslib_ToggleFullScreen(_THIS, int on)
icculus@1190
  2130
{
icculus@1190
  2131
#ifdef DEBUG_BUILD
slouken@1895
  2132
    printf("[os2fslib_ToggleFullScreen] : %d\n", on);
slouken@1895
  2133
    fflush(stdout);
icculus@1190
  2134
#endif
slouken@1895
  2135
    // If there is no more window, nothing we can do!
slouken@1895
  2136
    if (_this->hidden->iPMThreadStatus != 1)
slouken@1895
  2137
        return 0;
slouken@1895
  2138
slouken@1895
  2139
    FSLib_ToggleFSMode(_this->hidden->hwndClient, on);
slouken@1895
  2140
    /* Cursor manager functions to Windowed/FS mode */
slouken@1895
  2141
    os2fslib_SetCursorManagementFunctions(_this, !on);
slouken@1895
  2142
    return 1;
icculus@1190
  2143
}
icculus@1190
  2144
icculus@1190
  2145
/* This is called after the video mode has been set, to get the
icculus@1190
  2146
 initial mouse state.  It should queue events as necessary to
icculus@1190
  2147
 properly represent the current mouse focus and position.
icculus@1190
  2148
 */
slouken@1895
  2149
static void
slouken@1895
  2150
os2fslib_UpdateMouse(_THIS)
icculus@1190
  2151
{
slouken@1895
  2152
    POINTL ptl;
slouken@1895
  2153
    HAB hab;
slouken@1895
  2154
    HMQ hmq;
slouken@1895
  2155
    ERRORID hmqerror;
slouken@1895
  2156
    SWP swpClient;
slouken@1895
  2157
slouken@1895
  2158
    // If there is no more window, nothing we can do!
slouken@1895
  2159
    if (_this->hidden->iPMThreadStatus != 1)
slouken@1895
  2160
        return;
slouken@1895
  2161
slouken@1895
  2162
slouken@1895
  2163
    // Make sure this thread is prepared for using the Presentation Manager!
slouken@1895
  2164
    hab = WinInitialize(0);
slouken@1895
  2165
    hmq = WinCreateMsgQueue(hab, 0);
slouken@1895
  2166
    // Remember if there was an error at WinCreateMsgQueue(), because we don't
slouken@1895
  2167
    // want to destroy somebody else's queue later. :)
slouken@1895
  2168
    hmqerror = WinGetLastError(hab);
slouken@1895
  2169
slouken@1895
  2170
slouken@1895
  2171
slouken@1895
  2172
    if (_this->hidden->fInFocus) {
slouken@1895
  2173
        // If our app is in focus
slouken@1895
  2174
        SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
slouken@1895
  2175
        SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
slouken@1895
  2176
        SDL_PrivateAppActive(1, SDL_APPACTIVE);
slouken@1895
  2177
        WinQueryPointerPos(HWND_DESKTOP, &ptl);
slouken@1895
  2178
        WinMapWindowPoints(HWND_DESKTOP, _this->hidden->hwndClient, &ptl, 1);
slouken@1895
  2179
        WinQueryWindowPos(_this->hidden->hwndClient, &swpClient);
slouken@1895
  2180
        // Convert OS/2 mouse position to SDL position, and also scale it!
slouken@1895
  2181
        ptl.x =
slouken@1895
  2182
            ptl.x * _this->hidden->SrcBufferDesc.uiXResolution / swpClient.cx;
slouken@1895
  2183
        ptl.y =
slouken@1895
  2184
            ptl.y * _this->hidden->SrcBufferDesc.uiYResolution / swpClient.cy;
slouken@1895
  2185
        ptl.y = _this->hidden->SrcBufferDesc.uiYResolution - ptl.y - 1;
slouken@1895
  2186
        SDL_PrivateMouseMotion(0, 0, (Sint16) (ptl.x), (Sint16) (ptl.y));
slouken@1895
  2187
    } else {
slouken@1895
  2188
        // If we're not in focus
slouken@1895
  2189
        SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
slouken@1895
  2190
        SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
slouken@1895
  2191
        SDL_PrivateAppActive(0, SDL_APPACTIVE);
slouken@1895
  2192
        SDL_PrivateMouseMotion(0, 0, (Sint16) - 1, (Sint16) - 1);
slouken@1895
  2193
    }
slouken@1895
  2194
slouken@1895
  2195
    // Now destroy the message queue, if we've created it!
slouken@1895
  2196
    if (ERRORIDERROR(hmqerror) == 0)
slouken@1895
  2197
        WinDestroyMsgQueue(hmq);
icculus@1190
  2198
icculus@1190
  2199
}
icculus@1190
  2200
icculus@1190
  2201
/* This pointer should exist in the native video subsystem and should
icculus@1190
  2202
 point to an appropriate update function for the current video mode
icculus@1190
  2203
 */
slouken@1895
  2204
static void
slouken@1895
  2205
os2fslib_UpdateRects(_THIS, int numrects, SDL_Rect * rects)
icculus@1190
  2206
{
slouken@1895
  2207
    // If there is no more window, nothing we can do!
slouken@1895
  2208
    if (_this->hidden->iPMThreadStatus != 1)
slouken@1895
  2209
        return;
icculus@1190
  2210
icculus@1190
  2211
#ifdef BITBLT_IN_WINMESSAGEPROC
slouken@1895
  2212
    WinSendMsg(_this->hidden->hwndClient,
slouken@1895
  2213
               WM_UPDATERECTSREQUEST, (MPARAM) numrects, (MPARAM) rects);
icculus@1190
  2214
#else
slouken@1895
  2215
    if (DosRequestMutexSem
slouken@1895
  2216
        (_this->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT) == NO_ERROR) {
slouken@1895
  2217
        int i;
slouken@1895
  2218
slouken@1895
  2219
        if (_this->hidden->pSDLSurface) {
icculus@1190
  2220
#ifndef RESIZE_EVEN_IF_RESIZABLE
slouken@1895
  2221
            SWP swp;
slouken@1895
  2222
            // But only blit if the window is not resizable, or if
slouken@1895
  2223
            // the window is resizable and the source buffer size is the
slouken@1895
  2224
            // same as the destination buffer size!
slouken@1895
  2225
            WinQueryWindowPos(_this->hidden->hwndClient, &swp);
slouken@1895
  2226
            if ((_this->hidden->pSDLSurface) &&
slouken@1895
  2227
                (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) &&
slouken@1895
  2228
                ((swp.cx != _this->hidden->SrcBufferDesc.uiXResolution) ||
slouken@1895
  2229
                 (swp.cy != _this->hidden->SrcBufferDesc.uiYResolution))
slouken@1895
  2230
                && (!FSLib_QueryFSMode(_this->hidden->hwndClient))) {
slouken@1895
  2231
                // Resizable surface and in resizing!
slouken@1895
  2232
                // So, don't blit now!
icculus@1190
  2233
#ifdef DEBUG_BUILD
slouken@1895
  2234
                printf("[UpdateRects] : Skipping blit while resizing!\n");
slouken@1895
  2235
                fflush(stdout);
slouken@1895
  2236
#endif
slouken@1895
  2237
            } else
icculus@1190
  2238
#endif
slouken@1895
  2239
            {
slouken@1895
  2240
                /*
slouken@1895
  2241
                   // Blit the whole window
slouken@1895
  2242
                   FSLIB_BITBLT(_this->hidden->hwndClient, _this->hidden->pchSrcBuffer,
slouken@1895
  2243
                   0, 0,
slouken@1895
  2244
                   _this->hidden->SrcBufferDesc.uiXResolution,
slouken@1895
  2245
                   _this->hidden->SrcBufferDesc.uiYResolution);
slouken@1895
  2246
                 */
slouken@1895
  2247
#ifdef DEBUG_BUILD
slouken@1895
  2248
                printf("[os2fslib_UpdateRects] : Blitting!\n");
slouken@1895
  2249
                fflush(stdout);
icculus@1190
  2250
#endif
slouken@1895
  2251
slouken@1895
  2252
                // Blit the changed areas
slouken@1895
  2253
                for (i = 0; i < numrects; i++)
slouken@1895
  2254
                    FSLIB_BITBLT(_this->hidden->hwndClient,
slouken@1895
  2255
                                 _this->hidden->pchSrcBuffer,
slouken@1895
  2256
                                 rects[i].y, rects[i].x, rects[i].w,
slouken@1895
  2257
                                 rects[i].h);
slouken@1895
  2258
            }
slouken@1895
  2259
        }
icculus@1190
  2260
#ifdef DEBUG_BUILD
slouken@1895
  2261
        else
slouken@1895
  2262
            printf("[os2fslib_UpdateRects] : No public surface!\n");
slouken@1895
  2263
        fflush(stdout);
icculus@1190
  2264
#endif
slouken@1895
  2265
        DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer);
icculus@1190
  2266
    }
icculus@1190
  2267
#ifdef DEBUG_BUILD
slouken@1895
  2268
    else
slouken@1895
  2269
        printf("[os2fslib_UpdateRects] : Error in mutex!\n");
slouken@1895
  2270
    fflush(stdout);
icculus@1190
  2271
#endif
icculus@1190
  2272
#endif
icculus@1190
  2273
}
icculus@1190
  2274
icculus@1190
  2275
icculus@1190
  2276
/* Reverse the effects VideoInit() -- called if VideoInit() fails
icculus@1190
  2277
 or if the application is shutting down the video subsystem.
icculus@1190
  2278
 */
slouken@1895
  2279
static void
slouken@1895
  2280
os2fslib_VideoQuit(_THIS)
icculus@1190
  2281
{
icculus@1190
  2282
#ifdef DEBUG_BUILD
slouken@1895
  2283
    printf("[os2fslib_VideoQuit]\n");
slouken@1895
  2284
    fflush(stdout);
icculus@1190
  2285
#endif
slouken@1895
  2286
    // Close PM stuff if running!
slouken@1895
  2287
    if (_this->hidden->iPMThreadStatus == 1) {
slouken@1895
  2288
        int iTimeout;
slouken@1895
  2289
        WinPostMsg(_this->hidden->hwndFrame, WM_QUIT, (MPARAM) 0, (MPARAM) 0);
slouken@1895
  2290
        // HACK: We had this line before:
slouken@1895
  2291
        //DosWaitThread((TID *) &(_this->hidden->tidPMThread), DCWW_WAIT);
slouken@1895
  2292
        // We don't use it, because the PMThread will never stop, or if it stops,
slouken@1895
  2293
        // it will kill the whole process as a emergency fallback.
slouken@1895
  2294
        // So, we only check for the iPMThreadStatus stuff!
icculus@1190
  2295
#ifdef DEBUG_BUILD
slouken@1895
  2296
        printf("[os2fslib_VideoQuit] : Waiting for PM thread to die\n");
slouken@1895
  2297
        fflush(stdout);
icculus@1190
  2298
#endif
icculus@1190
  2299
slouken@1895
  2300
        iTimeout = 0;
slouken@1895
  2301
        while ((_this->hidden->iPMThreadStatus == 1) && (iTimeout < 100)) {
slouken@1895
  2302
            iTimeout++;
slouken@1895
  2303
            DosSleep(64);
slouken@1895
  2304
        }
icculus@1190
  2305
icculus@1190
  2306
#ifdef DEBUG_BUILD
slouken@1895
  2307
        printf("[os2fslib_VideoQuit] : End of wait.\n");
slouken@1895
  2308
        fflush(stdout);
icculus@1190
  2309
#endif
icculus@1190
  2310
slouken@1895
  2311
        if (_this->hidden->iPMThreadStatus == 1) {
icculus@1190
  2312
#ifdef DEBUG_BUILD
slouken@1895
  2313
            printf("[os2fslib_VideoQuit] : Killing PM thread!\n");
slouken@1895
  2314
            fflush(stdout);
icculus@1190
  2315
#endif
slouken@1895
  2316
slouken@1895
  2317
            _this->hidden->iPMThreadStatus = 0;
slouken@1895
  2318
            DosKillThread(_this->hidden->tidPMThread);
slouken@1895
  2319
slouken@1895
  2320
            if (_this->hidden->hwndFrame) {
icculus@1190
  2321
#ifdef DEBUG_BUILD
slouken@1895
  2322
                printf("[os2fslib_VideoQuit] : Destroying PM window!\n");
slouken@1895
  2323
                fflush(stdout);
icculus@1190
  2324
#endif
icculus@1190
  2325
slouken@1895
  2326
                WinDestroyWindow(_this->hidden->hwndFrame);
slouken@1895
  2327
                _this->hidden->hwndFrame = NULL;
slouken@1895
  2328
            }
slouken@1895
  2329
        }
slouken@1895
  2330
icculus@1190
  2331
    }
slouken@1895
  2332
    // Free result of an old ListModes() call, because there is
slouken@1895
  2333
    // no FreeListModes() call in SDL!
slouken@1895
  2334
    if (_this->hidden->pListModesResult) {
slouken@1895
  2335
        SDL_free(_this->hidden->pListModesResult);
slouken@1895
  2336
        _this->hidden->pListModesResult = NULL;
slouken@1895
  2337
    }
slouken@1895
  2338
    // Free list of available fullscreen modes
slouken@1895
  2339
    if (_this->hidden->pAvailableFSLibVideoModes) {
slouken@1895
  2340
        FSLib_FreeVideoModeList(_this->hidden->pAvailableFSLibVideoModes);
slouken@1895
  2341
        _this->hidden->pAvailableFSLibVideoModes = NULL;
slouken@1895
  2342
    }
slouken@1895
  2343
    // Free application icon if we had one
slouken@1895
  2344
    if (hptrCurrentIcon) {
slouken@1895
  2345
        WinDestroyPointer(hptrCurrentIcon);
slouken@1895
  2346
        hptrCurrentIcon = NULL;
slouken@1895
  2347
    }
icculus@1190
  2348
}
icculus@1190
  2349
icculus@1190
  2350
/* Set the requested video mode, returning a surface which will be
icculus@1190
  2351
 set to the SDL_VideoSurface.  The width and height will already
icculus@1190
  2352
 be verified by ListModes(), and the video subsystem is free to
icculus@1190
  2353
 set the mode to a supported bit depth different from the one
icculus@1190
  2354
 specified -- the desired bpp will be emulated with a shadow
icculus@1190
  2355
 surface if necessary.  If a new mode is returned, this function
icculus@1190
  2356
 should take care of cleaning up the current mode.
icculus@1190
  2357
 */
slouken@1895
  2358
static SDL_Surface *
slouken@1895
  2359
os2fslib_SetVideoMode(_THIS, SDL_Surface * current,
slouken@1895
  2360
                      int width, int height, int bpp, Uint32 flags)
icculus@1190
  2361
{
slouken@1895
  2362
    static int bFirstCall = 1;
slouken@1895
  2363
    FSLib_VideoMode_p pModeInfo, pModeInfoFound;
slouken@1895
  2364
    FSLib_VideoMode TempModeInfo;
slouken@1895
  2365
    HAB hab;
slouken@1895
  2366
    HMQ hmq;
slouken@1895
  2367
    ERRORID hmqerror;
slouken@1895
  2368
    RECTL rectl;
slouken@1895
  2369
    SDL_Surface *pResult;
slouken@1895
  2370
slouken@1895
  2371
    // If there is no more window, nothing we can do!
slouken@1895
  2372
    if (_this->hidden->iPMThreadStatus != 1)
slouken@1895
  2373
        return NULL;
icculus@1190
  2374
icculus@1190
  2375
#ifdef DEBUG_BUILD
slouken@1895
  2376
    printf
slouken@1895
  2377
        ("[os2fslib_SetVideoMode] : Request for %dx%d @ %dBPP, flags=0x%x\n",
slouken@1895
  2378
         width, height, bpp, flags);
slouken@1895
  2379
    fflush(stdout);
icculus@1190
  2380
#endif
icculus@1190
  2381
slouken@1895
  2382
    // We don't support palette modes!
slouken@1895
  2383
    if (bpp == 8)
slouken@1895
  2384
        bpp = 32;
slouken@1895
  2385
slouken@1895
  2386
    // Also, we don't support resizable modes in fullscreen mode.
slouken@1895
  2387
    if (flags & SDL_RESIZABLE)
slouken@1895
  2388
        flags &= ~SDL_FULLSCREEN;
slouken@1895
  2389
slouken@1895
  2390
    // No double buffered mode
slouken@1895
  2391
    if (flags & SDL_DOUBLEBUF)
slouken@1895
  2392
        flags &= ~SDL_DOUBLEBUF;
slouken@1895
  2393
slouken@1895
  2394
    // And, we don't support HWSURFACE yet.
slouken@1895
  2395
    if (flags & SDL_HWSURFACE) {
slouken@1895
  2396
        flags &= ~SDL_HWSURFACE;
slouken@1895
  2397
        flags |= SDL_SWSURFACE;
slouken@1895
  2398
    }
icculus@1190
  2399
#ifdef DEBUG_BUILD
slouken@1895
  2400
    printf
slouken@1895
  2401
        ("[os2fslib_SetVideoMode] : Changed request to %dx%d @ %dBPP, flags=0x%x\n",
slouken@1895
  2402
         width, height, bpp, flags);
slouken@1895
  2403
    fflush(stdout);
icculus@1190
  2404
#endif
slouken@1895
  2405
slouken@1895
  2406
    // First check if there is such a video mode they want!
slouken@1895
  2407
    pModeInfoFound = NULL;
slouken@1895
  2408
slouken@1895
  2409
    // For fullscreen mode we don't support every resolution!
slouken@1895
  2410
    // So, go through the video modes, and check for such a resolution!
slouken@1895
  2411
    pModeInfoFound = NULL;
slouken@1895
  2412
    pModeInfo = _this->hidden->pAvailableFSLibVideoModes;
slouken@1895
  2413
slouken@1895
  2414
    while (pModeInfo) {
slouken@1895
  2415
        // Check all available fullscreen modes for this resolution
slouken@1895
  2416
        if ((pModeInfo->uiXResolution == width) && (pModeInfo->uiYResolution == height) && (pModeInfo->uiBPP != 8))     // palettized modes not yet supported
slouken@1895
  2417
        {
slouken@1895
  2418
            // If good resolution, try to find the exact BPP, or at least
slouken@1895
  2419
            // something similar...
slouken@1895
  2420
            if (!pModeInfoFound)
slouken@1895
  2421
                pModeInfoFound = pModeInfo;
slouken@1895
  2422
            else if ((pModeInfoFound->uiBPP != bpp) &&
slouken@1895
  2423
                     (pModeInfoFound->uiBPP < pModeInfo->uiBPP))
slouken@1895
  2424
                pModeInfoFound = pModeInfo;
slouken@1895
  2425
        }
slouken@1895
  2426
        pModeInfo = pModeInfo->pNext;
slouken@1895
  2427
    }
slouken@1895
  2428
slouken@1895
  2429
    // If we did not find a good fullscreen mode, then try a similar
slouken@1895
  2430
    if (!pModeInfoFound) {
icculus@1190
  2431
#ifdef DEBUG_BUILD
slouken@1895
  2432
        printf
slouken@1895
  2433
            ("[os2fslib_SetVideoMode] : Requested video mode not found, looking for a similar one!\n");
slouken@1895
  2434
        fflush(stdout);
slouken@1895
  2435
#endif
slouken@1895
  2436
        // Go through the video modes again, and find a similar resolution!
slouken@1895
  2437
        pModeInfo = _this->hidden->pAvailableFSLibVideoModes;
slouken@1895
  2438
        while (pModeInfo) {
slouken@1895
  2439
            // Check all available fullscreen modes for this resolution
slouken@1895
  2440
            if ((pModeInfo->uiXResolution >= width) &&
slouken@1895
  2441
                (pModeInfo->uiYResolution >= height) &&
slouken@1895
  2442
                (pModeInfo->uiBPP == bpp)) {
slouken@1895
  2443
                if (!pModeInfoFound)
slouken@1895
  2444
                    pModeInfoFound = pModeInfo;
slouken@1895
  2445
                else if (((pModeInfoFound->uiXResolution -
slouken@1895
  2446
                           width) * (pModeInfoFound->uiYResolution -
slouken@1895
  2447
                                     height)) >
slouken@1895
  2448
                         ((pModeInfo->uiXResolution -
slouken@1895
  2449
                           width) * (pModeInfo->uiYResolution - height))) {
slouken@1895
  2450
                    // Found a mode which is closer than the current one
slouken@1895
  2451
                    pModeInfoFound = pModeInfo;
slouken@1895
  2452
                }
slouken@1895
  2453
            }
slouken@1895
  2454
            pModeInfo = pModeInfo->pNext;
slouken@1895
  2455
        }
slouken@1895
  2456
    }
slouken@1895
  2457
    // If we did not find a good fullscreen mode, then return NULL
slouken@1895
  2458
    if (!pModeInfoFound) {
slouken@1895
  2459
#ifdef DEBUG_BUILD
slouken@1895
  2460
        printf("[os2fslib_SetVideoMode] : Requested video mode not found!\n");
slouken@1895
  2461
        fflush(stdout);
icculus@1190
  2462
#endif
slouken@1895
  2463
        return NULL;
slouken@1895
  2464
    }
slouken@1895
  2465
#ifdef DEBUG_BUILD
slouken@1895
  2466
    printf("[os2fslib_SetVideoMode] : Found mode!\n");
slouken@1895
  2467
    fflush(stdout);
slouken@1895
  2468
#endif
slouken@1895
  2469
slouken@1895
  2470
    // We'll possibly adjust the structure, so copy out the values
slouken@1895
  2471
    // into TempModeInfo!
slouken@1895
  2472
    SDL_memcpy(&TempModeInfo, pModeInfoFound, sizeof(TempModeInfo));
slouken@1895
  2473
    pModeInfoFound = &TempModeInfo;
slouken@1895
  2474
slouken@1895
  2475
    if (flags & SDL_RESIZABLE) {
slouken@1895
  2476
#ifdef DEBUG_BUILD
slouken@1895
  2477
        printf
slouken@1895
  2478
            ("[os2fslib_SetVideoMode] : Requested mode is resizable, changing width/height\n");
slouken@1895
  2479
        fflush(stdout);
slouken@1895
  2480
#endif
slouken@1895
  2481
        // Change width and height to requested one!
slouken@1895
  2482
        TempModeInfo.uiXResolution = width;
slouken@1895
  2483
        TempModeInfo.uiYResolution = height;
slouken@1895
  2484
        TempModeInfo.uiScanLineSize = width * ((TempModeInfo.uiBPP + 7) / 8);
icculus@1190
  2485
    }
slouken@1895
  2486
    // We can try create new surface!
slouken@1895
  2487
slouken@1895
  2488
    // Make sure this thread is prepared for using the Presentation Manager!
slouken@1895
  2489
    hab = WinInitialize(0);
slouken@1895
  2490
    hmq = WinCreateMsgQueue(hab, 0);
slouken@1895
  2491
    // Remember if there was an error at WinCreateMsgQueue(), because we don't
slouken@1895
  2492
    // want to destroy somebody else's queue later. :)
slouken@1895
  2493
    hmqerror = WinGetLastError(hab);
slouken@1895
  2494
slouken@1895
  2495
slouken@1895
  2496
slouken@1895
  2497
    if (DosRequestMutexSem
slouken@1895
  2498
        (_this->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT) == NO_ERROR) {
icculus@1190
  2499
#ifdef DEBUG_BUILD
slouken@1895
  2500
        printf("[os2fslib_SetVideoMode] : Creating new SW surface\n");
slouken@1895
  2501
        fflush(stdout);
icculus@1190
  2502
#endif
icculus@1190
  2503
slouken@1895
  2504
        // Create new software surface!
slouken@1895
  2505
        pResult = SDL_CreateRGBSurface(SDL_SWSURFACE,
slouken@1895
  2506
                                       pModeInfoFound->uiXResolution,
slouken@1895
  2507
                                       pModeInfoFound->uiYResolution,
slouken@1895
  2508
                                       pModeInfoFound->uiBPP,
slouken@1895
  2509
                                       ((unsigned int) pModeInfoFound->
slouken@1895
  2510
                                        PixelFormat.
slouken@1895
  2511
                                        ucRedMask) << pModeInfoFound->
slouken@1895
  2512
                                       PixelFormat.ucRedPosition,
slouken@1895
  2513
                                       ((unsigned int) pModeInfoFound->
slouken@1895
  2514
                                        PixelFormat.
slouken@1895
  2515
                                        ucGreenMask) << pModeInfoFound->
slouken@1895
  2516
                                       PixelFormat.ucGreenPosition,
slouken@1895
  2517
                                       ((unsigned int) pModeInfoFound->
slouken@1895
  2518
                                        PixelFormat.
slouken@1895
  2519
                                        ucBlueMask) << pModeInfoFound->
slouken@1895
  2520
                                       PixelFormat.ucBluePosition,
slouken@1895
  2521
                                       ((unsigned int) pModeInfoFound->
slouken@1895
  2522
                                        PixelFormat.
slouken@1895
  2523
                                        ucAlphaMask) << pModeInfoFound->
slouken@1895
  2524
                                       PixelFormat.ucAlphaPosition);
slouken@1895
  2525
slouken@1895
  2526
        if (pResult == NULL) {
slouken@1895
  2527
            DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer);
slouken@1895
  2528
            SDL_OutOfMemory();
slouken@1895
  2529
            return NULL;
slouken@1895
  2530
        }
slouken@1895
  2531
#ifdef DEBUG_BUILD
slouken@1895
  2532
        printf("[os2fslib_SetVideoMode] : Adjusting pixel format\n");
slouken@1895
  2533
        fflush(stdout);
slouken@1895
  2534
#endif
slouken@1895
  2535
slouken@1895
  2536
        // Adjust pixel format mask!
slouken@1895
  2537
        pResult->format->Rmask =
slouken@1895
  2538
            ((unsigned int) pModeInfoFound->PixelFormat.
slouken@1895
  2539
             ucRedMask) << pModeInfoFound->PixelFormat.ucRedPosition;
slouken@1895
  2540
        pResult->format->Rshift = pModeInfoFound->PixelFormat.ucRedPosition;
slouken@1895
  2541
        pResult->format->Rloss = pModeInfoFound->PixelFormat.ucRedAdjust;
slouken@1895
  2542
        pResult->format->Gmask =
slouken@1895
  2543
            ((unsigned int) pModeInfoFound->PixelFormat.
slouken@1895
  2544
             ucGreenMask) << pModeInfoFound->PixelFormat.ucGreenPosition;
slouken@1895
  2545
        pResult->format->Gshift = pModeInfoFound->PixelFormat.ucGreenPosition;