From b07b4efa606017a8fb9ff922e8463abd0ed08ec6 Mon Sep 17 00:00:00 2001 From: tpearson Date: Mon, 10 Oct 2011 01:04:16 +0000 Subject: [PATCH] Force kgtk-qt3 to only provide open/save dialogs for recognized applications This fixes a number of random crash bugs in GTK apps under Trinity sessions Bugs affected: 468, 535 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kgtk-qt3@1258106 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- gtk2/kgtk2.c | 205 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 181 insertions(+), 24 deletions(-) diff --git a/gtk2/kgtk2.c b/gtk2/kgtk2.c index 6377d66..e76aba6 100644 --- a/gtk2/kgtk2.c +++ b/gtk2/kgtk2.c @@ -71,6 +71,8 @@ TODO #define KGTK_DLSYM_VERSION "GLIBC_2.0" #endif +#define BLACKLIST_UNKNOWN_GTK_APPS 1 + /* #define KGTK_DEBUG_DLSYM */ @@ -88,7 +90,7 @@ static void * real_dlsym (void *handle, const char *name); typedef enum { - APP_ANY, + APP_UNKNOWN, APP_GIMP, APP_INKSCAPE, APP_FIREFOX, @@ -100,7 +102,7 @@ static gboolean useKde=FALSE; static gboolean kdialogdError=FALSE; static GMainLoop *kdialogdLoop=NULL; static gchar *kgtkFileFilter=NULL; -static Application kgtkApp=APP_ANY; +static Application kgtkApp=APP_UNKNOWN; #define MAX_DATA_LEN 4096 #define MAX_FILTER_LEN 256 @@ -468,23 +470,8 @@ static gboolean isMozApp(const char *app, const char *check) return FALSE; } -static gboolean kgtkInit(const char *appName) +static void determineAppName() { - static gboolean initialised=FALSE; -#ifdef KGTK_DEBUG - printf("KGTK::kgtkInit %s\n", appName); -#endif - if(!initialised) - { -#ifdef KGTK_DEBUG - printf("KGTK::Running under KDE? %d\n", NULL!=getenv("TDE_FULL_SESSION")); -#endif - - initialised=TRUE; - kgtkAppName=getAppName(appName); - useKde=NULL!=getenv("TDE_FULL_SESSION") && connectToKDialogD(kgtkAppName); - if(useKde) - { const gchar *prg=getAppName(NULL); if(prg) @@ -521,19 +508,44 @@ static gboolean kgtkInit(const char *appName) printf("KGTK::Firefox\n"); #endif } + else + { + kgtkApp=APP_UNKNOWN; + } } +} - if(!g_threads_got_initialized) - g_thread_init(NULL); - atexit(&kgtkExit); +static gboolean kgtkInit(const char *appName) +{ + static gboolean initialised=FALSE; +#ifdef KGTK_DEBUG + printf("KGTK::kgtkInit %s\n", appName); +#endif + if(!initialised) + { +#ifdef KGTK_DEBUG + printf("KGTK::Running under KDE? %d\n", NULL!=getenv("TDE_FULL_SESSION")); +#endif + + initialised=TRUE; + kgtkAppName=getAppName(appName); + useKde=NULL!=getenv("TDE_FULL_SESSION") && connectToKDialogD(kgtkAppName); + if(useKde) + { + determineAppName(); + if ((kgtkApp != APP_UNKNOWN) || (!BLACKLIST_UNKNOWN_GTK_APPS)) { + if(!g_threads_got_initialized) + g_thread_init(NULL); + atexit(&kgtkExit); + } } } #ifdef KGTK_DEBUG - printf("KGTK::kgtkInit useKde:%d\n", useKde); + printf("KGTK::kgtkInit useKde:%d\n", (useKde && ((kgtkApp != APP_UNKNOWN) || (!BLACKLIST_UNKNOWN_GTK_APPS)))); #endif - return useKde; + return (useKde && ((kgtkApp != APP_UNKNOWN) || (!BLACKLIST_UNKNOWN_GTK_APPS))); } /* ......................... */ @@ -1129,6 +1141,15 @@ void gtk_widget_hide(GtkWidget *widget) if(!realFunction) realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_widget_hide"); + determineAppName(); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { +#ifdef KGTK_DEBUG + printf("KGTK::gtk_widget_hide Bypassing internal function\n\r"); fflush(stdout); +#endif + realFunction(widget); + return; + } + if(widget && !GTK_IS_FILE_CHOOSER_BUTTON(widget) && GTK_IS_FILE_CHOOSER(widget)) { #ifdef KGTK_DEBUG @@ -1230,6 +1251,14 @@ gint gtk_dialog_run(GtkDialog *dialog) if(!realFunction) realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_dialog_run"); + determineAppName(); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { +#ifdef KGTK_DEBUG + printf("KGTK::gtk_dialog_run Bypassing internal function\n\r"); fflush(stdout); +#endif + return realFunction(dialog); + } + #ifdef KGTK_DEBUG printf("KGTK::gtk_dialog_run %s \n", dialog ? gtk_type_name(GTK_WIDGET_TYPE(dialog)) : ""); #endif @@ -1439,6 +1468,19 @@ gchar * gtk_file_chooser_get_filename(GtkFileChooser *chooser) { KGtkFileData *data=lookupHash(chooser, FALSE); + static void * (*realFunction)() = NULL; + + if(!realFunction) + realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_get_filename"); + + determineAppName(); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { +#ifdef KGTK_DEBUG + printf("KGTK::gtk_file_chooser_get_filename Bypassing internal function\n\r"); fflush(stdout); +#endif + return realFunction(chooser); + } + #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_get_filename %d %s\n", data ? g_slist_length(data->files) : 12345, data && data->files && data->files->data ? data->files->data : "<>"); @@ -1454,6 +1496,9 @@ gboolean gtk_file_chooser_select_filename(GtkFileChooser *chooser, const char *f if(!realFunction) realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_select_filename"); realFunction(chooser, filename); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { + return; + } #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_select_filename %s, %d\n", filename, @@ -1492,6 +1537,9 @@ void gtk_file_chooser_unselect_all(GtkFileChooser *chooser) if(!realFunction) realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_unselect_all"); realFunction(chooser); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { + return; + } #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_unselect_all %d\n", data ? g_slist_length(data->files) : 12345); @@ -1512,6 +1560,9 @@ gboolean gtk_file_chooser_set_filename(GtkFileChooser *chooser, const char *file if(!realFunction) realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_set_filename"); realFunction(chooser, filename); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { + return; + } #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_set_filename %s %d\n", filename, @@ -1549,13 +1600,18 @@ void gtk_file_chooser_set_current_name(GtkFileChooser *chooser, const char *file KGtkFileData *data=lookupHash(chooser, TRUE); GtkFileChooserAction act=gtk_file_chooser_get_action(chooser); - if(GTK_FILE_CHOOSER_ACTION_SAVE==act || GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER==act) + if ((GTK_FILE_CHOOSER_ACTION_SAVE==act || GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER==act) || + ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS) + ) { static void * (*realFunction)() = NULL; if(!realFunction) realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_set_current_name"); realFunction(chooser, filename); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { + return; + } } #ifdef KGTK_DEBUG @@ -1570,11 +1626,26 @@ void gtk_file_chooser_set_current_name(GtkFileChooser *chooser, const char *file } } +// [FIXME] +// This function cannot pick up filenames chosen by a program such as geany GSList * gtk_file_chooser_get_filenames(GtkFileChooser *chooser) { KGtkFileData *data=lookupHash(chooser, FALSE); GSList *rv=NULL; + static void * (*realFunction)() = NULL; + + if(!realFunction) + realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_get_filenames"); + + determineAppName(); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { +#ifdef KGTK_DEBUG + printf("KGTK::gtk_file_chooser_get_filenames Bypassing internal function\n\r"); fflush(stdout); +#endif + return realFunction(chooser); + } + #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_get_filenames %d\n", data ? g_slist_length(data->files) : 12345); #endif @@ -1605,6 +1676,9 @@ gboolean gtk_file_chooser_set_current_folder(GtkFileChooser *chooser, const gcha if(!realFunction) realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_set_current_folder"); realFunction(chooser, folder); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { + return; + } #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_set_current_folder %s %d\n", folder, @@ -1625,6 +1699,19 @@ gchar * gtk_file_chooser_get_current_folder(GtkFileChooser *chooser) { KGtkFileData *data=lookupHash(chooser, FALSE); + static void * (*realFunction)() = NULL; + + if(!realFunction) + realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_get_current_folder"); + + determineAppName(); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { +#ifdef KGTK_DEBUG + printf("KGTK::gtk_file_chooser_get_current_folder Bypassing internal function\n\r"); fflush(stdout); +#endif + return realFunction(chooser); + } + #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_get_current_folder %d\n", data ? g_slist_length(data->files) : 12345); @@ -1640,6 +1727,19 @@ gchar * gtk_file_chooser_get_current_folder(GtkFileChooser *chooser) gchar * gtk_file_chooser_get_uri(GtkFileChooser *chooser) { + static void * (*realFunction)() = NULL; + + if(!realFunction) + realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_get_uri"); + + determineAppName(); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { +#ifdef KGTK_DEBUG + printf("KGTK::gtk_file_chooser_get_uri Bypassing internal function\n\r"); fflush(stdout); +#endif + return realFunction(chooser); + } + #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_get_uri\n"); #endif @@ -1658,6 +1758,19 @@ gchar * gtk_file_chooser_get_uri(GtkFileChooser *chooser) gboolean gtk_file_chooser_set_uri(GtkFileChooser *chooser, const char *uri) { + static void * (*realFunction)() = NULL; + + if(!realFunction) + realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_set_uri"); + + determineAppName(); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { +#ifdef KGTK_DEBUG + printf("KGTK::gtk_file_chooser_set_uri Bypassing internal function\n\r"); fflush(stdout); +#endif + return realFunction(chooser, uri); + } + #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_set_uri\n"); #endif @@ -1676,6 +1789,19 @@ gboolean gtk_file_chooser_set_uri(GtkFileChooser *chooser, const char *uri) GSList * gtk_file_chooser_get_uris(GtkFileChooser *chooser) { + static void * (*realFunction)() = NULL; + + if(!realFunction) + realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_get_uris"); + + determineAppName(); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { +#ifdef KGTK_DEBUG + printf("KGTK::gtk_file_chooser_get_uris Bypassing internal function\n\r"); fflush(stdout); +#endif + return realFunction(chooser); + } + #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_get_uris\n"); #endif @@ -1684,6 +1810,19 @@ GSList * gtk_file_chooser_get_uris(GtkFileChooser *chooser) gboolean gtk_file_chooser_set_current_folder_uri(GtkFileChooser *chooser, const gchar *uri) { + static void * (*realFunction)() = NULL; + + if(!realFunction) + realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_set_current_folder_uri"); + + determineAppName(); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { +#ifdef KGTK_DEBUG + printf("KGTK::gtk_file_chooser_set_current_folder_uri Bypassing internal function\n\r"); fflush(stdout); +#endif + return realFunction(chooser, uri); + } + #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_set_current_folder_uri\n"); #endif @@ -1701,6 +1840,19 @@ gboolean gtk_file_chooser_set_current_folder_uri(GtkFileChooser *chooser, const gchar * gtk_file_chooser_get_current_folder_uri(GtkFileChooser *chooser) { + static void * (*realFunction)() = NULL; + + if(!realFunction) + realFunction = (void *(*)()) real_dlsym(RTLD_NEXT, "gtk_file_chooser_get_current_folder_uri"); + + determineAppName(); + if ((kgtkApp == APP_UNKNOWN) && BLACKLIST_UNKNOWN_GTK_APPS && realFunction) { +#ifdef KGTK_DEBUG + printf("KGTK::gtk_file_chooser_get_current_folder_uri Bypassing internal function\n\r"); fflush(stdout); +#endif + return realFunction(chooser); + } + #ifdef KGTK_DEBUG printf("KGTK::gtk_file_chooser_get_current_folder_uri\n"); #endif @@ -1737,6 +1889,11 @@ void g_signal_stop_emission_by_name(gpointer instance, const gchar *detailed_sig #endif } +// [FIXME] +// This needs to use the real gtk_file_chooser_dialog_new function when an app is blacklisted, +// but I don't know how to handle the variable arguments! +// On the other hand this program seems to work just fine with this function this way...hmmm... +// ...does anything need to be changed in reality? GtkWidget * gtk_file_chooser_dialog_new(const gchar *title, GtkWindow *parent, GtkFileChooserAction action, const gchar *first_button_text, ...)