Mac and Linux SDL2 binary snapshots
Edward Rudd
2014-03-08 e2b6e957100030b4c9e8d720157b0a34195e6dcb
source/src/video/windows/SDL_windowsevents.c
@@ -1,6 +1,6 @@
/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
@@ -18,13 +18,14 @@
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_config.h"
#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_WINDOWS
#include "SDL_windowsvideo.h"
#include "SDL_windowsshape.h"
#include "SDL_syswm.h"
#include "SDL_timer.h"
#include "SDL_vkeys.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_touch_c.h"
@@ -66,6 +67,9 @@
#endif
#ifndef WM_TOUCH
#define WM_TOUCH 0x0240
#endif
#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif
static SDL_Scancode
@@ -256,6 +260,30 @@
    }
}
void
WIN_CheckAsyncMouseRelease( SDL_WindowData *data )
{
    Uint32 mouseFlags;
    SHORT keyState;
    /* mouse buttons may have changed state here, we need to resync them,
       but we will get a WM_MOUSEMOVE right away which will fix things up if in non raw mode also
    */
    mouseFlags = SDL_GetMouseState( NULL, NULL );
    keyState = GetAsyncKeyState( VK_LBUTTON );
    WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), ( mouseFlags & SDL_BUTTON_LMASK ), data, SDL_BUTTON_LEFT );
    keyState = GetAsyncKeyState( VK_RBUTTON );
    WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), ( mouseFlags & SDL_BUTTON_RMASK ), data, SDL_BUTTON_RIGHT );
    keyState = GetAsyncKeyState( VK_MBUTTON );
    WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), ( mouseFlags & SDL_BUTTON_MMASK ), data, SDL_BUTTON_MIDDLE );
    keyState = GetAsyncKeyState( VK_XBUTTON1 );
    WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), ( mouseFlags & SDL_BUTTON_X1MASK ), data, SDL_BUTTON_X1 );
    keyState = GetAsyncKeyState( VK_XBUTTON2 );
    WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), ( mouseFlags & SDL_BUTTON_X2MASK ), data, SDL_BUTTON_X2 );
    data->mouse_button_flags = 0;
}
SDL_FORCE_INLINE BOOL
WIN_ConvertUTF32toUTF8(UINT32 codepoint, char * text)
{
@@ -309,15 +337,15 @@
    }
#ifdef WMMSG_DEBUG
   {
      char message[1024];
      if (msg > MAX_WMMSG) {
         SDL_snprintf(message, sizeof(message), "Received windows message: %p UNKNOWN (%d) -- 0x%X, 0x%X\n", hwnd, msg, wParam, lParam);
      } else {
         SDL_snprintf(message, sizeof(message), "Received windows message: %p %s -- 0x%X, 0x%X\n", hwnd, wmtab[msg], wParam, lParam);
      }
      OutputDebugStringA(message);
   }
    {
        char message[1024];
        if (msg > MAX_WMMSG) {
            SDL_snprintf(message, sizeof(message), "Received windows message: %p UNKNOWN (%d) -- 0x%X, 0x%X\n", hwnd, msg, wParam, lParam);
        } else {
            SDL_snprintf(message, sizeof(message), "Received windows message: %p %s -- 0x%X, 0x%X\n", hwnd, wmtab[msg], wParam, lParam);
        }
        OutputDebugStringA(message);
    }
#endif /* WMMSG_DEBUG */
    if (IME_HandleMessage(hwnd, msg, wParam, &lParam, data->videodata))
@@ -341,53 +369,12 @@
            minimized = HIWORD(wParam);
            if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
                Uint32 mouseFlags;
                SHORT keyState;
                SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
                SDL_SendWindowEvent(data->window,
                                    SDL_WINDOWEVENT_RESTORED, 0, 0);
                if (IsZoomed(hwnd)) {
                    SDL_SendWindowEvent(data->window,
                                        SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
                }
                if (SDL_GetKeyboardFocus() != data->window) {
                    SDL_SetKeyboardFocus(data->window);
                }
                /* mouse buttons may have changed state here, we need
                to resync them, but we will get a WM_MOUSEMOVE right away which will fix
                things up if in non raw mode also
                */
                mouseFlags = SDL_GetMouseState( NULL, NULL );
                keyState = GetAsyncKeyState( VK_LBUTTON );
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT );
                keyState = GetAsyncKeyState( VK_RBUTTON );
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT );
                keyState = GetAsyncKeyState( VK_MBUTTON );
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE );
                keyState = GetAsyncKeyState( VK_XBUTTON1 );
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1 );
                keyState = GetAsyncKeyState( VK_XBUTTON2 );
                WIN_CheckWParamMouseButton( ( keyState & 0x8000 ), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2 );
                data->mouse_button_flags = 0;
                if(SDL_GetMouse()->relative_mode) {
                    LONG cx, cy;
                    RECT rect;
                    GetWindowRect(hwnd, &rect);
                    cx = (rect.left + rect.right) / 2;
                    cy = (rect.top + rect.bottom) / 2;
                    /* Make an absurdly small clip rect */
                    rect.left = cx-1;
                    rect.right = cx+1;
                    rect.top = cy-1;
                    rect.bottom = cy+1;
                    ClipCursor(&rect);
                }
                WIN_UpdateClipCursor(data->window);
                WIN_CheckAsyncMouseRelease(data);
                /*
                 * FIXME: Update keyboard state
@@ -397,18 +384,20 @@
                if (SDL_GetKeyboardFocus() == data->window) {
                    SDL_SetKeyboardFocus(NULL);
                }
                if (minimized) {
                    SDL_SendWindowEvent(data->window,
                                        SDL_WINDOWEVENT_MINIMIZED, 0, 0);
                }
                ClipCursor(NULL);
            }
        }
        returnCode = 0;
        break;
    case WM_MOUSEMOVE:
        if( !SDL_GetMouse()->relative_mode )
            SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
        {
            SDL_Mouse *mouse = SDL_GetMouse();
            if (!mouse->relative_mode || mouse->relative_mode_warp) {
                SDL_SendMouseMotion(data->window, 0, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
            }
        }
        /* don't break here, fall through to check the wParam like the button presses */
    case WM_LBUTTONUP:
    case WM_RBUTTONUP:
@@ -418,49 +407,50 @@
    case WM_RBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_XBUTTONDOWN:
        if( !SDL_GetMouse()->relative_mode )
            WIN_CheckWParamMouseButtons( wParam, data );
        {
            SDL_Mouse *mouse = SDL_GetMouse();
            if (!mouse->relative_mode || mouse->relative_mode_warp) {
                WIN_CheckWParamMouseButtons(wParam, data);
            }
        }
        break;
    case WM_INPUT:
    {
        HRAWINPUT hRawInput = (HRAWINPUT)lParam;
        RAWINPUT inp;
        UINT size = sizeof(inp);
        if(!SDL_GetMouse()->relative_mode)
            break;
        GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
        /* Mouse data */
        if(inp.header.dwType == RIM_TYPEMOUSE)
        {
            RAWMOUSE* mouse = &inp.data.mouse;
            SDL_Mouse *mouse = SDL_GetMouse();
            HRAWINPUT hRawInput = (HRAWINPUT)lParam;
            RAWINPUT inp;
            UINT size = sizeof(inp);
            if((mouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE)
            {
                SDL_SendMouseMotion(data->window, 0, 1, (int)mouse->lLastX, (int)mouse->lLastY);
            if (!mouse->relative_mode || mouse->relative_mode_warp || mouse->focus != data->window) {
                break;
            }
            else
            {
                /* synthesize relative moves from the abs position */
                static SDL_Point initialMousePoint;
                if ( initialMousePoint.x == 0 && initialMousePoint.y == 0 )
                {
            GetRawInputData(hRawInput, RID_INPUT, &inp, &size, sizeof(RAWINPUTHEADER));
            /* Mouse data */
            if (inp.header.dwType == RIM_TYPEMOUSE) {
                RAWMOUSE* mouse = &inp.data.mouse;
                if ((mouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
                    SDL_SendMouseMotion(data->window, 0, 1, (int)mouse->lLastX, (int)mouse->lLastY);
                } else {
                    /* synthesize relative moves from the abs position */
                    static SDL_Point initialMousePoint;
                    if (initialMousePoint.x == 0 && initialMousePoint.y == 0) {
                        initialMousePoint.x = mouse->lLastX;
                        initialMousePoint.y = mouse->lLastY;
                    }
                    SDL_SendMouseMotion(data->window, 0, 1, (int)(mouse->lLastX-initialMousePoint.x), (int)(mouse->lLastY-initialMousePoint.y) );
                    initialMousePoint.x = mouse->lLastX;
                    initialMousePoint.y = mouse->lLastY;
                }
                SDL_SendMouseMotion(data->window, 0, 1, (int)(mouse->lLastX-initialMousePoint.x), (int)(mouse->lLastY-initialMousePoint.y) );
                initialMousePoint.x = mouse->lLastX;
                initialMousePoint.y = mouse->lLastY;
                WIN_CheckRawMouseButtons( mouse->usButtonFlags, data );
            }
            WIN_CheckRawMouseButtons( mouse->usButtonFlags, data );
        }
        break;
    }
    case WM_MOUSEWHEEL:
        {
@@ -478,16 +468,37 @@
                    s_AccumulatedMotion += WHEEL_DELTA;
                }
            }
            break;
        }
        break;
    case WM_MOUSEHWHEEL:
        {
            static short s_AccumulatedMotion;
            s_AccumulatedMotion += GET_WHEEL_DELTA_WPARAM(wParam);
            if (s_AccumulatedMotion > 0) {
                while (s_AccumulatedMotion >= WHEEL_DELTA) {
                    SDL_SendMouseWheel(data->window, 0, 1, 0);
                    s_AccumulatedMotion -= WHEEL_DELTA;
                }
            } else {
                while (s_AccumulatedMotion <= -WHEEL_DELTA) {
                    SDL_SendMouseWheel(data->window, 0, -1, 0);
                    s_AccumulatedMotion += WHEEL_DELTA;
                }
            }
        }
        break;
#ifdef WM_MOUSELEAVE
    case WM_MOUSELEAVE:
        if (SDL_GetMouseFocus() == data->window && !SDL_GetMouse()->relative_mode) {
            POINT cursorPos;
            GetCursorPos(&cursorPos);
            ScreenToClient(hwnd, &cursorPos);
            SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
            if (!IsIconic(hwnd)) {
                POINT cursorPos;
                GetCursorPos(&cursorPos);
                ScreenToClient(hwnd, &cursorPos);
                SDL_SendMouseMotion(data->window, 0, 0, cursorPos.x, cursorPos.y);
            }
            SDL_SetMouseFocus(NULL);
        }
        returnCode = 0;
@@ -509,8 +520,8 @@
            GetKeyboardState(keyboardState);
            if (ToUnicode(wParam, (lParam >> 16) & 0xff, keyboardState, (LPWSTR)&utf32, 1, 0) > 0) {
                WORD repitition;
                for (repitition = lParam & 0xffff; repitition > 0; repitition--) {
                WORD repetition;
                for (repetition = lParam & 0xffff; repetition > 0; repetition--) {
                    WIN_ConvertUTF32toUTF8(utf32, text);
                    SDL_SendKeyboardText(text);
                }
@@ -523,9 +534,19 @@
    case WM_KEYUP:
        {
            SDL_Scancode code = WindowsScanCodeToSDLScanCode( lParam, wParam );
            const Uint8 *keyboardState = SDL_GetKeyboardState(NULL);
            /* Detect relevant keyboard shortcuts */
            if (keyboardState[SDL_SCANCODE_LALT] == SDL_PRESSED || keyboardState[SDL_SCANCODE_RALT] == SDL_PRESSED ) {
                /* ALT+F4: Close window */
                if (code == SDL_SCANCODE_F4) {
                    SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
                }
            }
            if ( code != SDL_SCANCODE_UNKNOWN ) {
                if (code == SDL_SCANCODE_PRINTSCREEN &&
                    SDL_GetKeyboardState(NULL)[code] == SDL_RELEASED) {
                    keyboardState[code] == SDL_RELEASED) {
                    SDL_SendKeyboardKey(SDL_PRESSED, code);
                }
                SDL_SendKeyboardKey(SDL_RELEASED, code);
@@ -535,20 +556,8 @@
        break;
    case WM_UNICHAR:
        {
            if (wParam == UNICODE_NOCHAR) {
                returnCode = 1;
                break;
            }
        }
        /* no break */
    case WM_CHAR:
        {
            char text[5];
            WIN_ConvertUTF32toUTF8(wParam, text);
            SDL_SendKeyboardText(text);
        }
        /* Ignore WM_CHAR messages that come from TranslateMessage(), since we handle WM_KEY* messages directly */
        returnCode = 0;
        break;
@@ -560,6 +569,39 @@
        returnCode = 1;
        break;
#endif /* WM_INPUTLANGCHANGE */
    case WM_NCLBUTTONDOWN:
        {
            data->in_title_click = SDL_TRUE;
            WIN_UpdateClipCursor(data->window);
        }
        break;
    case WM_NCMOUSELEAVE:
        {
            data->in_title_click = SDL_FALSE;
            WIN_UpdateClipCursor(data->window);
        }
        break;
    case WM_ENTERSIZEMOVE:
    case WM_ENTERMENULOOP:
        {
            data->in_modal_loop = SDL_TRUE;
            WIN_UpdateClipCursor(data->window);
        }
        break;
    case WM_EXITSIZEMOVE:
    case WM_EXITMENULOOP:
        {
            data->in_modal_loop = SDL_FALSE;
            WIN_UpdateClipCursor(data->window);
            /* The mouse may have been released during the modal loop */
            WIN_CheckAsyncMouseRelease(data);
        }
        break;
#ifdef WM_GETMINMAXINFO
    case WM_GETMINMAXINFO:
@@ -574,9 +616,13 @@
            BOOL menu;
            BOOL constrain_max_size;
            /* If we allow resizing, let the resize happen naturally */
            if (SDL_IsShapedWindow(data->window))
                Win32_ResizeWindowShape(data->window);
            /* If this is an expected size change, allow it */
            if (data->expected_resize) {
                break;
            }
            /* Get the current position of our window */
            GetWindowRect(hwnd, &size);
@@ -645,20 +691,14 @@
            RECT rect;
            int x, y;
            int w, h;
            Uint32 window_flags;
            if (!GetClientRect(hwnd, &rect) ||
                (rect.right == rect.left && rect.bottom == rect.top)) {
            if (!GetClientRect(hwnd, &rect) || IsRectEmpty(&rect)) {
                break;
            }
            ClientToScreen(hwnd, (LPPOINT) & rect);
            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
            window_flags = SDL_GetWindowFlags(data->window);
            if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
                (window_flags & SDL_WINDOW_INPUT_FOCUS)) {
                ClipCursor(&rect);
            }
            WIN_UpdateClipCursor(data->window);
            x = rect.left;
            y = rect.top;
@@ -668,6 +708,26 @@
            h = rect.bottom - rect.top;
            SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESIZED, w,
                                h);
        }
        break;
    case WM_SIZE:
        {
            switch (wParam)
            {
            case SIZE_MAXIMIZED:
                SDL_SendWindowEvent(data->window,
                    SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
                break;
            case SIZE_MINIMIZED:
                SDL_SendWindowEvent(data->window,
                    SDL_WINDOWEVENT_MINIMIZED, 0, 0);
                break;
            default:
                SDL_SendWindowEvent(data->window,
                    SDL_WINDOWEVENT_RESTORED, 0, 0);
                break;
            }
        }
        break;
@@ -815,8 +875,17 @@
{
    const Uint8 *keystate;
    MSG msg;
    DWORD start_ticks = GetTickCount();
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
        DispatchMessage(&msg);
        /* Always translate the message in case it's a non-SDL window (e.g. with Qt integration) */
        TranslateMessage(&msg);
        DispatchMessage( &msg );
        /* Make sure we don't busy loop here forever if there are lots of events coming in */
        if (SDL_TICKS_PASSED(msg.time, start_ticks)) {
            break;
        }
    }
    /* Windows loses a shift KEYUP event when you have both pressed at once and let go of one.