Browse Source

fixed locale code, added locale files, made wx use locale files, fixed some bugs, and added platform-specific files to the main program

jp9000 12 năm trước cách đây
mục cha
commit
70290b8c2b

+ 3 - 3
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)

+ 2 - 2
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;
 }

+ 2 - 2
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;
 }

+ 3 - 3
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);

+ 3 - 2
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,

+ 2 - 1
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;
 		}
 	}

+ 45 - 12
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,

+ 13 - 1
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

+ 12 - 0
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

+ 29 - 3
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;

+ 9 - 0
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)

+ 28 - 0
obs/obs-wrappers.hpp

@@ -21,6 +21,7 @@
 #include <stdarg.h>
 
 #include <util/config-file.h>
+#include <util/text-lookup.h>
 #include <obs.h>
 
 /* 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;
 

+ 25 - 0
obs/platform-nix.cpp

@@ -0,0 +1,25 @@
+/******************************************************************************
+    Copyright (C) 2013 by Hugh Bailey <[email protected]>
+
+    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 <http://www.gnu.org/licenses/>.
+******************************************************************************/
+
+#include <sstream>
+#include "platform.hpp"
+
+bool GetDataFilePath(const char *data, string &output)
+{
+	// TODO
+	return true;
+}

+ 25 - 0
obs/platform-osx.cpp

@@ -0,0 +1,25 @@
+/******************************************************************************
+    Copyright (C) 2013 by Hugh Bailey <[email protected]>
+
+    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 <http://www.gnu.org/licenses/>.
+******************************************************************************/
+
+#include <sstream>
+#include "platform.hpp"
+
+bool GetDataFilePath(const char *data, string &output)
+{
+	// TODO
+	return true;
+}

+ 27 - 0
obs/platform-windows.cpp

@@ -0,0 +1,27 @@
+/******************************************************************************
+    Copyright (C) 2013 by Hugh Bailey <[email protected]>
+
+    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 <http://www.gnu.org/licenses/>.
+******************************************************************************/
+
+#include <sstream>
+#include "platform.hpp"
+
+bool GetDataFilePath(const char *data, string &output)
+{
+	stringstream str;
+	str << "../../data/obs-studio/" << data;
+	output = str.str();
+	return true;
+}

+ 24 - 0
obs/platform.hpp

@@ -0,0 +1,24 @@
+/******************************************************************************
+    Copyright (C) 2013 by Hugh Bailey <[email protected]>
+
+    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 <http://www.gnu.org/licenses/>.
+******************************************************************************/
+
+#pragma once
+
+#include <string>
+using namespace std;
+
+/* Gets the path of obs-studio specific data files (such as locale) */
+bool GetDataFilePath(const char *data, string &path);

+ 3 - 1
obs/wx-subclass.hpp

@@ -19,6 +19,8 @@
 #include <wx/frame.h>
 #include <wx/listctrl.h>
 
+#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 {

+ 14 - 0
obs/wx-wrappers.cpp

@@ -16,6 +16,7 @@
 ******************************************************************************/
 
 #include <wx/window.h>
+#include <wx/msgdlg.h>
 #include <obs.h>
 #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);
+}

+ 1 - 0
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, ...);

+ 2 - 0
vs/2010/OBS/OBS.vcxproj

@@ -169,6 +169,7 @@
   <ItemGroup>
     <ClCompile Include="..\..\..\obs\forms\OBSWindows.cpp" />
     <ClCompile Include="..\..\..\obs\obs-app.cpp" />
+    <ClCompile Include="..\..\..\obs\platform-windows.cpp" />
     <ClCompile Include="..\..\..\obs\window-main-basic.cpp" />
     <ClCompile Include="..\..\..\obs\wx-subclass.cpp" />
     <ClCompile Include="..\..\..\obs\wx-wrappers.cpp" />
@@ -177,6 +178,7 @@
     <ClInclude Include="..\..\..\obs\forms\OBSWindows.h" />
     <ClInclude Include="..\..\..\obs\obs-app.hpp" />
     <ClInclude Include="..\..\..\obs\obs-wrappers.hpp" />
+    <ClInclude Include="..\..\..\obs\platform.hpp" />
     <ClInclude Include="..\..\..\obs\window-main-basic.hpp" />
     <ClInclude Include="..\..\..\obs\wx-subclass.hpp" />
     <ClInclude Include="..\..\..\obs\wx-wrappers.hpp" />

+ 6 - 0
vs/2010/OBS/OBS.vcxproj.filters

@@ -33,6 +33,9 @@
     <ClCompile Include="..\..\..\obs\wx-subclass.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\obs\platform-windows.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\obs\obs-app.hpp">
@@ -53,5 +56,8 @@
     <ClInclude Include="..\..\..\obs\wx-subclass.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\obs\platform.hpp">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>