diff --git a/binding/oneshot-binding.cpp b/binding/oneshot-binding.cpp index 120cb49ca..a138aedef 100644 --- a/binding/oneshot-binding.cpp +++ b/binding/oneshot-binding.cpp @@ -119,8 +119,34 @@ void oneshotBindingInit() { rb_const_set(module, rb_intern("OS"), rb_str_new2(shState->oneshot().os().c_str())); #ifdef __linux__ - rb_const_set(module, rb_intern("DE"), - rb_str_new2(shState->oneshot().desktopEnv.c_str())); + const char *text; + switch (shState->oneshot().desktop) { + case Oneshot::DE_GNOME: + text = "gnome"; + break; + case Oneshot::DE_CINNAMON: + text = "cinnamon"; + break; + case Oneshot::DE_MATE: + text = "mate"; + break; + case Oneshot::DE_LXDE: + text = "lxde"; + break; + case Oneshot::DE_XFCE: + text = "xfce"; + break; + case Oneshot::DE_KDE: + text = "kde"; + break; + case Oneshot::DE_DEEPIN: + text = "deepin"; + break; + case Oneshot::DE_FALLBACK: + text = "fallback"; + break; + } + rb_const_set(module, rb_intern("DE"), rb_str_new2(text)); #endif rb_const_set(module, rb_intern("USER_NAME"), rb_str_new2(shState->oneshot().userName().c_str())); diff --git a/binding/oneshot-wallpaper-binding.cpp b/binding/oneshot-wallpaper-binding.cpp index 81415521f..00a1016f2 100644 --- a/binding/oneshot-wallpaper-binding.cpp +++ b/binding/oneshot-wallpaper-binding.cpp @@ -1,505 +1,665 @@ #include -#include +#include #include -#include +#include #include +#include +#include -#include - -#include "etc.h" -#include "sharedstate.h" -#include "binding-util.h" #include "binding-types.h" +#include "binding-util.h" #include "config.h" -#include "oneshot.h" #include "debugwriter.h" +#include "etc.h" +#include "oneshot.h" +#include "sharedstate.h" #ifdef _WIN32 - #include - static WCHAR szStyle[8] = {0}; - static WCHAR szTile[8] = {0}; - static WCHAR szFile[MAX_PATH+1] = {0}; - static DWORD oldcolor = 0; - static DWORD szStyleSize = sizeof(szStyle) - 1; - static DWORD szTileSize = sizeof(szTile) - 1; - static bool setStyle = false; - static bool setTile = false; - static bool isCached = false; +#include +static WCHAR szStyle[8] = {0}; +static WCHAR szTile[8] = {0}; +static WCHAR szFile[MAX_PATH + 1] = {0}; +static DWORD oldcolor = 0; +static DWORD szStyleSize = sizeof(szStyle) - 1; +static DWORD szTileSize = sizeof(szTile) - 1; +static bool setStyle = false; +static bool setTile = false; +static bool isCached = false; +#else +#ifdef __APPLE__ +#include "mac-desktop.h" +static bool isCached = false; #else - #ifdef __APPLE__ - #include "mac-desktop.h" - static bool isCached = false; - #else - #include - #include - #include - #include - #include - #include - #include - static std::string desktop = "uninitialized"; - // GNOME settings - static GSettings *bgsetting; - static std::string defPictureURI, defPictureOptions, defPrimaryColor, defColorShading; - // XFCE settings - static XfconfChannel* bgchannel; - static int defPictureStyle; - static int defColorStyle; - static GValue defColor = G_VALUE_INIT; - static bool defColorExists; - static std::string optionImage, optionColor, optionImageStyle, optionColorStyle; - // KDE settings - static std::map defPlugins, defPictures, defColors, defModes; - static std::map defBlurs; - // Fallback settings - static std::string fallbackPath; - #endif +#include +#include +#include +#include +#include +#include + +struct XfconfChannel; +typedef gboolean (*xfconf_init_fn)(GError **error); +typedef void (*xfconf_shutdown_fn)(void); + +typedef XfconfChannel *(*xfconf_channel_get_fn)(const gchar *channel_name); +typedef gchar *(*xfconf_channel_get_string_fn)(XfconfChannel *channel, + const gchar *property, + const gchar *default_value); +typedef gboolean (*xfconf_channel_set_string_fn)(XfconfChannel *channel, + const gchar *property, + const gchar *value); +typedef gint32 (*xfconf_channel_get_int_fn)(XfconfChannel *channel, + const gchar *property, + gint32 default_value); +typedef gboolean (*xfconf_channel_set_int_fn)(XfconfChannel *channel, + const gchar *property, + gint32 value); + +typedef gboolean (*xfconf_channel_get_property_fn)(XfconfChannel *channel, + const gchar *property, + GValue *value); +typedef gboolean (*xfconf_channel_set_property_fn)(XfconfChannel *channel, + const gchar *property, + const GValue *value); + +typedef void (*xfconf_channel_reset_property_fn)(XfconfChannel *channel, + const gchar *property_base, + gboolean recursive); + +struct DesktopEnv { + DesktopEnv(); + ~DesktopEnv(); + + void set_wallpaper(std::string path, std::string gameDirStr, int color); + void reset_wallpaper(); + + Oneshot::Desktop desktop; + + // GNOME settings + GSettings *bgsetting; + std::string defPictureURI, defPictureOptions, defPrimaryColor, + defColorShading; + // XFCE settings + XfconfChannel *bgchannel; + void *xfconf_dl; + int defPictureStyle; + int defColorStyle; + GValue defColor = G_VALUE_INIT; + bool defColorExists; + std::string optionImage, optionColor, optionImageStyle, optionColorStyle; + // KDE settings + std::map defPlugins, defPictures, defColors, + defModes; + std::map defBlurs; + // Fallback settings + std::string fallbackPath; +}; +static DesktopEnv *env; + +#endif #endif #ifdef __linux__ - void desktopEnvironmentInit() - { - if (desktop != "uninitialized") { - return; - } - desktop = shState->oneshot().desktopEnv; - if (desktop == "cinnamon" || desktop == "gnome" || desktop == "mate" || desktop == "deepin") { - if (desktop == "cinnamon" || desktop == "gnome" || desktop == "deepin") { - if (desktop == "cinnamon") bgsetting = g_settings_new("org.cinnamon.desktop.background"); - else if (desktop == "deepin") bgsetting = g_settings_new("com.deepin.wrap.gnome.desktop.background"); - else bgsetting = g_settings_new("org.gnome.desktop.background"); - defPictureURI = g_settings_get_string(bgsetting, "picture-uri"); - } else { - bgsetting = g_settings_new("org.mate.background"); - defPictureURI = g_settings_get_string(bgsetting, "picture-filename"); - } - defPictureOptions = g_settings_get_string(bgsetting, "picture-options"); - defPrimaryColor = g_settings_get_string(bgsetting, "primary-color"); - defColorShading = g_settings_get_string(bgsetting, "color-shading-type"); - } else if (desktop == "xfce") { - GError *xferror = NULL; - if (xfconf_init(&xferror)) { - bgchannel = xfconf_channel_get("xfce4-desktop"); - std::string optionPrefix = "/backdrop/screen0/monitor0/workspace0/"; - optionImage = optionPrefix + "last-image"; - optionColor = optionPrefix + "color1"; - optionImageStyle = optionPrefix + "image-style"; - optionColorStyle = optionPrefix + "color-style"; - defPictureURI = xfconf_channel_get_string(bgchannel, optionImage.c_str(), ""); - defPictureStyle = xfconf_channel_get_int(bgchannel, optionImageStyle.c_str(), -1); - defColorExists = xfconf_channel_get_property(bgchannel, optionColor.c_str(), &defColor); - defColorStyle = xfconf_channel_get_int(bgchannel, optionColorStyle.c_str(), -1); - } else { - // Configuration failed to initialize, we won't set the wallpaper - desktop = "xfce_error"; - g_error_free(xferror); - } - } else if (desktop == "kde") { - std::ifstream configFile; - configFile.open(std::string(getenv("HOME")) + "/.config/plasma-org.kde.plasma.desktop-appletsrc", std::ios::in); - if (configFile.is_open()) { - std::string line; - std::vector sections; - std::size_t undefined = 999999999; - bool readPlugin = false, readOther = false; - std::string containment; - while (getline(configFile, line)) { - std::size_t index = undefined, lastIndex = undefined; - if (line.size() == 0) { - readPlugin = false; - readOther = false; - } else if (readPlugin) { - index = line.find('='); - if (line.substr(0, index) == "wallpaperplugin") { - defPlugins[containment] = line.substr(index + 1); - } - } else if (readOther) { - index = line.find('='); - std::string key = line.substr(0, index); - std::string val = line.substr(index + 1); - if (key == "Image") { - defPictures[containment] = val; - } else if (key == "Color") { - defColors[containment] = val; - } else if (key == "FillMode") { - defModes[containment] = val; - } else if (key == "Blur") { - defBlurs[containment] = (val == "true"); - } - } else if (line.at(0) == '[') { - sections.clear(); - while (true) { - index = line.find(lastIndex == undefined ? '[' : ']', index == undefined ? 0 : index); - if (index == std::string::npos) { - break; - } - if (lastIndex == undefined) { - lastIndex = index; - } else { - sections.push_back(line.substr(lastIndex + 1, index - lastIndex - 1)); - lastIndex = undefined; - } - } - if (sections.size() == 2 && sections[0] == "Containments") { - readPlugin = true; - containment = sections[1]; - } else if ( - sections.size() == 5 && - sections[0] == "Containments" && - sections[2] == "Wallpaper" && - sections[3] == "org.kde.image" && - sections[4] == "General" - ) { - readOther = true; - containment = sections[1]; - } - } - } - configFile.close(); - } else { - Debug() << "FATAL: Cannot find desktop configuration!"; - desktop = "kde_error"; - } - } else { - fallbackPath = std::string(getenv("HOME")) + "/Desktop/ONESHOT_hint.png"; - } - } +DesktopEnv::DesktopEnv() { + desktop = shState->oneshot().desktop; + switch (desktop) { + case Oneshot::DE_CINNAMON: + case Oneshot::DE_GNOME: + case Oneshot::DE_MATE: + case Oneshot::DE_DEEPIN: { + switch (desktop) { + case Oneshot::DE_CINNAMON: + bgsetting = g_settings_new("org.cinnamon.desktop.background"); + break; + case Oneshot::DE_DEEPIN: + bgsetting = g_settings_new("com.deepin.wrap.gnome.desktop.background"); + break; + case Oneshot::DE_GNOME: + bgsetting = g_settings_new("org.gnome.desktop.background"); + break; + case Oneshot::DE_MATE: + bgsetting = g_settings_new("org.mate.background"); + defPictureURI = g_settings_get_string(bgsetting, "picture-filename"); + break; + default: + break; + } + defPictureOptions = g_settings_get_string(bgsetting, "picture-options"); + defPrimaryColor = g_settings_get_string(bgsetting, "primary-color"); + defColorShading = g_settings_get_string(bgsetting, "color-shading-type"); + break; + } + case Oneshot::DE_XFCE: { + GError *xferror = NULL; + xfconf_dl = dlopen("libxfconf.so", RTLD_NOW); + + if (!xfconf_dl) { + desktop = Oneshot::DE_FALLBACK; + break; + } + auto xfconf_init = (xfconf_init_fn)dlsym(xfconf_dl, "xfconf_init"); + auto xfconf_channel_get = + (xfconf_channel_get_fn)dlsym(xfconf_dl, "xfconf_init"); + auto xfconf_channel_get_string = (xfconf_channel_get_string_fn)dlsym( + xfconf_dl, "xfconf_channel_get_string"); + auto xfconf_channel_get_int = + (xfconf_channel_get_int_fn)dlsym(xfconf_dl, "xfconf_channel_get_int"); + auto xfconf_channel_get_property = (xfconf_channel_get_property_fn)dlsym( + xfconf_dl, "xfconf_channel_get_property"); + + if (!xfconf_init(&xferror)) { + // Configuration failed to initialize, we won't set the wallpaper + desktop = Oneshot::DE_FALLBACK; + g_error_free(xferror); + break; + } + bgchannel = xfconf_channel_get("xfce4-desktop"); + std::string optionPrefix = "/backdrop/screen0/monitor0/workspace0/"; + optionImage = optionPrefix + "last-image"; + optionColor = optionPrefix + "color1"; + optionImageStyle = optionPrefix + "image-style"; + optionColorStyle = optionPrefix + "color-style"; + defPictureURI = + xfconf_channel_get_string(bgchannel, optionImage.c_str(), ""); + defPictureStyle = + xfconf_channel_get_int(bgchannel, optionImageStyle.c_str(), -1); + defColorExists = + xfconf_channel_get_property(bgchannel, optionColor.c_str(), &defColor); + defColorStyle = + xfconf_channel_get_int(bgchannel, optionColorStyle.c_str(), -1); + break; + } + case Oneshot::DE_KDE: { + std::ifstream configFile; + configFile.open(std::string(getenv("HOME")) + + "/.config/plasma-org.kde.plasma.desktop-appletsrc", + std::ios::in); + if (!configFile.is_open()) { + Debug() << "FATAL: Cannot find desktop configuration!"; + desktop = Oneshot::DE_FALLBACK; + break; + } + + std::string line; + std::vector sections; + std::size_t undefined = 999999999; + bool readPlugin = false, readOther = false; + std::string containment; + while (getline(configFile, line)) { + std::size_t index = undefined, lastIndex = undefined; + if (line.size() == 0) { + readPlugin = false; + readOther = false; + } else if (readPlugin) { + index = line.find('='); + if (line.substr(0, index) == "wallpaperplugin") { + defPlugins[containment] = line.substr(index + 1); + } + } else if (readOther) { + index = line.find('='); + std::string key = line.substr(0, index); + std::string val = line.substr(index + 1); + if (key == "Image") { + defPictures[containment] = val; + } else if (key == "Color") { + defColors[containment] = val; + } else if (key == "FillMode") { + defModes[containment] = val; + } else if (key == "Blur") { + defBlurs[containment] = (val == "true"); + } + } else if (line.at(0) == '[') { + sections.clear(); + while (true) { + index = line.find(lastIndex == undefined ? '[' : ']', + index == undefined ? 0 : index); + if (index == std::string::npos) { + break; + } + if (lastIndex == undefined) { + lastIndex = index; + } else { + sections.push_back( + line.substr(lastIndex + 1, index - lastIndex - 1)); + lastIndex = undefined; + } + } + if (sections.size() == 2 && sections[0] == "Containments") { + readPlugin = true; + containment = sections[1]; + } else if (sections.size() == 5 && sections[0] == "Containments" && + sections[2] == "Wallpaper" && + sections[3] == "org.kde.image" && sections[4] == "General") { + readOther = true; + containment = sections[1]; + } + } + } + configFile.close(); + + break; + } + case Oneshot::DE_LXDE: + case Oneshot::DE_FALLBACK: { + break; + } + } + + // if fallback, do fallback to a path on the desktop + if (desktop == Oneshot::DE_FALLBACK) { + fallbackPath = std::string(getenv("HOME")) + "/Desktop/ONESHOT_hint.png"; + } +} + +DesktopEnv::~DesktopEnv() { + if (desktop == Oneshot::DE_XFCE) { + auto xfconf_shutdown = + (xfconf_shutdown_fn)dlsym(xfconf_dl, "xfconf_shutdown"); + xfconf_shutdown(); + dlclose(xfconf_dl); + } +} + +void DesktopEnv::set_wallpaper(std::string path, std::string gameDirStr, + int color) { + switch (desktop) { + case Oneshot::DE_CINNAMON: + case Oneshot::DE_GNOME: + case Oneshot::DE_MATE: + case Oneshot::DE_DEEPIN: { + std::stringstream hexColor; + hexColor << "#" << std::hex << color; + g_settings_set_string(bgsetting, "picture-options", "scaled"); + g_settings_set_string(bgsetting, "primary-color", hexColor.str().c_str()); + g_settings_set_string(bgsetting, "color-shading-type", "solid"); + if (desktop == Oneshot::DE_MATE) { + g_settings_set_string(bgsetting, "picture-filename", + (gameDirStr + path).c_str()); + } else { + g_settings_set_string(bgsetting, "picture-uri", + ("file://" + gameDirStr + path).c_str()); + } + break; + } + case Oneshot::DE_XFCE: { + auto xfconf_channel_set_string = (xfconf_channel_set_string_fn)dlsym( + xfconf_dl, "xfconf_channel_set_string"); + auto xfconf_channel_set_int = + (xfconf_channel_set_int_fn)dlsym(xfconf_dl, "xfconf_channel_set_int"); + auto xfconf_channel_get_property = (xfconf_channel_get_property_fn)dlsym( + xfconf_dl, "xfconf_channel_get_property"); + auto xfconf_channel_set_property = (xfconf_channel_set_property_fn)dlsym( + xfconf_dl, "xfconf_channel_set_property"); + + int r = (color >> 16) & 0xFF; + int g = (color >> 8) & 0xFF; + int b = color & 0xFF; + unsigned int ur = r * 256 + r; + unsigned int ug = g * 256 + g; + unsigned int ub = b * 256 + b; + unsigned int alpha = 65535; + std::string concatPath(gameDirStr + path); + xfconf_channel_set_string(bgchannel, optionImage.c_str(), + concatPath.c_str()); + xfconf_channel_set_int(bgchannel, optionColorStyle.c_str(), 0); + xfconf_channel_set_int(bgchannel, optionImageStyle.c_str(), 4); + GValue colorValue = G_VALUE_INIT; + GPtrArray *colorArr = g_ptr_array_sized_new(4); + GType colorArrType = g_type_from_name("GPtrArray_GValue_"); + if (!colorArrType) { + std::stringstream colorCommand; + colorCommand << "xfconf-query -c xfce4-desktop -n -p " << optionColor + << " -t uint -t uint -t uint -t uint -s " << ub << " -s " + << ug << " -s " << ub << " -s " << alpha; + int colorCommandRes = system(colorCommand.str().c_str()); + defColorExists = xfconf_channel_get_property( + bgchannel, optionColor.c_str(), &defColor); + colorArrType = g_type_from_name("GPtrArray_GValue_"); + if (!colorArrType) { + // Let's do some debug output here and skip changing the color + Debug() << "WALLPAPER ERROR: xfconf-query call returned" + << colorCommandRes; + return; + } + } + g_value_init(&colorValue, colorArrType); + GValue *vr = g_new0(GValue, 1); + GValue *vg = g_new0(GValue, 1); + GValue *vb = g_new0(GValue, 1); + GValue *va = g_new0(GValue, 1); + g_value_init(vr, G_TYPE_UINT); + g_value_init(vg, G_TYPE_UINT); + g_value_init(vb, G_TYPE_UINT); + g_value_init(va, G_TYPE_UINT); + g_value_set_uint(vr, ur); + g_value_set_uint(vg, ug); + g_value_set_uint(vb, ub); + g_value_set_uint(va, alpha); + g_ptr_array_add(colorArr, vr); + g_ptr_array_add(colorArr, vg); + g_ptr_array_add(colorArr, vb); + g_ptr_array_add(colorArr, va); + g_value_set_boxed(&colorValue, colorArr); + xfconf_channel_set_property(bgchannel, optionColor.c_str(), &colorValue); + break; + } + case Oneshot::DE_KDE: { + std::stringstream command; + std::string concatPath(gameDirStr + path); + concatPath = std::regex_replace(concatPath, std::regex("\\"), "\\\\"); + concatPath = std::regex_replace(concatPath, std::regex("\""), "\\\""); + concatPath = std::regex_replace(concatPath, std::regex("'"), "\\x27"); + + command << "qdbus org.kde.plasmashell /PlasmaShell " + "org.kde.PlasmaShell.evaluateScript 'string:" + << "var allDesktops = desktops();" + << "for (var i = 0, l = allDesktops.length; i < l; ++i) {" + << "var d = allDesktops[i];" + << "d.wallpaperPlugin = \"org.kde.image\";" + << "d.currentConfigGroup = [\"Wallpaper\", \"org.kde.image\", " + "\"General\"];" + << "d.writeConfig(\"Image\", \"file://" << concatPath << "\");" + << "d.writeConfig(\"FillMode\", \"6\");" + << "d.writeConfig(\"Blur\", false);" + << "d.writeConfig(\"Color\", [\"" + << std::to_string((color >> 16) & 0xFF) << "\", \"" + << std::to_string((color >> 8) & 0xFF) << "\", \"" + << std::to_string(color & 0xFF) << "\"]);" << "}" << "'"; + Debug() << "Wallpaper command:" << command.str(); + int result = system(command.str().c_str()); + Debug() << "Result:" << result; + break; + } + case Oneshot::DE_LXDE: + case Oneshot::DE_FALLBACK: + std::ifstream srcHint(gameDirStr + path); + std::ofstream dstHint(fallbackPath); + dstHint << srcHint.rdbuf(); + srcHint.close(); + dstHint.close(); + break; + } +} + +void DesktopEnv::reset_wallpaper() { + switch (desktop) { + + case Oneshot::DE_GNOME: + case Oneshot::DE_CINNAMON: + case Oneshot::DE_MATE: + case Oneshot::DE_DEEPIN: { + if (desktop == Oneshot::DE_MATE) { + g_settings_set_string(bgsetting, "picture-filename", + defPictureURI.c_str()); + } else { + g_settings_set_string(bgsetting, "picture-uri", defPictureURI.c_str()); + } + g_settings_set_string(bgsetting, "picture-options", + defPictureOptions.c_str()); + g_settings_set_string(bgsetting, "primary-color", defPrimaryColor.c_str()); + g_settings_set_string(bgsetting, "color-shading-type", + defColorShading.c_str()); + break; + } + case Oneshot::DE_XFCE: { + auto xfconf_channel_set_string = (xfconf_channel_set_string_fn)dlsym( + xfconf_dl, "xfconf_channel_set_string"); + auto xfconf_channel_set_int = + (xfconf_channel_set_int_fn)dlsym(xfconf_dl, "xfconf_channel_set_int"); + auto xfconf_channel_set_property = (xfconf_channel_set_property_fn)dlsym( + xfconf_dl, "xfconf_channel_set_property"); + auto xfconf_channel_reset_property = + (xfconf_channel_reset_property_fn)dlsym( + xfconf_dl, "xfconf_channel_reset_property"); + + if (defColorExists) { + xfconf_channel_set_property(bgchannel, optionColor.c_str(), &defColor); + } else { + xfconf_channel_reset_property(bgchannel, optionColor.c_str(), false); + } + if (defPictureURI == "") { + xfconf_channel_reset_property(bgchannel, optionImage.c_str(), false); + } else { + xfconf_channel_set_string(bgchannel, optionImage.c_str(), + defPictureURI.c_str()); + } + if (defPictureStyle == -1) { + xfconf_channel_reset_property(bgchannel, optionImageStyle.c_str(), false); + } else { + xfconf_channel_set_int(bgchannel, optionImageStyle.c_str(), + defPictureStyle); + } + if (defColorStyle == -1) { + xfconf_channel_reset_property(bgchannel, optionColorStyle.c_str(), false); + } else { + xfconf_channel_set_int(bgchannel, optionColorStyle.c_str(), + defColorStyle); + } + break; + } + case Oneshot::DE_KDE: { + std::stringstream command; + command << "qdbus org.kde.plasmashell /PlasmaShell " + "org.kde.PlasmaShell.evaluateScript 'string:" + << "var allDesktops = desktops();" << "var data = {"; + // Plugin, picture, color, mode, blur + for (auto const &x : defPlugins) { + command << "\"" << x.first << "\": {" + << "plugin: \"" << x.second << "\""; + if (defPictures.find(x.first) != defPictures.end()) { + std::string picture = defPictures[x.first]; + picture = std::regex_replace(picture, std::regex("\\"), "\\\\"); + picture = std::regex_replace(picture, std::regex("\""), "\\\""); + picture = std::regex_replace(picture, std::regex("'"), "\\x27"); + command << ", picture: \"" << picture << "\""; + } + if (defColors.find(x.first) != defColors.end()) { + command << ", color: \"" << defColors[x.first] << "\""; + } + if (defModes.find(x.first) != defModes.end()) { + command << ", mode: \"" << defModes[x.first] << "\""; + } + if (defBlurs.find(x.first) != defBlurs.end() && defBlurs[x.first]) { + command << ", blur: true"; + } + command << "},"; + } + command << "\"no\": {}};" + << "for (var i = 0, l = allDesktops.length; i < l; ++i) {" + << "var d = allDesktops[i];" << "var dat = data[d.id];" + << "d.wallpaperPlugin = dat.plugin;" + << "d.currentConfigGroup = [\"Wallpaper\", \"org.kde.image\", " + "\"General\"];" + << "if (dat.picture) {" << "d.writeConfig(\"Image\", dat.picture);" + << "}" << "if (dat.color) {" + << "d.writeConfig(\"Color\", dat.color.split(\",\"));" << "}" + << "if (dat.mode) {" << "d.writeConfig(\"FillMode\", dat.mode);" + << "}" << "if (dat.blur) {" << "d.writeConfig(\"Blur\", dat.blur);" + << "}" << "}" << "'"; + Debug() << "Reset wallpaper command:" << command.str(); + int result = system(command.str().c_str()); + Debug() << "Reset result:" << result; + break; + } + case Oneshot::DE_LXDE: + case Oneshot::DE_FALLBACK: { + if (remove(fallbackPath.c_str()) != 0) { + Debug() << "Failed to delete:" << fallbackPath; + } + break; + } + } +} + #endif -RB_METHOD(wallpaperSet) -{ - RB_UNUSED_PARAM; - const char *name; - int color; - rb_get_args(argc, argv, "zi", &name, &color RB_ARG_END); - std::string path; - std::string nameStr = name; +RB_METHOD(wallpaperSet) { + RB_UNUSED_PARAM; + const char *name; + int color; + rb_get_args(argc, argv, "zi", &name, &color RB_ARG_END); + std::string path; + std::string nameStr = name; #ifdef _WIN32 - path = "Wallpaper\\" + nameStr + ".bmp"; - Debug() << "Setting wallpaper to" << path; - // Crapify the slashes - size_t index = 0; - for (;;) { - index = path.find("/", index); - if (index == std::string::npos) - break; - path.replace(index, 1, "\\"); - index += 1; - } - WCHAR imgnameW[MAX_PATH]; - WCHAR imgnameFull[MAX_PATH]; - MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, imgnameW, MAX_PATH); - GetFullPathNameW(imgnameW, MAX_PATH, imgnameFull, NULL); - - - int colorId = COLOR_BACKGROUND; - WCHAR zero[2] = L"0"; - DWORD zeroSize = 4; - - HKEY hKey = NULL; - if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_READ, &hKey) != ERROR_SUCCESS) - goto end; - - if (!isCached) { - // QUERY - - // Style - setStyle = RegQueryValueExW(hKey, L"WallpaperStyle", 0, NULL, (LPBYTE)(szStyle), &szStyleSize) == ERROR_SUCCESS; - - // Tile - setTile = RegQueryValueExW(hKey, L"TileWallpaper", 0, NULL, (LPBYTE)(szTile), &szTileSize) == ERROR_SUCCESS; - - // File path - if (!SystemParametersInfoW(SPI_GETDESKWALLPAPER, MAX_PATH, (PVOID)szFile, 0)) - goto end; - - // Color - oldcolor = GetSysColor(COLOR_BACKGROUND); - - isCached = true; - } - - RegCloseKey(hKey); - hKey = NULL; - if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_WRITE, &hKey) != ERROR_SUCCESS) - goto end; - - // SET - - // Set the style - if (RegSetValueExW(hKey, L"WallpaperStyle", 0, REG_SZ, (const BYTE*)zero, zeroSize) != ERROR_SUCCESS) - goto end; - - if (RegSetValueExW(hKey, L"TileWallpaper", 0, REG_SZ, (const BYTE*)zero, zeroSize) != ERROR_SUCCESS) - goto end; - - // Set the wallpaper - if (!SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (PVOID)imgnameFull, SPIF_UPDATEINIFILE)) - goto end; - - // Set the color - if (!SetSysColors(1, &colorId, (const COLORREF *)&color)) - goto end; + path = "Wallpaper\\" + nameStr + ".bmp"; + Debug() << "Setting wallpaper to" << path; + // Crapify the slashes + size_t index = 0; + for (;;) { + index = path.find("/", index); + if (index == std::string::npos) + break; + path.replace(index, 1, "\\"); + index += 1; + } + WCHAR imgnameW[MAX_PATH]; + WCHAR imgnameFull[MAX_PATH]; + MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, imgnameW, MAX_PATH); + GetFullPathNameW(imgnameW, MAX_PATH, imgnameFull, NULL); + + int colorId = COLOR_BACKGROUND; + WCHAR zero[2] = L"0"; + DWORD zeroSize = 4; + + HKEY hKey = NULL; + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_READ, + &hKey) != ERROR_SUCCESS) + goto end; + + if (!isCached) { + // QUERY + + // Style + setStyle = + RegQueryValueExW(hKey, L"WallpaperStyle", 0, NULL, (LPBYTE)(szStyle), + &szStyleSize) == ERROR_SUCCESS; + + // Tile + setTile = RegQueryValueExW(hKey, L"TileWallpaper", 0, NULL, + (LPBYTE)(szTile), &szTileSize) == ERROR_SUCCESS; + + // File path + if (!SystemParametersInfoW(SPI_GETDESKWALLPAPER, MAX_PATH, (PVOID)szFile, + 0)) + goto end; + + // Color + oldcolor = GetSysColor(COLOR_BACKGROUND); + + isCached = true; + } + + RegCloseKey(hKey); + hKey = NULL; + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_WRITE, + &hKey) != ERROR_SUCCESS) + goto end; + + // SET + + // Set the style + if (RegSetValueExW(hKey, L"WallpaperStyle", 0, REG_SZ, (const BYTE *)zero, + zeroSize) != ERROR_SUCCESS) + goto end; + + if (RegSetValueExW(hKey, L"TileWallpaper", 0, REG_SZ, (const BYTE *)zero, + zeroSize) != ERROR_SUCCESS) + goto end; + + // Set the wallpaper + if (!SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (PVOID)imgnameFull, + SPIF_UPDATEINIFILE)) + goto end; + + // Set the color + if (!SetSysColors(1, &colorId, (const COLORREF *)&color)) + goto end; end: - if (hKey) - RegCloseKey(hKey); + if (hKey) + RegCloseKey(hKey); #else - std::string nameFix(name); - std::size_t found = nameFix.find("w32"); - if (found != std::string::npos) { - nameFix.replace(nameFix.end()-3, nameFix.end(), "unix"); - } - path = "/Wallpaper/" + nameFix + ".png"; - - Debug() << "Setting wallpaper to " << path; - - #ifdef __APPLE__ - if (!isCached) { - MacDesktop::CacheCurrentBackground(); - isCached = true; - } - MacDesktop::ChangeBackground(shState->config().gameFolder + path, ((color >> 16) & 0xFF) / 255.0, ((color >> 8) & 0xFF) / 255.0, (color & 0xFF) / 255.0); - #else - char gameDir[PATH_MAX]; - if (getcwd(gameDir, sizeof(gameDir)) == NULL) { - return Qnil; - } - std::string gameDirStr(gameDir); - desktopEnvironmentInit(); - if (desktop == "cinnamon" || desktop == "gnome" || desktop == "mate" || desktop == "deepin") { - std::stringstream hexColor; - hexColor << "#" << std::hex << color; - g_settings_set_string(bgsetting, "picture-options", "scaled"); - g_settings_set_string(bgsetting, "primary-color", hexColor.str().c_str()); - g_settings_set_string(bgsetting, "color-shading-type", "solid"); - if (desktop == "cinnamon" || desktop == "gnome" || desktop == "deepin") { - g_settings_set_string(bgsetting, "picture-uri", ("file://" + gameDirStr + path).c_str()); - } else { - g_settings_set_string(bgsetting, "picture-filename", (gameDirStr + path).c_str()); - } - } else if (desktop == "xfce") { - int r = (color >> 16) & 0xFF; - int g = (color >> 8) & 0xFF; - int b = color & 0xFF; - unsigned int ur = r * 256 + r; - unsigned int ug = g * 256 + g; - unsigned int ub = b * 256 + b; - unsigned int alpha = 65535; - std::string concatPath(gameDirStr + path); - xfconf_channel_set_string(bgchannel, optionImage.c_str(), concatPath.c_str()); - xfconf_channel_set_int(bgchannel, optionColorStyle.c_str(), 0); - xfconf_channel_set_int(bgchannel, optionImageStyle.c_str(), 4); - GValue colorValue = G_VALUE_INIT; - GPtrArray *colorArr = g_ptr_array_sized_new(4); - GType colorArrType = g_type_from_name("GPtrArray_GValue_"); - if (!colorArrType) { - std::stringstream colorCommand; - colorCommand << "xfconf-query -c xfce4-desktop -n -p " << optionColor - << " -t uint -t uint -t uint -t uint -s " << ub - << " -s " << ug << " -s " << ub << " -s " << alpha; - int colorCommandRes = system(colorCommand.str().c_str()); - defColorExists = xfconf_channel_get_property(bgchannel, optionColor.c_str(), &defColor); - colorArrType = g_type_from_name("GPtrArray_GValue_"); - if (!colorArrType) { - // Let's do some debug output here and skip changing the color - Debug() << "WALLPAPER ERROR: xfconf-query call returned" << colorCommandRes; - return Qnil; - } - } - g_value_init(&colorValue, colorArrType); - GValue *vr = g_new0(GValue, 1); - GValue *vg = g_new0(GValue, 1); - GValue *vb = g_new0(GValue, 1); - GValue *va = g_new0(GValue, 1); - g_value_init(vr, G_TYPE_UINT); - g_value_init(vg, G_TYPE_UINT); - g_value_init(vb, G_TYPE_UINT); - g_value_init(va, G_TYPE_UINT); - g_value_set_uint(vr, ur); - g_value_set_uint(vg, ug); - g_value_set_uint(vb, ub); - g_value_set_uint(va, alpha); - g_ptr_array_add(colorArr, vr); - g_ptr_array_add(colorArr, vg); - g_ptr_array_add(colorArr, vb); - g_ptr_array_add(colorArr, va); - g_value_set_boxed(&colorValue, colorArr); - xfconf_channel_set_property(bgchannel, optionColor.c_str(), &colorValue); - } else if (desktop == "kde") { - std::stringstream command; - std::string concatPath(gameDirStr + path); - boost::replace_all(concatPath, "\\", "\\\\"); - boost::replace_all(concatPath, "\"", "\\\""); - boost::replace_all(concatPath, "'", "\\x27"); - command << "qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript 'string:" << - "var allDesktops = desktops();" << - "for (var i = 0, l = allDesktops.length; i < l; ++i) {" << - "var d = allDesktops[i];" << - "d.wallpaperPlugin = \"org.kde.image\";" << - "d.currentConfigGroup = [\"Wallpaper\", \"org.kde.image\", \"General\"];" << - "d.writeConfig(\"Image\", \"file://" << concatPath << "\");" << - "d.writeConfig(\"FillMode\", \"6\");" << - "d.writeConfig(\"Blur\", false);" << - "d.writeConfig(\"Color\", [\"" << - std::to_string((color >> 16) & 0xFF) << "\", \"" << - std::to_string((color >> 8) & 0xFF) << "\", \"" << - std::to_string(color & 0xFF) << - "\"]);" << - "}" << - "'"; - Debug() << "Wallpaper command:" << command.str(); - int result = system(command.str().c_str()); - Debug() << "Result:" << result; - } else { - std::ifstream srcHint(gameDirStr + path); - std::ofstream dstHint(fallbackPath); - dstHint << srcHint.rdbuf(); - srcHint.close(); - dstHint.close(); - } - #endif + std::string nameFix(name); + std::size_t found = nameFix.find("w32"); + if (found != std::string::npos) { + nameFix.replace(nameFix.end() - 3, nameFix.end(), "unix"); + } + path = "/Wallpaper/" + nameFix + ".png"; + + Debug() << "Setting wallpaper to " << path; + +#ifdef __APPLE__ + if (!isCached) { + MacDesktop::CacheCurrentBackground(); + isCached = true; + } + MacDesktop::ChangeBackground( + shState->config().gameFolder + path, ((color >> 16) & 0xFF) / 255.0, + ((color >> 8) & 0xFF) / 255.0, (color & 0xFF) / 255.0); +#else + char gameDir[PATH_MAX]; + if (getcwd(gameDir, sizeof(gameDir)) == NULL) { + return Qnil; + } + std::string gameDirStr(gameDir); + env->set_wallpaper(path, gameDirStr, color); + +#endif #endif - return Qnil; + return Qnil; } -RB_METHOD(wallpaperReset) -{ - RB_UNUSED_PARAM; +RB_METHOD(wallpaperReset) { + RB_UNUSED_PARAM; #ifdef _WIN32 - if (isCached) { - int colorId = COLOR_BACKGROUND; - HKEY hKey = NULL; - if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, KEY_WRITE, &hKey) != ERROR_SUCCESS) - goto end; - - // Set the style - if (setStyle) - RegSetValueExW(hKey, L"WallpaperStyle", 0, REG_SZ, (const BYTE*)szStyle, szStyleSize); - - if (setTile) - RegSetValueExW(hKey, L"TileWallpaper", 0, REG_SZ, (const BYTE*)szTile, szTileSize); - - // Set the wallpaper - if (!SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (PVOID)szFile, SPIF_UPDATEINIFILE)) - goto end; - - // Set the color - if (!SetSysColors(1, &colorId, (const COLORREF *)&oldcolor)) - goto end; - end: - if (hKey) - RegCloseKey(hKey); - } + if (isCached) { + int colorId = COLOR_BACKGROUND; + HKEY hKey = NULL; + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Control Panel\\Desktop", 0, + KEY_WRITE, &hKey) != ERROR_SUCCESS) + goto end; + + // Set the style + if (setStyle) + RegSetValueExW(hKey, L"WallpaperStyle", 0, REG_SZ, (const BYTE *)szStyle, + szStyleSize); + + if (setTile) + RegSetValueExW(hKey, L"TileWallpaper", 0, REG_SZ, (const BYTE *)szTile, + szTileSize); + + // Set the wallpaper + if (!SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, (PVOID)szFile, + SPIF_UPDATEINIFILE)) + goto end; + + // Set the color + if (!SetSysColors(1, &colorId, (const COLORREF *)&oldcolor)) + goto end; + end: + if (hKey) + RegCloseKey(hKey); + } #else - #ifdef __APPLE__ - MacDesktop::ResetBackground(); - #else - desktopEnvironmentInit(); - if (desktop == "cinnamon" || desktop == "gnome" || desktop == "mate" || desktop == "deepin") { - if (desktop == "cinnamon" || desktop == "gnome" || desktop == "deepin") { - g_settings_set_string(bgsetting, "picture-uri", defPictureURI.c_str()); - } else { - g_settings_set_string(bgsetting, "picture-filename", defPictureURI.c_str()); - } - g_settings_set_string(bgsetting, "picture-options", defPictureOptions.c_str()); - g_settings_set_string(bgsetting, "primary-color", defPrimaryColor.c_str()); - g_settings_set_string(bgsetting, "color-shading-type", defColorShading.c_str()); - } else if (desktop == "xfce") { - if (defColorExists) { - xfconf_channel_set_property(bgchannel, optionColor.c_str(), &defColor); - } else { - xfconf_channel_reset_property(bgchannel, optionColor.c_str(), false); - } - if (defPictureURI == "") { - xfconf_channel_reset_property(bgchannel, optionImage.c_str(), false); - } else { - xfconf_channel_set_string(bgchannel, optionImage.c_str(), defPictureURI.c_str()); - } - if (defPictureStyle == -1) { - xfconf_channel_reset_property(bgchannel, optionImageStyle.c_str(), false); - } else { - xfconf_channel_set_int(bgchannel, optionImageStyle.c_str(), defPictureStyle); - } - if (defColorStyle == -1) { - xfconf_channel_reset_property(bgchannel, optionColorStyle.c_str(), false); - } else { - xfconf_channel_set_int(bgchannel, optionColorStyle.c_str(), defColorStyle); - } - } else if (desktop == "kde") { - std::stringstream command; - command << "qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript 'string:" << - "var allDesktops = desktops();" << - "var data = {"; - // Plugin, picture, color, mode, blur - for (auto const& x : defPlugins) { - command << "\"" << x.first << "\": {" - << "plugin: \"" << x.second << "\""; - if (defPictures.find(x.first) != defPictures.end()) { - std::string picture = defPictures[x.first]; - boost::replace_all(picture, "\\", "\\\\"); - boost::replace_all(picture, "\"", "\\\""); - boost::replace_all(picture, "'", "\\x27"); - command << ", picture: \"" << picture << "\""; - } - if (defColors.find(x.first) != defColors.end()) { - command << ", color: \"" << defColors[x.first] << "\""; - } - if (defModes.find(x.first) != defModes.end()) { - command << ", mode: \"" << defModes[x.first] << "\""; - } - if (defBlurs.find(x.first) != defBlurs.end() && defBlurs[x.first]) { - command << ", blur: true"; - } - command << "},"; - } - command << "\"no\": {}};" << - "for (var i = 0, l = allDesktops.length; i < l; ++i) {" << - "var d = allDesktops[i];" << - "var dat = data[d.id];" << - "d.wallpaperPlugin = dat.plugin;" << - "d.currentConfigGroup = [\"Wallpaper\", \"org.kde.image\", \"General\"];" << - "if (dat.picture) {" << - "d.writeConfig(\"Image\", dat.picture);" << - "}" << - "if (dat.color) {" << - "d.writeConfig(\"Color\", dat.color.split(\",\"));" << - "}" << - "if (dat.mode) {" << - "d.writeConfig(\"FillMode\", dat.mode);" << - "}" << - "if (dat.blur) {" << - "d.writeConfig(\"Blur\", dat.blur);" << - "}" << - "}" << - "'"; - Debug() << "Reset wallpaper command:" << command.str(); - int result = system(command.str().c_str()); - Debug() << "Reset result:" << result; - } else { - if (remove(fallbackPath.c_str()) != 0) { - Debug() << "Failed to delete:" << fallbackPath; - } - } - #endif +#ifdef __APPLE__ + MacDesktop::ResetBackground(); +#else + env->reset_wallpaper(); +#endif #endif - return Qnil; + return Qnil; } -void oneshotWallpaperBindingInit() -{ - VALUE module = rb_define_module("Wallpaper"); +void oneshotWallpaperBindingInit() { +#ifdef __linux + env = new DesktopEnv(); +#endif + VALUE module = rb_define_module("Wallpaper"); - // Functions - _rb_define_module_function(module, "set", wallpaperSet); - _rb_define_module_function(module, "reset", wallpaperReset); + // Functions + _rb_define_module_function(module, "set", wallpaperSet); + _rb_define_module_function(module, "reset", wallpaperReset); } #ifdef __linux__ -void oneshotWallpaperBindingTerminate() -{ - // Clean up. - if (desktop == "xfce") { - xfconf_shutdown(); - } -} +void oneshotWallpaperBindingTerminate() { delete env; } #endif \ No newline at end of file diff --git a/src/oneshot/oneshot.cpp b/src/oneshot/oneshot.cpp index 2ca91cc27..ec986160d 100644 --- a/src/oneshot/oneshot.cpp +++ b/src/oneshot/oneshot.cpp @@ -4,9 +4,9 @@ * HERE BE DRAGONS ******************/ -#include "eventthread.h" -#include "debugwriter.h" #include "bitmap.h" +#include "debugwriter.h" +#include "eventthread.h" #include "font.h" #include @@ -15,597 +15,538 @@ // OS-Specific code #if defined _WIN32 - #define OS_W32 - //#define WIN32_LEAN_AND_MEAN - #define SECURITY_WIN32 - #include - #include - #include - #include +#define OS_W32 +// #define WIN32_LEAN_AND_MEAN +#define SECURITY_WIN32 +#include +#include +#include +#include #elif defined __APPLE__ || __linux__ - #include - #include - #include - #include - - #ifdef __APPLE__ - #define OS_OSX - #include - #else - #define OS_LINUX - #include - #include - #include "xdg-user-dir-lookup.h" - #endif +#include +#include +#include +#include + +#ifdef __APPLE__ +#define OS_OSX +#include #else - #error "Operating system not detected." +#define OS_LINUX +#include "xdg-user-dir-lookup.h" +#include +#include +#endif +#else +#error "Operating system not detected." #endif #define DEF_SCREEN_W 640 #define DEF_SCREEN_H 480 -struct OneshotPrivate -{ - // Main SDL window - SDL_Window *window; - - // String data - std::string os; - std::string lang; - std::string userName; - std::string savePath; - std::string docsPath; - std::string gamePath; - std::string journal; - - // Dialog text - std::string txtYes; - std::string txtNo; - - // Booleans - bool exiting; - bool allowExit; - - // Alpha texture data for portions of window obscured by screen edges - int winX, winY; - SDL_Mutex *winMutex; - bool winPosChanged; - std::vector obscuredMap; - bool obscuredCleared; - - OneshotPrivate() - : window(0), - winMutex(SDL_CreateMutex()) - { - } - - ~OneshotPrivate() - { - SDL_DestroyMutex(winMutex); - } +struct OneshotPrivate { + // Main SDL window + SDL_Window *window; + + // String data + std::string os; + std::string lang; + std::string userName; + std::string savePath; + std::string docsPath; + std::string gamePath; + std::string journal; + + // Dialog text + std::string txtYes; + std::string txtNo; + + // Booleans + bool exiting; + bool allowExit; + + // Alpha texture data for portions of window obscured by screen edges + int winX, winY; + SDL_Mutex *winMutex; + bool winPosChanged; + std::vector obscuredMap; + bool obscuredCleared; + + OneshotPrivate() : window(0), winMutex(SDL_CreateMutex()) {} + + ~OneshotPrivate() { SDL_DestroyMutex(winMutex); } }; -//OS-SPECIFIC FUNCTIONS +// OS-SPECIFIC FUNCTIONS #if defined OS_LINUX -struct linux_DialogData -{ - // Input - int type; - const char *body; - const char *title; - - // Output - bool result; +struct linux_DialogData { + // Input + int type; + const char *body; + const char *title; + + // Output + bool result; }; -static int linux_dialog(void *rawData) -{ - linux_DialogData *data = reinterpret_cast(rawData); - - // Determine correct flags - GtkMessageType gtktype; - GtkButtonsType gtkbuttons = GTK_BUTTONS_OK; - switch (data->type) - { - case Oneshot::MSG_INFO: - gtktype = GTK_MESSAGE_INFO; - break; - case Oneshot::MSG_YESNO: - gtktype = GTK_MESSAGE_QUESTION; - gtkbuttons = GTK_BUTTONS_YES_NO; - break; - case Oneshot::MSG_WARN: - gtktype = GTK_MESSAGE_WARNING; - break; - case Oneshot::MSG_ERR: - gtktype = GTK_MESSAGE_ERROR; - break; - default: - gtk_main_quit(); - return 0; - } - - // Display dialog and get result - GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, gtktype, gtkbuttons, "%s", data->body); - gtk_window_set_title(GTK_WINDOW(dialog), data->title); - int result = gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - - // Interpret result and return - data->result = (result == GTK_RESPONSE_OK || result == GTK_RESPONSE_YES); - gtk_main_quit(); - return 0; +static int linux_dialog(void *rawData) { + linux_DialogData *data = reinterpret_cast(rawData); + + // Determine correct flags + GtkMessageType gtktype; + GtkButtonsType gtkbuttons = GTK_BUTTONS_OK; + switch (data->type) { + case Oneshot::MSG_INFO: + gtktype = GTK_MESSAGE_INFO; + break; + case Oneshot::MSG_YESNO: + gtktype = GTK_MESSAGE_QUESTION; + gtkbuttons = GTK_BUTTONS_YES_NO; + break; + case Oneshot::MSG_WARN: + gtktype = GTK_MESSAGE_WARNING; + break; + case Oneshot::MSG_ERR: + gtktype = GTK_MESSAGE_ERROR; + break; + default: + gtk_main_quit(); + return 0; + } + + // Display dialog and get result + GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, gtktype, + gtkbuttons, "%s", data->body); + gtk_window_set_title(GTK_WINDOW(dialog), data->title); + int result = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + + // Interpret result and return + data->result = (result == GTK_RESPONSE_OK || result == GTK_RESPONSE_YES); + gtk_main_quit(); + return 0; } #elif defined OS_W32 /* Convert WCHAR pointer to std::string */ -static std::string w32_fromWide(const WCHAR *ustr) -{ - std::string result; - int size = WideCharToMultiByte(CP_UTF8, 0, ustr, -1, 0, 0, 0, 0); - if (size > 0) - { - CHAR *str = new CHAR[size]; - if (WideCharToMultiByte(CP_UTF8, 0, ustr, -1, str, size, 0, 0) == size) - result = str; - delete [] str; - } - return result; +static std::string w32_fromWide(const WCHAR *ustr) { + std::string result; + int size = WideCharToMultiByte(CP_UTF8, 0, ustr, -1, 0, 0, 0, 0); + if (size > 0) { + CHAR *str = new CHAR[size]; + if (WideCharToMultiByte(CP_UTF8, 0, ustr, -1, str, size, 0, 0) == size) + result = str; + delete[] str; + } + return result; } /* Convert WCHAR pointer from const char* */ // static WCHAR *w32_toWide(const char *str) // { -// if (str) -// { -// int size = MultiByteToWideChar(CP_UTF8, 0, str, -1, 0, 0); -// if (size > 0) -// { -// WCHAR *ustr = new WCHAR[size]; -// if (MultiByteToWideChar(CP_UTF8, 0, str, -1, ustr, size) == size) -// return ustr; -// delete [] ustr; -// } -// } +// if (str) +// { +// int size = MultiByteToWideChar(CP_UTF8, 0, str, -1, 0, 0); +// if (size > 0) +// { +// WCHAR *ustr = new WCHAR[size]; +// if (MultiByteToWideChar(CP_UTF8, 0, str, -1, ustr, size) == size) +// return ustr; +// delete [] ustr; +// } +// } // -// //Return empty string -// WCHAR *ustr = new WCHAR[1]; -// *ustr = 0; -// return ustr; +// //Return empty string +// WCHAR *ustr = new WCHAR[1]; +// *ustr = 0; +// return ustr; // } #endif -Oneshot::Oneshot(RGSSThreadData &threadData) : - threadData(threadData) -{ - p = new OneshotPrivate(); - p->window = threadData.window; - p->savePath = threadData.config.customDataPath.substr(0, threadData.config.customDataPath.size() - 1); - p->obscuredMap.resize(640 * 480, 255); - obscuredDirty = true; - p->winX = 0; - p->winY = 0; - p->winPosChanged = false; - p->allowExit = true; - p->exiting = false; - #ifdef OS_W32 - p->os = "windows"; - #elif defined OS_OSX - p->os = "macos"; - #else - p->os = "linux"; - #endif - - /******************** - * USERNAME/DOCS PATH - ********************/ +Oneshot::Oneshot(RGSSThreadData &threadData) : threadData(threadData) { + p = new OneshotPrivate(); + p->window = threadData.window; + p->savePath = threadData.config.customDataPath.substr( + 0, threadData.config.customDataPath.size() - 1); + p->obscuredMap.resize(640 * 480, 255); + obscuredDirty = true; + p->winX = 0; + p->winY = 0; + p->winPosChanged = false; + p->allowExit = true; + p->exiting = false; +#ifdef OS_W32 + p->os = "windows"; +#elif defined OS_OSX + p->os = "macos"; +#else + p->os = "linux"; +#endif + + /******************** + * USERNAME/DOCS PATH + ********************/ #if defined OS_W32 - //Get language code - WCHAR wlang[9]; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, wlang, sizeof(wlang) / sizeof(WCHAR)); - p->lang = w32_fromWide(wlang) + "_"; - GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, wlang, sizeof(wlang) / sizeof(WCHAR)); - p->lang += w32_fromWide(wlang); - - //Get user's name - ULONG size = 0; - GetUserNameExW(NameDisplay, 0, &size); - if (GetLastError() == ERROR_MORE_DATA) - { - //Get their full (display) name - wchar_t* name = new wchar_t[size]; - GetUserNameExW(NameDisplay, name, &size); - p->userName = w32_fromWide(name); - delete [] name; - } - else - { - //Get their login name - DWORD size2 = 0; - GetUserNameW(0, &size2); - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - wchar_t* name = new wchar_t[size2]; - GetUserNameW(name, &size2); - p->userName = w32_fromWide(name); - delete [] name; - } - } - - // Get documents path - //char* path = new char[MAX_PATH]; - //SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, path); - //p->docsPath = w32_fromWide((WCHAR*) path); - p->docsPath = getenv("USERPROFILE") + std::string("\\Documents"); - p->gamePath = p->docsPath + "\\My Games"; - p->journal = "_______.exe"; + // Get language code + WCHAR wlang[9]; + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, wlang, + sizeof(wlang) / sizeof(WCHAR)); + p->lang = w32_fromWide(wlang) + "_"; + GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, wlang, + sizeof(wlang) / sizeof(WCHAR)); + p->lang += w32_fromWide(wlang); + + // Get user's name + ULONG size = 0; + GetUserNameExW(NameDisplay, 0, &size); + if (GetLastError() == ERROR_MORE_DATA) { + // Get their full (display) name + wchar_t *name = new wchar_t[size]; + GetUserNameExW(NameDisplay, name, &size); + p->userName = w32_fromWide(name); + delete[] name; + } else { + // Get their login name + DWORD size2 = 0; + GetUserNameW(0, &size2); + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { + wchar_t *name = new wchar_t[size2]; + GetUserNameW(name, &size2); + p->userName = w32_fromWide(name); + delete[] name; + } + } + + // Get documents path + // char* path = new char[MAX_PATH]; + // SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, path); + // p->docsPath = w32_fromWide((WCHAR*) path); + p->docsPath = getenv("USERPROFILE") + std::string("\\Documents"); + p->gamePath = p->docsPath + "\\My Games"; + p->journal = "_______.exe"; #else - // Get language code - const char *lc_all = getenv("LC_ALL"); - const char *lang = getenv("LANG"); - const char *code = (lc_all ? lc_all : lang); - if (code) - { - // find first dot, copy language code - int end = 0; - for (; code[end] && code[end] != '.'; ++end) {} - p->lang = std::string(code, end); - } - else - p->lang = "en"; - - // Get user's name - #ifdef OS_OSX - struct passwd *pwd = getpwuid(geteuid()); - #elif defined OS_LINUX - struct passwd *pwd = getpwuid(getuid()); - #endif - if (pwd) - { - if (pwd->pw_gecos && pwd->pw_gecos[0] && pwd->pw_gecos[0] != ',') - { - //Get the user's full name - int comma = 0; - for (; pwd->pw_gecos[comma] && pwd->pw_gecos[comma] != ','; ++comma) {} - p->userName = std::string(pwd->pw_gecos, comma); - } - else - p->userName = pwd->pw_name; - } - - // Get documents path - #ifdef OS_OSX - std::string path = std::string(getenv("HOME")) + "/Documents"; - p->docsPath = path.c_str(); - p->gamePath = path.c_str(); - p->journal = "_______.app"; - #elif defined OS_LINUX - char * path = xdg_user_dir_lookup("DOCUMENTS"); - p->docsPath = path; - p->gamePath = path; - p->journal = "_______"; - #endif + // Get language code + const char *lc_all = getenv("LC_ALL"); + const char *lang = getenv("LANG"); + const char *code = (lc_all ? lc_all : lang); + if (code) { + // find first dot, copy language code + int end = 0; + for (; code[end] && code[end] != '.'; ++end) { + } + p->lang = std::string(code, end); + } else + p->lang = "en"; + +// Get user's name +#ifdef OS_OSX + struct passwd *pwd = getpwuid(geteuid()); +#elif defined OS_LINUX + struct passwd *pwd = getpwuid(getuid()); +#endif + if (pwd) { + if (pwd->pw_gecos && pwd->pw_gecos[0] && pwd->pw_gecos[0] != ',') { + // Get the user's full name + int comma = 0; + for (; pwd->pw_gecos[comma] && pwd->pw_gecos[comma] != ','; ++comma) { + } + p->userName = std::string(pwd->pw_gecos, comma); + } else + p->userName = pwd->pw_name; + } + +// Get documents path +#ifdef OS_OSX + std::string path = std::string(getenv("HOME")) + "/Documents"; + p->docsPath = path.c_str(); + p->gamePath = path.c_str(); + p->journal = "_______.app"; +#elif defined OS_LINUX + char *path = xdg_user_dir_lookup("DOCUMENTS"); + p->docsPath = path; + p->gamePath = path; + p->journal = "_______"; +#endif #endif - Debug() << "Game path :" << p->gamePath; - Debug() << "Docs path :" << p->docsPath; + Debug() << "Game path :" << p->gamePath; + Debug() << "Docs path :" << p->docsPath; #ifdef OS_LINUX - char const* xdg_current_desktop = getenv("XDG_CURRENT_DESKTOP"); - gtk_init(0, 0); - - if (xdg_current_desktop == NULL) { - desktopEnv = "nope"; - } else { - std::string desktop(xdg_current_desktop); - std::transform(desktop.begin(), desktop.end(), desktop.begin(), ::tolower); - if (desktop.find("cinnamon") != std::string::npos) { - desktopEnv = "cinnamon"; - } else if ( - desktop.find("gnome") != std::string::npos || - desktop.find("unity") != std::string::npos - ) { - desktopEnv = "gnome"; - } else if (desktop.find("mate") != std::string::npos) { - desktopEnv = "mate"; - } else if (desktop.find("xfce") != std::string::npos) { - desktopEnv = "xfce"; - } else if (desktop.find("kde") != std::string::npos) { - desktopEnv = "kde"; - } else if (desktop.find("lxde") != std::string::npos) { - desktopEnv = "lxde"; - } else if (desktop.find("deepin") != std::string::npos) { - desktopEnv = "deepin"; - } - } - - Debug() << "Desktop env :" << desktopEnv; + char const *xdg_current_desktop = getenv("XDG_CURRENT_DESKTOP"); + gtk_init(0, 0); + + if (xdg_current_desktop == NULL) { + desktop = DE_FALLBACK; + } else { + std::string desktop(xdg_current_desktop); + std::transform(desktop.begin(), desktop.end(), desktop.begin(), ::tolower); + if (desktop.find("cinnamon") != std::string::npos) { + desktop = DE_CINNAMON; + } else if (desktop.find("gnome") != std::string::npos || + desktop.find("unity") != std::string::npos) { + desktop = DE_GNOME; + } else if (desktop.find("mate") != std::string::npos) { + desktop = DE_MATE; + } else if (desktop.find("xfce") != std::string::npos) { + desktop = DE_XFCE; + } else if (desktop.find("kde") != std::string::npos) { + desktop = DE_XFCE; + } else if (desktop.find("lxde") != std::string::npos) { + desktop = DE_LXDE; + } else if (desktop.find("deepin") != std::string::npos) { + desktop = DE_DEEPIN; + } + } + + Debug() << "Desktop env :" << desktop; #endif } -Oneshot::~Oneshot() -{ - delete p; -} - -void Oneshot::update() -{ - if (p->winPosChanged) - { - p->winPosChanged = false; - - //Map of unobscured pixels in this frame - static std::vector obscuredFrame; - obscuredFrame.resize(p->obscuredMap.size()); - std::fill(obscuredFrame.begin(), obscuredFrame.end(), true); - - SDL_Rect screenRect; - SDL_LockMutex(p->winMutex); - screenRect.x = p->winX; - screenRect.y = p->winY; - SDL_UnlockMutex(p->winMutex); - screenRect.w = 640; - screenRect.h = 480; - - int display_count; - SDL_DisplayID *ids = SDL_GetDisplays(&display_count); - //Update obscured map and texture for window portion offscreen - for (int i = 0, max = display_count; i < max; ++i) - { - SDL_Rect bounds; - SDL_GetDisplayBounds(ids[i], &bounds); - - //Get intersection of window and the screen - SDL_Rect intersect; - if (!SDL_GetRectIntersection(&screenRect, &bounds, &intersect)) - continue; - intersect.x -= screenRect.x; - intersect.y -= screenRect.y; - - //If it's entirely within the bounds of the screen, we don't need to check out - //any other monitors - if (intersect.x == 0 && intersect.y == 0 && intersect.w == 640 && intersect.h == 480) - return; - - for (int y = intersect.y; y < intersect.y + intersect.h; ++y) - { - int start = y * 640 + intersect.x; - std::fill(obscuredFrame.begin() + start, obscuredFrame.begin() + (start + intersect.w), false); - } - } - - //Update the obscured map, and return prematurely if we don't have any changes - //to make to the texture - bool needsUpdate = false; - bool cleared = true; - for (size_t i = 0; i < obscuredFrame.size(); ++i) - { - if (obscuredFrame[i]) - { - p->obscuredMap[i] = 0; - needsUpdate = true; - } - if (p->obscuredMap[i] == 255) - cleared = false; - } - p->obscuredCleared = cleared; - if (!needsUpdate) - return; - - //Flag as dirty - obscuredDirty = true; - } +Oneshot::~Oneshot() { delete p; } + +void Oneshot::update() { + if (p->winPosChanged) { + p->winPosChanged = false; + + // Map of unobscured pixels in this frame + static std::vector obscuredFrame; + obscuredFrame.resize(p->obscuredMap.size()); + std::fill(obscuredFrame.begin(), obscuredFrame.end(), true); + + SDL_Rect screenRect; + SDL_LockMutex(p->winMutex); + screenRect.x = p->winX; + screenRect.y = p->winY; + SDL_UnlockMutex(p->winMutex); + screenRect.w = 640; + screenRect.h = 480; + + int display_count; + SDL_DisplayID *ids = SDL_GetDisplays(&display_count); + // Update obscured map and texture for window portion offscreen + for (int i = 0, max = display_count; i < max; ++i) { + SDL_Rect bounds; + SDL_GetDisplayBounds(ids[i], &bounds); + + // Get intersection of window and the screen + SDL_Rect intersect; + if (!SDL_GetRectIntersection(&screenRect, &bounds, &intersect)) + continue; + intersect.x -= screenRect.x; + intersect.y -= screenRect.y; + + // If it's entirely within the bounds of the screen, we don't need to + // check out any other monitors + if (intersect.x == 0 && intersect.y == 0 && intersect.w == 640 && + intersect.h == 480) + return; + + for (int y = intersect.y; y < intersect.y + intersect.h; ++y) { + int start = y * 640 + intersect.x; + std::fill(obscuredFrame.begin() + start, + obscuredFrame.begin() + (start + intersect.w), false); + } + } + + // Update the obscured map, and return prematurely if we don't have any + // changes to make to the texture + bool needsUpdate = false; + bool cleared = true; + for (size_t i = 0; i < obscuredFrame.size(); ++i) { + if (obscuredFrame[i]) { + p->obscuredMap[i] = 0; + needsUpdate = true; + } + if (p->obscuredMap[i] == 255) + cleared = false; + } + p->obscuredCleared = cleared; + if (!needsUpdate) + return; + + // Flag as dirty + obscuredDirty = true; + } } -const std::string &Oneshot::os() const -{ - return p->os; -} +const std::string &Oneshot::os() const { return p->os; } -const std::string &Oneshot::lang() const -{ - return p->lang; -} +const std::string &Oneshot::lang() const { return p->lang; } -const std::string &Oneshot::userName() const -{ - return p->userName; -} +const std::string &Oneshot::userName() const { return p->userName; } -const std::string &Oneshot::savePath() const -{ - return p->savePath; -} +const std::string &Oneshot::savePath() const { return p->savePath; } -const std::string &Oneshot::docsPath() const -{ - return p->docsPath; -} +const std::string &Oneshot::docsPath() const { return p->docsPath; } -const std::string &Oneshot::gamePath() const -{ - return p->gamePath; -} +const std::string &Oneshot::gamePath() const { return p->gamePath; } -const std::string &Oneshot::journal() const -{ - return p->journal; -} +const std::string &Oneshot::journal() const { return p->journal; } -const std::vector &Oneshot::obscuredMap() const -{ - return p->obscuredMap; +const std::vector &Oneshot::obscuredMap() const { + return p->obscuredMap; } -bool Oneshot::obscuredCleared() const -{ - return p->obscuredCleared; -} +bool Oneshot::obscuredCleared() const { return p->obscuredCleared; } -bool Oneshot::exiting() const -{ - return p->exiting; -} +bool Oneshot::exiting() const { return p->exiting; } -bool Oneshot::allowExit() const -{ - return p->allowExit; -} +bool Oneshot::allowExit() const { return p->allowExit; } -void Oneshot::setYesNo(const char *yes, const char *no) -{ - p->txtYes = yes; - p->txtNo = no; +void Oneshot::setYesNo(const char *yes, const char *no) { + p->txtYes = yes; + p->txtNo = no; } -void Oneshot::setExiting(bool exiting) -{ - if (p->exiting != exiting) { - p->exiting = exiting; - if (exiting) { - threadData.exiting.set(); - } else { - threadData.exiting.clear(); - } - } +void Oneshot::setExiting(bool exiting) { + if (p->exiting != exiting) { + p->exiting = exiting; + if (exiting) { + threadData.exiting.set(); + } else { + threadData.exiting.clear(); + } + } } -void Oneshot::setAllowExit(bool allowExit) -{ - if (p->allowExit != allowExit) { - p->allowExit = allowExit; - if (allowExit) { - threadData.allowExit.set(); - } else { - threadData.allowExit.clear(); - } - } +void Oneshot::setAllowExit(bool allowExit) { + if (p->allowExit != allowExit) { + p->allowExit = allowExit; + if (allowExit) { + threadData.allowExit.set(); + } else { + threadData.allowExit.clear(); + } + } } -bool Oneshot::msgbox(int type, const char *body, const char *title) -{ - if (title && !title[0]) +bool Oneshot::msgbox(int type, const char *body, const char *title) { + if (title && !title[0]) #ifdef _WIN32 - title = "\u200b"; // Zero width space instead of filename in messagebox title + title = + "\u200b"; // Zero width space instead of filename in messagebox title #else - title = ""; + title = ""; #endif #ifdef OS_LINUX - linux_DialogData data = { type, body, title, 0 }; - gdk_threads_add_idle(linux_dialog, &data); - gtk_main(); - return data.result; + linux_DialogData data = {type, body, title, 0}; + gdk_threads_add_idle(linux_dialog, &data); + gtk_main(); + return data.result; #else - // Buttons data - static const SDL_MessageBoxButtonData buttonOk = { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "OK" }; - static const SDL_MessageBoxButtonData buttonsOk[] = { buttonOk }; - SDL_MessageBoxButtonData buttonYes = { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, p->txtYes.c_str() }; - SDL_MessageBoxButtonData buttonNo = { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, p->txtNo.c_str() }; - SDL_MessageBoxButtonData buttonsYesNo[] = { buttonNo, buttonYes }; - - // Message box data - SDL_MessageBoxData data; - data.window = NULL; //p->window; - data.colorScheme = 0; - data.title = title; - data.message = body; - - // Set message box type - switch (type) - { - case MSG_INFO: - case MSG_YESNO: - default: - data.flags = SDL_MESSAGEBOX_INFORMATION; - break; - case MSG_WARN: - data.flags = SDL_MESSAGEBOX_WARNING; - break; - case MSG_ERR: - data.flags = SDL_MESSAGEBOX_WARNING; - break; - } - - // Set message box buttons - switch (type) - { - case MSG_INFO: - case MSG_WARN: - case MSG_ERR: - default: - data.numbuttons = 1; - data.buttons = buttonsOk; - break; - case MSG_YESNO: - data.numbuttons = 2; - data.buttons = buttonsYesNo; - break; - } - - // Show message box - int button; - #ifdef OS_OSX - int *btn = &button; - // Message boxes and UI changes must be performed from the main thread on macOS Mojave and above. - // This block ensures the message box will show from the main thread. - dispatch_sync(dispatch_get_main_queue(), - ^{ SDL_ShowMessageBox(&data, btn); } - ); - #else - SDL_ShowMessageBox(&data, &button); - #endif - - return button ? true : false; + // Buttons data + static const SDL_MessageBoxButtonData buttonOk = { + SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "OK"}; + static const SDL_MessageBoxButtonData buttonsOk[] = {buttonOk}; + SDL_MessageBoxButtonData buttonYes = {SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, + 1, p->txtYes.c_str()}; + SDL_MessageBoxButtonData buttonNo = {SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, + 0, p->txtNo.c_str()}; + SDL_MessageBoxButtonData buttonsYesNo[] = {buttonNo, buttonYes}; + + // Message box data + SDL_MessageBoxData data; + data.window = NULL; // p->window; + data.colorScheme = 0; + data.title = title; + data.message = body; + + // Set message box type + switch (type) { + case MSG_INFO: + case MSG_YESNO: + default: + data.flags = SDL_MESSAGEBOX_INFORMATION; + break; + case MSG_WARN: + data.flags = SDL_MESSAGEBOX_WARNING; + break; + case MSG_ERR: + data.flags = SDL_MESSAGEBOX_WARNING; + break; + } + + // Set message box buttons + switch (type) { + case MSG_INFO: + case MSG_WARN: + case MSG_ERR: + default: + data.numbuttons = 1; + data.buttons = buttonsOk; + break; + case MSG_YESNO: + data.numbuttons = 2; + data.buttons = buttonsYesNo; + break; + } + + // Show message box + int button; +#ifdef OS_OSX + int *btn = &button; + // Message boxes and UI changes must be performed from the main thread on + // macOS Mojave and above. This block ensures the message box will show from + // the main thread. + dispatch_sync(dispatch_get_main_queue(), ^{ + SDL_ShowMessageBox(&data, btn); + }); +#else + SDL_ShowMessageBox(&data, &button); +#endif + + return button ? true : false; #endif } // not used anywhere or provided by modshot -// std::string Oneshot::textinput(const char* prompt, int char_limit, const char* fontName) { -// std::vector *fontNames = new std::vector(); -// fontNames->push_back(fontName); -// fontNames->push_back("VL Gothic"); -// Font *font = new Font(fontNames, 18); - -// Bitmap *promptBmp = new Bitmap(DEF_SCREEN_W, DEF_SCREEN_H); -// promptBmp->setInitFont(font); -// promptBmp->drawText(0, 0, DEF_SCREEN_W, DEF_SCREEN_H, prompt, 1); - -// Bitmap *inputBmp = new Bitmap(DEF_SCREEN_W, DEF_SCREEN_H); -// inputBmp->setInitFont(font); -// inputBmp->drawText(0, 0, DEF_SCREEN_W, DEF_SCREEN_H, "", 1); - -// std::string inputTextPrev = std::string(""); -// threadData.acceptingTextInput.set(); -// threadData.inputTextLimit = char_limit; -// threadData.inputText.clear(); -// SDL_StartTextInput(); - -// // Main loop -// while (threadData.acceptingTextInput) { -// if (inputTextPrev != threadData.inputText) { -// inputBmp->clear(); -// inputBmp->drawText(DEF_SCREEN_W / 2, DEF_SCREEN_H / 2, DEF_SCREEN_W, DEF_SCREEN_H, threadData.inputText.c_str(), 1); -// inputTextPrev = threadData.inputText; -// } -// } - -// // Disable text input -// SDL_StopTextInput(); - -// return threadData.inputText; +// std::string Oneshot::textinput(const char* prompt, int char_limit, const +// char* fontName) { +// std::vector *fontNames = new std::vector(); +// fontNames->push_back(fontName); +// fontNames->push_back("VL Gothic"); +// Font *font = new Font(fontNames, 18); + +// Bitmap *promptBmp = new Bitmap(DEF_SCREEN_W, DEF_SCREEN_H); +// promptBmp->setInitFont(font); +// promptBmp->drawText(0, 0, DEF_SCREEN_W, DEF_SCREEN_H, prompt, 1); + +// Bitmap *inputBmp = new Bitmap(DEF_SCREEN_W, DEF_SCREEN_H); +// inputBmp->setInitFont(font); +// inputBmp->drawText(0, 0, DEF_SCREEN_W, DEF_SCREEN_H, "", 1); + +// std::string inputTextPrev = std::string(""); +// threadData.acceptingTextInput.set(); +// threadData.inputTextLimit = char_limit; +// threadData.inputText.clear(); +// SDL_StartTextInput(); + +// // Main loop +// while (threadData.acceptingTextInput) { +// if (inputTextPrev != threadData.inputText) { +// inputBmp->clear(); +// inputBmp->drawText(DEF_SCREEN_W / 2, DEF_SCREEN_H / 2, DEF_SCREEN_W, +// DEF_SCREEN_H, threadData.inputText.c_str(), 1); inputTextPrev = +// threadData.inputText; +// } +// } + +// // Disable text input +// SDL_StopTextInput(); + +// return threadData.inputText; // } -void Oneshot::setWindowPos(int x, int y) -{ - SDL_LockMutex(p->winMutex); - p->winX = x; - p->winY = y; - p->winPosChanged = true; - SDL_UnlockMutex(p->winMutex); +void Oneshot::setWindowPos(int x, int y) { + SDL_LockMutex(p->winMutex); + p->winX = x; + p->winY = y; + p->winPosChanged = true; + SDL_UnlockMutex(p->winMutex); } -void Oneshot::resetObscured() -{ - std::fill(p->obscuredMap.begin(), p->obscuredMap.end(), 255); - obscuredDirty = true; - p->obscuredCleared = false; +void Oneshot::resetObscured() { + std::fill(p->obscuredMap.begin(), p->obscuredMap.end(), 255); + obscuredDirty = true; + p->obscuredCleared = false; } \ No newline at end of file diff --git a/src/oneshot/oneshot.h b/src/oneshot/oneshot.h index 62ae6d118..57647dbf3 100644 --- a/src/oneshot/oneshot.h +++ b/src/oneshot/oneshot.h @@ -11,77 +11,86 @@ struct OneshotPrivate; struct RGSSThreadData; -class Oneshot -{ +class Oneshot { public: - Oneshot(RGSSThreadData &threadData); - ~Oneshot(); - - //msgbox type codes - enum - { - MSG_INFO, - MSG_YESNO, - MSG_WARN, - MSG_ERR, - }; - - //Wallpaper style - enum - { - STYLE_NONE, - STYLE_TILE, - STYLE_CENTER, - STYLE_STRETCH, - STYLE_FIT, - STYLE_FILL, - STYLE_SPAN, - }; - - //Wallpaper gradient - enum - { - GRADIENT_NONE, - GRADIENT_HORIZONTAL, - GRADIENT_VERTICAL, - }; - - void update(); - - //Accessors - const std::string &os() const; - const std::string &lang() const; - const std::string &userName() const; - const std::string &savePath() const; - const std::string &docsPath() const; - const std::string &gamePath() const; - const std::string &journal() const; - const std::vector &obscuredMap() const; - bool obscuredCleared() const; - bool allowExit() const; - bool exiting() const; - - //Mutators - void setYesNo(const char *yes, const char *no); - void setWindowPos(int x, int y); - void setExiting(bool exiting); - void setAllowExit(bool allowExit); - void resetObscured(); - - //Functions - bool msgbox(int type, const char *body, const char *title); - // std::string textinput(const char* prompt, int char_limit, const char* fontName); - - //Dirty flag for obscured texture - bool obscuredDirty; + Oneshot(RGSSThreadData &threadData); + ~Oneshot(); + + // msgbox type codes + enum { + MSG_INFO, + MSG_YESNO, + MSG_WARN, + MSG_ERR, + }; + + // Wallpaper style + enum { + STYLE_NONE, + STYLE_TILE, + STYLE_CENTER, + STYLE_STRETCH, + STYLE_FIT, + STYLE_FILL, + STYLE_SPAN, + }; + + // Wallpaper gradient + enum { + GRADIENT_NONE, + GRADIENT_HORIZONTAL, + GRADIENT_VERTICAL, + }; + + // this isn't JS, we have enums!!!!!!! + enum Desktop { + DE_GNOME, + DE_CINNAMON, + DE_MATE, + DE_LXDE, + DE_XFCE, + DE_KDE, + DE_DEEPIN, + DE_FALLBACK, + }; + + void update(); + + // Accessors + const std::string &os() const; + const std::string &lang() const; + const std::string &userName() const; + const std::string &savePath() const; + const std::string &docsPath() const; + const std::string &gamePath() const; + const std::string &journal() const; + const std::vector &obscuredMap() const; + bool obscuredCleared() const; + bool allowExit() const; + bool exiting() const; + + // Mutators + void setYesNo(const char *yes, const char *no); + void setWindowPos(int x, int y); + void setExiting(bool exiting); + void setAllowExit(bool allowExit); + void resetObscured(); + + // Functions + bool msgbox(int type, const char *body, const char *title); + // std::string textinput(const char* prompt, int char_limit, const char* + // fontName); + + // Dirty flag for obscured texture + bool obscuredDirty; #ifdef __linux__ - std::string desktopEnv; + Desktop desktop; #endif private: - OneshotPrivate *p; - RGSSThreadData &threadData; + OneshotPrivate *p; + RGSSThreadData &threadData; }; #endif // ONESHOT_H \ No newline at end of file