Applied David MacCormack's patch to fix SDL_WINDOWID on Windows,
authorSam Lantinga <slouken@libsdl.org>
Thu, 09 Aug 2001 12:21:32 +0000
changeset 14529a638dc26db
parent 144 1cfa4282f2eb
child 146 ddd322dba625
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.
include/SDL_main.h
src/main/win32/SDL_main.c
src/main/win32/exports/SDL.def
src/main/win32/exports/gendef.pl
src/video/wincommon/SDL_lowvideo.h
src/video/wincommon/SDL_sysevents.c
src/video/windib/SDL_dibevents.c
src/video/windib/SDL_dibvideo.c
src/video/windx5/SDL_dx5events.c
     1.1 --- a/include/SDL_main.h	Thu Aug 09 06:14:06 2001 +0000
     1.2 +++ b/include/SDL_main.h	Thu Aug 09 12:21:32 2001 +0000
     1.3 @@ -64,7 +64,9 @@
     1.4  #endif
     1.5  
     1.6  /* This should be called from your WinMain() function, if any */
     1.7 -extern DECLSPEC int SDL_RegisterApp(char *name, Uint32 style, void *hInst);
     1.8 +extern DECLSPEC void SDL_SetModuleHandle(HMODULE hInst);
     1.9 +/* This can also be called, but is no longer necessary */
    1.10 +extern DECLSPEC int SDL_RegisterApp(char *name, Uint32 style, HMODULE hInst);
    1.11  
    1.12  #ifdef __cplusplus
    1.13  }
     2.1 --- a/src/main/win32/SDL_main.c	Thu Aug 09 06:14:06 2001 +0000
     2.2 +++ b/src/main/win32/SDL_main.c	Thu Aug 09 12:21:32 2001 +0000
     2.3 @@ -199,12 +199,16 @@
     2.4  	atexit(SDL_Quit);
     2.5  
     2.6  #ifndef DISABLE_VIDEO
     2.7 -	/* Create and register our class */
     2.8 +	/* Create and register our class *
     2.9 +      DJM: If we do this here, the user nevers gets a chance to
    2.10 +      putenv(SDL_WINDOWID).  This is already called later by
    2.11 +      the (DIB|DX5)_CreateWindow function, so it should be
    2.12 +      safe to comment it out here.
    2.13  	if ( SDL_RegisterApp(appname, CS_BYTEALIGNCLIENT, 
    2.14  	                     GetModuleHandle(NULL)) < 0 ) {
    2.15  		ShowError("WinMain() error", SDL_GetError());
    2.16  		exit(1);
    2.17 -	}
    2.18 +	}*/
    2.19  #endif /* !DISABLE_VIDEO */
    2.20  
    2.21  	/* Run the application main() code */
     3.1 --- a/src/main/win32/exports/SDL.def	Thu Aug 09 06:14:06 2001 +0000
     3.2 +++ b/src/main/win32/exports/SDL.def	Thu Aug 09 12:21:32 2001 +0000
     3.3 @@ -174,4 +174,6 @@
     3.4  	SDL_WM_IconifyWindow
     3.5  	SDL_WM_ToggleFullScreen
     3.6  	SDL_WM_GrabInput
     3.7 +	SDL_SoftStretch
     3.8  	SDL_RegisterApp
     3.9 +	SDL_SetModuleHandle
     4.1 --- a/src/main/win32/exports/gendef.pl	Thu Aug 09 06:14:06 2001 +0000
     4.2 +++ b/src/main/win32/exports/gendef.pl	Thu Aug 09 12:21:32 2001 +0000
     4.3 @@ -20,3 +20,4 @@
     4.4  }
     4.5  # Special exports not in the header files
     4.6  print "\tSDL_RegisterApp\n";
     4.7 +print "\tSDL_SetModuleHandle\n";
     5.1 --- a/src/video/wincommon/SDL_lowvideo.h	Thu Aug 09 06:14:06 2001 +0000
     5.2 +++ b/src/video/wincommon/SDL_lowvideo.h	Thu Aug 09 12:21:32 2001 +0000
     5.3 @@ -87,4 +87,8 @@
     5.4  /* This is really from SDL_dx5audio.c */
     5.5  extern void DX5_SoundFocus(HWND window);
     5.6  
     5.7 +/* DJM: This is really from SDL_sysevents.c, we need it in
     5.8 +   GDL_CreateWindow as well */
     5.9 +LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    5.10 +
    5.11  #endif /* SDL_lowvideo_h */
     6.1 --- a/src/video/wincommon/SDL_sysevents.c	Thu Aug 09 06:14:06 2001 +0000
     6.2 +++ b/src/video/wincommon/SDL_sysevents.c	Thu Aug 09 12:21:32 2001 +0000
     6.3 @@ -145,8 +145,10 @@
     6.4  #endif /* !NO_GETKEYBOARDSTATE */
     6.5  }
     6.6  
     6.7 -/* The main Win32 event handler */
     6.8 -static LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
     6.9 +/* The main Win32 event handler
    6.10 +DJM: This is no longer static as (DX5/DIB)_CreateWindow needs it
    6.11 +*/
    6.12 +LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    6.13  {
    6.14  	SDL_VideoDevice *this = current_video;
    6.15  	static int mouse_pressed = 0;
    6.16 @@ -265,6 +267,13 @@
    6.17  				Sint16 x, y;
    6.18  				Uint8 button, state;
    6.19  
    6.20 +				/* DJM:
    6.21 +				   We want the SDL window to take focus so that
    6.22 +				   it acts like a normal windows "component"
    6.23 +				   (e.g. gains keyboard focus on a mouse click).
    6.24 +				 */
    6.25 +				SetFocus(SDL_Window);
    6.26 +
    6.27  				/* Figure out which button to use */
    6.28  				switch (msg) {
    6.29  					case WM_LBUTTONDOWN:
    6.30 @@ -465,10 +474,11 @@
    6.31  		}
    6.32  		return(0);
    6.33  
    6.34 +		/* DJM: Send an expose event in this case */
    6.35  		case WM_ERASEBKGND: {
    6.36 -			/* Just do nothing */ ;
    6.37 +			posted = SDL_PrivateExpose();
    6.38  		}
    6.39 -		return(1);
    6.40 +		return(0);
    6.41  
    6.42  		case WM_CLOSE: {
    6.43  			if ( (posted = SDL_PrivateQuit()) )
    6.44 @@ -493,11 +503,35 @@
    6.45  	return(DefWindowProc(hwnd, msg, wParam, lParam));
    6.46  }
    6.47  
    6.48 +/* Allow the application handle to be stored and retrieved later */
    6.49 +static HMODULE SDL_handle = NULL;
    6.50 +
    6.51 +void SDL_SetModuleHandle(HMODULE handle)
    6.52 +{
    6.53 +	SDL_handle = handle;
    6.54 +}
    6.55 +HMODULE SDL_GetModuleHandle(void)
    6.56 +{
    6.57 +	void *handle;
    6.58 +
    6.59 +	if ( SDL_handle ) {
    6.60 +		handle = SDL_handle;
    6.61 +	} else {
    6.62 +		/* Warning:
    6.63 +		   If SDL is built as a DLL, this will return a handle to
    6.64 +		   the DLL, not the application, and DirectInput may fail
    6.65 +		   to initialize.
    6.66 +		 */
    6.67 +		handle = GetModuleHandle(NULL);
    6.68 +	}
    6.69 +	return(handle);
    6.70 +}
    6.71 +
    6.72  /* This allows the SDL_WINDOWID hack */
    6.73  const char *SDL_windowid = NULL;
    6.74  
    6.75  /* Register the class for this application -- exported for winmain.c */
    6.76 -int SDL_RegisterApp(char *name, Uint32 style, void *hInst)
    6.77 +int SDL_RegisterApp(char *name, Uint32 style, HMODULE hInst)
    6.78  {
    6.79  	static int initialized = 0;
    6.80  	WNDCLASS class;
    6.81 @@ -511,12 +545,10 @@
    6.82  	}
    6.83  
    6.84  	/* This function needs to be passed the correct process handle
    6.85 -	   by the application.  The following call just returns a handle
    6.86 -	   to the SDL DLL, which is useless for our purposes and causes
    6.87 -	   DirectInput to fail to initialize.
    6.88 +	   by the application.
    6.89  	 */
    6.90  	if ( ! hInst ) {
    6.91 -		hInst = GetModuleHandle(NULL);
    6.92 +		hInst = SDL_GetModuleHandle();
    6.93  	}
    6.94  
    6.95  	/* Register the application class */
     7.1 --- a/src/video/windib/SDL_dibevents.c	Thu Aug 09 06:14:06 2001 +0000
     7.2 +++ b/src/video/windib/SDL_dibevents.c	Thu Aug 09 12:21:32 2001 +0000
     7.3 @@ -54,6 +54,10 @@
     7.4  #define REPEATED_KEYMASK	(1<<30)
     7.5  #define EXTENDED_KEYMASK	(1<<24)
     7.6  
     7.7 +/* DJM: If the user setup the window for us, we want to save his window proc,
     7.8 +   and give him a chance to handle some messages. */
     7.9 +static WNDPROC userWindowProc = NULL;
    7.10 +
    7.11  /* The main Win32 event handler */
    7.12  LONG
    7.13   DIB_HandleMessage(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    7.14 @@ -150,6 +154,13 @@
    7.15  				wmmsg.wParam = wParam;
    7.16  				wmmsg.lParam = lParam;
    7.17  				posted = SDL_PrivateSysWMEvent(&wmmsg);
    7.18 +
    7.19 +			/* DJM: If the user isn't watching for private
    7.20 +				messages in her SDL event loop, then pass it
    7.21 +				along to any win32 specific window proc.
    7.22 +			 */
    7.23 +			} else if (userWindowProc) {
    7.24 +				return userWindowProc(hwnd, msg, wParam, lParam);
    7.25  			}
    7.26  		}
    7.27  		break;
    7.28 @@ -339,6 +350,14 @@
    7.29  	SDL_RegisterApp("SDL_app", CS_BYTEALIGNCLIENT, 0);
    7.30  	if ( SDL_windowid ) {
    7.31  		SDL_Window = (HWND)strtol(SDL_windowid, NULL, 0);
    7.32 +
    7.33 +      /* DJM: we want all event's for the user specified
    7.34 +         window to be handled by SDL.
    7.35 +       */
    7.36 +      if (SDL_Window) {
    7.37 +         userWindowProc = (WNDPROC)GetWindowLong(SDL_Window, GWL_WNDPROC);
    7.38 +         SetWindowLong(SDL_Window, GWL_WNDPROC, (LONG)WinMessage);
    7.39 +      }
    7.40  	} else {
    7.41  		SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
    7.42                          (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),
     8.1 --- a/src/video/windib/SDL_dibvideo.c	Thu Aug 09 06:14:06 2001 +0000
     8.2 +++ b/src/video/windib/SDL_dibvideo.c	Thu Aug 09 12:21:32 2001 +0000
     8.3 @@ -574,7 +574,10 @@
     8.4  		if (IsZoomed(SDL_Window)) style |= WS_MAXIMIZE;
     8.5  #endif
     8.6  	}
     8.7 -	SetWindowLong(SDL_Window, GWL_STYLE, style);
     8.8 +
     8.9 +   /* DJM: Don't piss of anyone who has setup his own window */
    8.10 +   if (!SDL_windowid)
    8.11 +	   SetWindowLong(SDL_Window, GWL_STYLE, style);
    8.12  
    8.13  	/* Delete the old bitmap if necessary */
    8.14  	if ( screen_bmp != NULL ) {
     9.1 --- a/src/video/windx5/SDL_dx5events.c	Thu Aug 09 06:14:06 2001 +0000
     9.2 +++ b/src/video/windx5/SDL_dx5events.c	Thu Aug 09 12:21:32 2001 +0000
     9.3 @@ -59,6 +59,10 @@
     9.4  static SDLKey DIK_keymap[256];
     9.5  static SDL_keysym *TranslateKey(UINT scancode, SDL_keysym *keysym, int pressed);
     9.6  
     9.7 +/* DJM: If the user setup the window for us, we want to save his window proc,
     9.8 +   and give him a chance to handle some messages. */
     9.9 +static WNDPROC userWindowProc = NULL;
    9.10 +
    9.11  /* Convert a DirectInput return code to a text message */
    9.12  static void SetDIerror(char *function, int code)
    9.13  {
    9.14 @@ -509,7 +513,14 @@
    9.15  				wmmsg.wParam = wParam;
    9.16  				wmmsg.lParam = lParam;
    9.17  				posted = SDL_PrivateSysWMEvent(&wmmsg);
    9.18 -			}
    9.19 +
    9.20 +         /* DJM: If the user isn't watching for private messages in her
    9.21 +            SDL event loop, then pass it along to any win32 specific
    9.22 +            window proc.
    9.23 +          */
    9.24 +         } else if (userWindowProc) {
    9.25 +            return userWindowProc(hwnd, msg, wParam, lParam);
    9.26 +         }
    9.27  		}
    9.28  		break;
    9.29  	}
    9.30 @@ -764,6 +775,14 @@
    9.31  	SDL_RegisterApp("SDL_app", CS_BYTEALIGNCLIENT, 0);
    9.32  	if ( SDL_windowid ) {
    9.33  		SDL_Window = (HWND)strtol(SDL_windowid, NULL, 0);
    9.34 +
    9.35 +      /* DJM: we want all event's for the user specified
    9.36 +         window to be handled by SDL.
    9.37 +       */
    9.38 +      if (SDL_Window) {
    9.39 +         userWindowProc = (WNDPROC)GetWindowLong(SDL_Window, GWL_WNDPROC);
    9.40 +         SetWindowLong(SDL_Window, GWL_WNDPROC, (LONG)WinMessage);
    9.41 +      }
    9.42  	} else {
    9.43  		SDL_Window = CreateWindow(SDL_Appname, SDL_Appname,
    9.44                          (WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX),