diff src/video/win32/SDL_win32events.c @ 1722:5daa04d862f1 SDL-1.3

Added a userdata parameter for event filters. Added a function to filter the existing queued events. Added explicit support for relative mouse mode to the API.
author Sam Lantinga <slouken@libsdl.org>
date Fri, 30 Jun 2006 08:18:44 +0000
parents 5b9f50c957ed
children 6c63fc2bd986
line wrap: on
line diff
--- a/src/video/win32/SDL_win32events.c	Fri Jun 30 05:50:35 2006 +0000
+++ b/src/video/win32/SDL_win32events.c	Fri Jun 30 08:18:44 2006 +0000
@@ -22,21 +22,363 @@
 #include "SDL_config.h"
 
 #include "SDL_win32video.h"
+#include "../../events/SDL_events_c.h"
 
 
 LRESULT CALLBACK
 WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
     SDL_WindowData *data;
-    SDL_Window *window;
 
     /* Get the window data for the window */
     data = (SDL_WindowData *) GetProp(hwnd, TEXT("SDL_WindowData"));
     if (!data) {
         return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
     }
-    window = data->window;
+#if 0
+    switch (msg) {
+
+    case WM_ACTIVATE:
+        {
+            BOOL minimized;
+
+            minimized = HIWORD(wParam);
+            if (!minimized && (LOWORD(wParam) != WA_INACTIVE)) {
+                SDL_PrivateWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN,
+                                       0, 0);
+                SDL_PrivateWindowEvent(data->windowID,
+                                       SDL_WINDOWEVENT_RESTORED, 0, 0);
+                if (IsZoomed(hwnd)) {
+                    SDL_PrivateWindowEvent(data->windowID,
+                                           SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
+                }
+                SDL_PrivateWindowEvent(data->windowID,
+                                       SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
+                /* FIXME: Restore mode state (mode, gamma, grab) */
+                /* FIXME: Update keyboard state */
+            } else {
+                SDL_PrivateWindowEvent(data->windowID,
+                                       SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
+                if (minimized) {
+                    SDL_PrivateWindowEvent(data->windowID,
+                                           SDL_WINDOWEVENT_MINIMIZED, 0, 0);
+                }
+                /* FIXME: Restore desktop state (mode, gamma, grab) */
+            }
+            return (0);
+        }
+        break;
+
+    case WM_MOUSEMOVE:
+        {
+            int index;
+            SDL_Mouse *mouse;
+
+            if (!
+                (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_MOUSE_FOCUS))
+            {
+                /* mouse has entered the window */
+                TRACKMOUSEEVENT tme;
+
+                tme.cbSize = sizeof(tme);
+                tme.dwFlags = TME_LEAVE;
+                tme.hwndTrack = hwnd;
+                TrackMouseEvent(&tme);
+
+                SDL_PrivateWindowEvent(data->windowID, SDL_WINDOWEVENT_ENTER,
+                                       0, 0);
+            }
+
+            index = data->videodata->mouse;
+            mouse = SDL_GetMouse(index);
+            if (mouse) {
+                int x, y;
+                /* 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(SDL_Window, &center);
+                        SetCursorPos(center.x, center.y);
+                        SDL_SendMouseMotion(index, data->windowID, 1, x, y);
+                    }
+                } else {
+                    SDL_SendMouseMotion(index, data->windowID, 0, x, y);
+                }
+            }
+        }
+        return (0);
+
+    case WM_MOUSELEAVE:
+        {
+            SDL_PrivateWindowEvent(data->windowID, SDL_WINDOWEVENT_LEAVE, 0,
+                                   0);
+        }
+        return (0);
+
+    case WM_LBUTTONDOWN:
+    case WM_LBUTTONUP:
+    case WM_MBUTTONDOWN:
+    case WM_MBUTTONUP:
+    case WM_RBUTTONDOWN:
+    case WM_RBUTTONUP:
+        {
+            int x, y;
+            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;
+            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;
+                }
+            }
+            x = LOWORD(lParam);
+            y = HIWORD(lParam);
+#ifdef _WIN32_WCE
+            if (SDL_VideoSurface)
+                GapiTransform(this->hidden->userOrientation,
+                              this->hidden->hiresFix, &x, &y);
+#endif
+            posted = SDL_PrivateMouseButton(state, button, x, y);
+        }
+
+        return (0);
+
 
+#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
+    case WM_MOUSEWHEEL:
+        if (SDL_VideoSurface && !DINPUT_FULLSCREEN()) {
+            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_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_INTERNALOPENGL)) {
+                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);
+    }
+#endif
     return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam);
 }