summaryrefslogtreecommitdiff
path: root/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx')
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx254
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$".
//