1
0
mirror of synced 2024-12-01 02:37:18 +01:00

sys: Merge splash screen and ImHex into one application

This fixes so many issues the previous implementation had, especially on Unix
This commit is contained in:
WerWolv 2021-04-20 21:46:48 +02:00
parent d7811e2c55
commit 1f2fe6b93d
24 changed files with 342 additions and 335 deletions

1
.idea/vcs.xml generated
View File

@ -2,6 +2,7 @@
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/curl" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/fmt" vcs="Git" /> <mapping directory="$PROJECT_DIR$/external/fmt" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/nativefiledialog" vcs="Git" /> <mapping directory="$PROJECT_DIR$/external/nativefiledialog" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/xdgpp" vcs="Git" /> <mapping directory="$PROJECT_DIR$/external/xdgpp" vcs="Git" />

View File

@ -40,10 +40,13 @@ add_executable(imhex ${application_type}
source/main.cpp source/main.cpp
source/window.cpp source/window.cpp
source/init/splash_window.cpp
source/init/tasks.cpp
source/helpers/patches.cpp source/helpers/patches.cpp
source/helpers/project_file_handler.cpp source/helpers/project_file_handler.cpp
source/helpers/loader_script_handler.cpp source/helpers/loader_script_handler.cpp
source/helpers/plugin_handler.cpp source/helpers/plugin_manager.cpp
source/helpers/encoding_file.cpp source/helpers/encoding_file.cpp
source/providers/file_provider.cpp source/providers/file_provider.cpp
@ -68,7 +71,6 @@ add_executable(imhex ${application_type}
${imhex_icon} ${imhex_icon}
) )
set_target_properties(imhex PROPERTIES OUTPUT_NAME "imhexg")
set_target_properties(imhex PROPERTIES CXX_VISIBILITY_PRESET hidden) set_target_properties(imhex PROPERTIES CXX_VISIBILITY_PRESET hidden)
target_link_directories(imhex PRIVATE ${CAPSTONE_LIBRARY_DIRS} ${MAGIC_LIBRARY_DIRS}) target_link_directories(imhex PRIVATE ${CAPSTONE_LIBRARY_DIRS} ${MAGIC_LIBRARY_DIRS})
@ -78,8 +80,4 @@ else ()
target_link_libraries(imhex magic ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} dl pthread libyara) target_link_libraries(imhex magic ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} dl pthread libyara)
endif () endif ()
set_target_properties(imhex PROPERTIES VERSION ${IMHEX_VERSION})
add_subdirectory(splash)
set_target_properties(splash PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
createPackage() createPackage()

View File

@ -252,9 +252,9 @@ macro(createPackage)
# Enforce DragNDrop packaging. # Enforce DragNDrop packaging.
set(CPACK_GENERATOR "DragNDrop") set(CPACK_GENERATOR "DragNDrop")
install(TARGETS splash imhex BUNDLE DESTINATION .) install(TARGETS imhex BUNDLE DESTINATION .)
else() else()
install(TARGETS splash imhex RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS imhex RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif() endif()

View File

@ -44,16 +44,16 @@ namespace hex {
}; };
}; };
class PluginHandler { class PluginManager {
public: public:
PluginHandler() = delete; PluginManager() = delete;
static void load(std::string_view pluginFolder); static bool load(std::string_view pluginFolder);
static void unload(); static void unload();
static void reload(); static void reload();
static const auto& getPlugins() { static const auto& getPlugins() {
return PluginHandler::s_plugins; return PluginManager::s_plugins;
} }
private: private:

View File

@ -8,11 +8,11 @@
struct GLFWwindow; struct GLFWwindow;
namespace hex::pre { namespace hex::init {
class WindowSplash { class WindowSplash {
public: public:
WindowSplash(); WindowSplash(int &argc, char **&argv);
~WindowSplash(); ~WindowSplash();
bool loop(); bool loop();
@ -24,7 +24,7 @@ namespace hex::pre {
private: private:
GLFWwindow *m_window; GLFWwindow *m_window;
std::mutex m_progressMutex; std::mutex m_progressMutex;
float m_progress; float m_progress = 0;
std::string m_currTaskName; std::string m_currTaskName;
void initGLFW(); void initGLFW();

22
include/init/tasks.hpp Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include <functional>
#include <string>
#include <vector>
namespace hex::init {
struct Task {
std::string name;
std::function<bool()> function;
};
struct Argument {
std::string name, value;
};
std::vector<Task> getInitTasks();
std::vector<Task> getExitTasks();
std::vector<Argument>& getInitArguments();
}

View File

@ -21,7 +21,7 @@ namespace hex {
class ViewHexEditor : public View { class ViewHexEditor : public View {
public: public:
ViewHexEditor(std::vector<lang::PatternData*> &patternData); ViewHexEditor();
~ViewHexEditor() override; ~ViewHexEditor() override;
void drawContent() override; void drawContent() override;
@ -32,8 +32,6 @@ namespace hex {
private: private:
MemoryEditor m_memoryEditor; MemoryEditor m_memoryEditor;
std::vector<lang::PatternData*> &m_patternData;
std::map<u64, u32> m_highlightedBytes; std::map<u64, u32> m_highlightedBytes;
std::vector<char> m_searchStringBuffer; std::vector<char> m_searchStringBuffer;

View File

@ -18,7 +18,7 @@ namespace hex {
class ViewPattern : public View { class ViewPattern : public View {
public: public:
explicit ViewPattern(std::vector<lang::PatternData*> &patternData); ViewPattern();
~ViewPattern() override; ~ViewPattern() override;
void drawMenu() override; void drawMenu() override;
@ -27,7 +27,6 @@ namespace hex {
private: private:
lang::PatternLanguage *m_patternLanguageRuntime; lang::PatternLanguage *m_patternLanguageRuntime;
std::vector<lang::PatternData*> &m_patternData;
std::vector<std::string> m_possiblePatternFiles; std::vector<std::string> m_possiblePatternFiles;
int m_selectedPatternFile = 0; int m_selectedPatternFile = 0;
bool m_runAutomatically = false; bool m_runAutomatically = false;

View File

@ -16,15 +16,13 @@ namespace hex {
class ViewPatternData : public View { class ViewPatternData : public View {
public: public:
ViewPatternData(std::vector<lang::PatternData*> &patternData); ViewPatternData();
~ViewPatternData() override; ~ViewPatternData() override;
void drawContent() override; void drawContent() override;
void drawMenu() override; void drawMenu() override;
private: private:
std::vector<lang::PatternData*> &m_patternData;
std::vector<lang::PatternData*> m_sortedPatternData; std::vector<lang::PatternData*> m_sortedPatternData;
}; };

View File

@ -15,7 +15,7 @@ namespace hex {
class Window { class Window {
public: public:
Window(int &argc, char **&argv); Window();
~Window(); ~Window();
void loop(); void loop();
@ -26,9 +26,6 @@ namespace hex {
friend void ImHexSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler *handler, ImGuiTextBuffer *buf); friend void ImHexSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandler *handler, ImGuiTextBuffer *buf);
bool setFont(const std::filesystem::path &font_path); bool setFont(const std::filesystem::path &font_path);
void initPlugins();
void deinitPlugins();
private: private:
void frameBegin(); void frameBegin();
void frameEnd(); void frameEnd();

View File

@ -4,6 +4,7 @@
#include <cstddef> #include <cstddef>
#include <hex/helpers/lang.hpp> #include <hex/helpers/lang.hpp>
#include <hex/helpers/logger.hpp>
using namespace hex::lang_literals; using namespace hex::lang_literals;
using u8 = std::uint8_t; using u8 = std::uint8_t;

View File

@ -0,0 +1,40 @@
#pragma once
#include <fmt/core.h>
#include <fmt/color.h>
namespace hex::log {
void debug(std::string_view fmt, auto ... args) {
#if defined(DEBUG)
fmt::print(fg(fmt::color::green_yellow) | fmt::emphasis::bold, "[DEBUG] ");
fmt::print(fmt, args...);
fmt::print("\n");
#endif
}
void info(std::string_view fmt, auto ... args) {
fmt::print(fg(fmt::color::cadet_blue) | fmt::emphasis::bold, "[INFO] ");
fmt::print(fmt, args...);
fmt::print("\n");
}
void warn(std::string_view fmt, auto ... args) {
fmt::print(fg(fmt::color::light_golden_rod_yellow) | fmt::emphasis::bold, "[WARN] ");
fmt::print(fmt, args...);
fmt::print("\n");
}
void error(std::string_view fmt, auto ... args) {
fmt::print(fg(fmt::color::red) | fmt::emphasis::bold, "[ERROR] ");
fmt::print(fmt, args...);
fmt::print("\n");
}
void fatal(std::string_view fmt, auto ... args) {
fmt::print(fg(fmt::color::purple) | fmt::emphasis::bold, "[FATAL] ");
fmt::print(fmt, args...);
fmt::print("\n");
}
}

View File

@ -25,6 +25,8 @@ namespace hex {
namespace prv { class Provider; } namespace prv { class Provider; }
namespace dp { class Node; } namespace dp { class Node; }
namespace lang { class PatternData; }
class View; class View;
class SharedData { class SharedData {
@ -58,6 +60,7 @@ namespace hex {
static u32 patternPaletteOffset; static u32 patternPaletteOffset;
static std::string errorPopupMessage; static std::string errorPopupMessage;
static std::list<ImHexApi::Bookmarks::Entry> bookmarkEntries; static std::list<ImHexApi::Bookmarks::Entry> bookmarkEntries;
static std::vector<lang::PatternData*> patternData;
static std::map<std::string, std::string> languageNames; static std::map<std::string, std::string> languageNames;
static std::map<std::string, std::vector<LanguageDefinition>> languageDefinitions; static std::map<std::string, std::vector<LanguageDefinition>> languageDefinitions;

View File

@ -14,6 +14,7 @@ namespace hex {
u32 SharedData::patternPaletteOffset; u32 SharedData::patternPaletteOffset;
std::string SharedData::errorPopupMessage; std::string SharedData::errorPopupMessage;
std::list<ImHexApi::Bookmarks::Entry> SharedData::bookmarkEntries; std::list<ImHexApi::Bookmarks::Entry> SharedData::bookmarkEntries;
std::vector<lang::PatternData*> SharedData::patternData;
std::map<std::string, std::string> SharedData::languageNames; std::map<std::string, std::string> SharedData::languageNames;
std::map<std::string, std::vector<LanguageDefinition>> SharedData::languageDefinitions; std::map<std::string, std::vector<LanguageDefinition>> SharedData::languageDefinitions;

View File

@ -1,4 +1,4 @@
#include "helpers/plugin_handler.hpp" #include "helpers/plugin_manager.hpp"
#include <filesystem> #include <filesystem>
@ -71,26 +71,31 @@ namespace hex {
return ""; return "";
} }
void PluginHandler::load(std::string_view pluginFolder) { bool PluginManager::load(std::string_view pluginFolder) {
if (!std::filesystem::exists(pluginFolder)) if (!std::filesystem::exists(pluginFolder))
throw std::runtime_error("Failed to find plugin folder"); return false;
PluginHandler::s_pluginFolder = pluginFolder; PluginManager::s_pluginFolder = pluginFolder;
for (auto& pluginPath : std::filesystem::directory_iterator(pluginFolder)) { for (auto& pluginPath : std::filesystem::directory_iterator(pluginFolder)) {
if (pluginPath.is_regular_file() && pluginPath.path().extension() == ".hexplug") if (pluginPath.is_regular_file() && pluginPath.path().extension() == ".hexplug")
PluginHandler::s_plugins.emplace_back(pluginPath.path().string()); PluginManager::s_plugins.emplace_back(pluginPath.path().string());
}
} }
void PluginHandler::unload() { if (PluginManager::s_plugins.empty())
PluginHandler::s_plugins.clear(); return false;
PluginHandler::s_pluginFolder.clear();
return true;
} }
void PluginHandler::reload() { void PluginManager::unload() {
PluginHandler::unload(); PluginManager::s_plugins.clear();
PluginHandler::load(PluginHandler::s_pluginFolder); PluginManager::s_pluginFolder.clear();
}
void PluginManager::reload() {
PluginManager::unload();
PluginManager::load(PluginManager::s_pluginFolder);
} }
} }

View File

@ -1,6 +1,7 @@
#include "splash_window.hpp" #include "init/splash_window.hpp"
#include <hex/helpers/utils.hpp> #include <hex/helpers/utils.hpp>
#include <hex/helpers/shared_data.hpp>
#include <imgui.h> #include <imgui.h>
#include <imgui_internal.h> #include <imgui_internal.h>
@ -17,28 +18,12 @@
using namespace std::literals::chrono_literals; using namespace std::literals::chrono_literals;
namespace hex::pre { namespace hex::init {
static void centerWindow(GLFWwindow *window) { WindowSplash::WindowSplash(int &argc, char **&argv) {
GLFWmonitor *monitor = glfwGetPrimaryMonitor(); SharedData::mainArgc = argc;
if (!monitor) SharedData::mainArgv = argv;
return;
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
if (!mode)
return;
int monitorX, monitorY;
glfwGetMonitorPos(monitor, &monitorX, &monitorY);
int windowWidth, windowHeight;
glfwGetWindowSize(window, &windowWidth, &windowHeight);
glfwSetWindowPos(window, monitorX + (mode->width - windowWidth) / 2, monitorY + (mode->height - windowHeight) / 2);
}
WindowSplash::WindowSplash() {
this->initGLFW(); this->initGLFW();
this->initImGui(); this->initImGui();
} }
@ -84,13 +69,14 @@ namespace hex::pre {
break; break;
} }
if (splashTexture == nullptr) if (splashTexture == nullptr) {
log::fatal("Could not load splash screen image!");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
ON_SCOPE_EXIT { ImGui::UnloadImage(splashTexture); }; ON_SCOPE_EXIT { ImGui::UnloadImage(splashTexture); };
auto tasksSucceeded = processTasksAsync();
auto done = processTasksAsync();
while (!glfwWindowShouldClose(this->m_window)) { while (!glfwWindowShouldClose(this->m_window)) {
glfwPollEvents(); glfwPollEvents();
@ -120,22 +106,42 @@ namespace hex::pre {
glfwSwapBuffers(this->m_window); glfwSwapBuffers(this->m_window);
if (done.wait_for(0s) == std::future_status::ready) { if (tasksSucceeded.wait_for(0s) == std::future_status::ready) {
return done.get(); return tasksSucceeded.get();
} }
} }
return false; return false;
} }
static void centerWindow(GLFWwindow *window) {
GLFWmonitor *monitor = glfwGetPrimaryMonitor();
if (!monitor)
return;
const GLFWvidmode *mode = glfwGetVideoMode(monitor);
if (!mode)
return;
int monitorX, monitorY;
glfwGetMonitorPos(monitor, &monitorX, &monitorY);
int windowWidth, windowHeight;
glfwGetWindowSize(window, &windowWidth, &windowHeight);
glfwSetWindowPos(window, monitorX + (mode->width - windowWidth) / 2, monitorY + (mode->height - windowHeight) / 2);
}
void WindowSplash::initGLFW() { void WindowSplash::initGLFW() {
glfwSetErrorCallback([](int error, const char *description) { glfwSetErrorCallback([](int error, const char *description) {
printf("GLFW Error: %d - %s\n", error, description); log::fatal("GLFW Error: {0} - {0}", error, description);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}); });
if (!glfwInit()) if (!glfwInit()) {
log::fatal("Failed to initialize GLFW!");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
@ -145,17 +151,21 @@ namespace hex::pre {
glfwWindowHint(GLFW_FLOATING, GLFW_TRUE); glfwWindowHint(GLFW_FLOATING, GLFW_TRUE);
this->m_window = glfwCreateWindow(640, 400, "ImHex", nullptr, nullptr); this->m_window = glfwCreateWindow(640, 400, "ImHex", nullptr, nullptr);
if (this->m_window == nullptr) if (this->m_window == nullptr) {
log::fatal("Failed to create GLFW window!");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
centerWindow(this->m_window); centerWindow(this->m_window);
glfwMakeContextCurrent(this->m_window); glfwMakeContextCurrent(this->m_window);
glfwSwapInterval(1); glfwSwapInterval(1);
if (gladLoadGL() == 0) if (gladLoadGL() == 0) {
log::fatal("Failed to load OpenGL Context!");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
}
void WindowSplash::initImGui() { void WindowSplash::initImGui() {
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();

150
source/init/tasks.cpp Normal file
View File

@ -0,0 +1,150 @@
#include "init/tasks.hpp"
#include <hex/helpers/net.hpp>
#include <hex/helpers/utils.hpp>
#include <hex/api/content_registry.hpp>
#include "views/view_hexeditor.hpp"
#include "views/view_pattern.hpp"
#include "views/view_pattern_data.hpp"
#include "views/view_hashes.hpp"
#include "views/view_information.hpp"
#include "views/view_help.hpp"
#include "views/view_tools.hpp"
#include "views/view_strings.hpp"
#include "views/view_data_inspector.hpp"
#include "views/view_disassembler.hpp"
#include "views/view_bookmarks.hpp"
#include "views/view_patches.hpp"
#include "views/view_command_palette.hpp"
#include "views/view_settings.hpp"
#include "views/view_data_processor.hpp"
#include "views/view_yara.hpp"
#include "helpers/plugin_manager.hpp"
#include <filesystem>
namespace hex::init {
static bool checkForUpdates() {
hex::Net net;
auto releases = net.getJson("https://api.github.com/repos/WerWolv/ImHex/releases/latest");
if (releases.code != 200)
return false;
if (!releases.response.contains("tag_name") || !releases.response["tag_name"].is_string())
return false;
auto currVersion = "v" + std::string(IMHEX_VERSION).substr(0, 5);
auto latestVersion = releases.response["tag_name"].get<std::string_view>();
if (latestVersion != currVersion)
getInitArguments().push_back({ "update-available", latestVersion.data() });
return true;
}
bool createDirectories() {
std::filesystem::create_directories(hex::getPath(ImHexPath::Patterns)[0]);
std::filesystem::create_directories(hex::getPath(ImHexPath::PatternsInclude)[0]);
std::filesystem::create_directories(hex::getPath(ImHexPath::Magic)[0]);
std::filesystem::create_directories(hex::getPath(ImHexPath::Plugins)[0]);
std::filesystem::create_directories(hex::getPath(ImHexPath::Resources)[0]);
std::filesystem::create_directories(hex::getPath(ImHexPath::Config)[0]);
return true;
}
bool loadDefaultViews() {
ContentRegistry::Views::add<ViewHexEditor>();
ContentRegistry::Views::add<ViewPattern>();
ContentRegistry::Views::add<ViewPatternData>();
ContentRegistry::Views::add<ViewDataInspector>();
ContentRegistry::Views::add<ViewHashes>();
ContentRegistry::Views::add<ViewInformation>();
ContentRegistry::Views::add<ViewStrings>();
ContentRegistry::Views::add<ViewDisassembler>();
ContentRegistry::Views::add<ViewBookmarks>();
ContentRegistry::Views::add<ViewPatches>();
ContentRegistry::Views::add<ViewTools>();
ContentRegistry::Views::add<ViewCommandPalette>();
ContentRegistry::Views::add<ViewHelp>();
ContentRegistry::Views::add<ViewSettings>();
ContentRegistry::Views::add<ViewDataProcessor>();
ContentRegistry::Views::add<ViewYara>();
return true;
}
bool deleteViews() {
for (auto &view : SharedData::views)
delete view;
SharedData::views.clear();
return true;
}
bool loadPlugins() {
for (const auto &dir : hex::getPath(ImHexPath::Plugins)) {
PluginManager::load(dir);
}
if (PluginManager::getPlugins().empty()) {
getInitArguments().push_back({ "no-plugins", { } });
return false;
}
for (const auto &plugin : PluginManager::getPlugins()) {
plugin.initializePlugin();
}
return true;
}
bool unloadPlugins() {
PluginManager::unload();
return true;
}
bool loadSettings() {
ContentRegistry::Settings::load();
return true;
}
bool storeSettings() {
ContentRegistry::Settings::store();
return true;
}
std::vector<Task> getInitTasks() {
return {
{ "Checking for updates...", checkForUpdates },
{ "Creating directories...", createDirectories },
{ "Loading default views...", loadDefaultViews },
{ "Loading plugins...", loadPlugins },
{ "Loading settings...", loadSettings }
};
}
std::vector<Task> getExitTasks() {
return {
{ "Unloading plugins...", unloadPlugins },
{ "Saving settings...", storeSettings },
{ "Cleaning up views...", deleteViews }
};
}
std::vector<Argument>& getInitArguments() {
static std::vector<Argument> initArguments;
return initArguments;
}
}

View File

@ -2,61 +2,47 @@
#include "window.hpp" #include "window.hpp"
#include <hex/api/content_registry.hpp> #include "init/splash_window.hpp"
#include <hex/providers/provider.hpp> #include "init/tasks.hpp"
#include <hex/lang/pattern_data.hpp>
#include <hex/helpers/utils.hpp>
#include "views/view_hexeditor.hpp"
#include "views/view_pattern.hpp"
#include "views/view_pattern_data.hpp"
#include "views/view_hashes.hpp"
#include "views/view_information.hpp"
#include "views/view_help.hpp"
#include "views/view_tools.hpp"
#include "views/view_strings.hpp"
#include "views/view_data_inspector.hpp"
#include "views/view_disassembler.hpp"
#include "views/view_bookmarks.hpp"
#include "views/view_patches.hpp"
#include "views/view_command_palette.hpp"
#include "views/view_settings.hpp"
#include "views/view_data_processor.hpp"
#include "views/view_yara.hpp"
#include <vector>
int main(int argc, char **argv) { int main(int argc, char **argv) {
using namespace hex; using namespace hex;
Window window(argc, argv); // Initialization
{
init::WindowSplash splashWindow(argc, argv);
// Shared Data for (const auto &[name, task] : init::getInitTasks())
std::vector<lang::PatternData*> patternData; splashWindow.addStartupTask(name, task);
// Create views if (!splashWindow.loop())
ContentRegistry::Views::add<ViewHexEditor>(patternData); init::getInitArguments().push_back({ "tasks-failed", { } });
ContentRegistry::Views::add<ViewPattern>(patternData); }
ContentRegistry::Views::add<ViewPatternData>(patternData);
ContentRegistry::Views::add<ViewDataInspector>();
ContentRegistry::Views::add<ViewHashes>();
ContentRegistry::Views::add<ViewInformation>();
ContentRegistry::Views::add<ViewStrings>();
ContentRegistry::Views::add<ViewDisassembler>();
ContentRegistry::Views::add<ViewBookmarks>();
ContentRegistry::Views::add<ViewPatches>();
ContentRegistry::Views::add<ViewTools>();
ContentRegistry::Views::add<ViewCommandPalette>();
ContentRegistry::Views::add<ViewHelp>();
ContentRegistry::Views::add<ViewSettings>();
ContentRegistry::Views::add<ViewDataProcessor>();
ContentRegistry::Views::add<ViewYara>();
if (argc > 2) // Clean up
ON_SCOPE_EXIT {
for (const auto &[name, task] : init::getExitTasks())
task();
};
// Main window
{
Window window;
if (argc == 1)
; // No arguments provided
else if (argc == 2)
EventManager::post<EventFileDropped>(argv[1]); EventManager::post<EventFileDropped>(argv[1]);
else {
hex::log::fatal("Usage: imhex [file_name]");
return EXIT_SUCCESS;
}
hex::log::info("Welcome to ImHex!");
window.loop(); window.loop();
}
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -18,8 +18,7 @@
namespace hex { namespace hex {
ViewHexEditor::ViewHexEditor(std::vector<lang::PatternData*> &patternData) ViewHexEditor::ViewHexEditor() : View("hex.view.hexeditor.name"_lang) {
: View("hex.view.hexeditor.name"_lang), m_patternData(patternData) {
this->m_searchStringBuffer.resize(0xFFF, 0x00); this->m_searchStringBuffer.resize(0xFFF, 0x00);
this->m_searchHexBuffer.resize(0xFFF, 0x00); this->m_searchHexBuffer.resize(0xFFF, 0x00);
@ -162,7 +161,7 @@ namespace hex {
EventManager::subscribe<EventPatternChanged>(this, [this]() { EventManager::subscribe<EventPatternChanged>(this, [this]() {
this->m_highlightedBytes.clear(); this->m_highlightedBytes.clear();
for (const auto &pattern : this->m_patternData) for (const auto &pattern : SharedData::patternData)
this->m_highlightedBytes.merge(pattern->getHighlightedAddresses()); this->m_highlightedBytes.merge(pattern->getHighlightedAddresses());
}); });

View File

@ -76,7 +76,7 @@ namespace hex {
} }
ViewPattern::ViewPattern(std::vector<lang::PatternData*> &patternData) : View("hex.view.pattern.name"), m_patternData(patternData) { ViewPattern::ViewPattern() : View("hex.view.pattern.name") {
this->m_patternLanguageRuntime = new lang::PatternLanguage(); this->m_patternLanguageRuntime = new lang::PatternLanguage();
this->m_textEditor.SetLanguageDefinition(PatternLanguage()); this->m_textEditor.SetLanguageDefinition(PatternLanguage());
@ -345,10 +345,10 @@ namespace hex {
} }
void ViewPattern::clearPatternData() { void ViewPattern::clearPatternData() {
for (auto &data : this->m_patternData) for (auto &data : SharedData::patternData)
delete data; delete data;
this->m_patternData.clear(); SharedData::patternData.clear();
lang::PatternData::resetPalette(); lang::PatternData::resetPalette();
} }
@ -371,7 +371,7 @@ namespace hex {
this->m_console = this->m_patternLanguageRuntime->getConsoleLog(); this->m_console = this->m_patternLanguageRuntime->getConsoleLog();
if (result.has_value()) { if (result.has_value()) {
this->m_patternData = std::move(result.value()); SharedData::patternData = std::move(result.value());
View::doLater([]{ View::doLater([]{
EventManager::post<EventPatternChanged>(); EventManager::post<EventPatternChanged>();
}); });

View File

@ -5,8 +5,7 @@
namespace hex { namespace hex {
ViewPatternData::ViewPatternData(std::vector<lang::PatternData*> &patternData) ViewPatternData::ViewPatternData() : View("hex.view.pattern_data.name") {
: View("hex.view.pattern_data.name"), m_patternData(patternData) {
EventManager::subscribe<EventPatternChanged>(this, [this]() { EventManager::subscribe<EventPatternChanged>(this, [this]() {
this->m_sortedPatternData.clear(); this->m_sortedPatternData.clear();
@ -53,7 +52,7 @@ namespace hex {
auto provider = SharedData::currentProvider; auto provider = SharedData::currentProvider;
if (provider != nullptr && provider->isReadable()) { if (provider != nullptr && provider->isReadable()) {
if (beginPatternDataTable(provider, this->m_patternData, this->m_sortedPatternData)) { if (beginPatternDataTable(provider, SharedData::patternData, this->m_sortedPatternData)) {
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
if (this->m_sortedPatternData.size() > 0) { if (this->m_sortedPatternData.size() > 0) {

View File

@ -21,7 +21,8 @@
#include <fontawesome_font.h> #include <fontawesome_font.h>
#include "helpers/plugin_handler.hpp" #include "helpers/plugin_manager.hpp"
#include "init/tasks.hpp"
#include <glad/glad.h> #include <glad/glad.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@ -53,64 +54,19 @@ namespace hex {
buf->append("\n"); buf->append("\n");
} }
Window::Window(int &argc, char **&argv) { Window::Window() {
SharedData::mainArgc = argc;
SharedData::mainArgv = argv;
SharedData::currentProvider = nullptr; SharedData::currentProvider = nullptr;
#if defined(RELEASE) #if !defined(RELEASE)
{ {
if (argc < 2) { for (const auto &[argument, value] : init::getInitArguments()) {
View::showFatalPopup("No launch arguments supplied! Please launch imhex instead of imhexg!"); if (argument == "update-available") {
}
std::string launchArguments = argv[argc - 1];
if (launchArguments.find("--args=") != 0) {
View::showFatalPopup("No launch arguments supplied! Please launch imhex instead of imhexg!");
}
bool commitChecked = false;
bool branchChecked = false;
for (const auto& arg : hex::splitString(launchArguments.substr(7), "|")) {
auto splitArg = hex::splitString(arg, "=");
// Handle flags
if (splitArg.size() == 1) {
auto &flag = splitArg[0];
if (flag == "tasks-failed") {
} else if (flag == "splash-skipped") {
}
}
// Handle arguments
else if (splitArg.size() == 2) {
auto &name = splitArg[0];
auto &value = splitArg[1];
if (name == "git-hash") {
if (value != GIT_COMMIT_HASH)
View::showFatalPopup("Launcher and ImHex version commit mismatch. Please fully update ImHex before using it!");
commitChecked = true;
} else if (name == "git-branch") {
if (value != GIT_BRANCH)
View::showFatalPopup("Launcher and ImHex version branch mismatch. Please fully update ImHex before using it!");
branchChecked = true;
} else if (name == "update") {
this->m_availableUpdate = value; this->m_availableUpdate = value;
} else if (argument == "no-plugins") {
View::showErrorPopup("No plugins are loaded, including the built-in functions plugin!\n"
"Make sure you got at least builtin.hexplug in your plugins folder.");
} }
} }
// Handle others
else {
View::showFatalPopup("Invalid launch arguments supplied! Please launch imhex instead of imhexg!");
}
}
if (!commitChecked || !branchChecked)
View::showFatalPopup("No commit information available! Please launch imhex instead of imhexg!");
} }
#endif #endif
@ -207,9 +163,6 @@ namespace hex {
glfwSetWindowTitle(this->m_window, ("ImHex - " + windowTitle).c_str()); glfwSetWindowTitle(this->m_window, ("ImHex - " + windowTitle).c_str());
}); });
this->initPlugins();
ContentRegistry::Settings::load();
EventManager::post<EventSettingsChanged>(); EventManager::post<EventSettingsChanged>();
for (const auto &path : ContentRegistry::Settings::read("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files")) for (const auto &path : ContentRegistry::Settings::read("hex.builtin.setting.imhex", "hex.builtin.setting.imhex.recent_files"))
@ -221,13 +174,6 @@ namespace hex {
this->deinitImGui(); this->deinitImGui();
this->deinitGLFW(); this->deinitGLFW();
ContentRegistry::Settings::store();
for (auto &view : SharedData::views)
delete view;
SharedData::views.clear();
this->deinitPlugins();
EventManager::unsubscribe<EventSettingsChanged>(this); EventManager::unsubscribe<EventSettingsChanged>(this);
EventManager::unsubscribe<EventFileLoaded>(this); EventManager::unsubscribe<EventFileLoaded>(this);
@ -236,7 +182,7 @@ namespace hex {
} }
void Window::loop() { void Window::loop() {
bool pressedKeys[512] = { 0 }; bool pressedKeys[512] = { false };
this->m_lastFrameTime = glfwGetTime(); this->m_lastFrameTime = glfwGetTime();
while (!glfwWindowShouldClose(this->m_window)) { while (!glfwWindowShouldClose(this->m_window)) {
@ -513,7 +459,7 @@ namespace hex {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::TextUnformatted("hex.welcome.header.plugins"_lang); ImGui::TextUnformatted("hex.welcome.header.plugins"_lang);
{ {
const auto &plugins = PluginHandler::getPlugins(); const auto &plugins = PluginManager::getPlugins();
if (plugins.empty()) { if (plugins.empty()) {
// Intentionally left untranslated so it will be readable even if no plugin with translations is loaded // Intentionally left untranslated so it will be readable even if no plugin with translations is loaded
@ -817,20 +763,6 @@ namespace hex {
ImGui_ImplOpenGL3_Init("#version 150"); ImGui_ImplOpenGL3_Init("#version 150");
} }
void Window::initPlugins() {
for (const auto &dir : hex::getPath(ImHexPath::Plugins)) {
try {
PluginHandler::load(dir);
} catch (std::runtime_error &e) {
// Plugin folder not found. Not a problem.
}
}
for (const auto &plugin : PluginHandler::getPlugins()) {
plugin.initializePlugin();
}
}
void Window::deinitGLFW() { void Window::deinitGLFW() {
glfwDestroyWindow(this->m_window); glfwDestroyWindow(this->m_window);
glfwTerminate(); glfwTerminate();
@ -845,8 +777,4 @@ namespace hex {
ImGui::DestroyContext(); ImGui::DestroyContext();
} }
void Window::deinitPlugins() {
PluginHandler::unload();
}
} }

View File

@ -1,34 +0,0 @@
cmake_minimum_required(VERSION 3.16)
include("${CMAKE_SOURCE_DIR}/cmake/build_helpers.cmake")
include("${CMAKE_SOURCE_DIR}/cmake/modules/PostprocessBundle.cmake")
get_target_property(IMHEX_VERSION imhex VERSION)
project(splash VERSION ${IMHEX_VERSION})
addVersionDefines()
configurePackageCreation()
if (WIN32)
set(application_type "WIN32")
else ()
set(application_type)
endif ()
add_executable(splash ${application_type}
source/main.cpp
source/splash_window.cpp
${imhex_icon}
)
target_include_directories(splash PUBLIC include)
add_compile_definitions(IMHEX_FILE_NAME=\"$<TARGET_FILE_NAME:imhex>\")
set_target_properties(splash PROPERTIES OUTPUT_NAME "imhex")
add_dependencies(splash imhex)
if (WIN32)
target_link_libraries(splash libimhex winpthread)
else ()
target_link_libraries(splash libimhex pthread)
endif ()

View File

@ -1,94 +0,0 @@
#include <hex.hpp>
#include "splash_window.hpp"
#include <chrono>
#include <filesystem>
#include <vector>
#include <unistd.h>
#include <hex/helpers/net.hpp>
#include <hex/helpers/utils.hpp>
using namespace std::literals::chrono_literals;
constexpr auto ImHexPath = IMHEX_FILE_NAME;
int main(int argc, char **argv) {
bool skipSplash = false;
std::string fileToOpen;
std::vector<std::string> imHexArgs;
// Handle command line arguments
{
if (argc == 1) {
// No optional arguments used, use default
} else if (argc == 2) {
if (argv[1] == std::string("--no-splash")) skipSplash = true;
else fileToOpen = argv[1];
} else if (argc == 3) {
fileToOpen = argv[1];
if (argv[2] == std::string("--no-splash")) skipSplash = true;
else {
printf("Invalid argument '%s'\n", argv[2]);
return EXIT_FAILURE;
}
} else {
printf("Usage: imhex [file_path] [--no-splash] ");
return EXIT_FAILURE;
}
}
imHexArgs.emplace_back("git-hash=" GIT_COMMIT_HASH);
imHexArgs.emplace_back("git-branch=" GIT_BRANCH);
if (!skipSplash) {
hex::pre::WindowSplash window;
window.addStartupTask("Checking for updates...", [&]{
hex::Net net;
auto releases = net.getJson("https://api.github.com/repos/WerWolv/ImHex/releases/latest");
if (releases.code != 200)
return false;
if (!releases.response.contains("tag_name") || !releases.response["tag_name"].is_string())
return false;
auto currVersion = "v" + std::string(IMHEX_VERSION).substr(0, 5);
auto latestVersion = releases.response["tag_name"].get<std::string_view>();
if (latestVersion != currVersion)
imHexArgs.push_back(std::string("update=") + latestVersion.data());
return true;
});
window.addStartupTask("Creating directories...", []{
std::filesystem::create_directories(hex::getPath(hex::ImHexPath::Patterns)[0]);
std::filesystem::create_directories(hex::getPath(hex::ImHexPath::PatternsInclude)[0]);
std::filesystem::create_directories(hex::getPath(hex::ImHexPath::Magic)[0]);
std::filesystem::create_directories(hex::getPath(hex::ImHexPath::Plugins)[0]);
std::filesystem::create_directories(hex::getPath(hex::ImHexPath::Resources)[0]);
std::filesystem::create_directories(hex::getPath(hex::ImHexPath::Config)[0]);
return true;
});
if (!window.loop())
imHexArgs.emplace_back("tasks-failed");
} else {
imHexArgs.emplace_back("splash-skipped");
}
// Launch ImHex
std::string packedArgs = "--args=" + hex::combineStrings(imHexArgs, "|");
if (fileToOpen.empty())
return execl(ImHexPath, ImHexPath, packedArgs.c_str(), nullptr);
else
return execl(ImHexPath, ImHexPath, fileToOpen.c_str(), packedArgs.c_str(), nullptr);
}