diff options
Diffstat (limited to 'src/video/wincommon')
-rw-r--r-- | src/video/wincommon/SDL_lowvideo.h | 148 | ||||
-rw-r--r-- | src/video/wincommon/SDL_sysevents.c | 865 | ||||
-rw-r--r-- | src/video/wincommon/SDL_sysmouse.c | 259 | ||||
-rw-r--r-- | src/video/wincommon/SDL_sysmouse_c.h | 33 | ||||
-rw-r--r-- | src/video/wincommon/SDL_syswm.c | 297 | ||||
-rw-r--r-- | src/video/wincommon/SDL_syswm_c.h | 35 | ||||
-rw-r--r-- | src/video/wincommon/SDL_wingl.c | 647 | ||||
-rw-r--r-- | src/video/wincommon/SDL_wingl_c.h | 135 | ||||
-rw-r--r-- | src/video/wincommon/wmmsg.h | 1030 |
9 files changed, 3449 insertions, 0 deletions
diff --git a/src/video/wincommon/SDL_lowvideo.h b/src/video/wincommon/SDL_lowvideo.h new file mode 100644 index 0000000..940995c --- /dev/null +++ b/src/video/wincommon/SDL_lowvideo.h @@ -0,0 +1,148 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_lowvideo_h +#define _SDL_lowvideo_h + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#ifndef SetClassLongPtr +#define SetClassLongPtr SetClassLong +#endif +#ifndef GetWindowLongPtr +#define GetWindowLongPtr GetWindowLong +#endif +#ifndef SetWindowLongPtr +#define SetWindowLongPtr SetWindowLong +#endif +#ifndef GWLP_WNDPROC +#define GWLP_WNDPROC GWL_WNDPROC +#endif +#ifndef GWLP_HINSTANCE +#define GWLP_HINSTANCE GWL_HINSTANCE +#endif +#ifndef GCLP_HICON +#define GCLP_HICON GCL_HICON +#endif + +#include "../SDL_sysvideo.h" + +/* Hidden "this" pointer for the video functions */ +#define _THIS SDL_VideoDevice *this + +#define FULLSCREEN() \ + ((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) + +#define WINDIB_FULLSCREEN() \ +( \ + SDL_VideoSurface && \ + FULLSCREEN() && \ + (((SDL_VideoSurface->flags & SDL_OPENGL ) == SDL_OPENGL ) || \ + ((SDL_strcmp(this->name, "windib") == 0) || \ + (SDL_strcmp(this->name, "gapi") == 0))) \ +) +#define DDRAW_FULLSCREEN() \ +( \ + SDL_VideoSurface && \ + FULLSCREEN() && \ + ((SDL_VideoSurface->flags & SDL_OPENGL ) != SDL_OPENGL ) && \ + (SDL_strcmp(this->name, "directx") == 0) \ +) + +#define DINPUT_FULLSCREEN() \ +( \ + FULLSCREEN() && \ + (strcmp(this->name, "directx") == 0) \ +) + +#define DINPUT() (strcmp(this->name, "directx") == 0) + +/* The main window -- and a function to set it for the audio */ +#ifdef _WIN32_WCE +extern LPWSTR SDL_Appname; +#else +extern LPSTR SDL_Appname; +#endif +extern HINSTANCE SDL_Instance; +extern HWND SDL_Window; +extern BOOL SDL_windowid; + +/* Variables and functions exported to other parts of the native video + subsystem (SDL_sysevents.c) +*/ +extern void WIN_FlushMessageQueue(); + +/* Called by windows message loop when application is activated */ +extern void (*WIN_Activate)(_THIS, BOOL active, BOOL minimized); + +/* Called by windows message loop when system palette is available */ +extern void (*WIN_RealizePalette)(_THIS); + +/* Called by windows message loop when the system palette changes */ +extern void (*WIN_PaletteChanged)(_THIS, HWND window); + +/* Called by windows message loop when a portion of the screen needs update */ +extern void (*WIN_WinPAINT)(_THIS, HDC hdc); + +/* Called by windows message loop when the message isn't handled */ +extern LONG (*HandleMessage)(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +/* The window cursor (from SDL_sysmouse.c) */ +extern HCURSOR SDL_hcursor; + +/* The bounds of the window in screen coordinates */ +extern RECT SDL_bounds; + +/* The position of the window in windowed mode */ +extern int SDL_windowX; +extern int SDL_windowY; + +/* Flag -- SDL is performing a resize, rather than the user */ +extern int SDL_resizing; + +/* Flag -- the mouse is in relative motion mode */ +extern int mouse_relative; + +/* The GDI fullscreen mode currently active */ +#ifndef NO_CHANGEDISPLAYSETTINGS +extern DEVMODE SDL_desktop_mode; +extern DEVMODE SDL_fullscreen_mode; +#endif + +/* The system gamma ramp for GDI modes */ +extern WORD *gamma_saved; + +/* This is really from SDL_dx5audio.c */ +extern void DX5_SoundFocus(HWND window); + +/* DJM: This is really from SDL_sysevents.c, we need it in + GDL_CreateWindow as well */ +LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +/* JFP: Implementation of ToUnicode() that works on 9x/ME/2K/XP */ +typedef int (WINAPI *ToUnicodeFN)(UINT, UINT, PBYTE, LPWSTR, int, UINT); + +extern ToUnicodeFN SDL_ToUnicode; + +#endif /* SDL_lowvideo_h */ diff --git a/src/video/wincommon/SDL_sysevents.c b/src/video/wincommon/SDL_sysevents.c new file mode 100644 index 0000000..f7db2e2 --- /dev/null +++ b/src/video/wincommon/SDL_sysevents.c @@ -0,0 +1,865 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +/* Make sure XBUTTON stuff is defined that isn't in older Platform SDKs... */ +#ifndef WM_XBUTTONDOWN +#define WM_XBUTTONDOWN 0x020B +#endif +#ifndef WM_XBUTTONUP +#define WM_XBUTTONUP 0x020C +#endif +#ifndef GET_XBUTTON_WPARAM +#define GET_XBUTTON_WPARAM(w) (HIWORD(w)) +#endif + +#include "SDL_events.h" +#include "SDL_video.h" +#include "SDL_syswm.h" +#include "../SDL_sysvideo.h" +#include "../../events/SDL_sysevents.h" +#include "../../events/SDL_events_c.h" +#include "SDL_lowvideo.h" +#include "SDL_syswm_c.h" +#include "SDL_main.h" +#include "SDL_loadso.h" + +#ifdef WMMSG_DEBUG +#include "wmmsg.h" +#endif + +#include "../windib/SDL_gapidibvideo.h" + +#ifdef SDL_VIDEO_DRIVER_GAPI +#include "../gapi/SDL_gapivideo.h" +#endif + +#ifdef _WIN32_WCE +#define IsZoomed(HWND) 1 +#define NO_GETKEYBOARDSTATE +#if _WIN32_WCE < 420 +#define NO_CHANGEDISPLAYSETTINGS +#endif +#endif + +/* The window we use for everything... */ +#ifdef _WIN32_WCE +LPWSTR SDL_Appname = NULL; +#else +LPSTR SDL_Appname = NULL; +#endif +Uint32 SDL_Appstyle = 0; +HINSTANCE SDL_Instance = NULL; +HWND SDL_Window = NULL; +RECT SDL_bounds = {0, 0, 0, 0}; +int SDL_windowX = 0; +int SDL_windowY = 0; +int SDL_resizing = 0; +int mouse_relative = 0; +int posted = 0; +#ifndef NO_CHANGEDISPLAYSETTINGS +DEVMODE SDL_desktop_mode; +DEVMODE SDL_fullscreen_mode; +#endif +WORD *gamma_saved = NULL; + + +/* Functions called by the message processing function */ +LONG (*HandleMessage)(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)=NULL; +void (*WIN_Activate)(_THIS, BOOL active, BOOL iconic); +void (*WIN_RealizePalette)(_THIS); +void (*WIN_PaletteChanged)(_THIS, HWND window); +void (*WIN_WinPAINT)(_THIS, HDC hdc); +extern void DIB_SwapGamma(_THIS); + +#ifndef NO_GETKEYBOARDSTATE +/* Variables and support functions for SDL_ToUnicode() */ +static int codepage; +static int Is9xME(); +static int GetCodePage(); +static int WINAPI ToUnicode9xME(UINT vkey, UINT scancode, BYTE *keystate, LPWSTR wchars, int wsize, UINT flags); + +ToUnicodeFN SDL_ToUnicode = ToUnicode9xME; +#endif /* !NO_GETKEYBOARDSTATE */ + + +#if defined(_WIN32_WCE) + +//AdjustWindowRect is not available under WinCE 2003 +#define AdjustWindowRect(a,b,c) (AdjustWindowRectEx((a),(b),(c),0)) + +// dynamically load aygshell dll because we want SDL to work on HPC and be300 +HINSTANCE aygshell = NULL; +BOOL (WINAPI *SHFullScreen)(HWND hwndRequester, DWORD dwState) = 0; + +#define SHFS_SHOWTASKBAR 0x0001 +#define SHFS_HIDETASKBAR 0x0002 +#define SHFS_SHOWSIPBUTTON 0x0004 +#define SHFS_HIDESIPBUTTON 0x0008 +#define SHFS_SHOWSTARTICON 0x0010 +#define SHFS_HIDESTARTICON 0x0020 + +static void LoadAygshell(void) +{ + if( !aygshell ) + aygshell = SDL_LoadObject("aygshell.dll"); + if( (aygshell != 0) && (SHFullScreen == 0) ) + { + SHFullScreen = (int (WINAPI *)(struct HWND__ *,unsigned long)) SDL_LoadFunction(aygshell, "SHFullScreen"); + } +} + +#endif + +/* JC 14 Mar 2006 + This is used all over the place, in the windib driver and in the dx5 driver + So we may as well stick it here instead of having multiple copies scattered + about +*/ +void WIN_FlushMessageQueue() +{ + MSG msg; + while ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) { + if ( msg.message == WM_QUIT ) break; + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } +} + +static void SDL_RestoreGameMode(void) +{ +#ifdef _WIN32_WCE //Under ce we don't minimize, therefore no restore + +#ifdef SDL_VIDEO_DRIVER_GAPI + SDL_VideoDevice *this = current_video; + if(SDL_strcmp(this->name, "gapi") == 0) + { + if( this->hidden->gapiInfo->suspended ) + { + this->hidden->gapiInfo->suspended = 0; + } + } +#endif + +#else + ShowWindow(SDL_Window, SW_RESTORE); +#endif + +#ifndef NO_CHANGEDISPLAYSETTINGS +#ifndef _WIN32_WCE + ChangeDisplaySettings(&SDL_fullscreen_mode, CDS_FULLSCREEN); +#endif +#endif /* NO_CHANGEDISPLAYSETTINGS */ +} +static void SDL_RestoreDesktopMode(void) +{ + +#ifdef _WIN32_WCE + +#ifdef SDL_VIDEO_DRIVER_GAPI + SDL_VideoDevice *this = current_video; + if(SDL_strcmp(this->name, "gapi") == 0) + { + if( !this->hidden->gapiInfo->suspended ) + { + this->hidden->gapiInfo->suspended = 1; + } + } +#endif + +#else + /* WinCE does not have a taskbar, so minimizing is not convenient */ + ShowWindow(SDL_Window, SW_MINIMIZE); +#endif + +#ifndef NO_CHANGEDISPLAYSETTINGS +#ifndef _WIN32_WCE + ChangeDisplaySettings(NULL, 0); +#endif +#endif /* NO_CHANGEDISPLAYSETTINGS */ +} + +#ifdef WM_MOUSELEAVE +/* + Special code to handle mouse leave events - this sucks... + http://support.microsoft.com/support/kb/articles/q183/1/07.asp + + TrackMouseEvent() is only available on Win98 and WinNT. + _TrackMouseEvent() is available on Win95, but isn't yet in the mingw32 + development environment, and only works on systems that have had IE 3.0 + or newer installed on them (which is not the case with the base Win95). + Therefore, we implement our own version of _TrackMouseEvent() which + uses our own implementation if TrackMouseEvent() is not available. +*/ +static BOOL (WINAPI *_TrackMouseEvent)(TRACKMOUSEEVENT *ptme) = NULL; + +static VOID CALLBACK +TrackMouseTimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime) +{ + RECT rect; + POINT pt; + + GetClientRect(hWnd, &rect); + MapWindowPoints(hWnd, NULL, (LPPOINT)&rect, 2); + GetCursorPos(&pt); + if ( !PtInRect(&rect, pt) || (WindowFromPoint(pt) != hWnd) ) { + if ( !KillTimer(hWnd, idEvent) ) { + /* Error killing the timer! */ + } + PostMessage(hWnd, WM_MOUSELEAVE, 0, 0); + } +} +static BOOL WINAPI WIN_TrackMouseEvent(TRACKMOUSEEVENT *ptme) +{ + if ( ptme->dwFlags == TME_LEAVE ) { + return SetTimer(ptme->hwndTrack, ptme->dwFlags, 100, + (TIMERPROC)TrackMouseTimerProc) != 0; + } + return FALSE; +} +#endif /* WM_MOUSELEAVE */ + +/* Function to retrieve the current keyboard modifiers */ +static void WIN_GetKeyboardState(void) +{ +#ifndef NO_GETKEYBOARDSTATE + SDLMod state; + BYTE keyboard[256]; + Uint8 *kstate = SDL_GetKeyState(NULL); + + state = KMOD_NONE; + if ( GetKeyboardState(keyboard) ) { + if ( keyboard[VK_LSHIFT] & 0x80) { + state |= KMOD_LSHIFT; + kstate[SDLK_LSHIFT] = SDL_PRESSED; + } + if ( keyboard[VK_RSHIFT] & 0x80) { + state |= KMOD_RSHIFT; + kstate[SDLK_RSHIFT] = SDL_PRESSED; + } + if ( keyboard[VK_LCONTROL] & 0x80) { + state |= KMOD_LCTRL; + kstate[SDLK_LCTRL] = SDL_PRESSED; + } + if ( keyboard[VK_RCONTROL] & 0x80) { + state |= KMOD_RCTRL; + kstate[SDLK_RCTRL] = SDL_PRESSED; + } + if ( keyboard[VK_LMENU] & 0x80) { + state |= KMOD_LALT; + kstate[SDLK_LALT] = SDL_PRESSED; + } + if ( keyboard[VK_RMENU] & 0x80) { + state |= KMOD_RALT; + kstate[SDLK_RALT] = SDL_PRESSED; + } + if ( keyboard[VK_NUMLOCK] & 0x01) { + state |= KMOD_NUM; + kstate[SDLK_NUMLOCK] = SDL_PRESSED; + } + if ( keyboard[VK_CAPITAL] & 0x01) { + state |= KMOD_CAPS; + kstate[SDLK_CAPSLOCK] = SDL_PRESSED; + } + } + SDL_SetModState(state); +#endif /* !NO_GETKEYBOARDSTATE */ +} + +/* The main Win32 event handler +DJM: This is no longer static as (DX5/DIB)_CreateWindow needs it +*/ +LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + SDL_VideoDevice *this = current_video; + static int mouse_pressed = 0; +#ifdef WMMSG_DEBUG + fprintf(stderr, "Received windows message: "); + if ( msg > MAX_WMMSG ) { + fprintf(stderr, "%d", msg); + } else { + fprintf(stderr, "%s", wmtab[msg]); + } + fprintf(stderr, " -- 0x%X, 0x%X\n", wParam, lParam); +#endif + switch (msg) { + + case WM_ACTIVATE: { + SDL_VideoDevice *this = current_video; + BOOL active, minimized; + Uint8 appstate; + + minimized = HIWORD(wParam); + active = (LOWORD(wParam) != WA_INACTIVE) && !minimized; + if ( active ) { + /* Gain the following states */ + appstate = SDL_APPACTIVE|SDL_APPINPUTFOCUS; + if ( this->input_grab != SDL_GRAB_OFF ) { + WIN_GrabInput(this, SDL_GRAB_ON); + } + if ( !(SDL_GetAppState()&SDL_APPINPUTFOCUS) ) { + if ( ! DDRAW_FULLSCREEN() ) { + DIB_SwapGamma(this); + } + if ( WINDIB_FULLSCREEN() ) { + SDL_RestoreGameMode(); + } + } +#if defined(_WIN32_WCE) + if ( WINDIB_FULLSCREEN() ) { + LoadAygshell(); + if( SHFullScreen ) + SHFullScreen(SDL_Window, SHFS_HIDESTARTICON|SHFS_HIDETASKBAR|SHFS_HIDESIPBUTTON); + else + ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_HIDE); + } +#endif + posted = SDL_PrivateAppActive(1, appstate); + WIN_GetKeyboardState(); + } else { + /* Lose the following states */ + appstate = SDL_APPINPUTFOCUS; + if ( minimized ) { + appstate |= SDL_APPACTIVE; + } + if ( this->input_grab != SDL_GRAB_OFF ) { + WIN_GrabInput(this, SDL_GRAB_OFF); + } + if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) { + if ( ! DDRAW_FULLSCREEN() ) { + DIB_SwapGamma(this); + } + if ( WINDIB_FULLSCREEN() ) { + SDL_RestoreDesktopMode(); +#if defined(_WIN32_WCE) + LoadAygshell(); + if( SHFullScreen ) + SHFullScreen(SDL_Window, SHFS_SHOWSTARTICON|SHFS_SHOWTASKBAR|SHFS_SHOWSIPBUTTON); + else + ShowWindow(FindWindow(TEXT("HHTaskBar"),NULL),SW_SHOW); +#endif + } + } + posted = SDL_PrivateAppActive(0, appstate); + } + WIN_Activate(this, active, minimized); + return(0); + } + break; + + case WM_MOUSEMOVE: { + +#ifdef WM_MOUSELEAVE + /* No need to handle SDL_APPMOUSEFOCUS when fullscreen */ + if ( SDL_VideoSurface && !FULLSCREEN() ) { + /* mouse has entered the window */ + + if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) { + TRACKMOUSEEVENT tme; + + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = SDL_Window; + _TrackMouseEvent(&tme); + } + } +#endif /* WM_MOUSELEAVE */ + + /* Mouse motion is handled in DIB_PumpEvents or + * DX5_PumpEvents, depending on the video driver + * in use */ + + posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); + } + return(0); + +#ifdef WM_MOUSELEAVE + case WM_MOUSELEAVE: { + + /* No need to handle SDL_APPMOUSEFOCUS when fullscreen */ + if ( SDL_VideoSurface && !FULLSCREEN() ) { + /* mouse has left the window */ + /* or */ + /* Elvis has left the building! */ + posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); + } + } + return(0); +#endif /* WM_MOUSELEAVE */ + + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: { + /* Mouse is handled by DirectInput when fullscreen */ + if ( SDL_VideoSurface && ! DINPUT() ) { + WORD xbuttonval = 0; + Uint8 button, state; + + /* DJM: + We want the SDL window to take focus so that + it acts like a normal windows "component" + (e.g. gains keyboard focus on a mouse click). + */ + SetFocus(SDL_Window); + + /* Figure out which button to use */ + switch (msg) { + case WM_LBUTTONDOWN: + button = SDL_BUTTON_LEFT; + state = SDL_PRESSED; + break; + case WM_LBUTTONUP: + button = SDL_BUTTON_LEFT; + state = SDL_RELEASED; + break; + case WM_MBUTTONDOWN: + button = SDL_BUTTON_MIDDLE; + state = SDL_PRESSED; + break; + case WM_MBUTTONUP: + button = SDL_BUTTON_MIDDLE; + state = SDL_RELEASED; + break; + case WM_RBUTTONDOWN: + button = SDL_BUTTON_RIGHT; + state = SDL_PRESSED; + break; + case WM_RBUTTONUP: + button = SDL_BUTTON_RIGHT; + state = SDL_RELEASED; + break; + case WM_XBUTTONDOWN: + xbuttonval = GET_XBUTTON_WPARAM(wParam); + button = SDL_BUTTON_X1 + xbuttonval - 1; + state = SDL_PRESSED; + break; + case WM_XBUTTONUP: + xbuttonval = GET_XBUTTON_WPARAM(wParam); + button = SDL_BUTTON_X1 + xbuttonval - 1; + state = SDL_RELEASED; + break; + default: + /* Eh? Unknown button? */ + return(0); + } + if ( state == SDL_PRESSED ) { + /* Grab mouse so we get up events */ + if ( ++mouse_pressed > 0 ) { + SetCapture(hwnd); + } + } else { + /* Release mouse after all up events */ + if ( --mouse_pressed <= 0 ) { + ReleaseCapture(); + mouse_pressed = 0; + } + } + posted = SDL_PrivateMouseButton( + state, button, 0, 0); + + /* + * MSDN says: + * "Unlike the WM_LBUTTONUP, WM_MBUTTONUP, and WM_RBUTTONUP + * messages, an application should return TRUE from [an + * XBUTTON message] if it processes it. Doing so will allow + * software that simulates this message on Microsoft Windows + * systems earlier than Windows 2000 to determine whether + * the window procedure processed the message or called + * DefWindowProc to process it. + */ + if (xbuttonval > 0) + return(TRUE); + } + } + return(0); + + +#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) + case WM_MOUSEWHEEL: + if ( SDL_VideoSurface && ! DINPUT() ) { + int move = (short)HIWORD(wParam); + if ( move ) { + Uint8 button; + if ( move > 0 ) + button = SDL_BUTTON_WHEELUP; + else + button = SDL_BUTTON_WHEELDOWN; + posted = SDL_PrivateMouseButton( + SDL_PRESSED, button, 0, 0); + posted |= SDL_PrivateMouseButton( + SDL_RELEASED, button, 0, 0); + } + } + return(0); +#endif + +#ifdef WM_GETMINMAXINFO + /* This message is sent as a way for us to "check" the values + * of a position change. If we don't like it, we can adjust + * the values before they are changed. + */ + case WM_GETMINMAXINFO: { + MINMAXINFO *info; + RECT size; + int x, y; + int style; + int width; + int height; + + /* We don't want to clobber an internal resize */ + if ( SDL_resizing ) + return(0); + + /* We allow resizing with the SDL_RESIZABLE flag */ + if ( SDL_PublicSurface && + (SDL_PublicSurface->flags & SDL_RESIZABLE) ) { + return(0); + } + + /* Get the current position of our window */ + GetWindowRect(SDL_Window, &size); + x = size.left; + y = size.top; + + /* Calculate current width and height of our window */ + size.top = 0; + size.left = 0; + if ( SDL_PublicSurface != NULL ) { + size.bottom = SDL_PublicSurface->h; + size.right = SDL_PublicSurface->w; + } else { + size.bottom = 0; + size.right = 0; + } + + /* DJM - according to the docs for GetMenu(), the + return value is undefined if hwnd is a child window. + Aparently it's too difficult for MS to check + inside their function, so I have to do it here. + */ + style = GetWindowLong(hwnd, GWL_STYLE); + AdjustWindowRect( + &size, + style, + style & WS_CHILDWINDOW ? FALSE + : GetMenu(hwnd) != NULL); + + width = size.right - size.left; + height = size.bottom - size.top; + + /* Fix our size to the current size */ + info = (MINMAXINFO *)lParam; + info->ptMaxSize.x = width; + info->ptMaxSize.y = height; + info->ptMaxPosition.x = x; + info->ptMaxPosition.y = y; + info->ptMinTrackSize.x = width; + info->ptMinTrackSize.y = height; + info->ptMaxTrackSize.x = width; + info->ptMaxTrackSize.y = height; + } + return(0); +#endif /* WM_GETMINMAXINFO */ + + case WM_WINDOWPOSCHANGING: { + WINDOWPOS *windowpos = (WINDOWPOS*)lParam; + + /* When menu is at the side or top, Windows likes + to try to reposition the fullscreen window when + changing video modes. + */ + if ( !SDL_resizing && + SDL_PublicSurface && + (SDL_PublicSurface->flags & SDL_FULLSCREEN) ) { + windowpos->x = 0; + windowpos->y = 0; + } + } + return(0); + + case WM_WINDOWPOSCHANGED: { + SDL_VideoDevice *this = current_video; + int w, h; + + GetClientRect(SDL_Window, &SDL_bounds); + ClientToScreen(SDL_Window, (LPPOINT)&SDL_bounds); + ClientToScreen(SDL_Window, (LPPOINT)&SDL_bounds+1); + if ( !SDL_resizing && !IsZoomed(SDL_Window) && + SDL_PublicSurface && + !(SDL_PublicSurface->flags & SDL_FULLSCREEN) ) { + SDL_windowX = SDL_bounds.left; + SDL_windowY = SDL_bounds.top; + } + w = SDL_bounds.right-SDL_bounds.left; + h = SDL_bounds.bottom-SDL_bounds.top; + if ( this->input_grab != SDL_GRAB_OFF ) { + ClipCursor(&SDL_bounds); + } + if ( SDL_PublicSurface && + (SDL_PublicSurface->flags & SDL_RESIZABLE) ) { + SDL_PrivateResize(w, h); + } + } + break; + + /* We need to set the cursor */ + case WM_SETCURSOR: { + Uint16 hittest; + + hittest = LOWORD(lParam); + if ( hittest == HTCLIENT ) { + SetCursor(SDL_hcursor); + return(TRUE); + } + } + break; + + /* We are about to get palette focus! */ + case WM_QUERYNEWPALETTE: { + WIN_RealizePalette(current_video); + return(TRUE); + } + break; + + /* Another application changed the palette */ + case WM_PALETTECHANGED: { + WIN_PaletteChanged(current_video, (HWND)wParam); + } + break; + + /* We were occluded, refresh our display */ + case WM_PAINT: { + HDC hdc; + PAINTSTRUCT ps; + + hdc = BeginPaint(SDL_Window, &ps); + if ( current_video->screen && + !(current_video->screen->flags & SDL_OPENGL) ) { + WIN_WinPAINT(current_video, hdc); + } + EndPaint(SDL_Window, &ps); + } + return(0); + + /* DJM: Send an expose event in this case */ + case WM_ERASEBKGND: { + posted = SDL_PrivateExpose(); + } + return(0); + + case WM_CLOSE: { + if ( (posted = SDL_PrivateQuit()) ) + PostQuitMessage(0); + } + return(0); + + case WM_DESTROY: { + PostQuitMessage(0); + } + return(0); + +#ifndef NO_GETKEYBOARDSTATE + case WM_INPUTLANGCHANGE: { + codepage = GetCodePage(); + } + return(TRUE); +#endif + + default: { + /* Special handling by the video driver */ + if (HandleMessage) { + return(HandleMessage(current_video, + hwnd, msg, wParam, lParam)); + } + } + break; + } + return(DefWindowProc(hwnd, msg, wParam, lParam)); +} + +/* Allow the application handle to be stored and retrieved later */ +static void *SDL_handle = NULL; + +void SDL_SetModuleHandle(void *handle) +{ + SDL_handle = handle; +} +void *SDL_GetModuleHandle(void) +{ + void *handle; + + if ( SDL_handle ) { + handle = SDL_handle; + } else { + handle = GetModuleHandle(NULL); + } + return(handle); +} + +/* This allows the SDL_WINDOWID hack */ +BOOL SDL_windowid = FALSE; + +static int app_registered = 0; + +/* Register the class for this application -- exported for winmain.c */ +int SDL_RegisterApp(char *name, Uint32 style, void *hInst) +{ + WNDCLASS class; +#ifdef WM_MOUSELEAVE + HMODULE handle; +#endif + + /* Only do this once... */ + if ( app_registered ) { + ++app_registered; + return(0); + } + +#ifndef CS_BYTEALIGNCLIENT +#define CS_BYTEALIGNCLIENT 0 +#endif + if ( ! name && ! SDL_Appname ) { + name = "SDL_app"; + SDL_Appstyle = CS_BYTEALIGNCLIENT; + SDL_Instance = hInst ? hInst : SDL_GetModuleHandle(); + } + + if ( name ) { +#ifdef _WIN32_WCE + /* WinCE uses the UNICODE version */ + SDL_Appname = SDL_iconv_utf8_ucs2(name); +#else + SDL_Appname = SDL_iconv_utf8_locale(name); +#endif /* _WIN32_WCE */ + SDL_Appstyle = style; + SDL_Instance = hInst ? hInst : SDL_GetModuleHandle(); + } + + /* Register the application class */ + class.hCursor = NULL; + class.hIcon = LoadImage(SDL_Instance, SDL_Appname, + IMAGE_ICON, + 0, 0, LR_DEFAULTCOLOR); + class.lpszMenuName = NULL; + class.lpszClassName = SDL_Appname; + class.hbrBackground = NULL; + class.hInstance = SDL_Instance; + class.style = SDL_Appstyle; +#if SDL_VIDEO_OPENGL + class.style |= CS_OWNDC; +#endif + class.lpfnWndProc = WinMessage; + class.cbWndExtra = 0; + class.cbClsExtra = 0; + if ( ! RegisterClass(&class) ) { + SDL_SetError("Couldn't register application class"); + return(-1); + } + +#ifdef WM_MOUSELEAVE + /* Get the version of TrackMouseEvent() we use */ + _TrackMouseEvent = NULL; + handle = GetModuleHandle("USER32.DLL"); + if ( handle ) { + _TrackMouseEvent = (BOOL (WINAPI *)(TRACKMOUSEEVENT *))GetProcAddress(handle, "TrackMouseEvent"); + } + if ( _TrackMouseEvent == NULL ) { + _TrackMouseEvent = WIN_TrackMouseEvent; + } +#endif /* WM_MOUSELEAVE */ + +#ifndef NO_GETKEYBOARDSTATE + /* Initialise variables for SDL_ToUnicode() */ + codepage = GetCodePage(); + SDL_ToUnicode = Is9xME() ? ToUnicode9xME : ToUnicode; +#endif + + app_registered = 1; + return(0); +} + +/* Unregisters the windowclass registered in SDL_RegisterApp above. */ +void SDL_UnregisterApp() +{ + WNDCLASS class; + + /* SDL_RegisterApp might not have been called before */ + if ( !app_registered ) { + return; + } + --app_registered; + if ( app_registered == 0 ) { + /* Check for any registered window classes. */ + if ( GetClassInfo(SDL_Instance, SDL_Appname, &class) ) { + UnregisterClass(SDL_Appname, SDL_Instance); + } + SDL_free(SDL_Appname); + SDL_Appname = NULL; + } +} + +#ifndef NO_GETKEYBOARDSTATE +/* JFP: Implementation of ToUnicode() that works on 9x/ME/2K/XP */ + +static int Is9xME() +{ + OSVERSIONINFO info; + + SDL_memset(&info, 0, sizeof(info)); + info.dwOSVersionInfoSize = sizeof(info); + if (!GetVersionEx(&info)) { + return 0; + } + return (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); +} + +static int GetCodePage() +{ + char buff[8]; + int lcid = MAKELCID(LOWORD(GetKeyboardLayout(0)), SORT_DEFAULT); + int cp = GetACP(); + + if (GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE, buff, sizeof(buff))) { + cp = SDL_atoi(buff); + } + return cp; +} + +static int WINAPI ToUnicode9xME(UINT vkey, UINT scancode, PBYTE keystate, LPWSTR wchars, int wsize, UINT flags) +{ + BYTE chars[2]; + + if (ToAsciiEx(vkey, scancode, keystate, (WORD*)chars, 0, GetKeyboardLayout(0)) == 1) { + return MultiByteToWideChar(codepage, 0, chars, 1, wchars, wsize); + } + return 0; +} + +#endif /* !NO_GETKEYBOARDSTATE */ diff --git a/src/video/wincommon/SDL_sysmouse.c b/src/video/wincommon/SDL_sysmouse.c new file mode 100644 index 0000000..b53bf9c --- /dev/null +++ b/src/video/wincommon/SDL_sysmouse.c @@ -0,0 +1,259 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include "SDL_mouse.h" +#include "../../events/SDL_events_c.h" +#include "../SDL_cursor_c.h" +#include "SDL_sysmouse_c.h" +#include "SDL_lowvideo.h" + +#ifdef _WIN32_WCE +#define USE_STATIC_CURSOR +#endif + +HCURSOR SDL_hcursor = NULL; /* Exported for SDL_eventloop.c */ + +/* The implementation dependent data for the window manager cursor */ +/* For some reason when creating a windows cursor, the ands and xors memory + is not copied, so we need to keep track of it and free it when we are done + with the cursor. If we free the memory prematurely, the app crashes. :-} +*/ +struct WMcursor { + HCURSOR curs; +#ifndef USE_STATIC_CURSOR + Uint8 *ands; + Uint8 *xors; +#endif +}; + +/* Convert bits to padded bytes */ +#define PAD_BITS(bits) ((bits+7)/8) + +#ifdef CURSOR_DEBUG +static void PrintBITMAP(FILE *out, char *bits, int w, int h) +{ + int i; + unsigned char ch; + + while ( h-- > 0 ) { + for ( i=0; i<w; ++i ) { + if ( (i%8) == 0 ) + ch = *bits++; + if ( ch&0x80 ) + fprintf(out, "X"); + else + fprintf(out, " "); + ch <<= 1; + } + fprintf(out, "\n"); + } +} +#endif + +#ifndef USE_STATIC_CURSOR +/* Local functions to convert the SDL cursor mask into Windows format */ +static void memnot(Uint8 *dst, Uint8 *src, int len) +{ + while ( len-- > 0 ) + *dst++ = ~*src++; +} +static void memxor(Uint8 *dst, Uint8 *src1, Uint8 *src2, int len) +{ + while ( len-- > 0 ) + *dst++ = (*src1++)^(*src2++); +} +#endif /* !USE_STATIC_CURSOR */ + +void WIN_FreeWMCursor(_THIS, WMcursor *cursor) +{ +#ifndef USE_STATIC_CURSOR + if ( cursor->curs == GetCursor() ) + SetCursor(NULL); + if ( cursor->curs != NULL ) + DestroyCursor(cursor->curs); + if ( cursor->ands != NULL ) + SDL_free(cursor->ands); + if ( cursor->xors != NULL ) + SDL_free(cursor->xors); +#endif /* !USE_STATIC_CURSOR */ + SDL_free(cursor); +} + +WMcursor *WIN_CreateWMCursor(_THIS, + Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y) +{ +#ifdef USE_STATIC_CURSOR + WMcursor *cursor; + + /* Allocate the cursor */ + cursor = (WMcursor *)SDL_malloc(sizeof(*cursor)); + if ( cursor ) { + cursor->curs = LoadCursor(NULL, IDC_ARROW); + } + return(cursor); +#else + WMcursor *cursor; + int allowed_x; + int allowed_y; + int run, pad, i; + Uint8 *aptr, *xptr; + + /* Check to make sure the cursor size is okay */ + allowed_x = GetSystemMetrics(SM_CXCURSOR); + allowed_y = GetSystemMetrics(SM_CYCURSOR); + if ( (w > allowed_x) || (h > allowed_y) ) { + SDL_SetError("Only cursors of dimension (%dx%d) are allowed", + allowed_x, allowed_y); + return(NULL); + } + + /* Allocate the cursor */ + cursor = (WMcursor *)SDL_malloc(sizeof(*cursor)); + if ( cursor == NULL ) { + SDL_SetError("Out of memory"); + return(NULL); + } + cursor->curs = NULL; + cursor->ands = NULL; + cursor->xors = NULL; + + /* Pad out to the normal cursor size */ + run = PAD_BITS(w); + pad = PAD_BITS(allowed_x)-run; + aptr = cursor->ands = (Uint8 *)SDL_malloc((run+pad)*allowed_y); + xptr = cursor->xors = (Uint8 *)SDL_malloc((run+pad)*allowed_y); + if ( (aptr == NULL) || (xptr == NULL) ) { + WIN_FreeWMCursor(NULL, cursor); + SDL_OutOfMemory(); + return(NULL); + } + for ( i=0; i<h; ++i ) { + memxor(xptr, data, mask, run); + xptr += run; + data += run; + memnot(aptr, mask, run); + mask += run; + aptr += run; + SDL_memset(xptr, 0, pad); + xptr += pad; + SDL_memset(aptr, ~0, pad); + aptr += pad; + } + pad += run; + for ( ; i<allowed_y; ++i ) { + SDL_memset(xptr, 0, pad); + xptr += pad; + SDL_memset(aptr, ~0, pad); + aptr += pad; + } + + /* Create the cursor */ + cursor->curs = CreateCursor( + (HINSTANCE)GetWindowLongPtr(SDL_Window, GWLP_HINSTANCE), + hot_x, hot_y, allowed_x, allowed_y, + cursor->ands, cursor->xors); + if ( cursor->curs == NULL ) { + WIN_FreeWMCursor(NULL, cursor); + SDL_SetError("Windows couldn't create the requested cursor"); + return(NULL); + } + return(cursor); +#endif /* USE_STATIC_CURSOR */ +} + +int WIN_ShowWMCursor(_THIS, WMcursor *cursor) +{ + POINT mouse_pos; + + if ( !this->screen ) { + return(0); + } + + /* Set the window cursor to our cursor, if applicable */ + if ( cursor != NULL ) { + SDL_hcursor = cursor->curs; + } else { + SDL_hcursor = NULL; + } + GetCursorPos(&mouse_pos); + if ( PtInRect(&SDL_bounds, mouse_pos) ) { + SetCursor(SDL_hcursor); + } + return(1); +} + +void WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y) +{ + if ( mouse_relative) { + /* RJR: March 28, 2000 + leave physical cursor at center of screen if + mouse hidden and grabbed */ + SDL_PrivateMouseMotion(0, 0, x, y); + } else { + POINT pt; + + /* With DirectInput the position doesn't follow + * the cursor, so it is set manually */ + if ( DINPUT() ) { + SDL_PrivateMouseMotion(0, 0, x, y); + } + + pt.x = x; + pt.y = y; + ClientToScreen(SDL_Window, &pt); + SetCursorPos(pt.x, pt.y); + } +} + +/* Update the current mouse state and position */ +void WIN_UpdateMouse(_THIS) +{ + POINT pt; + + /* Always unset SDL_APPMOUSEFOCUS to give the WM_MOUSEMOVE event + * handler a chance to install a TRACKMOUSEEVENT */ + SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); + + GetCursorPos(&pt); + ScreenToClient(SDL_Window, &pt); + SDL_PrivateMouseMotion(0,0, (Sint16)pt.x, (Sint16)pt.y); +} + +/* Check to see if we need to enter or leave mouse relative mode */ +void WIN_CheckMouseMode(_THIS) +{ +#ifndef _WIN32_WCE + /* If the mouse is hidden and input is grabbed, we use relative mode */ + if ( !(SDL_cursorstate & CURSOR_VISIBLE) && + (this->input_grab != SDL_GRAB_OFF) ) { + mouse_relative = 1; + } else { + mouse_relative = 0; + } +#else + mouse_relative = 0; +#endif +} diff --git a/src/video/wincommon/SDL_sysmouse_c.h b/src/video/wincommon/SDL_sysmouse_c.h new file mode 100644 index 0000000..de75e8e --- /dev/null +++ b/src/video/wincommon/SDL_sysmouse_c.h @@ -0,0 +1,33 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_lowvideo.h" + +/* Functions to be exported */ +extern void WIN_FreeWMCursor(_THIS, WMcursor *cursor); +extern WMcursor *WIN_CreateWMCursor(_THIS, + Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); +extern int WIN_ShowWMCursor(_THIS, WMcursor *cursor); +extern void WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y); +extern void WIN_UpdateMouse(_THIS); +extern void WIN_CheckMouseMode(_THIS); diff --git a/src/video/wincommon/SDL_syswm.c b/src/video/wincommon/SDL_syswm.c new file mode 100644 index 0000000..9212c18 --- /dev/null +++ b/src/video/wincommon/SDL_syswm.c @@ -0,0 +1,297 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include "SDL_version.h" +#include "SDL_video.h" +#include "SDL_loadso.h" +#include "SDL_syswm.h" +#include "../SDL_pixels_c.h" +#include "../SDL_cursor_c.h" +#include "SDL_syswm_c.h" +#include "SDL_wingl_c.h" + + +#ifdef _WIN32_WCE +#define DISABLE_ICON_SUPPORT +#endif + +/* The screen icon -- needs to be freed on SDL_VideoQuit() */ +HICON screen_icn = NULL; + +/* Win32 icon mask semantics are different from those of SDL: + SDL applies the mask to the icon and copies result to desktop. + Win32 applies the mask to the desktop and XORs the icon on. + This means that the SDL mask needs to be applied to the icon and + then inverted and passed to Win32. +*/ +void WIN_SetWMIcon(_THIS, SDL_Surface *icon, Uint8 *mask) +{ +#ifdef DISABLE_ICON_SUPPORT + return; +#else + SDL_Palette *pal_256; + SDL_Surface *icon_256; + Uint8 *pdata, *pwin32; + Uint8 *mdata, *mwin32, m = 0; + int icon_len; + int icon_plen; + int icon_mlen; + int icon_pitch; + int mask_pitch; + SDL_Rect bounds; + int i, skip; + int row, col; + struct /* quasi-BMP format */ Win32Icon { + Uint32 biSize; + Sint32 biWidth; + Sint32 biHeight; + Uint16 biPlanes; + Uint16 biBitCount; + Uint32 biCompression; + Uint32 biSizeImage; + Sint32 biXPelsPerMeter; + Sint32 biYPelsPerMeter; + Uint32 biClrUsed; + Uint32 biClrImportant; + struct /* RGBQUAD -- note it's BGR ordered */ { + Uint8 rgbBlue; + Uint8 rgbGreen; + Uint8 rgbRed; + Uint8 rgbReserved; + } biColors[256]; + /* Pixels: + Uint8 pixels[] + */ + /* Mask: + Uint8 mask[] + */ + } *icon_win32; + + /* Allocate the win32 bmp icon and set everything to zero */ + icon_pitch = ((icon->w+3)&~3); + mask_pitch = ((icon->w+7)/8); + icon_plen = icon->h*icon_pitch; + icon_mlen = icon->h*mask_pitch; + icon_len = sizeof(*icon_win32)+icon_plen+icon_mlen; + icon_win32 = (struct Win32Icon *)SDL_stack_alloc(Uint8, icon_len); + if ( icon_win32 == NULL ) { + return; + } + SDL_memset(icon_win32, 0, icon_len); + + /* Set the basic BMP parameters */ + icon_win32->biSize = sizeof(*icon_win32)-sizeof(icon_win32->biColors); + icon_win32->biWidth = icon->w; + icon_win32->biHeight = icon->h*2; + icon_win32->biPlanes = 1; + icon_win32->biBitCount = 8; + icon_win32->biSizeImage = icon_plen+icon_mlen; + + /* Allocate a standard 256 color icon surface */ + icon_256 = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h, + icon_win32->biBitCount, 0, 0, 0, 0); + if ( icon_256 == NULL ) { + SDL_stack_free(icon_win32); + return; + } + pal_256 = icon_256->format->palette; + if (icon->format->palette && + (icon->format->BitsPerPixel == icon_256->format->BitsPerPixel)){ + Uint8 black; + SDL_memcpy(pal_256->colors, icon->format->palette->colors, + pal_256->ncolors*sizeof(SDL_Color)); + /* Make sure that 0 is black! */ + black = SDL_FindColor(pal_256, 0x00, 0x00, 0x00); + pal_256->colors[black] = pal_256->colors[0]; + pal_256->colors[0].r = 0x00; + pal_256->colors[0].g = 0x00; + pal_256->colors[0].b = 0x00; + } else { + SDL_DitherColors(pal_256->colors, + icon_256->format->BitsPerPixel); + } + + /* Now copy color data to the icon BMP */ + for ( i=0; i<(1<<icon_win32->biBitCount); ++i ) { + icon_win32->biColors[i].rgbRed = pal_256->colors[i].r; + icon_win32->biColors[i].rgbGreen = pal_256->colors[i].g; + icon_win32->biColors[i].rgbBlue = pal_256->colors[i].b; + } + + /* Convert icon to a standard surface format. This may not always + be necessary, as Windows supports a variety of BMP formats, but + it greatly simplifies our code. + */ + bounds.x = 0; + bounds.y = 0; + bounds.w = icon->w; + bounds.h = icon->h; + if ( SDL_LowerBlit(icon, &bounds, icon_256, &bounds) < 0 ) { + SDL_stack_free(icon_win32); + SDL_FreeSurface(icon_256); + return; + } + + /* Copy pixels upside-down to icon BMP, masked with the icon mask */ + if ( SDL_MUSTLOCK(icon_256) || (icon_256->pitch != icon_pitch) ) { + SDL_stack_free(icon_win32); + SDL_FreeSurface(icon_256); + SDL_SetError("Warning: Unexpected icon_256 characteristics"); + return; + } + pdata = (Uint8 *)icon_256->pixels; + mdata = mask; + pwin32 = (Uint8 *)icon_win32+sizeof(*icon_win32)+icon_plen-icon_pitch; + skip = icon_pitch - icon->w; + for ( row=0; row<icon->h; ++row ) { + for ( col=0; col<icon->w; ++col ) { + if ( (col%8) == 0 ) { + m = *mdata++; + } + if ( (m&0x80) != 0x00 ) { + *pwin32 = *pdata; + } + m <<= 1; + ++pdata; + ++pwin32; + } + pdata += skip; + pwin32 += skip; + pwin32 -= 2*icon_pitch; + } + SDL_FreeSurface(icon_256); + + /* Copy mask inverted and upside-down to icon BMP */ + mdata = mask; + mwin32 = (Uint8 *)icon_win32 + +sizeof(*icon_win32)+icon_plen+icon_mlen-mask_pitch; + for ( row=0; row<icon->h; ++row ) { + for ( col=0; col<mask_pitch; ++col ) { + *mwin32++ = ~*mdata++; + } + mwin32 -= 2*mask_pitch; + } + + /* Finally, create the icon handle and set the window icon */ + screen_icn = CreateIconFromResourceEx((Uint8 *)icon_win32, icon_len, + TRUE, 0x00030000, icon->w, icon->h, LR_DEFAULTCOLOR); + if ( screen_icn == NULL ) { + SDL_SetError("Couldn't create Win32 icon handle"); + } else { + SetClassLongPtr(SDL_Window, GCLP_HICON, (LONG_PTR)screen_icn); + } + SDL_stack_free(icon_win32); +#endif /* DISABLE_ICON_SUPPORT */ +} + +typedef BOOL (WINAPI *PtrSetWindowTextW)(HWND hWnd, LPCWSTR lpString); + +void WIN_SetWMCaption(_THIS, const char *title, const char *icon) +{ +#ifdef _WIN32_WCE + /* WinCE uses the UNICODE version */ + LPWSTR lpszW = SDL_iconv_utf8_ucs2((char *)title); + SetWindowText(SDL_Window, lpszW); + SDL_free(lpszW); +#else + Uint16 *lpsz = SDL_iconv_utf8_ucs2(title); + size_t len = WideCharToMultiByte(CP_ACP, 0, lpsz, -1, NULL, 0, NULL, NULL); + char *cvt = SDL_stack_alloc(char, len + 1); + WideCharToMultiByte(CP_ACP, 0, lpsz, -1, cvt, len, NULL, NULL); + SetWindowText(SDL_Window, cvt); + SDL_stack_free(cvt); + SDL_free(lpsz); +#endif +} + +int WIN_IconifyWindow(_THIS) +{ + ShowWindow(SDL_Window, SW_MINIMIZE); + return(1); +} + +SDL_GrabMode WIN_GrabInput(_THIS, SDL_GrabMode mode) +{ + if ( mode == SDL_GRAB_OFF ) { + ClipCursor(NULL); + if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) { + /* RJR: March 28, 2000 + must be leaving relative mode, move mouse from + center of window to where it belongs ... */ + POINT pt; + int x, y; + SDL_GetMouseState(&x,&y); + pt.x = x; + pt.y = y; + ClientToScreen(SDL_Window, &pt); + SetCursorPos(pt.x,pt.y); + } +#ifdef _WIN32_WCE + AllKeys(0); +#endif + } else { + ClipCursor(&SDL_bounds); + if ( !(SDL_cursorstate & CURSOR_VISIBLE) ) { + /* RJR: March 28, 2000 + must be entering relative mode, get ready by + moving mouse to center of window ... */ + POINT pt; + pt.x = (SDL_VideoSurface->w/2); + pt.y = (SDL_VideoSurface->h/2); + ClientToScreen(SDL_Window, &pt); + SetCursorPos(pt.x, pt.y); + } +#ifdef _WIN32_WCE + AllKeys(1); +#endif + } + return(mode); +} + +/* If 'info' is the right version, this function fills it and returns 1. + Otherwise, in case of a version mismatch, it returns -1. +*/ +int WIN_GetWMInfo(_THIS, SDL_SysWMinfo *info) +{ + if ( info->version.major <= SDL_MAJOR_VERSION ) { + info->window = SDL_Window; + if ( SDL_VERSIONNUM(info->version.major, + info->version.minor, + info->version.patch) >= + SDL_VERSIONNUM(1, 2, 5) ) { +#if SDL_VIDEO_OPENGL + info->hglrc = GL_hrc; +#else + info->hglrc = NULL; +#endif + } + return(1); + } else { + SDL_SetError("Application not compiled with SDL %d.%d\n", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + return(-1); + } +} diff --git a/src/video/wincommon/SDL_syswm_c.h b/src/video/wincommon/SDL_syswm_c.h new file mode 100644 index 0000000..5c60af5 --- /dev/null +++ b/src/video/wincommon/SDL_syswm_c.h @@ -0,0 +1,35 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#include "SDL_lowvideo.h" + +/* Data that needs to be freed at SDL_SYS_VideoQuit() */ +extern HICON screen_icn; + +/* Functions to be exported */ +extern void WIN_SetWMIcon(_THIS, SDL_Surface *icon, Uint8 *mask); +extern void WIN_SetWMCaption(_THIS, const char *title, const char *icon); +extern int WIN_IconifyWindow(_THIS); +extern SDL_GrabMode WIN_GrabInput(_THIS, SDL_GrabMode mode); +extern int WIN_GetWMInfo(_THIS, SDL_SysWMinfo *info); + diff --git a/src/video/wincommon/SDL_wingl.c b/src/video/wincommon/SDL_wingl.c new file mode 100644 index 0000000..626bca5 --- /dev/null +++ b/src/video/wincommon/SDL_wingl.c @@ -0,0 +1,647 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* WGL implementation of SDL OpenGL support */ + +#if SDL_VIDEO_OPENGL +#include "SDL_opengl.h" +#endif +#include "SDL_lowvideo.h" +#include "SDL_wingl_c.h" + +#if SDL_VIDEO_OPENGL +#define DEFAULT_GL_DRIVER_PATH "OPENGL32.DLL" +#endif + +/* If setting the HDC fails, we may need to recreate the window (MSDN) */ +static int WIN_GL_ResetWindow(_THIS) +{ + int status = 0; + +#ifndef _WIN32_WCE /* FIXME WinCE needs the UNICODE version of CreateWindow() */ + /* This doesn't work with DirectX code (see CVS comments) */ + /* If we were passed a window, then we can't create a new one */ + if ( !SDL_windowid && SDL_strcmp(this->name, "windib") == 0 ) { + /* Save the existing window attributes */ + LONG style; + RECT rect = { 0, 0, 0, 0 }; + style = GetWindowLong(SDL_Window, GWL_STYLE); + GetWindowRect(SDL_Window, &rect); + DestroyWindow(SDL_Window); + WIN_FlushMessageQueue(); + + SDL_resizing = 1; + SDL_Window = CreateWindow(SDL_Appname, SDL_Appname, + style, + rect.left, rect.top, + (rect.right-rect.left)+1, + (rect.bottom-rect.top)+1, + NULL, NULL, SDL_Instance, NULL); + WIN_FlushMessageQueue(); + SDL_resizing = 0; + + if ( SDL_Window ) { + this->SetCaption(this, this->wm_title, this->wm_icon); + } else { + SDL_SetError("Couldn't create window"); + status = -1; + } + } else +#endif /* !_WIN32_WCE */ + { + SDL_SetError("Unable to reset window for OpenGL context"); + status = -1; + } + return(status); +} + +#if SDL_VIDEO_OPENGL + +static int ExtensionSupported(const char *extension, const char *extensions) +{ + const char *start; + const char *where, *terminator; + + /* Extension names should not have spaces. */ + where = SDL_strchr(extension, ' '); + if ( where || *extension == '\0' ) + return 0; + + if ( ! extensions ) + return 0; + + /* It takes a bit of care to be fool-proof about parsing the + * OpenGL extensions string. Don't be fooled by sub-strings, + * etc. */ + + start = extensions; + + for (;;) + { + where = SDL_strstr(start, extension); + if (!where) break; + + terminator = where + SDL_strlen(extension); + if (where == start || *(where - 1) == ' ') + if (*terminator == ' ' || *terminator == '\0') return 1; + + start = terminator; + } + + return 0; +} + +static int ChoosePixelFormatARB(_THIS, const int *iAttribs, const FLOAT *fAttribs) +{ + HWND hwnd; + HDC hdc; + HGLRC hglrc; + const char * (WINAPI *wglGetExtensionsStringARB)(HDC) = 0; + const char *extensions; + int pformat = 0; + UINT matches = 0; + + hwnd = CreateWindow(SDL_Appname, SDL_Appname, WS_POPUP | WS_DISABLED, + 0, 0, 10, 10, + NULL, NULL, SDL_Instance, NULL); + WIN_FlushMessageQueue(); + + hdc = GetDC(hwnd); + + SetPixelFormat(hdc, ChoosePixelFormat(hdc, &GL_pfd), &GL_pfd); + + hglrc = this->gl_data->wglCreateContext(hdc); + if ( hglrc ) { + this->gl_data->wglMakeCurrent(hdc, hglrc); + } + + wglGetExtensionsStringARB = (const char * (WINAPI *)(HDC)) + this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB"); + + if( wglGetExtensionsStringARB ) { + extensions = wglGetExtensionsStringARB(hdc); + } else { + extensions = NULL; + } + + this->gl_data->WGL_ARB_pixel_format = 0; + if( ExtensionSupported("WGL_ARB_pixel_format", extensions) ) { + BOOL (WINAPI *wglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); + wglChoosePixelFormatARB = + (BOOL (WINAPI *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *)) + this->gl_data->wglGetProcAddress("wglChoosePixelFormatARB"); + if( wglChoosePixelFormatARB && + wglChoosePixelFormatARB(hdc, iAttribs, fAttribs, 1, &pformat, &matches) && pformat ) { + this->gl_data->WGL_ARB_pixel_format = 1; + } + } + + if ( hglrc ) { + this->gl_data->wglMakeCurrent(NULL, NULL); + this->gl_data->wglDeleteContext(hglrc); + } + ReleaseDC(hwnd, hdc); + DestroyWindow(hwnd); + WIN_FlushMessageQueue(); + + return pformat; +} + +#endif /* SDL_VIDEO_OPENGL */ + +int WIN_GL_SetupWindow(_THIS) +{ + int retval; +#if SDL_VIDEO_OPENGL + int i; + int iAttribs[64]; + int *iAttr; + float fAttribs[1] = { 0 }; + const GLubyte *(WINAPI *glGetStringFunc)(GLenum); + const char *wglext; + + /* load the gl driver from a default path */ + if ( ! this->gl_config.driver_loaded ) { + /* no driver has been loaded, use default (ourselves) */ + if ( WIN_GL_LoadLibrary(this, NULL) < 0 ) { + return(-1); + } + } + + /* Set up the pixel format descriptor with our needed format */ + SDL_memset(&GL_pfd, 0, sizeof(GL_pfd)); + GL_pfd.nSize = sizeof(GL_pfd); + GL_pfd.nVersion = 1; + GL_pfd.dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL); + if ( this->gl_config.double_buffer ) { + GL_pfd.dwFlags |= PFD_DOUBLEBUFFER; + } + if ( this->gl_config.stereo ) { + GL_pfd.dwFlags |= PFD_STEREO; + } + GL_pfd.iPixelType = PFD_TYPE_RGBA; + GL_pfd.cColorBits = this->gl_config.buffer_size; + GL_pfd.cRedBits = this->gl_config.red_size; + GL_pfd.cGreenBits = this->gl_config.green_size; + GL_pfd.cBlueBits = this->gl_config.blue_size; + GL_pfd.cAlphaBits = this->gl_config.alpha_size; + GL_pfd.cAccumRedBits = this->gl_config.accum_red_size; + GL_pfd.cAccumGreenBits = this->gl_config.accum_green_size; + GL_pfd.cAccumBlueBits = this->gl_config.accum_blue_size; + GL_pfd.cAccumAlphaBits = this->gl_config.accum_alpha_size; + GL_pfd.cAccumBits = + (GL_pfd.cAccumRedBits + GL_pfd.cAccumGreenBits + + GL_pfd.cAccumBlueBits + GL_pfd.cAccumAlphaBits); + GL_pfd.cDepthBits = this->gl_config.depth_size; + GL_pfd.cStencilBits = this->gl_config.stencil_size; + + /* setup WGL_ARB_pixel_format attribs */ + iAttr = &iAttribs[0]; + + *iAttr++ = WGL_DRAW_TO_WINDOW_ARB; + *iAttr++ = GL_TRUE; + *iAttr++ = WGL_ACCELERATION_ARB; + *iAttr++ = WGL_FULL_ACCELERATION_ARB; + *iAttr++ = WGL_RED_BITS_ARB; + *iAttr++ = this->gl_config.red_size; + *iAttr++ = WGL_GREEN_BITS_ARB; + *iAttr++ = this->gl_config.green_size; + *iAttr++ = WGL_BLUE_BITS_ARB; + *iAttr++ = this->gl_config.blue_size; + + if ( this->gl_config.alpha_size ) { + *iAttr++ = WGL_ALPHA_BITS_ARB; + *iAttr++ = this->gl_config.alpha_size; + } + + *iAttr++ = WGL_DOUBLE_BUFFER_ARB; + *iAttr++ = this->gl_config.double_buffer; + + *iAttr++ = WGL_DEPTH_BITS_ARB; + *iAttr++ = this->gl_config.depth_size; + + if ( this->gl_config.stencil_size ) { + *iAttr++ = WGL_STENCIL_BITS_ARB; + *iAttr++ = this->gl_config.stencil_size; + } + + if ( this->gl_config.accum_red_size ) { + *iAttr++ = WGL_ACCUM_RED_BITS_ARB; + *iAttr++ = this->gl_config.accum_red_size; + } + + if ( this->gl_config.accum_green_size ) { + *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB; + *iAttr++ = this->gl_config.accum_green_size; + } + + if ( this->gl_config.accum_blue_size ) { + *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB; + *iAttr++ = this->gl_config.accum_blue_size; + } + + if ( this->gl_config.accum_alpha_size ) { + *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB; + *iAttr++ = this->gl_config.accum_alpha_size; + } + + if ( this->gl_config.stereo ) { + *iAttr++ = WGL_STEREO_ARB; + *iAttr++ = GL_TRUE; + } + + if ( this->gl_config.multisamplebuffers ) { + *iAttr++ = WGL_SAMPLE_BUFFERS_ARB; + *iAttr++ = this->gl_config.multisamplebuffers; + } + + if ( this->gl_config.multisamplesamples ) { + *iAttr++ = WGL_SAMPLES_ARB; + *iAttr++ = this->gl_config.multisamplesamples; + } + + if ( this->gl_config.accelerated >= 0 ) { + *iAttr++ = WGL_ACCELERATION_ARB; + *iAttr++ = (this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB : WGL_NO_ACCELERATION_ARB); + } + + *iAttr = 0; + + for ( i=0; ; ++i ) { + /* Get the window device context for our OpenGL drawing */ + GL_hdc = GetDC(SDL_Window); + if ( GL_hdc == NULL ) { + SDL_SetError("Unable to get DC for SDL_Window"); + return(-1); + } + + /* Choose and set the closest available pixel format */ + pixel_format = ChoosePixelFormatARB(this, iAttribs, fAttribs); + if ( !pixel_format ) { + pixel_format = ChoosePixelFormat(GL_hdc, &GL_pfd); + } + if ( !pixel_format ) { + SDL_SetError("No matching GL pixel format available"); + return(-1); + } + if ( !SetPixelFormat(GL_hdc, pixel_format, &GL_pfd) ) { + if ( i == 0 ) { + /* First time through, try resetting the window */ + if ( WIN_GL_ResetWindow(this) < 0 ) { + return(-1); + } + continue; + } + SDL_SetError("Unable to set HDC pixel format"); + return(-1); + } + /* We either succeeded or failed by this point */ + break; + } + DescribePixelFormat(GL_hdc, pixel_format, sizeof(GL_pfd), &GL_pfd); + + GL_hrc = this->gl_data->wglCreateContext(GL_hdc); + if ( GL_hrc == NULL ) { + SDL_SetError("Unable to create GL context"); + return(-1); + } + if ( WIN_GL_MakeCurrent(this) < 0 ) { + return(-1); + } + gl_active = 1; + + /* Get the wglGetPixelFormatAttribivARB pointer for the context */ + if ( this->gl_data->WGL_ARB_pixel_format ) { + this->gl_data->wglGetPixelFormatAttribivARB = + (BOOL (WINAPI *)(HDC, int, int, UINT, const int *, int *)) + this->gl_data->wglGetProcAddress("wglGetPixelFormatAttribivARB"); + } else { + this->gl_data->wglGetPixelFormatAttribivARB = NULL; + } + + /* Vsync control under Windows. Checking glGetString here is + * somewhat a documented and reliable hack - it was originally + * as a feature added by mistake, but since so many people rely + * on it, it will not be removed. strstr should be safe here.*/ + glGetStringFunc = WIN_GL_GetProcAddress(this, "glGetString"); + if ( glGetStringFunc ) { + wglext = (const char *)glGetStringFunc(GL_EXTENSIONS); + } else { + /* Uh oh, something is seriously wrong here... */ + wglext = NULL; + } + if ( wglext && SDL_strstr(wglext, "WGL_EXT_swap_control") ) { + this->gl_data->wglSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglSwapIntervalEXT"); + this->gl_data->wglGetSwapIntervalEXT = WIN_GL_GetProcAddress(this, "wglGetSwapIntervalEXT"); + } else { + this->gl_data->wglSwapIntervalEXT = NULL; + this->gl_data->wglGetSwapIntervalEXT = NULL; + } + if ( this->gl_config.swap_control >= 0 ) { + if ( this->gl_data->wglSwapIntervalEXT ) { + this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control); + } + } +#else + SDL_SetError("WIN driver not configured with OpenGL"); +#endif + if ( gl_active ) { + retval = 0; + } else { + retval = -1; + } + return(retval); +} + +void WIN_GL_ShutDown(_THIS) +{ +#if SDL_VIDEO_OPENGL + /* Clean up OpenGL */ + if ( GL_hrc ) { + this->gl_data->wglMakeCurrent(NULL, NULL); + this->gl_data->wglDeleteContext(GL_hrc); + GL_hrc = NULL; + } + if ( GL_hdc ) { + ReleaseDC(SDL_Window, GL_hdc); + GL_hdc = NULL; + } + gl_active = 0; + + WIN_GL_UnloadLibrary(this); +#endif /* SDL_VIDEO_OPENGL */ +} + +#if SDL_VIDEO_OPENGL + +/* Make the current context active */ +int WIN_GL_MakeCurrent(_THIS) +{ + int retval; + + retval = 0; + if ( ! this->gl_data->wglMakeCurrent(GL_hdc, GL_hrc) ) { + SDL_SetError("Unable to make GL context current"); + retval = -1; + } + return(retval); +} + +/* Get attribute data from wgl. */ +int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) +{ + int retval; + + if (attrib == SDL_GL_SWAP_CONTROL) { + if ( this->gl_data->wglGetSwapIntervalEXT ) { + *value = this->gl_data->wglGetSwapIntervalEXT(); + return 0; + } + return -1; + } + + if ( this->gl_data->wglGetPixelFormatAttribivARB ) { + int wgl_attrib; + + switch(attrib) { + case SDL_GL_RED_SIZE: + wgl_attrib = WGL_RED_BITS_ARB; + break; + case SDL_GL_GREEN_SIZE: + wgl_attrib = WGL_GREEN_BITS_ARB; + break; + case SDL_GL_BLUE_SIZE: + wgl_attrib = WGL_BLUE_BITS_ARB; + break; + case SDL_GL_ALPHA_SIZE: + wgl_attrib = WGL_ALPHA_BITS_ARB; + break; + case SDL_GL_DOUBLEBUFFER: + wgl_attrib = WGL_DOUBLE_BUFFER_ARB; + break; + case SDL_GL_BUFFER_SIZE: + wgl_attrib = WGL_COLOR_BITS_ARB; + break; + case SDL_GL_DEPTH_SIZE: + wgl_attrib = WGL_DEPTH_BITS_ARB; + break; + case SDL_GL_STENCIL_SIZE: + wgl_attrib = WGL_STENCIL_BITS_ARB; + break; + case SDL_GL_ACCUM_RED_SIZE: + wgl_attrib = WGL_ACCUM_RED_BITS_ARB; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + wgl_attrib = WGL_ACCUM_GREEN_BITS_ARB; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + wgl_attrib = WGL_ACCUM_BLUE_BITS_ARB; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + wgl_attrib = WGL_ACCUM_ALPHA_BITS_ARB; + break; + case SDL_GL_STEREO: + wgl_attrib = WGL_STEREO_ARB; + break; + case SDL_GL_MULTISAMPLEBUFFERS: + wgl_attrib = WGL_SAMPLE_BUFFERS_ARB; + break; + case SDL_GL_MULTISAMPLESAMPLES: + wgl_attrib = WGL_SAMPLES_ARB; + break; + case SDL_GL_ACCELERATED_VISUAL: + wgl_attrib = WGL_ACCELERATION_ARB; + this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value); + if ( *value == WGL_NO_ACCELERATION_ARB ) { + *value = SDL_FALSE; + } else { + *value = SDL_TRUE; + } + return 0; + default: + return(-1); + } + this->gl_data->wglGetPixelFormatAttribivARB(GL_hdc, pixel_format, 0, 1, &wgl_attrib, value); + + return 0; + } + + retval = 0; + switch ( attrib ) { + case SDL_GL_RED_SIZE: + *value = GL_pfd.cRedBits; + break; + case SDL_GL_GREEN_SIZE: + *value = GL_pfd.cGreenBits; + break; + case SDL_GL_BLUE_SIZE: + *value = GL_pfd.cBlueBits; + break; + case SDL_GL_ALPHA_SIZE: + *value = GL_pfd.cAlphaBits; + break; + case SDL_GL_DOUBLEBUFFER: + if ( GL_pfd.dwFlags & PFD_DOUBLEBUFFER ) { + *value = 1; + } else { + *value = 0; + } + break; + case SDL_GL_BUFFER_SIZE: + *value = GL_pfd.cColorBits; + break; + case SDL_GL_DEPTH_SIZE: + *value = GL_pfd.cDepthBits; + break; + case SDL_GL_STENCIL_SIZE: + *value = GL_pfd.cStencilBits; + break; + case SDL_GL_ACCUM_RED_SIZE: + *value = GL_pfd.cAccumRedBits; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + *value = GL_pfd.cAccumGreenBits; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + *value = GL_pfd.cAccumBlueBits; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + *value = GL_pfd.cAccumAlphaBits; + break; + case SDL_GL_STEREO: + if ( GL_pfd.dwFlags & PFD_STEREO ) { + *value = 1; + } else { + *value = 0; + } + break; + case SDL_GL_MULTISAMPLEBUFFERS: + *value = 0; + break; + case SDL_GL_MULTISAMPLESAMPLES: + *value = 1; + break; + case SDL_GL_SWAP_CONTROL: + if ( this->gl_data->wglGetSwapIntervalEXT ) { + *value = this->gl_data->wglGetSwapIntervalEXT(); + return 0; + } else { + return -1; + } + break; + default: + retval = -1; + break; + } + return retval; +} + +void WIN_GL_SwapBuffers(_THIS) +{ + SwapBuffers(GL_hdc); +} + +void WIN_GL_UnloadLibrary(_THIS) +{ + if ( this->gl_config.driver_loaded ) { + FreeLibrary((HMODULE)this->gl_config.dll_handle); + + this->gl_data->wglGetProcAddress = NULL; + this->gl_data->wglCreateContext = NULL; + this->gl_data->wglDeleteContext = NULL; + this->gl_data->wglMakeCurrent = NULL; + this->gl_data->wglGetPixelFormatAttribivARB = NULL; + this->gl_data->wglSwapIntervalEXT = NULL; + this->gl_data->wglGetSwapIntervalEXT = NULL; + + this->gl_config.dll_handle = NULL; + this->gl_config.driver_loaded = 0; + } +} + +/* Passing a NULL path means load pointers from the application */ +int WIN_GL_LoadLibrary(_THIS, const char* path) +{ + HMODULE handle; + + if ( gl_active ) { + SDL_SetError("OpenGL context already created"); + return -1; + } + + if ( path == NULL ) { + path = DEFAULT_GL_DRIVER_PATH; + } + handle = LoadLibrary(path); + if ( handle == NULL ) { + SDL_SetError("Could not load OpenGL library"); + return -1; + } + + /* Unload the old driver and reset the pointers */ + WIN_GL_UnloadLibrary(this); + + /* Load new function pointers */ + SDL_memset(this->gl_data, 0, sizeof(*this->gl_data)); + this->gl_data->wglGetProcAddress = (void * (WINAPI *)(const char *)) + GetProcAddress(handle, "wglGetProcAddress"); + this->gl_data->wglCreateContext = (HGLRC (WINAPI *)(HDC)) + GetProcAddress(handle, "wglCreateContext"); + this->gl_data->wglDeleteContext = (BOOL (WINAPI *)(HGLRC)) + GetProcAddress(handle, "wglDeleteContext"); + this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC)) + GetProcAddress(handle, "wglMakeCurrent"); + this->gl_data->wglSwapIntervalEXT = (void (WINAPI *)(int)) + GetProcAddress(handle, "wglSwapIntervalEXT"); + this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *)(void)) + GetProcAddress(handle, "wglGetSwapIntervalEXT"); + + if ( (this->gl_data->wglGetProcAddress == NULL) || + (this->gl_data->wglCreateContext == NULL) || + (this->gl_data->wglDeleteContext == NULL) || + (this->gl_data->wglMakeCurrent == NULL) ) { + SDL_SetError("Could not retrieve OpenGL functions"); + FreeLibrary(handle); + return -1; + } + + this->gl_config.dll_handle = handle; + SDL_strlcpy(this->gl_config.driver_path, path, SDL_arraysize(this->gl_config.driver_path)); + this->gl_config.driver_loaded = 1; + return 0; +} + +void *WIN_GL_GetProcAddress(_THIS, const char* proc) +{ + void *func; + + /* This is to pick up extensions */ + func = this->gl_data->wglGetProcAddress(proc); + if ( ! func ) { + /* This is probably a normal GL function */ + func = GetProcAddress(this->gl_config.dll_handle, proc); + } + return func; +} + +#endif /* SDL_VIDEO_OPENGL */ diff --git a/src/video/wincommon/SDL_wingl_c.h b/src/video/wincommon/SDL_wingl_c.h new file mode 100644 index 0000000..c3fb6a8 --- /dev/null +++ b/src/video/wincommon/SDL_wingl_c.h @@ -0,0 +1,135 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* WGL implementation of SDL OpenGL support */ + +#include "../SDL_sysvideo.h" + + +struct SDL_PrivateGLData { + int gl_active; /* to stop switching drivers while we have a valid context */ + +#if SDL_VIDEO_OPENGL + PIXELFORMATDESCRIPTOR GL_pfd; + HDC GL_hdc; + HGLRC GL_hrc; + int pixel_format; + int WGL_ARB_pixel_format; + + void * (WINAPI *wglGetProcAddress)(const char *proc); + + HGLRC (WINAPI *wglCreateContext)(HDC hdc); + + BOOL (WINAPI *wglDeleteContext)(HGLRC hglrc); + + BOOL (WINAPI *wglMakeCurrent)(HDC hdc, HGLRC hglrc); + + BOOL (WINAPI *wglGetPixelFormatAttribivARB)(HDC hdc, int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int *piAttributes, + int *piValues); + void (WINAPI *wglSwapIntervalEXT)(int interval); + int (WINAPI *wglGetSwapIntervalEXT)(void); +#endif /* SDL_VIDEO_OPENGL */ +}; + +/* Old variable names */ +#define gl_active (this->gl_data->gl_active) +#define GL_pfd (this->gl_data->GL_pfd) +#define GL_hdc (this->gl_data->GL_hdc) +#define GL_hrc (this->gl_data->GL_hrc) +#define pixel_format (this->gl_data->pixel_format) + +/* OpenGL functions */ +extern int WIN_GL_SetupWindow(_THIS); +extern void WIN_GL_ShutDown(_THIS); +#if SDL_VIDEO_OPENGL +extern int WIN_GL_MakeCurrent(_THIS); +extern int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value); +extern void WIN_GL_SwapBuffers(_THIS); +extern void WIN_GL_UnloadLibrary(_THIS); +extern int WIN_GL_LoadLibrary(_THIS, const char* path); +extern void *WIN_GL_GetProcAddress(_THIS, const char* proc); +#endif + +#if SDL_VIDEO_OPENGL + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#endif diff --git a/src/video/wincommon/wmmsg.h b/src/video/wincommon/wmmsg.h new file mode 100644 index 0000000..175a8ce --- /dev/null +++ b/src/video/wincommon/wmmsg.h @@ -0,0 +1,1030 @@ + +#define MAX_WMMSG (sizeof(wmtab)/sizeof(wmtab[0])) + +char *wmtab[] = { + "WM_NULL", + "WM_CREATE", + "WM_DESTROY", + "WM_MOVE", + "UNKNOWN (4)", + "WM_SIZE", + "WM_ACTIVATE", + "WM_SETFOCUS", + "WM_KILLFOCUS", + "UNKNOWN (9)", + "WM_ENABLE", + "WM_SETREDRAW", + "WM_SETTEXT", + "WM_GETTEXT", + "WM_GETTEXTLENGTH", + "WM_PAINT", + "WM_CLOSE", + "WM_QUERYENDSESSION", + "WM_QUIT", + "WM_QUERYOPEN", + "WM_ERASEBKGND", + "WM_SYSCOLORCHANGE", + "WM_ENDSESSION", + "UNKNOWN (23)", + "WM_SHOWWINDOW", + "UNKNOWN (25)", + "WM_SETTINGCHANGE", + "WM_DEVMODECHANGE", + "WM_ACTIVATEAPP", + "WM_FONTCHANGE", + "WM_TIMECHANGE", + "WM_CANCELMODE", + "WM_SETCURSOR", + "WM_MOUSEACTIVATE", + "WM_CHILDACTIVATE", + "WM_QUEUESYNC", + "WM_GETMINMAXINFO", + "UNKNOWN (37)", + "WM_PAINTICON", + "WM_ICONERASEBKGND", + "WM_NEXTDLGCTL", + "UNKNOWN (41)", + "WM_SPOOLERSTATUS", + "WM_DRAWITEM", + "WM_MEASUREITEM", + "WM_DELETEITEM", + "WM_VKEYTOITEM", + "WM_CHARTOITEM", + "WM_SETFONT", + "WM_GETFONT", + "WM_SETHOTKEY", + "WM_GETHOTKEY", + "UNKNOWN (52)", + "UNKNOWN (53)", + "UNKNOWN (54)", + "WM_QUERYDRAGICON", + "UNKNOWN (56)", + "WM_COMPAREITEM", + "UNKNOWN (58)", + "UNKNOWN (59)", + "UNKNOWN (60)", + "WM_GETOBJECT", + "UNKNOWN (62)", + "UNKNOWN (63)", + "UNKNOWN (64)", + "WM_COMPACTING", + "UNKNOWN (66)", + "UNKNOWN (67)", + "WM_COMMNOTIFY", + "UNKNOWN (69)", + "WM_WINDOWPOSCHANGING", + "WM_WINDOWPOSCHANGED", + "WM_POWER", + "UNKNOWN (73)", + "WM_COPYDATA", + "WM_CANCELJOURNAL", + "UNKNOWN (76)", + "UNKNOWN (77)", + "WM_NOTIFY", + "UNKNOWN (79)", + "WM_INPUTLANGCHANGEREQUEST", + "WM_INPUTLANGCHANGE", + "WM_TCARD", + "WM_HELP", + "WM_USERCHANGED", + "WM_NOTIFYFORMAT", + "UNKNOWN (86)", + "UNKNOWN (87)", + "UNKNOWN (88)", + "UNKNOWN (89)", + "UNKNOWN (90)", + "UNKNOWN (91)", + "UNKNOWN (92)", + "UNKNOWN (93)", + "UNKNOWN (94)", + "UNKNOWN (95)", + "UNKNOWN (96)", + "UNKNOWN (97)", + "UNKNOWN (98)", + "UNKNOWN (99)", + "UNKNOWN (100)", + "UNKNOWN (101)", + "UNKNOWN (102)", + "UNKNOWN (103)", + "UNKNOWN (104)", + "UNKNOWN (105)", + "UNKNOWN (106)", + "UNKNOWN (107)", + "UNKNOWN (108)", + "UNKNOWN (109)", + "UNKNOWN (110)", + "UNKNOWN (111)", + "UNKNOWN (112)", + "UNKNOWN (113)", + "UNKNOWN (114)", + "UNKNOWN (115)", + "UNKNOWN (116)", + "UNKNOWN (117)", + "UNKNOWN (118)", + "UNKNOWN (119)", + "UNKNOWN (120)", + "UNKNOWN (121)", + "UNKNOWN (122)", + "WM_CONTEXTMENU", + "WM_STYLECHANGING", + "WM_STYLECHANGED", + "WM_DISPLAYCHANGE", + "WM_GETICON", + "WM_SETICON", + "WM_NCCREATE", + "WM_NCDESTROY", + "WM_NCCALCSIZE", + "WM_NCHITTEST", + "WM_NCPAINT", + "WM_NCACTIVATE", + "WM_GETDLGCODE", + "WM_SYNCPAINT", + "UNKNOWN (137)", + "UNKNOWN (138)", + "UNKNOWN (139)", + "UNKNOWN (140)", + "UNKNOWN (141)", + "UNKNOWN (142)", + "UNKNOWN (143)", + "UNKNOWN (144)", + "UNKNOWN (145)", + "UNKNOWN (146)", + "UNKNOWN (147)", + "UNKNOWN (148)", + "UNKNOWN (149)", + "UNKNOWN (150)", + "UNKNOWN (151)", + "UNKNOWN (152)", + "UNKNOWN (153)", + "UNKNOWN (154)", + "UNKNOWN (155)", + "UNKNOWN (156)", + "UNKNOWN (157)", + "UNKNOWN (158)", + "UNKNOWN (159)", + "WM_NCMOUSEMOVE", + "WM_NCLBUTTONDOWN", + "WM_NCLBUTTONUP", + "WM_NCLBUTTONDBLCLK", + "WM_NCRBUTTONDOWN", + "WM_NCRBUTTONUP", + "WM_NCRBUTTONDBLCLK", + "WM_NCMBUTTONDOWN", + "WM_NCMBUTTONUP", + "WM_NCMBUTTONDBLCLK", + "UNKNOWN (170)", + "UNKNOWN (171)", + "UNKNOWN (172)", + "UNKNOWN (173)", + "UNKNOWN (174)", + "UNKNOWN (175)", + "UNKNOWN (176)", + "UNKNOWN (177)", + "UNKNOWN (178)", + "UNKNOWN (179)", + "UNKNOWN (180)", + "UNKNOWN (181)", + "UNKNOWN (182)", + "UNKNOWN (183)", + "UNKNOWN (184)", + "UNKNOWN (185)", + "UNKNOWN (186)", + "UNKNOWN (187)", + "UNKNOWN (188)", + "UNKNOWN (189)", + "UNKNOWN (190)", + "UNKNOWN (191)", + "UNKNOWN (192)", + "UNKNOWN (193)", + "UNKNOWN (194)", + "UNKNOWN (195)", + "UNKNOWN (196)", + "UNKNOWN (197)", + "UNKNOWN (198)", + "UNKNOWN (199)", + "UNKNOWN (200)", + "UNKNOWN (201)", + "UNKNOWN (202)", + "UNKNOWN (203)", + "UNKNOWN (204)", + "UNKNOWN (205)", + "UNKNOWN (206)", + "UNKNOWN (207)", + "UNKNOWN (208)", + "UNKNOWN (209)", + "UNKNOWN (210)", + "UNKNOWN (211)", + "UNKNOWN (212)", + "UNKNOWN (213)", + "UNKNOWN (214)", + "UNKNOWN (215)", + "UNKNOWN (216)", + "UNKNOWN (217)", + "UNKNOWN (218)", + "UNKNOWN (219)", + "UNKNOWN (220)", + "UNKNOWN (221)", + "UNKNOWN (222)", + "UNKNOWN (223)", + "UNKNOWN (224)", + "UNKNOWN (225)", + "UNKNOWN (226)", + "UNKNOWN (227)", + "UNKNOWN (228)", + "UNKNOWN (229)", + "UNKNOWN (230)", + "UNKNOWN (231)", + "UNKNOWN (232)", + "UNKNOWN (233)", + "UNKNOWN (234)", + "UNKNOWN (235)", + "UNKNOWN (236)", + "UNKNOWN (237)", + "UNKNOWN (238)", + "UNKNOWN (239)", + "UNKNOWN (240)", + "UNKNOWN (241)", + "UNKNOWN (242)", + "UNKNOWN (243)", + "UNKNOWN (244)", + "UNKNOWN (245)", + "UNKNOWN (246)", + "UNKNOWN (247)", + "UNKNOWN (248)", + "UNKNOWN (249)", + "UNKNOWN (250)", + "UNKNOWN (251)", + "UNKNOWN (252)", + "UNKNOWN (253)", + "UNKNOWN (254)", + "UNKNOWN (255)", + "WM_KEYDOWN", + "WM_KEYUP", + "WM_CHAR", + "WM_DEADCHAR", + "WM_SYSKEYDOWN", + "WM_SYSKEYUP", + "WM_SYSCHAR", + "WM_SYSDEADCHAR", + "WM_KEYLAST", + "UNKNOWN (265)", + "UNKNOWN (266)", + "UNKNOWN (267)", + "UNKNOWN (268)", + "UNKNOWN (269)", + "UNKNOWN (270)", + "UNKNOWN (271)", + "WM_INITDIALOG", + "WM_COMMAND", + "WM_SYSCOMMAND", + "WM_TIMER", + "WM_HSCROLL", + "WM_VSCROLL", + "WM_INITMENU", + "WM_INITMENUPOPUP", + "UNKNOWN (280)", + "UNKNOWN (281)", + "UNKNOWN (282)", + "UNKNOWN (283)", + "UNKNOWN (284)", + "UNKNOWN (285)", + "UNKNOWN (286)", + "WM_MENUSELECT", + "WM_MENUCHAR", + "WM_ENTERIDLE", + "WM_MENURBUTTONUP", + "WM_MENUDRAG", + "WM_MENUGETOBJECT", + "WM_UNINITMENUPOPUP", + "WM_MENUCOMMAND", + "UNKNOWN (295)", + "UNKNOWN (296)", + "UNKNOWN (297)", + "UNKNOWN (298)", + "UNKNOWN (299)", + "UNKNOWN (300)", + "UNKNOWN (301)", + "UNKNOWN (302)", + "UNKNOWN (303)", + "UNKNOWN (304)", + "UNKNOWN (305)", + "WM_CTLCOLORMSGBOX", + "WM_CTLCOLOREDIT", + "WM_CTLCOLORLISTBOX", + "WM_CTLCOLORBTN", + "WM_CTLCOLORDLG", + "WM_CTLCOLORSCROLLBAR", + "WM_CTLCOLORSTATIC", + "UNKNOWN (313)", + "UNKNOWN (314)", + "UNKNOWN (315)", + "UNKNOWN (316)", + "UNKNOWN (317)", + "UNKNOWN (318)", + "UNKNOWN (319)", + "UNKNOWN (320)", + "UNKNOWN (321)", + "UNKNOWN (322)", + "UNKNOWN (323)", + "UNKNOWN (324)", + "UNKNOWN (325)", + "UNKNOWN (326)", + "UNKNOWN (327)", + "UNKNOWN (328)", + "UNKNOWN (329)", + "UNKNOWN (330)", + "UNKNOWN (331)", + "UNKNOWN (332)", + "UNKNOWN (333)", + "UNKNOWN (334)", + "UNKNOWN (335)", + "UNKNOWN (336)", + "UNKNOWN (337)", + "UNKNOWN (338)", + "UNKNOWN (339)", + "UNKNOWN (340)", + "UNKNOWN (341)", + "UNKNOWN (342)", + "UNKNOWN (343)", + "UNKNOWN (344)", + "UNKNOWN (345)", + "UNKNOWN (346)", + "UNKNOWN (347)", + "UNKNOWN (348)", + "UNKNOWN (349)", + "UNKNOWN (350)", + "UNKNOWN (351)", + "UNKNOWN (352)", + "UNKNOWN (353)", + "UNKNOWN (354)", + "UNKNOWN (355)", + "UNKNOWN (356)", + "UNKNOWN (357)", + "UNKNOWN (358)", + "UNKNOWN (359)", + "UNKNOWN (360)", + "UNKNOWN (361)", + "UNKNOWN (362)", + "UNKNOWN (363)", + "UNKNOWN (364)", + "UNKNOWN (365)", + "UNKNOWN (366)", + "UNKNOWN (367)", + "UNKNOWN (368)", + "UNKNOWN (369)", + "UNKNOWN (370)", + "UNKNOWN (371)", + "UNKNOWN (372)", + "UNKNOWN (373)", + "UNKNOWN (374)", + "UNKNOWN (375)", + "UNKNOWN (376)", + "UNKNOWN (377)", + "UNKNOWN (378)", + "UNKNOWN (379)", + "UNKNOWN (380)", + "UNKNOWN (381)", + "UNKNOWN (382)", + "UNKNOWN (383)", + "UNKNOWN (384)", + "UNKNOWN (385)", + "UNKNOWN (386)", + "UNKNOWN (387)", + "UNKNOWN (388)", + "UNKNOWN (389)", + "UNKNOWN (390)", + "UNKNOWN (391)", + "UNKNOWN (392)", + "UNKNOWN (393)", + "UNKNOWN (394)", + "UNKNOWN (395)", + "UNKNOWN (396)", + "UNKNOWN (397)", + "UNKNOWN (398)", + "UNKNOWN (399)", + "UNKNOWN (400)", + "UNKNOWN (401)", + "UNKNOWN (402)", + "UNKNOWN (403)", + "UNKNOWN (404)", + "UNKNOWN (405)", + "UNKNOWN (406)", + "UNKNOWN (407)", + "UNKNOWN (408)", + "UNKNOWN (409)", + "UNKNOWN (410)", + "UNKNOWN (411)", + "UNKNOWN (412)", + "UNKNOWN (413)", + "UNKNOWN (414)", + "UNKNOWN (415)", + "UNKNOWN (416)", + "UNKNOWN (417)", + "UNKNOWN (418)", + "UNKNOWN (419)", + "UNKNOWN (420)", + "UNKNOWN (421)", + "UNKNOWN (422)", + "UNKNOWN (423)", + "UNKNOWN (424)", + "UNKNOWN (425)", + "UNKNOWN (426)", + "UNKNOWN (427)", + "UNKNOWN (428)", + "UNKNOWN (429)", + "UNKNOWN (430)", + "UNKNOWN (431)", + "UNKNOWN (432)", + "UNKNOWN (433)", + "UNKNOWN (434)", + "UNKNOWN (435)", + "UNKNOWN (436)", + "UNKNOWN (437)", + "UNKNOWN (438)", + "UNKNOWN (439)", + "UNKNOWN (440)", + "UNKNOWN (441)", + "UNKNOWN (442)", + "UNKNOWN (443)", + "UNKNOWN (444)", + "UNKNOWN (445)", + "UNKNOWN (446)", + "UNKNOWN (447)", + "UNKNOWN (448)", + "UNKNOWN (449)", + "UNKNOWN (450)", + "UNKNOWN (451)", + "UNKNOWN (452)", + "UNKNOWN (453)", + "UNKNOWN (454)", + "UNKNOWN (455)", + "UNKNOWN (456)", + "UNKNOWN (457)", + "UNKNOWN (458)", + "UNKNOWN (459)", + "UNKNOWN (460)", + "UNKNOWN (461)", + "UNKNOWN (462)", + "UNKNOWN (463)", + "UNKNOWN (464)", + "UNKNOWN (465)", + "UNKNOWN (466)", + "UNKNOWN (467)", + "UNKNOWN (468)", + "UNKNOWN (469)", + "UNKNOWN (470)", + "UNKNOWN (471)", + "UNKNOWN (472)", + "UNKNOWN (473)", + "UNKNOWN (474)", + "UNKNOWN (475)", + "UNKNOWN (476)", + "UNKNOWN (477)", + "UNKNOWN (478)", + "UNKNOWN (479)", + "UNKNOWN (480)", + "UNKNOWN (481)", + "UNKNOWN (482)", + "UNKNOWN (483)", + "UNKNOWN (484)", + "UNKNOWN (485)", + "UNKNOWN (486)", + "UNKNOWN (487)", + "UNKNOWN (488)", + "UNKNOWN (489)", + "UNKNOWN (490)", + "UNKNOWN (491)", + "UNKNOWN (492)", + "UNKNOWN (493)", + "UNKNOWN (494)", + "UNKNOWN (495)", + "UNKNOWN (496)", + "UNKNOWN (497)", + "UNKNOWN (498)", + "UNKNOWN (499)", + "UNKNOWN (500)", + "UNKNOWN (501)", + "UNKNOWN (502)", + "UNKNOWN (503)", + "UNKNOWN (504)", + "UNKNOWN (505)", + "UNKNOWN (506)", + "UNKNOWN (507)", + "UNKNOWN (508)", + "UNKNOWN (509)", + "UNKNOWN (510)", + "UNKNOWN (511)", + "WM_MOUSEMOVE", + "WM_LBUTTONDOWN", + "WM_LBUTTONUP", + "WM_LBUTTONDBLCLK", + "WM_RBUTTONDOWN", + "WM_RBUTTONUP", + "WM_RBUTTONDBLCLK", + "WM_MBUTTONDOWN", + "WM_MBUTTONUP", + "WM_MOUSELAST", + "WM_MOUSEWHEEL", + "WM_XBUTTONDOWN", + "WM_XBUTTONUP", + "UNKNOWN (525)", + "UNKNOWN (526)", + "UNKNOWN (527)", + "WM_PARENTNOTIFY", + "WM_ENTERMENULOOP", + "WM_EXITMENULOOP", + "WM_NEXTMENU", + "WM_SIZING", + "WM_CAPTURECHANGED", + "WM_MOVING", + "UNKNOWN (535)", + "WM_POWERBROADCAST", + "WM_DEVICECHANGE", + "UNKNOWN (538)", + "UNKNOWN (539)", + "UNKNOWN (540)", + "UNKNOWN (541)", + "UNKNOWN (542)", + "UNKNOWN (543)", + "WM_MDICREATE", + "WM_MDIDESTROY", + "WM_MDIACTIVATE", + "WM_MDIRESTORE", + "WM_MDINEXT", + "WM_MDIMAXIMIZE", + "WM_MDITILE", + "WM_MDICASCADE", + "WM_MDIICONARRANGE", + "WM_MDIGETACTIVE", + "UNKNOWN (554)", + "UNKNOWN (555)", + "UNKNOWN (556)", + "UNKNOWN (557)", + "UNKNOWN (558)", + "UNKNOWN (559)", + "WM_MDISETMENU", + "WM_ENTERSIZEMOVE", + "WM_EXITSIZEMOVE", + "WM_DROPFILES", + "WM_MDIREFRESHMENU", + "UNKNOWN (565)", + "UNKNOWN (566)", + "UNKNOWN (567)", + "UNKNOWN (568)", + "UNKNOWN (569)", + "UNKNOWN (570)", + "UNKNOWN (571)", + "UNKNOWN (572)", + "UNKNOWN (573)", + "UNKNOWN (574)", + "UNKNOWN (575)", + "UNKNOWN (576)", + "UNKNOWN (577)", + "UNKNOWN (578)", + "UNKNOWN (579)", + "UNKNOWN (580)", + "UNKNOWN (581)", + "UNKNOWN (582)", + "UNKNOWN (583)", + "UNKNOWN (584)", + "UNKNOWN (585)", + "UNKNOWN (586)", + "UNKNOWN (587)", + "UNKNOWN (588)", + "UNKNOWN (589)", + "UNKNOWN (590)", + "UNKNOWN (591)", + "UNKNOWN (592)", + "UNKNOWN (593)", + "UNKNOWN (594)", + "UNKNOWN (595)", + "UNKNOWN (596)", + "UNKNOWN (597)", + "UNKNOWN (598)", + "UNKNOWN (599)", + "UNKNOWN (600)", + "UNKNOWN (601)", + "UNKNOWN (602)", + "UNKNOWN (603)", + "UNKNOWN (604)", + "UNKNOWN (605)", + "UNKNOWN (606)", + "UNKNOWN (607)", + "UNKNOWN (608)", + "UNKNOWN (609)", + "UNKNOWN (610)", + "UNKNOWN (611)", + "UNKNOWN (612)", + "UNKNOWN (613)", + "UNKNOWN (614)", + "UNKNOWN (615)", + "UNKNOWN (616)", + "UNKNOWN (617)", + "UNKNOWN (618)", + "UNKNOWN (619)", + "UNKNOWN (620)", + "UNKNOWN (621)", + "UNKNOWN (622)", + "UNKNOWN (623)", + "UNKNOWN (624)", + "UNKNOWN (625)", + "UNKNOWN (626)", + "UNKNOWN (627)", + "UNKNOWN (628)", + "UNKNOWN (629)", + "UNKNOWN (630)", + "UNKNOWN (631)", + "UNKNOWN (632)", + "UNKNOWN (633)", + "UNKNOWN (634)", + "UNKNOWN (635)", + "UNKNOWN (636)", + "UNKNOWN (637)", + "UNKNOWN (638)", + "UNKNOWN (639)", + "UNKNOWN (640)", + "UNKNOWN (641)", + "UNKNOWN (642)", + "UNKNOWN (643)", + "UNKNOWN (644)", + "UNKNOWN (645)", + "UNKNOWN (646)", + "UNKNOWN (647)", + "UNKNOWN (648)", + "UNKNOWN (649)", + "UNKNOWN (650)", + "UNKNOWN (651)", + "UNKNOWN (652)", + "UNKNOWN (653)", + "UNKNOWN (654)", + "UNKNOWN (655)", + "UNKNOWN (656)", + "UNKNOWN (657)", + "UNKNOWN (658)", + "UNKNOWN (659)", + "UNKNOWN (660)", + "UNKNOWN (661)", + "UNKNOWN (662)", + "UNKNOWN (663)", + "UNKNOWN (664)", + "UNKNOWN (665)", + "UNKNOWN (666)", + "UNKNOWN (667)", + "UNKNOWN (668)", + "UNKNOWN (669)", + "UNKNOWN (670)", + "UNKNOWN (671)", + "UNKNOWN (672)", + "WM_MOUSEHOVER", + "UNKNOWN (674)", + "WM_MOUSELEAVE", + "UNKNOWN (676)", + "UNKNOWN (677)", + "UNKNOWN (678)", + "UNKNOWN (679)", + "UNKNOWN (680)", + "UNKNOWN (681)", + "UNKNOWN (682)", + "UNKNOWN (683)", + "UNKNOWN (684)", + "UNKNOWN (685)", + "UNKNOWN (686)", + "UNKNOWN (687)", + "UNKNOWN (688)", + "UNKNOWN (689)", + "UNKNOWN (690)", + "UNKNOWN (691)", + "UNKNOWN (692)", + "UNKNOWN (693)", + "UNKNOWN (694)", + "UNKNOWN (695)", + "UNKNOWN (696)", + "UNKNOWN (697)", + "UNKNOWN (698)", + "UNKNOWN (699)", + "UNKNOWN (700)", + "UNKNOWN (701)", + "UNKNOWN (702)", + "UNKNOWN (703)", + "UNKNOWN (704)", + "UNKNOWN (705)", + "UNKNOWN (706)", + "UNKNOWN (707)", + "UNKNOWN (708)", + "UNKNOWN (709)", + "UNKNOWN (710)", + "UNKNOWN (711)", + "UNKNOWN (712)", + "UNKNOWN (713)", + "UNKNOWN (714)", + "UNKNOWN (715)", + "UNKNOWN (716)", + "UNKNOWN (717)", + "UNKNOWN (718)", + "UNKNOWN (719)", + "UNKNOWN (720)", + "UNKNOWN (721)", + "UNKNOWN (722)", + "UNKNOWN (723)", + "UNKNOWN (724)", + "UNKNOWN (725)", + "UNKNOWN (726)", + "UNKNOWN (727)", + "UNKNOWN (728)", + "UNKNOWN (729)", + "UNKNOWN (730)", + "UNKNOWN (731)", + "UNKNOWN (732)", + "UNKNOWN (733)", + "UNKNOWN (734)", + "UNKNOWN (735)", + "UNKNOWN (736)", + "UNKNOWN (737)", + "UNKNOWN (738)", + "UNKNOWN (739)", + "UNKNOWN (740)", + "UNKNOWN (741)", + "UNKNOWN (742)", + "UNKNOWN (743)", + "UNKNOWN (744)", + "UNKNOWN (745)", + "UNKNOWN (746)", + "UNKNOWN (747)", + "UNKNOWN (748)", + "UNKNOWN (749)", + "UNKNOWN (750)", + "UNKNOWN (751)", + "UNKNOWN (752)", + "UNKNOWN (753)", + "UNKNOWN (754)", + "UNKNOWN (755)", + "UNKNOWN (756)", + "UNKNOWN (757)", + "UNKNOWN (758)", + "UNKNOWN (759)", + "UNKNOWN (760)", + "UNKNOWN (761)", + "UNKNOWN (762)", + "UNKNOWN (763)", + "UNKNOWN (764)", + "UNKNOWN (765)", + "UNKNOWN (766)", + "UNKNOWN (767)", + "WM_CUT", + "WM_COPY", + "WM_PASTE", + "WM_CLEAR", + "WM_UNDO", + "WM_RENDERFORMAT", + "WM_RENDERALLFORMATS", + "WM_DESTROYCLIPBOARD", + "WM_DRAWCLIPBOARD", + "WM_PAINTCLIPBOARD", + "WM_VSCROLLCLIPBOARD", + "WM_SIZECLIPBOARD", + "WM_ASKCBFORMATNAME", + "WM_CHANGECBCHAIN", + "WM_HSCROLLCLIPBOARD", + "WM_QUERYNEWPALETTE", + "WM_PALETTEISCHANGING", + "WM_PALETTECHANGED", + "WM_HOTKEY", + "UNKNOWN (787)", + "UNKNOWN (788)", + "UNKNOWN (789)", + "UNKNOWN (790)", + "WM_PRINT", + "WM_PRINTCLIENT", + "UNKNOWN (793)", + "UNKNOWN (794)", + "UNKNOWN (795)", + "UNKNOWN (796)", + "UNKNOWN (797)", + "UNKNOWN (798)", + "UNKNOWN (799)", + "UNKNOWN (800)", + "UNKNOWN (801)", + "UNKNOWN (802)", + "UNKNOWN (803)", + "UNKNOWN (804)", + "UNKNOWN (805)", + "UNKNOWN (806)", + "UNKNOWN (807)", + "UNKNOWN (808)", + "UNKNOWN (809)", + "UNKNOWN (810)", + "UNKNOWN (811)", + "UNKNOWN (812)", + "UNKNOWN (813)", + "UNKNOWN (814)", + "UNKNOWN (815)", + "UNKNOWN (816)", + "UNKNOWN (817)", + "UNKNOWN (818)", + "UNKNOWN (819)", + "UNKNOWN (820)", + "UNKNOWN (821)", + "UNKNOWN (822)", + "UNKNOWN (823)", + "UNKNOWN (824)", + "UNKNOWN (825)", + "UNKNOWN (826)", + "UNKNOWN (827)", + "UNKNOWN (828)", + "UNKNOWN (829)", + "UNKNOWN (830)", + "UNKNOWN (831)", + "UNKNOWN (832)", + "UNKNOWN (833)", + "UNKNOWN (834)", + "UNKNOWN (835)", + "UNKNOWN (836)", + "UNKNOWN (837)", + "UNKNOWN (838)", + "UNKNOWN (839)", + "UNKNOWN (840)", + "UNKNOWN (841)", + "UNKNOWN (842)", + "UNKNOWN (843)", + "UNKNOWN (844)", + "UNKNOWN (845)", + "UNKNOWN (846)", + "UNKNOWN (847)", + "UNKNOWN (848)", + "UNKNOWN (849)", + "UNKNOWN (850)", + "UNKNOWN (851)", + "UNKNOWN (852)", + "UNKNOWN (853)", + "UNKNOWN (854)", + "UNKNOWN (855)", + "WM_HANDHELDFIRST", + "UNKNOWN (857)", + "UNKNOWN (858)", + "UNKNOWN (859)", + "UNKNOWN (860)", + "UNKNOWN (861)", + "UNKNOWN (862)", + "WM_HANDHELDLAST", + "WM_AFXFIRST", + "UNKNOWN (865)", + "UNKNOWN (866)", + "UNKNOWN (867)", + "UNKNOWN (868)", + "UNKNOWN (869)", + "UNKNOWN (870)", + "UNKNOWN (871)", + "UNKNOWN (872)", + "UNKNOWN (873)", + "UNKNOWN (874)", + "UNKNOWN (875)", + "UNKNOWN (876)", + "UNKNOWN (877)", + "UNKNOWN (878)", + "UNKNOWN (879)", + "UNKNOWN (880)", + "UNKNOWN (881)", + "UNKNOWN (882)", + "UNKNOWN (883)", + "UNKNOWN (884)", + "UNKNOWN (885)", + "UNKNOWN (886)", + "UNKNOWN (887)", + "UNKNOWN (888)", + "UNKNOWN (889)", + "UNKNOWN (890)", + "UNKNOWN (891)", + "UNKNOWN (892)", + "UNKNOWN (893)", + "UNKNOWN (894)", + "WM_AFXLAST", + "WM_PENWINFIRST", + "UNKNOWN (897)", + "UNKNOWN (898)", + "UNKNOWN (899)", + "UNKNOWN (900)", + "UNKNOWN (901)", + "UNKNOWN (902)", + "UNKNOWN (903)", + "UNKNOWN (904)", + "UNKNOWN (905)", + "UNKNOWN (906)", + "UNKNOWN (907)", + "UNKNOWN (908)", + "UNKNOWN (909)", + "UNKNOWN (910)", + "WM_PENWINLAST", + "UNKNOWN (912)", + "UNKNOWN (913)", + "UNKNOWN (914)", + "UNKNOWN (915)", + "UNKNOWN (916)", + "UNKNOWN (917)", + "UNKNOWN (918)", + "UNKNOWN (919)", + "UNKNOWN (920)", + "UNKNOWN (921)", + "UNKNOWN (922)", + "UNKNOWN (923)", + "UNKNOWN (924)", + "UNKNOWN (925)", + "UNKNOWN (926)", + "UNKNOWN (927)", + "UNKNOWN (928)", + "UNKNOWN (929)", + "UNKNOWN (930)", + "UNKNOWN (931)", + "UNKNOWN (932)", + "UNKNOWN (933)", + "UNKNOWN (934)", + "UNKNOWN (935)", + "UNKNOWN (936)", + "UNKNOWN (937)", + "UNKNOWN (938)", + "UNKNOWN (939)", + "UNKNOWN (940)", + "UNKNOWN (941)", + "UNKNOWN (942)", + "UNKNOWN (943)", + "UNKNOWN (944)", + "UNKNOWN (945)", + "UNKNOWN (946)", + "UNKNOWN (947)", + "UNKNOWN (948)", + "UNKNOWN (949)", + "UNKNOWN (950)", + "UNKNOWN (951)", + "UNKNOWN (952)", + "UNKNOWN (953)", + "UNKNOWN (954)", + "UNKNOWN (955)", + "UNKNOWN (956)", + "UNKNOWN (957)", + "UNKNOWN (958)", + "UNKNOWN (959)", + "UNKNOWN (960)", + "UNKNOWN (961)", + "UNKNOWN (962)", + "UNKNOWN (963)", + "UNKNOWN (964)", + "UNKNOWN (965)", + "UNKNOWN (966)", + "UNKNOWN (967)", + "UNKNOWN (968)", + "UNKNOWN (969)", + "UNKNOWN (970)", + "UNKNOWN (971)", + "UNKNOWN (972)", + "UNKNOWN (973)", + "UNKNOWN (974)", + "UNKNOWN (975)", + "UNKNOWN (976)", + "UNKNOWN (977)", + "UNKNOWN (978)", + "UNKNOWN (979)", + "UNKNOWN (980)", + "UNKNOWN (981)", + "UNKNOWN (982)", + "UNKNOWN (983)", + "UNKNOWN (984)", + "UNKNOWN (985)", + "UNKNOWN (986)", + "UNKNOWN (987)", + "UNKNOWN (988)", + "UNKNOWN (989)", + "UNKNOWN (990)", + "UNKNOWN (991)", + "UNKNOWN (992)", + "UNKNOWN (993)", + "UNKNOWN (994)", + "UNKNOWN (995)", + "UNKNOWN (996)", + "UNKNOWN (997)", + "UNKNOWN (998)", + "UNKNOWN (999)", + "UNKNOWN (1000)", + "UNKNOWN (1001)", + "UNKNOWN (1002)", + "UNKNOWN (1003)", + "UNKNOWN (1004)", + "UNKNOWN (1005)", + "UNKNOWN (1006)", + "UNKNOWN (1007)", + "UNKNOWN (1008)", + "UNKNOWN (1009)", + "UNKNOWN (1010)", + "UNKNOWN (1011)", + "UNKNOWN (1012)", + "UNKNOWN (1013)", + "UNKNOWN (1014)", + "UNKNOWN (1015)", + "UNKNOWN (1016)", + "UNKNOWN (1017)", + "UNKNOWN (1018)", + "UNKNOWN (1019)", + "UNKNOWN (1020)", + "UNKNOWN (1021)", + "UNKNOWN (1022)", + "UNKNOWN (1023)", + "WM_USER" +}; |