diff --git a/src/wx/CMakeLists.txt b/src/wx/CMakeLists.txt index 3a1c6755..ba52363d 100644 --- a/src/wx/CMakeLists.txt +++ b/src/wx/CMakeLists.txt @@ -696,8 +696,14 @@ set( # from external source with minor modifications widgets/wx/checkedlistctrl.h ../common/version_cpp.h + winsparkle-wrapper.h ) +if(WIN32) + list(APPEND SRC_WX winsparkle-wrapper.cpp) + list(APPEND HDR_WX winsparkle-wrapper.h) +endif() + set( RES_WX ${XRC_SOURCES} @@ -757,6 +763,25 @@ add_executable( ${CM_STUFF} ) +if(WIN32 AND (AMD64 OR X86_32)) + if(NOT DEFINED WINSPARKLE_BIN_RELEASE_DIR) + set(WINSPARKLE_BIN_RELEASE_DIR ${CMAKE_SOURCE_DIR}/dependencies/WinSparkle-0.6.0) + endif() + + target_include_directories( + visualboyadvance-m + PRIVATE ${WINSPARKLE_BIN_RELEASE_DIR}/include + ) + + if(AMD64) + set(WINSPARKLE_DLL ${CMAKE_SOURCE_DIR}/dependencies/WinSparkle-0.6.0/x64/Release/WinSparkle.dll) + else() + set(WINSPARKLE_DLL ${CMAKE_SOURCE_DIR}/dependencies/WinSparkle-0.6.0/Release/WinSparkle.dll) + endif() + + configure_file(winsparkle-path.h.in ${CMAKE_BINARY_DIR}/winsparkle-path.h) +endif() + target_link_libraries( visualboyadvance-m ${VBAMCORE_LIBS} diff --git a/src/wx/winsparkle-path.h.in b/src/wx/winsparkle-path.h.in new file mode 100644 index 00000000..6791868d --- /dev/null +++ b/src/wx/winsparkle-path.h.in @@ -0,0 +1 @@ +#define WINSPARKLE_DLL_PATH "@WINSPARKLE_DLL@" diff --git a/src/wx/winsparkle-wrapper.cpp b/src/wx/winsparkle-wrapper.cpp new file mode 100644 index 00000000..5a6f86ae --- /dev/null +++ b/src/wx/winsparkle-wrapper.cpp @@ -0,0 +1,93 @@ +#include + +#include "wxvbam.h" +#include "winsparkle-wrapper.h" +#include "wx/msw/private.h" + +wxDynamicLibrary *winsparkle_dll = nullptr; + +typedef void (*func_win_sparkle_init)(); +func_win_sparkle_init winsparkle_init = nullptr; + +typedef void (*func_win_sparkle_check_update_with_ui)(); +func_win_sparkle_check_update_with_ui winsparkle_check_update_with_ui = nullptr; + +typedef void (*func_win_sparkle_set_appcast_url)(const char *); +func_win_sparkle_set_appcast_url winsparkle_set_appcast_url = nullptr; + +typedef void (*func_win_sparkle_set_app_details)(const wchar_t*, const wchar_t*, const wchar_t*); +func_win_sparkle_set_app_details winsparkle_set_app_details = nullptr; + +typedef void (*func_win_sparkle_cleanup)(); +func_win_sparkle_cleanup winsparkle_cleanup = nullptr; + +wxString *temp_file_name = nullptr; + +WinSparkleDllWrapper::WinSparkleDllWrapper() +{ + wxFile temp_file; + temp_file_name = new wxString(wxFileName::CreateTempFileName("winsparkle", &temp_file)); + + HRSRC res = FindResource(wxGetInstance(), MAKEINTRESOURCE(WINSPARKLE_DLL_RC), RT_RCDATA); + + if (!res) + wxLogFatalError("Could not find resource for winsparkle DLL."); + + HGLOBAL res_handle = LoadResource(NULL, res); + + if (!res_handle) + wxLogFatalError("Could not load resource for winsparkle DLL."); + + uint64_t res_size = SizeofResource(NULL, res); + + char *res_data = (char *)LockResource(res_handle); + + temp_file.Write((void *)res_data, res_size); + + temp_file.Close(); + + winsparkle_dll = new wxDynamicLibrary(*temp_file_name, wxDL_NOW | wxDL_VERBATIM); + + winsparkle_init = reinterpret_cast(winsparkle_dll->GetSymbol("win_sparkle_init")); + winsparkle_check_update_with_ui = reinterpret_cast(winsparkle_dll->GetSymbol("win_sparkle_check_update_with_ui")); + winsparkle_set_appcast_url = reinterpret_cast(winsparkle_dll->GetSymbol("win_sparkle_set_appcast_url")); + winsparkle_set_app_details = reinterpret_cast(winsparkle_dll->GetSymbol("win_sparkle_set_app_details")); + winsparkle_cleanup = reinterpret_cast(winsparkle_dll->GetSymbol("win_sparkle_cleanup")); +} + +WinSparkleDllWrapper::~WinSparkleDllWrapper() +{ + delete winsparkle_dll; + + wxRemoveFile(*temp_file_name); + + delete temp_file_name; +} + +void win_sparkle_init() +{ + winsparkle_init(); +} + +void win_sparkle_check_update_with_ui() +{ + winsparkle_check_update_with_ui(); +} + + +void win_sparkle_set_appcast_url(const char *url) +{ + winsparkle_set_appcast_url(url); +} + + +void win_sparkle_set_app_details(const wchar_t *company_name, const wchar_t *app_name, const wchar_t *app_version) +{ + winsparkle_set_app_details(company_name, app_name, app_version); +} + + +void win_sparkle_cleanup() +{ + winsparkle_cleanup(); +} diff --git a/src/wx/winsparkle-wrapper.h b/src/wx/winsparkle-wrapper.h new file mode 100644 index 00000000..99cfcb4c --- /dev/null +++ b/src/wx/winsparkle-wrapper.h @@ -0,0 +1,17 @@ +#ifndef WINSPARKLE_WRAPPER_H +#define WINSPARKLE_WRAPPER_H + +#define WINSPARKLE_DLL_RC 300 + +struct WinSparkleDllWrapper { + WinSparkleDllWrapper(); + ~WinSparkleDllWrapper(); +}; + +void win_sparkle_init(); +void win_sparkle_check_update_with_ui(); +void win_sparkle_set_appcast_url(const char *url); +void win_sparkle_set_app_details(const wchar_t *company_name, const wchar_t *app_name, const wchar_t *app_version); +void win_sparkle_cleanup(); + +#endif /* WINSPARKLE_WRAPPER_H */ diff --git a/src/wx/wxvbam.h b/src/wx/wxvbam.h index 451a5599..b64d309d 100644 --- a/src/wx/wxvbam.h +++ b/src/wx/wxvbam.h @@ -73,6 +73,7 @@ inline std::string ToString(const wxChar* aString) } class MainFrame; +class WinSparkleDllWrapper; class wxvbamApp : public wxApp { public: @@ -156,7 +157,8 @@ protected: private: wxPathList config_path; - char* home = NULL; + char* home = nullptr; + WinSparkleDllWrapper *winsparkle = nullptr; }; DECLARE_APP(wxvbamApp); diff --git a/src/wx/wxvbam.rc b/src/wx/wxvbam.rc index 1451ae90..46372f0c 100644 --- a/src/wx/wxvbam.rc +++ b/src/wx/wxvbam.rc @@ -5,6 +5,9 @@ AAAAA_MAINICON ICON "icons/vbam.ico" #include "version.h" +#include "winsparkle-wrapper.h" +#include "winsparkle-path.h" + ///////////////////////////////////////////////////////////////////////////// // // Version @@ -13,6 +16,8 @@ AAAAA_MAINICON ICON "icons/vbam.ico" #define VER_PRODUCTVERSION VER_FILEVERSION #define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR +WINSPARKLE_DLL_RC RCDATA WINSPARKLE_DLL_PATH + VS_VERSION_INFO VERSIONINFO FILEVERSION VER_FILEVERSION PRODUCTVERSION VER_PRODUCTVERSION