Mercurial > sdl-ios-xcode
comparison src/main/win32/SDL_win32_main.c @ 1895:c121d94672cb
SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 10 Jul 2006 21:04:37 +0000 |
parents | 290b5baf2fca |
children | 41a6675d8700 |
comparison
equal
deleted
inserted
replaced
1894:c69cee13dd76 | 1895:c121d94672cb |
---|---|
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 | 9 |
10 #define WIN32_LEAN_AND_MEAN | 10 #define WIN32_LEAN_AND_MEAN |
11 #include <windows.h> | 11 #include <windows.h> |
12 | 12 |
13 #ifdef _WIN32_WCE | |
14 # define DIR_SEPERATOR TEXT("\\") | |
15 # undef _getcwd | |
16 # define _getcwd(str,len) wcscpy(str,TEXT("")) | |
17 # define setbuf(f,b) | |
18 # define setvbuf(w,x,y,z) | |
19 # define fopen _wfopen | |
20 # define freopen _wfreopen | |
21 # define remove(x) DeleteFile(x) | |
22 #else | |
23 # define DIR_SEPERATOR TEXT("/") | |
24 # include <direct.h> | |
25 #endif | |
26 | |
27 /* Include the SDL main definition header */ | 13 /* Include the SDL main definition header */ |
28 #include "SDL.h" | 14 #include "SDL.h" |
29 #include "SDL_main.h" | 15 #include "SDL_main.h" |
30 | 16 |
31 #ifdef main | 17 #ifdef main |
32 # ifndef _WIN32_WCE_EMULATION | 18 # ifndef _WIN32_WCE_EMULATION |
33 # undef main | 19 # undef main |
34 # endif /* _WIN32_WCE_EMULATION */ | 20 # endif /* _WIN32_WCE_EMULATION */ |
35 #endif /* main */ | 21 #endif /* main */ |
36 | 22 |
37 /* The standard output files */ | |
38 #define STDOUT_FILE TEXT("stdout.txt") | |
39 #define STDERR_FILE TEXT("stderr.txt") | |
40 | |
41 #ifndef NO_STDIO_REDIRECT | |
42 # ifdef _WIN32_WCE | |
43 static wchar_t stdoutPath[MAX_PATH]; | |
44 static wchar_t stderrPath[MAX_PATH]; | |
45 # else | |
46 static char stdoutPath[MAX_PATH]; | |
47 static char stderrPath[MAX_PATH]; | |
48 # endif | |
49 #endif | |
50 | |
51 #if defined(_WIN32_WCE) && _WIN32_WCE < 300 | 23 #if defined(_WIN32_WCE) && _WIN32_WCE < 300 |
52 /* seems to be undefined in Win CE although in online help */ | 24 /* seems to be undefined in Win CE although in online help */ |
53 #define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) | 25 #define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t')) |
54 #endif /* _WIN32_WCE < 300 */ | 26 #endif /* _WIN32_WCE < 300 */ |
55 | 27 |
56 /* Parse a command line buffer into arguments */ | 28 /* Parse a command line buffer into arguments */ |
57 static int ParseCommandLine(char *cmdline, char **argv) | 29 static int |
30 ParseCommandLine(char *cmdline, char **argv) | |
58 { | 31 { |
59 char *bufp; | 32 char *bufp; |
60 int argc; | 33 int argc; |
61 | 34 |
62 argc = 0; | 35 argc = 0; |
63 for ( bufp = cmdline; *bufp; ) { | 36 for (bufp = cmdline; *bufp;) { |
64 /* Skip leading whitespace */ | 37 /* Skip leading whitespace */ |
65 while ( isspace(*bufp) ) { | 38 while (isspace(*bufp)) { |
66 ++bufp; | 39 ++bufp; |
67 } | 40 } |
68 /* Skip over argument */ | 41 /* Skip over argument */ |
69 if ( *bufp == '"' ) { | 42 if (*bufp == '"') { |
70 ++bufp; | 43 ++bufp; |
71 if ( *bufp ) { | 44 if (*bufp) { |
72 if ( argv ) { | 45 if (argv) { |
73 argv[argc] = bufp; | 46 argv[argc] = bufp; |
74 } | 47 } |
75 ++argc; | 48 ++argc; |
76 } | 49 } |
77 /* Skip over word */ | 50 /* Skip over word */ |
78 while ( *bufp && (*bufp != '"') ) { | 51 while (*bufp && (*bufp != '"')) { |
79 ++bufp; | 52 ++bufp; |
80 } | 53 } |
81 } else { | 54 } else { |
82 if ( *bufp ) { | 55 if (*bufp) { |
83 if ( argv ) { | 56 if (argv) { |
84 argv[argc] = bufp; | 57 argv[argc] = bufp; |
85 } | 58 } |
86 ++argc; | 59 ++argc; |
87 } | 60 } |
88 /* Skip over word */ | 61 /* Skip over word */ |
89 while ( *bufp && ! isspace(*bufp) ) { | 62 while (*bufp && !isspace(*bufp)) { |
90 ++bufp; | 63 ++bufp; |
91 } | 64 } |
92 } | 65 } |
93 if ( *bufp ) { | 66 if (*bufp) { |
94 if ( argv ) { | 67 if (argv) { |
95 *bufp = '\0'; | 68 *bufp = '\0'; |
96 } | 69 } |
97 ++bufp; | 70 ++bufp; |
98 } | 71 } |
99 } | 72 } |
100 if ( argv ) { | 73 if (argv) { |
101 argv[argc] = NULL; | 74 argv[argc] = NULL; |
102 } | 75 } |
103 return(argc); | 76 return (argc); |
104 } | 77 } |
105 | 78 |
106 /* Show an error message */ | 79 /* Show an error message */ |
107 static void ShowError(const char *title, const char *message) | 80 static void |
81 ShowError(const char *title, const char *message) | |
108 { | 82 { |
109 /* If USE_MESSAGEBOX is defined, you need to link with user32.lib */ | 83 /* If USE_MESSAGEBOX is defined, you need to link with user32.lib */ |
110 #ifdef USE_MESSAGEBOX | 84 #ifdef USE_MESSAGEBOX |
111 MessageBox(NULL, message, title, MB_ICONEXCLAMATION|MB_OK); | 85 MessageBox(NULL, message, title, MB_ICONEXCLAMATION | MB_OK); |
112 #else | 86 #else |
113 fprintf(stderr, "%s: %s\n", title, message); | 87 fprintf(stderr, "%s: %s\n", title, message); |
114 #endif | 88 #endif |
115 } | 89 } |
116 | 90 |
117 /* Pop up an out of memory message, returns to Windows */ | 91 /* Pop up an out of memory message, returns to Windows */ |
118 static BOOL OutOfMemory(void) | 92 static BOOL |
93 OutOfMemory(void) | |
119 { | 94 { |
120 ShowError("Fatal Error", "Out of memory - aborting"); | 95 ShowError("Fatal Error", "Out of memory - aborting"); |
121 return FALSE; | 96 return FALSE; |
122 } | |
123 | |
124 /* SDL_Quit() shouldn't be used with atexit() directly because | |
125 calling conventions may differ... */ | |
126 static void cleanup(void) | |
127 { | |
128 SDL_Quit(); | |
129 } | |
130 | |
131 /* Remove the output files if there was no output written */ | |
132 static void cleanup_output(void) | |
133 { | |
134 #ifndef NO_STDIO_REDIRECT | |
135 FILE *file; | |
136 int empty; | |
137 #endif | |
138 | |
139 /* Flush the output in case anything is queued */ | |
140 fclose(stdout); | |
141 fclose(stderr); | |
142 | |
143 #ifndef NO_STDIO_REDIRECT | |
144 /* See if the files have any output in them */ | |
145 if ( stdoutPath[0] ) { | |
146 file = fopen(stdoutPath, TEXT("rb")); | |
147 if ( file ) { | |
148 empty = (fgetc(file) == EOF) ? 1 : 0; | |
149 fclose(file); | |
150 if ( empty ) { | |
151 remove(stdoutPath); | |
152 } | |
153 } | |
154 } | |
155 if ( stderrPath[0] ) { | |
156 file = fopen(stderrPath, TEXT("rb")); | |
157 if ( file ) { | |
158 empty = (fgetc(file) == EOF) ? 1 : 0; | |
159 fclose(file); | |
160 if ( empty ) { | |
161 remove(stderrPath); | |
162 } | |
163 } | |
164 } | |
165 #endif | |
166 } | 97 } |
167 | 98 |
168 #if defined(_MSC_VER) && !defined(_WIN32_WCE) | 99 #if defined(_MSC_VER) && !defined(_WIN32_WCE) |
169 /* The VC++ compiler needs main defined */ | 100 /* The VC++ compiler needs main defined */ |
170 #define console_main main | 101 #define console_main main |
171 #endif | 102 #endif |
172 | 103 |
173 /* This is where execution begins [console apps] */ | 104 /* This is where execution begins [console apps] */ |
174 int console_main(int argc, char *argv[]) | 105 int |
106 console_main(int argc, char *argv[]) | |
175 { | 107 { |
176 size_t n; | 108 int status; |
177 char *bufp, *appname; | |
178 int status; | |
179 | 109 |
180 /* Get the class name from argv[0] */ | 110 /* Run the application main() code */ |
181 appname = argv[0]; | 111 status = SDL_main(argc, argv); |
182 if ( (bufp=SDL_strrchr(argv[0], '\\')) != NULL ) { | |
183 appname = bufp+1; | |
184 } else | |
185 if ( (bufp=SDL_strrchr(argv[0], '/')) != NULL ) { | |
186 appname = bufp+1; | |
187 } | |
188 | 112 |
189 if ( (bufp=SDL_strrchr(appname, '.')) == NULL ) | 113 /* Exit cleanly, calling atexit() functions */ |
190 n = SDL_strlen(appname); | 114 exit(status); |
191 else | |
192 n = (bufp-appname); | |
193 | 115 |
194 bufp = SDL_stack_alloc(char, n+1); | 116 /* Hush little compiler, don't you cry... */ |
195 if ( bufp == NULL ) { | 117 return 0; |
196 return OutOfMemory(); | |
197 } | |
198 SDL_strlcpy(bufp, appname, n+1); | |
199 appname = bufp; | |
200 | |
201 /* Load SDL dynamic link library */ | |
202 if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) { | |
203 ShowError("WinMain() error", SDL_GetError()); | |
204 return(FALSE); | |
205 } | |
206 atexit(cleanup_output); | |
207 atexit(cleanup); | |
208 | |
209 /* Sam: | |
210 We still need to pass in the application handle so that | |
211 DirectInput will initialize properly when SDL_RegisterApp() | |
212 is called later in the video initialization. | |
213 */ | |
214 SDL_SetModuleHandle(GetModuleHandle(NULL)); | |
215 | |
216 /* Run the application main() code */ | |
217 status = SDL_main(argc, argv); | |
218 | |
219 /* Exit cleanly, calling atexit() functions */ | |
220 exit(status); | |
221 | |
222 /* Hush little compiler, don't you cry... */ | |
223 return 0; | |
224 } | 118 } |
225 | 119 |
226 /* This is where execution begins [windowed apps] */ | 120 /* This is where execution begins [windowed apps] */ |
121 int WINAPI | |
122 WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int sw) | |
123 { | |
124 char **argv; | |
125 int argc; | |
126 char *cmdline; | |
227 #ifdef _WIN32_WCE | 127 #ifdef _WIN32_WCE |
228 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPWSTR szCmdLine, int sw) | 128 wchar_t *bufp; |
129 int nLen; | |
229 #else | 130 #else |
230 int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw) | 131 char *bufp; |
231 #endif | 132 size_t nLen; |
232 { | |
233 HINSTANCE handle; | |
234 char **argv; | |
235 int argc; | |
236 char *cmdline; | |
237 DWORD pathlen; | |
238 #ifdef _WIN32_WCE | |
239 wchar_t path[MAX_PATH]; | |
240 #else | |
241 char path[MAX_PATH]; | |
242 #endif | |
243 #ifdef _WIN32_WCE | |
244 wchar_t *bufp; | |
245 int nLen; | |
246 #else | |
247 char *bufp; | |
248 size_t nLen; | |
249 #endif | |
250 #ifndef NO_STDIO_REDIRECT | |
251 FILE *newfp; | |
252 #endif | 133 #endif |
253 | 134 |
254 /* Start up DDHELP.EXE before opening any files, so DDHELP doesn't | |
255 keep them open. This is a hack.. hopefully it will be fixed | |
256 someday. DDHELP.EXE starts up the first time DDRAW.DLL is loaded. | |
257 */ | |
258 handle = LoadLibrary(TEXT("DDRAW.DLL")); | |
259 if ( handle != NULL ) { | |
260 FreeLibrary(handle); | |
261 } | |
262 | |
263 #ifndef NO_STDIO_REDIRECT | |
264 pathlen = GetModuleFileName(NULL, path, SDL_arraysize(path)); | |
265 while ( pathlen > 0 && path[pathlen] != '\\' ) { | |
266 --pathlen; | |
267 } | |
268 path[pathlen] = '\0'; | |
269 | |
270 #ifdef _WIN32_WCE | 135 #ifdef _WIN32_WCE |
271 wcsncpy( stdoutPath, path, SDL_arraysize(stdoutPath) ); | 136 nLen = wcslen(szCmdLine) + 128 + 1; |
272 wcsncat( stdoutPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); | 137 bufp = SDL_stack_alloc(wchar_t, nLen * 2); |
138 wcscpy(bufp, TEXT("\"")); | |
139 GetModuleFileName(NULL, bufp + 1, 128 - 3); | |
140 wcscpy(bufp + wcslen(bufp), TEXT("\" ")); | |
141 wcsncpy(bufp + wcslen(bufp), szCmdLine, nLen - wcslen(bufp)); | |
142 nLen = wcslen(bufp) + 1; | |
143 cmdline = SDL_stack_alloc(char, nLen); | |
144 if (cmdline == NULL) { | |
145 return OutOfMemory(); | |
146 } | |
147 WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL); | |
273 #else | 148 #else |
274 SDL_strlcpy( stdoutPath, path, SDL_arraysize(stdoutPath) ); | 149 /* Grab the command line */ |
275 SDL_strlcat( stdoutPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); | 150 bufp = GetCommandLine(); |
276 #endif | 151 nLen = SDL_strlen(bufp) + 1; |
277 | 152 cmdline = SDL_stack_alloc(char, nLen); |
278 /* Redirect standard input and standard output */ | 153 if (cmdline == NULL) { |
279 newfp = freopen(stdoutPath, TEXT("w"), stdout); | 154 return OutOfMemory(); |
280 | 155 } |
281 #ifndef _WIN32_WCE | 156 SDL_strlcpy(cmdline, bufp, nLen); |
282 if ( newfp == NULL ) { /* This happens on NT */ | |
283 #if !defined(stdout) | |
284 stdout = fopen(stdoutPath, TEXT("w")); | |
285 #else | |
286 newfp = fopen(stdoutPath, TEXT("w")); | |
287 if ( newfp ) { | |
288 *stdout = *newfp; | |
289 } | |
290 #endif | |
291 } | |
292 #endif /* _WIN32_WCE */ | |
293 | |
294 #ifdef _WIN32_WCE | |
295 wcsncpy( stderrPath, path, SDL_arraysize(stdoutPath) ); | |
296 wcsncat( stderrPath, DIR_SEPERATOR STDOUT_FILE, SDL_arraysize(stdoutPath) ); | |
297 #else | |
298 SDL_strlcpy( stderrPath, path, SDL_arraysize(stderrPath) ); | |
299 SDL_strlcat( stderrPath, DIR_SEPERATOR STDERR_FILE, SDL_arraysize(stderrPath) ); | |
300 #endif | 157 #endif |
301 | 158 |
302 newfp = freopen(stderrPath, TEXT("w"), stderr); | 159 /* Parse it into argv and argc */ |
303 #ifndef _WIN32_WCE | 160 argc = ParseCommandLine(cmdline, NULL); |
304 if ( newfp == NULL ) { /* This happens on NT */ | 161 argv = SDL_stack_alloc(char *, argc + 1); |
305 #if !defined(stderr) | 162 if (argv == NULL) { |
306 stderr = fopen(stderrPath, TEXT("w")); | 163 return OutOfMemory(); |
307 #else | 164 } |
308 newfp = fopen(stderrPath, TEXT("w")); | 165 ParseCommandLine(cmdline, argv); |
309 if ( newfp ) { | |
310 *stderr = *newfp; | |
311 } | |
312 #endif | |
313 } | |
314 #endif /* _WIN32_WCE */ | |
315 | 166 |
316 setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* Line buffered */ | 167 /* Run the main program */ |
317 setbuf(stderr, NULL); /* No buffering */ | 168 console_main(argc, argv); |
318 #endif /* !NO_STDIO_REDIRECT */ | |
319 | 169 |
320 #ifdef _WIN32_WCE | 170 /* Hush little compiler, don't you cry... */ |
321 nLen = wcslen(szCmdLine)+128+1; | 171 return 0; |
322 bufp = SDL_stack_alloc(wchar_t, nLen*2); | 172 } |
323 wcscpy (bufp, TEXT("\"")); | |
324 GetModuleFileName(NULL, bufp+1, 128-3); | |
325 wcscpy (bufp+wcslen(bufp), TEXT("\" ")); | |
326 wcsncpy(bufp+wcslen(bufp), szCmdLine,nLen-wcslen(bufp)); | |
327 nLen = wcslen(bufp)+1; | |
328 cmdline = SDL_stack_alloc(char, nLen); | |
329 if ( cmdline == NULL ) { | |
330 return OutOfMemory(); | |
331 } | |
332 WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL); | |
333 #else | |
334 /* Grab the command line */ | |
335 bufp = GetCommandLine(); | |
336 nLen = SDL_strlen(bufp)+1; | |
337 cmdline = SDL_stack_alloc(char, nLen); | |
338 if ( cmdline == NULL ) { | |
339 return OutOfMemory(); | |
340 } | |
341 SDL_strlcpy(cmdline, bufp, nLen); | |
342 #endif | |
343 | 173 |
344 /* Parse it into argv and argc */ | 174 /* vi: set ts=4 sw=4 expandtab: */ |
345 argc = ParseCommandLine(cmdline, NULL); | |
346 argv = SDL_stack_alloc(char*, argc+1); | |
347 if ( argv == NULL ) { | |
348 return OutOfMemory(); | |
349 } | |
350 ParseCommandLine(cmdline, argv); | |
351 | |
352 /* Run the main program (after a little SDL initialization) */ | |
353 console_main(argc, argv); | |
354 | |
355 /* Hush little compiler, don't you cry... */ | |
356 return 0; | |
357 } |