From e921da8a83d09d33a22efea5f33fb0a1aedc256a Mon Sep 17 00:00:00 2001 From: RadRussianRus Date: Sun, 27 Jun 2021 13:45:07 +0300 Subject: [PATCH 01/14] Fix `echo` in WinRT header generation Since `echo` is shell command, not executable binary, CMake won't see it. --- nuget.cmake | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/nuget.cmake b/nuget.cmake index 6fc9fd6..b420923 100644 --- a/nuget.cmake +++ b/nuget.cmake @@ -92,14 +92,7 @@ function(nuget_add_winrt target_name) ${winrt_version_test} COMMAND_ERROR_IS_FATAL ANY ) - execute_process( - COMMAND - echo - ${winrt_sdk_version} - OUTPUT_FILE - ${sdk_version_test} - COMMAND_ERROR_IS_FATAL ANY - ) + file(WRITE ${sdk_version_test} ${winrt_sdk_version}) execute_process( COMMAND ${CMAKE_COMMAND} -E compare_files ${winrt_version_key} ${winrt_version_test} From 4a63a30c17309a886961075118012fe87a1dbbff Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Tue, 29 Jun 2021 06:10:37 +0400 Subject: [PATCH 02/14] Get rid of unneeded glibc wraps --- CMakeLists.txt | 3 -- .../openssl/openssl_common/CMakeLists.txt | 8 --- external/qt/CMakeLists.txt | 27 ---------- linux_glibc_wraps/CMakeLists.txt | 22 -------- .../platform/linux/linux_glibc_wraps.c | 29 ----------- .../platform/linux/linux_glibc_wraps_32.c | 49 ----------------- .../platform/linux/linux_glibc_wraps_64.c | 52 ------------------- variables.cmake | 1 - 8 files changed, 191 deletions(-) delete mode 100644 linux_glibc_wraps/CMakeLists.txt delete mode 100644 linux_glibc_wraps/platform/linux/linux_glibc_wraps.c delete mode 100644 linux_glibc_wraps/platform/linux/linux_glibc_wraps_32.c delete mode 100644 linux_glibc_wraps/platform/linux/linux_glibc_wraps_64.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 15c7247..7299f07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,9 +5,6 @@ # https://github.com/desktop-app/legal/blob/master/LEGAL add_subdirectory(external) -if (DESKTOP_APP_USE_GLIBC_WRAPS) - add_subdirectory(linux_glibc_wraps) -endif() if (LINUX AND NOT DESKTOP_APP_USE_PACKAGED AND Qt5WaylandClient_FOUND) diff --git a/external/openssl/openssl_common/CMakeLists.txt b/external/openssl/openssl_common/CMakeLists.txt index e05ef9f..3343366 100644 --- a/external/openssl/openssl_common/CMakeLists.txt +++ b/external/openssl/openssl_common/CMakeLists.txt @@ -21,14 +21,6 @@ if (NOT DESKTOP_APP_USE_PACKAGED) endif() if (LINUX) - if (DESKTOP_APP_USE_GLIBC_WRAPS) - target_link_libraries(external_openssl_common - INTERFACE - desktop-app::linux_glibc_wraps - $ - ) - endif() - target_link_libraries(external_openssl_common INTERFACE ${CMAKE_DL_LIBS} diff --git a/external/qt/CMakeLists.txt b/external/qt/CMakeLists.txt index bd51d20..77aa5b5 100644 --- a/external/qt/CMakeLists.txt +++ b/external/qt/CMakeLists.txt @@ -287,26 +287,6 @@ else() -Wl,--no-as-needed,-lrt ) endif() - if (DESKTOP_APP_USE_GLIBC_WRAPS) - target_link_options(external_qt - INTERFACE - -Wl,-wrap,aligned_alloc - -Wl,-wrap,secure_getenv - -Wl,-wrap,clock_gettime - -Wl,--no-as-needed,-lrt - ) - if (NOT build_linux32) - target_link_options(external_qt - INTERFACE - -Wl,-wrap,__divmodti4 - ) - else() - target_link_options(external_qt - INTERFACE - -Wl,-wrap,__divmoddi4 - ) - endif() - endif() target_link_static_libraries(external_qt INTERFACE proxy @@ -335,13 +315,6 @@ else() $ ) endif() - if (DESKTOP_APP_USE_GLIBC_WRAPS) - target_link_libraries(external_qt - INTERFACE - desktop-app::linux_glibc_wraps - $ - ) - endif() if (Qt5WaylandClient_FOUND) target_link_libraries(external_qt INTERFACE diff --git a/linux_glibc_wraps/CMakeLists.txt b/linux_glibc_wraps/CMakeLists.txt deleted file mode 100644 index 49a4329..0000000 --- a/linux_glibc_wraps/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -# This file is part of Desktop App Toolkit, -# a set of libraries for developing nice desktop applications. -# -# For license and copyright information please follow this link: -# https://github.com/desktop-app/legal/blob/master/LEGAL - -add_library(linux_glibc_wraps STATIC) -add_library(desktop-app::linux_glibc_wraps ALIAS linux_glibc_wraps) - -get_filename_component(src_loc . REALPATH) - -nice_target_sources(linux_glibc_wraps ${src_loc} -PRIVATE - platform/linux/linux_glibc_wraps.c - platform/linux/linux_glibc_wraps_32.c - platform/linux/linux_glibc_wraps_64.c -) -if (NOT build_linux32) - set_source_files_properties(${src_loc}/platform/linux/linux_glibc_wraps_32.c PROPERTIES HEADER_FILE_ONLY TRUE) -else() - set_source_files_properties(${src_loc}/platform/linux/linux_glibc_wraps_64.c PROPERTIES HEADER_FILE_ONLY TRUE) -endif() diff --git a/linux_glibc_wraps/platform/linux/linux_glibc_wraps.c b/linux_glibc_wraps/platform/linux/linux_glibc_wraps.c deleted file mode 100644 index 1770ab1..0000000 --- a/linux_glibc_wraps/platform/linux/linux_glibc_wraps.c +++ /dev/null @@ -1,29 +0,0 @@ -// This file is part of Desktop App Toolkit, -// a set of libraries for developing nice desktop applications. -// -// For license and copyright information please follow this link: -// https://github.com/desktop-app/legal/blob/master/LEGAL -// -#include -#include -#include - -void *__wrap_aligned_alloc(size_t alignment, size_t size) { - void *result = NULL; - return (posix_memalign(&result, alignment, size) == 0) - ? result - : NULL; -} - -int enable_secure_inited = 0; -int enable_secure = 1; - -char *__wrap_secure_getenv(const char *name) { - if (enable_secure_inited == 0) { - enable_secure_inited = 1; - enable_secure = (geteuid() != getuid()) - || (getegid() != getgid()); - } - return enable_secure ? NULL : getenv(name); -} - diff --git a/linux_glibc_wraps/platform/linux/linux_glibc_wraps_32.c b/linux_glibc_wraps/platform/linux/linux_glibc_wraps_32.c deleted file mode 100644 index 2a0890f..0000000 --- a/linux_glibc_wraps/platform/linux/linux_glibc_wraps_32.c +++ /dev/null @@ -1,49 +0,0 @@ -// This file is part of Desktop App Toolkit, -// a set of libraries for developing nice desktop applications. -// -// For license and copyright information please follow this link: -// https://github.com/desktop-app/legal/blob/master/LEGAL -// -#include -#include - -#if defined(_M_IX86) || defined(__i386__) -#define GETTIME_GLIBC_VERSION "2.2" -#elif defined(_M_ARM) || defined(__arm__) -#define GETTIME_GLIBC_VERSION "2.4" -#else -#error Please add glibc wraps for your architecture -#endif - -int __clock_gettime_glibc_old(clockid_t clk_id, struct timespec *tp); -__asm__(".symver __clock_gettime_glibc_old,clock_gettime@GLIBC_" GETTIME_GLIBC_VERSION); - -int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) { - return __clock_gettime_glibc_old(clk_id, tp); -} - -uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p); - -int64_t __wrap___divmoddi4(int64_t num, int64_t den, int64_t *rem_p) { - int minus = 0; - int64_t v; - - if (num < 0) { - num = -num; - minus = 1; - } - if (den < 0) { - den = -den; - minus ^= 1; - } - - v = __udivmoddi4(num, den, (uint64_t *)rem_p); - if (minus) { - v = -v; - if (rem_p) - *rem_p = -(*rem_p); - } - - return v; -} - diff --git a/linux_glibc_wraps/platform/linux/linux_glibc_wraps_64.c b/linux_glibc_wraps/platform/linux/linux_glibc_wraps_64.c deleted file mode 100644 index 2d1ca15..0000000 --- a/linux_glibc_wraps/platform/linux/linux_glibc_wraps_64.c +++ /dev/null @@ -1,52 +0,0 @@ -// This file is part of Desktop App Toolkit, -// a set of libraries for developing nice desktop applications. -// -// For license and copyright information please follow this link: -// https://github.com/desktop-app/legal/blob/master/LEGAL -// -#include - -#if defined(_M_X64) || defined(__x86_64__) -#define GETTIME_GLIBC_VERSION "2.2.5" -#elif defined(__aarch64__) -#define GETTIME_GLIBC_VERSION "2.17" -#else -#error Please add glibc wraps for your architecture -#endif - -typedef unsigned int UTItype __attribute__ ((mode (TI))); -typedef int TItype __attribute__ ((mode (TI))); - -int __clock_gettime_glibc_old(clockid_t clk_id, struct timespec *tp); -__asm__(".symver __clock_gettime_glibc_old,clock_gettime@GLIBC_" GETTIME_GLIBC_VERSION); - - -int __wrap_clock_gettime(clockid_t clk_id, struct timespec *tp) { - return __clock_gettime_glibc_old(clk_id, tp); -} - -UTItype __udivmodti4(UTItype num, UTItype den, UTItype *rem_p); - -TItype __wrap___divmodti4(TItype num, TItype den, TItype *rem_p) { - int minus = 0; - TItype v; - - if (num < 0) { - num = -num; - minus = 1; - } - if (den < 0) { - den = -den; - minus ^= 1; - } - - v = __udivmodti4(num, den, (UTItype *)rem_p); - if (minus) { - v = -v; - if (rem_p) - *rem_p = -(*rem_p); - } - - return v; -} - diff --git a/variables.cmake b/variables.cmake index 5c19c2c..80c336a 100644 --- a/variables.cmake +++ b/variables.cmake @@ -32,7 +32,6 @@ option(DESKTOP_APP_DISABLE_DBUS_INTEGRATION "Disable all code for D-Bus integrat option(DESKTOP_APP_DISABLE_X11_INTEGRATION "Disable all code for X11 integration (Linux only)." OFF) option(DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION "Disable all code for Wayland integration (Linux only)." OFF) option(DESKTOP_APP_DISABLE_GTK_INTEGRATION "Disable all code for GTK integration (Linux only)." OFF) -option(DESKTOP_APP_USE_GLIBC_WRAPS "Use wraps for new GLIBC features." OFF) option(DESKTOP_APP_USE_ALLOCATION_TRACER "Use simple allocation tracer (Linux only)." OFF) option(DESKTOP_APP_USE_PACKAGED "Find libraries using CMake instead of exact paths." ${no_special_target}) option(DESKTOP_APP_USE_PACKAGED_LAZY "Bundle recommended Qt plugins for self-contained packages. (Linux only)" OFF) From cb92f08d51d38cae4cec093e8fd77e8fc38f6800 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Sat, 26 Jun 2021 20:40:07 +0400 Subject: [PATCH 03/14] Enable Qt's gtk integration --- CMakeLists.txt | 5 + external/qt/CMakeLists.txt | 14 + .../qt_static_plugins/qt_static_plugins.cpp | 3 + linux_gtk_helper/CMakeLists.txt | 24 + linux_gtk_helper/linux_gtk_helper.cpp | 972 ++++++++++++++++++ 5 files changed, 1018 insertions(+) create mode 100644 linux_gtk_helper/CMakeLists.txt create mode 100644 linux_gtk_helper/linux_gtk_helper.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7299f07..799ba0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,11 @@ if (LINUX AND Qt5WaylandClient_FOUND) add_subdirectory(linux_wayland_helper) endif() +if (LINUX + AND NOT DESKTOP_APP_USE_PACKAGED + AND NOT DESKTOP_APP_DIABLE_GTK_INTEGRATION) + add_subdirectory(linux_gtk_helper) +endif() if (DESKTOP_APP_USE_ALLOCATION_TRACER) add_subdirectory(linux_allocation_tracer) endif() diff --git a/external/qt/CMakeLists.txt b/external/qt/CMakeLists.txt index 77aa5b5..e601502 100644 --- a/external/qt/CMakeLists.txt +++ b/external/qt/CMakeLists.txt @@ -220,10 +220,17 @@ else() plugins/wayland-decoration-client/${qt_lib_prefix}bradient ) endif() + set(qt_libs_gtk_plugins) + if (NOT DESKTOP_APP_DISABLE_GTK_INTEGRATION) + set(qt_libs_gtk_plugins + plugins/platformthemes/${qt_lib_prefix}qgtk3 + ) + endif() set(qt_libs plugins/platforminputcontexts/${qt_lib_prefix}composeplatforminputcontextplugin ${qt_libs_dbus_plugins} ${qt_libs_waylandclient_plugins} + ${qt_libs_gtk_plugins} plugins/platforms/${qt_lib_prefix}qxcb plugins/xcbglintegrations/${qt_lib_prefix}qxcb-egl-integration plugins/xcbglintegrations/${qt_lib_prefix}qxcb-glx-integration @@ -322,6 +329,13 @@ else() $ ) endif() + if (NOT DESKTOP_APP_DISABLE_GTK_INTEGRATION) + target_link_libraries(external_qt + INTERFACE + desktop-app::linux_gtk_helper + $ + ) + endif() target_link_libraries(external_qt INTERFACE fontconfig diff --git a/external/qt/qt_static_plugins/qt_static_plugins.cpp b/external/qt/qt_static_plugins/qt_static_plugins.cpp index 9f0244b..71b4bad 100644 --- a/external/qt/qt_static_plugins/qt_static_plugins.cpp +++ b/external/qt/qt_static_plugins/qt_static_plugins.cpp @@ -39,6 +39,9 @@ Q_IMPORT_PLUGIN(QWaylandEglClientBufferPlugin) Q_IMPORT_PLUGIN(QWaylandWlShellIntegrationPlugin) Q_IMPORT_PLUGIN(QWaylandBradientDecorationPlugin) #endif // !DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION +#ifndef DESKTOP_APP_DISABLE_GTK_INTEGRATION +Q_IMPORT_PLUGIN(QGtk3ThemePlugin) +#endif // !DESKTOP_APP_DISABLE_GTK_INTEGRATION #endif // Q_OS_WIN | Q_OS_MAC | Q_OS_UNIX #endif // !DESKTOP_APP_USE_PACKAGED diff --git a/linux_gtk_helper/CMakeLists.txt b/linux_gtk_helper/CMakeLists.txt new file mode 100644 index 0000000..32ec4aa --- /dev/null +++ b/linux_gtk_helper/CMakeLists.txt @@ -0,0 +1,24 @@ +# This file is part of Desktop App Toolkit, +# a set of libraries for developing nice desktop applications. +# +# For license and copyright information please follow this link: +# https://github.com/desktop-app/legal/blob/master/LEGAL + +add_library(linux_gtk_helper STATIC) +add_library(desktop-app::linux_gtk_helper ALIAS linux_gtk_helper) + +nice_target_sources(linux_gtk_helper ${CMAKE_CURRENT_SOURCE_DIR} +PRIVATE + linux_gtk_helper.cpp +) + +target_compile_definitions(linux_gtk_helper PRIVATE G_LOG_DOMAIN="GtkHelper") + +target_link_libraries(linux_gtk_helper +PUBLIC + desktop-app::external_glib +) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED gtk+-3.0) +target_include_directories(linux_gtk_helper PRIVATE ${GTK_INCLUDE_DIRS}) diff --git a/linux_gtk_helper/linux_gtk_helper.cpp b/linux_gtk_helper/linux_gtk_helper.cpp new file mode 100644 index 0000000..231eb78 --- /dev/null +++ b/linux_gtk_helper/linux_gtk_helper.cpp @@ -0,0 +1,972 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#include +#include +#include +#include +#include +#include + +#define LOAD_SYMBOL(handle, func) LoadSymbol(handle, #func, func) + +namespace GtkHelper { +namespace { + +GdkPixbuf *(*gdk_pixbuf_new_from_file_at_size)( + const char *filename, + int width, + int height, + GError **error); +void (*gdk_window_focus)(GdkWindow *window, guint32 timestamp); +GdkDisplay *(*gdk_window_get_display)(GdkWindow *window); +void (*gdk_window_set_modal_hint)(GdkWindow *window, gboolean modal); +Display *(*gdk_x11_display_get_xdisplay)(GdkDisplay *display); +GType (*gdk_x11_window_get_type)(void); +Window (*gdk_x11_window_get_xid)(GdkWindow *window); +GType (*gtk_accel_label_get_type)(void); +void (*gtk_accel_label_set_accel)( + GtkAccelLabel *accel_label, + guint accelerator_key, + GdkModifierType accelerator_mods); +GtkWidget *(*gtk_bin_get_child)(GtkBin *bin); +GType (*gtk_bin_get_type)(void); +GType (*gtk_button_get_type)(void); +void (*gtk_button_set_label)(GtkButton *button, const gchar *label); +gboolean (*gtk_check_menu_item_get_active)(GtkCheckMenuItem *check_menu_item); +GType (*gtk_check_menu_item_get_type)(void); +GtkWidget* (*gtk_check_menu_item_new)(void); +void (*gtk_check_menu_item_set_active)( + GtkCheckMenuItem *check_menu_item, + gboolean is_active); +const gchar *(*gtk_check_version)( + guint required_major, + guint required_minor, + guint required_micro); +GtkClipboard *(*gtk_clipboard_get)(GdkAtom selection); +void (*gtk_clipboard_store)(GtkClipboard *clipboard); +GtkWidget *(*gtk_color_chooser_dialog_new)( + const gchar *title, + GtkWindow *parent); +GType (*gtk_color_chooser_get_type)(void); +void (*gtk_color_chooser_get_rgba)( + GtkColorChooser *chooser, + GdkRGBA *color); +void (*gtk_color_chooser_set_rgba)( + GtkColorChooser *chooser, + const GdkRGBA *color); +void (*gtk_color_chooser_set_use_alpha)( + GtkColorChooser *chooser, + gboolean use_alpha); +GType (*gtk_container_get_type)(void); +void (*gtk_container_remove)(GtkContainer *container, GtkWidget *widget); +GType (*gtk_dialog_get_type)(void); +GtkWidget* (*gtk_dialog_get_widget_for_response)( + GtkDialog *dialog, + gint response_id); +gint (*gtk_dialog_run)(GtkDialog *dialog); +void (*gtk_file_chooser_add_filter)( + GtkFileChooser *chooser, + GtkFileFilter *filter); +GtkWidget *(*gtk_file_chooser_dialog_new)( + const gchar *title, + GtkWindow *parent, + GtkFileChooserAction action, + const gchar *first_button_text, + ...); +gchar *(*gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser); +gchar *(*gtk_file_chooser_get_filename)(GtkFileChooser *chooser); +GSList *(*gtk_file_chooser_get_filenames)(GtkFileChooser *chooser); +GtkFileFilter *(*gtk_file_chooser_get_filter)(GtkFileChooser *chooser); +char *(*gtk_file_chooser_get_preview_filename)(GtkFileChooser *chooser); +GType (*gtk_file_chooser_get_type)(void); +void (*gtk_file_chooser_remove_filter)( + GtkFileChooser *chooser, + GtkFileFilter *filter); +gboolean (*gtk_file_chooser_select_filename)( + GtkFileChooser *chooser, + const char *filename); +void (*gtk_file_chooser_set_action)( + GtkFileChooser *chooser, + GtkFileChooserAction action); +void (*gtk_file_chooser_set_create_folders)( + GtkFileChooser *chooser, + gboolean create_folders); +gboolean (*gtk_file_chooser_set_current_folder)( + GtkFileChooser *chooser, + const gchar *filename); +void (*gtk_file_chooser_set_current_name)( + GtkFileChooser *chooser, + const gchar *name); +void (*gtk_file_chooser_set_do_overwrite_confirmation)( + GtkFileChooser *chooser, + gboolean do_overwrite_confirmation); +void (*gtk_file_chooser_set_filter)( + GtkFileChooser *chooser, + GtkFileFilter *filter); +void (*gtk_file_chooser_set_local_only)( + GtkFileChooser *chooser, + gboolean local_only); +void (*gtk_file_chooser_set_preview_widget)( + GtkFileChooser *chooser, + GtkWidget *preview_widget); +void (*gtk_file_chooser_set_preview_widget_active)( + GtkFileChooser *chooser, + gboolean active); +void (*gtk_file_chooser_set_select_multiple)( + GtkFileChooser *chooser, + gboolean select_multiple); +void (*gtk_file_filter_add_pattern)( + GtkFileFilter *filter, + const gchar *pattern); +GtkFileFilter *(*gtk_file_filter_new)(void); +void (*gtk_file_filter_set_name)( + GtkFileFilter *filter, + const gchar *name); +GtkWidget* (*gtk_font_chooser_dialog_new)( + const gchar *title, + GtkWindow *parent); +gchar* (*gtk_font_chooser_get_font)(GtkFontChooser *fontchooser); +GType (*gtk_font_chooser_get_type)(void); +void (*gtk_font_chooser_set_font)( + GtkFontChooser *fontchooser, + const gchar *fontname); +guint32 (*gtk_get_current_event_time)(void); +GType (*gtk_image_get_type)(void); +GtkWidget* (*gtk_image_new)(void); +void (*gtk_image_set_from_pixbuf)(GtkImage *image, GdkPixbuf *pixbuf); +void (*gtk_init)(int *argc, char ***argv); +GType (*gtk_menu_get_type)(void); +GType (*gtk_menu_item_get_type)(void); +GtkWidget* (*gtk_menu_item_new)(void); +void (*gtk_menu_item_set_label)(GtkMenuItem *menu_item, const gchar *label); +void (*gtk_menu_item_set_submenu)(GtkMenuItem *menu_item, GtkWidget *submenu); +void (*gtk_menu_item_set_use_underline)( + GtkMenuItem *menu_item, + gboolean setting); +GtkWidget* (*gtk_menu_new)(void); +void (*gtk_menu_popdown)(GtkMenu *menu); +void (*gtk_menu_popup)( + GtkMenu *menu, + GtkWidget *parent_menu_shell, + GtkWidget *parent_menu_item, + GtkMenuPositionFunc func, + gpointer data, + guint button, + guint32 activate_time); +GType (*gtk_menu_shell_get_type)(void); +void (*gtk_menu_shell_insert)( + GtkMenuShell *menu_shell, + GtkWidget *child, + gint position); +void (*gtk_menu_shell_select_item)( + GtkMenuShell *menu_shell, + GtkWidget *menu_item); +GtkWidget* (*gtk_separator_menu_item_new)(void); +GtkSettings* (*gtk_settings_get_default)(void); +void (*gtk_widget_destroy)(GtkWidget *widget); +gint (*gtk_widget_get_scale_factor)(GtkWidget *widget); +GType (*gtk_widget_get_type)(void); +GdkWindow *(*gtk_widget_get_window)(GtkWidget *widget); +void (*gtk_widget_hide)(GtkWidget *widget); +gboolean (*gtk_widget_hide_on_delete)(GtkWidget *widget); +void (*gtk_widget_realize)(GtkWidget *widget); +void (*gtk_widget_set_sensitive)(GtkWidget *widget, gboolean sensitive); +void (*gtk_widget_set_visible)(GtkWidget *widget, gboolean visible); +void (*gtk_widget_show)(GtkWidget *widget); +GType (*gtk_window_get_type)(void); +void (*gtk_window_set_title)(GtkWindow *window, const gchar *title); +void (*pango_font_description_free)(PangoFontDescription *desc); +PangoFontDescription *(*pango_font_description_from_string)(const char *str); +const char *(*pango_font_description_get_family)( + const PangoFontDescription *desc); +gint (*pango_font_description_get_size)(const PangoFontDescription *desc); +PangoStyle (*pango_font_description_get_style)( + const PangoFontDescription *desc); +PangoWeight (*pango_font_description_get_weight)( + const PangoFontDescription *desc); +PangoFontDescription *(*pango_font_description_new)(void); +void (*pango_font_description_set_family)( + PangoFontDescription *desc, + const char *family); +void (*pango_font_description_set_size)( + PangoFontDescription *desc, + gint size); +void (*pango_font_description_set_style)( + PangoFontDescription *desc, + PangoStyle style); +void (*pango_font_description_set_weight)( + PangoFontDescription *desc, + PangoWeight weight); +char *(*pango_font_description_to_string)(const PangoFontDescription *desc); +GType (*pango_font_face_get_type)(void); +GType (*pango_font_family_get_type)(void); + +struct HandleDeleter { + void operator()(void *handle) { + dlclose(handle); + } +}; + +using Handle = std::unique_ptr; + +bool LoadLibrary(Handle &handle, const char *name) { + handle = Handle(dlopen(name, RTLD_LAZY | RTLD_NODELETE)); + if (handle) { + return true; + } + g_warning("Could not load library '%s': %s", name, dlerror()); + return false; +} + +template +inline bool LoadSymbol(const Handle &handle, const char *name, Function &func) { + func = handle + ? reinterpret_cast(dlsym(handle.get(), name)) + : nullptr; + if (const auto error = dlerror()) { + g_warning("Failed to load function '%s': %s", name, error); + } + return (func != nullptr); +} + +bool Resolve() { + static const auto loaded = [&] { + auto lib = Handle(); + return LoadLibrary(lib, "libgtk-3.so.0") + && LOAD_SYMBOL(lib, gdk_pixbuf_new_from_file_at_size) + && LOAD_SYMBOL(lib, gdk_window_focus) + && LOAD_SYMBOL(lib, gdk_window_get_display) + && LOAD_SYMBOL(lib, gdk_window_set_modal_hint) + && LOAD_SYMBOL(lib, gdk_x11_display_get_xdisplay) + && LOAD_SYMBOL(lib, gdk_x11_window_get_type) + && LOAD_SYMBOL(lib, gdk_x11_window_get_xid) + && LOAD_SYMBOL(lib, gtk_accel_label_get_type) + && LOAD_SYMBOL(lib, gtk_accel_label_set_accel) + && LOAD_SYMBOL(lib, gtk_bin_get_child) + && LOAD_SYMBOL(lib, gtk_bin_get_type) + && LOAD_SYMBOL(lib, gtk_button_get_type) + && LOAD_SYMBOL(lib, gtk_button_set_label) + && LOAD_SYMBOL(lib, gtk_check_menu_item_get_active) + && LOAD_SYMBOL(lib, gtk_check_menu_item_get_type) + && LOAD_SYMBOL(lib, gtk_check_menu_item_new) + && LOAD_SYMBOL(lib, gtk_check_menu_item_set_active) + && LOAD_SYMBOL(lib, gtk_check_version) + && LOAD_SYMBOL(lib, gtk_clipboard_get) + && LOAD_SYMBOL(lib, gtk_clipboard_store) + && LOAD_SYMBOL(lib, gtk_color_chooser_dialog_new) + && LOAD_SYMBOL(lib, gtk_color_chooser_get_rgba) + && LOAD_SYMBOL(lib, gtk_color_chooser_get_type) + && LOAD_SYMBOL(lib, gtk_color_chooser_set_rgba) + && LOAD_SYMBOL(lib, gtk_color_chooser_set_use_alpha) + && LOAD_SYMBOL(lib, gtk_container_get_type) + && LOAD_SYMBOL(lib, gtk_container_remove) + && LOAD_SYMBOL(lib, gtk_dialog_get_type) + && LOAD_SYMBOL(lib, gtk_dialog_get_widget_for_response) + && LOAD_SYMBOL(lib, gtk_dialog_run) + && LOAD_SYMBOL(lib, gtk_file_chooser_add_filter) + && LOAD_SYMBOL(lib, gtk_file_chooser_dialog_new) + && LOAD_SYMBOL(lib, gtk_file_chooser_get_current_folder) + && LOAD_SYMBOL(lib, gtk_file_chooser_get_filename) + && LOAD_SYMBOL(lib, gtk_file_chooser_get_filenames) + && LOAD_SYMBOL(lib, gtk_file_chooser_get_filter) + && LOAD_SYMBOL(lib, gtk_file_chooser_get_preview_filename) + && LOAD_SYMBOL(lib, gtk_file_chooser_get_type) + && LOAD_SYMBOL(lib, gtk_file_chooser_remove_filter) + && LOAD_SYMBOL(lib, gtk_file_chooser_select_filename) + && LOAD_SYMBOL(lib, gtk_file_chooser_set_action) + && LOAD_SYMBOL(lib, gtk_file_chooser_set_create_folders) + && LOAD_SYMBOL(lib, gtk_file_chooser_set_current_folder) + && LOAD_SYMBOL(lib, gtk_file_chooser_set_current_name) + && LOAD_SYMBOL(lib, gtk_file_chooser_set_do_overwrite_confirmation) + && LOAD_SYMBOL(lib, gtk_file_chooser_set_filter) + && LOAD_SYMBOL(lib, gtk_file_chooser_set_local_only) + && LOAD_SYMBOL(lib, gtk_file_chooser_set_preview_widget) + && LOAD_SYMBOL(lib, gtk_file_chooser_set_preview_widget_active) + && LOAD_SYMBOL(lib, gtk_file_chooser_set_select_multiple) + && LOAD_SYMBOL(lib, gtk_file_filter_add_pattern) + && LOAD_SYMBOL(lib, gtk_file_filter_new) + && LOAD_SYMBOL(lib, gtk_file_filter_set_name) + && LOAD_SYMBOL(lib, gtk_font_chooser_dialog_new) + && LOAD_SYMBOL(lib, gtk_font_chooser_get_font) + && LOAD_SYMBOL(lib, gtk_font_chooser_get_type) + && LOAD_SYMBOL(lib, gtk_font_chooser_set_font) + && LOAD_SYMBOL(lib, gtk_get_current_event_time) + && LOAD_SYMBOL(lib, gtk_image_get_type) + && LOAD_SYMBOL(lib, gtk_image_new) + && LOAD_SYMBOL(lib, gtk_image_set_from_pixbuf) + && LOAD_SYMBOL(lib, gtk_init) + && LOAD_SYMBOL(lib, gtk_menu_get_type) + && LOAD_SYMBOL(lib, gtk_menu_item_get_type) + && LOAD_SYMBOL(lib, gtk_menu_item_new) + && LOAD_SYMBOL(lib, gtk_menu_item_set_label) + && LOAD_SYMBOL(lib, gtk_menu_item_set_submenu) + && LOAD_SYMBOL(lib, gtk_menu_item_set_use_underline) + && LOAD_SYMBOL(lib, gtk_menu_new) + && LOAD_SYMBOL(lib, gtk_menu_popdown) + && LOAD_SYMBOL(lib, gtk_menu_popup) + && LOAD_SYMBOL(lib, gtk_menu_shell_get_type) + && LOAD_SYMBOL(lib, gtk_menu_shell_insert) + && LOAD_SYMBOL(lib, gtk_menu_shell_select_item) + && LOAD_SYMBOL(lib, gtk_separator_menu_item_new) + && LOAD_SYMBOL(lib, gtk_settings_get_default) + && LOAD_SYMBOL(lib, gtk_widget_destroy) + && LOAD_SYMBOL(lib, gtk_widget_get_scale_factor) + && LOAD_SYMBOL(lib, gtk_widget_get_type) + && LOAD_SYMBOL(lib, gtk_widget_get_window) + && LOAD_SYMBOL(lib, gtk_widget_hide) + && LOAD_SYMBOL(lib, gtk_widget_hide_on_delete) + && LOAD_SYMBOL(lib, gtk_widget_realize) + && LOAD_SYMBOL(lib, gtk_widget_set_sensitive) + && LOAD_SYMBOL(lib, gtk_widget_set_visible) + && LOAD_SYMBOL(lib, gtk_widget_show) + && LOAD_SYMBOL(lib, gtk_window_get_type) + && LOAD_SYMBOL(lib, gtk_window_set_title) + && LOAD_SYMBOL(lib, pango_font_description_free) + && LOAD_SYMBOL(lib, pango_font_description_from_string) + && LOAD_SYMBOL(lib, pango_font_description_get_family) + && LOAD_SYMBOL(lib, pango_font_description_get_size) + && LOAD_SYMBOL(lib, pango_font_description_get_style) + && LOAD_SYMBOL(lib, pango_font_description_get_weight) + && LOAD_SYMBOL(lib, pango_font_description_new) + && LOAD_SYMBOL(lib, pango_font_description_set_family) + && LOAD_SYMBOL(lib, pango_font_description_set_size) + && LOAD_SYMBOL(lib, pango_font_description_set_style) + && LOAD_SYMBOL(lib, pango_font_description_set_weight) + && LOAD_SYMBOL(lib, pango_font_description_to_string) + && LOAD_SYMBOL(lib, pango_font_face_get_type) + && LOAD_SYMBOL(lib, pango_font_family_get_type); + }(); + return loaded; +} + +} // namespace +} // namespace GtkHelper + +GdkPixbuf *gdk_pixbuf_new_from_file_at_size( + const char *filename, + int width, + int height, + GError **error) { + GtkHelper::Resolve(); + return GtkHelper::gdk_pixbuf_new_from_file_at_size( + filename, + width, + height, + error); +} + +void gdk_window_focus(GdkWindow *window, guint32 timestamp) { + GtkHelper::Resolve(); + return GtkHelper::gdk_window_focus(window, timestamp); +} + +GdkDisplay *gdk_window_get_display(GdkWindow *window) { + GtkHelper::Resolve(); + return GtkHelper::gdk_window_get_display(window); +} + +void gdk_window_set_modal_hint(GdkWindow *window, gboolean modal) { + GtkHelper::Resolve(); + GtkHelper::gdk_window_set_modal_hint(window, modal); +} + +Display *gdk_x11_display_get_xdisplay(GdkDisplay *display) { + GtkHelper::Resolve(); + return GtkHelper::gdk_x11_display_get_xdisplay(display); +} + +GType gdk_x11_window_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gdk_x11_window_get_type(); +} + +Window gdk_x11_window_get_xid(GdkWindow *window) { + GtkHelper::Resolve(); + return GtkHelper::gdk_x11_window_get_xid(window); +} + +GType gtk_accel_label_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_accel_label_get_type(); +} + +void gtk_accel_label_set_accel( + GtkAccelLabel *accel_label, + guint accelerator_key, + GdkModifierType accelerator_mods) { + GtkHelper::Resolve(); + GtkHelper::gtk_accel_label_set_accel( + accel_label, + accelerator_key, + accelerator_mods); +} + +GtkWidget *gtk_bin_get_child(GtkBin *bin) { + GtkHelper::Resolve(); + return GtkHelper::gtk_bin_get_child(bin); +} + +GType gtk_bin_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_bin_get_type(); +} + +GType gtk_button_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_button_get_type(); +} + +void gtk_button_set_label(GtkButton *button, const gchar *label) { + GtkHelper::Resolve(); + GtkHelper::gtk_button_set_label(button, label); +} + +gboolean gtk_check_menu_item_get_active(GtkCheckMenuItem *check_menu_item) { + GtkHelper::Resolve(); + return GtkHelper::gtk_check_menu_item_get_active(check_menu_item); +} + +GType gtk_check_menu_item_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_check_menu_item_get_type(); +} + +GtkWidget* gtk_check_menu_item_new(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_check_menu_item_new(); +} + +void gtk_check_menu_item_set_active( + GtkCheckMenuItem *check_menu_item, + gboolean is_active) { + GtkHelper::Resolve(); + return GtkHelper::gtk_check_menu_item_set_active( + check_menu_item, + is_active); +} + +const gchar *gtk_check_version( + guint required_major, + guint required_minor, + guint required_micro) { + GtkHelper::Resolve(); + return GtkHelper::gtk_check_version( + required_major, + required_minor, + required_micro); +} + +GtkClipboard *gtk_clipboard_get(GdkAtom selection) { + GtkHelper::Resolve(); + return GtkHelper::gtk_clipboard_get(selection); +} + +void gtk_clipboard_store(GtkClipboard *clipboard) { + GtkHelper::Resolve(); + GtkHelper::gtk_clipboard_store(clipboard); +} + +GtkWidget *gtk_color_chooser_dialog_new( + const gchar *title, + GtkWindow *parent) { + GtkHelper::Resolve(); + return GtkHelper::gtk_color_chooser_dialog_new(title, parent); +} + +GType gtk_color_chooser_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_color_chooser_get_type(); +} + +void gtk_color_chooser_get_rgba( + GtkColorChooser *chooser, + GdkRGBA *color) { + GtkHelper::Resolve(); + GtkHelper::gtk_color_chooser_get_rgba(chooser, color); +} + +void gtk_color_chooser_set_rgba( + GtkColorChooser *chooser, + const GdkRGBA *color) { + GtkHelper::Resolve(); + GtkHelper::gtk_color_chooser_set_rgba(chooser, color); +} + +void gtk_color_chooser_set_use_alpha( + GtkColorChooser *chooser, + gboolean use_alpha) { + GtkHelper::Resolve(); + GtkHelper::gtk_color_chooser_set_use_alpha(chooser, use_alpha); +} + +GType gtk_container_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_container_get_type(); +} + +void gtk_container_remove(GtkContainer *container, GtkWidget *widget) { + GtkHelper::Resolve(); + GtkHelper::gtk_container_remove(container, widget); +} + +GType gtk_dialog_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_dialog_get_type(); +} + +GtkWidget* gtk_dialog_get_widget_for_response( + GtkDialog *dialog, + gint response_id) { + GtkHelper::Resolve(); + return GtkHelper::gtk_dialog_get_widget_for_response( + dialog, + response_id); +} + +gint gtk_dialog_run(GtkDialog *dialog) { + GtkHelper::Resolve(); + return GtkHelper::gtk_dialog_run(dialog); +} + +void gtk_file_chooser_add_filter( + GtkFileChooser *chooser, + GtkFileFilter *filter) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_add_filter(chooser, filter); +} + +GtkWidget *gtk_file_chooser_dialog_new( + const gchar *title, + GtkWindow *parent, + GtkFileChooserAction action, + const gchar *first_button_text, + ...) { + GtkHelper::Resolve(); + __builtin_return( + __builtin_apply( + reinterpret_cast( + GtkHelper::gtk_file_chooser_dialog_new), + __builtin_apply_args(), + 1000)); +} + +gchar *gtk_file_chooser_get_current_folder(GtkFileChooser *chooser) { + GtkHelper::Resolve(); + return GtkHelper::gtk_file_chooser_get_current_folder(chooser); +} + +gchar *gtk_file_chooser_get_filename(GtkFileChooser *chooser) { + GtkHelper::Resolve(); + return GtkHelper::gtk_file_chooser_get_filename(chooser); +} + +GSList *gtk_file_chooser_get_filenames(GtkFileChooser *chooser) { + GtkHelper::Resolve(); + return GtkHelper::gtk_file_chooser_get_filenames(chooser); +} + +GtkFileFilter *gtk_file_chooser_get_filter(GtkFileChooser *chooser) { + GtkHelper::Resolve(); + return GtkHelper::gtk_file_chooser_get_filter(chooser); +} + +char *gtk_file_chooser_get_preview_filename(GtkFileChooser *chooser) { + GtkHelper::Resolve(); + return GtkHelper::gtk_file_chooser_get_preview_filename(chooser); +} + +GType gtk_file_chooser_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_file_chooser_get_type(); +} + +void gtk_file_chooser_remove_filter( + GtkFileChooser *chooser, + GtkFileFilter *filter) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_remove_filter(chooser, filter); +} + +gboolean gtk_file_chooser_select_filename( + GtkFileChooser *chooser, + const char *filename) { + GtkHelper::Resolve(); + return GtkHelper::gtk_file_chooser_select_filename(chooser, filename); +} + +void gtk_file_chooser_set_action( + GtkFileChooser *chooser, + GtkFileChooserAction action) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_set_action(chooser, action); +} + +void gtk_file_chooser_set_create_folders( + GtkFileChooser *chooser, + gboolean create_folders) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_set_create_folders( + chooser, + create_folders); +} + +gboolean gtk_file_chooser_set_current_folder( + GtkFileChooser *chooser, + const gchar *filename) { + GtkHelper::Resolve(); + return GtkHelper::gtk_file_chooser_set_current_folder(chooser, filename); +} + +void gtk_file_chooser_set_current_name( + GtkFileChooser *chooser, + const gchar *name) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_set_current_name(chooser, name); +} + +void gtk_file_chooser_set_do_overwrite_confirmation( + GtkFileChooser *chooser, + gboolean do_overwrite_confirmation) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_set_do_overwrite_confirmation( + chooser, + do_overwrite_confirmation); +} + +void gtk_file_chooser_set_filter( + GtkFileChooser *chooser, + GtkFileFilter *filter) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_set_filter(chooser, filter); +} + +void gtk_file_chooser_set_local_only( + GtkFileChooser *chooser, + gboolean local_only) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_set_local_only(chooser, local_only); +} + +void gtk_file_chooser_set_preview_widget( + GtkFileChooser *chooser, + GtkWidget *preview_widget) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_set_preview_widget(chooser, preview_widget); +} + +void gtk_file_chooser_set_preview_widget_active( + GtkFileChooser *chooser, + gboolean active) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_set_preview_widget_active(chooser, active); +} + +void gtk_file_chooser_set_select_multiple( + GtkFileChooser *chooser, + gboolean select_multiple) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_chooser_set_select_multiple(chooser, select_multiple); +} + +void gtk_file_filter_add_pattern( + GtkFileFilter *filter, + const gchar *pattern) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_filter_add_pattern(filter, pattern); +} + +GtkFileFilter *gtk_file_filter_new(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_file_filter_new(); +} + +void gtk_file_filter_set_name( + GtkFileFilter *filter, + const gchar *name) { + GtkHelper::Resolve(); + GtkHelper::gtk_file_filter_set_name(filter, name); +} + +GtkWidget* gtk_font_chooser_dialog_new( + const gchar *title, + GtkWindow *parent) { + GtkHelper::Resolve(); + return GtkHelper::gtk_font_chooser_dialog_new(title, parent); +} + +gchar* gtk_font_chooser_get_font(GtkFontChooser *fontchooser) { + GtkHelper::Resolve(); + return GtkHelper::gtk_font_chooser_get_font(fontchooser); +} + +GType gtk_font_chooser_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_font_chooser_get_type(); +} + +void gtk_font_chooser_set_font( + GtkFontChooser *fontchooser, + const gchar *fontname) { + GtkHelper::Resolve(); + GtkHelper::gtk_font_chooser_set_font(fontchooser, fontname); +} + +guint32 gtk_get_current_event_time(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_get_current_event_time(); +} + +GType gtk_image_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_image_get_type(); +} + +GtkWidget* gtk_image_new(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_image_new(); +} + +void gtk_image_set_from_pixbuf(GtkImage *image, GdkPixbuf *pixbuf) { + GtkHelper::Resolve(); + GtkHelper::gtk_image_set_from_pixbuf(image, pixbuf); +} + +void gtk_init(int *argc, char ***argv) { + GtkHelper::Resolve(); + GtkHelper::gtk_init(argc, argv); +} + +GType gtk_menu_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_menu_get_type(); +} + +GType gtk_menu_item_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_menu_item_get_type(); +} + +GtkWidget* gtk_menu_item_new(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_menu_item_new(); +} + +void gtk_menu_item_set_label(GtkMenuItem *menu_item, const gchar *label) { + GtkHelper::Resolve(); + GtkHelper::gtk_menu_item_set_label(menu_item, label); +} + +void gtk_menu_item_set_submenu(GtkMenuItem *menu_item, GtkWidget *submenu) { + GtkHelper::Resolve(); + GtkHelper::gtk_menu_item_set_submenu(menu_item, submenu); +} + +void gtk_menu_item_set_use_underline( + GtkMenuItem *menu_item, + gboolean setting) { + GtkHelper::Resolve(); + GtkHelper::gtk_menu_item_set_use_underline(menu_item, setting); +} + +GtkWidget* gtk_menu_new(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_menu_new(); +} + +void gtk_menu_popdown(GtkMenu *menu) { + GtkHelper::Resolve(); + GtkHelper::gtk_menu_popdown(menu); +} + +void gtk_menu_popup( + GtkMenu *menu, + GtkWidget *parent_menu_shell, + GtkWidget *parent_menu_item, + GtkMenuPositionFunc func, + gpointer data, + guint button, + guint32 activate_time) { + GtkHelper::Resolve(); + GtkHelper::gtk_menu_popup( + menu, + parent_menu_shell, + parent_menu_item, + func, + data, + button, + activate_time); +} + +GType gtk_menu_shell_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_menu_shell_get_type(); +} +void gtk_menu_shell_insert( + GtkMenuShell *menu_shell, + GtkWidget *child, + gint position) { + GtkHelper::Resolve(); + GtkHelper::gtk_menu_shell_insert(menu_shell, child, position); +} + +void gtk_menu_shell_select_item( + GtkMenuShell *menu_shell, + GtkWidget *menu_item) { + GtkHelper::Resolve(); + GtkHelper::gtk_menu_shell_select_item(menu_shell, menu_item); +} + +GtkWidget* gtk_separator_menu_item_new(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_separator_menu_item_new(); +} + +GtkSettings* gtk_settings_get_default(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_settings_get_default(); +} + +void gtk_widget_destroy(GtkWidget *widget) { + GtkHelper::Resolve(); + GtkHelper::gtk_widget_destroy(widget); +} + +gint gtk_widget_get_scale_factor(GtkWidget *widget) { + GtkHelper::Resolve(); + return GtkHelper::gtk_widget_get_scale_factor(widget); +} + +GType gtk_widget_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_widget_get_type(); +} + +GdkWindow *gtk_widget_get_window(GtkWidget *widget) { + GtkHelper::Resolve(); + return GtkHelper::gtk_widget_get_window(widget); +} + +void gtk_widget_hide(GtkWidget *widget) { + GtkHelper::Resolve(); + GtkHelper::gtk_widget_hide(widget); +} + +gboolean gtk_widget_hide_on_delete(GtkWidget *widget) { + GtkHelper::Resolve(); + return GtkHelper::gtk_widget_hide_on_delete(widget); +} + +void gtk_widget_realize(GtkWidget *widget) { + GtkHelper::Resolve(); + GtkHelper::gtk_widget_realize(widget); +} + +void gtk_widget_set_sensitive(GtkWidget *widget, gboolean sensitive) { + GtkHelper::Resolve(); + GtkHelper::gtk_widget_set_sensitive(widget, sensitive); +} + +void gtk_widget_set_visible(GtkWidget *widget, gboolean visible) { + GtkHelper::Resolve(); + GtkHelper::gtk_widget_set_visible(widget, visible); +} + +void gtk_widget_show(GtkWidget *widget) { + GtkHelper::Resolve(); + GtkHelper::gtk_widget_show(widget); +} + +GType gtk_window_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::gtk_window_get_type(); +} + +void gtk_window_set_title(GtkWindow *window, const gchar *title) { + GtkHelper::Resolve(); + GtkHelper::gtk_window_set_title(window, title); +} + +void pango_font_description_free(PangoFontDescription *desc) { + GtkHelper::Resolve(); + GtkHelper::pango_font_description_free(desc); +} + +PangoFontDescription *pango_font_description_from_string(const char *str) { + GtkHelper::Resolve(); + return GtkHelper::pango_font_description_from_string(str); +} + +const char *pango_font_description_get_family( + const PangoFontDescription *desc) { + GtkHelper::Resolve(); + return GtkHelper::pango_font_description_get_family(desc); +} + +gint pango_font_description_get_size(const PangoFontDescription *desc) { + GtkHelper::Resolve(); + return GtkHelper::pango_font_description_get_size(desc); +} + +PangoStyle pango_font_description_get_style( + const PangoFontDescription *desc) { + GtkHelper::Resolve(); + return GtkHelper::pango_font_description_get_style(desc); +} + +PangoWeight pango_font_description_get_weight( + const PangoFontDescription *desc) { + GtkHelper::Resolve(); + return GtkHelper::pango_font_description_get_weight(desc); +} + +PangoFontDescription *pango_font_description_new(void) { + GtkHelper::Resolve(); + return GtkHelper::pango_font_description_new(); +} + +void pango_font_description_set_family( + PangoFontDescription *desc, + const char *family) { + GtkHelper::Resolve(); + GtkHelper::pango_font_description_set_family(desc, family); +} + +void pango_font_description_set_size( + PangoFontDescription *desc, + gint size) { + GtkHelper::Resolve(); + GtkHelper::pango_font_description_set_size(desc, size); +} + +void pango_font_description_set_style( + PangoFontDescription *desc, + PangoStyle style) { + GtkHelper::Resolve(); + GtkHelper::pango_font_description_set_style(desc, style); +} + +void pango_font_description_set_weight( + PangoFontDescription *desc, + PangoWeight weight) { + GtkHelper::Resolve(); + GtkHelper::pango_font_description_set_weight(desc, weight); +} + +char *pango_font_description_to_string(const PangoFontDescription *desc) { + GtkHelper::Resolve(); + return GtkHelper::pango_font_description_to_string(desc); +} + +GType pango_font_face_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::pango_font_face_get_type(); +} + +GType pango_font_family_get_type(void) { + GtkHelper::Resolve(); + return GtkHelper::pango_font_family_get_type(); +} From 8d7772ab33f2b04efde728decd8ae265a461b185 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Wed, 30 Jun 2021 05:13:44 +0400 Subject: [PATCH 04/14] Switch from mallocng to jemalloc --- external/CMakeLists.txt | 6 ++-- external/jemalloc/CMakeLists.txt | 51 ++++++++++++++++++++++++++++++++ external/mallocng/CMakeLists.txt | 46 ---------------------------- options_linux.cmake | 5 ++++ 4 files changed, 59 insertions(+), 49 deletions(-) create mode 100644 external/jemalloc/CMakeLists.txt delete mode 100644 external/mallocng/CMakeLists.txt diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 91a7806..24b7a9a 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -36,14 +36,14 @@ if (add_hunspell_library) add_checked_subdirectory(hunspell) endif() add_checked_subdirectory(iconv) +if (LINUX) + add_checked_subdirectory(jemalloc) +endif() add_checked_subdirectory(jpeg) if (LINUX AND NOT DESKTOP_APP_DISABLE_WAYLAND_INTEGRATION) add_checked_subdirectory(kwayland) endif() add_checked_subdirectory(lz4) -if (LINUX) - add_checked_subdirectory(mallocng) -endif() add_checked_subdirectory(minizip) if (LINUX) add_checked_subdirectory(nimf_qt5) diff --git a/external/jemalloc/CMakeLists.txt b/external/jemalloc/CMakeLists.txt new file mode 100644 index 0000000..084b79d --- /dev/null +++ b/external/jemalloc/CMakeLists.txt @@ -0,0 +1,51 @@ +# This file is part of Desktop App Toolkit, +# a set of libraries for developing nice desktop applications. +# +# For license and copyright information please follow this link: +# https://github.com/desktop-app/legal/blob/master/LEGAL + +add_library(external_jemalloc INTERFACE IMPORTED GLOBAL) +add_library(desktop-app::external_jemalloc ALIAS external_jemalloc) + +if (DESKTOP_APP_USE_PACKAGED) + find_package(PkgConfig REQUIRED) + pkg_check_modules(JEMALLOC IMPORTED_TARGET jemalloc) + + if (JEMALLOC_FOUND) + target_link_libraries(external_jemalloc INTERFACE PkgConfig::JEMALLOC) + endif() +endif() + +if (NOT JEMALLOC_FOUND) + add_library(external_jemalloc_bundled STATIC IMPORTED GLOBAL) + + include(ExternalProject) + ExternalProject_Add(jemalloc + URL https://github.com/jemalloc/jemalloc/releases/download/5.2.1/jemalloc-5.2.1.tar.bz2 + CONFIGURE_COMMAND cd "${CMAKE_CURRENT_BINARY_DIR}/jemalloc-prefix/src/jemalloc" && ./configure + BUILD_IN_SOURCE 1 + ) + + ExternalProject_Get_property(jemalloc SOURCE_DIR) + ExternalProject_Get_property(jemalloc BINARY_DIR) + + file(MAKE_DIRECTORY "${SOURCE_DIR}/include") + + set_target_properties(external_jemalloc_bundled PROPERTIES + IMPORTED_LOCATION "${BINARY_DIR}/lib/libjemalloc.a" + ) + + target_include_directories(external_jemalloc_bundled + INTERFACE + ${SOURCE_DIR}/include + ) + + add_dependencies(external_jemalloc_bundled jemalloc) + + target_link_libraries(external_jemalloc + INTERFACE + -Wl,--whole-archive + external_jemalloc_bundled + -Wl,--no-whole-archive + ) +endif() diff --git a/external/mallocng/CMakeLists.txt b/external/mallocng/CMakeLists.txt deleted file mode 100644 index c3d2422..0000000 --- a/external/mallocng/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -# This file is part of Desktop App Toolkit, -# a set of libraries for developing nice desktop applications. -# -# For license and copyright information please follow this link: -# https://github.com/desktop-app/legal/blob/master/LEGAL - -add_library(external_mallocng INTERFACE IMPORTED GLOBAL) -add_library(desktop-app::external_mallocng ALIAS external_mallocng) - -add_library(external_mallocng_bundled STATIC) -init_target(external_mallocng_bundled "(external)") - -set(mallocng_loc ${third_party_loc}/mallocng) - -nice_target_sources(external_mallocng_bundled ${mallocng_loc} -PRIVATE - malloc.c - calloc.c - free.c - realloc.c - aligned_alloc.c - posix_memalign.c - memalign.c - malloc_usable_size.c - meta.h - glue.h - valloc.c - pvalloc.c -) - -target_compile_options(external_mallocng_bundled -PRIVATE - -Wno-unused-value -) - -target_include_directories(external_mallocng_bundled -PRIVATE - ${mallocng_loc} -) - -target_link_libraries(external_mallocng -INTERFACE - -Wl,--whole-archive - external_mallocng_bundled - -Wl,--no-whole-archive -) diff --git a/options_linux.cmake b/options_linux.cmake index d586e79..ae687ff 100644 --- a/options_linux.cmake +++ b/options_linux.cmake @@ -48,6 +48,11 @@ if (DESKTOP_APP_SPECIAL_TARGET) endif() endif() +target_link_libraries(common_options +INTERFACE + desktop-app::external_jemalloc +) + if (DESKTOP_APP_USE_PACKAGED) find_library(ATOMIC_LIBRARY atomic) else() From 32ec2b8db2e16f220e52bfe7454d50f834ef5d23 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Fri, 2 Jul 2021 00:33:03 +0400 Subject: [PATCH 05/14] Add missed jemalloc dependencies --- external/jemalloc/CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/external/jemalloc/CMakeLists.txt b/external/jemalloc/CMakeLists.txt index 084b79d..9d7ce2f 100644 --- a/external/jemalloc/CMakeLists.txt +++ b/external/jemalloc/CMakeLists.txt @@ -40,12 +40,19 @@ if (NOT JEMALLOC_FOUND) ${SOURCE_DIR}/include ) + target_link_libraries(external_jemalloc_bundled + INTERFACE + dl + pthread + ) + add_dependencies(external_jemalloc_bundled jemalloc) target_link_libraries(external_jemalloc INTERFACE -Wl,--whole-archive - external_jemalloc_bundled + $ -Wl,--no-whole-archive + external_jemalloc_bundled ) endif() From fc4d02573c232befca4b061cba00251ac5a8e18d Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 29 Jun 2021 16:51:57 +0300 Subject: [PATCH 06/14] Link Qt with statically built ANGLE. --- external/qt/CMakeLists.txt | 16 ++++++++++++++++ external/qt/package.cmake | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/external/qt/CMakeLists.txt b/external/qt/CMakeLists.txt index e601502..415f4d5 100644 --- a/external/qt/CMakeLists.txt +++ b/external/qt/CMakeLists.txt @@ -157,6 +157,22 @@ else() foreach (lib ${qt_libs}) list(APPEND qt_libs_list "${qt_loc}/${lib}${qt_lib_suffix}") endforeach() + + target_include_directories(external_qt + INTERFACE + ${libs_loc}/angle/include + ) + set(angle_libs_loc ${libs_loc}/angle/out/$,Debug,Release>/obj) + target_link_libraries(external_qt + INTERFACE + ${angle_libs_loc}/libANGLE_static.lib + ${angle_libs_loc}/libGLESv2_static.lib + ${angle_libs_loc}/libEGL_static.lib + d3d9.lib + d3d11.lib + dxgi.lib + dxguid.lib + ) elseif (APPLE) if (NOT build_osx) set(qt_libs diff --git a/external/qt/package.cmake b/external/qt/package.cmake index fedb6eb..994114b 100644 --- a/external/qt/package.cmake +++ b/external/qt/package.cmake @@ -12,7 +12,7 @@ if (NOT DESKTOP_APP_USE_PACKAGED) endif() if (WIN32) - set(qt_loc ${libs_loc}/Qt-${qt_version}) + set(qt_loc ${libs_loc}/Al-${qt_version}) else() set(qt_loc /usr/local/desktop-app/Qt-${qt_version}) endif() From e2455f3194b3591d5046d0d38b8e5921c1149302 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 30 Jun 2021 13:43:36 +0300 Subject: [PATCH 07/14] Add dynamic DirectX loading helper. --- CMakeLists.txt | 3 + external/CMakeLists.txt | 1 + external/angle/CMakeLists.txt | 27 +++ external/qt/CMakeLists.txt | 13 +- linux_wayland_helper/linux_wayland_helper.cpp | 3 +- win_directx_helper/CMakeLists.txt | 14 ++ win_directx_helper/win_directx_helper.cpp | 200 ++++++++++++++++++ 7 files changed, 248 insertions(+), 13 deletions(-) create mode 100644 external/angle/CMakeLists.txt create mode 100644 win_directx_helper/CMakeLists.txt create mode 100644 win_directx_helper/win_directx_helper.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 799ba0b..3a3892e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,3 +18,6 @@ endif() if (DESKTOP_APP_USE_ALLOCATION_TRACER) add_subdirectory(linux_allocation_tracer) endif() +if (WIN32) + add_subdirectory(win_directx_helper) +endif() diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 24b7a9a..118178c 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -11,6 +11,7 @@ macro(add_checked_subdirectory name) endif() endmacro() +add_checked_subdirectory(angle) add_checked_subdirectory(auto_updates) add_checked_subdirectory(crash_reports) if (LINUX AND NOT DESKTOP_APP_DISABLE_DBUS_INTEGRATION) diff --git a/external/angle/CMakeLists.txt b/external/angle/CMakeLists.txt new file mode 100644 index 0000000..5526582 --- /dev/null +++ b/external/angle/CMakeLists.txt @@ -0,0 +1,27 @@ +# This file is part of Desktop App Toolkit, +# a set of libraries for developing nice desktop applications. +# +# For license and copyright information please follow this link: +# https://github.com/desktop-app/legal/blob/master/LEGAL + +add_library(external_angle INTERFACE IMPORTED GLOBAL) +add_library(desktop-app::external_angle ALIAS external_angle) + +if (WIN32) + target_include_directories(external_angle + INTERFACE + ${libs_loc}/angle/include + ) + set(angle_libs_loc ${libs_loc}/angle/out/$,Debug,Release>/obj) + target_link_libraries(external_angle + INTERFACE + ${angle_libs_loc}/libANGLE_static.lib + ${angle_libs_loc}/libGLESv2_static.lib + ${angle_libs_loc}/libEGL_static.lib + dxguid.lib + ) + target_link_libraries(external_angle + INTERFACE + desktop-app::win_directx_helper + ) +endif() diff --git a/external/qt/CMakeLists.txt b/external/qt/CMakeLists.txt index 415f4d5..e7c78a8 100644 --- a/external/qt/CMakeLists.txt +++ b/external/qt/CMakeLists.txt @@ -158,20 +158,9 @@ else() list(APPEND qt_libs_list "${qt_loc}/${lib}${qt_lib_suffix}") endforeach() - target_include_directories(external_qt - INTERFACE - ${libs_loc}/angle/include - ) - set(angle_libs_loc ${libs_loc}/angle/out/$,Debug,Release>/obj) target_link_libraries(external_qt INTERFACE - ${angle_libs_loc}/libANGLE_static.lib - ${angle_libs_loc}/libGLESv2_static.lib - ${angle_libs_loc}/libEGL_static.lib - d3d9.lib - d3d11.lib - dxgi.lib - dxguid.lib + desktop-app::external_angle ) elseif (APPLE) if (NOT build_osx) diff --git a/linux_wayland_helper/linux_wayland_helper.cpp b/linux_wayland_helper/linux_wayland_helper.cpp index cbcbeaf..5d75469 100644 --- a/linux_wayland_helper/linux_wayland_helper.cpp +++ b/linux_wayland_helper/linux_wayland_helper.cpp @@ -200,7 +200,7 @@ inline bool LoadSymbol(const Handle &handle, const char *name, Function &func) { } bool Resolve() { - static const auto loaded = [&] { + static const auto loaded = [] { auto egl = Handle(); auto cursor = Handle(); auto client = Handle(); @@ -618,4 +618,5 @@ struct wl_proxy *wl_proxy_marshal_constructor_versioned( args, interface, version); } + } // extern "C" diff --git a/win_directx_helper/CMakeLists.txt b/win_directx_helper/CMakeLists.txt new file mode 100644 index 0000000..c98935c --- /dev/null +++ b/win_directx_helper/CMakeLists.txt @@ -0,0 +1,14 @@ +# This file is part of Desktop App Toolkit, +# a set of libraries for developing nice desktop applications. +# +# For license and copyright information please follow this link: +# https://github.com/desktop-app/legal/blob/master/LEGAL + +add_library(win_directx_helper STATIC) +init_target(win_directx_helper "(external)") +add_library(desktop-app::win_directx_helper ALIAS win_directx_helper) + +nice_target_sources(win_directx_helper ${CMAKE_CURRENT_SOURCE_DIR} +PRIVATE + win_directx_helper.cpp +) diff --git a/win_directx_helper/win_directx_helper.cpp b/win_directx_helper/win_directx_helper.cpp new file mode 100644 index 0000000..11590db --- /dev/null +++ b/win_directx_helper/win_directx_helper.cpp @@ -0,0 +1,200 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// + +#include +#include +#include + +#define LOAD_SYMBOL(handle, func) LoadSymbol(handle, #func, func) + +namespace DirectX { +namespace { + +using Handle = HINSTANCE; + +// d3d9.dll + +IDirect3D9 * (__stdcall *Direct3DCreate9)(UINT SDKVersion); +int (__stdcall *D3DPERF_BeginEvent)(D3DCOLOR col, LPCWSTR wszName); +int (__stdcall *D3DPERF_EndEvent)(void); +void (__stdcall *D3DPERF_SetMarker)(D3DCOLOR col, LPCWSTR wszName); +DWORD (__stdcall *D3DPERF_GetStatus)(void); + +// d3d11.dll + +HRESULT (__stdcall *D3D11CreateDevice)( + _In_opt_ IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + _In_reads_opt_(FeatureLevels) CONST D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + _COM_Outptr_opt_ ID3D11Device** ppDevice, + _Out_opt_ D3D_FEATURE_LEVEL* pFeatureLevel, + _COM_Outptr_opt_ ID3D11DeviceContext** ppImmediateContext); + +// dxgi.dll + +HRESULT (__stdcall *CreateDXGIFactory)( + REFIID riid, + _COM_Outptr_ void **ppFactory); + +HRESULT (__stdcall *CreateDXGIFactory1)( + REFIID riid, + _COM_Outptr_ void **ppFactory); + +Handle SafeLoadLibrary(const wchar_t *name) { + static const auto SystemPath = [] { + WCHAR buffer[MAX_PATH + 1] = { 0 }; + return GetSystemDirectory(buffer, MAX_PATH) + ? std::wstring(buffer) + : std::wstring(); + }(); + static const auto WindowsPath = [] { + WCHAR buffer[MAX_PATH + 1] = { 0 }; + return GetWindowsDirectory(buffer, MAX_PATH) + ? std::wstring(buffer) + : std::wstring(); + }(); + const auto tryPath = [&](const std::wstring &path) { + if (!path.empty()) { + const auto full = path + L'\\' + name; + if (const auto result = Handle(LoadLibrary(full.c_str()))) { + return result; + } + } + return Handle(); + }; + if (const auto result1 = tryPath(SystemPath)) { + return result1; + } else if (const auto result2 = tryPath(WindowsPath)) { + return result2; + } + return nullptr; +} + +template +inline bool LoadSymbol(Handle handle, const char *name, Function &func) { + func = handle + ? reinterpret_cast(GetProcAddress(handle, name)) + : nullptr; + return (func != nullptr); +} + +bool ResolveD3D9() { + static const auto loaded = [] { + const auto d3d9 = SafeLoadLibrary(L"d3d9.dll"); + LOAD_SYMBOL(d3d9, D3DPERF_BeginEvent); + LOAD_SYMBOL(d3d9, D3DPERF_EndEvent); + LOAD_SYMBOL(d3d9, D3DPERF_SetMarker); + LOAD_SYMBOL(d3d9, D3DPERF_GetStatus); + return true + && LOAD_SYMBOL(d3d9, Direct3DCreate9); + }(); + return loaded; +} + +bool ResolveD3D11() { + static const auto loaded = [] { + const auto d3d11 = SafeLoadLibrary(L"d3d11.dll"); + return true + && LOAD_SYMBOL(d3d11, D3D11CreateDevice); + }(); + return loaded; +} + +bool ResolveDXGI() { + static const auto loaded = [&] { + const auto dxgi = SafeLoadLibrary(L"dxgi.dll"); + LOAD_SYMBOL(dxgi, CreateDXGIFactory1); + return true + && LOAD_SYMBOL(dxgi, CreateDXGIFactory); + }(); + return loaded; +} + +} // namespace +} // namespace DirectX + +namespace D = DirectX; + +extern "C" { + +IDirect3D9 * WINAPI Direct3DCreate9(UINT SDKVersion) { + return D::ResolveD3D9() + ? D::Direct3DCreate9(SDKVersion) + : nullptr; +} + +int WINAPI D3DPERF_BeginEvent(D3DCOLOR col, LPCWSTR wszName) { + return (D::ResolveD3D9() && D::D3DPERF_BeginEvent) + ? D::D3DPERF_BeginEvent(col, wszName) + : -1; +} + +int WINAPI D3DPERF_EndEvent(void) { + return (D::ResolveD3D9() && D::D3DPERF_EndEvent) + ? D::D3DPERF_EndEvent() + : -1; +} + +void WINAPI D3DPERF_SetMarker(D3DCOLOR col, LPCWSTR wszName) { + if (D::ResolveD3D9() && D::D3DPERF_SetMarker) { + D::D3DPERF_SetMarker(col, wszName); + } +} + +DWORD WINAPI D3DPERF_GetStatus(void) { + return (D::ResolveD3D9() && D::D3DPERF_GetStatus) + ? D::D3DPERF_GetStatus() + : 0; +} + +HRESULT WINAPI D3D11CreateDevice( + _In_opt_ IDXGIAdapter* pAdapter, + D3D_DRIVER_TYPE DriverType, + HMODULE Software, + UINT Flags, + _In_reads_opt_(FeatureLevels) CONST D3D_FEATURE_LEVEL* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + _COM_Outptr_opt_ ID3D11Device** ppDevice, + _Out_opt_ D3D_FEATURE_LEVEL* pFeatureLevel, + _COM_Outptr_opt_ ID3D11DeviceContext** ppImmediateContext) { + return D::ResolveD3D11() + ? D::D3D11CreateDevice( + pAdapter, + DriverType, + Software, + Flags, + pFeatureLevels, + FeatureLevels, + SDKVersion, + ppDevice, + pFeatureLevel, + ppImmediateContext) + : CO_E_DLLNOTFOUND; +} + +HRESULT WINAPI CreateDXGIFactory( + REFIID riid, + _COM_Outptr_ void **ppFactory) { + return D::ResolveDXGI() + ? D::CreateDXGIFactory(riid, ppFactory) + : CO_E_DLLNOTFOUND; +} + +HRESULT WINAPI CreateDXGIFactory1( + REFIID riid, + _COM_Outptr_ void **ppFactory) { + return (D::ResolveDXGI() && D::CreateDXGIFactory1) + ? D::CreateDXGIFactory1(riid, ppFactory) + : CO_E_DLLNOTFOUND; +} + +} // extern "C" From 387a2b37ad949e1e9471f922c288ddb00bdbd57e Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 30 Jun 2021 18:20:25 +0300 Subject: [PATCH 08/14] Use "SetDefaultDllDirectories". --- win_directx_helper/win_directx_helper.cpp | 29 ++--------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/win_directx_helper/win_directx_helper.cpp b/win_directx_helper/win_directx_helper.cpp index 11590db..42a4024 100644 --- a/win_directx_helper/win_directx_helper.cpp +++ b/win_directx_helper/win_directx_helper.cpp @@ -49,33 +49,8 @@ HRESULT (__stdcall *CreateDXGIFactory1)( _COM_Outptr_ void **ppFactory); Handle SafeLoadLibrary(const wchar_t *name) { - static const auto SystemPath = [] { - WCHAR buffer[MAX_PATH + 1] = { 0 }; - return GetSystemDirectory(buffer, MAX_PATH) - ? std::wstring(buffer) - : std::wstring(); - }(); - static const auto WindowsPath = [] { - WCHAR buffer[MAX_PATH + 1] = { 0 }; - return GetWindowsDirectory(buffer, MAX_PATH) - ? std::wstring(buffer) - : std::wstring(); - }(); - const auto tryPath = [&](const std::wstring &path) { - if (!path.empty()) { - const auto full = path + L'\\' + name; - if (const auto result = Handle(LoadLibrary(full.c_str()))) { - return result; - } - } - return Handle(); - }; - if (const auto result1 = tryPath(SystemPath)) { - return result1; - } else if (const auto result2 = tryPath(WindowsPath)) { - return result2; - } - return nullptr; + SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32); + return LoadLibrary(name); } template From d13a57db67d288682351f4939fd92313b81f866b Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 1 Jul 2021 00:13:59 +0300 Subject: [PATCH 09/14] Use plain "LoadLibrary". --- win_directx_helper/win_directx_helper.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/win_directx_helper/win_directx_helper.cpp b/win_directx_helper/win_directx_helper.cpp index 42a4024..d987a32 100644 --- a/win_directx_helper/win_directx_helper.cpp +++ b/win_directx_helper/win_directx_helper.cpp @@ -48,11 +48,6 @@ HRESULT (__stdcall *CreateDXGIFactory1)( REFIID riid, _COM_Outptr_ void **ppFactory); -Handle SafeLoadLibrary(const wchar_t *name) { - SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32); - return LoadLibrary(name); -} - template inline bool LoadSymbol(Handle handle, const char *name, Function &func) { func = handle @@ -63,7 +58,7 @@ inline bool LoadSymbol(Handle handle, const char *name, Function &func) { bool ResolveD3D9() { static const auto loaded = [] { - const auto d3d9 = SafeLoadLibrary(L"d3d9.dll"); + const auto d3d9 = LoadLibrary(L"d3d9.dll"); LOAD_SYMBOL(d3d9, D3DPERF_BeginEvent); LOAD_SYMBOL(d3d9, D3DPERF_EndEvent); LOAD_SYMBOL(d3d9, D3DPERF_SetMarker); @@ -76,7 +71,7 @@ bool ResolveD3D9() { bool ResolveD3D11() { static const auto loaded = [] { - const auto d3d11 = SafeLoadLibrary(L"d3d11.dll"); + const auto d3d11 = LoadLibrary(L"d3d11.dll"); return true && LOAD_SYMBOL(d3d11, D3D11CreateDevice); }(); @@ -85,7 +80,7 @@ bool ResolveD3D11() { bool ResolveDXGI() { static const auto loaded = [&] { - const auto dxgi = SafeLoadLibrary(L"dxgi.dll"); + const auto dxgi = LoadLibrary(L"dxgi.dll"); LOAD_SYMBOL(dxgi, CreateDXGIFactory1); return true && LOAD_SYMBOL(dxgi, CreateDXGIFactory); From 843225765113b8277f624283de63beedfa64155f Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 1 Jul 2021 09:49:50 +0300 Subject: [PATCH 10/14] Use default Qt-{version} folder on Windows. --- external/qt/package.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/qt/package.cmake b/external/qt/package.cmake index 994114b..fedb6eb 100644 --- a/external/qt/package.cmake +++ b/external/qt/package.cmake @@ -12,7 +12,7 @@ if (NOT DESKTOP_APP_USE_PACKAGED) endif() if (WIN32) - set(qt_loc ${libs_loc}/Al-${qt_version}) + set(qt_loc ${libs_loc}/Qt-${qt_version}) else() set(qt_loc /usr/local/desktop-app/Qt-${qt_version}) endif() From 95a3953c218847d1d32bad72511d412ee700e711 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 4 Jul 2021 01:31:43 +0300 Subject: [PATCH 11/14] Fixed typo in name of GTK integration option. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a3892e..6bf1930 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ if (LINUX endif() if (LINUX AND NOT DESKTOP_APP_USE_PACKAGED - AND NOT DESKTOP_APP_DIABLE_GTK_INTEGRATION) + AND NOT DESKTOP_APP_DISABLE_GTK_INTEGRATION) add_subdirectory(linux_gtk_helper) endif() if (DESKTOP_APP_USE_ALLOCATION_TRACER) From 5217f7154254c819c21c7bc7761c2c3429c441b8 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 6 Jul 2021 15:54:43 +0300 Subject: [PATCH 12/14] Use tg_angle fork. --- external/angle/CMakeLists.txt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/external/angle/CMakeLists.txt b/external/angle/CMakeLists.txt index 5526582..a646db2 100644 --- a/external/angle/CMakeLists.txt +++ b/external/angle/CMakeLists.txt @@ -10,14 +10,11 @@ add_library(desktop-app::external_angle ALIAS external_angle) if (WIN32) target_include_directories(external_angle INTERFACE - ${libs_loc}/angle/include + ${libs_loc}/tg_angle/include ) - set(angle_libs_loc ${libs_loc}/angle/out/$,Debug,Release>/obj) target_link_libraries(external_angle INTERFACE - ${angle_libs_loc}/libANGLE_static.lib - ${angle_libs_loc}/libGLESv2_static.lib - ${angle_libs_loc}/libEGL_static.lib + ${libs_loc}/tg_angle/out/$,Debug,Release>/tg_angle.lib dxguid.lib ) target_link_libraries(external_angle From 1c8cfe49c50d469db67ad8769c038e9ab5e296e4 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Mon, 12 Jul 2021 00:11:19 +0400 Subject: [PATCH 13/14] Clang build fixes --- .../hime_qt/hime_im_client/CMakeLists.txt | 14 +++++ init_target.cmake | 2 +- linux_gtk_helper/linux_gtk_helper.cpp | 51 ++++++++++++++----- options_linux.cmake | 22 +++++--- variables.cmake | 2 +- 5 files changed, 70 insertions(+), 21 deletions(-) diff --git a/external/hime_qt/hime_im_client/CMakeLists.txt b/external/hime_qt/hime_im_client/CMakeLists.txt index 63773b0..9e70b1d 100644 --- a/external/hime_qt/hime_im_client/CMakeLists.txt +++ b/external/hime_qt/hime_im_client/CMakeLists.txt @@ -55,6 +55,20 @@ else() GTK_DISABLE_DEPRECATED ) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + add_library(external_hime_im_client_options INTERFACE) + + target_compile_options(external_hime_im_client_options + INTERFACE + -Wno-sometimes-uninitialized + ) + + target_link_libraries(external_hime_im_client + PRIVATE + external_hime_im_client_options + ) + endif() + target_link_libraries(external_hime_im_client PRIVATE desktop-app::external_glib diff --git a/init_target.cmake b/init_target.cmake index 3a4806b..19efc98 100644 --- a/init_target.cmake +++ b/init_target.cmake @@ -5,7 +5,7 @@ # https://github.com/desktop-app/legal/blob/master/LEGAL set(MAXIMUM_CXX_STANDARD cxx_std_20) -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(MAXIMUM_CXX_STANDARD cxx_std_17) endif() diff --git a/linux_gtk_helper/linux_gtk_helper.cpp b/linux_gtk_helper/linux_gtk_helper.cpp index 231eb78..4cb4ea1 100644 --- a/linux_gtk_helper/linux_gtk_helper.cpp +++ b/linux_gtk_helper/linux_gtk_helper.cpp @@ -63,6 +63,10 @@ void (*gtk_color_chooser_set_use_alpha)( gboolean use_alpha); GType (*gtk_container_get_type)(void); void (*gtk_container_remove)(GtkContainer *container, GtkWidget *widget); +GtkWidget *(*gtk_dialog_add_button)( + GtkDialog *dialog, + const gchar *button_text, + gint response_id); GType (*gtk_dialog_get_type)(void); GtkWidget* (*gtk_dialog_get_widget_for_response)( GtkDialog *dialog, @@ -71,12 +75,7 @@ gint (*gtk_dialog_run)(GtkDialog *dialog); void (*gtk_file_chooser_add_filter)( GtkFileChooser *chooser, GtkFileFilter *filter); -GtkWidget *(*gtk_file_chooser_dialog_new)( - const gchar *title, - GtkWindow *parent, - GtkFileChooserAction action, - const gchar *first_button_text, - ...); +GType (*gtk_file_chooser_dialog_get_type)(void); gchar *(*gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser); gchar *(*gtk_file_chooser_get_filename)(GtkFileChooser *chooser); GSList *(*gtk_file_chooser_get_filenames)(GtkFileChooser *chooser); @@ -179,6 +178,7 @@ void (*gtk_widget_set_visible)(GtkWidget *widget, gboolean visible); void (*gtk_widget_show)(GtkWidget *widget); GType (*gtk_window_get_type)(void); void (*gtk_window_set_title)(GtkWindow *window, const gchar *title); +void (*gtk_window_set_transient_for)(GtkWindow *window, GtkWindow *parent); void (*pango_font_description_free)(PangoFontDescription *desc); PangoFontDescription *(*pango_font_description_from_string)(const char *str); const char *(*pango_font_description_get_family)( @@ -264,11 +264,12 @@ bool Resolve() { && LOAD_SYMBOL(lib, gtk_color_chooser_set_use_alpha) && LOAD_SYMBOL(lib, gtk_container_get_type) && LOAD_SYMBOL(lib, gtk_container_remove) + && LOAD_SYMBOL(lib, gtk_dialog_add_button) && LOAD_SYMBOL(lib, gtk_dialog_get_type) && LOAD_SYMBOL(lib, gtk_dialog_get_widget_for_response) && LOAD_SYMBOL(lib, gtk_dialog_run) && LOAD_SYMBOL(lib, gtk_file_chooser_add_filter) - && LOAD_SYMBOL(lib, gtk_file_chooser_dialog_new) + && LOAD_SYMBOL(lib, gtk_file_chooser_dialog_get_type) && LOAD_SYMBOL(lib, gtk_file_chooser_get_current_folder) && LOAD_SYMBOL(lib, gtk_file_chooser_get_filename) && LOAD_SYMBOL(lib, gtk_file_chooser_get_filenames) @@ -325,6 +326,7 @@ bool Resolve() { && LOAD_SYMBOL(lib, gtk_widget_show) && LOAD_SYMBOL(lib, gtk_window_get_type) && LOAD_SYMBOL(lib, gtk_window_set_title) + && LOAD_SYMBOL(lib, gtk_window_set_transient_for) && LOAD_SYMBOL(lib, pango_font_description_free) && LOAD_SYMBOL(lib, pango_font_description_from_string) && LOAD_SYMBOL(lib, pango_font_description_get_family) @@ -546,12 +548,35 @@ GtkWidget *gtk_file_chooser_dialog_new( const gchar *first_button_text, ...) { GtkHelper::Resolve(); - __builtin_return( - __builtin_apply( - reinterpret_cast( - GtkHelper::gtk_file_chooser_dialog_new), - __builtin_apply_args(), - 1000)); + + va_list varargs; + va_start(varargs, first_button_text); + + const auto result = static_cast(g_object_new( + GtkHelper::gtk_file_chooser_dialog_get_type(), + "title", + title, + "action", + action, + nullptr)); + + if (parent) { + GtkHelper::gtk_window_set_transient_for(GTK_WINDOW(result), parent); + } + + auto button_text = first_button_text; + gint response_id; + while (button_text) { + response_id = va_arg(varargs, gint); + GtkHelper::gtk_dialog_add_button( + GTK_DIALOG(result), + button_text, + response_id); + button_text = va_arg(varargs, const gchar *); + } + + va_end(varargs); + return result; } gchar *gtk_file_chooser_get_current_folder(GtkFileChooser *chooser) { diff --git a/options_linux.cmake b/options_linux.cmake index ae687ff..e7b164f 100644 --- a/options_linux.cmake +++ b/options_linux.cmake @@ -16,17 +16,23 @@ INTERFACE -Wno-unused-function -Wno-switch -Wno-comment - -Wno-unused-but-set-variable -Wno-missing-field-initializers -Wno-sign-compare -Wno-attributes -Wno-parentheses - -Wno-stringop-overflow - -Wno-maybe-uninitialized - -Wno-error=class-memaccess $<$>:-Wno-register> ) +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_options(common_options + INTERFACE + -Wno-unused-but-set-variable + -Wno-stringop-overflow + -Wno-maybe-uninitialized + -Wno-error=class-memaccess + ) +endif() + if (DESKTOP_APP_SPECIAL_TARGET) target_compile_options(common_options INTERFACE @@ -43,8 +49,12 @@ if (DESKTOP_APP_SPECIAL_TARGET) target_compile_options(common_options INTERFACE -g0) target_link_options(common_options INTERFACE -g0) else() - target_compile_options(common_options INTERFACE $,,-g -flto>) - target_link_options(common_options INTERFACE $,,-g -flto -fuse-linker-plugin>) + target_compile_options(common_options INTERFACE $,,-g>) + target_link_options(common_options INTERFACE $,,-g>) + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_options(common_options INTERFACE $,,-flto>) + target_link_options(common_options INTERFACE $,,-flto -fuse-linker-plugin>) + endif() endif() endif() diff --git a/variables.cmake b/variables.cmake index 80c336a..bff1d6e 100644 --- a/variables.cmake +++ b/variables.cmake @@ -95,7 +95,7 @@ else() report_bad_special_target() endif() endif() - if (DESKTOP_APP_SPECIAL_TARGET) + if (DESKTOP_APP_SPECIAL_TARGET AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_AR "gcc-ar") set(CMAKE_RANLIB "gcc-ranlib") set(CMAKE_NM "gcc-nm") From a79798285dfc49f63022d4f3aaa1a0da7b49bafa Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 13 Jul 2021 22:08:45 +0300 Subject: [PATCH 14/14] Add 'unused variable' warning on MSVC. --- options_win.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/options_win.cmake b/options_win.cmake index cf94d56..fed51de 100644 --- a/options_win.cmake +++ b/options_win.cmake @@ -25,6 +25,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") /w14834 # [[nodiscard]] /w15038 # wrong initialization order /w14265 # class has virtual functions, but destructor is not virtual + /w14101 # 'identifier' : unreferenced local variable /wd4068 # Disable "warning C4068: unknown pragma" /wd4267 # 'initializing': conversion from 'size_t' to 'int', possible loss of data. /wd4244 # '=': conversion from 'size_t' to 'int', possible loss of data.