src/video/os2fslib/SDL_os2fslib.c
author Ozkan Sezer <sezeroz@gmail.com>
Sat, 24 Mar 2018 22:25:33 +0300
branchSDL-1.2
changeset 11964 6c37a15030e7
parent 6137 4720145f848b
permissions -rw-r--r--
OS/2 fixes:

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