From 70290b8c2b52c8bf354dd801043eb16bc609b156 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Sat, 7 Dec 2013 10:22:56 -0700 Subject: [PATCH] fixed locale code, added locale files, made wx use locale files, fixed some bugs, and added platform-specific files to the main program --- build/makefile.am | 6 ++-- libobs/obs-cocoa.c | 4 +-- libobs/obs-windows.c | 4 +-- libobs/util/config-file.c | 6 ++-- libobs/util/darray.h | 5 +-- libobs/util/lexer.c | 3 +- libobs/util/text-lookup.c | 57 ++++++++++++++++++++++++++------- obs/CMakeLists.txt | 14 +++++++- obs/makefile.am | 12 +++++++ obs/obs-app.cpp | 32 ++++++++++++++++-- obs/obs-app.hpp | 9 ++++++ obs/obs-wrappers.hpp | 28 ++++++++++++++++ obs/platform-nix.cpp | 25 +++++++++++++++ obs/platform-osx.cpp | 25 +++++++++++++++ obs/platform-windows.cpp | 27 ++++++++++++++++ obs/platform.hpp | 24 ++++++++++++++ obs/wx-subclass.hpp | 4 ++- obs/wx-wrappers.cpp | 14 ++++++++ obs/wx-wrappers.hpp | 1 + vs/2010/OBS/OBS.vcxproj | 2 ++ vs/2010/OBS/OBS.vcxproj.filters | 6 ++++ 21 files changed, 278 insertions(+), 30 deletions(-) create mode 100644 obs/platform-nix.cpp create mode 100644 obs/platform-osx.cpp create mode 100644 obs/platform-windows.cpp create mode 100644 obs/platform.hpp diff --git a/build/makefile.am b/build/makefile.am index 1e29d057d..248cb1513 100644 --- a/build/makefile.am +++ b/build/makefile.am @@ -2,9 +2,9 @@ obs_plugin_datadir = $(datadir)/obs-plugins obs_plugin_data_testdir = $(obs_plugin_datadir)/test-input data_libobsdir = $(datadir)/libobs -obs_plugin_data_test_DATA = data/test-input/draw.effect \ - data/test-input/test.effect -data_libobs_DATA = libobs/default.effect +obs_plugin_data_test_DATA = data/obs-plugins/test-input/draw.effect \ + data/obs-plugins/test-input/test.effect +data_libobs_DATA = data/libobs/default.effect #uninstall-local: # rm -r $(DESTDIR)$(obs_plugin_datadir) diff --git a/libobs/obs-cocoa.c b/libobs/obs-cocoa.c index a7d967e04..87c60a8cf 100644 --- a/libobs/obs-cocoa.c +++ b/libobs/obs-cocoa.c @@ -47,7 +47,7 @@ char *find_plugin(const char *plugin) char *find_libobs_data_file(const char *file) { struct dstr path; - dstr_init_copy(&path, "../libobs/"); + dstr_init_copy(&path, "../data/libobs/"); dstr_cat(&path, file); return path.array; } @@ -55,7 +55,7 @@ char *find_libobs_data_file(const char *file) char *obs_find_plugin_file(const char *file) { struct dstr path; - dstr_init_copy(&path, "../data/"); + dstr_init_copy(&path, "../data/obs-plugins/"); dstr_cat(&path, file); return path.array; } diff --git a/libobs/obs-windows.c b/libobs/obs-windows.c index c6913ed0d..b152486e8 100644 --- a/libobs/obs-windows.c +++ b/libobs/obs-windows.c @@ -37,7 +37,7 @@ char *find_plugin(const char *plugin) char *find_libobs_data_file(const char *file) { struct dstr path; - dstr_init_copy(&path, "../../libobs/"); + dstr_init_copy(&path, "../../data/libobs/"); dstr_cat(&path, file); return path.array; } @@ -46,7 +46,7 @@ char *find_libobs_data_file(const char *file) char *obs_find_plugin_file(const char *file) { struct dstr path; - dstr_init_copy(&path, "../../data/"); + dstr_init_copy(&path, "../../data/obs-plugins/"); dstr_cat(&path, file); return path.array; } diff --git a/libobs/util/config-file.c b/libobs/util/config-file.c index 53b87c48a..e8fa6ded5 100644 --- a/libobs/util/config-file.c +++ b/libobs/util/config-file.c @@ -340,11 +340,11 @@ static struct config_item *config_find_item(struct darray *sections, struct config_section *sec = darray_item( sizeof(struct config_section), sections, i); - if (astrcmpi(sec->name, section) != 0) { + if (astrcmpi(sec->name, section) == 0) { for (j = 0; j < sec->items.num; j++) { struct config_item *item = darray_item( sizeof(struct config_item), - &sec->items, i); + &sec->items, j); if (astrcmpi(item->name, name) == 0) return item; @@ -369,7 +369,7 @@ static void config_set_item(struct darray *sections, const char *section, if (astrcmpi(cur_sec->name, section) == 0) { for (j = 0; j < cur_sec->items.num; j++) { - item = items+i; + item = items+j; if (astrcmpi(item->name, name) == 0) { bfree(item->value); diff --git a/libobs/util/darray.h b/libobs/util/darray.h index fa416880e..53343812a 100644 --- a/libobs/util/darray.h +++ b/libobs/util/darray.h @@ -171,8 +171,9 @@ static inline void darray_move(struct darray *dst, struct darray *src) { darray_free(dst); memcpy(dst, src, sizeof(struct darray)); - src->array = NULL; - src->num = 0; + src->array = NULL; + src->capacity = 0; + src->num = 0; } static inline size_t darray_find(const size_t element_size, diff --git a/libobs/util/lexer.c b/libobs/util/lexer.c index e094bcb9b..d15424657 100644 --- a/libobs/util/lexer.c +++ b/libobs/util/lexer.c @@ -271,7 +271,7 @@ bool lexer_getbasetoken(struct lexer *lex, struct base_token *token, token_start = offset-1; type = new_type; - if (type != BASETOKEN_DIGIT || + if (type != BASETOKEN_DIGIT && type != BASETOKEN_ALPHA) { if (is_newline(ch) && is_newline_pair(ch, *offset)) { @@ -280,6 +280,7 @@ bool lexer_getbasetoken(struct lexer *lex, struct base_token *token, break; } } else if (type != new_type) { + offset--; break; } } diff --git a/libobs/util/text-lookup.c b/libobs/util/text-lookup.c index 69bcaf314..3f848562f 100644 --- a/libobs/util/text-lookup.c +++ b/libobs/util/text-lookup.c @@ -33,10 +33,11 @@ struct text_leaf { char *lookup, *value; }; -static inline void text_leaf_free(struct text_leaf *leaf) +static inline void text_leaf_destroy(struct text_leaf *leaf) { bfree(leaf->lookup); bfree(leaf->value); + bfree(leaf); } /* ------------------------------------------------------------------------- */ @@ -60,7 +61,7 @@ static void text_node_destroy(struct text_node *node) for (i = 0; i < node->subnodes.num; i++) text_node_destroy(subnodes[i]); if (node->leaf) - text_leaf_free(node->leaf); + text_leaf_destroy(node->leaf); darray_free(&node->subnodes); bfree(node); } @@ -171,7 +172,7 @@ static bool lookup_addstring(const char *lookup_val, struct text_leaf *leaf, else lookup_splitnode(lookup_val, len, leaf, child); } else { - lookup_createsubnode(lookup_val, leaf, child); + lookup_createsubnode(lookup_val, leaf, node); } return true; @@ -187,7 +188,7 @@ static void lookup_getstringtoken(struct lexer *lex, struct strref *token) if (*temp == '\\') { was_backslash = true; } else if (*temp == '"') { - ++temp; + temp++; break; } } else { @@ -197,8 +198,16 @@ static void lookup_getstringtoken(struct lexer *lex, struct strref *token) ++temp; } - /* include starting " char */ - token->len += (size_t)(temp - lex->offset - 1); + token->len += (size_t)(temp - lex->offset); + + if (*token->array == '"') { + token->array++; + token->len--; + } + + if (*(temp-1) == '"') + token->len--; + lex->offset = temp; } @@ -217,19 +226,26 @@ static bool lookup_gettoken(struct lexer *lex, struct strref *str) if (ch == '#') { while(ch != '\n' && ch != 0) ch = *(++lex->offset); + } else if (temp.type == BASETOKEN_WHITESPACE) { + strref_copy(str, &temp.text); + break; } else { strref_copy(str, &temp.text); + if (ch == '"') { + lookup_getstringtoken(lex, str); + break; + } else if (ch == '=') { + break; + } } } else { - if (temp.type == BASETOKEN_WHITESPACE) { + if (temp.type == BASETOKEN_WHITESPACE || + *temp.text.array == '=') { lex->offset -= temp.text.len; break; } - if (ch == '"') { - lookup_getstringtoken(lex, str); - break; - } else if (ch == '#') { + if (ch == '#') { lex->offset--; break; } @@ -260,12 +276,27 @@ static inline bool lookup_goto_nextline(struct lexer *p) return success; } +static char *convert_string(const char *str, size_t len) +{ + struct dstr out; + out.array = bstrdup_n(str, len); + out.capacity = len+1; + out.len = len; + + dstr_replace(&out, "\\n", "\n"); + dstr_replace(&out, "\\t", "\t"); + dstr_replace(&out, "\\r", "\r"); + + return out.array; +} + static void lookup_addfiledata(struct text_lookup *lookup, const char *file_data) { struct lexer lex; struct strref name, value; + lexer_init(&lex); lexer_start(&lex, file_data); strref_clear(&name); strref_clear(&value); @@ -288,13 +319,15 @@ getval: leaf = bmalloc(sizeof(struct text_leaf)); leaf->lookup = bstrdup_n(name.array, name.len); - leaf->value = bstrdup_n(value.array, value.len); + leaf->value = convert_string(value.array, value.len); lookup_addstring(leaf->lookup, leaf, lookup->top); if (!lookup_goto_nextline(&lex)) break; } + + lexer_free(&lex); } static inline bool lookup_getstring(const char *lookup_val, diff --git a/obs/CMakeLists.txt b/obs/CMakeLists.txt index 35bda4f16..39a731146 100644 --- a/obs/CMakeLists.txt +++ b/obs/CMakeLists.txt @@ -29,12 +29,24 @@ include_directories(SYSTEM ${obs_SOURCE_DIR}/libobs) link_libraries(${wxWidgets_LIBRARIES} libobs) +if(WIN32) + set(obs_platform_src + platform-windows.cpp) +elseif(APPLE) + set(obs_platform_src + platform-osx.cpp) +elseif(UNIX) + set(obs_platform_src + platform-nix.cpp) +endif() + add_executable(obs window-main-basic.cpp wx-subclass.cpp wx-wrappers.cpp obs-app.cpp - forms/OBSWindows.cpp) + forms/OBSWindows.cpp + ${obs_platform_src}) if(APPLE) set_target_properties(obs PROPERTIES diff --git a/obs/makefile.am b/obs/makefile.am index 7953aff5b..acef263ed 100644 --- a/obs/makefile.am +++ b/obs/makefile.am @@ -17,3 +17,15 @@ obs_SOURCES = window-main-basic.cpp \ wx-subclass.cpp \ wx-wrappers.cpp \ forms/OBSWindows.cpp + +if OS_WIN +obs_SOURCES += platform-windows.cpp +endif + +if OS_OSX +obs_SOURCES += platform-osx.cpp +endif + +if OS_NIX +obs_SOURCES += platform-nix.cpp +endif diff --git a/obs/obs-app.cpp b/obs/obs-app.cpp index 3c98e1b70..00dcd9965 100644 --- a/obs/obs-app.cpp +++ b/obs/obs-app.cpp @@ -24,6 +24,7 @@ #include "window-main-basic.hpp" #include "obs-wrappers.hpp" #include "wx-wrappers.hpp" +#include "platform.hpp" using namespace std; @@ -50,6 +51,7 @@ static void do_log(enum log_type type, const char *msg, va_list args) void OBSApp::InitGlobalConfigDefaults() { + config_set_default_string(globalConfig, "General", "Language", "en-US"); config_set_default_int(globalConfig, "Window", "PosX", -1); config_set_default_int(globalConfig, "Window", "PosY", -1); config_set_default_int(globalConfig, "Window", "SizeX", -1); @@ -59,7 +61,7 @@ void OBSApp::InitGlobalConfigDefaults() static bool do_mkdir(const char *path) { if (os_mkdir(path) == MKDIR_ERROR) { - blog(LOG_ERROR, "Failed to create directory %s", path); + OBSErrorBox(NULL, "Failed to create directory %s", path); return false; } @@ -84,7 +86,7 @@ bool OBSApp::InitGlobalConfig() stringstream str; if (!homePath) { - blog(LOG_ERROR, "Failed to get home path"); + OBSErrorBox(NULL, "Failed to get home path"); return false; } @@ -93,7 +95,7 @@ bool OBSApp::InitGlobalConfig() int errorcode = globalConfig.Open(path.c_str(), CONFIG_OPEN_ALWAYS); if (errorcode != CONFIG_SUCCESS) { - blog(LOG_ERROR, "Failed to open global.ini: %d", errorcode); + OBSErrorBox(NULL, "Failed to open global.ini: %d", errorcode); return false; } @@ -101,6 +103,27 @@ bool OBSApp::InitGlobalConfig() return true; } +bool OBSApp::InitLocale() +{ + const char *lang = config_get_string(globalConfig, "General", + "Language"); + + stringstream file; + file << "locale/" << lang << ".txt"; + + string path; + if (!GetDataFilePath(file.str().c_str(), path)) { + /* use en-US by default if language file is not found */ + if (!GetDataFilePath("locale/en-US.txt", path)) { + OBSErrorBox(NULL, "Failed to open locale file"); + return false; + } + } + + textLookup = text_lookup_create(path.c_str()); + return true; +} + bool OBSApp::OnInit() { base_set_log_handler(do_log); @@ -111,6 +134,8 @@ bool OBSApp::OnInit() return false; if (!InitGlobalConfig()) return false; + if (!InitLocale()) + return false; if (!obs_startup()) return false; @@ -120,6 +145,7 @@ bool OBSApp::OnInit() OBSBasic *mainWindow = new OBSBasic(); + /* this is a test */ struct obs_video_info ovi; ovi.graphics_module = "libobs-opengl"; ovi.fps_num = 30000; diff --git a/obs/obs-app.hpp b/obs/obs-app.hpp index 3f9daef6b..01f4cdb59 100644 --- a/obs/obs-app.hpp +++ b/obs/obs-app.hpp @@ -28,16 +28,25 @@ public: class OBSApp : public OBSAppBase { ConfigFile globalConfig; + TextLookup textLookup; wxFrame *dummyWindow; bool InitGlobalConfig(); void InitGlobalConfigDefaults(); bool InitConfigDefaults(); + bool InitLocale(); public: virtual bool OnInit(); virtual int OnExit(); virtual void CleanUp(); + + inline const char *GetString(const char *lookupVal) + { + return textLookup.GetString(lookupVal); + } }; wxDECLARE_APP(OBSApp); + +#define Str(lookupVal) wxGetApp().GetString(lookupVal) diff --git a/obs/obs-wrappers.hpp b/obs/obs-wrappers.hpp index 9b4627193..e3dd9b76a 100644 --- a/obs/obs-wrappers.hpp +++ b/obs/obs-wrappers.hpp @@ -21,6 +21,7 @@ #include #include +#include #include /* RAII wrappers */ @@ -79,6 +80,33 @@ public: inline operator config_t() {return config;} }; +class TextLookup { + lookup_t lookup; + +public: + inline TextLookup() : lookup(NULL) {} + inline TextLookup(lookup_t lookup) : lookup(lookup) {} + inline ~TextLookup() {text_lookup_destroy(lookup);} + + inline TextLookup& operator=(lookup_t val) + { + text_lookup_destroy(lookup); + lookup = val; + return *this; + } + + inline operator lookup_t() {return lookup;} + + inline const char *GetString(const char *lookupVal) + { + const char *out; + if (!text_lookup_getstr(lookup, lookupVal, &out)) + return lookupVal; + + return out; + } +}; + class OBSSource { obs_source_t source; diff --git a/obs/platform-nix.cpp b/obs/platform-nix.cpp new file mode 100644 index 000000000..dfc3bcee1 --- /dev/null +++ b/obs/platform-nix.cpp @@ -0,0 +1,25 @@ +/****************************************************************************** + Copyright (C) 2013 by Hugh Bailey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#include +#include "platform.hpp" + +bool GetDataFilePath(const char *data, string &output) +{ + // TODO + return true; +} diff --git a/obs/platform-osx.cpp b/obs/platform-osx.cpp new file mode 100644 index 000000000..dfc3bcee1 --- /dev/null +++ b/obs/platform-osx.cpp @@ -0,0 +1,25 @@ +/****************************************************************************** + Copyright (C) 2013 by Hugh Bailey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#include +#include "platform.hpp" + +bool GetDataFilePath(const char *data, string &output) +{ + // TODO + return true; +} diff --git a/obs/platform-windows.cpp b/obs/platform-windows.cpp new file mode 100644 index 000000000..ea388bc25 --- /dev/null +++ b/obs/platform-windows.cpp @@ -0,0 +1,27 @@ +/****************************************************************************** + Copyright (C) 2013 by Hugh Bailey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#include +#include "platform.hpp" + +bool GetDataFilePath(const char *data, string &output) +{ + stringstream str; + str << "../../data/obs-studio/" << data; + output = str.str(); + return true; +} diff --git a/obs/platform.hpp b/obs/platform.hpp new file mode 100644 index 000000000..478ca9dc7 --- /dev/null +++ b/obs/platform.hpp @@ -0,0 +1,24 @@ +/****************************************************************************** + Copyright (C) 2013 by Hugh Bailey + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +******************************************************************************/ + +#pragma once + +#include +using namespace std; + +/* Gets the path of obs-studio specific data files (such as locale) */ +bool GetDataFilePath(const char *data, string &path); diff --git a/obs/wx-subclass.hpp b/obs/wx-subclass.hpp index 26cc761b5..9efec6419 100644 --- a/obs/wx-subclass.hpp +++ b/obs/wx-subclass.hpp @@ -19,6 +19,8 @@ #include #include +#include "obs-app.hpp" + /* * Fixes windows fonts to be default dialog fonts (I don't give a crap what * microsoft "recommends", the fonts they recommend look like utter garbage) @@ -26,7 +28,7 @@ #ifdef _ #undef _ -#define _(str) str +#define _(str) Str(str) #endif class WindowSubclass : public wxFrame { diff --git a/obs/wx-wrappers.cpp b/obs/wx-wrappers.cpp index 2d5d7757f..554833806 100644 --- a/obs/wx-wrappers.cpp +++ b/obs/wx-wrappers.cpp @@ -16,6 +16,7 @@ ******************************************************************************/ #include +#include #include #include "wx-wrappers.hpp" @@ -31,3 +32,16 @@ gs_window WxToGSWindow(const wxWindow *wxwin) #endif return window; } + +void OBSErrorBox(wxWindow *parent, const char *message, ...) +{ + va_list args; + char output[4096]; + + va_start(args, message); + vsnprintf(output, 4095, message, args); + va_end(args); + + wxMessageBox(message, "Error"); + blog(LOG_ERROR, "%s", output); +} diff --git a/obs/wx-wrappers.hpp b/obs/wx-wrappers.hpp index 9281c1ce1..77e911d4f 100644 --- a/obs/wx-wrappers.hpp +++ b/obs/wx-wrappers.hpp @@ -21,3 +21,4 @@ struct gs_window; class wxWindow; gs_window WxToGSWindow(const wxWindow *window); +void OBSErrorBox(wxWindow *parent, const char *message, ...); diff --git a/vs/2010/OBS/OBS.vcxproj b/vs/2010/OBS/OBS.vcxproj index e3647aa27..c0395b597 100644 --- a/vs/2010/OBS/OBS.vcxproj +++ b/vs/2010/OBS/OBS.vcxproj @@ -169,6 +169,7 @@ + @@ -177,6 +178,7 @@ + diff --git a/vs/2010/OBS/OBS.vcxproj.filters b/vs/2010/OBS/OBS.vcxproj.filters index a21fb31d4..bd92426ba 100644 --- a/vs/2010/OBS/OBS.vcxproj.filters +++ b/vs/2010/OBS/OBS.vcxproj.filters @@ -33,6 +33,9 @@ Source Files + + Source Files + @@ -53,5 +56,8 @@ Header Files + + Header Files + \ No newline at end of file -- GitLab