src/video/wincommon/SDL_sysevents.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 09 Apr 2002 23:32:40 +0000
changeset 333 f2ba51f64d49
parent 332 3d6dd1b7b7ba
child 335 bc4d50d2edd9
permissions -rw-r--r--
Fixed a crash bug in the WM_ACTIVATE code (thanks John!)
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997, 1998, 1999  Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 #include <stdlib.h>
    29 #include <stdio.h>
    30 #include <windows.h>
    31 
    32 #include "SDL_getenv.h"
    33 #include "SDL_events.h"
    34 #include "SDL_video.h"
    35 #include "SDL_error.h"
    36 #include "SDL_syswm.h"
    37 #include "SDL_sysevents.h"
    38 #include "SDL_events_c.h"
    39 #include "SDL_sysvideo.h"
    40 #include "SDL_lowvideo.h"
    41 #include "SDL_syswm_c.h"
    42 #include "SDL_main.h"
    43 
    44 #ifdef WMMSG_DEBUG
    45 #include "wmmsg.h"
    46 #endif
    47 
    48 #ifdef _WIN32_WCE
    49 #define NO_GETKEYBOARDSTATE
    50 #endif
    51 
    52 /* The window we use for everything... */
    53 const char *SDL_Appname = NULL;
    54 HINSTANCE SDL_Instance = NULL;
    55 HWND SDL_Window = NULL;
    56 RECT SDL_bounds = {0, 0, 0, 0};
    57 int SDL_resizing = 0;
    58 int mouse_relative = 0;
    59 int posted = 0;
    60 #ifndef NO_CHANGEDISPLAYSETTINGS
    61 DEVMODE SDL_fullscreen_mode;
    62 #endif
    63 
    64 
    65 /* Functions called by the message processing function */
    66 LONG
    67 (*HandleMessage)(_THIS, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)=NULL;
    68 void (*WIN_RealizePalette)(_THIS);
    69 void (*WIN_PaletteChanged)(_THIS, HWND window);
    70 void (*WIN_SwapGamma)(_THIS);
    71 void (*WIN_WinPAINT)(_THIS, HDC hdc);
    72 
    73 static void SDL_RestoreGameMode(void)
    74 {
    75 #ifndef NO_CHANGEDISPLAYSETTINGS
    76 	ShowWindow(SDL_Window, SW_RESTORE);
    77 	ChangeDisplaySettings(&SDL_fullscreen_mode, CDS_FULLSCREEN);
    78 #endif
    79 }
    80 static void SDL_RestoreDesktopMode(void)
    81 {
    82 #ifndef NO_CHANGEDISPLAYSETTINGS
    83 	ShowWindow(SDL_Window, SW_MINIMIZE);
    84 	ChangeDisplaySettings(NULL, 0);
    85 #endif
    86 }
    87 
    88 #ifdef WM_MOUSELEAVE
    89 /* 
    90    Special code to handle mouse leave events - this sucks...
    91    http://support.microsoft.com/support/kb/articles/q183/1/07.asp
    92 
    93    TrackMouseEvent() is only available on Win98 and WinNT.
    94    _TrackMouseEvent() is available on Win95, but isn't yet in the mingw32
    95    development environment, and only works on systems that have had IE 3.0
    96    or newer installed on them (which is not the case with the base Win95).
    97    Therefore, we implement our own version of _TrackMouseEvent() which
    98    uses our own implementation if TrackMouseEvent() is not available.
    99 */
   100 static BOOL (WINAPI *_TrackMouseEvent)(TRACKMOUSEEVENT *ptme) = NULL;
   101 
   102 static VOID CALLBACK
   103 TrackMouseTimerProc(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime)
   104 {
   105 	RECT rect;
   106 	POINT pt;
   107 
   108 	GetClientRect(hWnd, &rect);
   109 	MapWindowPoints(hWnd, NULL, (LPPOINT)&rect, 2);
   110 	GetCursorPos(&pt);
   111 	if ( !PtInRect(&rect, pt) || (WindowFromPoint(pt) != hWnd) ) {
   112 		if ( !KillTimer(hWnd, idEvent) ) {
   113 			/* Error killing the timer! */
   114 		}
   115 		PostMessage(hWnd, WM_MOUSELEAVE, 0, 0);
   116 	}
   117 }
   118 static BOOL WINAPI WIN_TrackMouseEvent(TRACKMOUSEEVENT *ptme)
   119 {
   120 	if ( ptme->dwFlags == TME_LEAVE ) {
   121 		return SetTimer(ptme->hwndTrack, ptme->dwFlags, 100,
   122 		                (TIMERPROC)TrackMouseTimerProc);
   123 	}
   124 	return FALSE;
   125 }
   126 #endif /* WM_MOUSELEAVE */
   127 
   128 /* Function to retrieve the current keyboard modifiers */
   129 static void WIN_GetKeyboardState(void)
   130 {
   131 #ifndef NO_GETKEYBOARDSTATE
   132 	SDLMod state;
   133 	BYTE keyboard[256];
   134 	Uint8 *kstate = SDL_GetKeyState(NULL);
   135 
   136 	state = KMOD_NONE;
   137 	if ( GetKeyboardState(keyboard) ) {
   138 		if ( keyboard[VK_LSHIFT] & 0x80) {
   139 			state |= KMOD_LSHIFT;
   140 		}
   141 		if ( keyboard[VK_RSHIFT] & 0x80) {
   142 			state |= KMOD_RSHIFT;
   143 		}
   144 		if ( keyboard[VK_LCONTROL] & 0x80) {
   145 			state |= KMOD_LCTRL;
   146 		}
   147 		if ( keyboard[VK_RCONTROL] & 0x80) {
   148 			state |= KMOD_RCTRL;
   149 		}
   150 		if ( keyboard[VK_LMENU] & 0x80) {
   151 			state |= KMOD_LALT;
   152 		}
   153 		if ( keyboard[VK_RMENU] & 0x80) {
   154 			state |= KMOD_RALT;
   155 		}
   156 		if ( keyboard[VK_NUMLOCK] & 0x01) {
   157 			state |= KMOD_NUM;
   158 			kstate[SDLK_NUMLOCK] = SDL_PRESSED;
   159 		}
   160 		if ( keyboard[VK_CAPITAL] & 0x01) {
   161 			state |= KMOD_CAPS;
   162 			kstate[SDLK_CAPSLOCK] = SDL_PRESSED;
   163 		}
   164 	}
   165 	SDL_SetModState(state);
   166 #endif /* !NO_GETKEYBOARDSTATE */
   167 }
   168 
   169 /* The main Win32 event handler
   170 DJM: This is no longer static as (DX5/DIB)_CreateWindow needs it
   171 */
   172 LONG CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
   173 {
   174 	SDL_VideoDevice *this = current_video;
   175 	static int mouse_pressed = 0;
   176 	static int in_window = 0;
   177 #ifdef WMMSG_DEBUG
   178 	fprintf(stderr, "Received windows message:  ");
   179 	if ( msg > MAX_WMMSG ) {
   180 		fprintf(stderr, "%d", msg);
   181 	} else {
   182 		fprintf(stderr, "%s", wmtab[msg]);
   183 	}
   184 	fprintf(stderr, " -- 0x%X, 0x%X\n", wParam, lParam);
   185 #endif
   186 	switch (msg) {
   187 
   188 		case WM_ACTIVATE: {
   189 			SDL_VideoDevice *this = current_video;
   190 			BOOL minimized;
   191 			Uint8 appstate;
   192 
   193 			if ( ! this->screen ) {
   194 				/* What do we do when we get the screen? */
   195 				return(0);
   196 			}
   197 			minimized = HIWORD(wParam);
   198 			if ( !minimized && (LOWORD(wParam) != WA_INACTIVE) ) {
   199 				/* Gain the following states */
   200 				appstate = SDL_APPACTIVE|SDL_APPINPUTFOCUS;
   201 				if ( this->input_grab != SDL_GRAB_OFF ) {
   202 					WIN_GrabInput(this, SDL_GRAB_ON);
   203 				}
   204 				if ( !(SDL_GetAppState()&SDL_APPINPUTFOCUS) ) {
   205 					WIN_SwapGamma(this);
   206 					if ( WINDIB_FULLSCREEN() ) {
   207 						SDL_RestoreGameMode();
   208 					}
   209 				}
   210 				posted = SDL_PrivateAppActive(1, appstate);
   211 				WIN_GetKeyboardState();
   212 			} else {
   213 				/* Lose the following states */
   214 				appstate = SDL_APPINPUTFOCUS;
   215 				if ( minimized ) {
   216 					appstate |= SDL_APPACTIVE;
   217 				}
   218 				if ( this->input_grab != SDL_GRAB_OFF ) {
   219 					WIN_GrabInput(this, SDL_GRAB_OFF);
   220 				}
   221 				if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) {
   222 					WIN_SwapGamma(this);
   223 					if ( WINDIB_FULLSCREEN() ) {
   224 						SDL_RestoreDesktopMode();
   225 					}
   226 				}
   227 				posted = SDL_PrivateAppActive(0, appstate);
   228 			}
   229 			return(0);
   230 		}
   231 		break;
   232 
   233 		case WM_MOUSEMOVE: {
   234 			
   235 			/* Mouse is handled by DirectInput when fullscreen */
   236 			if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
   237 				Sint16 x, y;
   238 
   239 				/* mouse has entered the window */
   240 				if ( ! in_window ) {
   241 #ifdef WM_MOUSELEAVE
   242 					TRACKMOUSEEVENT tme;
   243 
   244 					tme.cbSize = sizeof(tme);
   245 					tme.dwFlags = TME_LEAVE;
   246 					tme.hwndTrack = SDL_Window;
   247 					_TrackMouseEvent(&tme);
   248 #endif /* WM_MOUSELEAVE */
   249 					in_window = TRUE;
   250 
   251 					posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
   252 				}
   253 
   254 				/* mouse has moved within the window */
   255 				x = LOWORD(lParam);
   256 				y = HIWORD(lParam);
   257 				if ( mouse_relative ) {
   258 					POINT center;
   259 					center.x = (SDL_VideoSurface->w/2);
   260 					center.y = (SDL_VideoSurface->h/2);
   261 					x -= (Sint16)center.x;
   262 					y -= (Sint16)center.y;
   263 					if ( x || y ) {
   264 						ClientToScreen(SDL_Window, &center);
   265 						SetCursorPos(center.x, center.y);
   266 						posted = SDL_PrivateMouseMotion(0, 1, x, y);
   267 					}
   268 				} else {
   269 					posted = SDL_PrivateMouseMotion(0, 0, x, y);
   270 				}
   271 			}
   272 		}
   273 		return(0);
   274 
   275 #ifdef WM_MOUSELEAVE
   276 		case WM_MOUSELEAVE: {
   277 
   278 			/* Mouse is handled by DirectInput when fullscreen */
   279 			if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
   280 				/* mouse has left the window */
   281 				/* or */
   282 				/* Elvis has left the building! */
   283 				in_window = FALSE;
   284 				posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
   285 			}
   286 		}
   287 		return(0);
   288 #endif /* WM_MOUSELEAVE */
   289 
   290 		case WM_LBUTTONDOWN:
   291 		case WM_LBUTTONUP:
   292 		case WM_MBUTTONDOWN:
   293 		case WM_MBUTTONUP:
   294 		case WM_RBUTTONDOWN:
   295 		case WM_RBUTTONUP: {
   296 			/* Mouse is handled by DirectInput when fullscreen */
   297 			if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
   298 				Sint16 x, y;
   299 				Uint8 button, state;
   300 
   301 				/* DJM:
   302 				   We want the SDL window to take focus so that
   303 				   it acts like a normal windows "component"
   304 				   (e.g. gains keyboard focus on a mouse click).
   305 				 */
   306 				SetFocus(SDL_Window);
   307 
   308 				/* Figure out which button to use */
   309 				switch (msg) {
   310 					case WM_LBUTTONDOWN:
   311 						button = 1;
   312 						state = SDL_PRESSED;
   313 						break;
   314 					case WM_LBUTTONUP:
   315 						button = 1;
   316 						state = SDL_RELEASED;
   317 						break;
   318 					case WM_MBUTTONDOWN:
   319 						button = 2;
   320 						state = SDL_PRESSED;
   321 						break;
   322 					case WM_MBUTTONUP:
   323 						button = 2;
   324 						state = SDL_RELEASED;
   325 						break;
   326 					case WM_RBUTTONDOWN:
   327 						button = 3;
   328 						state = SDL_PRESSED;
   329 						break;
   330 					case WM_RBUTTONUP:
   331 						button = 3;
   332 						state = SDL_RELEASED;
   333 						break;
   334 					default:
   335 						/* Eh? Unknown button? */
   336 						return(0);
   337 				}
   338 				if ( state == SDL_PRESSED ) {
   339 					/* Grab mouse so we get up events */
   340 					if ( ++mouse_pressed > 0 ) {
   341 						SetCapture(hwnd);
   342 					}
   343 				} else {
   344 					/* Release mouse after all up events */
   345 					if ( --mouse_pressed <= 0 ) {
   346 						ReleaseCapture();
   347 						mouse_pressed = 0;
   348 					}
   349 				}
   350 				if ( mouse_relative ) {
   351 				/*	RJR: March 28, 2000
   352 					report internal mouse position if in relative mode */
   353 					x = 0; y = 0;
   354 				} else {
   355 					x = (Sint16)LOWORD(lParam);
   356 					y = (Sint16)HIWORD(lParam);
   357 				}
   358 				posted = SDL_PrivateMouseButton(
   359 							state, button, x, y);
   360 			}
   361 		}
   362 		return(0);
   363 
   364 
   365 #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
   366 		case WM_MOUSEWHEEL: 
   367 			if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
   368 				int move = (short)HIWORD(wParam);
   369 				if ( move ) {
   370 					Uint8 button;
   371 					if ( move > 0 )
   372 						button = 4;
   373 					else
   374 						button = 5;
   375 					posted = SDL_PrivateMouseButton(
   376 						SDL_PRESSED, button, 0, 0);
   377 					posted |= SDL_PrivateMouseButton(
   378 						SDL_RELEASED, button, 0, 0);
   379 				}
   380 			}
   381 			return(0);
   382 #endif
   383 
   384 #ifdef WM_GETMINMAXINFO
   385 		/* This message is sent as a way for us to "check" the values
   386 		 * of a position change.  If we don't like it, we can adjust
   387 		 * the values before they are changed.
   388 		 */
   389 		case WM_GETMINMAXINFO: {
   390 			MINMAXINFO *info;
   391 			RECT        size;
   392 			int x, y;
   393 			int width;
   394 			int height;
   395 
   396 			/* We don't want to clobber an internal resize */
   397 			if ( SDL_resizing )
   398 				return(0);
   399 
   400 			/* We allow resizing with the SDL_RESIZABLE flag */
   401 			if ( SDL_PublicSurface &&
   402 				(SDL_PublicSurface->flags & SDL_RESIZABLE) ) {
   403 				return(0);
   404 			}
   405 
   406 			/* Get the current position of our window */
   407 			GetWindowRect(SDL_Window, &size);
   408 			x = size.left;
   409 			y = size.top;
   410 
   411 			/* Calculate current width and height of our window */
   412 			size.top = 0;
   413 			size.left = 0;
   414 			if ( SDL_PublicSurface != NULL ) {
   415 				size.bottom = SDL_PublicSurface->h;
   416 				size.right = SDL_PublicSurface->w;
   417 			} else {
   418 				size.bottom = 0;
   419 				size.right = 0;
   420 			}
   421 			AdjustWindowRect(&size, GetWindowLong(hwnd, GWL_STYLE),
   422 									FALSE);
   423 			width = size.right - size.left;
   424 			height = size.bottom - size.top;
   425 
   426 			/* Fix our size to the current size */
   427 			info = (MINMAXINFO *)lParam;
   428 			info->ptMaxSize.x = width;
   429 			info->ptMaxSize.y = height;
   430 			info->ptMaxPosition.x = x;
   431 			info->ptMaxPosition.y = y;
   432 			info->ptMinTrackSize.x = width;
   433 			info->ptMinTrackSize.y = height;
   434 			info->ptMaxTrackSize.x = width;
   435 			info->ptMaxTrackSize.y = height;
   436 		}
   437 		return(0);
   438 #endif /* WM_GETMINMAXINFO */
   439 
   440 		case WM_MOVE: {
   441 			SDL_VideoDevice *this = current_video;
   442 
   443 			GetClientRect(SDL_Window, &SDL_bounds);
   444 			ClientToScreen(SDL_Window, (LPPOINT)&SDL_bounds);
   445 			ClientToScreen(SDL_Window, (LPPOINT)&SDL_bounds+1);
   446 			if ( this->input_grab != SDL_GRAB_OFF ) {
   447 				ClipCursor(&SDL_bounds);
   448 			}
   449 		}
   450 		break;
   451 	
   452 		case WM_SIZE: {
   453 			if ( SDL_PublicSurface &&
   454 				(SDL_PublicSurface->flags & SDL_RESIZABLE) ) {
   455 				SDL_PrivateResize(LOWORD(lParam), HIWORD(lParam));
   456 			}
   457 			return(0);
   458 		}
   459 		break;
   460 
   461 		/* We need to set the cursor */
   462 		case WM_SETCURSOR: {
   463 			Uint16 hittest;
   464 
   465 			hittest = LOWORD(lParam);
   466 			if ( hittest == HTCLIENT ) {
   467 				SetCursor(SDL_hcursor);
   468 				return(TRUE);
   469 			}
   470 		}
   471 		break;
   472 
   473 		/* We are about to get palette focus! */
   474 		case WM_QUERYNEWPALETTE: {
   475 			WIN_RealizePalette(current_video);
   476 			return(TRUE);
   477 		}
   478 		break;
   479 
   480 		/* Another application changed the palette */
   481 		case WM_PALETTECHANGED: {
   482 			WIN_PaletteChanged(current_video, (HWND)wParam);
   483 		}
   484 		break;
   485 
   486 		/* We were occluded, refresh our display */
   487 		case WM_PAINT: {
   488 			HDC hdc;
   489 			PAINTSTRUCT ps;
   490 
   491 			hdc = BeginPaint(SDL_Window, &ps);
   492 			if ( current_video->screen &&
   493 			     !(current_video->screen->flags & SDL_OPENGL) ) {
   494 				WIN_WinPAINT(current_video, hdc);
   495 			}
   496 			EndPaint(SDL_Window, &ps);
   497 		}
   498 		return(0);
   499 
   500 		/* DJM: Send an expose event in this case */
   501 		case WM_ERASEBKGND: {
   502 			posted = SDL_PrivateExpose();
   503 		}
   504 		return(0);
   505 
   506 		case WM_CLOSE: {
   507 			if ( (posted = SDL_PrivateQuit()) )
   508 				PostQuitMessage(0);
   509 		}
   510 		return(0);
   511 
   512 		case WM_DESTROY: {
   513 			PostQuitMessage(0);
   514 		}
   515 		return(0);
   516 
   517 		default: {
   518 			/* Special handling by the video driver */
   519 			if (HandleMessage) {
   520 				return(HandleMessage(current_video,
   521 			                     hwnd, msg, wParam, lParam));
   522 			}
   523 		}
   524 		break;
   525 	}
   526 	return(DefWindowProc(hwnd, msg, wParam, lParam));
   527 }
   528 
   529 /* Allow the application handle to be stored and retrieved later */
   530 static void *SDL_handle = NULL;
   531 
   532 void SDL_SetModuleHandle(void *handle)
   533 {
   534 	SDL_handle = handle;
   535 }
   536 void *SDL_GetModuleHandle(void)
   537 {
   538 	void *handle;
   539 
   540 	if ( SDL_handle ) {
   541 		handle = SDL_handle;
   542 	} else {
   543 		/* Warning:
   544 		   If SDL is built as a DLL, this will return a handle to
   545 		   the DLL, not the application, and DirectInput may fail
   546 		   to initialize.
   547 		 */
   548 		handle = GetModuleHandle(NULL);
   549 	}
   550 	return(handle);
   551 }
   552 
   553 /* This allows the SDL_WINDOWID hack */
   554 const char *SDL_windowid = NULL;
   555 
   556 /* Register the class for this application -- exported for winmain.c */
   557 int SDL_RegisterApp(char *name, Uint32 style, void *hInst)
   558 {
   559 	static int initialized = 0;
   560 	WNDCLASS class;
   561 #ifdef WM_MOUSELEAVE
   562 	HMODULE handle;
   563 #endif
   564 
   565 	/* Only do this once... */
   566 	if ( initialized ) {
   567 		return(0);
   568 	}
   569 
   570 	/* This function needs to be passed the correct process handle
   571 	   by the application.
   572 	 */
   573 	if ( ! hInst ) {
   574 		hInst = SDL_GetModuleHandle();
   575 	}
   576 
   577 	/* Register the application class */
   578 	class.hCursor		= NULL;
   579 #ifdef _WIN32_WCE
   580     {
   581 	/* WinCE uses the UNICODE version */
   582 	int nLen = strlen(name)+1;
   583 	LPWSTR lpszW = alloca(nLen*2);
   584 	MultiByteToWideChar(CP_ACP, 0, name, -1, lpszW, nLen);
   585 	class.hIcon		= LoadImage(hInst, lpszW, IMAGE_ICON,
   586 	                                    0, 0, LR_DEFAULTCOLOR);
   587 	class.lpszMenuName	= NULL;
   588 	class.lpszClassName	= lpszW;
   589     }
   590 #else
   591 	class.hIcon		= LoadImage(hInst, name, IMAGE_ICON,
   592 	                                    0, 0, LR_DEFAULTCOLOR);
   593 	class.lpszMenuName	= "(none)";
   594 	class.lpszClassName	= name;
   595 #endif /* _WIN32_WCE */
   596 	class.hbrBackground	= NULL;
   597 	class.hInstance		= hInst;
   598 	class.style		= style;
   599 #ifdef HAVE_OPENGL
   600 	class.style		|= CS_OWNDC;
   601 #endif
   602 	class.lpfnWndProc	= WinMessage;
   603 	class.cbWndExtra	= 0;
   604 	class.cbClsExtra	= 0;
   605 	if ( ! RegisterClass(&class) ) {
   606 		SDL_SetError("Couldn't register application class");
   607 		return(-1);
   608 	}
   609 	SDL_Appname = name;
   610 	SDL_Instance = hInst;
   611 
   612 #ifdef WM_MOUSELEAVE
   613 	/* Get the version of TrackMouseEvent() we use */
   614 	_TrackMouseEvent = NULL;
   615 	handle = GetModuleHandle("USER32.DLL");
   616 	if ( handle ) {
   617 		_TrackMouseEvent = (BOOL (WINAPI *)(TRACKMOUSEEVENT *))GetProcAddress(handle, "TrackMouseEvent");
   618 	}
   619 	if ( _TrackMouseEvent == NULL ) {
   620 		_TrackMouseEvent = WIN_TrackMouseEvent;
   621 	}
   622 #endif /* WM_MOUSELEAVE */
   623 
   624 	/* Check for SDL_WINDOWID hack */
   625 	SDL_windowid = getenv("SDL_WINDOWID");
   626 
   627 	initialized = 1;
   628 	return(0);
   629 }
   630