From 74bd0fba9c4e601fb1732c0186d3e81fe250a5a8 Mon Sep 17 00:00:00 2001 From: Daniel Collin Date: Tue, 1 Jan 2013 12:25:48 +0100 Subject: [PATCH] Implemented support for unicode on Win32 Closes #51 --- ogl_editor/src/Dialog.h | 9 +++++ ogl_editor/src/Editor.c | 73 +++++++++++++++++++++++++---------- ogl_editor/src/Editor.h | 2 +- ogl_editor/src/TrackView.c | 2 +- ogl_editor/src/loadsave.c | 21 +++++++--- ogl_editor/src/loadsave.h | 10 +++-- ogl_editor/src/windows/Dialogs.c | 4 +- ogl_editor/src/windows/RocketWindow.c | 14 +++---- tundra.lua | 6 +-- 9 files changed, 97 insertions(+), 44 deletions(-) diff --git a/ogl_editor/src/Dialog.h b/ogl_editor/src/Dialog.h index eb5e156..8a35e03 100644 --- a/ogl_editor/src/Dialog.h +++ b/ogl_editor/src/Dialog.h @@ -1,5 +1,14 @@ #pragma once +#if defined(_WIN32) + +int Dialog_open(wchar_t* dest); +int Dialog_save(wchar_t* dest); + +#else + int Dialog_open(char* dest); int Dialog_save(char* dest); +#endif + diff --git a/ogl_editor/src/Editor.c b/ogl_editor/src/Editor.c index 0661127..676f878 100644 --- a/ogl_editor/src/Editor.c +++ b/ogl_editor/src/Editor.c @@ -17,8 +17,8 @@ #include "../../sync/base.h" #include "../../sync/data.h" -extern void Window_setTitle(const char* title); -extern void Window_populateRecentList(const char** files); +extern void Window_setTitle(const text_t* title); +extern void Window_populateRecentList(const text_t** files); static void updateNeedsSaving(); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -54,10 +54,10 @@ static EditorData s_editorData; static CopyData s_copyData; static int s_undoLevel = 0; static bool reset_tracks = true; -static char s_filenames[5][2048]; -static char* s_loadedFilename = 0; +static text_t s_filenames[5][2048]; +static text_t* s_loadedFilename = 0; -static char* s_recentFiles[] = +static text_t* s_recentFiles[] = { s_filenames[0], s_filenames[1], @@ -68,47 +68,71 @@ static char* s_recentFiles[] = /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -char** Editor_getRecentFiles() +text_t** Editor_getRecentFiles() { - return (char**)s_recentFiles; + return (text_t**)s_recentFiles; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -const char* getMostRecentFile() +const text_t* getMostRecentFile() { return s_recentFiles[0]; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void setMostRecentFile(const char* filename) +static void textCopy(text_t* dest, const text_t* src) +{ +#if defined(_WIN32) + wcscpy_s(dest, 2048, src); +#else + strcpy(dest, src); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +static int textCmp(text_t* t0, const text_t* t1) +{ +#if defined(_WIN32) + return wcscmp(t0, t1); +#else + return strcmp(t0, t1); +#endif +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void setMostRecentFile(const text_t* filename) { int i; // move down all files for (i = 3; i >= 0; --i) - strcpy(s_recentFiles[i+1], s_recentFiles[i]); + textCopy(s_recentFiles[i+1], s_recentFiles[i]); - strcpy(s_recentFiles[0], filename); + textCopy(s_recentFiles[0], filename); s_loadedFilename = s_recentFiles[0]; // check if the string was already present and remove it if that is the case by compacting the array for (i = 1; i < 5; ++i) { - if (!strcmp(s_recentFiles[i], filename)) + if (!textCmp(s_recentFiles[i], filename)) { for (; i < 4; ++i) - strcpy(s_recentFiles[i], s_recentFiles[i + 1]); + textCopy(s_recentFiles[i], s_recentFiles[i + 1]); break; } } - Window_populateRecentList((const char**)s_recentFiles); + Window_populateRecentList((const text_t**)s_recentFiles); } +// + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static inline struct sync_track** getTracks() @@ -1261,13 +1285,20 @@ void Editor_timedUpdate() /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static void setWindowTitle(const char* path, bool needsSave) +static void setWindowTitle(const text_t* path, bool needsSave) { - char windowTitle[4096]; + text_t windowTitle[4096]; +#if defined(_WIN32) + if (needsSave) + swprintf_s(windowTitle, sizeof(windowTitle), L"RocketEditor - (%s) *", path); + else + swprintf_s(windowTitle, sizeof(windowTitle), L"RocketEditor - (%s)", path); +#else if (needsSave) sprintf(windowTitle, "RocketEditor - (%s) *", path); else sprintf(windowTitle, "RocketEditor - (%s)", path); +#endif Window_setTitle(windowTitle); } @@ -1291,7 +1322,7 @@ void updateNeedsSaving() /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static void onFinishedLoad(const char* path) +static void onFinishedLoad(const text_t* path) { Editor_update(); setWindowTitle(path, false); @@ -1303,8 +1334,8 @@ static void onFinishedLoad(const char* path) void Editor_loadRecentFile(int id) { - char path[2048]; - strcpy(path, s_recentFiles[id]); // must be unique buffer when doing set mostRecent + text_t path[2048]; + textCopy(path, s_recentFiles[id]); // must be unique buffer when doing set mostRecent if (LoadSave_loadRocketXML(path, getTrackData())) onFinishedLoad(path); @@ -1314,7 +1345,7 @@ void Editor_loadRecentFile(int id) static void onOpen() { - char currentFile[2048]; + text_t currentFile[2048]; if (LoadSave_loadRocketXMLDialog(currentFile, getTrackData())) onFinishedLoad(currentFile); @@ -1324,7 +1355,7 @@ static void onOpen() static bool onSaveDialog() { - char path[2048]; + text_t path[2048]; int ret; if (!(ret = LoadSave_saveRocketXMLDialog(path, getTrackData()))) diff --git a/ogl_editor/src/Editor.h b/ogl_editor/src/Editor.h index ec579fd..3aec7f7 100644 --- a/ogl_editor/src/Editor.h +++ b/ogl_editor/src/Editor.h @@ -16,7 +16,7 @@ void Editor_updateTrackScroll(); void Editor_loadRecentFile(int file); bool Editor_saveBeforeExit(); -char** Editor_getRecentFiles(); +text_t** Editor_getRecentFiles(); enum { diff --git a/ogl_editor/src/TrackView.c b/ogl_editor/src/TrackView.c index 3efe420..fd8b957 100644 --- a/ogl_editor/src/TrackView.c +++ b/ogl_editor/src/TrackView.c @@ -317,7 +317,7 @@ static int renderChannel(struct TrackInfo* info, int startX, Track* trackData, b const int endPos = info->endPos; struct sync_track* track = 0; const uint32_t color = trackData->color; - bool folded; + bool folded = false; if (!valuesOnly) { diff --git a/ogl_editor/src/loadsave.c b/ogl_editor/src/loadsave.c index 17491e7..ca19a5d 100644 --- a/ogl_editor/src/loadsave.c +++ b/ogl_editor/src/loadsave.c @@ -146,13 +146,18 @@ static void parseXml(mxml_node_t* rootNode, TrackData* trackData) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int LoadSave_loadRocketXML(const char* path, TrackData* trackData) +int LoadSave_loadRocketXML(const text_t* path, TrackData* trackData) { FILE* fp = 0; mxml_node_t* tree = 0; +#if defined(_WIN32) + if (_wfopen_s(&fp, path, L"r") != 0) + return false; +#else if (!(fp = fopen(path, "r"))) return false; +#endif if (!(tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK))) { @@ -170,7 +175,7 @@ int LoadSave_loadRocketXML(const char* path, TrackData* trackData) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int LoadSave_loadRocketXMLDialog(char* path, TrackData* trackData) +int LoadSave_loadRocketXMLDialog(text_t* path, TrackData* trackData) { if (!Dialog_open(path)) return false; @@ -238,7 +243,7 @@ static void setElementFloat(mxml_node_t* node, char* attr, float v) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int LoadSave_saveRocketXML(const char* path, TrackData* trackData) +int LoadSave_saveRocketXML(const text_t* path, TrackData* trackData) { mxml_node_t* xml; mxml_node_t* tracks; @@ -251,7 +256,7 @@ int LoadSave_saveRocketXML(const char* path, TrackData* trackData) // save groups that are folded - for (p = 0; p < trackData->groupCount; ++p) + for (p = 0; p < (size_t)trackData->groupCount; ++p) { mxml_node_t* node; Group* group = &trackData->groups[p]; @@ -288,7 +293,13 @@ int LoadSave_saveRocketXML(const char* path, TrackData* trackData) } } + +#if defined(_WIN32) + _wfopen_s(&fp, path, L"wt"); +#else fp = fopen(path, "wt"); +#endif + mxmlSaveFile(xml, fp, whitespaceCallback); fclose(fp); @@ -297,7 +308,7 @@ int LoadSave_saveRocketXML(const char* path, TrackData* trackData) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int LoadSave_saveRocketXMLDialog(char* path, TrackData* trackData) +int LoadSave_saveRocketXMLDialog(text_t* path, TrackData* trackData) { if (!Dialog_save(path)) return false; diff --git a/ogl_editor/src/loadsave.h b/ogl_editor/src/loadsave.h index 3723d7c..cab8617 100644 --- a/ogl_editor/src/loadsave.h +++ b/ogl_editor/src/loadsave.h @@ -1,9 +1,11 @@ #pragma once +#include + struct TrackData; -int LoadSave_loadRocketXML(const char* path, struct TrackData* trackData); -int LoadSave_loadRocketXMLDialog(char* path, struct TrackData* trackData); -int LoadSave_saveRocketXML(const char* path, struct TrackData* trackData); -int LoadSave_saveRocketXMLDialog(char* path, struct TrackData* trackData); +int LoadSave_loadRocketXML(const text_t* path, struct TrackData* trackData); +int LoadSave_loadRocketXMLDialog(text_t* path, struct TrackData* trackData); +int LoadSave_saveRocketXML(const text_t* path, struct TrackData* trackData); +int LoadSave_saveRocketXMLDialog(text_t* path, struct TrackData* trackData); diff --git a/ogl_editor/src/windows/Dialogs.c b/ogl_editor/src/windows/Dialogs.c index 73cba95..631d924 100644 --- a/ogl_editor/src/windows/Dialogs.c +++ b/ogl_editor/src/windows/Dialogs.c @@ -2,7 +2,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int Dialog_open(char* path, int pathSize) +int Dialog_open(wchar_t* path, int pathSize) { OPENFILENAME ofn; @@ -11,7 +11,7 @@ int Dialog_open(char* path, int pathSize) ofn.lpstrFile = path; ofn.lpstrFile[0] = '\0'; ofn.nMaxFile = pathSize; - ofn.lpstrFilter = "All\0*.*\0Rocket\0*.Rocket\0"; + ofn.lpstrFilter = L"All\0*.*\0Rocket\0*.Rocket\0"; ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; diff --git a/ogl_editor/src/windows/RocketWindow.c b/ogl_editor/src/windows/RocketWindow.c index 71e3f6e..992de48 100644 --- a/ogl_editor/src/windows/RocketWindow.c +++ b/ogl_editor/src/windows/RocketWindow.c @@ -37,7 +37,7 @@ static void closeWindow() DestroyWindow(s_window); } - UnregisterClass("GLRocket", s_instance); + UnregisterClass(L"GLRocket", s_instance); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -49,7 +49,7 @@ void swapBuffers() /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bool createWindow(const char* title, int width, int height) +bool createWindow(const wchar_t* title, int width, int height) { GLuint format; WNDCLASS wc; @@ -93,14 +93,14 @@ bool createWindow(const char* title, int width, int height) wc.lpfnWndProc = (WNDPROC)WndProc; wc.hInstance = s_instance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.lpszClassName = "RocketEditor"; + wc.lpszClassName = L"RocketEditor"; wc.hIcon = LoadIcon(s_instance, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); if (!RegisterClass(&wc)) { - MessageBox(0, "Failed To Register Window Class", "ERROR", MB_OK | MB_ICONEXCLAMATION); + MessageBox(0, L"Failed To Register Window Class", L"ERROR", MB_OK | MB_ICONEXCLAMATION); return FALSE; } @@ -110,7 +110,7 @@ bool createWindow(const char* title, int width, int height) AdjustWindowRectEx(&rect, style, FALSE, exStyle); // Create The Window - if (!(s_window = CreateWindowEx(exStyle, "RocketEditor", title, style | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, + if (!(s_window = CreateWindowEx(exStyle, L"RocketEditor", title, style | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 0, 0, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, s_instance, NULL))) { closeWindow(); // Reset The Display @@ -157,7 +157,7 @@ bool createWindow(const char* title, int width, int height) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void Window_setTitle(const char* title) +void Window_setTitle(const wchar_t* title) { SetWindowText(s_window, title); } @@ -343,7 +343,7 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmndLine, i memset(&msg, 0, sizeof(MSG)); - if (!createWindow("RocketEditor", 800, 600)) + if (!createWindow(L"RocketEditor", 800, 600)) return 0; accel = LoadAccelerators(instance, MAKEINTRESOURCE(IDR_ACCELERATOR)); diff --git a/tundra.lua b/tundra.lua index 73fbeb4..55e46f1 100644 --- a/tundra.lua +++ b/tundra.lua @@ -2,11 +2,11 @@ local macosx = { Env = { CPPDEFS = { "EMGUI_MACOSX" }, CCOPTS = { - -- "-Weverything", + "-Wall", "-Wno-deprecated-declarations", -- TickCount issue no Mountain Lion (needs to be fixed) "-I.", "-DMACOSX", "-Wall", { "-O0", "-g"; Config = "*-*-debug" }, - { "-O3"; Config = "*-*-release" }, + { "-O4"; Config = "*-*-release" }, }, }, @@ -17,7 +17,7 @@ local win32 = { Env = { GENERATE_PDB = "1", CCOPTS = { - "/W4", "/I.", "/DWIN32", "/D_CRT_SECURE_NO_WARNINGS", + "/W4", "/I.", "/WX", "/DUNICODE", "/D_UNICODE", "/DWIN32", "/D_CRT_SECURE_NO_WARNINGS", "/wd4996", { "/Od"; Config = "*-*-debug" }, { "/O2"; Config = "*-*-release" }, },