From 0d18b5a806fcd0e491dbf266c6ba99c66abc71ee Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 6 Jul 2006 07:17:11 +0000 Subject: [PATCH] Proof of concept done - Win32 GDI implementation mostly complete. --- configure.in | 2 +- include/SDL_compat.h | 6 + include/SDL_events.h | 33 +- include/SDL_keyboard.h | 2 +- include/SDL_mouse.h | 4 - include/SDL_video.h | 9 + src/SDL_compat.c | 46 +- src/events/SDL_events.c | 8 +- src/events/SDL_events_c.h | 3 + src/events/SDL_keyboard.c | 166 +++-- src/events/SDL_keyboard_c.h | 10 +- src/events/SDL_mouse.c | 93 ++- src/events/SDL_mouse_c.h | 12 +- src/events/SDL_windowevents.c | 14 +- src/events/SDL_windowevents_c.h | 2 - src/video/SDL_surface.c | 2 +- src/video/SDL_video.c | 79 +- src/video/win32/SDL_dibrender.c | 711 ++++++++++++++++++ src/video/win32/SDL_dibrender.h | 28 + src/video/win32/SDL_vkeys.h | 76 ++ src/video/win32/SDL_win32events.c | 772 +++++++++++++++----- src/video/win32/SDL_win32keyboard.c | 8 + src/video/win32/SDL_win32keyboard.h | 1 + src/video/win32/SDL_win32mouse.c | 8 + src/video/win32/SDL_win32mouse.h | 1 + src/video/win32/SDL_win32video.c | 50 +- src/video/win32/SDL_win32video.h | 1 + src/video/win32/SDL_win32window.c | 3 + src/video/win32/SDL_win32window.h | 1 + src/video/win32/wmmsg.h | 1032 +++++++++++++++++++++++++++ test/graywin.c | 7 +- test/testsprite2.c | 24 +- test/testwm.c | 4 +- test/threadwin.c | 4 +- 34 files changed, 2927 insertions(+), 295 deletions(-) create mode 100644 src/video/win32/SDL_dibrender.c create mode 100644 src/video/win32/SDL_dibrender.h create mode 100644 src/video/win32/SDL_vkeys.h create mode 100644 src/video/win32/wmmsg.h diff --git a/configure.in b/configure.in index d51abe4dc..57e229023 100644 --- a/configure.in +++ b/configure.in @@ -2347,7 +2347,7 @@ case "$host" in have_loadso=yes fi # Set up the system libraries we need - EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lmsimg32 -lwinmm" # The Win32 platform requires special setup SDLMAIN_SOURCES="$srcdir/src/main/win32/*.c" SDL_CFLAGS="$SDL_CFLAGS -Dmain=SDL_main" diff --git a/include/SDL_compat.h b/include/SDL_compat.h index 1a2a0246a..fe1cd30ad 100644 --- a/include/SDL_compat.h +++ b/include/SDL_compat.h @@ -57,6 +57,12 @@ extern "C" { #define SDL_ACTIVEEVENT SDL_EVENT_RESERVED1 #define SDL_VIDEORESIZE SDL_EVENT_RESERVED2 #define SDL_VIDEOEXPOSE SDL_EVENT_RESERVED3 +#define SDL_ACTIVEEVENTMASK SDL_EVENTMASK(SDL_ACTIVEEVENT) +#define SDL_VIDEORESIZEMASK SDL_EVENTMASK(SDL_VIDEORESIZE) +#define SDL_VIDEOEXPOSEMASK SDL_EVENTMASK(SDL_VIDEOEXPOSE) + +#define SDL_BUTTON_WHEELUP 4 +#define SDL_BUTTON_WHEELDOWN 5 typedef struct SDL_VideoInfo { diff --git a/include/SDL_events.h b/include/SDL_events.h index 669648165..97d16e384 100644 --- a/include/SDL_events.h +++ b/include/SDL_events.h @@ -60,9 +60,11 @@ typedef enum SDL_WINDOWEVENT, /**< Window state change */ SDL_KEYDOWN, /**< Keys pressed */ SDL_KEYUP, /**< Keys released */ + SDL_TEXTINPUT, /**< Keyboard text input */ SDL_MOUSEMOTION, /**< Mouse moved */ SDL_MOUSEBUTTONDOWN, /**< Mouse button pressed */ SDL_MOUSEBUTTONUP, /**< Mouse button released */ + SDL_MOUSEWHEEL, /**< Mouse wheel motion */ SDL_JOYAXISMOTION, /**< Joystick axis motion */ SDL_JOYBALLMOTION, /**< Joystick trackball motion */ SDL_JOYHATMOTION, /**< Joystick hat position change */ @@ -93,9 +95,11 @@ typedef enum SDL_KEYDOWNMASK = SDL_EVENTMASK(SDL_KEYDOWN), SDL_KEYUPMASK = SDL_EVENTMASK(SDL_KEYUP), SDL_KEYEVENTMASK = SDL_EVENTMASK(SDL_KEYDOWN) | SDL_EVENTMASK(SDL_KEYUP), + SDL_TEXTINPUTMASK = SDL_EVENTMASK(SDL_TEXTINPUT), SDL_MOUSEMOTIONMASK = SDL_EVENTMASK(SDL_MOUSEMOTION), SDL_MOUSEBUTTONDOWNMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN), SDL_MOUSEBUTTONUPMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONUP), + SDL_MOUSEWHEELMASK = SDL_EVENTMASK(SDL_MOUSEWHEEL), SDL_MOUSEEVENTMASK = SDL_EVENTMASK(SDL_MOUSEMOTION) | SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN) | SDL_EVENTMASK(SDL_MOUSEBUTTONUP), SDL_JOYAXISMOTIONMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION), @@ -141,17 +145,17 @@ typedef struct SDL_KeyboardEvent } SDL_KeyboardEvent; /** - * \struct SDL_CharEvent + * \struct SDL_TextInputEvent * - * \brief Keyboard input event structure + * \brief Keyboard text input event structure */ -typedef struct SDL_CharEvent +typedef struct SDL_TextInputEvent { - Uint8 type; /**< SDL_CHARINPUT (FIXME: NYI) */ + Uint8 type; /**< SDL_TEXTINPUT */ Uint8 which; /**< The keyboard device index */ char text[32]; /**< The input text */ SDL_WindowID windowID; /**< The window with keyboard focus, if any */ -} SDL_CharEvent; +} SDL_TextInputEvent; /** * \struct SDL_MouseMotionEvent @@ -186,6 +190,19 @@ typedef struct SDL_MouseButtonEvent SDL_WindowID windowID; /**< The window with mouse focus, if any */ } SDL_MouseButtonEvent; +/** + * \struct SDL_MouseWheelEvent + * + * \brief Mouse wheel event structure + */ +typedef struct SDL_MouseWheelEvent +{ + Uint8 type; /**< SDL_MOUSEWHEEL */ + Uint8 which; /**< The mouse device index */ + int motion; /**< The direction and distance scrolled */ + SDL_WindowID windowID; /**< The window with mouse focus, if any */ +} SDL_MouseWheelEvent; + /** * \struct SDL_JoyAxisEvent * @@ -306,8 +323,10 @@ typedef union SDL_Event Uint8 type; /**< Event type, shared with all events */ SDL_WindowEvent window; /**< Window event data */ SDL_KeyboardEvent key; /**< Keyboard event data */ + SDL_TextInputEvent text; /**< Text input event data */ SDL_MouseMotionEvent motion; /**< Mouse motion event data */ SDL_MouseButtonEvent button; /**< Mouse button event data */ + SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ SDL_JoyBallEvent jball; /**< Joystick ball event data */ SDL_JoyHatEvent jhat; /**< Joystick hat event data */ @@ -353,6 +372,10 @@ extern DECLSPEC int SDLCALL SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action, Uint32 mask); +/* Checks to see if certain event types are in the event queue. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasEvent(Uint32 mask); + /* Polls for currently pending events, and returns 1 if there are any pending events, or 0 if there are none available. If 'event' is not NULL, the next event is removed from the queue and stored in that area. diff --git a/include/SDL_keyboard.h b/include/SDL_keyboard.h index f127e86f2..9652dfb4f 100644 --- a/include/SDL_keyboard.h +++ b/include/SDL_keyboard.h @@ -52,7 +52,7 @@ typedef struct SDL_keysym Uint8 padding[3]; /**< alignment padding */ Uint16 sym; /**< SDL virtual keysym */ Uint16 mod; /**< current key modifiers */ - Uint32 unicode; /**< OBSOLETE, use SDL_CharEvent instead */ + Uint32 unicode; /**< OBSOLETE, use SDL_TextInputEvent instead */ } SDL_keysym; /* Function prototypes */ diff --git a/include/SDL_mouse.h b/include/SDL_mouse.h index 2525e5d80..5c7728a82 100644 --- a/include/SDL_mouse.h +++ b/include/SDL_mouse.h @@ -202,15 +202,11 @@ extern DECLSPEC int SDLCALL SDL_ShowCursor(int toggle); Button 1: Left mouse button Button 2: Middle mouse button Button 3: Right mouse button - Button 4: Mouse wheel up (may also be a real button) - Button 5: Mouse wheel down (may also be a real button) */ #define SDL_BUTTON(X) (1 << ((X)-1)) #define SDL_BUTTON_LEFT 1 #define SDL_BUTTON_MIDDLE 2 #define SDL_BUTTON_RIGHT 3 -#define SDL_BUTTON_WHEELUP 4 -#define SDL_BUTTON_WHEELDOWN 5 #define SDL_BUTTON_LMASK SDL_BUTTON(SDL_BUTTON_LEFT) #define SDL_BUTTON_MMASK SDL_BUTTON(SDL_BUTTON_MIDDLE) #define SDL_BUTTON_RMASK SDL_BUTTON(SDL_BUTTON_RIGHT) diff --git a/include/SDL_video.h b/include/SDL_video.h index 5de849499..c279bd1d9 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -148,6 +148,7 @@ typedef enum SDL_WINDOWEVENT_NONE, /**< Never used */ SDL_WINDOWEVENT_SHOWN, /**< Window has been shown */ SDL_WINDOWEVENT_HIDDEN, /**< Window has been hidden */ + SDL_WINDOWEVENT_EXPOSED, /**< Window has been exposed and should be redrawn */ SDL_WINDOWEVENT_MOVED, /**< Window has been moved to data1,data2 */ SDL_WINDOWEVENT_RESIZED, /**< Window size changed to data1xdata2 */ SDL_WINDOWEVENT_MINIMIZED, /**< Window has been minimized */ @@ -157,6 +158,7 @@ typedef enum SDL_WINDOWEVENT_LEAVE, /**< The window has lost mouse focus */ SDL_WINDOWEVENT_FOCUS_GAINED, /**< The window has gained keyboard focus */ SDL_WINDOWEVENT_FOCUS_LOST, /**< The window has lost keyboard focus */ + SDL_WINDOWEVENT_CLOSE, /**< The window manager requests that the window be closed */ } SDL_WindowEventID; /** @@ -1419,6 +1421,13 @@ extern DECLSPEC int SDLCALL SDL_GL_GetAttribute(SDL_GLattr attr, int *value); */ extern DECLSPEC void SDLCALL SDL_GL_SwapBuffers(void); +/* + * Calculate the intersection of two rectangles + */ +extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRect(const SDL_Rect * A, + const SDL_Rect * B, + SDL_Rect * intersection); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ diff --git a/src/SDL_compat.c b/src/SDL_compat.c index 51936df8b..6ed5e61b2 100644 --- a/src/SDL_compat.c +++ b/src/SDL_compat.c @@ -164,6 +164,12 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event) switch (event->type) { case SDL_WINDOWEVENT: switch (event->window.event) { + case SDL_WINDOWEVENT_EXPOSED: + if (!SDL_HasEvent(SDL_VIDEOEXPOSEMASK)) { + fake.type = SDL_VIDEOEXPOSE; + SDL_PushEvent(&fake); + } + break; case SDL_WINDOWEVENT_RESIZED: fake.type = SDL_VIDEORESIZE; fake.resize.w = event->window.data1; @@ -206,6 +212,10 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event) fake.active.state = SDL_APPINPUTFOCUS; SDL_PushEvent(&fake); break; + case SDL_WINDOWEVENT_CLOSE: + fake.type = SDL_QUIT; + SDL_PushEvent(&fake); + break; } case SDL_KEYDOWN: case SDL_KEYUP: @@ -226,6 +236,38 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event) } break; } + case SDL_MOUSEWHEEL: + { + Uint8 button; + int selected; + int x, y; + + selected = SDL_SelectMouse(event->wheel.which); + SDL_GetMouseState(&x, &y); + SDL_SelectMouse(selected); + + if (event->wheel.motion > 0) { + button = SDL_BUTTON_WHEELUP; + } else { + button = SDL_BUTTON_WHEELDOWN; + } + + fake.button.which = event->wheel.windowID; + fake.button.button = button; + fake.button.x = x; + fake.button.y = y; + fake.button.windowID = event->wheel.windowID; + + fake.type = SDL_MOUSEBUTTONDOWN; + fake.button.state = SDL_PRESSED; + SDL_PushEvent(&fake); + + fake.type = SDL_MOUSEBUTTONUP; + fake.button.state = SDL_RELEASED; + SDL_PushEvent(&fake); + break; + } + } if (orig_eventfilter) { return orig_eventfilter(orig_eventfilterparam, event); @@ -304,7 +346,9 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) window_flags |= SDL_WINDOW_BORDERLESS; } SDL_VideoWindow = - SDL_CreateWindow(wm_title, 0, 0, width, height, window_flags); + SDL_CreateWindow(wm_title, SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, width, height, + window_flags); if (!SDL_VideoWindow) { return NULL; } diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 2093b6b59..c55df5eea 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -373,6 +373,12 @@ SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action, return (used); } +SDL_bool +SDL_HasEvent(Uint32 mask) +{ + return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, mask) > 0); +} + /* Run the system dependent event loops */ void SDL_PumpEvents(void) @@ -520,7 +526,7 @@ SDL_EventState(Uint8 type, int state) /* This is a generic event handler. */ int -SDL_PrivateSysWMEvent(SDL_SysWMmsg * message) +SDL_SendSysWMEvent(SDL_SysWMmsg * message) { int posted; diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h index bcf61e38b..9dc6c0976 100644 --- a/src/events/SDL_events_c.h +++ b/src/events/SDL_events_c.h @@ -25,6 +25,7 @@ #include "SDL_events.h" #include "SDL_mouse_c.h" #include "SDL_keyboard_c.h" +#include "SDL_windowevents_c.h" /* Start and stop the event processing loop */ extern int SDL_StartEventLoop(Uint32 flags); @@ -35,6 +36,8 @@ extern void SDL_Lock_EventThread(void); extern void SDL_Unlock_EventThread(void); extern Uint32 SDL_EventThreadID(void); +extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message); + extern int SDL_QuitInit(void); extern int SDL_SendQuit(void); extern void SDL_QuitQuit(void); diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index 3ef6d5683..533e7b5e1 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -338,18 +338,15 @@ void SDL_ResetKeyboard(int index) { SDL_Keyboard *keyboard = SDL_GetKeyboard(index); - SDL_keysym keysym; - Uint16 key; + SDLKey key; if (!keyboard) { return; } - SDL_memset(&keysym, 0, (sizeof keysym)); for (key = SDLK_FIRST; key < SDLK_LAST; ++key) { if (keyboard->keystate[key] == SDL_PRESSED) { - keysym.sym = key; - SDL_SendKeyboardKey(index, 0, SDL_RELEASED, &keysym); + SDL_SendKeyboardKey(index, SDL_RELEASED, 0, key); } } keyboard->repeat.timestamp = 0; @@ -463,9 +460,57 @@ SDL_GetKeyName(SDLKey key) return keyname; } +void +SDL_SetKeyboardFocus(int index, SDL_WindowID windowID) +{ + SDL_Keyboard *keyboard = SDL_GetKeyboard(index); + int i; + SDL_bool focus; + + if (!keyboard || (keyboard->focus == windowID)) { + return; + } + + /* See if the current window has lost focus */ + if (keyboard->focus) { + focus = SDL_FALSE; + for (i = 0; i < SDL_num_keyboards; ++i) { + SDL_Keyboard *check; + if (i != index) { + check = SDL_GetKeyboard(i); + if (check && check->focus == keyboard->focus) { + focus = SDL_TRUE; + break; + } + } + } + if (!focus) { + SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0); + } + } + + keyboard->focus = windowID; + + if (keyboard->focus) { + focus = SDL_FALSE; + for (i = 0; i < SDL_num_keyboards; ++i) { + SDL_Keyboard *check; + if (i != index) { + check = SDL_GetKeyboard(i); + if (check && check->focus == keyboard->focus) { + focus = SDL_TRUE; + break; + } + } + } + if (!focus) { + SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); + } + } +} + int -SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state, - SDL_keysym * keysym) +SDL_SendKeyboardKey(int index, Uint8 state, Uint8 scancode, SDLKey key) { SDL_Keyboard *keyboard = SDL_GetKeyboard(index); int posted, repeatable; @@ -475,106 +520,91 @@ SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state, if (!keyboard) { return 0; } - - if (windowID) { - keyboard->focus = windowID; - } #if 0 - printf("The '%s' key has been %s\n", SDL_GetKeyName(keysym->sym), + printf("The '%s' key has been %s\n", SDL_GetKeyName(key), state == SDL_PRESSED ? "pressed" : "released"); #endif - /* Set up the keysym */ - modstate = keyboard->modstate; - repeatable = 0; - if (state == SDL_PRESSED) { - keysym->mod = modstate; - switch (keysym->sym) { + modstate = keyboard->modstate; + switch (key) { case SDLK_UNKNOWN: break; case SDLK_NUMLOCK: - modstate ^= KMOD_NUM; - if (!(modstate & KMOD_NUM)) - state = SDL_RELEASED; - keysym->mod = modstate; + keyboard->modstate ^= KMOD_NUM; break; case SDLK_CAPSLOCK: - modstate ^= KMOD_CAPS; - if (!(modstate & KMOD_CAPS)) - state = SDL_RELEASED; - keysym->mod = modstate; + keyboard->modstate ^= KMOD_CAPS; break; case SDLK_LCTRL: - modstate |= KMOD_LCTRL; + keyboard->modstate |= KMOD_LCTRL; break; case SDLK_RCTRL: - modstate |= KMOD_RCTRL; + keyboard->modstate |= KMOD_RCTRL; break; case SDLK_LSHIFT: - modstate |= KMOD_LSHIFT; + keyboard->modstate |= KMOD_LSHIFT; break; case SDLK_RSHIFT: - modstate |= KMOD_RSHIFT; + keyboard->modstate |= KMOD_RSHIFT; break; case SDLK_LALT: - modstate |= KMOD_LALT; + keyboard->modstate |= KMOD_LALT; break; case SDLK_RALT: - modstate |= KMOD_RALT; + keyboard->modstate |= KMOD_RALT; break; case SDLK_LMETA: - modstate |= KMOD_LMETA; + keyboard->modstate |= KMOD_LMETA; break; case SDLK_RMETA: - modstate |= KMOD_RMETA; + keyboard->modstate |= KMOD_RMETA; break; case SDLK_MODE: - modstate |= KMOD_MODE; + keyboard->modstate |= KMOD_MODE; break; default: repeatable = 1; break; } } else { - switch (keysym->sym) { + switch (key) { case SDLK_UNKNOWN: break; case SDLK_NUMLOCK: case SDLK_CAPSLOCK: - /* Only send keydown events */ - return (0); + break; case SDLK_LCTRL: - modstate &= ~KMOD_LCTRL; + keyboard->modstate &= ~KMOD_LCTRL; break; case SDLK_RCTRL: - modstate &= ~KMOD_RCTRL; + keyboard->modstate &= ~KMOD_RCTRL; break; case SDLK_LSHIFT: - modstate &= ~KMOD_LSHIFT; + keyboard->modstate &= ~KMOD_LSHIFT; break; case SDLK_RSHIFT: - modstate &= ~KMOD_RSHIFT; + keyboard->modstate &= ~KMOD_RSHIFT; break; case SDLK_LALT: - modstate &= ~KMOD_LALT; + keyboard->modstate &= ~KMOD_LALT; break; case SDLK_RALT: - modstate &= ~KMOD_RALT; + keyboard->modstate &= ~KMOD_RALT; break; case SDLK_LMETA: - modstate &= ~KMOD_LMETA; + keyboard->modstate &= ~KMOD_LMETA; break; case SDLK_RMETA: - modstate &= ~KMOD_RMETA; + keyboard->modstate &= ~KMOD_RMETA; break; case SDLK_MODE: - modstate &= ~KMOD_MODE; + keyboard->modstate &= ~KMOD_MODE; break; default: break; } - keysym->mod = modstate; + modstate = keyboard->modstate; } /* Figure out what type of event this is */ @@ -588,7 +618,7 @@ SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state, * jk 991215 - Added */ if (keyboard->repeat.timestamp && - keyboard->repeat.evt.key.keysym.sym == keysym->sym) { + keyboard->repeat.evt.key.keysym.sym == key) { keyboard->repeat.timestamp = 0; } break; @@ -597,9 +627,9 @@ SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state, return 0; } - if (keysym->sym != SDLK_UNKNOWN) { + if (key != SDLK_UNKNOWN) { /* Drop events that don't change state */ - if (keyboard->keystate[keysym->sym] == state) { + if (keyboard->keystate[key] == state) { #if 0 printf("Keyboard event didn't change state - dropped!\n"); #endif @@ -607,8 +637,7 @@ SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state, } /* Update internal keyboard state */ - keyboard->modstate = modstate; - keyboard->keystate[keysym->sym] = state; + keyboard->keystate[key] = state; } /* Post the event, if desired */ @@ -618,7 +647,10 @@ SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state, event.key.type = type; event.key.which = (Uint8) index; event.key.state = state; - event.key.keysym = *keysym; + event.key.keysym.scancode = scancode; + event.key.keysym.sym = (Uint16) key; + event.key.keysym.mod = modstate; + event.key.keysym.unicode = 0; event.key.windowID = keyboard->focus; /* * jk 991215 - Added @@ -640,6 +672,32 @@ SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state, return (posted); } +int +SDL_SendKeyboardText(int index, const char *text) +{ + SDL_Keyboard *keyboard = SDL_GetKeyboard(index); + int posted; + + if (!keyboard) { + return 0; + } + + /* Post the event, if desired */ + posted = 0; + if (SDL_ProcessEvents[SDL_TEXTINPUT] == SDL_ENABLE) { + SDL_Event event; + event.text.type = SDL_TEXTINPUT; + event.text.which = (Uint8) index; + SDL_strlcpy(event.text.text, text, SDL_arraysize(event.text.text)); + event.key.windowID = keyboard->focus; + if ((SDL_EventOK == NULL) || SDL_EventOK(SDL_EventOKParam, &event)) { + posted = 1; + SDL_PushEvent(&event); + } + } + return (posted); +} + /* * jk 991215 - Added */ diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h index d0baa4403..0d0b58627 100644 --- a/src/events/SDL_keyboard_c.h +++ b/src/events/SDL_keyboard_c.h @@ -75,9 +75,15 @@ extern void SDL_DelKeyboard(int index); /* Clear the state of a keyboard at an index */ extern void SDL_ResetKeyboard(int index); +/* Set the keyboard focus window */ +extern void SDL_SetKeyboardFocus(int index, SDL_WindowID windowID); + /* Send a keyboard event for a keyboard at an index */ -extern int SDL_SendKeyboardKey(int index, SDL_WindowID windowID, Uint8 state, - SDL_keysym * keysym); +extern int SDL_SendKeyboardKey(int index, Uint8 state, Uint8 scancode, + SDLKey key); + +/* Send keyboard text input for a keyboard at an index */ +extern int SDL_SendKeyboardText(int index, const char *text); /* Used by the event loop to queue pending keyboard repeat events */ extern void SDL_CheckKeyRepeat(void); diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index c75c81363..87a323baa 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -265,9 +265,57 @@ SDL_GetRelativeMouseState(int *x, int *y) return mouse->buttonstate; } +void +SDL_SetMouseFocus(int index, SDL_WindowID windowID) +{ + SDL_Mouse *mouse = SDL_GetMouse(index); + int i; + SDL_bool focus; + + if (!mouse || (mouse->focus == windowID)) { + return; + } + + /* See if the current window has lost focus */ + if (mouse->focus) { + focus = SDL_FALSE; + for (i = 0; i < SDL_num_mice; ++i) { + SDL_Mouse *check; + if (i != index) { + check = SDL_GetMouse(i); + if (check && check->focus == mouse->focus) { + focus = SDL_TRUE; + break; + } + } + } + if (!focus) { + SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_LEAVE, 0, 0); + } + } + + mouse->focus = windowID; + + if (mouse->focus) { + focus = SDL_FALSE; + for (i = 0; i < SDL_num_mice; ++i) { + SDL_Mouse *check; + if (i != index) { + check = SDL_GetMouse(i); + if (check && check->focus == mouse->focus) { + focus = SDL_TRUE; + break; + } + } + } + if (!focus) { + SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_ENTER, 0, 0); + } + } +} + int -SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative, int x, - int y) +SDL_SendMouseMotion(int index, int relative, int x, int y) { SDL_Mouse *mouse = SDL_GetMouse(index); int posted; @@ -278,10 +326,6 @@ SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative, int x, return 0; } - if (windowID) { - mouse->focus = windowID; - } - if (relative) { /* Push the cursor around */ xrel = x; @@ -337,8 +381,7 @@ SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative, int x, } int -SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state, - Uint8 button) +SDL_SendMouseButton(int index, Uint8 state, Uint8 button) { SDL_Mouse *mouse = SDL_GetMouse(index); int posted; @@ -348,10 +391,6 @@ SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state, return 0; } - if (windowID) { - mouse->focus = windowID; - } - /* Figure out which event to perform */ switch (state) { case SDL_PRESSED: @@ -395,6 +434,33 @@ SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state, return posted; } +int +SDL_SendMouseWheel(int index, int motion) +{ + SDL_Mouse *mouse = SDL_GetMouse(index); + int posted; + + if (!mouse || !motion) { + return 0; + } + + /* Post the event, if desired */ + posted = 0; + if (SDL_ProcessEvents[SDL_MOUSEWHEEL] == SDL_ENABLE) { + SDL_Event event; + event.type = SDL_MOUSEWHEEL; + event.wheel.which = (Uint8) index; + event.wheel.motion = motion; + event.wheel.windowID = mouse->focus; + if ((SDL_EventOK == NULL) + || (*SDL_EventOK) (SDL_EventOKParam, &event)) { + posted = 1; + SDL_PushEvent(&event); + } + } + return posted; +} + void SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y) { @@ -407,7 +473,8 @@ SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y) if (mouse->WarpMouse) { mouse->WarpMouse(mouse, windowID, x, y); } else { - SDL_SendMouseMotion(SDL_current_mouse, windowID, 0, x, y); + SDL_SetMouseFocus(SDL_current_mouse, windowID); + SDL_SendMouseMotion(SDL_current_mouse, 0, x, y); } } diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index f0b5ca927..4bc60835f 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -92,13 +92,17 @@ extern void SDL_DelMouse(int index); /* Clear the button state of a mouse at an index */ extern void SDL_ResetMouse(int index); +/* Set the mouse focus window */ +extern void SDL_SetMouseFocus(int index, SDL_WindowID windowID); + /* Send a mouse motion event for a mouse at an index */ -extern int SDL_SendMouseMotion(int index, SDL_WindowID windowID, int relative, - int x, int y); +extern int SDL_SendMouseMotion(int index, int relative, int x, int y); /* Send a mouse button event for a mouse at an index */ -extern int SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state, - Uint8 button); +extern int SDL_SendMouseButton(int index, Uint8 state, Uint8 button); + +/* Send a mouse wheel event for a mouse at an index */ +extern int SDL_SendMouseWheel(int index, int motion); /* Shutdown the mouse subsystem */ extern void SDL_MouseQuit(void); diff --git a/src/events/SDL_windowevents.c b/src/events/SDL_windowevents.c index f4153388c..35f12a33a 100644 --- a/src/events/SDL_windowevents.c +++ b/src/events/SDL_windowevents.c @@ -28,8 +28,8 @@ #include "../video/SDL_sysvideo.h" int -SDL_PrivateWindowEvent(SDL_WindowID windowID, Uint8 windowevent, int data1, - int data2) +SDL_SendWindowEvent(SDL_WindowID windowID, Uint8 windowevent, int data1, + int data2) { int posted; SDL_Window *window; @@ -51,6 +51,16 @@ SDL_PrivateWindowEvent(SDL_WindowID windowID, Uint8 windowevent, int data1, } window->flags &= ~SDL_WINDOW_SHOWN; break; + case SDL_WINDOWEVENT_MOVED: + if (data1 == window->x && data2 == window->y) { + return 0; + } + break; + case SDL_WINDOWEVENT_RESIZED: + if (data1 == window->w && data2 == window->h) { + return 0; + } + break; case SDL_WINDOWEVENT_MINIMIZED: if (window->flags & SDL_WINDOW_MINIMIZED) { return 0; diff --git a/src/events/SDL_windowevents_c.h b/src/events/SDL_windowevents_c.h index dfd2ed8a7..39aef943f 100644 --- a/src/events/SDL_windowevents_c.h +++ b/src/events/SDL_windowevents_c.h @@ -27,8 +27,6 @@ extern int SDL_SendWindowEvent(SDL_WindowID windowID, Uint8 windowevent, int data1, int data2); -extern int SDL_SendSysWMEvent(SDL_SysWMmsg * message); - #endif /* _SDL_windowevents_c_h */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/SDL_surface.c b/src/video/SDL_surface.c index 2fe1622f0..e3c41eebc 100644 --- a/src/video/SDL_surface.c +++ b/src/video/SDL_surface.c @@ -418,7 +418,7 @@ SDL_SetAlphaChannel(SDL_Surface * surface, Uint8 value) * A function to calculate the intersection of two rectangles: * return true if the rectangles intersect, false otherwise */ -static __inline__ SDL_bool +SDL_bool SDL_IntersectRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * intersection) { diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 10a9a9289..ee405a300 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -188,6 +188,11 @@ SDL_VideoInit(const char *driver_name, Uint32 flags) } #endif + /* Start the event loop */ + if (SDL_StartEventLoop(flags) < 0) { + return -1; + } + /* Check to make sure we don't overwrite '_this' */ if (_this != NULL) { SDL_VideoQuit(); @@ -277,12 +282,6 @@ SDL_VideoInit(const char *driver_name, Uint32 flags) } } - /* Start the event loop */ - if (SDL_StartEventLoop(flags) < 0) { - SDL_VideoQuit(); - return -1; - } - /* We're ready to go! */ return 0; } @@ -1286,10 +1285,22 @@ SDL_CreateTextureFromSurface(Uint32 format, int access, SDL_Surface * surface) } /* Copy the palette if any */ - if (fmt->palette) { - SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, - fmt->palette->ncolors); - SDL_SetSurfacePalette(&dst, fmt->palette); + if (SDL_ISPIXELFORMAT_INDEXED(format)) { + if (fmt->palette) { + SDL_SetTexturePalette(textureID, fmt->palette->colors, 0, + fmt->palette->ncolors); + SDL_SetSurfacePalette(&dst, fmt->palette); + } else { + dst.format->palette = + SDL_AllocPalette((1 << SDL_BITSPERPIXEL(format))); + if (!dst.format->palette) { + SDL_DestroyTexture(textureID); + SDL_FreeFormat(dst.format); + return 0; + } + SDL_DitherColors(dst.format->palette->colors, + SDL_BITSPERPIXEL(format)); + } } /* Make the texture transparent if the surface has colorkey */ @@ -1557,7 +1568,8 @@ int SDL_RenderFill(const SDL_Rect * rect, Uint32 color) { SDL_Renderer *renderer; - SDL_Rect full_rect; + SDL_Window *window; + SDL_Rect real_rect; if (!_this) { return -1; @@ -1568,14 +1580,17 @@ SDL_RenderFill(const SDL_Rect * rect, Uint32 color) return -1; } - if (!rect) { - SDL_Window *window = SDL_GetWindowFromID(renderer->window); - full_rect.x = 0; - full_rect.y = 0; - full_rect.w = window->w; - full_rect.h = window->h; - rect = &full_rect; + window = SDL_GetWindowFromID(renderer->window); + real_rect.x = 0; + real_rect.y = 0; + real_rect.w = window->w; + real_rect.h = window->h; + if (rect) { + if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) { + return 0; + } } + rect = &real_rect; return renderer->RenderFill(renderer, rect, color); } @@ -1586,8 +1601,9 @@ SDL_RenderCopy(SDL_TextureID textureID, const SDL_Rect * srcrect, { SDL_Texture *texture = SDL_GetTextureFromID(textureID); SDL_Renderer *renderer; - SDL_Rect full_srcrect; - SDL_Rect full_dstrect; + SDL_Window *window; + SDL_Rect real_srcrect; + SDL_Rect real_dstrect; if (!texture || texture->renderer != SDL_CurrentDisplay.current_renderer) { return -1; @@ -1598,20 +1614,21 @@ SDL_RenderCopy(SDL_TextureID textureID, const SDL_Rect * srcrect, return -1; } + /* FIXME: implement clipping */ + window = SDL_GetWindowFromID(renderer->window); + real_srcrect.x = 0; + real_srcrect.y = 0; + real_srcrect.w = texture->w; + real_srcrect.h = texture->h; + real_dstrect.x = 0; + real_dstrect.y = 0; + real_dstrect.w = window->w; + real_dstrect.h = window->h; if (!srcrect) { - full_srcrect.x = 0; - full_srcrect.y = 0; - full_srcrect.w = texture->w; - full_srcrect.h = texture->h; - srcrect = &full_srcrect; + srcrect = &real_srcrect; } if (!dstrect) { - SDL_Window *window = SDL_GetWindowFromID(renderer->window); - full_dstrect.x = 0; - full_dstrect.y = 0; - full_dstrect.w = window->w; - full_dstrect.h = window->h; - dstrect = &full_dstrect; + dstrect = &real_dstrect; } return renderer->RenderCopy(renderer, texture, srcrect, dstrect, diff --git a/src/video/win32/SDL_dibrender.c b/src/video/win32/SDL_dibrender.c new file mode 100644 index 000000000..01bdb9068 --- /dev/null +++ b/src/video/win32/SDL_dibrender.c @@ -0,0 +1,711 @@ +/* + 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_yuv_sw_c.h" + +/* GDI renderer implementation */ + +static SDL_Renderer *SDL_DIB_CreateRenderer(SDL_Window * window, + Uint32 flags); +static int SDL_DIB_CreateTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static int SDL_DIB_QueryTexturePixels(SDL_Renderer * renderer, + SDL_Texture * texture, void **pixels, + int *pitch); +static int SDL_DIB_SetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, + int ncolors); +static int SDL_DIB_GetTexturePalette(SDL_Renderer * renderer, + SDL_Texture * texture, + SDL_Color * colors, int firstcolor, + int ncolors); +static int SDL_DIB_UpdateTexture(SDL_Renderer * renderer, + SDL_Texture * texture, const SDL_Rect * rect, + const void *pixels, int pitch); +static int SDL_DIB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, + void **pixels, int *pitch); +static void SDL_DIB_UnlockTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static void SDL_DIB_DirtyTexture(SDL_Renderer * renderer, + SDL_Texture * texture, int numrects, + const SDL_Rect * rects); +static void SDL_DIB_SelectRenderTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static int SDL_DIB_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 color); +static int SDL_DIB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, + const SDL_Rect * dstrect, int blendMode, + int scaleMode); +static int SDL_DIB_RenderReadPixels(SDL_Renderer * renderer, + const SDL_Rect * rect, void *pixels, + int pitch); +static int SDL_DIB_RenderWritePixels(SDL_Renderer * renderer, + const SDL_Rect * rect, + const void *pixels, int pitch); +static void SDL_DIB_RenderPresent(SDL_Renderer * renderer); +static void SDL_DIB_DestroyTexture(SDL_Renderer * renderer, + SDL_Texture * texture); +static void SDL_DIB_DestroyRenderer(SDL_Renderer * renderer); + + +SDL_RenderDriver SDL_DIB_RenderDriver = { + SDL_DIB_CreateRenderer, + { + "gdi", + (SDL_Renderer_PresentDiscard | + SDL_Renderer_PresentCopy | SDL_Renderer_RenderTarget), + (SDL_TextureBlendMode_None | + SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend), + (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), + 11, + { + SDL_PixelFormat_Index8, + SDL_PixelFormat_RGB555, + SDL_PixelFormat_RGB565, + SDL_PixelFormat_RGB888, + SDL_PixelFormat_BGR888, + SDL_PixelFormat_ARGB8888, + SDL_PixelFormat_RGBA8888, + SDL_PixelFormat_ABGR8888, + SDL_PixelFormat_BGRA8888, + SDL_PixelFormat_YUY2, + SDL_PixelFormat_UYVY}, + 0, + 0} +}; + +typedef struct +{ + HWND hwnd; + HDC window_hdc; + HDC render_hdc; + HDC memory_hdc; + HDC current_hdc; + LPBITMAPINFO bmi; + HBITMAP window_bmp; + void *window_pixels; + int window_pitch; +} SDL_DIB_RenderData; + +typedef struct +{ + SDL_SW_YUVTexture *yuv; + Uint32 format; + HPALETTE hpal; + HBITMAP hbm; + void *pixels; + int pitch; +} SDL_DIB_TextureData; + +static void +UpdateYUVTextureData(SDL_Texture * texture) +{ + SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata; + SDL_Rect rect; + + rect.x = 0; + rect.y = 0; + rect.w = texture->w; + rect.h = texture->h; + SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w, + texture->h, data->pixels, data->pitch); +} + +SDL_Renderer * +SDL_DIB_CreateRenderer(SDL_Window * window, Uint32 flags) +{ + SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; + SDL_Renderer *renderer; + SDL_DIB_RenderData *data; + int bmi_size; + HBITMAP hbm; + + renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer)); + if (!renderer) { + SDL_OutOfMemory(); + return NULL; + } + SDL_zerop(renderer); + + data = (SDL_DIB_RenderData *) SDL_malloc(sizeof(*data)); + if (!data) { + SDL_DIB_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + SDL_zerop(data); + + data->hwnd = windowdata->hwnd; + data->window_hdc = GetDC(data->hwnd); + data->render_hdc = CreateCompatibleDC(data->window_hdc); + data->memory_hdc = CreateCompatibleDC(data->window_hdc); + data->current_hdc = data->window_hdc; + + /* Fill in the compatible bitmap info */ + bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); + data->bmi = (LPBITMAPINFO) SDL_malloc(bmi_size); + if (!data->bmi) { + SDL_DIB_DestroyRenderer(renderer); + SDL_OutOfMemory(); + return NULL; + } + SDL_memset(data->bmi, 0, bmi_size); + data->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + + hbm = CreateCompatibleBitmap(data->window_hdc, 1, 1); + GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS); + GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS); + DeleteObject(hbm); + + renderer->CreateTexture = SDL_DIB_CreateTexture; + renderer->QueryTexturePixels = SDL_DIB_QueryTexturePixels; + renderer->SetTexturePalette = SDL_DIB_SetTexturePalette; + renderer->GetTexturePalette = SDL_DIB_GetTexturePalette; + renderer->UpdateTexture = SDL_DIB_UpdateTexture; + renderer->LockTexture = SDL_DIB_LockTexture; + renderer->UnlockTexture = SDL_DIB_UnlockTexture; + renderer->DirtyTexture = SDL_DIB_DirtyTexture; + renderer->SelectRenderTexture = SDL_DIB_SelectRenderTexture; + renderer->RenderFill = SDL_DIB_RenderFill; + renderer->RenderCopy = SDL_DIB_RenderCopy; + renderer->RenderReadPixels = SDL_DIB_RenderReadPixels; + renderer->RenderWritePixels = SDL_DIB_RenderWritePixels; + renderer->RenderPresent = SDL_DIB_RenderPresent; + renderer->DestroyTexture = SDL_DIB_DestroyTexture; + renderer->DestroyRenderer = SDL_DIB_DestroyRenderer; + renderer->info = SDL_DIB_RenderDriver.info; + renderer->window = window->id; + renderer->driverdata = data; + + renderer->info.flags = SDL_Renderer_RenderTarget; + + return renderer; +} + +static int +SDL_DIB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + SDL_DIB_RenderData *renderdata = + (SDL_DIB_RenderData *) renderer->driverdata; + SDL_Window *window = SDL_GetWindowFromID(renderer->window); + SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); + SDL_DIB_TextureData *data; + + data = (SDL_DIB_TextureData *) SDL_malloc(sizeof(*data)); + if (!data) { + SDL_OutOfMemory(); + return -1; + } + SDL_zerop(data); + + texture->driverdata = data; + + if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { + if (texture->access == SDL_TextureAccess_Render) { + SDL_SetError("Rendering to YUV format textures is not supported"); + return -1; + } + data->yuv = SDL_SW_CreateYUVTexture(texture); + if (!data->yuv) { + SDL_DIB_DestroyTexture(renderer, texture); + return -1; + } + data->format = display->current_mode.format; + } else { + data->format = texture->format; + } + data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format)); + + if (data->yuv || texture->access == SDL_TextureAccess_Local + || texture->format != SDL_GetCurrentDisplayMode()->format) { + int bmi_size; + LPBITMAPINFO bmi; + + bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); + bmi = (LPBITMAPINFO) SDL_malloc(bmi_size); + if (!bmi) { + SDL_DIB_DestroyTexture(renderer, texture); + SDL_OutOfMemory(); + return -1; + } + SDL_memset(bmi, 0, bmi_size); + bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi->bmiHeader.biWidth = texture->w; + bmi->bmiHeader.biHeight = -texture->h; /* topdown bitmap */ + bmi->bmiHeader.biPlanes = 1; + bmi->bmiHeader.biSizeImage = texture->h * data->pitch; + bmi->bmiHeader.biXPelsPerMeter = 0; + bmi->bmiHeader.biYPelsPerMeter = 0; + bmi->bmiHeader.biClrUsed = 0; + bmi->bmiHeader.biClrImportant = 0; + bmi->bmiHeader.biBitCount = SDL_BYTESPERPIXEL(data->format) * 8; + if (SDL_ISPIXELFORMAT_INDEXED(data->format)) { + int i, ncolors; + LOGPALETTE *palette; + + bmi->bmiHeader.biCompression = BI_RGB; + ncolors = (1 << SDL_BITSPERPIXEL(data->format)); + palette = + (LOGPALETTE *) SDL_malloc(sizeof(*palette) + + ncolors * sizeof(PALETTEENTRY)); + if (!palette) { + SDL_free(bmi); + SDL_DIB_DestroyTexture(renderer, texture); + SDL_OutOfMemory(); + return -1; + } + palette->palVersion = 0x300; + palette->palNumEntries = ncolors; + for (i = 0; i < ncolors; ++i) { + palette->palPalEntry[i].peRed = 0xFF; + palette->palPalEntry[i].peGreen = 0xFF; + palette->palPalEntry[i].peBlue = 0xFF; + palette->palPalEntry[i].peFlags = 0; + } + data->hpal = CreatePalette(palette); + SDL_free(palette); + } else { + int bpp; + Uint32 Rmask, Gmask, Bmask, Amask; + + bmi->bmiHeader.biCompression = BI_BITFIELDS; + SDL_PixelFormatEnumToMasks(data->format, &bpp, &Rmask, &Gmask, + &Bmask, &Amask); + ((Uint32 *) bmi->bmiColors)[0] = Rmask; + ((Uint32 *) bmi->bmiColors)[1] = Gmask; + ((Uint32 *) bmi->bmiColors)[2] = Bmask; + data->hpal = NULL; + } + data->hbm = + CreateDIBSection(renderdata->memory_hdc, bmi, DIB_RGB_COLORS, + &data->pixels, NULL, 0); + } else { + data->hbm = + CreateCompatibleBitmap(renderdata->window_hdc, texture->w, + texture->h); + data->pixels = NULL; + } + if (!data->hbm) { + SDL_DIB_DestroyTexture(renderer, texture); + WIN_SetError("Couldn't create bitmap"); + return -1; + } + return 0; +} + +static int +SDL_DIB_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, + void **pixels, int *pitch) +{ + SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata; + + if (data->yuv) { + return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch); + } else { + *pixels = data->pixels; + *pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); + return 0; + } +} + +static int +SDL_DIB_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Color * colors, int firstcolor, + int ncolors) +{ + SDL_DIB_RenderData *renderdata = + (SDL_DIB_RenderData *) renderer->driverdata; + SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata; + + if (data->yuv) { + SDL_SetError("YUV textures don't have a palette"); + return -1; + } else { + PALETTEENTRY entries[256]; + int i; + + for (i = 0; i < ncolors; ++i) { + entries[i].peRed = colors[i].r; + entries[i].peGreen = colors[i].g; + entries[i].peBlue = colors[i].b; + entries[i].peFlags = 0; + } + if (!SetPaletteEntries(data->hpal, firstcolor, ncolors, entries)) { + WIN_SetError("SetPaletteEntries()"); + return -1; + } + return 0; + } +} + +static int +SDL_DIB_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, + SDL_Color * colors, int firstcolor, int ncolors) +{ + SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata; + + if (data->yuv) { + SDL_SetError("YUV textures don't have a palette"); + return -1; + } else { + PALETTEENTRY entries[256]; + int i; + + if (!GetPaletteEntries(data->hpal, firstcolor, ncolors, entries)) { + WIN_SetError("GetPaletteEntries()"); + return -1; + } + for (i = 0; i < ncolors; ++i) { + colors[i].r = entries[i].peRed; + colors[i].g = entries[i].peGreen; + colors[i].b = entries[i].peBlue; + } + return 0; + } +} + +static int +SDL_DIB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, const void *pixels, int pitch) +{ + SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata; + + if (data->yuv) { + if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) { + return -1; + } + UpdateYUVTextureData(texture); + return 0; + } else { + SDL_DIB_RenderData *renderdata = + (SDL_DIB_RenderData *) renderer->driverdata; + + if (data->pixels) { + Uint8 *src, *dst; + int row; + size_t length; + + src = (Uint8 *) pixels; + dst = + (Uint8 *) data->pixels + rect->y * data->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format); + length = rect->w * SDL_BYTESPERPIXEL(texture->format); + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, length); + src += pitch; + dst += data->pitch; + } + } else if (rect->w == texture->w && pitch == data->pitch) { + if (!SetDIBits + (renderdata->window_hdc, data->hbm, rect->y, rect->h, pixels, + renderdata->bmi, DIB_RGB_COLORS)) { + WIN_SetError("SetDIBits()"); + return -1; + } + } else { + SDL_SetError + ("FIXME: Need to allocate temporary memory and do GetDIBits() followed by SetDIBits(), since we can only set blocks of scanlines at a time"); + return -1; + } + return 0; + } +} + +static int +SDL_DIB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * rect, int markDirty, void **pixels, + int *pitch) +{ + SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata; + + if (data->yuv) { + return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, + pitch); + } else { + GdiFlush(); + *pixels = + (void *) ((Uint8 *) data->pixels + rect->y * data->pitch + + rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = data->pitch; + return 0; + } +} + +static void +SDL_DIB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata; + + if (data->yuv) { + SDL_SW_UnlockYUVTexture(data->yuv); + UpdateYUVTextureData(texture); + } +} + +static void +SDL_DIB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, + int numrects, const SDL_Rect * rects) +{ +} + +static void +SDL_DIB_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata; + + if (texture) { + SDL_DIB_TextureData *texturedata = + (SDL_DIB_TextureData *) texture->driverdata; + SelectObject(data->render_hdc, texturedata->hbm); + if (texturedata->hpal) { + SelectPalette(data->render_hdc, texturedata->hpal, TRUE); + RealizePalette(data->render_hdc); + } + data->current_hdc = data->render_hdc; + } else { + data->current_hdc = data->current_hdc; + } +} + +static int +SDL_DIB_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, + Uint32 color) +{ + SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata; + Uint8 r, g, b; + RECT rc; + static HBRUSH brush; + int status; + + r = (Uint8) ((color >> 16) & 0xFF); + g = (Uint8) ((color >> 8) & 0xFF); + b = (Uint8) (color & 0xFF); + + rc.left = rect->x; + rc.top = rect->y; + rc.right = rect->x + rect->w + 1; + rc.bottom = rect->y + rect->h + 1; + + /* Should we cache the brushes? .. it looks like GDI does for us. :) */ + brush = CreateSolidBrush(RGB(r, g, b)); + SelectObject(data->current_hdc, brush); + status = FillRect(data->current_hdc, &rc, brush); + DeleteObject(brush); + + if (!status) { + WIN_SetError("FillRect()"); + return -1; + } + return 0; +} + +static int +SDL_DIB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, + const SDL_Rect * srcrect, const SDL_Rect * dstrect, + int blendMode, int scaleMode) +{ + SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata; + SDL_DIB_TextureData *texturedata = + (SDL_DIB_TextureData *) texture->driverdata; + + SelectObject(data->memory_hdc, texturedata->hbm); + if (texturedata->hpal) { + SelectPalette(data->memory_hdc, texturedata->hpal, TRUE); + RealizePalette(data->memory_hdc); + } + if (blendMode & (SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend)) { + static BLENDFUNCTION blendFunc = { + AC_SRC_OVER, + 0, + 255, + AC_SRC_ALPHA + }; + /* FIXME: GDI uses premultiplied alpha! */ + if (!AlphaBlend + (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, + dstrect->h, data->memory_hdc, srcrect->x, srcrect->y, srcrect->w, + srcrect->h, blendFunc)) { + WIN_SetError("AlphaBlend()"); + return -1; + } + } else { + if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) { + if (!BitBlt + (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, + srcrect->h, data->memory_hdc, srcrect->x, srcrect->y, + SRCCOPY)) { + WIN_SetError("BitBlt()"); + return -1; + } + } else { + if (!StretchBlt + (data->current_hdc, dstrect->x, dstrect->y, dstrect->w, + srcrect->h, data->memory_hdc, srcrect->x, srcrect->y, + srcrect->w, srcrect->h, SRCCOPY)) { + WIN_SetError("StretchBlt()"); + return -1; + } + } + } + return 0; +} + +static int +CreateWindowDIB(SDL_DIB_RenderData * data, SDL_Window * window) +{ + data->window_pitch = window->w * (data->bmi->bmiHeader.biBitCount / 8); + data->bmi->bmiHeader.biWidth = window->w; + data->bmi->bmiHeader.biHeight = -window->h; + data->bmi->bmiHeader.biSizeImage = + window->h * (data->bmi->bmiHeader.biBitCount / 8); + data->window_bmp = + CreateDIBSection(data->window_hdc, data->bmi, DIB_RGB_COLORS, + &data->window_pixels, NULL, 0); + if (!data->window_bmp) { + WIN_SetError("CreateDIBSection()"); + return -1; + } + return 0; +} + +static int +SDL_DIB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect, + void *pixels, int pitch) +{ + SDL_Window *window = SDL_GetWindowFromID(renderer->window); + SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata; + + if (!data->window_bmp) { + if (CreateWindowDIB(data, window) < 0) { + return -1; + } + } + + SelectObject(data->memory_hdc, data->window_bmp); + BitBlt(data->memory_hdc, rect->x, rect->y, rect->w, rect->h, + data->window_hdc, rect->x, rect->y, SRCCOPY); + + { + int bpp = data->bmi->bmiHeader.biBitCount / 8; + Uint8 *src = + (Uint8 *) data->window_pixels + rect->y * data->window_pitch + + rect->x * bpp; + Uint8 *dst = (Uint8 *) pixels; + int row; + + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, rect->w * bpp); + src += data->window_pitch; + dst += pitch; + } + } + + return 0; +} + +static int +SDL_DIB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, + const void *pixels, int pitch) +{ + SDL_Window *window = SDL_GetWindowFromID(renderer->window); + SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata; + + if (!data->window_bmp) { + if (CreateWindowDIB(data, window) < 0) { + return -1; + } + } + + { + int bpp = data->bmi->bmiHeader.biBitCount / 8; + Uint8 *src = (Uint8 *) pixels; + Uint8 *dst = + (Uint8 *) data->window_pixels + rect->y * data->window_pitch + + rect->x * bpp; + int row; + + for (row = 0; row < rect->h; ++row) { + SDL_memcpy(dst, src, rect->w * bpp); + src += pitch; + dst += data->window_pitch; + } + } + + SelectObject(data->memory_hdc, data->window_bmp); + BitBlt(data->window_hdc, rect->x, rect->y, rect->w, rect->h, + data->memory_hdc, rect->x, rect->y, SRCCOPY); + + return 0; +} + +static void +SDL_DIB_RenderPresent(SDL_Renderer * renderer) +{ +} + +static void +SDL_DIB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) +{ + SDL_DIB_TextureData *data = (SDL_DIB_TextureData *) texture->driverdata; + + if (!data) { + return; + } + if (data->yuv) { + SDL_SW_DestroyYUVTexture(data->yuv); + } + if (data->hpal) { + DeleteObject(data->hpal); + } + if (data->hbm) { + DeleteObject(data->hbm); + } + SDL_free(data); + texture->driverdata = NULL; +} + +void +SDL_DIB_DestroyRenderer(SDL_Renderer * renderer) +{ + SDL_DIB_RenderData *data = (SDL_DIB_RenderData *) renderer->driverdata; + + if (data) { + ReleaseDC(data->hwnd, data->window_hdc); + DeleteDC(data->render_hdc); + DeleteDC(data->memory_hdc); + if (data->bmi) { + SDL_free(data->bmi); + } + if (data->window_bmp) { + DeleteObject(data->window_bmp); + } + SDL_free(data); + } + SDL_free(renderer); +} + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_dibrender.h b/src/video/win32/SDL_dibrender.h new file mode 100644 index 000000000..7d7e5c4de --- /dev/null +++ b/src/video/win32/SDL_dibrender.h @@ -0,0 +1,28 @@ +/* + 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" + +/* SDL surface based renderer implementation */ + +extern SDL_RenderDriver SDL_DIB_RenderDriver; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_vkeys.h b/src/video/win32/SDL_vkeys.h new file mode 100644 index 000000000..0ada01138 --- /dev/null +++ b/src/video/win32/SDL_vkeys.h @@ -0,0 +1,76 @@ +/* + 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 +*/ + +#ifndef VK_0 +#define VK_0 '0' +#define VK_1 '1' +#define VK_2 '2' +#define VK_3 '3' +#define VK_4 '4' +#define VK_5 '5' +#define VK_6 '6' +#define VK_7 '7' +#define VK_8 '8' +#define VK_9 '9' +#define VK_A 'A' +#define VK_B 'B' +#define VK_C 'C' +#define VK_D 'D' +#define VK_E 'E' +#define VK_F 'F' +#define VK_G 'G' +#define VK_H 'H' +#define VK_I 'I' +#define VK_J 'J' +#define VK_K 'K' +#define VK_L 'L' +#define VK_M 'M' +#define VK_N 'N' +#define VK_O 'O' +#define VK_P 'P' +#define VK_Q 'Q' +#define VK_R 'R' +#define VK_S 'S' +#define VK_T 'T' +#define VK_U 'U' +#define VK_V 'V' +#define VK_W 'W' +#define VK_X 'X' +#define VK_Y 'Y' +#define VK_Z 'Z' +#endif /* VK_0 */ + +/* These keys haven't been defined, but were experimentally determined */ +#define VK_SEMICOLON 0xBA +#define VK_EQUALS 0xBB +#define VK_COMMA 0xBC +#define VK_MINUS 0xBD +#define VK_PERIOD 0xBE +#define VK_SLASH 0xBF +#define VK_GRAVE 0xC0 +#define VK_LBRACKET 0xDB +#define VK_BACKSLASH 0xDC +#define VK_RBRACKET 0xDD +#define VK_APOSTROPHE 0xDE +#define VK_BACKTICK 0xDF +#define VK_OEM_102 0xE2 +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32events.c b/src/video/win32/SDL_win32events.c index af0c65e2f..3a928c4ac 100644 --- a/src/video/win32/SDL_win32events.c +++ b/src/video/win32/SDL_win32events.c @@ -22,8 +22,370 @@ #include "SDL_config.h" #include "SDL_win32video.h" +#include "SDL_version.h" +#include "SDL_syswm.h" +#include "SDL_vkeys.h" #include "../../events/SDL_events_c.h" +/*#define WMMSG_DEBUG*/ +#ifdef WMMSG_DEBUG +#include "wmmsg.h" +#endif + +/* Masks for processing the windows KEYDOWN and KEYUP messages */ +#define REPEATED_KEYMASK (1<<30) +#define EXTENDED_KEYMASK (1<<24) + + +static SDLKey +TranslateKey(WPARAM vkey) +{ + SDLKey key; + + /* FIXME: Assign vkey directly to key if in ASCII range */ + switch (vkey) { + case VK_BACK: + key = SDLK_BACKSPACE; + break; + case VK_TAB: + key = SDLK_TAB; + break; + case VK_CLEAR: + key = SDLK_CLEAR; + break; + case VK_RETURN: + key = SDLK_RETURN; + break; + case VK_PAUSE: + key = SDLK_PAUSE; + break; + case VK_ESCAPE: + key = SDLK_ESCAPE; + break; + case VK_SPACE: + key = SDLK_SPACE; + break; + case VK_APOSTROPHE: + key = SDLK_QUOTE; + break; + case VK_COMMA: + key = SDLK_COMMA; + break; + case VK_MINUS: + key = SDLK_MINUS; + break; + case VK_PERIOD: + key = SDLK_PERIOD; + break; + case VK_SLASH: + key = SDLK_SLASH; + break; + case VK_0: + key = SDLK_0; + break; + case VK_1: + key = SDLK_1; + break; + case VK_2: + key = SDLK_2; + break; + case VK_3: + key = SDLK_3; + break; + case VK_4: + key = SDLK_4; + break; + case VK_5: + key = SDLK_5; + break; + case VK_6: + key = SDLK_6; + break; + case VK_7: + key = SDLK_7; + break; + case VK_8: + key = SDLK_8; + break; + case VK_9: + key = SDLK_9; + break; + case VK_SEMICOLON: + key = SDLK_SEMICOLON; + break; + case VK_EQUALS: + key = SDLK_EQUALS; + break; + case VK_LBRACKET: + key = SDLK_LEFTBRACKET; + break; + case VK_BACKSLASH: + key = SDLK_BACKSLASH; + break; + case VK_OEM_102: + key = SDLK_LESS; + break; + case VK_RBRACKET: + key = SDLK_RIGHTBRACKET; + break; + case VK_GRAVE: + key = SDLK_BACKQUOTE; + break; + case VK_BACKTICK: + key = SDLK_BACKQUOTE; + break; + case VK_A: + key = SDLK_a; + break; + case VK_B: + key = SDLK_b; + break; + case VK_C: + key = SDLK_c; + break; + case VK_D: + key = SDLK_d; + break; + case VK_E: + key = SDLK_e; + break; + case VK_F: + key = SDLK_f; + break; + case VK_G: + key = SDLK_g; + break; + case VK_H: + key = SDLK_h; + break; + case VK_I: + key = SDLK_i; + break; + case VK_J: + key = SDLK_j; + break; + case VK_K: + key = SDLK_k; + break; + case VK_L: + key = SDLK_l; + break; + case VK_M: + key = SDLK_m; + break; + case VK_N: + key = SDLK_n; + break; + case VK_O: + key = SDLK_o; + break; + case VK_P: + key = SDLK_p; + break; + case VK_Q: + key = SDLK_q; + break; + case VK_R: + key = SDLK_r; + break; + case VK_S: + key = SDLK_s; + break; + case VK_T: + key = SDLK_t; + break; + case VK_U: + key = SDLK_u; + break; + case VK_V: + key = SDLK_v; + break; + case VK_W: + key = SDLK_w; + break; + case VK_X: + key = SDLK_x; + break; + case VK_Y: + key = SDLK_y; + break; + case VK_Z: + key = SDLK_z; + break; + case VK_DELETE: + key = SDLK_DELETE; + break; + case VK_NUMPAD0: + key = SDLK_KP0; + break; + case VK_NUMPAD1: + key = SDLK_KP1; + break; + case VK_NUMPAD2: + key = SDLK_KP2; + break; + case VK_NUMPAD3: + key = SDLK_KP3; + break; + case VK_NUMPAD4: + key = SDLK_KP4; + break; + case VK_NUMPAD5: + key = SDLK_KP5; + break; + case VK_NUMPAD6: + key = SDLK_KP6; + break; + case VK_NUMPAD7: + key = SDLK_KP7; + break; + case VK_NUMPAD8: + key = SDLK_KP8; + break; + case VK_NUMPAD9: + key = SDLK_KP9; + break; + case VK_DECIMAL: + key = SDLK_KP_PERIOD; + break; + case VK_DIVIDE: + key = SDLK_KP_DIVIDE; + break; + case VK_MULTIPLY: + key = SDLK_KP_MULTIPLY; + break; + case VK_SUBTRACT: + key = SDLK_KP_MINUS; + break; + case VK_ADD: + key = SDLK_KP_PLUS; + break; + case VK_UP: + key = SDLK_UP; + break; + case VK_DOWN: + key = SDLK_DOWN; + break; + case VK_RIGHT: + key = SDLK_RIGHT; + break; + case VK_LEFT: + key = SDLK_LEFT; + break; + case VK_INSERT: + key = SDLK_INSERT; + break; + case VK_HOME: + key = SDLK_HOME; + break; + case VK_END: + key = SDLK_END; + break; + case VK_PRIOR: + key = SDLK_PAGEUP; + break; + case VK_NEXT: + key = SDLK_PAGEDOWN; + break; + case VK_F1: + key = SDLK_F1; + break; + case VK_F2: + key = SDLK_F2; + break; + case VK_F3: + key = SDLK_F3; + break; + case VK_F4: + key = SDLK_F4; + break; + case VK_F5: + key = SDLK_F5; + break; + case VK_F6: + key = SDLK_F6; + break; + case VK_F7: + key = SDLK_F7; + break; + case VK_F8: + key = SDLK_F8; + break; + case VK_F9: + key = SDLK_F9; + break; + case VK_F10: + key = SDLK_F10; + break; + case VK_F11: + key = SDLK_F11; + break; + case VK_F12: + key = SDLK_F12; + break; + case VK_F13: + key = SDLK_F13; + break; + case VK_F14: + key = SDLK_F14; + break; + case VK_F15: + key = SDLK_F15; + break; + case VK_NUMLOCK: + key = SDLK_NUMLOCK; + break; + case VK_CAPITAL: + key = SDLK_CAPSLOCK; + break; + case VK_SCROLL: + key = SDLK_SCROLLOCK; + break; + case VK_RSHIFT: + key = SDLK_RSHIFT; + break; + case VK_LSHIFT: + key = SDLK_LSHIFT; + break; + case VK_RCONTROL: + key = SDLK_RCTRL; + break; + case VK_LCONTROL: + key = SDLK_LCTRL; + break; + case VK_RMENU: + key = SDLK_RALT; + break; + case VK_LMENU: + key = SDLK_LALT; + break; + case VK_RWIN: + key = SDLK_RSUPER; + break; + case VK_LWIN: + key = SDLK_LSUPER; + break; + case VK_HELP: + key = SDLK_HELP; + break; + case VK_PRINT: + key = SDLK_PRINT; + break; + case VK_SNAPSHOT: + key = SDLK_PRINT; + break; + case VK_CANCEL: + key = SDLK_BREAK; + break; + case VK_APPS: + key = SDLK_MENU; + break; + default: + key = SDLK_UNKNOWN; + break; + } + return key; +} LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -35,33 +397,60 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (!data) { return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam); } -#if 0 +#ifdef WMMSG_DEBUG + fprintf(stderr, "Received windows message: "); + if (msg > MAX_WMMSG) { + fprintf(stderr, "%d", msg); + } else { + fprintf(stderr, "%s", wmtab[msg]); + } + fprintf(stderr, " -- 0x%X, 0x%X\n", wParam, lParam); +#endif + + /* 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); + } + switch (msg) { 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_PrivateWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, - 0, 0); - SDL_PrivateWindowEvent(data->windowID, - SDL_WINDOWEVENT_RESTORED, 0, 0); + SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_SHOWN, + 0, 0); + SDL_SendWindowEvent(data->windowID, + SDL_WINDOWEVENT_RESTORED, 0, 0); if (IsZoomed(hwnd)) { - SDL_PrivateWindowEvent(data->windowID, - SDL_WINDOWEVENT_MAXIMIZED, 0, 0); + SDL_SendWindowEvent(data->windowID, + SDL_WINDOWEVENT_MAXIMIZED, 0, 0); + } + if (keyboard && keyboard->focus != data->windowID) { + SDL_SetKeyboardFocus(index, data->windowID); } - 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 (keyboard && keyboard->focus == data->windowID) { + SDL_SetKeyboardFocus(index, 0); + } if (minimized) { - SDL_PrivateWindowEvent(data->windowID, - SDL_WINDOWEVENT_MINIMIZED, 0, 0); + SDL_SendWindowEvent(data->windowID, + SDL_WINDOWEVENT_MINIMIZED, 0, 0); } /* FIXME: Restore desktop state (mode, gamma, grab) */ } @@ -73,11 +462,12 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { int index; SDL_Mouse *mouse; + int x, y; + + index = data->videodata->mouse; + mouse = SDL_GetMouse(index); - if (! - (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_MOUSE_FOCUS)) - { - /* mouse has entered the window */ + if (mouse->focus != data->windowID) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); @@ -85,41 +475,42 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) tme.hwndTrack = hwnd; TrackMouseEvent(&tme); - SDL_PrivateWindowEvent(data->windowID, SDL_WINDOWEVENT_ENTER, - 0, 0); + SDL_SetMouseFocus(index, data->windowID); } - 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, ¢er); - SetCursorPos(center.x, center.y); - SDL_SendMouseMotion(index, data->windowID, 1, x, y); - } - } else { - SDL_SendMouseMotion(index, data->windowID, 0, 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(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: { - SDL_PrivateWindowEvent(data->windowID, SDL_WINDOWEVENT_LEAVE, 0, - 0); + int index; + SDL_Mouse *mouse; + + index = data->videodata->mouse; + mouse = SDL_GetMouse(index); + + if (mouse->focus == data->windowID) { + SDL_SetMouseFocus(index, 0); + } } return (0); @@ -130,7 +521,8 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_RBUTTONDOWN: case WM_RBUTTONUP: { - int x, y; + int index; + SDL_Mouse *mouse; Uint8 button, state; /* DJM: @@ -138,7 +530,10 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) it acts like a normal windows "component" (e.g. gains keyboard focus on a mouse click). */ - SetFocus(SDL_Window); + SetFocus(hwnd); + + index = data->videodata->mouse; + mouse = SDL_GetMouse(index); /* Figure out which button to use */ switch (msg) { @@ -172,85 +567,155 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) } if (state == SDL_PRESSED) { /* Grab mouse so we get up events */ - if (++mouse_pressed > 0) { + if (++data->mouse_pressed > 0) { SetCapture(hwnd); } } else { /* Release mouse after all up events */ - if (--mouse_pressed <= 0) { + if (--data->mouse_pressed <= 0) { ReleaseCapture(); - mouse_pressed = 0; + data->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); + + if (!mouse->relative_mode) { + int x, y; + x = LOWORD(lParam); + y = HIWORD(lParam); + SDL_SendMouseMotion(index, 0, x, y); + } + SDL_SendMouseButton(index, state, button); } + return (0); + + case WM_MOUSEWHEEL: + { + int index; + int motion = (short) HIWORD(wParam); + index = data->videodata->mouse; + SDL_SendMouseWheel(index, motion); + } return (0); + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + { + int index; -#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; + /* Ignore repeated keys */ + if (lParam & REPEATED_KEYMASK) { + return (0); + } + + index = data->videodata->keyboard; + 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_GetKeyState(NULL); + if (state[SDLK_LSHIFT] == SDL_RELEASED + && (GetKeyState(VK_LSHIFT) & 0x8000)) { + wParam = VK_LSHIFT; + } else if (state[SDLK_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 - button = SDL_BUTTON_WHEELDOWN; - posted = SDL_PrivateMouseButton(SDL_PRESSED, button, 0, 0); - posted |= SDL_PrivateMouseButton(SDL_RELEASED, button, 0, 0); + wParam = VK_LMENU; + break; } + SDL_SendKeyboardKey(index, SDL_PRESSED, (Uint8) HIWORD(lParam), + TranslateKey(wParam)); + } + return (0); + + case WM_SYSKEYUP: + case WM_KEYUP: + { + int index; + + index = data->videodata->keyboard; + 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_GetKeyState(NULL); + if (state[SDLK_LSHIFT] == SDL_PRESSED + && !(GetKeyState(VK_LSHIFT) & 0x8000)) { + wParam = VK_LSHIFT; + } else if (state[SDLK_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; + } + /* Windows only reports keyup for print screen */ + if (wParam == VK_SNAPSHOT + && SDL_GetKeyState(NULL)[SDLK_PRINT] == SDL_RELEASED) { + SDL_SendKeyboardKey(index, SDL_PRESSED, + (Uint8) HIWORD(lParam), + TranslateKey(wParam)); + } + SDL_SendKeyboardKey(index, SDL_RELEASED, (Uint8) HIWORD(lParam), + TranslateKey(wParam)); } 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 w, h; 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)) { + /* 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(SDL_Window, &size); + GetWindowRect(hwnd, &size); x = size.left; y = size.top; - /* Calculate current width and height of our window */ + /* Calculate current size of our window */ + SDL_GetWindowSize(data->windowID, &w, &h); 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; - } + size.bottom = h; + size.right = w; /* DJM - according to the docs for GetMenu(), the return value is undefined if hwnd is a child window. @@ -263,122 +728,111 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) style & WS_CHILDWINDOW ? FALSE : GetMenu(hwnd) != NULL); - width = size.right - size.left; - height = size.bottom - size.top; + w = size.right - size.left; + h = size.bottom - size.top; /* Fix our size to the current size */ info = (MINMAXINFO *) lParam; - info->ptMaxSize.x = width; - info->ptMaxSize.y = height; + info->ptMaxSize.x = w; + info->ptMaxSize.y = h; info->ptMaxPosition.x = x; info->ptMaxPosition.y = y; - info->ptMinTrackSize.x = width; - info->ptMinTrackSize.y = height; - info->ptMaxTrackSize.x = width; - info->ptMaxTrackSize.y = height; + info->ptMinTrackSize.x = w; + info->ptMinTrackSize.y = h; + info->ptMaxTrackSize.x = w; + info->ptMaxTrackSize.y = h; } - return (0); -#endif /* WM_GETMINMAXINFO */ case WM_WINDOWPOSCHANGED: { - SDL_VideoDevice *this = current_video; + RECT rect; + int x, y; 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); + GetClientRect(hwnd, &rect); + ClientToScreen(hwnd, (LPPOINT) & rect); + ClientToScreen(hwnd, (LPPOINT) & rect + 1); + + if (SDL_GetWindowFlags(data->windowID) & SDL_WINDOW_INPUT_GRABBED) { + 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; - /* We need to set the cursor */ case WM_SETCURSOR: { - Uint16 hittest; - - hittest = LOWORD(lParam); - if (hittest == HTCLIENT) { - SetCursor(SDL_hcursor); - return (TRUE); - } + /* + 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); + /* + WIN_RealizePalette(current_video); + return (TRUE); + */ } - break; /* Another application changed the palette */ case WM_PALETTECHANGED: { - WIN_PaletteChanged(current_video, (HWND) wParam); + /* + 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); + RECT rect; + if (GetUpdateRect(hwnd, &rect, FALSE)) { + ValidateRect(hwnd, &rect); + SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_EXPOSED, + 0, 0); } - EndPaint(SDL_Window, &ps); } - return (0); - /* DJM: Send an expose event in this case */ - case WM_ERASEBKGND: + case WM_SYSCOMMAND: { - posted = SDL_PrivateExpose(); + /* 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); + } + } } - - return (0); + break; case WM_CLOSE: { - if ((posted = SDL_PrivateQuit())) - PostQuitMessage(0); + SDL_SendWindowEvent(data->windowID, SDL_WINDOWEVENT_CLOSE, 0, 0); } - - return (0); - - case WM_DESTROY: - { - PostQuitMessage(0); - } - return (0); } -#endif return CallWindowProc(data->wndproc, hwnd, msg, wParam, lParam); } diff --git a/src/video/win32/SDL_win32keyboard.c b/src/video/win32/SDL_win32keyboard.c index a383b259d..5691ceef1 100644 --- a/src/video/win32/SDL_win32keyboard.c +++ b/src/video/win32/SDL_win32keyboard.c @@ -35,4 +35,12 @@ WIN_AddKeyboard(_THIS) data->keyboard = SDL_AddKeyboard(&keyboard, -1); } +void +WIN_DelKeyboard(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + SDL_DelKeyboard(data->keyboard); +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32keyboard.h b/src/video/win32/SDL_win32keyboard.h index 232ba8a10..1c2a5ab02 100644 --- a/src/video/win32/SDL_win32keyboard.h +++ b/src/video/win32/SDL_win32keyboard.h @@ -25,6 +25,7 @@ #define _SDL_win32keyboard_h extern void WIN_AddKeyboard(_THIS); +extern void WIN_DelKeyboard(_THIS); #endif /* _SDL_win32keyboard_h */ diff --git a/src/video/win32/SDL_win32mouse.c b/src/video/win32/SDL_win32mouse.c index d4c268edb..be75d49aa 100644 --- a/src/video/win32/SDL_win32mouse.c +++ b/src/video/win32/SDL_win32mouse.c @@ -35,4 +35,12 @@ WIN_AddMouse(_THIS) data->mouse = SDL_AddMouse(&mouse, -1); } +void +WIN_DelMouse(_THIS) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + SDL_DelMouse(data->mouse); +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32mouse.h b/src/video/win32/SDL_win32mouse.h index 1a79fe85e..1989931cc 100644 --- a/src/video/win32/SDL_win32mouse.h +++ b/src/video/win32/SDL_win32mouse.h @@ -25,6 +25,7 @@ #define _SDL_win32mouse_h extern void WIN_AddMouse(_THIS); +extern void WIN_DelMouse(_THIS); #endif /* _SDL_win32mouse_h */ diff --git a/src/video/win32/SDL_win32video.c b/src/video/win32/SDL_win32video.c index 5c2fe35e3..addb0ba1c 100644 --- a/src/video/win32/SDL_win32video.c +++ b/src/video/win32/SDL_win32video.c @@ -28,8 +28,7 @@ #include "../SDL_pixels_c.h" #include "SDL_win32video.h" -#include "SDL_win32events.h" -#include "SDL_win32window.h" +#include "SDL_dibrender.h" /* Initialization/Query functions */ static int WIN_VideoInit(_THIS); @@ -109,10 +108,51 @@ VideoBootStrap WIN32_bootstrap = { int WIN_VideoInit(_THIS) { + int bmi_size; + LPBITMAPINFO bmi; SDL_DisplayMode mode; - SDL_AddBasicVideoDisplay(NULL); - //SDL_AddRenderDriver(0, &SDL_WIN_RenderDriver); + /* Find out the desktop mode */ + mode.format = SDL_PixelFormat_Unknown; + mode.w = GetSystemMetrics(SM_CXSCREEN); + mode.h = GetSystemMetrics(SM_CYSCREEN); + mode.refresh_rate = 0; + + bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD); + bmi = (LPBITMAPINFO) SDL_malloc(bmi_size); + if (bmi) { + HDC hdc; + HBITMAP hbm; + + SDL_memset(bmi, 0, bmi_size); + bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + hdc = GetDC(NULL); + hbm = CreateCompatibleBitmap(hdc, 1, 1); + GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS); + GetDIBits(hdc, hbm, 0, 1, NULL, bmi, DIB_RGB_COLORS); + DeleteObject(hbm); + ReleaseDC(NULL, hdc); + if (bmi->bmiHeader.biCompression == BI_BITFIELDS) { + switch (*(Uint32 *) bmi->bmiColors) { + case 0x00FF0000: + mode.format = SDL_PixelFormat_RGB888; + break; + case 0x000000FF: + mode.format = SDL_PixelFormat_BGR888; + break; + case 0xF800: + mode.format = SDL_PixelFormat_RGB565; + break; + case 0x7C00: + mode.format = SDL_PixelFormat_RGB555; + break; + } + } else if (bmi->bmiHeader.biBitCount == 8) { + mode.format = SDL_PixelFormat_Index8; + } + } + SDL_AddBasicVideoDisplay(&mode); + SDL_AddRenderDriver(0, &SDL_DIB_RenderDriver); SDL_zero(mode); SDL_AddDisplayMode(0, &mode); @@ -134,6 +174,8 @@ WIN_SetDisplayMode(_THIS, const SDL_DisplayMode * mode) void WIN_VideoQuit(_THIS) { + WIN_DelKeyboard(_this); + WIN_DelMouse(_this); } /* vim: set ts=4 sw=4 expandtab: */ diff --git a/src/video/win32/SDL_win32video.h b/src/video/win32/SDL_win32video.h index 21e4a1984..7ebb42b27 100644 --- a/src/video/win32/SDL_win32video.h +++ b/src/video/win32/SDL_win32video.h @@ -28,6 +28,7 @@ #define WIN32_LEAN_AND_MEAN #define UNICODE +#define WINVER 0x0410 // 0x0410 needed for AlphaBlend() #include #include "SDL_win32events.h" diff --git a/src/video/win32/SDL_win32window.c b/src/video/win32/SDL_win32window.c index ef1392113..2216e9fe9 100644 --- a/src/video/win32/SDL_win32window.c +++ b/src/video/win32/SDL_win32window.c @@ -43,6 +43,7 @@ SetupWindowData(SDL_Window * window, HWND hwnd, BOOL created) data->windowID = window->id; data->hwnd = hwnd; data->created = created; + data->mouse_pressed = SDL_FALSE; data->videodata = (SDL_VideoData *) SDL_GetVideoDevice()->driverdata; /* Associate the data with the window */ @@ -180,6 +181,8 @@ WIN_CreateWindow(_THIS, SDL_Window * window) hwnd = CreateWindow(SDL_Appname, title ? title : TEXT(""), style, x, y, w, h, NULL, NULL, SDL_Instance, NULL); + WIN_PumpEvents(_this); + if (title) { SDL_free(title); } diff --git a/src/video/win32/SDL_win32window.h b/src/video/win32/SDL_win32window.h index 4e3a7e993..5582f9e74 100644 --- a/src/video/win32/SDL_win32window.h +++ b/src/video/win32/SDL_win32window.h @@ -33,6 +33,7 @@ typedef struct HWND hwnd; WNDPROC wndproc; BOOL created; + int mouse_pressed; struct SDL_VideoData *videodata; } SDL_WindowData; diff --git a/src/video/win32/wmmsg.h b/src/video/win32/wmmsg.h new file mode 100644 index 000000000..4b5098ac6 --- /dev/null +++ b/src/video/win32/wmmsg.h @@ -0,0 +1,1032 @@ + +#define MAX_WMMSG (sizeof(wmtab)/sizeof(wmtab[0])) + +char *wmtab[] = { + "WM_NULL", + "WM_CREATE", + "WM_DESTROY", + "WM_MOVE", + "UNKNOWN (4)", + "WM_SIZE", + "WM_ACTIVATE", + "WM_SETFOCUS", + "WM_KILLFOCUS", + "UNKNOWN (9)", + "WM_ENABLE", + "WM_SETREDRAW", + "WM_SETTEXT", + "WM_GETTEXT", + "WM_GETTEXTLENGTH", + "WM_PAINT", + "WM_CLOSE", + "WM_QUERYENDSESSION", + "WM_QUIT", + "WM_QUERYOPEN", + "WM_ERASEBKGND", + "WM_SYSCOLORCHANGE", + "WM_ENDSESSION", + "UNKNOWN (23)", + "WM_SHOWWINDOW", + "UNKNOWN (25)", + "WM_SETTINGCHANGE", + "WM_DEVMODECHANGE", + "WM_ACTIVATEAPP", + "WM_FONTCHANGE", + "WM_TIMECHANGE", + "WM_CANCELMODE", + "WM_SETCURSOR", + "WM_MOUSEACTIVATE", + "WM_CHILDACTIVATE", + "WM_QUEUESYNC", + "WM_GETMINMAXINFO", + "UNKNOWN (37)", + "WM_PAINTICON", + "WM_ICONERASEBKGND", + "WM_NEXTDLGCTL", + "UNKNOWN (41)", + "WM_SPOOLERSTATUS", + "WM_DRAWITEM", + "WM_MEASUREITEM", + "WM_DELETEITEM", + "WM_VKEYTOITEM", + "WM_CHARTOITEM", + "WM_SETFONT", + "WM_GETFONT", + "WM_SETHOTKEY", + "WM_GETHOTKEY", + "UNKNOWN (52)", + "UNKNOWN (53)", + "UNKNOWN (54)", + "WM_QUERYDRAGICON", + "UNKNOWN (56)", + "WM_COMPAREITEM", + "UNKNOWN (58)", + "UNKNOWN (59)", + "UNKNOWN (60)", + "WM_GETOBJECT", + "UNKNOWN (62)", + "UNKNOWN (63)", + "UNKNOWN (64)", + "WM_COMPACTING", + "UNKNOWN (66)", + "UNKNOWN (67)", + "WM_COMMNOTIFY", + "UNKNOWN (69)", + "WM_WINDOWPOSCHANGING", + "WM_WINDOWPOSCHANGED", + "WM_POWER", + "UNKNOWN (73)", + "WM_COPYDATA", + "WM_CANCELJOURNAL", + "UNKNOWN (76)", + "UNKNOWN (77)", + "WM_NOTIFY", + "UNKNOWN (79)", + "WM_INPUTLANGCHANGEREQUEST", + "WM_INPUTLANGCHANGE", + "WM_TCARD", + "WM_HELP", + "WM_USERCHANGED", + "WM_NOTIFYFORMAT", + "UNKNOWN (86)", + "UNKNOWN (87)", + "UNKNOWN (88)", + "UNKNOWN (89)", + "UNKNOWN (90)", + "UNKNOWN (91)", + "UNKNOWN (92)", + "UNKNOWN (93)", + "UNKNOWN (94)", + "UNKNOWN (95)", + "UNKNOWN (96)", + "UNKNOWN (97)", + "UNKNOWN (98)", + "UNKNOWN (99)", + "UNKNOWN (100)", + "UNKNOWN (101)", + "UNKNOWN (102)", + "UNKNOWN (103)", + "UNKNOWN (104)", + "UNKNOWN (105)", + "UNKNOWN (106)", + "UNKNOWN (107)", + "UNKNOWN (108)", + "UNKNOWN (109)", + "UNKNOWN (110)", + "UNKNOWN (111)", + "UNKNOWN (112)", + "UNKNOWN (113)", + "UNKNOWN (114)", + "UNKNOWN (115)", + "UNKNOWN (116)", + "UNKNOWN (117)", + "UNKNOWN (118)", + "UNKNOWN (119)", + "UNKNOWN (120)", + "UNKNOWN (121)", + "UNKNOWN (122)", + "WM_CONTEXTMENU", + "WM_STYLECHANGING", + "WM_STYLECHANGED", + "WM_DISPLAYCHANGE", + "WM_GETICON", + "WM_SETICON", + "WM_NCCREATE", + "WM_NCDESTROY", + "WM_NCCALCSIZE", + "WM_NCHITTEST", + "WM_NCPAINT", + "WM_NCACTIVATE", + "WM_GETDLGCODE", + "WM_SYNCPAINT", + "UNKNOWN (137)", + "UNKNOWN (138)", + "UNKNOWN (139)", + "UNKNOWN (140)", + "UNKNOWN (141)", + "UNKNOWN (142)", + "UNKNOWN (143)", + "UNKNOWN (144)", + "UNKNOWN (145)", + "UNKNOWN (146)", + "UNKNOWN (147)", + "UNKNOWN (148)", + "UNKNOWN (149)", + "UNKNOWN (150)", + "UNKNOWN (151)", + "UNKNOWN (152)", + "UNKNOWN (153)", + "UNKNOWN (154)", + "UNKNOWN (155)", + "UNKNOWN (156)", + "UNKNOWN (157)", + "UNKNOWN (158)", + "UNKNOWN (159)", + "WM_NCMOUSEMOVE", + "WM_NCLBUTTONDOWN", + "WM_NCLBUTTONUP", + "WM_NCLBUTTONDBLCLK", + "WM_NCRBUTTONDOWN", + "WM_NCRBUTTONUP", + "WM_NCRBUTTONDBLCLK", + "WM_NCMBUTTONDOWN", + "WM_NCMBUTTONUP", + "WM_NCMBUTTONDBLCLK", + "UNKNOWN (170)", + "UNKNOWN (171)", + "UNKNOWN (172)", + "UNKNOWN (173)", + "UNKNOWN (174)", + "UNKNOWN (175)", + "UNKNOWN (176)", + "UNKNOWN (177)", + "UNKNOWN (178)", + "UNKNOWN (179)", + "UNKNOWN (180)", + "UNKNOWN (181)", + "UNKNOWN (182)", + "UNKNOWN (183)", + "UNKNOWN (184)", + "UNKNOWN (185)", + "UNKNOWN (186)", + "UNKNOWN (187)", + "UNKNOWN (188)", + "UNKNOWN (189)", + "UNKNOWN (190)", + "UNKNOWN (191)", + "UNKNOWN (192)", + "UNKNOWN (193)", + "UNKNOWN (194)", + "UNKNOWN (195)", + "UNKNOWN (196)", + "UNKNOWN (197)", + "UNKNOWN (198)", + "UNKNOWN (199)", + "UNKNOWN (200)", + "UNKNOWN (201)", + "UNKNOWN (202)", + "UNKNOWN (203)", + "UNKNOWN (204)", + "UNKNOWN (205)", + "UNKNOWN (206)", + "UNKNOWN (207)", + "UNKNOWN (208)", + "UNKNOWN (209)", + "UNKNOWN (210)", + "UNKNOWN (211)", + "UNKNOWN (212)", + "UNKNOWN (213)", + "UNKNOWN (214)", + "UNKNOWN (215)", + "UNKNOWN (216)", + "UNKNOWN (217)", + "UNKNOWN (218)", + "UNKNOWN (219)", + "UNKNOWN (220)", + "UNKNOWN (221)", + "UNKNOWN (222)", + "UNKNOWN (223)", + "UNKNOWN (224)", + "UNKNOWN (225)", + "UNKNOWN (226)", + "UNKNOWN (227)", + "UNKNOWN (228)", + "UNKNOWN (229)", + "UNKNOWN (230)", + "UNKNOWN (231)", + "UNKNOWN (232)", + "UNKNOWN (233)", + "UNKNOWN (234)", + "UNKNOWN (235)", + "UNKNOWN (236)", + "UNKNOWN (237)", + "UNKNOWN (238)", + "UNKNOWN (239)", + "UNKNOWN (240)", + "UNKNOWN (241)", + "UNKNOWN (242)", + "UNKNOWN (243)", + "UNKNOWN (244)", + "UNKNOWN (245)", + "UNKNOWN (246)", + "UNKNOWN (247)", + "UNKNOWN (248)", + "UNKNOWN (249)", + "UNKNOWN (250)", + "UNKNOWN (251)", + "UNKNOWN (252)", + "UNKNOWN (253)", + "UNKNOWN (254)", + "UNKNOWN (255)", + "WM_KEYDOWN", + "WM_KEYUP", + "WM_CHAR", + "WM_DEADCHAR", + "WM_SYSKEYDOWN", + "WM_SYSKEYUP", + "WM_SYSCHAR", + "WM_SYSDEADCHAR", + "WM_KEYLAST", + "UNKNOWN (265)", + "UNKNOWN (266)", + "UNKNOWN (267)", + "UNKNOWN (268)", + "UNKNOWN (269)", + "UNKNOWN (270)", + "UNKNOWN (271)", + "WM_INITDIALOG", + "WM_COMMAND", + "WM_SYSCOMMAND", + "WM_TIMER", + "WM_HSCROLL", + "WM_VSCROLL", + "WM_INITMENU", + "WM_INITMENUPOPUP", + "UNKNOWN (280)", + "UNKNOWN (281)", + "UNKNOWN (282)", + "UNKNOWN (283)", + "UNKNOWN (284)", + "UNKNOWN (285)", + "UNKNOWN (286)", + "WM_MENUSELECT", + "WM_MENUCHAR", + "WM_ENTERIDLE", + "WM_MENURBUTTONUP", + "WM_MENUDRAG", + "WM_MENUGETOBJECT", + "WM_UNINITMENUPOPUP", + "WM_MENUCOMMAND", + "UNKNOWN (295)", + "UNKNOWN (296)", + "UNKNOWN (297)", + "UNKNOWN (298)", + "UNKNOWN (299)", + "UNKNOWN (300)", + "UNKNOWN (301)", + "UNKNOWN (302)", + "UNKNOWN (303)", + "UNKNOWN (304)", + "UNKNOWN (305)", + "WM_CTLCOLORMSGBOX", + "WM_CTLCOLOREDIT", + "WM_CTLCOLORLISTBOX", + "WM_CTLCOLORBTN", + "WM_CTLCOLORDLG", + "WM_CTLCOLORSCROLLBAR", + "WM_CTLCOLORSTATIC", + "UNKNOWN (313)", + "UNKNOWN (314)", + "UNKNOWN (315)", + "UNKNOWN (316)", + "UNKNOWN (317)", + "UNKNOWN (318)", + "UNKNOWN (319)", + "UNKNOWN (320)", + "UNKNOWN (321)", + "UNKNOWN (322)", + "UNKNOWN (323)", + "UNKNOWN (324)", + "UNKNOWN (325)", + "UNKNOWN (326)", + "UNKNOWN (327)", + "UNKNOWN (328)", + "UNKNOWN (329)", + "UNKNOWN (330)", + "UNKNOWN (331)", + "UNKNOWN (332)", + "UNKNOWN (333)", + "UNKNOWN (334)", + "UNKNOWN (335)", + "UNKNOWN (336)", + "UNKNOWN (337)", + "UNKNOWN (338)", + "UNKNOWN (339)", + "UNKNOWN (340)", + "UNKNOWN (341)", + "UNKNOWN (342)", + "UNKNOWN (343)", + "UNKNOWN (344)", + "UNKNOWN (345)", + "UNKNOWN (346)", + "UNKNOWN (347)", + "UNKNOWN (348)", + "UNKNOWN (349)", + "UNKNOWN (350)", + "UNKNOWN (351)", + "UNKNOWN (352)", + "UNKNOWN (353)", + "UNKNOWN (354)", + "UNKNOWN (355)", + "UNKNOWN (356)", + "UNKNOWN (357)", + "UNKNOWN (358)", + "UNKNOWN (359)", + "UNKNOWN (360)", + "UNKNOWN (361)", + "UNKNOWN (362)", + "UNKNOWN (363)", + "UNKNOWN (364)", + "UNKNOWN (365)", + "UNKNOWN (366)", + "UNKNOWN (367)", + "UNKNOWN (368)", + "UNKNOWN (369)", + "UNKNOWN (370)", + "UNKNOWN (371)", + "UNKNOWN (372)", + "UNKNOWN (373)", + "UNKNOWN (374)", + "UNKNOWN (375)", + "UNKNOWN (376)", + "UNKNOWN (377)", + "UNKNOWN (378)", + "UNKNOWN (379)", + "UNKNOWN (380)", + "UNKNOWN (381)", + "UNKNOWN (382)", + "UNKNOWN (383)", + "UNKNOWN (384)", + "UNKNOWN (385)", + "UNKNOWN (386)", + "UNKNOWN (387)", + "UNKNOWN (388)", + "UNKNOWN (389)", + "UNKNOWN (390)", + "UNKNOWN (391)", + "UNKNOWN (392)", + "UNKNOWN (393)", + "UNKNOWN (394)", + "UNKNOWN (395)", + "UNKNOWN (396)", + "UNKNOWN (397)", + "UNKNOWN (398)", + "UNKNOWN (399)", + "UNKNOWN (400)", + "UNKNOWN (401)", + "UNKNOWN (402)", + "UNKNOWN (403)", + "UNKNOWN (404)", + "UNKNOWN (405)", + "UNKNOWN (406)", + "UNKNOWN (407)", + "UNKNOWN (408)", + "UNKNOWN (409)", + "UNKNOWN (410)", + "UNKNOWN (411)", + "UNKNOWN (412)", + "UNKNOWN (413)", + "UNKNOWN (414)", + "UNKNOWN (415)", + "UNKNOWN (416)", + "UNKNOWN (417)", + "UNKNOWN (418)", + "UNKNOWN (419)", + "UNKNOWN (420)", + "UNKNOWN (421)", + "UNKNOWN (422)", + "UNKNOWN (423)", + "UNKNOWN (424)", + "UNKNOWN (425)", + "UNKNOWN (426)", + "UNKNOWN (427)", + "UNKNOWN (428)", + "UNKNOWN (429)", + "UNKNOWN (430)", + "UNKNOWN (431)", + "UNKNOWN (432)", + "UNKNOWN (433)", + "UNKNOWN (434)", + "UNKNOWN (435)", + "UNKNOWN (436)", + "UNKNOWN (437)", + "UNKNOWN (438)", + "UNKNOWN (439)", + "UNKNOWN (440)", + "UNKNOWN (441)", + "UNKNOWN (442)", + "UNKNOWN (443)", + "UNKNOWN (444)", + "UNKNOWN (445)", + "UNKNOWN (446)", + "UNKNOWN (447)", + "UNKNOWN (448)", + "UNKNOWN (449)", + "UNKNOWN (450)", + "UNKNOWN (451)", + "UNKNOWN (452)", + "UNKNOWN (453)", + "UNKNOWN (454)", + "UNKNOWN (455)", + "UNKNOWN (456)", + "UNKNOWN (457)", + "UNKNOWN (458)", + "UNKNOWN (459)", + "UNKNOWN (460)", + "UNKNOWN (461)", + "UNKNOWN (462)", + "UNKNOWN (463)", + "UNKNOWN (464)", + "UNKNOWN (465)", + "UNKNOWN (466)", + "UNKNOWN (467)", + "UNKNOWN (468)", + "UNKNOWN (469)", + "UNKNOWN (470)", + "UNKNOWN (471)", + "UNKNOWN (472)", + "UNKNOWN (473)", + "UNKNOWN (474)", + "UNKNOWN (475)", + "UNKNOWN (476)", + "UNKNOWN (477)", + "UNKNOWN (478)", + "UNKNOWN (479)", + "UNKNOWN (480)", + "UNKNOWN (481)", + "UNKNOWN (482)", + "UNKNOWN (483)", + "UNKNOWN (484)", + "UNKNOWN (485)", + "UNKNOWN (486)", + "UNKNOWN (487)", + "UNKNOWN (488)", + "UNKNOWN (489)", + "UNKNOWN (490)", + "UNKNOWN (491)", + "UNKNOWN (492)", + "UNKNOWN (493)", + "UNKNOWN (494)", + "UNKNOWN (495)", + "UNKNOWN (496)", + "UNKNOWN (497)", + "UNKNOWN (498)", + "UNKNOWN (499)", + "UNKNOWN (500)", + "UNKNOWN (501)", + "UNKNOWN (502)", + "UNKNOWN (503)", + "UNKNOWN (504)", + "UNKNOWN (505)", + "UNKNOWN (506)", + "UNKNOWN (507)", + "UNKNOWN (508)", + "UNKNOWN (509)", + "UNKNOWN (510)", + "UNKNOWN (511)", + "WM_MOUSEMOVE", + "WM_LBUTTONDOWN", + "WM_LBUTTONUP", + "WM_LBUTTONDBLCLK", + "WM_RBUTTONDOWN", + "WM_RBUTTONUP", + "WM_RBUTTONDBLCLK", + "WM_MBUTTONDOWN", + "WM_MBUTTONUP", + "WM_MOUSELAST", + "WM_MOUSELAST", + "UNKNOWN (523)", + "UNKNOWN (524)", + "UNKNOWN (525)", + "UNKNOWN (526)", + "UNKNOWN (527)", + "WM_PARENTNOTIFY", + "WM_ENTERMENULOOP", + "WM_EXITMENULOOP", + "WM_NEXTMENU", + "WM_SIZING", + "WM_CAPTURECHANGED", + "WM_MOVING", + "UNKNOWN (535)", + "WM_POWERBROADCAST", + "WM_DEVICECHANGE", + "UNKNOWN (538)", + "UNKNOWN (539)", + "UNKNOWN (540)", + "UNKNOWN (541)", + "UNKNOWN (542)", + "UNKNOWN (543)", + "WM_MDICREATE", + "WM_MDIDESTROY", + "WM_MDIACTIVATE", + "WM_MDIRESTORE", + "WM_MDINEXT", + "WM_MDIMAXIMIZE", + "WM_MDITILE", + "WM_MDICASCADE", + "WM_MDIICONARRANGE", + "WM_MDIGETACTIVE", + "UNKNOWN (554)", + "UNKNOWN (555)", + "UNKNOWN (556)", + "UNKNOWN (557)", + "UNKNOWN (558)", + "UNKNOWN (559)", + "WM_MDISETMENU", + "WM_ENTERSIZEMOVE", + "WM_EXITSIZEMOVE", + "WM_DROPFILES", + "WM_MDIREFRESHMENU", + "UNKNOWN (565)", + "UNKNOWN (566)", + "UNKNOWN (567)", + "UNKNOWN (568)", + "UNKNOWN (569)", + "UNKNOWN (570)", + "UNKNOWN (571)", + "UNKNOWN (572)", + "UNKNOWN (573)", + "UNKNOWN (574)", + "UNKNOWN (575)", + "UNKNOWN (576)", + "UNKNOWN (577)", + "UNKNOWN (578)", + "UNKNOWN (579)", + "UNKNOWN (580)", + "UNKNOWN (581)", + "UNKNOWN (582)", + "UNKNOWN (583)", + "UNKNOWN (584)", + "UNKNOWN (585)", + "UNKNOWN (586)", + "UNKNOWN (587)", + "UNKNOWN (588)", + "UNKNOWN (589)", + "UNKNOWN (590)", + "UNKNOWN (591)", + "UNKNOWN (592)", + "UNKNOWN (593)", + "UNKNOWN (594)", + "UNKNOWN (595)", + "UNKNOWN (596)", + "UNKNOWN (597)", + "UNKNOWN (598)", + "UNKNOWN (599)", + "UNKNOWN (600)", + "UNKNOWN (601)", + "UNKNOWN (602)", + "UNKNOWN (603)", + "UNKNOWN (604)", + "UNKNOWN (605)", + "UNKNOWN (606)", + "UNKNOWN (607)", + "UNKNOWN (608)", + "UNKNOWN (609)", + "UNKNOWN (610)", + "UNKNOWN (611)", + "UNKNOWN (612)", + "UNKNOWN (613)", + "UNKNOWN (614)", + "UNKNOWN (615)", + "UNKNOWN (616)", + "UNKNOWN (617)", + "UNKNOWN (618)", + "UNKNOWN (619)", + "UNKNOWN (620)", + "UNKNOWN (621)", + "UNKNOWN (622)", + "UNKNOWN (623)", + "UNKNOWN (624)", + "UNKNOWN (625)", + "UNKNOWN (626)", + "UNKNOWN (627)", + "UNKNOWN (628)", + "UNKNOWN (629)", + "UNKNOWN (630)", + "UNKNOWN (631)", + "UNKNOWN (632)", + "UNKNOWN (633)", + "UNKNOWN (634)", + "UNKNOWN (635)", + "UNKNOWN (636)", + "UNKNOWN (637)", + "UNKNOWN (638)", + "UNKNOWN (639)", + "UNKNOWN (640)", + "UNKNOWN (641)", + "UNKNOWN (642)", + "UNKNOWN (643)", + "UNKNOWN (644)", + "UNKNOWN (645)", + "UNKNOWN (646)", + "UNKNOWN (647)", + "UNKNOWN (648)", + "UNKNOWN (649)", + "UNKNOWN (650)", + "UNKNOWN (651)", + "UNKNOWN (652)", + "UNKNOWN (653)", + "UNKNOWN (654)", + "UNKNOWN (655)", + "UNKNOWN (656)", + "UNKNOWN (657)", + "UNKNOWN (658)", + "UNKNOWN (659)", + "UNKNOWN (660)", + "UNKNOWN (661)", + "UNKNOWN (662)", + "UNKNOWN (663)", + "UNKNOWN (664)", + "UNKNOWN (665)", + "UNKNOWN (666)", + "UNKNOWN (667)", + "UNKNOWN (668)", + "UNKNOWN (669)", + "UNKNOWN (670)", + "UNKNOWN (671)", + "UNKNOWN (672)", + "WM_MOUSEHOVER", + "UNKNOWN (674)", + "WM_MOUSELEAVE", + "UNKNOWN (676)", + "UNKNOWN (677)", + "UNKNOWN (678)", + "UNKNOWN (679)", + "UNKNOWN (680)", + "UNKNOWN (681)", + "UNKNOWN (682)", + "UNKNOWN (683)", + "UNKNOWN (684)", + "UNKNOWN (685)", + "UNKNOWN (686)", + "UNKNOWN (687)", + "UNKNOWN (688)", + "UNKNOWN (689)", + "UNKNOWN (690)", + "UNKNOWN (691)", + "UNKNOWN (692)", + "UNKNOWN (693)", + "UNKNOWN (694)", + "UNKNOWN (695)", + "UNKNOWN (696)", + "UNKNOWN (697)", + "UNKNOWN (698)", + "UNKNOWN (699)", + "UNKNOWN (700)", + "UNKNOWN (701)", + "UNKNOWN (702)", + "UNKNOWN (703)", + "UNKNOWN (704)", + "UNKNOWN (705)", + "UNKNOWN (706)", + "UNKNOWN (707)", + "UNKNOWN (708)", + "UNKNOWN (709)", + "UNKNOWN (710)", + "UNKNOWN (711)", + "UNKNOWN (712)", + "UNKNOWN (713)", + "UNKNOWN (714)", + "UNKNOWN (715)", + "UNKNOWN (716)", + "UNKNOWN (717)", + "UNKNOWN (718)", + "UNKNOWN (719)", + "UNKNOWN (720)", + "UNKNOWN (721)", + "UNKNOWN (722)", + "UNKNOWN (723)", + "UNKNOWN (724)", + "UNKNOWN (725)", + "UNKNOWN (726)", + "UNKNOWN (727)", + "UNKNOWN (728)", + "UNKNOWN (729)", + "UNKNOWN (730)", + "UNKNOWN (731)", + "UNKNOWN (732)", + "UNKNOWN (733)", + "UNKNOWN (734)", + "UNKNOWN (735)", + "UNKNOWN (736)", + "UNKNOWN (737)", + "UNKNOWN (738)", + "UNKNOWN (739)", + "UNKNOWN (740)", + "UNKNOWN (741)", + "UNKNOWN (742)", + "UNKNOWN (743)", + "UNKNOWN (744)", + "UNKNOWN (745)", + "UNKNOWN (746)", + "UNKNOWN (747)", + "UNKNOWN (748)", + "UNKNOWN (749)", + "UNKNOWN (750)", + "UNKNOWN (751)", + "UNKNOWN (752)", + "UNKNOWN (753)", + "UNKNOWN (754)", + "UNKNOWN (755)", + "UNKNOWN (756)", + "UNKNOWN (757)", + "UNKNOWN (758)", + "UNKNOWN (759)", + "UNKNOWN (760)", + "UNKNOWN (761)", + "UNKNOWN (762)", + "UNKNOWN (763)", + "UNKNOWN (764)", + "UNKNOWN (765)", + "UNKNOWN (766)", + "UNKNOWN (767)", + "WM_CUT", + "WM_COPY", + "WM_PASTE", + "WM_CLEAR", + "WM_UNDO", + "WM_RENDERFORMAT", + "WM_RENDERALLFORMATS", + "WM_DESTROYCLIPBOARD", + "WM_DRAWCLIPBOARD", + "WM_PAINTCLIPBOARD", + "WM_VSCROLLCLIPBOARD", + "WM_SIZECLIPBOARD", + "WM_ASKCBFORMATNAME", + "WM_CHANGECBCHAIN", + "WM_HSCROLLCLIPBOARD", + "WM_QUERYNEWPALETTE", + "WM_PALETTEISCHANGING", + "WM_PALETTECHANGED", + "WM_HOTKEY", + "UNKNOWN (787)", + "UNKNOWN (788)", + "UNKNOWN (789)", + "UNKNOWN (790)", + "WM_PRINT", + "WM_PRINTCLIENT", + "UNKNOWN (793)", + "UNKNOWN (794)", + "UNKNOWN (795)", + "UNKNOWN (796)", + "UNKNOWN (797)", + "UNKNOWN (798)", + "UNKNOWN (799)", + "UNKNOWN (800)", + "UNKNOWN (801)", + "UNKNOWN (802)", + "UNKNOWN (803)", + "UNKNOWN (804)", + "UNKNOWN (805)", + "UNKNOWN (806)", + "UNKNOWN (807)", + "UNKNOWN (808)", + "UNKNOWN (809)", + "UNKNOWN (810)", + "UNKNOWN (811)", + "UNKNOWN (812)", + "UNKNOWN (813)", + "UNKNOWN (814)", + "UNKNOWN (815)", + "UNKNOWN (816)", + "UNKNOWN (817)", + "UNKNOWN (818)", + "UNKNOWN (819)", + "UNKNOWN (820)", + "UNKNOWN (821)", + "UNKNOWN (822)", + "UNKNOWN (823)", + "UNKNOWN (824)", + "UNKNOWN (825)", + "UNKNOWN (826)", + "UNKNOWN (827)", + "UNKNOWN (828)", + "UNKNOWN (829)", + "UNKNOWN (830)", + "UNKNOWN (831)", + "UNKNOWN (832)", + "UNKNOWN (833)", + "UNKNOWN (834)", + "UNKNOWN (835)", + "UNKNOWN (836)", + "UNKNOWN (837)", + "UNKNOWN (838)", + "UNKNOWN (839)", + "UNKNOWN (840)", + "UNKNOWN (841)", + "UNKNOWN (842)", + "UNKNOWN (843)", + "UNKNOWN (844)", + "UNKNOWN (845)", + "UNKNOWN (846)", + "UNKNOWN (847)", + "UNKNOWN (848)", + "UNKNOWN (849)", + "UNKNOWN (850)", + "UNKNOWN (851)", + "UNKNOWN (852)", + "UNKNOWN (853)", + "UNKNOWN (854)", + "UNKNOWN (855)", + "WM_HANDHELDFIRST", + "UNKNOWN (857)", + "UNKNOWN (858)", + "UNKNOWN (859)", + "UNKNOWN (860)", + "UNKNOWN (861)", + "UNKNOWN (862)", + "WM_HANDHELDLAST", + "WM_AFXFIRST", + "UNKNOWN (865)", + "UNKNOWN (866)", + "UNKNOWN (867)", + "UNKNOWN (868)", + "UNKNOWN (869)", + "UNKNOWN (870)", + "UNKNOWN (871)", + "UNKNOWN (872)", + "UNKNOWN (873)", + "UNKNOWN (874)", + "UNKNOWN (875)", + "UNKNOWN (876)", + "UNKNOWN (877)", + "UNKNOWN (878)", + "UNKNOWN (879)", + "UNKNOWN (880)", + "UNKNOWN (881)", + "UNKNOWN (882)", + "UNKNOWN (883)", + "UNKNOWN (884)", + "UNKNOWN (885)", + "UNKNOWN (886)", + "UNKNOWN (887)", + "UNKNOWN (888)", + "UNKNOWN (889)", + "UNKNOWN (890)", + "UNKNOWN (891)", + "UNKNOWN (892)", + "UNKNOWN (893)", + "UNKNOWN (894)", + "WM_AFXLAST", + "WM_PENWINFIRST", + "UNKNOWN (897)", + "UNKNOWN (898)", + "UNKNOWN (899)", + "UNKNOWN (900)", + "UNKNOWN (901)", + "UNKNOWN (902)", + "UNKNOWN (903)", + "UNKNOWN (904)", + "UNKNOWN (905)", + "UNKNOWN (906)", + "UNKNOWN (907)", + "UNKNOWN (908)", + "UNKNOWN (909)", + "UNKNOWN (910)", + "WM_PENWINLAST", + "UNKNOWN (912)", + "UNKNOWN (913)", + "UNKNOWN (914)", + "UNKNOWN (915)", + "UNKNOWN (916)", + "UNKNOWN (917)", + "UNKNOWN (918)", + "UNKNOWN (919)", + "UNKNOWN (920)", + "UNKNOWN (921)", + "UNKNOWN (922)", + "UNKNOWN (923)", + "UNKNOWN (924)", + "UNKNOWN (925)", + "UNKNOWN (926)", + "UNKNOWN (927)", + "UNKNOWN (928)", + "UNKNOWN (929)", + "UNKNOWN (930)", + "UNKNOWN (931)", + "UNKNOWN (932)", + "UNKNOWN (933)", + "UNKNOWN (934)", + "UNKNOWN (935)", + "UNKNOWN (936)", + "UNKNOWN (937)", + "UNKNOWN (938)", + "UNKNOWN (939)", + "UNKNOWN (940)", + "UNKNOWN (941)", + "UNKNOWN (942)", + "UNKNOWN (943)", + "UNKNOWN (944)", + "UNKNOWN (945)", + "UNKNOWN (946)", + "UNKNOWN (947)", + "UNKNOWN (948)", + "UNKNOWN (949)", + "UNKNOWN (950)", + "UNKNOWN (951)", + "UNKNOWN (952)", + "UNKNOWN (953)", + "UNKNOWN (954)", + "UNKNOWN (955)", + "UNKNOWN (956)", + "UNKNOWN (957)", + "UNKNOWN (958)", + "UNKNOWN (959)", + "UNKNOWN (960)", + "UNKNOWN (961)", + "UNKNOWN (962)", + "UNKNOWN (963)", + "UNKNOWN (964)", + "UNKNOWN (965)", + "UNKNOWN (966)", + "UNKNOWN (967)", + "UNKNOWN (968)", + "UNKNOWN (969)", + "UNKNOWN (970)", + "UNKNOWN (971)", + "UNKNOWN (972)", + "UNKNOWN (973)", + "UNKNOWN (974)", + "UNKNOWN (975)", + "UNKNOWN (976)", + "UNKNOWN (977)", + "UNKNOWN (978)", + "UNKNOWN (979)", + "UNKNOWN (980)", + "UNKNOWN (981)", + "UNKNOWN (982)", + "UNKNOWN (983)", + "UNKNOWN (984)", + "UNKNOWN (985)", + "UNKNOWN (986)", + "UNKNOWN (987)", + "UNKNOWN (988)", + "UNKNOWN (989)", + "UNKNOWN (990)", + "UNKNOWN (991)", + "UNKNOWN (992)", + "UNKNOWN (993)", + "UNKNOWN (994)", + "UNKNOWN (995)", + "UNKNOWN (996)", + "UNKNOWN (997)", + "UNKNOWN (998)", + "UNKNOWN (999)", + "UNKNOWN (1000)", + "UNKNOWN (1001)", + "UNKNOWN (1002)", + "UNKNOWN (1003)", + "UNKNOWN (1004)", + "UNKNOWN (1005)", + "UNKNOWN (1006)", + "UNKNOWN (1007)", + "UNKNOWN (1008)", + "UNKNOWN (1009)", + "UNKNOWN (1010)", + "UNKNOWN (1011)", + "UNKNOWN (1012)", + "UNKNOWN (1013)", + "UNKNOWN (1014)", + "UNKNOWN (1015)", + "UNKNOWN (1016)", + "UNKNOWN (1017)", + "UNKNOWN (1018)", + "UNKNOWN (1019)", + "UNKNOWN (1020)", + "UNKNOWN (1021)", + "UNKNOWN (1022)", + "UNKNOWN (1023)", + "WM_USER" +}; + +/* vi: set ts=4 sw=4 expandtab: */ diff --git a/test/graywin.c b/test/graywin.c index 9d7c939f2..8872f82c9 100644 --- a/test/graywin.c +++ b/test/graywin.c @@ -228,8 +228,11 @@ main(int argc, char *argv[]) DrawBackground(screen); break; case SDL_VIDEORESIZE: - screen = CreateScreen(event.resize.w, event.resize.h, - screen->format->BitsPerPixel, videoflags); + printf("Screen resized to %dx%d\n", event.resize.w, + event.resize.h); + screen = + CreateScreen(event.resize.w, event.resize.h, + screen->format->BitsPerPixel, videoflags); if (screen == NULL) { fprintf(stderr, "Couldn't resize video mode\n"); done = 1; diff --git a/test/testsprite2.c b/test/testsprite2.c index b83edd1dd..703c246e3 100644 --- a/test/testsprite2.c +++ b/test/testsprite2.c @@ -5,11 +5,12 @@ #include "SDL.h" -#define NUM_WINDOWS 2 +#define NUM_WINDOWS 4 #define WINDOW_W 640 #define WINDOW_H 480 #define NUM_SPRITES 100 #define MAX_SPEED 1 +#define BACKGROUND 0x00FFFFFF static int num_windows; static int num_sprites; @@ -85,13 +86,15 @@ MoveSprites(SDL_WindowID window, SDL_TextureID sprite) SDL_SelectRenderer(window); - SDL_RenderFill(NULL, 0); - /* Query the sizes */ SDL_GetWindowSize(window, &window_w, &window_h); /* Move the sprite, bounce at the wall, and draw */ n = 0; + for (i = 0; i < num_sprites; ++i) { + position = &positions[i]; + SDL_RenderFill(position, BACKGROUND); + } for (i = 0; i < num_sprites; ++i) { position = &positions[i]; velocity = &velocities[i]; @@ -168,7 +171,8 @@ main(int argc, char *argv[]) SDL_snprintf(title, sizeof(title), "testsprite %d", i + 1); windows[i] = - SDL_CreateWindow(title, -1, -1, window_w, window_h, + SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, window_w, window_h, SDL_WINDOW_SHOWN); if (!windows[i]) { fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError()); @@ -179,6 +183,7 @@ main(int argc, char *argv[]) fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError()); quit(2); } + SDL_RenderFill(NULL, BACKGROUND); } if (LoadSprite("icon.bmp") < 0) { quit(2); @@ -214,6 +219,17 @@ main(int argc, char *argv[]) ++frames; while (SDL_PollEvent(&event)) { switch (event.type) { + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_EXPOSED: + SDL_SelectRenderer(event.window.windowID); + SDL_RenderFill(NULL, BACKGROUND); + break; + case SDL_WINDOWEVENT_CLOSE: + done = 1; + break; + } + break; case SDL_KEYDOWN: /* Any keypress quits the app... */ case SDL_QUIT: diff --git a/test/testwm.c b/test/testwm.c index 60e8dfa6d..299cb93bc 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -176,7 +176,7 @@ HotKey_Quit(void) } int SDLCALL -FilterEvents(SDL_Event * event) +FilterEvents(void *userdata, SDL_Event * event) { static int reallyquit = 0; @@ -344,7 +344,7 @@ main(int argc, char *argv[]) } /* Set an event filter that discards everything but QUIT */ - SDL_SetEventFilter(FilterEvents); + SDL_SetEventFilter(FilterEvents, NULL); /* Ignore key up events, they don't even get filtered */ SDL_EventState(SDL_KEYUP, SDL_IGNORE); diff --git a/test/threadwin.c b/test/threadwin.c index edfc10755..f6ce62112 100644 --- a/test/threadwin.c +++ b/test/threadwin.c @@ -80,7 +80,7 @@ LoadIconSurface(char *file, Uint8 ** maskp) } int SDLCALL -FilterEvents(SDL_Event * event) +FilterEvents(void *userdata, SDL_Event * event) { static int reallyquit = 0; @@ -296,7 +296,7 @@ main(int argc, char *argv[]) SDL_EnableUNICODE(1); /* Set an event filter that discards everything but QUIT */ - SDL_SetEventFilter(FilterEvents); + SDL_SetEventFilter(FilterEvents, NULL); /* Create the event handling threads */ mouse_thread = SDL_CreateThread(HandleMouse, NULL);