Update ChangeLog
[openal-soft.git] / common / win_main_utf8.h
blob821312d7e1182c1bd7f2378dbaa8917f02755cdd
1 #ifndef WIN_MAIN_UTF8_H
2 #define WIN_MAIN_UTF8_H
4 /* For Windows systems this overrides main() so that the argv strings are UTF-8
5 * encoded, and also overrides fopen to accept UTF-8 filenames. Working with
6 * wmain directly complicates cross-platform compatibility, while normal main()
7 * in Windows uses the current codepage (which has limited availability of
8 * characters).
10 * For MinGW, you must link with -municode
12 #ifdef _WIN32
13 #define WIN32_LEAN_AND_MEAN
14 #include <windows.h>
15 #include <shellapi.h>
17 static FILE *my_fopen(const char *fname, const char *mode)
19 WCHAR *wname=NULL, *wmode=NULL;
20 int namelen, modelen;
21 FILE *file = NULL;
23 namelen = MultiByteToWideChar(CP_UTF8, 0, fname, -1, NULL, 0);
24 modelen = MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
26 if(namelen <= 0 || modelen <= 0)
28 fprintf(stderr, "Failed to convert UTF-8 fname \"%s\", mode \"%s\"\n", fname, mode);
29 return NULL;
32 wname = calloc(sizeof(WCHAR), namelen+modelen);
33 wmode = wname + namelen;
34 MultiByteToWideChar(CP_UTF8, 0, fname, -1, wname, namelen);
35 MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, modelen);
37 file = _wfopen(wname, wmode);
39 free(wname);
41 return file;
43 #define fopen my_fopen
46 static char **arglist;
47 static void cleanup_arglist(void)
49 free(arglist);
52 static void GetUnicodeArgs(int *argc, char ***argv)
54 size_t total;
55 wchar_t **args;
56 int nargs, i;
58 args = CommandLineToArgvW(GetCommandLineW(), &nargs);
59 if(!args)
61 fprintf(stderr, "Failed to get command line args: %ld\n", GetLastError());
62 exit(EXIT_FAILURE);
65 total = sizeof(**argv) * nargs;
66 for(i = 0;i < nargs;i++)
67 total += WideCharToMultiByte(CP_UTF8, 0, args[i], -1, NULL, 0, NULL, NULL);
69 atexit(cleanup_arglist);
70 arglist = *argv = calloc(1, total);
71 (*argv)[0] = (char*)(*argv + nargs);
72 for(i = 0;i < nargs-1;i++)
74 int len = WideCharToMultiByte(CP_UTF8, 0, args[i], -1, (*argv)[i], 65535, NULL, NULL);
75 (*argv)[i+1] = (*argv)[i] + len;
77 WideCharToMultiByte(CP_UTF8, 0, args[i], -1, (*argv)[i], 65535, NULL, NULL);
78 *argc = nargs;
80 LocalFree(args);
82 #define GET_UNICODE_ARGS(argc, argv) GetUnicodeArgs(argc, argv)
84 #else
86 /* Do nothing. */
87 #define GET_UNICODE_ARGS(argc, argv)
89 #endif
91 #endif /* WIN_MAIN_UTF8_H */