SDL_windows_main.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. SDL_windows_main.c, placed in the public domain by Sam Lantinga 4/13/98
  3. The WinMain function -- calls your program's main() function
  4. */
  5. #include "SDL_config.h"
  6. #ifdef __WIN32__
  7. //#include "../../core/windows/SDL_windows.h"
  8. /* Include this so we define UNICODE properly */
  9. #if defined(__WIN32__)
  10. #define WIN32_LEAN_AND_MEAN
  11. #define STRICT
  12. #ifndef UNICODE
  13. #define UNICODE 1
  14. #endif
  15. #undef _WIN32_WINNT
  16. #define _WIN32_WINNT 0x501 /* Need 0x410 for AlphaBlend() and 0x500 for EnumDisplayDevices(), 0x501 for raw input */
  17. #endif
  18. #include <windows.h>
  19. /* Routines to convert from UTF8 to native Windows text */
  20. #if UNICODE
  21. #define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "UTF-16LE", (char *)(S), (SDL_wcslen(S)+1)*sizeof(WCHAR))
  22. #define WIN_UTF8ToString(S) (WCHAR *)SDL_iconv_string("UTF-16LE", "UTF-8", (char *)(S), SDL_strlen(S)+1)
  23. #else
  24. /* !!! FIXME: UTF8ToString() can just be a SDL_strdup() here. */
  25. #define WIN_StringToUTF8(S) SDL_iconv_string("UTF-8", "ASCII", (char *)(S), (SDL_strlen(S)+1))
  26. #define WIN_UTF8ToString(S) SDL_iconv_string("ASCII", "UTF-8", (char *)(S), SDL_strlen(S)+1)
  27. #endif
  28. /* Sets an error message based on a given HRESULT */
  29. extern int WIN_SetErrorFromHRESULT(const char *prefix, HRESULT hr);
  30. /* Sets an error message based on GetLastError(). Always return -1. */
  31. extern int WIN_SetError(const char *prefix);
  32. /* Wrap up the oddities of CoInitialize() into a common function. */
  33. extern HRESULT WIN_CoInitialize(void);
  34. extern void WIN_CoUninitialize(void);
  35. /* Returns SDL_TRUE if we're running on Windows Vista and newer */
  36. extern BOOL WIN_IsWindowsVistaOrGreater();
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. /* Include the SDL main definition header */
  40. #include "SDL.h"
  41. #include "SDL_main.h"
  42. #ifdef main
  43. # undef main
  44. #endif /* main */
  45. static void
  46. UnEscapeQuotes(char *arg)
  47. {
  48. char *last = NULL;
  49. while (*arg) {
  50. if (*arg == '"' && (last != NULL && *last == '\\')) {
  51. char *c_curr = arg;
  52. char *c_last = last;
  53. while (*c_curr) {
  54. *c_last = *c_curr;
  55. c_last = c_curr;
  56. c_curr++;
  57. }
  58. *c_last = '\0';
  59. }
  60. last = arg;
  61. arg++;
  62. }
  63. }
  64. /* Parse a command line buffer into arguments */
  65. static int
  66. ParseCommandLine(char *cmdline, char **argv)
  67. {
  68. char *bufp;
  69. char *lastp = NULL;
  70. int argc, last_argc;
  71. argc = last_argc = 0;
  72. for (bufp = cmdline; *bufp;) {
  73. /* Skip leading whitespace */
  74. while (SDL_isspace(*bufp)) {
  75. ++bufp;
  76. }
  77. /* Skip over argument */
  78. if (*bufp == '"') {
  79. ++bufp;
  80. if (*bufp) {
  81. if (argv) {
  82. argv[argc] = bufp;
  83. }
  84. ++argc;
  85. }
  86. /* Skip over word */
  87. lastp = bufp;
  88. while (*bufp && (*bufp != '"' || *lastp == '\\')) {
  89. lastp = bufp;
  90. ++bufp;
  91. }
  92. } else {
  93. if (*bufp) {
  94. if (argv) {
  95. argv[argc] = bufp;
  96. }
  97. ++argc;
  98. }
  99. /* Skip over word */
  100. while (*bufp && !SDL_isspace(*bufp)) {
  101. ++bufp;
  102. }
  103. }
  104. if (*bufp) {
  105. if (argv) {
  106. *bufp = '\0';
  107. }
  108. ++bufp;
  109. }
  110. /* Strip out \ from \" sequences */
  111. if (argv && last_argc != argc) {
  112. UnEscapeQuotes(argv[last_argc]);
  113. }
  114. last_argc = argc;
  115. }
  116. if (argv) {
  117. argv[argc] = NULL;
  118. }
  119. return (argc);
  120. }
  121. /* Show an error message */
  122. static void
  123. ShowError(const char *title, const char *message)
  124. {
  125. /* If USE_MESSAGEBOX is defined, you need to link with user32.lib */
  126. #ifdef USE_MESSAGEBOX
  127. MessageBox(NULL, message, title, MB_ICONEXCLAMATION | MB_OK);
  128. #else
  129. fprintf(stderr, "%s: %s\n", title, message);
  130. #endif
  131. }
  132. /* Pop up an out of memory message, returns to Windows */
  133. static BOOL
  134. OutOfMemory(void)
  135. {
  136. ShowError("Fatal Error", "Out of memory - aborting");
  137. return FALSE;
  138. }
  139. #if defined(_MSC_VER)
  140. /* The VC++ compiler needs main defined */
  141. #define console_main main
  142. #endif
  143. /* This is where execution begins [console apps] */
  144. int
  145. console_main(int argc, char *argv[])
  146. {
  147. int status;
  148. SDL_SetMainReady();
  149. /* Run the application main() code */
  150. status = SDL_main(argc, argv);
  151. /* Exit cleanly, calling atexit() functions */
  152. exit(status);
  153. /* Hush little compiler, don't you cry... */
  154. return 0;
  155. }
  156. /* This is where execution begins [windowed apps] */
  157. int WINAPI
  158. WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int sw)
  159. {
  160. char **argv;
  161. int argc;
  162. char *cmdline;
  163. /* Grab the command line */
  164. TCHAR *text = GetCommandLine();
  165. #if UNICODE
  166. cmdline = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char *)(text), (SDL_wcslen(text)+1)*sizeof(WCHAR));
  167. #else
  168. cmdline = SDL_strdup(text);
  169. #endif
  170. if (cmdline == NULL) {
  171. return OutOfMemory();
  172. }
  173. /* Parse it into argv and argc */
  174. argc = ParseCommandLine(cmdline, NULL);
  175. argv = SDL_stack_alloc(char *, argc + 1);
  176. if (argv == NULL) {
  177. return OutOfMemory();
  178. }
  179. ParseCommandLine(cmdline, argv);
  180. /* Run the main program */
  181. console_main(argc, argv);
  182. SDL_stack_free(argv);
  183. SDL_free(cmdline);
  184. /* Hush little compiler, don't you cry... */
  185. return 0;
  186. }
  187. #endif /* __WIN32__ */
  188. /* vi: set ts=4 sw=4 expandtab: */