Mercurial > sdl-ios-xcode
diff src/video/win32/SDL_win32events.c @ 2710:44e49d3fa6cf
Final merge of Google Summer of Code 2008 work...
Many-mouse and tablet support
by Szymon Wilczek, mentored by Ryan C. Gordon
Everything concerning the project is noted on the wiki:
http://wilku.ravenlord.ws/doku.php?id=start
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 25 Aug 2008 06:33:00 +0000 |
parents | 3202e4826c57 |
children | 62e7af9b2b67 |
line wrap: on
line diff
--- a/src/video/win32/SDL_win32events.c Mon Aug 25 05:30:28 2008 +0000 +++ b/src/video/win32/SDL_win32events.c Mon Aug 25 06:33:00 2008 +0000 @@ -19,6 +19,12 @@ Sam Lantinga slouken@libsdl.org */ + +#if (_WIN32_WINNT < 0x0501) +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif + #include "SDL_config.h" #include "SDL_win32video.h" @@ -26,6 +32,11 @@ #include "SDL_vkeys.h" #include "../../events/SDL_events_c.h" +#include <wintab.h> +#define PACKETDATA ( PK_X | PK_Y | PK_BUTTONS | PK_NORMAL_PRESSURE | PK_CURSOR) +#define PACKETMODE 0 +#include <pktdef.h> + /*#define WMMSG_DEBUG*/ #ifdef WMMSG_DEBUG #include <stdio.h> @@ -49,6 +60,12 @@ #define GET_XBUTTON_WPARAM(w) (HIWORD(w)) #endif +extern HCTX *g_hCtx; +extern HANDLE *mice; +extern int total_mice; +extern int tablet; +int pressure = 0; /* the pressure reported by the tablet */ + static WPARAM RemapVKEY(WPARAM wParam, LPARAM lParam) { @@ -84,6 +101,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { SDL_WindowData *data; + RAWINPUT *raw; + PACKET packet; /* Send a SDL_SYSWMEVENT if the application wants them */ if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) { @@ -114,10 +133,40 @@ fprintf(log, " -- 0x%X, 0x%X\n", wParam, lParam); fclose(log); } + #endif switch (msg) { + case WT_PACKET: + { + /* if we receive such data we need to update the pressure */ + if (WTPacket((HCTX) lParam, wParam, &packet)) { + SDL_ChangeEnd(tablet, (int) packet.pkCursor); + pressure = (int) packet.pkNormalPressure; + } + } + break; + + case WT_PROXIMITY: + { + /* checking where the proximity message showed up */ + int h_context = LOWORD(lParam); + LPPOINT point; + GetCursorPos(&point); + ScreenToClient(hwnd, &point); + + /* are we in proximity or out of proximity */ + if (h_context == 0) { + SDL_SendProximity(tablet, (int) (&point->x), + (int) (&point->y), SDL_PROXIMITYOUT); + } else { + SDL_SendProximity(tablet, (int) (&point->x), + (int) (&point->y), SDL_PROXIMITYIN); + } + } + break; + case WM_SHOWWINDOW: { if (wParam) { @@ -161,48 +210,72 @@ SDL_WINDOWEVENT_MINIMIZED, 0, 0); } } - return (0); } - break; - - case WM_MOUSEMOVE: - { - int index; - SDL_Mouse *mouse; - int x, y; + return (0); - index = data->videodata->mouse; - mouse = SDL_GetMouse(index); + case WM_INPUT: /* mouse events */ + { + LPBYTE lpb; + int w, h; + const RAWINPUTHEADER *header; + int index; + int i; + int size = 0; + const RAWMOUSE *raw_mouse = NULL; + LPPOINT point; + USHORT flags; - if (mouse->focus != data->windowID) { - TRACKMOUSEEVENT tme; - - tme.cbSize = sizeof(tme); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = hwnd; - TrackMouseEvent(&tme); + /* we're collecting data from the mouse */ + GetRawInputData((HRAWINPUT) lParam, RID_INPUT, NULL, &size, + sizeof(RAWINPUTHEADER)); + lpb = SDL_malloc(size * sizeof(LPBYTE)); + GetRawInputData((HRAWINPUT) lParam, RID_INPUT, lpb, &size, + sizeof(RAWINPUTHEADER)); + raw = (RAWINPUT *) lpb; + header = &raw->header; + flags = raw->data.mouse.usButtonFlags; - SDL_SetMouseFocus(index, data->windowID); + /* we're checking which mouse generated the event */ + for (i = 0; i < total_mice; ++i) { + if (mice[i] == header->hDevice) { + index = i; + break; + } } + GetCursorPos(&point); + ScreenToClient(hwnd, &point); + SDL_GetWindowSize(data->windowID, &w, &h); + SDL_UpdateCoordinates(w, h); /* we're updating the current window size */ - /* 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); + /* if the message was sent by a tablet we have to send also pressure */ + if (i == tablet) { + SDL_SendMouseMotion(index, 0, (int) (&point->x), + (int) (&point->y), pressure); + } else { + SDL_SendMouseMotion(index, 0, (int) (&point->x), + (int) (&point->y), 0); + } + /* we're sending mouse buttons messages to check up if sth changed */ + if (flags & RI_MOUSE_BUTTON_1_DOWN) { + SDL_SendMouseButton(index, SDL_PRESSED, SDL_BUTTON_LEFT); + } else if (flags & RI_MOUSE_BUTTON_1_UP) { + SDL_SendMouseButton(index, SDL_RELEASED, SDL_BUTTON_LEFT); + } + if (flags & RI_MOUSE_BUTTON_2_DOWN) { + SDL_SendMouseButton(index, SDL_PRESSED, SDL_BUTTON_MIDDLE); + } else if (flags & RI_MOUSE_BUTTON_2_UP) { + SDL_SendMouseButton(index, SDL_RELEASED, SDL_BUTTON_MIDDLE); + } + if (flags & RI_MOUSE_BUTTON_3_DOWN) { + SDL_SendMouseButton(index, SDL_PRESSED, SDL_BUTTON_RIGHT); + } else if (flags & RI_MOUSE_BUTTON_3_UP) { + SDL_SendMouseButton(index, SDL_RELEASED, SDL_BUTTON_RIGHT); + } + if (flags & RI_MOUSE_WHEEL) { + if (raw->data.mouse.usButtonData != 0) { + SDL_SendMouseWheel(index, 0, + raw->data.mouse.usButtonData); } - } else { - SDL_SendMouseMotion(index, 0, x, y); } } return (0); @@ -221,117 +294,6 @@ } 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: { @@ -426,6 +388,7 @@ wParam = VK_ENTER; break; } + /* Windows only reports keyup for print screen */ if (wParam == VK_SNAPSHOT && SDL_GetKeyboardState(NULL)[SDL_SCANCODE_PRINTSCREEN] == @@ -499,11 +462,9 @@ 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); - + AdjustWindowRect(&size, style, + style & WS_CHILDWINDOW ? FALSE : GetMenu(hwnd) + != NULL); w = size.right - size.left; h = size.bottom - size.top; @@ -661,8 +622,9 @@ /* Register the application class */ class.hCursor = NULL; - class.hIcon = LoadImage(SDL_Instance, SDL_Appname, - IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR); + class.hIcon = + LoadImage(SDL_Instance, SDL_Appname, IMAGE_ICON, 0, 0, + LR_DEFAULTCOLOR); class.lpszMenuName = NULL; class.lpszClassName = SDL_Appname; class.hbrBackground = NULL; @@ -707,11 +669,8 @@ { TCHAR buffer[1024]; char *message; - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError(), 0, buffer, SDL_arraysize(buffer), NULL); - + 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);