X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=theme.cpp;h=32a00ff7ec4ba639939bf34527b414a6ed120255;hb=e284d1c7a2e18ee7e4aea082c4a57a3504a0f5e8;hp=5fc5a7538cee288ae7e3fc335c1550bfdfe1dd2e;hpb=4ed8afda0ec060a66ca6af76d15afe62af543849;p=nageru diff --git a/theme.cpp b/theme.cpp index 5fc5a75..32a00ff 100644 --- a/theme.cpp +++ b/theme.cpp @@ -1090,24 +1090,7 @@ Theme::Theme(const string &filename, const vector &search_dirs, Resource L = luaL_newstate(); luaL_openlibs(L); - register_constants(); - register_class("EffectChain", EffectChain_funcs); - register_class("LiveInputWrapper", LiveInputWrapper_funcs); - register_class("ImageInput", ImageInput_funcs); - register_class("VideoInput", VideoInput_funcs); - register_class("HTMLInput", HTMLInput_funcs); - register_class("WhiteBalanceEffect", WhiteBalanceEffect_funcs); - register_class("ResampleEffect", ResampleEffect_funcs); - register_class("PaddingEffect", PaddingEffect_funcs); - register_class("IntegralPaddingEffect", IntegralPaddingEffect_funcs); - register_class("OverlayEffect", OverlayEffect_funcs); - register_class("ResizeEffect", ResizeEffect_funcs); - register_class("MultiplyEffect", MultiplyEffect_funcs); - register_class("MixEffect", MixEffect_funcs); - register_class("InputStateInfo", InputStateInfo_funcs); - register_class("ThemeMenu", ThemeMenu_funcs); - - // Run script. Search through all directories until we find a file that will load + // Search through all directories until we find a file that will load // (as in, does not return LUA_ERRFILE); then run it. We store load errors // from all the attempts, and show them once we know we can't find any of them. lua_settop(L, 0); @@ -1121,8 +1104,9 @@ Theme::Theme(const string &filename, const vector &search_dirs, Resource real_search_dirs = search_dirs; } + string path; + int theme_code_ref; for (const string &dir : real_search_dirs) { - string path; if (dir.empty()) { path = filename; } else { @@ -1130,11 +1114,13 @@ Theme::Theme(const string &filename, const vector &search_dirs, Resource } int err = luaL_loadfile(L, path.c_str()); if (err == 0) { - // Success; actually call the code. - if (lua_pcall(L, 0, LUA_MULTRET, 0)) { - fprintf(stderr, "Error when running %s: %s\n", path.c_str(), lua_tostring(L, -1)); - exit(1); - } + // Save the theme for when we're actually going to run it + // (we need to set up the right environment below first, + // and we couldn't do that before, because we didn't know the + // path to put in Nageru.THEME_PATH). + theme_code_ref = luaL_ref(L, LUA_REGISTRYINDEX); + assert(lua_gettop(L) == 0); + success = true; break; } @@ -1154,6 +1140,46 @@ Theme::Theme(const string &filename, const vector &search_dirs, Resource } assert(lua_gettop(L) == 0); + // Make sure the path exposed to the theme (as Nageru.THEME_PATH; + // can be useful for locating files when talking to CEF) is absolute. + // In a sense, it would be nice if realpath() had a mode not to + // resolve symlinks, but it doesn't, so we only call it if we don't + // already have an absolute path (which may leave ../ elements etc.). + if (path[0] == '/') { + theme_path = path; + } else { + char *absolute_theme_path = realpath(path.c_str(), nullptr); + theme_path = absolute_theme_path; + free(absolute_theme_path); + } + + // Set up the API we provide. + register_constants(); + register_class("EffectChain", EffectChain_funcs); + register_class("LiveInputWrapper", LiveInputWrapper_funcs); + register_class("ImageInput", ImageInput_funcs); + register_class("VideoInput", VideoInput_funcs); + register_class("HTMLInput", HTMLInput_funcs); + register_class("WhiteBalanceEffect", WhiteBalanceEffect_funcs); + register_class("ResampleEffect", ResampleEffect_funcs); + register_class("PaddingEffect", PaddingEffect_funcs); + register_class("IntegralPaddingEffect", IntegralPaddingEffect_funcs); + register_class("OverlayEffect", OverlayEffect_funcs); + register_class("ResizeEffect", ResizeEffect_funcs); + register_class("MultiplyEffect", MultiplyEffect_funcs); + register_class("MixEffect", MixEffect_funcs); + register_class("InputStateInfo", InputStateInfo_funcs); + register_class("ThemeMenu", ThemeMenu_funcs); + + // Now actually run the theme to get everything set up. + lua_rawgeti(L, LUA_REGISTRYINDEX, theme_code_ref); + luaL_unref(L, LUA_REGISTRYINDEX, theme_code_ref); + if (lua_pcall(L, 0, 0, 0)) { + fprintf(stderr, "Error when running %s: %s\n", path.c_str(), lua_tostring(L, -1)); + exit(1); + } + assert(lua_gettop(L) == 0); + // Ask it for the number of channels. num_channels = call_num_channels(L); } @@ -1166,18 +1192,26 @@ Theme::~Theme() void Theme::register_constants() { // Set Nageru.VIDEO_FORMAT_BGRA = bmusb::PixelFormat_8BitBGRA, etc. - const vector> constants = { + const vector> num_constants = { { "VIDEO_FORMAT_BGRA", bmusb::PixelFormat_8BitBGRA }, { "VIDEO_FORMAT_YCBCR", bmusb::PixelFormat_8BitYCbCrPlanar }, }; + const vector> str_constants = { + { "THEME_PATH", theme_path }, + }; lua_newtable(L); // t = {} - for (const pair &constant : constants) { + for (const pair &constant : num_constants) { lua_pushstring(L, constant.first.c_str()); lua_pushinteger(L, constant.second); lua_settable(L, 1); // t[key] = value } + for (const pair &constant : str_constants) { + lua_pushstring(L, constant.first.c_str()); + lua_pushstring(L, constant.second.c_str()); + lua_settable(L, 1); // t[key] = value + } lua_setglobal(L, "Nageru"); // Nageru = t assert(lua_gettop(L) == 0);