# HG changeset patch # User Sam Lantinga # Date 997359692 0 # Node ID 29a638dc26dbb64d34d8e6ae5a3f493c2f2331f2 # Parent 1cfa4282f2eb69ce99d256db883a29a9f9136743 Applied David MacCormack's patch to fix SDL_WINDOWID on Windows, and added a function to cache the application handle so DirectInput still works properly. diff -r 1cfa4282f2eb -r 29a638dc26db include/SDL_main.h --- a/include/SDL_main.h Thu Aug 09 06:14:06 2001 +0000 +++ b/include/SDL_main.h Thu Aug 09 12:21:32 2001 +0000 @@ -64,7 +64,9 @@ #endif /* This should be called from your WinMain() function, if any */ -extern DECLSPEC int SDL_RegisterApp(char *name, Uint32 style, void *hInst); +extern DECLSPEC void SDL_SetModuleHandle(HMODULE hInst); +/* This can also be called, but is no longer necessary */ +extern DECLSPEC int SDL_RegisterApp(char *name, Uint32 style, HMODULE hInst); #ifdef __cplusplus } diff -r 1cfa4282f2eb -r 29a638dc26db src/main/win32/SDL_main.c --- a/src/main/win32/SDL_main.c Thu Aug 09 06:14:06 2001 +0000 +++ b/src/main/win32/SDL_main.c Thu Aug 09 12:21:32 2001 +0000 @@ -199,12 +199,16 @@ atexit(SDL_Quit); #ifndef DISABLE_VIDEO - /* Create and register our class */ + /* Create and register our class * + DJM: If we do this here, the user nevers gets a chance to + putenv(SDL_WINDOWID). This is already called later by + the (DIB|DX5)_CreateWindow function, so it should be + safe to comment it out here. if ( SDL_RegisterApp(appname, CS_BYTEALIGNCLIENT, GetModuleHandle(NULL)) < 0 ) { ShowError("WinMain() error", SDL_GetError()); exit(1); - } + }*/ #endif /* !DISABLE_VIDEO */ /* Run the application main() code */ diff -r 1cfa4282f2eb -r 29a638dc26db src/main/win32/exports/SDL.def --- a/src/main/win32/exports/SDL.def Thu Aug 09 06:14:06 2001 +0000 +++ b/src/main/win32/exports/SDL.def Thu Aug 09 12:21:32 2001 +0000 @@ -174,4 +174,6 @@ SDL_WM_IconifyWindow SDL_WM_ToggleFullScreen SDL_WM_GrabInput + SDL_SoftStretch SDL_RegisterApp + SDL_SetModuleHandle diff -r 1cfa4282f2eb -r 29a638dc26db src/main/win32/exports/gendef.pl --- a/src/main/win32/exports/gendef.pl Thu Aug 09 06:14:06 2001 +0000 +++ b/src/main/win32/exports/gendef.pl Thu Aug 09 12:21:32 2001 +0000 @@ -20,3 +20,4 @@ } # Special exports not in the header files print "\tSDL_RegisterApp\n"; +print "\tSDL_SetModuleHandle\n"; diff -r 1cfa4282f2eb -r 29a638dc26db src/video/wincommon/SDL_lowvideo.h --- a/src/video/wincommon/SDL_lowvideo.h Thu Aug 09 06:14:06 2001 +0000 +++ b/src/video/wincommon/SDL_lowvideo.h Thu Aug 09 12:21:32 2001 +0000 @@ -87,4 +87,8 @@ /* This is really from SDL_dx5audio.c */ extern void DX5_SoundFocus(HWND window); +/* DJM: This is really from SDL_sysevents.c, we need it in + GDL_CreateWindow as well */ +LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + #endif /* SDL_lowvideo_h */ diff -r 1cfa4282f2eb -r 29a638dc26db src/video/wincommon/SDL_sysevents.c --- a/src/video/wincommon/SDL_sysevents.c Thu Aug 09 06:14:06 2001 +0000 +++ b/src/video/wincommon/SDL_sysevents.c Thu Aug 09 12:21:32 2001 +0000 @@ -145,8 +145,10 @@ #endif /* !NO_GETKEYBOARDSTATE */ } -/* The main Win32 event handler */ -static LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +/* The main Win32 event handler +DJM: This is no longer static as (DX5/DIB)_CreateWindow needs it +*/ +LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { SDL_VideoDevice *this = current_video; static int mouse_pressed = 0; @@ -265,6 +267,13 @@ Sint16 x, y; Uint8 button, state; + /* DJM: + We want the SDL window to take focus so that + it acts like a normal windows "component" + (e.g. gains keyboard focus on a mouse click). + */ + SetFocus(SDL_Window); + /* Figure out which button to use */ switch (msg) { case WM_LBUTTONDOWN: @@ -465,10 +474,11 @@ } return(0); + /* DJM: Send an expose event in this case */ case WM_ERASEBKGND: { - /* Just do nothing */ ; + posted = SDL_PrivateExpose(); } - return(1); + return(0); case WM_CLOSE: { if ( (posted = SDL_PrivateQuit()) ) @@ -493,11 +503,35 @@ return(DefWindowProc(hwnd, msg, wParam, lParam)); } +/* Allow the application handle to be stored and retrieved later */ +static HMODULE SDL_handle = NULL; + +void SDL_SetModuleHandle(HMODULE handle) +{ + SDL_handle = handle; +} +HMODULE SDL_GetModuleHandle(void) +{ + void *handle; + + if ( SDL_handle ) { + handle = SDL_handle; + } else { + /* Warning: + If SDL is built as a DLL, this will return a handle to + the DLL, not the application, and DirectInput may fail + to initialize. + */ + handle = GetModuleHandle(NULL); + } + return(handle); +} + /* This allows the SDL_WINDOWID hack */ const char *SDL_windowid = NULL; /* Register the class for this application -- exported for winmain.c */ -int SDL_RegisterApp(char *name, Uint32 style, void *hInst) +int SDL_RegisterApp(char *name, Uint32 style, HMODULE hInst) { static int initialized = 0; WNDCLASS class; @@ -511,12 +545,10 @@ } /* This function needs to be passed the correct process handle - by the application. The following call just returns a handle - to the SDL DLL, which is useless for our purposes and causes - DirectInput to fail to initialize. + by the application. */ if ( ! hInst ) { - hInst = GetModuleHandle(NULL); + hInst = SDL_GetModuleHandle(); } /* Register the application class */ diff -r 1cfa4282f2eb -r 29a638dc26db src/video/windib/SDL_dibevents.c --- a/src/video/windib/SDL_dibevents.c Thu Aug 09 06:14:06 2001 +0000 +++ b/src/video/windib/SDL_dibevents.c Thu Aug 09 12:21:32 2001 +0000 @@ -54,6 +54,10 @@ #define REPEATED_KEYMASK (1<<30) #define EXTENDED_KEYMASK (1<<24) +/* DJM: If the user setup the window for us, we want to save his window proc, + and give him a chance to handle some messages. */ +static WNDPROC userWindowProc = NULL; + /* The main Win32 event handler */ LONG DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -150,6 +154,13 @@ wmmsg.wParam = wParam; wmmsg.lParam = lParam; posted = SDL_PrivateSysWMEvent(&wmmsg); + + /* DJM: If the user isn't watching for private + messages in her SDL event loop, then pass it + along to any win32 specific window proc. + */ + } else if (userWindowProc) { + return userWindowProc(hwnd, msg, wParam, lParam); } } break; @@ -339,6 +350,14 @@ SDL_RegisterApp("SDL_app", CS_BYTEALIGNCLIENT, 0); if ( SDL_windowid ) { SDL_Window = (HWND)strtol(SDL_windowid, NULL, 0); + + /* DJM: we want all event's for the user specified + window to be handled by SDL. + */ + if (SDL_Window) { + userWindowProc = (WNDPROC)GetWindowLong(SDL_Window, GWL_WNDPROC); + SetWindowLong(SDL_Window, GWL_WNDPROC, (LONG)WinMessage); + } } else { SDL_Window = CreateWindow(SDL_Appname, SDL_Appname, (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX), diff -r 1cfa4282f2eb -r 29a638dc26db src/video/windib/SDL_dibvideo.c --- a/src/video/windib/SDL_dibvideo.c Thu Aug 09 06:14:06 2001 +0000 +++ b/src/video/windib/SDL_dibvideo.c Thu Aug 09 12:21:32 2001 +0000 @@ -574,7 +574,10 @@ if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE; #endif } - SetWindowLong(SDL_Window, GWL_STYLE, style); + + /* DJM: Don't piss of anyone who has setup his own window */ + if (!SDL_windowid) + SetWindowLong(SDL_Window, GWL_STYLE, style); /* Delete the old bitmap if necessary */ if ( screen_bmp != NULL ) { diff -r 1cfa4282f2eb -r 29a638dc26db src/video/windx5/SDL_dx5events.c --- a/src/video/windx5/SDL_dx5events.c Thu Aug 09 06:14:06 2001 +0000 +++ b/src/video/windx5/SDL_dx5events.c Thu Aug 09 12:21:32 2001 +0000 @@ -59,6 +59,10 @@ static SDLKey DIK_keymap[256]; static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed); +/* DJM: If the user setup the window for us, we want to save his window proc, + and give him a chance to handle some messages. */ +static WNDPROC userWindowProc = NULL; + /* Convert a DirectInput return code to a text message */ static void SetDIerror(char *function, int code) { @@ -509,7 +513,14 @@ wmmsg.wParam = wParam; wmmsg.lParam = lParam; posted = SDL_PrivateSysWMEvent(&wmmsg); - } + + /* DJM: If the user isn't watching for private messages in her + SDL event loop, then pass it along to any win32 specific + window proc. + */ + } else if (userWindowProc) { + return userWindowProc(hwnd, msg, wParam, lParam); + } } break; } @@ -764,6 +775,14 @@ SDL_RegisterApp("SDL_app", CS_BYTEALIGNCLIENT, 0); if ( SDL_windowid ) { SDL_Window = (HWND)strtol(SDL_windowid, NULL, 0); + + /* DJM: we want all event's for the user specified + window to be handled by SDL. + */ + if (SDL_Window) { + userWindowProc = (WNDPROC)GetWindowLong(SDL_Window, GWL_WNDPROC); + SetWindowLong(SDL_Window, GWL_WNDPROC, (LONG)WinMessage); + } } else { SDL_Window = CreateWindow(SDL_Appname, SDL_Appname, (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),