src/main/win32/SDL_win32_main.c
author Sam Lantinga
Sat, 29 Dec 2007 19:29:20 +0000
changeset 2286 41a6675d8700
parent 1895 c121d94672cb
child 4511 ae7799d16c87
permissions -rw-r--r--
Merged fix for bug #503 from SDL 1.2 revision 3487
     1 /*
     2     SDL_main.c, placed in the public domain by Sam Lantinga  4/13/98
     3 
     4     The WinMain function -- calls your program's main() function
     5 */
     6 
     7 #include <stdio.h>
     8 #include <stdlib.h>
     9 
    10 #define WIN32_LEAN_AND_MEAN
    11 #include <windows.h>
    12 
    13 /* Include the SDL main definition header */
    14 #include "SDL.h"
    15 #include "SDL_main.h"
    16 
    17 #ifdef main
    18 # ifndef _WIN32_WCE_EMULATION
    19 #  undef main
    20 # endif /* _WIN32_WCE_EMULATION */
    21 #endif /* main */
    22 
    23 #if defined(_WIN32_WCE) && _WIN32_WCE < 300
    24 /* seems to be undefined in Win CE although in online help */
    25 #define isspace(a) (((CHAR)a == ' ') || ((CHAR)a == '\t'))
    26 #endif /* _WIN32_WCE < 300 */
    27 
    28 static void
    29 UnEscapeQuotes(char *arg)
    30 {
    31     char *last = NULL;
    32 
    33     while (*arg) {
    34         if (*arg == '"' && *last == '\\') {
    35             char *c_curr = arg;
    36             char *c_last = last;
    37 
    38             while (*c_curr) {
    39                 *c_last = *c_curr;
    40                 c_last = c_curr;
    41                 c_curr++;
    42             }
    43             *c_last = '\0';
    44         }
    45         last = arg;
    46         arg++;
    47     }
    48 }
    49 
    50 /* Parse a command line buffer into arguments */
    51 static int
    52 ParseCommandLine(char *cmdline, char **argv)
    53 {
    54     char *bufp;
    55     char *lastp = NULL;
    56     int argc, last_argc;
    57 
    58     argc = last_argc = 0;
    59     for (bufp = cmdline; *bufp;) {
    60         /* Skip leading whitespace */
    61         while (isspace(*bufp)) {
    62             ++bufp;
    63         }
    64         /* Skip over argument */
    65         if (*bufp == '"') {
    66             ++bufp;
    67             if (*bufp) {
    68                 if (argv) {
    69                     argv[argc] = bufp;
    70                 }
    71                 ++argc;
    72             }
    73             /* Skip over word */
    74             while (*bufp && (*bufp != '"' || *lastp == '\\')) {
    75                 lastp = bufp;
    76                 ++bufp;
    77             }
    78         } else {
    79             if (*bufp) {
    80                 if (argv) {
    81                     argv[argc] = bufp;
    82                 }
    83                 ++argc;
    84             }
    85             /* Skip over word */
    86             while (*bufp && !isspace(*bufp)) {
    87                 ++bufp;
    88             }
    89         }
    90         if (*bufp) {
    91             if (argv) {
    92                 *bufp = '\0';
    93             }
    94             ++bufp;
    95         }
    96 
    97         /* Strip out \ from \" sequences */
    98         if (argv && last_argc != argc) {
    99             UnEscapeQuotes(argv[last_argc]);
   100         }
   101         last_argc = argc;
   102     }
   103     if (argv) {
   104         argv[argc] = NULL;
   105     }
   106     return (argc);
   107 }
   108 
   109 /* Show an error message */
   110 static void
   111 ShowError(const char *title, const char *message)
   112 {
   113 /* If USE_MESSAGEBOX is defined, you need to link with user32.lib */
   114 #ifdef USE_MESSAGEBOX
   115     MessageBox(NULL, message, title, MB_ICONEXCLAMATION | MB_OK);
   116 #else
   117     fprintf(stderr, "%s: %s\n", title, message);
   118 #endif
   119 }
   120 
   121 /* Pop up an out of memory message, returns to Windows */
   122 static BOOL
   123 OutOfMemory(void)
   124 {
   125     ShowError("Fatal Error", "Out of memory - aborting");
   126     return FALSE;
   127 }
   128 
   129 #if defined(_MSC_VER) && !defined(_WIN32_WCE)
   130 /* The VC++ compiler needs main defined */
   131 #define console_main main
   132 #endif
   133 
   134 /* This is where execution begins [console apps] */
   135 int
   136 console_main(int argc, char *argv[])
   137 {
   138     int status;
   139 
   140     /* Run the application main() code */
   141     status = SDL_main(argc, argv);
   142 
   143     /* Exit cleanly, calling atexit() functions */
   144     exit(status);
   145 
   146     /* Hush little compiler, don't you cry... */
   147     return 0;
   148 }
   149 
   150 /* This is where execution begins [windowed apps] */
   151 int WINAPI
   152 WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPTSTR szCmdLine, int sw)
   153 {
   154     char **argv;
   155     int argc;
   156     char *cmdline;
   157 #ifdef _WIN32_WCE
   158     wchar_t *bufp;
   159     int nLen;
   160 #else
   161     char *bufp;
   162     size_t nLen;
   163 #endif
   164 
   165 #ifdef _WIN32_WCE
   166     nLen = wcslen(szCmdLine) + 128 + 1;
   167     bufp = SDL_stack_alloc(wchar_t, nLen * 2);
   168     wcscpy(bufp, TEXT("\""));
   169     GetModuleFileName(NULL, bufp + 1, 128 - 3);
   170     wcscpy(bufp + wcslen(bufp), TEXT("\" "));
   171     wcsncpy(bufp + wcslen(bufp), szCmdLine, nLen - wcslen(bufp));
   172     nLen = wcslen(bufp) + 1;
   173     cmdline = SDL_stack_alloc(char, nLen);
   174     if (cmdline == NULL) {
   175         return OutOfMemory();
   176     }
   177     WideCharToMultiByte(CP_ACP, 0, bufp, -1, cmdline, nLen, NULL, NULL);
   178 #else
   179     /* Grab the command line */
   180     bufp = GetCommandLine();
   181     nLen = SDL_strlen(bufp) + 1;
   182     cmdline = SDL_stack_alloc(char, nLen);
   183     if (cmdline == NULL) {
   184         return OutOfMemory();
   185     }
   186     SDL_strlcpy(cmdline, bufp, nLen);
   187 #endif
   188 
   189     /* Parse it into argv and argc */
   190     argc = ParseCommandLine(cmdline, NULL);
   191     argv = SDL_stack_alloc(char *, argc + 1);
   192     if (argv == NULL) {
   193         return OutOfMemory();
   194     }
   195     ParseCommandLine(cmdline, argv);
   196 
   197     /* Run the main program */
   198     console_main(argc, argv);
   199 
   200     /* Hush little compiler, don't you cry... */
   201     return 0;
   202 }
   203 
   204 /* vi: set ts=4 sw=4 expandtab: */