From e5cf7e6bd8c6d171048ba4116c285923a72226c0 Mon Sep 17 00:00:00 2001 From: Szymon Wilczek Date: Wed, 23 Jul 2008 16:12:43 +0000 Subject: [PATCH] Proximity events, Pressure detection for multiple windows. Tablet button detection on the way. --- src/events/SDL_mouse.c | 21 +- src/events/SDL_mouse_c.h | 2 +- src/video/win32/SDL_win32events.c | 1484 ++++++++++++++------------- src/video/win32/SDL_win32keyboard.c | 12 +- src/video/win32/SDL_win32video.c | 7 + src/video/win32/SDL_win32window.c | 872 ++++++++-------- 6 files changed, 1249 insertions(+), 1149 deletions(-) diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index f4468ab0a..5b94f7378 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -28,12 +28,12 @@ #include "default_cursor.h" -static int SDL_num_mice; -static int SDL_current_mouse; -static SDL_Mouse **SDL_mice; -int *SDL_IdIndex; -int SDL_highestId; -int last_x, last_y; +static int SDL_num_mice=0; +static int SDL_current_mouse=-1; +static SDL_Mouse **SDL_mice=NULL; +static int *SDL_IdIndex=NULL; +static int SDL_highestId=-1; +static int last_x, last_y; int x_max, y_max; /* Public functions */ int @@ -56,7 +56,7 @@ SDL_AddMouse(const SDL_Mouse * mouse, int index, char* name,int pressure_max,int { SDL_Mouse **mice; int selected_mouse; - char* temp_name; + //char* temp_name; /* Add the mouse to the list of mice */ if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) { mice = @@ -76,8 +76,8 @@ SDL_AddMouse(const SDL_Mouse * mouse, int index, char* name,int pressure_max,int return -1; } *SDL_mice[index] = *mouse; - SDL_mice[index]->name=SDL_malloc(strlen(name)*sizeof(char)); - strcpy(SDL_mice[index]->name,name); + SDL_mice[index]->name=SDL_malloc(SDL_strlen(name)*sizeof(char)); + SDL_strlcpy(SDL_mice[index]->name,name,255); SDL_mice[index]->pressure_max=pressure_max; SDL_mice[index]->pressure_min=pressure_min; SDL_mice[index]->cursor_shown = SDL_TRUE; @@ -721,7 +721,7 @@ SDL_ShowCursor(int toggle) return shown; } -void SDL_SetIndexId(int id, int index) +int SDL_SetIndexId(int id, int index) { if(id>SDL_highestId) { @@ -741,6 +741,7 @@ void SDL_SetIndexId(int id, int index) { SDL_IdIndex[id]=index; } + return 1; } int SDL_GetIndexById(int id) diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index 85a35b081..054cfd5f9 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -118,7 +118,7 @@ extern void SDL_MouseQuit(void); extern int SDL_GetIndexById(int id); -extern void SDL_SetIndexId(int id, int index); +extern int SDL_SetIndexId(int id, int index); extern int SDL_GetNumOfMice(void); diff --git a/src/video/win32/SDL_win32events.c b/src/video/win32/SDL_win32events.c index 5f257136d..c561e3ca7 100644 --- a/src/video/win32/SDL_win32events.c +++ b/src/video/win32/SDL_win32events.c @@ -1,720 +1,764 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 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_win32video.h" -#include "SDL_syswm.h" -#include "SDL_vkeys.h" -#include "../../events/SDL_events_c.h" - -/*#define WMMSG_DEBUG*/ -#ifdef WMMSG_DEBUG -#include -#include "wmmsg.h" -#endif - -/* Masks for processing the windows KEYDOWN and KEYUP messages */ -#define REPEATED_KEYMASK (1<<30) -#define EXTENDED_KEYMASK (1<<24) - -#define VK_ENTER 10 /* Keypad Enter ... no VKEY defined? */ - -/* 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 - -static WPARAM -RemapVKEY(WPARAM wParam, LPARAM lParam) -{ - int i; - BYTE scancode = (BYTE) ((lParam >> 16) & 0xFF); - - /* Windows remaps alphabetic keys based on current layout. - We try to provide USB scancodes, so undo this mapping. - */ - if (wParam >= 'A' && wParam <= 'Z') { - if (scancode != alpha_scancodes[wParam - 'A']) { - for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) { - if (scancode == alpha_scancodes[i]) { - wParam = 'A' + i; - break; - } - } - } - } - - /* Keypad keys are a little trickier, we always scan for them. */ - for (i = 0; i < SDL_arraysize(keypad_scancodes); ++i) { - if (scancode == keypad_scancodes[i]) { - wParam = VK_NUMPAD0 + i; - break; - } - } - - return wParam; -} - -LRESULT CALLBACK -WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - SDL_WindowData *data; - - /* Send a SDL_SYSWMEVENT if the application wants them */ - if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) { - SDL_SysWMmsg wmmsg; - - SDL_VERSION(&wmmsg.version); - wmmsg.hwnd = hwnd; - wmmsg.msg = msg; - wmmsg.wParam = wParam; - wmmsg.lParam = lParam; - SDL_SendSysWMEvent(&wmmsg); - } - - /* Get the window data for the window */ - data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData")); - if (!data) { - return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); - } -#ifdef WMMSG_DEBUG - { - FILE *log = fopen("wmmsg.txt", "a"); - fprintf(log, "Received windows message: %p ", hwnd); - if (msg > MAX_WMMSG) { - fprintf(log, "%d", msg); - } else { - fprintf(log, "%s", wmtab[msg]); - } - fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam); - fclose(log); - } -#endif - - switch (msg) { - - case WM_SHOWWINDOW: - { - if (wParam) { - SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, 0, - 0); - } else { - SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_HIDDEN, 0, - 0); - } - } - break; - - case WM_ACTIVATE: - { - int index; - SDL_Keyboard *keyboard; - BOOL minimized; - - minimized = HIWORD(wParam); - index = data->videodata->keyboard; - keyboard = SDL_GetKeyboard(index); - if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) { - SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, - 0, 0); - SDL_SendWindowEvent(data->windowID, - SDL_WINDOWEVENT_RESTORED, 0, 0); - if (IsZoomed(hwnd)) { - SDL_SendWindowEvent(data->windowID, - SDL_WINDOWEVENT_MAXIMIZED, 0, 0); - } - if (keyboard && keyboard->focus != data->windowID) { - SDL_SetKeyboardFocus(index, data->windowID); - } - /* FIXME: Update keyboard state */ - } else { - if (keyboard && keyboard->focus == data->windowID) { - SDL_SetKeyboardFocus(index, 0); - } - if (minimized) { - SDL_SendWindowEvent(data->windowID, - SDL_WINDOWEVENT_MINIMIZED, 0, 0); - } - } - return (0); - } - break; - - case WM_MOUSEMOVE: - { - int index; - SDL_Mouse *mouse; - int x, y; - - index = data->videodata->mouse; - mouse = SDL_GetMouse(index); - - if (mouse->focus != data->windowID) { - TRACKMOUSEEVENT tme; - - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = hwnd; - TrackMouseEvent(&tme); - - SDL_SetMouseFocus(index, data->windowID); - } - - /* mouse has moved within the window */ - x = LOWORD(lParam); - y = HIWORD(lParam); - if (mouse->relative_mode) { - int w, h; - POINT center; - SDL_GetWindowSize(data->windowID, &w, &h); - center.x = (w / 2); - center.y = (h / 2); - x -= center.x; - y -= center.y; - if (x || y) { - ClientToScreen(hwnd, ¢er); - SetCursorPos(center.x, center.y); - SDL_SendMouseMotion(index, 1, x, y); - } - } else { - SDL_SendMouseMotion(index, 0, x, y); - } - } - return (0); - - case WM_MOUSELEAVE: - { - int index; - SDL_Mouse *mouse; - - index = data->videodata->mouse; - mouse = SDL_GetMouse(index); - - if (mouse->focus == data->windowID) { - SDL_SetMouseFocus(index, 0); - } - } - return (0); - - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_XBUTTONDOWN: - case WM_XBUTTONUP: - { - int xbuttonval = 0; - int index; - SDL_Mouse *mouse; - 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(hwnd); - - index = data->videodata->mouse; - mouse = SDL_GetMouse(index); - - /* 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 (++data->mouse_pressed > 0) { - SetCapture(hwnd); - } - } else { - /* Release mouse after all up events */ - if (--data->mouse_pressed <= 0) { - ReleaseCapture(); - data->mouse_pressed = 0; - } - } - - if (!mouse->relative_mode) { - int x, y; - x = LOWORD(lParam); - y = HIWORD(lParam); - SDL_SendMouseMotion(index, 0, x, y); - } - SDL_SendMouseButton(index, state, button); - - /* - * 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); - - case WM_MOUSEWHEEL: - { - int index; - int motion = (short) HIWORD(wParam); - - index = data->videodata->mouse; - SDL_SendMouseWheel(index, 0, motion); - } - return (0); - - case WM_SYSKEYDOWN: - case WM_KEYDOWN: - { - int index; - - /* Ignore repeated keys */ - if (lParam & REPEATED_KEYMASK) { - return (0); - } - - index = data->videodata->keyboard; - wParam = RemapVKEY(wParam, lParam); - switch (wParam) { - case VK_CONTROL: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_RCONTROL; - else - wParam = VK_LCONTROL; - break; - case VK_SHIFT: - /* EXTENDED trick doesn't work here */ - { - Uint8 *state = SDL_GetKeyboardState(NULL); - if (state[SDL_SCANCODE_LSHIFT] == SDL_RELEASED - && (GetKeyState(VK_LSHIFT) & 0x8000)) { - wParam = VK_LSHIFT; - } else if (state[SDL_SCANCODE_RSHIFT] == SDL_RELEASED - && (GetKeyState(VK_RSHIFT) & 0x8000)) { - wParam = VK_RSHIFT; - } else { - /* Probably a key repeat */ - return (0); - } - } - break; - case VK_MENU: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_RMENU; - else - wParam = VK_LMENU; - break; - case VK_RETURN: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_ENTER; - break; - } - if (wParam < 256) { - SDL_SendKeyboardKey(index, SDL_PRESSED, - data->videodata->key_layout[wParam]); - } - } - return (0); - - case WM_SYSKEYUP: - case WM_KEYUP: - { - int index; - - index = data->videodata->keyboard; - wParam = RemapVKEY(wParam, lParam); - switch (wParam) { - case VK_CONTROL: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_RCONTROL; - else - wParam = VK_LCONTROL; - break; - case VK_SHIFT: - /* EXTENDED trick doesn't work here */ - { - Uint8 *state = SDL_GetKeyboardState(NULL); - if (state[SDL_SCANCODE_LSHIFT] == SDL_PRESSED - && !(GetKeyState(VK_LSHIFT) & 0x8000)) { - wParam = VK_LSHIFT; - } else if (state[SDL_SCANCODE_RSHIFT] == SDL_PRESSED - && !(GetKeyState(VK_RSHIFT) & 0x8000)) { - wParam = VK_RSHIFT; - } else { - /* Probably a key repeat */ - return (0); - } - } - break; - case VK_MENU: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_RMENU; - else - wParam = VK_LMENU; - break; - case VK_RETURN: - if (lParam & EXTENDED_KEYMASK) - wParam = VK_ENTER; - break; - } - /* Windows only reports keyup for print screen */ - if (wParam == VK_SNAPSHOT - && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] == - SDL_RELEASED) { - SDL_SendKeyboardKey(index, SDL_PRESSED, - data->videodata->key_layout[wParam]); - } - if (wParam < 256) { - SDL_SendKeyboardKey(index, SDL_RELEASED, - data->videodata->key_layout[wParam]); - } - } - return (0); - - case WM_CHAR: - { - char text[4]; - - /* Convert to UTF-8 and send it on... */ - if (wParam <= 0x7F) { - text[0] = (char) wParam; - text[1] = '\0'; - } else if (wParam <= 0x7FF) { - text[0] = 0xC0 | (char) ((wParam >> 6) & 0x1F); - text[1] = 0x80 | (char) (wParam & 0x3F); - text[2] = '\0'; - } else { - text[0] = 0xE0 | (char) ((wParam >> 12) & 0x0F); - text[1] = 0x80 | (char) ((wParam >> 6) & 0x3F); - text[2] = 0x80 | (char) (wParam & 0x3F); - text[3] = '\0'; - } - SDL_SendKeyboardText(data->videodata->keyboard, text); - } - return (0); - - case WM_INPUTLANGCHANGE: - { - WIN_UpdateKeymap(data->videodata->keyboard); - } - return (1); - - case WM_GETMINMAXINFO: - { - MINMAXINFO *info; - RECT size; - int x, y; - int w, h; - int style; - - /* If we allow resizing, let the resize happen naturally */ - if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_RESIZABLE) { - return (0); - } - - /* Get the current position of our window */ - GetWindowRect(hwnd, &size); - x = size.left; - y = size.top; - - /* Calculate current size of our window */ - SDL_GetWindowSize(data->windowID, &w, &h); - size.top = 0; - size.left = 0; - size.bottom = h; - size.right = w; - - /* 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); - - w = size.right - size.left; - h = size.bottom - size.top; - - /* Fix our size to the current size */ - info = (MINMAXINFO *) lParam; - info->ptMaxSize.x = w; - info->ptMaxSize.y = h; - info->ptMaxPosition.x = x; - info->ptMaxPosition.y = y; - info->ptMinTrackSize.x = w; - info->ptMinTrackSize.y = h; - info->ptMaxTrackSize.x = w; - info->ptMaxTrackSize.y = h; - } - return (0); - - case WM_WINDOWPOSCHANGED: - { - RECT rect; - int x, y; - int w, h; - Uint32 window_flags; - - GetClientRect(hwnd, &rect); - ClientToScreen(hwnd, (LPPOINT) & rect); - ClientToScreen(hwnd, (LPPOINT) & rect + 1); - - window_flags = SDL_GetWindowFlags(data->windowID); - if ((window_flags & SDL_WINDOW_INPUT_GRABBED) && - (window_flags & SDL_WINDOW_INPUT_FOCUS)) { - ClipCursor(&rect); - } - - x = rect.left; - y = rect.top; - SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MOVED, x, y); - - w = rect.right - rect.left; - h = rect.bottom - rect.top; - SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESIZED, w, - h); - } - break; - - 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: - { - RECT rect; - if (GetUpdateRect(hwnd, &rect, FALSE)) { - ValidateRect(hwnd, &rect); - SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED, - 0, 0); - } - } - return (0); - - /* We'll do our own drawing, prevent flicker */ - case WM_ERASEBKGND: - { - } - return (1); - - case WM_SYSCOMMAND: - { - /* Don't start the screensaver or blank the monitor in fullscreen apps */ - if ((wParam & 0xFFF0) == SC_SCREENSAVE || - (wParam & 0xFFF0) == SC_MONITORPOWER) { - if (SDL_GetWindowFlags(data->windowID) & - SDL_WINDOW_FULLSCREEN) { - return (0); - } - } - } - break; - - case WM_CLOSE: - { - SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0, 0); - } - return (0); - } - return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam); -} - -void -WIN_PumpEvents(_THIS) -{ - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -} - -static int app_registered = 0; -LPTSTR SDL_Appname = NULL; -Uint32 SDL_Appstyle = 0; -HINSTANCE SDL_Instance = NULL; - -/* Register the class for this application */ -int -SDL_RegisterApp(char *name, Uint32 style, void *hInst) -{ - WNDCLASS class; - - /* Only do this once... */ - if (app_registered) { - ++app_registered; - return (0); - } - if (!name && !SDL_Appname) { - name = "SDL_app"; - SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC); - SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); - } - - if (name) { - SDL_Appname = WIN_UTF8ToString(name); - SDL_Appstyle = style; - SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); - } - - /* 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; - class.lpfnWndProc = DefWindowProc; - class.cbWndExtra = 0; - class.cbClsExtra = 0; - if (!RegisterClass(&class)) { - SDL_SetError("Couldn't register application class"); - return (-1); - } - - 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; - } -} - -/* Sets an error message based on GetLastError() */ -void -WIN_SetError(const char *prefix) -{ - TCHAR buffer[1024]; - char *message; - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), 0, buffer, SDL_arraysize(buffer), NULL); - - message = WIN_StringToUTF8(buffer); - SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ":" : "", message); - SDL_free(message); -} - -/* vi: set ts=4 sw=4 expandtab: */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_win32video.h" +#include "SDL_syswm.h" +#include "SDL_vkeys.h" +#include "../../events/SDL_events_c.h" +#include +#define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE) +#define PACKETMODE 0 +#include + +/*#define WMMSG_DEBUG*/ +#ifdef WMMSG_DEBUG +#include +#include "wmmsg.h" +#endif + +/* Masks for processing the windows KEYDOWN and KEYUP messages */ +#define REPEATED_KEYMASK (1<<30) +#define EXTENDED_KEYMASK (1<<24) + +#define VK_ENTER 10 /* Keypad Enter ... no VKEY defined? */ + +/* 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 + +#define pi 1.0 + +int first=1; + +LOGCONTEXT lc; + +static WPARAM +RemapVKEY(WPARAM wParam, LPARAM lParam) +{ + int i; + BYTE scancode = (BYTE) ((lParam >> 16) & 0xFF); + + /* Windows remaps alphabetic keys based on current layout. + We try to provide USB scancodes, so undo this mapping. + */ + if (wParam >= 'A' && wParam <= 'Z') { + if (scancode != alpha_scancodes[wParam - 'A']) { + for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) { + if (scancode == alpha_scancodes[i]) { + wParam = 'A' + i; + break; + } + } + } + } + + /* Keypad keys are a little trickier, we always scan for them. */ + for (i = 0; i < SDL_arraysize(keypad_scancodes); ++i) { + if (scancode == keypad_scancodes[i]) { + wParam = VK_NUMPAD0 + i; + break; + } + } + + return wParam; +} + +LRESULT CALLBACK +WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + SDL_WindowData *data; + + PACKET packet; + + /* Send a SDL_SYSWMEVENT if the application wants them */ + if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) { + SDL_SysWMmsg wmmsg; + + SDL_VERSION(&wmmsg.version); + wmmsg.hwnd = hwnd; + wmmsg.msg = msg; + wmmsg.wParam = wParam; + wmmsg.lParam = lParam; + SDL_SendSysWMEvent(&wmmsg); + } + + /* Get the window data for the window */ + data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData")); + if (!data) { + return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); + } +#ifdef WMMSG_DEBUG + { + FILE *log = fopen("wmmsg.txt", "a"); + fprintf(log, "Received windows message: %p ", hwnd); + if (msg > MAX_WMMSG) { + fprintf(log, "%d", msg); + } else { + fprintf(log, "%s", wmtab[msg]); + } + fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam); + fclose(log); + } +#endif + + switch (msg) { + case WT_PACKET: + { + if (WTPacket((HCTX)lParam, wParam, &packet)) + { + SDL_SendMouseMotion(0,0,(int)packet.pkX,(int)packet.pkY,(int)packet.pkNormalPressure); + } + } + break; + case WT_PROXIMITY: + { + int h_context=LOWORD(lParam); + if(h_context==0) + { + SDL_SendProximity(0, 0, 0, SDL_PROXIMITYOUT); + } + else + { + SDL_SendProximity(0, 0, 0, SDL_PROXIMITYIN); + } + } + break; + case WM_SHOWWINDOW: + { + if (wParam) { + SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, 0, + 0); + } else { + SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_HIDDEN, 0, + 0); + } + } + break; + + case WM_ACTIVATE: + { + int index; + SDL_Keyboard *keyboard; + BOOL minimized; + + minimized = HIWORD(wParam); + index = data->videodata->keyboard; + keyboard = SDL_GetKeyboard(index); + if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) { + SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, + 0, 0); + SDL_SendWindowEvent(data->windowID, + SDL_WINDOWEVENT_RESTORED, 0, 0); + if (IsZoomed(hwnd)) { + SDL_SendWindowEvent(data->windowID, + SDL_WINDOWEVENT_MAXIMIZED, 0, 0); + } + if (keyboard && keyboard->focus != data->windowID) { + SDL_SetKeyboardFocus(index, data->windowID); + } + /* FIXME: Update keyboard state */ + } else { + if (keyboard && keyboard->focus == data->windowID) { + SDL_SetKeyboardFocus(index, 0); + } + if (minimized) { + SDL_SendWindowEvent(data->windowID, + SDL_WINDOWEVENT_MINIMIZED, 0, 0); + } + } + return (0); + } + break; + case WT_CTXOPEN: + { + SDL_SendMouseMotion(0,1,1,0,0); + SDL_SendMouseMotion(0,1,-1,0,0); + } + case WM_MOUSEMOVE: + { + int index; + SDL_Mouse *mouse; + int x, y; + + index = data->videodata->mouse; + mouse = SDL_GetMouse(index); + + if (mouse->focus != data->windowID) { + TRACKMOUSEEVENT tme; + + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hwnd; + TrackMouseEvent(&tme); + + SDL_SetMouseFocus(index, data->windowID); + } + + /* mouse has moved within the window */ + x = LOWORD(lParam); + y = HIWORD(lParam); + //printf("index: %d\n",index); + if (mouse->relative_mode) { + int w, h; + POINT center; + SDL_GetWindowSize(data->windowID, &w, &h); + center.x = (w / 2); + center.y = (h / 2); + x -= center.x; + y -= center.y; + if (x || y) { + ClientToScreen(hwnd, ¢er); + SetCursorPos(center.x, center.y); + SDL_SendMouseMotion(index, 1, x, y,0); + } + } else { + SDL_SendMouseMotion(index, 0, x, y,0); + } + } + return (0); + + case WM_MOUSELEAVE: + { + int index; + SDL_Mouse *mouse; + + index = data->videodata->mouse; + mouse = SDL_GetMouse(index); + + if (mouse->focus == data->windowID) { + SDL_SetMouseFocus(index, 0); + } + } + return (0); + + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + { + int xbuttonval = 0; + int index; + SDL_Mouse *mouse; + 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(hwnd); + + index = data->videodata->mouse; + mouse = SDL_GetMouse(index); + + /* 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 (++data->mouse_pressed > 0) { + SetCapture(hwnd); + } + } else { + /* Release mouse after all up events */ + if (--data->mouse_pressed <= 0) { + ReleaseCapture(); + data->mouse_pressed = 0; + } + } + + if (!mouse->relative_mode) { + int x, y; + x = LOWORD(lParam); + y = HIWORD(lParam); + SDL_SendMouseMotion(index, 0, x, y,0); + } + SDL_SendMouseButton(index, state, button); + + /* + * 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); + + case WM_MOUSEWHEEL: + { + int index; + int motion = (short) HIWORD(wParam); + + index = data->videodata->mouse; + SDL_SendMouseWheel(index, 0, motion); + } + return (0); + + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + { + int index; + + /* Ignore repeated keys */ + if (lParam & REPEATED_KEYMASK) { + return (0); + } + + index = data->videodata->keyboard; + wParam = RemapVKEY(wParam, lParam); + switch (wParam) { + case VK_CONTROL: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_RCONTROL; + else + wParam = VK_LCONTROL; + break; + case VK_SHIFT: + /* EXTENDED trick doesn't work here */ + { + Uint8 *state = SDL_GetKeyboardState(NULL); + if (state[SDL_SCANCODE_LSHIFT] == SDL_RELEASED + && (GetKeyState(VK_LSHIFT) & 0x8000)) { + wParam = VK_LSHIFT; + } else if (state[SDL_SCANCODE_RSHIFT] == SDL_RELEASED + && (GetKeyState(VK_RSHIFT) & 0x8000)) { + wParam = VK_RSHIFT; + } else { + /* Probably a key repeat */ + return (0); + } + } + break; + case VK_MENU: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_RMENU; + else + wParam = VK_LMENU; + break; + case VK_RETURN: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_ENTER; + break; + } + if (wParam < 256) { + SDL_SendKeyboardKey(index, SDL_PRESSED, + data->videodata->key_layout[wParam]); + } + } + return (0); + + case WM_SYSKEYUP: + case WM_KEYUP: + { + int index; + + index = data->videodata->keyboard; + wParam = RemapVKEY(wParam, lParam); + switch (wParam) { + case VK_CONTROL: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_RCONTROL; + else + wParam = VK_LCONTROL; + break; + case VK_SHIFT: + /* EXTENDED trick doesn't work here */ + { + Uint8 *state = SDL_GetKeyboardState(NULL); + if (state[SDL_SCANCODE_LSHIFT] == SDL_PRESSED + && !(GetKeyState(VK_LSHIFT) & 0x8000)) { + wParam = VK_LSHIFT; + } else if (state[SDL_SCANCODE_RSHIFT] == SDL_PRESSED + && !(GetKeyState(VK_RSHIFT) & 0x8000)) { + wParam = VK_RSHIFT; + } else { + /* Probably a key repeat */ + return (0); + } + } + break; + case VK_MENU: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_RMENU; + else + wParam = VK_LMENU; + break; + case VK_RETURN: + if (lParam & EXTENDED_KEYMASK) + wParam = VK_ENTER; + break; + } + /* Windows only reports keyup for print screen */ + if (wParam == VK_SNAPSHOT + && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] == + SDL_RELEASED) { + SDL_SendKeyboardKey(index, SDL_PRESSED, + data->videodata->key_layout[wParam]); + } + if (wParam < 256) { + SDL_SendKeyboardKey(index, SDL_RELEASED, + data->videodata->key_layout[wParam]); + } + } + return (0); + + case WM_CHAR: + { + char text[4]; + + /* Convert to UTF-8 and send it on... */ + if (wParam <= 0x7F) { + text[0] = (char) wParam; + text[1] = '\0'; + } else if (wParam <= 0x7FF) { + text[0] = 0xC0 | (char) ((wParam >> 6) & 0x1F); + text[1] = 0x80 | (char) (wParam & 0x3F); + text[2] = '\0'; + } else { + text[0] = 0xE0 | (char) ((wParam >> 12) & 0x0F); + text[1] = 0x80 | (char) ((wParam >> 6) & 0x3F); + text[2] = 0x80 | (char) (wParam & 0x3F); + text[3] = '\0'; + } + SDL_SendKeyboardText(data->videodata->keyboard, text); + } + return (0); + + case WM_INPUTLANGCHANGE: + { + WIN_UpdateKeymap(data->videodata->keyboard); + } + return (1); + + case WM_GETMINMAXINFO: + { + MINMAXINFO *info; + RECT size; + int x, y; + int w, h; + int style; + + /* If we allow resizing, let the resize happen naturally */ + if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_RESIZABLE) { + return (0); + } + + /* Get the current position of our window */ + GetWindowRect(hwnd, &size); + x = size.left; + y = size.top; + + /* Calculate current size of our window */ + SDL_GetWindowSize(data->windowID, &w, &h); + size.top = 0; + size.left = 0; + size.bottom = h; + size.right = w; + + /* 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); + + w = size.right - size.left; + h = size.bottom - size.top; + + /* Fix our size to the current size */ + info = (MINMAXINFO *) lParam; + info->ptMaxSize.x = w; + info->ptMaxSize.y = h; + info->ptMaxPosition.x = x; + info->ptMaxPosition.y = y; + info->ptMinTrackSize.x = w; + info->ptMinTrackSize.y = h; + info->ptMaxTrackSize.x = w; + info->ptMaxTrackSize.y = h; + } + return (0); + + case WM_WINDOWPOSCHANGED: + { + RECT rect; + int x, y; + int w, h; + Uint32 window_flags; + + GetClientRect(hwnd, &rect); + ClientToScreen(hwnd, (LPPOINT) & rect); + ClientToScreen(hwnd, (LPPOINT) & rect + 1); + + window_flags = SDL_GetWindowFlags(data->windowID); + if ((window_flags & SDL_WINDOW_INPUT_GRABBED) && + (window_flags & SDL_WINDOW_INPUT_FOCUS)) { + ClipCursor(&rect); + } + + x = rect.left; + y = rect.top; + SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_MOVED, x, y); + + w = rect.right - rect.left; + h = rect.bottom - rect.top; + SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_RESIZED, w, + h); + } + break; + + 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: + { + RECT rect; + if (GetUpdateRect(hwnd, &rect, FALSE)) { + ValidateRect(hwnd, &rect); + SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED, + 0, 0); + } + } + return (0); + + /* We'll do our own drawing, prevent flicker */ + case WM_ERASEBKGND: + { + } + return (1); + + case WM_SYSCOMMAND: + { + /* Don't start the screensaver or blank the monitor in fullscreen apps */ + if ((wParam & 0xFFF0) == SC_SCREENSAVE || + (wParam & 0xFFF0) == SC_MONITORPOWER) { + if (SDL_GetWindowFlags(data->windowID) & + SDL_WINDOW_FULLSCREEN) { + return (0); + } + } + } + break; + + case WM_CLOSE: + { + SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0, 0); + } + return (0); + } + return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam); +} + +void +WIN_PumpEvents(_THIS) +{ + MSG msg; + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + + } + /*while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + }*/ + //WTClose(g_hCtx); +} + +static int app_registered = 0; +LPTSTR SDL_Appname = NULL; +Uint32 SDL_Appstyle = 0; +HINSTANCE SDL_Instance = NULL; + +/* Register the class for this application */ +int +SDL_RegisterApp(char *name, Uint32 style, void *hInst) +{ + WNDCLASS class; + + /* Only do this once... */ + if (app_registered) { + ++app_registered; + return (0); + } + if (!name && !SDL_Appname) { + name = "SDL_app"; + SDL_Appstyle = (CS_BYTEALIGNCLIENT | CS_OWNDC); + SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); + } + + if (name) { + SDL_Appname = WIN_UTF8ToString(name); + SDL_Appstyle = style; + SDL_Instance = hInst ? hInst : GetModuleHandle(NULL); + } + + /* 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; + class.lpfnWndProc = DefWindowProc; + class.cbWndExtra = 0; + class.cbClsExtra = 0; + if (!RegisterClass(&class)) { + SDL_SetError("Couldn't register application class"); + return (-1); + } + + 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; + } +} + +/* Sets an error message based on GetLastError() */ +void +WIN_SetError(const char *prefix) +{ + TCHAR buffer[1024]; + char *message; + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), 0, buffer, SDL_arraysize(buffer), NULL); + + message = WIN_StringToUTF8(buffer); + SDL_SetError("%s%s%s", prefix ? prefix : "", prefix ? ":" : "", message); + SDL_free(message); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32keyboard.c b/src/video/win32/SDL_win32keyboard.c index b050d89bc..e3fadd853 100644 --- a/src/video/win32/SDL_win32keyboard.c +++ b/src/video/win32/SDL_win32keyboard.c @@ -54,20 +54,20 @@ WIN_InitKeyboard(_THIS) /* Make sure the alpha scancodes are correct. T isn't usually remapped */ if (MapVirtualKey('T', MAPVK_VK_TO_VSC) != alpha_scancodes['T' - 'A']) { - printf - ("Fixing alpha scancode map, assuming US QWERTY layout!\nPlease send the following 26 lines of output to the SDL mailing list , including a description of your keyboard hardware.\n"); + //printf + // ("Fixing alpha scancode map, assuming US QWERTY layout!\nPlease send the following 26 lines of output to the SDL mailing list , including a description of your keyboard hardware.\n"); for (i = 0; i < SDL_arraysize(alpha_scancodes); ++i) { alpha_scancodes[i] = MapVirtualKey('A' + i, MAPVK_VK_TO_VSC); - printf("%d = %d\n", i, alpha_scancodes[i]); + // printf("%d = %d\n", i, alpha_scancodes[i]); } } if (MapVirtualKey(VK_NUMPAD0, MAPVK_VK_TO_VSC) != keypad_scancodes[0]) { - printf - ("Fixing keypad scancode map!\nPlease send the following 10 lines of output to the SDL mailing list , including a description of your keyboard hardware.\n"); + // printf + // ("Fixing keypad scancode map!\nPlease send the following 10 lines of output to the SDL mailing list , including a description of your keyboard hardware.\n"); for (i = 0; i < SDL_arraysize(keypad_scancodes); ++i) { keypad_scancodes[i] = MapVirtualKey(VK_NUMPAD0 + i, MAPVK_VK_TO_VSC); - printf("%d = %d\n", i, keypad_scancodes[i]); + // printf("%d = %d\n", i, keypad_scancodes[i]); } } diff --git a/src/video/win32/SDL_win32video.c b/src/video/win32/SDL_win32video.c index f00cc9442..e1b8c8680 100644 --- a/src/video/win32/SDL_win32video.c +++ b/src/video/win32/SDL_win32video.c @@ -31,10 +31,14 @@ #include "SDL_d3drender.h" #include "SDL_gdirender.h" +#include + /* Initialization/Query functions */ static int WIN_VideoInit(_THIS); static void WIN_VideoQuit(_THIS); +HCTX* g_hCtx = NULL; + /* WIN32 driver bootstrap functions */ static int @@ -157,6 +161,8 @@ WIN_VideoInit(_THIS) GDI_AddRenderDriver(_this); #endif + g_hCtx = SDL_malloc(sizeof(HCTX)); + WIN_InitKeyboard(_this); WIN_InitMouse(_this); @@ -169,6 +175,7 @@ WIN_VideoQuit(_THIS) WIN_QuitModes(_this); WIN_QuitKeyboard(_this); WIN_QuitMouse(_this); + SDL_free(g_hCtx); } /* vim: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32window.c b/src/video/win32/SDL_win32window.c index 07dc1a1f2..793ab9120 100644 --- a/src/video/win32/SDL_win32window.c +++ b/src/video/win32/SDL_win32window.c @@ -1,412 +1,460 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2006 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_sysvideo.h" -#include "../../events/SDL_keyboard_c.h" - -#include "SDL_win32video.h" - -/* This is included after SDL_win32video.h, which includes windows.h */ -#include "SDL_syswm.h" - - -static int -SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created) -{ - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - SDL_WindowData *data; - - /* Allocate the window data */ - data = (SDL_WindowData *) SDL_malloc(sizeof(*data)); - if (!data) { - SDL_OutOfMemory(); - return -1; - } - data->windowID = window->id; - data->hwnd = hwnd; - data->hdc = GetDC(hwnd); - data->created = created; - data->mouse_pressed = SDL_FALSE; - data->videodata = videodata; - - /* Associate the data with the window */ - if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) { - ReleaseDC(hwnd, data->hdc); - SDL_free(data); - WIN_SetError("SetProp() failed"); - return -1; - } - - /* Set up the window proc function */ - data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC); - if (data->wndproc == NULL) { - data->wndproc = DefWindowProc; - } else { - SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc); - } - - /* Fill in the SDL window with the window data */ - { - POINT point; - point.x = 0; - point.y = 0; - if (ClientToScreen(hwnd, &point)) { - window->x = point.x; - window->y = point.y; - } - } - { - RECT rect; - if (GetClientRect(hwnd, &rect)) { - window->w = rect.right; - window->h = rect.bottom; - } - } - { - DWORD style = GetWindowLong(hwnd, GWL_STYLE); - if (style & WS_VISIBLE) { - window->flags |= SDL_WINDOW_SHOWN; - } else { - window->flags &= ~SDL_WINDOW_SHOWN; - } - if (style & (WS_BORDER | WS_THICKFRAME)) { - window->flags &= ~SDL_WINDOW_BORDERLESS; - } else { - window->flags |= SDL_WINDOW_BORDERLESS; - } - if (style & WS_THICKFRAME) { - window->flags |= SDL_WINDOW_RESIZABLE; - } else { - window->flags &= ~SDL_WINDOW_RESIZABLE; - } - if (style & WS_MAXIMIZE) { - window->flags |= SDL_WINDOW_MAXIMIZED; - } else { - window->flags &= ~SDL_WINDOW_MAXIMIZED; - } - if (style & WS_MINIMIZE) { - window->flags |= SDL_WINDOW_MINIMIZED; - } else { - window->flags &= ~SDL_WINDOW_MINIMIZED; - } - } - if (GetFocus() == hwnd) { - int index = data->videodata->keyboard; - window->flags |= SDL_WINDOW_INPUT_FOCUS; - SDL_SetKeyboardFocus(index, data->windowID); - - if (window->flags & SDL_WINDOW_INPUT_GRABBED) { - RECT rect; - GetClientRect(hwnd, &rect); - ClientToScreen(hwnd, (LPPOINT) & rect); - ClientToScreen(hwnd, (LPPOINT) & rect + 1); - ClipCursor(&rect); - } - } - - /* All done! */ - window->driverdata = data; - return 0; -} - -int -WIN_CreateWindow(_THIS, SDL_Window * window) -{ - HWND hwnd; - HWND top; - RECT rect; - DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN); - int x, y; - int w, h; - - if (window->flags & SDL_WINDOW_BORDERLESS) { - style |= WS_POPUP; - } else { - style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX); - } - if (window->flags & SDL_WINDOW_RESIZABLE) { - style |= (WS_THICKFRAME | WS_MAXIMIZEBOX); - } - - /* Figure out what the window area will be */ - if (window->flags & SDL_WINDOW_FULLSCREEN) { - top = HWND_TOPMOST; - } else { - top = HWND_NOTOPMOST; - } - rect.left = 0; - rect.top = 0; - rect.right = window->w; - rect.bottom = window->h; - AdjustWindowRectEx(&rect, style, FALSE, 0); - w = (rect.right - rect.left); - h = (rect.bottom - rect.top); - - if (window->x == SDL_WINDOWPOS_CENTERED) { - x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; - } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { - x = CW_USEDEFAULT; - } else { - x = window->x + rect.left; - } - if (window->y == SDL_WINDOWPOS_CENTERED) { - y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; - } else if (window->y == SDL_WINDOWPOS_UNDEFINED) { - y = CW_USEDEFAULT; - } else { - y = window->y + rect.top; - } - - hwnd = - CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL, - SDL_Instance, NULL); - WIN_PumpEvents(_this); - - if (!hwnd) { - WIN_SetError("Couldn't create window"); - return -1; - } - - if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) { - DestroyWindow(hwnd); - return -1; - } -#ifdef SDL_VIDEO_OPENGL_WGL - if (window->flags & SDL_WINDOW_OPENGL) { - if (WIN_GL_SetupWindow(_this, window) < 0) { - WIN_DestroyWindow(_this, window); - return -1; - } - } -#endif - return 0; -} - -int -WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) -{ - HWND hwnd = (HWND) data; - LPTSTR title; - int titleLen; - - /* Query the title from the existing window */ - titleLen = GetWindowTextLength(hwnd); - title = SDL_stack_alloc(TCHAR, titleLen + 1); - if (title) { - titleLen = GetWindowText(hwnd, title, titleLen); - } else { - titleLen = 0; - } - if (titleLen > 0) { - window->title = WIN_StringToUTF8(title); - } - if (title) { - SDL_stack_free(title); - } - - if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) { - return -1; - } - return 0; -} - -void -WIN_SetWindowTitle(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - LPTSTR title; - - if (window->title) { - title = WIN_UTF8ToString(window->title); - } else { - title = NULL; - } - SetWindowText(hwnd, title ? title : TEXT("")); - if (title) { - SDL_free(title); - } -} - -void -WIN_SetWindowPosition(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - RECT rect; - DWORD style; - HWND top; - int x, y; - - /* Figure out what the window area will be */ - if (window->flags & SDL_WINDOW_FULLSCREEN) { - top = HWND_TOPMOST; - } else { - top = HWND_NOTOPMOST; - } - style = GetWindowLong(hwnd, GWL_STYLE); - rect.left = 0; - rect.top = 0; - rect.right = window->w; - rect.bottom = window->h; - AdjustWindowRectEx(&rect, style, - (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != - NULL), 0); - x = window->x + rect.left; - y = window->y + rect.top; - - SetWindowPos(hwnd, top, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE)); -} - -void -WIN_SetWindowSize(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - RECT rect; - DWORD style; - HWND top; - int w, h; - - /* Figure out what the window area will be */ - if (window->flags & SDL_WINDOW_FULLSCREEN) { - top = HWND_TOPMOST; - } else { - top = HWND_NOTOPMOST; - } - style = GetWindowLong(hwnd, GWL_STYLE); - rect.left = 0; - rect.top = 0; - rect.right = window->w; - rect.bottom = window->h; - AdjustWindowRectEx(&rect, style, - (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != - NULL), 0); - w = (rect.right - rect.left); - h = (rect.bottom - rect.top); - - SetWindowPos(hwnd, top, 0, 0, h, w, (SWP_NOCOPYBITS | SWP_NOMOVE)); -} - -void -WIN_ShowWindow(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - - ShowWindow(hwnd, SW_SHOW); -} - -void -WIN_HideWindow(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - - ShowWindow(hwnd, SW_HIDE); -} - -void -WIN_RaiseWindow(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - HWND top; - - if (window->flags & SDL_WINDOW_FULLSCREEN) { - top = HWND_TOPMOST; - } else { - top = HWND_NOTOPMOST; - } - SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE)); -} - -void -WIN_MaximizeWindow(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - - ShowWindow(hwnd, SW_MAXIMIZE); -} - -void -WIN_MinimizeWindow(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - - ShowWindow(hwnd, SW_MINIMIZE); -} - -void -WIN_RestoreWindow(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - - ShowWindow(hwnd, SW_RESTORE); -} - -void -WIN_SetWindowGrab(_THIS, SDL_Window * window) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - - if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && - (window->flags & SDL_WINDOW_INPUT_FOCUS)) { - RECT rect; - GetClientRect(hwnd, &rect); - ClientToScreen(hwnd, (LPPOINT) & rect); - ClientToScreen(hwnd, (LPPOINT) & rect + 1); - ClipCursor(&rect); - } else { - ClipCursor(NULL); - } -} - -void -WIN_DestroyWindow(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - - if (data) { -#ifdef SDL_VIDEO_OPENGL_WGL - if (window->flags & SDL_WINDOW_OPENGL) { - WIN_GL_CleanupWindow(_this, window); - } -#endif - ReleaseDC(data->hwnd, data->hdc); - if (data->created) { - DestroyWindow(data->hwnd); - } - SDL_free(data); - } -} - -SDL_bool -WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) -{ - HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; - if (info->version.major <= SDL_MAJOR_VERSION) { - info->window = hwnd; - return SDL_TRUE; - } else { - SDL_SetError("Application not compiled with SDL %d.%d\n", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); - return SDL_FALSE; - } -} - -/* vi: set ts=4 sw=4 expandtab: */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2006 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_sysvideo.h" +#include "../../events/SDL_keyboard_c.h" + +#include "SDL_win32video.h" + +/* This is included after SDL_win32video.h, which includes windows.h */ +#include "SDL_syswm.h" + +#include +#define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE) +#define PACKETMODE 0 +#include + +extern HCTX* g_hCtx; + +int highestId=0; + +static int +SetupWindowData(_THIS, SDL_Window * window, HWND hwnd, SDL_bool created) +{ + SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; + SDL_WindowData *data; + + /* Allocate the window data */ + data = (SDL_WindowData *) SDL_malloc(sizeof(*data)); + if (!data) { + SDL_OutOfMemory(); + return -1; + } + data->windowID = window->id; + data->hwnd = hwnd; + data->hdc = GetDC(hwnd); + data->created = created; + data->mouse_pressed = SDL_FALSE; + data->videodata = videodata; + + /* Associate the data with the window */ + if (!SetProp(hwnd, TEXT("SDL_WindowData"), data)) { + ReleaseDC(hwnd, data->hdc); + SDL_free(data); + WIN_SetError("SetProp() failed"); + return -1; + } + + /* Set up the window proc function */ + data->wndproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC); + if (data->wndproc == NULL) { + data->wndproc = DefWindowProc; + } else { + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) WIN_WindowProc); + } + + /* Fill in the SDL window with the window data */ + { + POINT point; + point.x = 0; + point.y = 0; + if (ClientToScreen(hwnd, &point)) { + window->x = point.x; + window->y = point.y; + } + } + { + RECT rect; + if (GetClientRect(hwnd, &rect)) { + window->w = rect.right; + window->h = rect.bottom; + } + } + { + DWORD style = GetWindowLong(hwnd, GWL_STYLE); + if (style & WS_VISIBLE) { + window->flags |= SDL_WINDOW_SHOWN; + } else { + window->flags &= ~SDL_WINDOW_SHOWN; + } + if (style & (WS_BORDER | WS_THICKFRAME)) { + window->flags &= ~SDL_WINDOW_BORDERLESS; + } else { + window->flags |= SDL_WINDOW_BORDERLESS; + } + if (style & WS_THICKFRAME) { + window->flags |= SDL_WINDOW_RESIZABLE; + } else { + window->flags &= ~SDL_WINDOW_RESIZABLE; + } + if (style & WS_MAXIMIZE) { + window->flags |= SDL_WINDOW_MAXIMIZED; + } else { + window->flags &= ~SDL_WINDOW_MAXIMIZED; + } + if (style & WS_MINIMIZE) { + window->flags |= SDL_WINDOW_MINIMIZED; + } else { + window->flags &= ~SDL_WINDOW_MINIMIZED; + } + } + if (GetFocus() == hwnd) { + int index = data->videodata->keyboard; + window->flags |= SDL_WINDOW_INPUT_FOCUS; + SDL_SetKeyboardFocus(index, data->windowID); + + if (window->flags & SDL_WINDOW_INPUT_GRABBED) { + RECT rect; + GetClientRect(hwnd, &rect); + ClientToScreen(hwnd, (LPPOINT) & rect); + ClientToScreen(hwnd, (LPPOINT) & rect + 1); + ClipCursor(&rect); + } + } + + /* All done! */ + window->driverdata = data; + return 0; +} + +int +WIN_CreateWindow(_THIS, SDL_Window * window) +{ + AXIS TabX,TabY; + LOGCONTEXT lc; + HWND hwnd; + HWND top; + RECT rect; + DWORD style = (WS_CLIPSIBLINGS | WS_CLIPCHILDREN); + int x, y; + int w, h; + + if (window->flags & SDL_WINDOW_BORDERLESS) { + style |= WS_POPUP; + } else { + style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX); + } + if (window->flags & SDL_WINDOW_RESIZABLE) { + style |= (WS_THICKFRAME | WS_MAXIMIZEBOX); + } + + /* Figure out what the window area will be */ + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + rect.left = 0; + rect.top = 0; + rect.right = window->w; + rect.bottom = window->h; + AdjustWindowRectEx(&rect, style, FALSE, 0); + w = (rect.right - rect.left); + h = (rect.bottom - rect.top); + + if (window->x == SDL_WINDOWPOS_CENTERED) { + x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; + } else if (window->x == SDL_WINDOWPOS_UNDEFINED) { + x = CW_USEDEFAULT; + } else { + x = window->x + rect.left; + } + if (window->y == SDL_WINDOWPOS_CENTERED) { + y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; + } else if (window->y == SDL_WINDOWPOS_UNDEFINED) { + y = CW_USEDEFAULT; + } else { + y = window->y + rect.top; + } + + hwnd = + CreateWindow(SDL_Appname, TEXT(""), style, x, y, w, h, NULL, NULL, + SDL_Instance, NULL); + + WTInfo(WTI_DEFCONTEXT, 0, &lc); + + lc.lcPktData = PACKETDATA; + lc.lcPktMode = PACKETMODE; + lc.lcOptions |= CXO_MESSAGES; + lc.lcMoveMask = PACKETDATA; + lc.lcBtnDnMask=lc.lcBtnUpMask = PACKETDATA; + + WTInfo(WTI_DEVICES,DVC_X,&TabX); + WTInfo(WTI_DEVICES,DVC_Y,&TabY); + + lc.lcInOrgX = 0; + lc.lcInOrgY = 0; + + lc.lcInExtX = TabX.axMax; + lc.lcInExtY = TabY.axMax; + + lc.lcOutOrgX = 0; + lc.lcOutOrgY = 0; + + lc.lcOutExtX = GetSystemMetrics(SM_CXSCREEN); + lc.lcOutExtY = -GetSystemMetrics(SM_CYSCREEN); + if(window->id>highestId) + { + HCTX* tmp_hctx; + highestId=window->id; + tmp_hctx= (HCTX*)SDL_realloc(g_hCtx,(highestId+1)*sizeof(HCTX)); + if (!tmp_hctx) { + SDL_OutOfMemory(); + return -1; + } + g_hCtx=tmp_hctx; + } + + g_hCtx[window->id] = WTOpen(hwnd, &lc, TRUE); + WIN_PumpEvents(_this); + + if (!hwnd) { + WIN_SetError("Couldn't create window"); + return -1; + } + + if (SetupWindowData(_this, window, hwnd, SDL_TRUE) < 0) { + DestroyWindow(hwnd); + return -1; + } +#ifdef SDL_VIDEO_OPENGL_WGL + if (window->flags & SDL_WINDOW_OPENGL) { + if (WIN_GL_SetupWindow(_this, window) < 0) { + WIN_DestroyWindow(_this, window); + return -1; + } + } +#endif + return 0; +} + +int +WIN_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) +{ + HWND hwnd = (HWND) data; + LPTSTR title; + int titleLen; + + /* Query the title from the existing window */ + titleLen = GetWindowTextLength(hwnd); + title = SDL_stack_alloc(TCHAR, titleLen + 1); + if (title) { + titleLen = GetWindowText(hwnd, title, titleLen); + } else { + titleLen = 0; + } + if (titleLen > 0) { + window->title = WIN_StringToUTF8(title); + } + if (title) { + SDL_stack_free(title); + } + + if (SetupWindowData(_this, window, hwnd, SDL_FALSE) < 0) { + return -1; + } + return 0; +} + +void +WIN_SetWindowTitle(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + LPTSTR title; + + if (window->title) { + title = WIN_UTF8ToString(window->title); + } else { + title = NULL; + } + SetWindowText(hwnd, title ? title : TEXT("")); + if (title) { + SDL_free(title); + } +} + +void +WIN_SetWindowPosition(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + RECT rect; + DWORD style; + HWND top; + int x, y; + + /* Figure out what the window area will be */ + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + style = GetWindowLong(hwnd, GWL_STYLE); + rect.left = 0; + rect.top = 0; + rect.right = window->w; + rect.bottom = window->h; + AdjustWindowRectEx(&rect, style, + (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != + NULL), 0); + x = window->x + rect.left; + y = window->y + rect.top; + + SetWindowPos(hwnd, top, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE)); +} + +void +WIN_SetWindowSize(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + RECT rect; + DWORD style; + HWND top; + int w, h; + + /* Figure out what the window area will be */ + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + style = GetWindowLong(hwnd, GWL_STYLE); + rect.left = 0; + rect.top = 0; + rect.right = window->w; + rect.bottom = window->h; + AdjustWindowRectEx(&rect, style, + (style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) != + NULL), 0); + w = (rect.right - rect.left); + h = (rect.bottom - rect.top); + + SetWindowPos(hwnd, top, 0, 0, h, w, (SWP_NOCOPYBITS | SWP_NOMOVE)); +} + +void +WIN_ShowWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_SHOW); +} + +void +WIN_HideWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_HIDE); +} + +void +WIN_RaiseWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + HWND top; + + if (window->flags & SDL_WINDOW_FULLSCREEN) { + top = HWND_TOPMOST; + } else { + top = HWND_NOTOPMOST; + } + SetWindowPos(hwnd, top, 0, 0, 0, 0, (SWP_NOMOVE | SWP_NOSIZE)); +} + +void +WIN_MaximizeWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_MAXIMIZE); +} + +void +WIN_MinimizeWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_MINIMIZE); +} + +void +WIN_RestoreWindow(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + ShowWindow(hwnd, SW_RESTORE); +} + +void +WIN_SetWindowGrab(_THIS, SDL_Window * window) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + + if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && + (window->flags & SDL_WINDOW_INPUT_FOCUS)) { + RECT rect; + GetClientRect(hwnd, &rect); + ClientToScreen(hwnd, (LPPOINT) & rect); + ClientToScreen(hwnd, (LPPOINT) & rect + 1); + ClipCursor(&rect); + } else { + ClipCursor(NULL); + } +} + +void +WIN_DestroyWindow(_THIS, SDL_Window * window) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (data) { +#ifdef SDL_VIDEO_OPENGL_WGL + if (window->flags & SDL_WINDOW_OPENGL) { + WIN_GL_CleanupWindow(_this, window); + } +#endif + ReleaseDC(data->hwnd, data->hdc); + if (data->created) { + WTClose(g_hCtx[window->id]); + DestroyWindow(data->hwnd); + } + SDL_free(data); + WTClose(g_hCtx[window->id]); + } +} + +SDL_bool +WIN_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) +{ + HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd; + if (info->version.major <= SDL_MAJOR_VERSION) { + info->window = hwnd; + return SDL_TRUE; + } else { + SDL_SetError("Application not compiled with SDL %d.%d\n", + SDL_MAJOR_VERSION, SDL_MINOR_VERSION); + return SDL_FALSE; + } +} + +/* vi: set ts=4 sw=4 expandtab: */