diff options
Diffstat (limited to 'src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx')
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx index b05796eb5..7cb0c0680 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx @@ -22,6 +22,8 @@ #include <FL/Fl.H> #include <stdio.h> #include <windows.h> +#include <wchar.h> +#include <process.h> #if !defined(FL_DOXYGEN) const char* fl_local_alt = "Alt"; @@ -30,6 +32,11 @@ const char* fl_local_meta = "Meta"; const char* fl_local_shift = "Shift"; #endif +static wchar_t *mbwbuf = NULL; +static wchar_t *wbuf = NULL; +static wchar_t *wbuf1 = NULL; + + Fl_System_Driver *Fl_System_Driver::driver() { static Fl_System_Driver *d = new Fl_WinAPI_System_Driver(); return d; @@ -68,6 +75,253 @@ int Fl_WinAPI_System_Driver::compose(int &del) { return 1; } +char *Fl_WinAPI_System_Driver::utf2mbcs(const char *s) { + if (!s) return NULL; + size_t l = strlen(s); + static char *buf = NULL; + + unsigned wn = fl_utf8toUtf16(s, (unsigned) l, NULL, 0) + 7; // Query length + mbwbuf = (wchar_t*)realloc(mbwbuf, sizeof(wchar_t)*wn); + l = fl_utf8toUtf16(s, (unsigned) l, (unsigned short *)mbwbuf, wn); // Convert string + mbwbuf[l] = 0; + + buf = (char*)realloc(buf, (unsigned) (l * 6 + 1)); + l = (unsigned) wcstombs(buf, mbwbuf, (unsigned) l * 6); + buf[l] = 0; + return buf; +} + +char *Fl_WinAPI_System_Driver::getenv(const char* v) { + size_t l = strlen(v); + unsigned wn = fl_utf8toUtf16(v, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(v, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + wchar_t *ret = _wgetenv(wbuf); + static char *buf = NULL; + if (ret) { + l = (unsigned) wcslen(ret); + wn = fl_utf8fromwc(NULL, 0, ret, (unsigned) l) + 1; // query length + buf = (char*) realloc(buf, wn); + wn = fl_utf8fromwc(buf, wn, ret, (unsigned) l); // convert string + buf[wn] = 0; + return buf; + } else { + return NULL; + } +} + +int Fl_WinAPI_System_Driver::open(const char* f, int oflags, int pmode) { + unsigned l = (unsigned) strlen(f); + unsigned wn = fl_utf8toUtf16(f, l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(f, l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + if (pmode == -1) return _wopen(wbuf, oflags); + else return _wopen(wbuf, oflags, pmode); +} + +FILE *Fl_WinAPI_System_Driver::fopen(const char* f, const char *mode) { + size_t l = strlen(f); + unsigned wn = fl_utf8toUtf16(f, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(f, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + l = strlen(mode); + wn = fl_utf8toUtf16(mode, (unsigned) l, NULL, 0) + 1; // Query length + wbuf1 = (wchar_t*)realloc(wbuf1, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(mode, (unsigned) l, (unsigned short *)wbuf1, wn); // Convert string + wbuf1[wn] = 0; + return _wfopen(wbuf, wbuf1); +} + +int Fl_WinAPI_System_Driver::system(const char* cmd) { +# ifdef __MINGW32__ + return system(fl_utf2mbcs(cmd)); +# else + size_t l = strlen(cmd); + unsigned wn = fl_utf8toUtf16(cmd, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(cmd, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wsystem(wbuf); +# endif +} + +int Fl_WinAPI_System_Driver::execvp(const char *file, char *const *argv) { +# ifdef __MINGW32__ + return _execvp(fl_utf2mbcs(file), argv); +# else + size_t l = strlen(file); + int i, n; + wchar_t **ar; + unsigned wn = fl_utf8toUtf16(file, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(file, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + + i = 0; n = 0; + while (argv[i]) {i++; n++;} + ar = (wchar_t**) malloc(sizeof(wchar_t*) * (n + 1)); + i = 0; + while (i <= n) { + unsigned wn; + l = strlen(argv[i]); + wn = fl_utf8toUtf16(argv[i], (unsigned) l, NULL, 0) + 1; // Query length + ar[i] = (wchar_t *)malloc(sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(argv[i], (unsigned) l, (unsigned short *)ar[i], wn); // Convert string + ar[i][wn] = 0; + i++; + } + ar[n] = NULL; + _wexecvp(wbuf, ar); // STR #3040 + i = 0; + while (i <= n) { + free(ar[i]); + i++; + } + free(ar); + return -1; // STR #3040 +#endif +} + +int Fl_WinAPI_System_Driver::chmod(const char* f, int mode) { + size_t l = strlen(f); + unsigned wn = fl_utf8toUtf16(f, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(f, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wchmod(wbuf, mode); +} + +int Fl_WinAPI_System_Driver::access(const char* f, int mode) { + size_t l = strlen(f); + unsigned wn = fl_utf8toUtf16(f, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(f, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _waccess(wbuf, mode); +} + +int Fl_WinAPI_System_Driver::stat(const char* f, struct stat *b) { + size_t l = strlen(f); + unsigned wn = fl_utf8toUtf16(f, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(f, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wstat(wbuf, (struct _stat*)b); +} + +char *Fl_WinAPI_System_Driver::getcwd(char* b, int l) { + static wchar_t *wbuf = NULL; + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t) * (l+1)); + wchar_t *ret = _wgetcwd(wbuf, l); + if (ret) { + unsigned dstlen = l; + l = (int) wcslen(wbuf); + dstlen = fl_utf8fromwc(b, dstlen, wbuf, (unsigned) l); + b[dstlen] = 0; + return b; + } else { + return NULL; + } +} + +int Fl_WinAPI_System_Driver::unlink(const char* f) { + size_t l = strlen(f); + unsigned wn = fl_utf8toUtf16(f, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(f, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wunlink(wbuf); +} + +int Fl_WinAPI_System_Driver::mkdir(const char* f, int mode) { + size_t l = strlen(f); + unsigned wn = fl_utf8toUtf16(f, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(f, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wmkdir(wbuf); +} + +int Fl_WinAPI_System_Driver::rmdir(const char* f) { + size_t l = strlen(f); + unsigned wn = fl_utf8toUtf16(f, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(f, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + return _wrmdir(wbuf); +} + +int Fl_WinAPI_System_Driver::rename(const char* f, const char *n) { + size_t l = strlen(f); + unsigned wn = fl_utf8toUtf16(f, (unsigned) l, NULL, 0) + 1; // Query length + wbuf = (wchar_t*)realloc(wbuf, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(f, (unsigned) l, (unsigned short *)wbuf, wn); // Convert string + wbuf[wn] = 0; + l = strlen(n); + wn = fl_utf8toUtf16(n, (unsigned) l, NULL, 0) + 1; // Query length + wbuf1 = (wchar_t*)realloc(wbuf1, sizeof(wchar_t)*wn); + wn = fl_utf8toUtf16(n, (unsigned) l, (unsigned short *)wbuf1, wn); // Convert string + wbuf1[wn] = 0; + return _wrename(wbuf, wbuf1); +} + +// Two WIN32-specific functions fl_utf8_to_locale() and fl_locale_to_utf8() +// from file fl_utf8.cxx are put here for API compatibility + +static char *buf = NULL; +static int buf_len = 0; +static unsigned short *wbufa = NULL; +unsigned int fl_codepage = 0; + + +// FIXME: This should *maybe* return 'const char *' instead of 'char *' +char *fl_utf8_to_locale(const char *s, int len, UINT codepage) +{ + if (!s) return (char *)""; + int l = 0; + unsigned wn = fl_utf8toUtf16(s, len, NULL, 0); // Query length + wn = wn * 2 + 1; + if (wn >= (unsigned)buf_len) { + buf_len = wn; + buf = (char*) realloc(buf, buf_len); + wbufa = (unsigned short*) realloc(wbufa, buf_len * sizeof(short)); + } + if (codepage < 1) codepage = fl_codepage; + l = fl_utf8toUtf16(s, len, wbufa, wn); // Convert string + wbufa[l] = 0; + buf[l] = 0; + l = WideCharToMultiByte(codepage, 0, (WCHAR*)wbufa, l, buf, buf_len, NULL, NULL); + if (l < 0) l = 0; + buf[l] = 0; + return buf; +} + +// FIXME: This should maybe return 'const char *' instead of 'char *' +char *fl_locale_to_utf8(const char *s, int len, UINT codepage) +{ + if (!s) return (char *)""; + int l = 0; + if (buf_len < len * 5 + 1) { + buf_len = len * 5 + 1; + buf = (char*) realloc(buf, buf_len); + wbufa = (unsigned short*) realloc(wbufa, buf_len * sizeof(short)); + } + if (codepage < 1) codepage = fl_codepage; + buf[l] = 0; + + l = MultiByteToWideChar(codepage, 0, s, len, (WCHAR*)wbufa, buf_len); + if (l < 0) l = 0; + wbufa[l] = 0; + l = fl_utf8fromwc(buf, buf_len, (wchar_t*)wbufa, l); + buf[l] = 0; + return buf; +} + +/////////////////////////////////// + // // End of "$Id$". // |
