|
|
@ -2,7 +2,7 @@ |
|
|
|
|
|
|
|
/* $Id$
|
|
|
|
* |
|
|
|
* Copyright © 2005 Jasper Huijsmans <jasper@xfce.org> |
|
|
|
* Copyright © 2005-2006 Jasper Huijsmans <jasper@xfce.org> |
|
|
|
* |
|
|
|
* This program is free software; you can redistribute it and/or modify |
|
|
|
* it under the terms of the GNU General Public License as published |
|
|
@ -48,24 +48,21 @@ typedef struct _XfcePanelItemClass XfcePanelItemClass; |
|
|
|
struct _XfcePanelItemClass |
|
|
|
{ |
|
|
|
/* info from .desktop file */ |
|
|
|
char *plugin_name; |
|
|
|
char *plugin_name; |
|
|
|
char *name; |
|
|
|
char *comment; |
|
|
|
char *icon; |
|
|
|
guint unique:1; |
|
|
|
guint is_external:1; |
|
|
|
|
|
|
|
char *name; |
|
|
|
char *comment; |
|
|
|
char *icon; |
|
|
|
|
|
|
|
guint unique:1; |
|
|
|
guint is_external:1; |
|
|
|
|
|
|
|
char *file; /* either executable or loadable module */ |
|
|
|
|
|
|
|
/* using the plugin */ |
|
|
|
int use_count; |
|
|
|
/* either executable or loadable module */ |
|
|
|
char *file; |
|
|
|
|
|
|
|
/* for loadable modules only */ |
|
|
|
GModule *gmodule; |
|
|
|
XfcePanelPluginFunc construct; |
|
|
|
XfcePanelPluginCheck check; |
|
|
|
int use_count; |
|
|
|
GModule *gmodule; |
|
|
|
XfcePanelPluginFunc construct; |
|
|
|
XfcePanelPluginCheck check; |
|
|
|
}; |
|
|
|
|
|
|
|
static GHashTable *plugin_classes = NULL; |
|
|
@ -73,7 +70,7 @@ static GHashTable *plugin_classes = NULL; |
|
|
|
/* hash table */ |
|
|
|
|
|
|
|
static void |
|
|
|
_free_item_class (XfcePanelItemClass *class) |
|
|
|
free_item_class (XfcePanelItemClass *class) |
|
|
|
{ |
|
|
|
DBG ("Free item class: %s", class->plugin_name); |
|
|
|
|
|
|
@ -91,10 +88,11 @@ _free_item_class (XfcePanelItemClass *class) |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
_add_item_info_to_array (char *plugin_name, XfcePanelItemClass *class, |
|
|
|
gpointer data) |
|
|
|
add_item_info_to_array (char *plugin_name, |
|
|
|
XfcePanelItemClass *class, |
|
|
|
gpointer data) |
|
|
|
{ |
|
|
|
GPtrArray *array = data; |
|
|
|
GPtrArray *array = data; |
|
|
|
XfcePanelItemInfo *info; |
|
|
|
|
|
|
|
info = panel_slice_new0 (XfcePanelItemInfo); |
|
|
@ -110,36 +108,100 @@ _add_item_info_to_array (char *plugin_name, XfcePanelItemClass *class, |
|
|
|
g_ptr_array_add (array, info); |
|
|
|
} |
|
|
|
|
|
|
|
static gboolean |
|
|
|
check_class_removal (gpointer key, XfcePanelItemClass *class) |
|
|
|
{ |
|
|
|
if (!g_file_test (class->file, G_FILE_TEST_EXISTS)) |
|
|
|
{ |
|
|
|
if (class->is_external || !class->use_count) |
|
|
|
return TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
compare_classes (gpointer *a, gpointer *b) |
|
|
|
{ |
|
|
|
XfcePanelItemClass *class_a, *class_b; |
|
|
|
|
|
|
|
if (!a || !(*a)) |
|
|
|
return 1; |
|
|
|
|
|
|
|
if (!b || !(*b)) |
|
|
|
return -1; |
|
|
|
|
|
|
|
if (*a == *b) |
|
|
|
return 0; |
|
|
|
|
|
|
|
class_a = *a; |
|
|
|
class_b = *b; |
|
|
|
|
|
|
|
if (strcmp (class_a->plugin_name, "launcher") == 0) |
|
|
|
return -1; |
|
|
|
|
|
|
|
if (strcmp (class_b->plugin_name, "launcher") == 0) |
|
|
|
return 1; |
|
|
|
|
|
|
|
return strcmp (class_a->name ? class_a->name : "z", |
|
|
|
class_b->name ? class_b->name : "z"); |
|
|
|
} |
|
|
|
|
|
|
|
/* plugin desktop files */ |
|
|
|
|
|
|
|
static char * |
|
|
|
_plugin_name_from_filename (const char *file) |
|
|
|
plugin_name_from_filename (const char *file) |
|
|
|
{ |
|
|
|
const char *s, *p; |
|
|
|
char *name; |
|
|
|
char *name; |
|
|
|
|
|
|
|
if ((s = strrchr (file, G_DIR_SEPARATOR))) |
|
|
|
if ((s = strrchr (file, G_DIR_SEPARATOR)) != NULL) |
|
|
|
{ |
|
|
|
s++; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
s = file; |
|
|
|
} |
|
|
|
|
|
|
|
p = strrchr (file, '.'); |
|
|
|
|
|
|
|
name = g_strndup (s, p - s); |
|
|
|
if ((p = strrchr (s, '.')) != NULL) |
|
|
|
{ |
|
|
|
name = g_strndup (s, p - s); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
name = g_strdup (s); |
|
|
|
} |
|
|
|
|
|
|
|
return name; |
|
|
|
} |
|
|
|
|
|
|
|
static XfcePanelItemClass * |
|
|
|
_new_plugin_class_from_desktop_file (const char *file) |
|
|
|
create_item_class (const char *file, |
|
|
|
gboolean is_external) |
|
|
|
{ |
|
|
|
XfcePanelItemClass *class; |
|
|
|
|
|
|
|
class = panel_slice_new0 (XfcePanelItemClass); |
|
|
|
class->file = g_strdup (file); |
|
|
|
class->is_external = is_external; |
|
|
|
|
|
|
|
return class; |
|
|
|
} |
|
|
|
|
|
|
|
static XfcePanelItemClass * |
|
|
|
new_plugin_class_from_desktop_file (const char *file) |
|
|
|
{ |
|
|
|
XfcePanelItemClass *class = NULL; |
|
|
|
XfceRc *rc; |
|
|
|
char *name; |
|
|
|
XfceRc *rc; |
|
|
|
char *name; |
|
|
|
const char *value; |
|
|
|
const char *dir; |
|
|
|
char *path; |
|
|
|
|
|
|
|
DBG ("Plugin .desktop file: %s", file); |
|
|
|
|
|
|
|
name = _plugin_name_from_filename (file); |
|
|
|
name = plugin_name_from_filename (file); |
|
|
|
|
|
|
|
if (g_hash_table_lookup (plugin_classes, name) != NULL) |
|
|
|
{ |
|
|
@ -152,51 +214,30 @@ _new_plugin_class_from_desktop_file (const char *file) |
|
|
|
|
|
|
|
if (rc && xfce_rc_has_group (rc, "Xfce Panel")) |
|
|
|
{ |
|
|
|
const char *value; |
|
|
|
|
|
|
|
xfce_rc_set_group (rc, "Xfce Panel"); |
|
|
|
|
|
|
|
if ((value = xfce_rc_read_entry (rc, "X-XFCE-Exec", NULL)) && |
|
|
|
g_file_test (value, G_FILE_TEST_EXISTS)) |
|
|
|
if ((value = xfce_rc_read_entry (rc, "X-XFCE-Exec", NULL)) |
|
|
|
&& g_file_test (value, G_FILE_TEST_EXISTS)) |
|
|
|
|
|
|
|
{ |
|
|
|
class = panel_slice_new0 (XfcePanelItemClass); |
|
|
|
|
|
|
|
class->file = g_strdup (value); |
|
|
|
|
|
|
|
class->is_external = TRUE; |
|
|
|
|
|
|
|
class = create_item_class (value, TRUE); |
|
|
|
DBG ("External plugin: %s", value); |
|
|
|
} |
|
|
|
else if ((value = xfce_rc_read_entry (rc, "X-XFCE-Module", NULL))) |
|
|
|
{ |
|
|
|
const char *dir; |
|
|
|
|
|
|
|
if (g_file_test (value, G_FILE_TEST_EXISTS)) |
|
|
|
{ |
|
|
|
class = panel_slice_new0 (XfcePanelItemClass); |
|
|
|
|
|
|
|
class->file = g_strdup (value); |
|
|
|
|
|
|
|
class->is_external = FALSE; |
|
|
|
|
|
|
|
class = create_item_class (value, FALSE); |
|
|
|
DBG ("Internal plugin: %s", value); |
|
|
|
} |
|
|
|
else if ((dir = xfce_rc_read_entry (rc, "X-XFCE-Module-Path", |
|
|
|
NULL))) |
|
|
|
{ |
|
|
|
char *path; |
|
|
|
|
|
|
|
path = g_module_build_path (dir, value); |
|
|
|
|
|
|
|
if (g_file_test (path, G_FILE_TEST_EXISTS)) |
|
|
|
{ |
|
|
|
class = panel_slice_new0 (XfcePanelItemClass); |
|
|
|
|
|
|
|
class->file = g_strdup (path); |
|
|
|
|
|
|
|
class->is_external = FALSE; |
|
|
|
|
|
|
|
class = create_item_class (path, FALSE); |
|
|
|
DBG ("Internal plugin: %s", path); |
|
|
|
} |
|
|
|
|
|
|
@ -241,15 +282,15 @@ _new_plugin_class_from_desktop_file (const char *file) |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
_update_plugin_list (void) |
|
|
|
update_plugin_list (void) |
|
|
|
{ |
|
|
|
char **dirs, **d; |
|
|
|
gboolean datadir_used = FALSE; |
|
|
|
gboolean use_user_config = xfce_allow_panel_customization(); |
|
|
|
char **dirs; |
|
|
|
char **d; |
|
|
|
gboolean datadir_used = FALSE; |
|
|
|
|
|
|
|
if (G_UNLIKELY (!use_user_config)) |
|
|
|
if (G_UNLIKELY (!xfce_allow_panel_customization())) |
|
|
|
{ |
|
|
|
dirs = g_new (char*, 2); |
|
|
|
dirs = g_new (char*, 2); |
|
|
|
dirs[0] = g_strdup (DATADIR); |
|
|
|
dirs[1] = NULL; |
|
|
|
} |
|
|
@ -260,9 +301,11 @@ _update_plugin_list (void) |
|
|
|
|
|
|
|
for (d = dirs; *d != NULL || !datadir_used; ++d) |
|
|
|
{ |
|
|
|
GDir *gdir; |
|
|
|
char *dirname; |
|
|
|
const char *file; |
|
|
|
GDir *gdir; |
|
|
|
char *dirname; |
|
|
|
const char *file; |
|
|
|
XfcePanelItemClass *class; |
|
|
|
char *path; |
|
|
|
|
|
|
|
/* check if resource dirs include our prefix */ |
|
|
|
if (*d == NULL) |
|
|
@ -283,40 +326,37 @@ _update_plugin_list (void) |
|
|
|
|
|
|
|
DBG (" + directory: %s", dirname); |
|
|
|
|
|
|
|
if (!gdir) |
|
|
|
{ |
|
|
|
g_free (dirname); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
while ((file = g_dir_read_name (gdir)) != NULL) |
|
|
|
if (gdir) |
|
|
|
{ |
|
|
|
XfcePanelItemClass *class; |
|
|
|
char *path; |
|
|
|
while ((file = g_dir_read_name (gdir)) != NULL) |
|
|
|
{ |
|
|
|
if (!g_str_has_suffix (file, ".desktop")) |
|
|
|
continue; |
|
|
|
|
|
|
|
if (!g_str_has_suffix (file, ".desktop")) |
|
|
|
continue; |
|
|
|
path = g_build_filename (dirname, file, NULL); |
|
|
|
|
|
|
|
path = g_build_filename (dirname, file, NULL); |
|
|
|
class = _new_plugin_class_from_desktop_file (path); |
|
|
|
class = new_plugin_class_from_desktop_file (path); |
|
|
|
|
|
|
|
g_free (path); |
|
|
|
g_free (path); |
|
|
|
|
|
|
|
if (class) |
|
|
|
{ |
|
|
|
DBG (" + class \"%s\": " |
|
|
|
"name=%s, comment=%s, icon=%s, external=%d, path=%s", |
|
|
|
class->plugin_name, |
|
|
|
class->name, class->comment, class->icon, |
|
|
|
class->is_external, class->file); |
|
|
|
if (class) |
|
|
|
{ |
|
|
|
DBG (" + class \"%s\": " |
|
|
|
"name=%s, comment=%s, icon=%s, external=%d, path=%s", |
|
|
|
class->plugin_name, |
|
|
|
class->name, class->comment, class->icon, |
|
|
|
class->is_external, class->file); |
|
|
|
|
|
|
|
g_hash_table_insert (plugin_classes, |
|
|
|
class->plugin_name, class); |
|
|
|
g_hash_table_insert (plugin_classes, |
|
|
|
class->plugin_name, |
|
|
|
class); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
g_dir_close (gdir); |
|
|
|
} |
|
|
|
|
|
|
|
g_free (dirname); |
|
|
|
g_dir_close (gdir); |
|
|
|
|
|
|
|
if (*d == NULL) |
|
|
|
break; |
|
|
@ -325,18 +365,68 @@ _update_plugin_list (void) |
|
|
|
g_strfreev (dirs); |
|
|
|
} |
|
|
|
|
|
|
|
static gboolean |
|
|
|
load_module (XfcePanelItemClass *class) |
|
|
|
{ |
|
|
|
gpointer symbol; |
|
|
|
XfcePanelPluginFunc (*get_construct) (void); |
|
|
|
XfcePanelPluginCheck (*get_check) (void); |
|
|
|
|
|
|
|
class->gmodule = g_module_open (class->file, G_MODULE_BIND_LOCAL); |
|
|
|
|
|
|
|
if (G_UNLIKELY (class->gmodule == NULL)) |
|
|
|
{ |
|
|
|
g_critical ("Could not open \"%s\": %s", |
|
|
|
class->name, g_module_error ()); |
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
if (!g_module_symbol (class->gmodule, |
|
|
|
"xfce_panel_plugin_get_construct", &symbol)) |
|
|
|
{ |
|
|
|
g_critical ("Could not open \"%s\": %s", |
|
|
|
class->name, g_module_error ()); |
|
|
|
g_module_close (class->gmodule); |
|
|
|
class->gmodule = NULL; |
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
get_construct = symbol; |
|
|
|
class->construct = get_construct (); |
|
|
|
|
|
|
|
if (g_module_symbol (class->gmodule, |
|
|
|
"xfce_panel_plugin_get_check", &symbol)) |
|
|
|
{ |
|
|
|
get_check = symbol; |
|
|
|
class->check = get_check (); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
class->check = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
return TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
decrease_use_count (GtkWidget *item, |
|
|
|
XfcePanelItemClass *class) |
|
|
|
{ |
|
|
|
if (class->use_count > 0) |
|
|
|
class->use_count--; |
|
|
|
} |
|
|
|
|
|
|
|
/* public API */ |
|
|
|
|
|
|
|
void |
|
|
|
xfce_panel_item_manager_init (void) |
|
|
|
{ |
|
|
|
plugin_classes = |
|
|
|
g_hash_table_new_full ((GHashFunc) g_str_hash, |
|
|
|
(GEqualFunc) g_str_equal, |
|
|
|
NULL, |
|
|
|
(GDestroyNotify)_free_item_class); |
|
|
|
plugin_classes = g_hash_table_new_full ((GHashFunc) g_str_hash, |
|
|
|
(GEqualFunc) g_str_equal, |
|
|
|
NULL, |
|
|
|
(GDestroyNotify) free_item_class); |
|
|
|
|
|
|
|
_update_plugin_list (); |
|
|
|
update_plugin_list (); |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
@ -347,74 +437,34 @@ xfce_panel_item_manager_cleanup (void) |
|
|
|
plugin_classes = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
_decrease_use_count (GtkWidget *item, XfcePanelItemClass *class) |
|
|
|
{ |
|
|
|
if (class->use_count > 0) |
|
|
|
class->use_count--; |
|
|
|
} |
|
|
|
|
|
|
|
GtkWidget * |
|
|
|
xfce_panel_item_manager_create_item (GdkScreen *screen, const char *name, |
|
|
|
const char *id, int size, |
|
|
|
XfceScreenPosition position) |
|
|
|
xfce_panel_item_manager_create_item (GdkScreen *screen, |
|
|
|
const char *name, |
|
|
|
const char *id, |
|
|
|
int size, |
|
|
|
XfceScreenPosition position) |
|
|
|
{ |
|
|
|
XfcePanelItemClass *class; |
|
|
|
GtkWidget *item = NULL; |
|
|
|
GtkWidget *item = NULL; |
|
|
|
|
|
|
|
if ((class = g_hash_table_lookup (plugin_classes, name)) == NULL) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
if (class->is_external) |
|
|
|
{ |
|
|
|
item = xfce_external_panel_item_new (class->plugin_name, id, |
|
|
|
class->name, class->file, |
|
|
|
size, position); |
|
|
|
item = xfce_external_panel_item_new (class->plugin_name, |
|
|
|
id, |
|
|
|
class->name, |
|
|
|
class->file, |
|
|
|
size, |
|
|
|
position); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
if (!class->gmodule) |
|
|
|
{ |
|
|
|
gpointer symbol; |
|
|
|
XfcePanelPluginFunc (*get_construct) (void); |
|
|
|
XfcePanelPluginCheck (*get_check) (void); |
|
|
|
|
|
|
|
class->gmodule = g_module_open (class->file, G_MODULE_BIND_LOCAL); |
|
|
|
if (G_UNLIKELY (class->gmodule == NULL)) |
|
|
|
{ |
|
|
|
g_critical ("Could not open \"%s\": %s", |
|
|
|
class->name, g_module_error ()); |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
if (!g_module_symbol (class->gmodule, |
|
|
|
"xfce_panel_plugin_get_construct", &symbol)) |
|
|
|
{ |
|
|
|
g_critical ("Could not open \"%s\": %s", |
|
|
|
class->name, g_module_error ()); |
|
|
|
g_module_close (class->gmodule); |
|
|
|
class->gmodule = NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
|
|
|
|
get_construct = symbol; |
|
|
|
|
|
|
|
class->construct = get_construct (); |
|
|
|
|
|
|
|
if (g_module_symbol (class->gmodule, |
|
|
|
"xfce_panel_plugin_get_check", &symbol)) |
|
|
|
{ |
|
|
|
get_check = symbol; |
|
|
|
|
|
|
|
class->check = get_check (); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
class->check = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!class->gmodule && !load_module (class)) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
if (!class->check || class->check(screen) == TRUE ) |
|
|
|
if (class->check == NULL || class->check(screen) == TRUE ) |
|
|
|
{ |
|
|
|
item = xfce_internal_panel_plugin_new (class->plugin_name, |
|
|
|
id, |
|
|
@ -429,70 +479,28 @@ xfce_panel_item_manager_create_item (GdkScreen *screen, const char *name, |
|
|
|
{ |
|
|
|
class->use_count++; |
|
|
|
g_signal_connect (item, "destroy", |
|
|
|
G_CALLBACK (_decrease_use_count), class); |
|
|
|
G_CALLBACK (decrease_use_count), class); |
|
|
|
} |
|
|
|
|
|
|
|
return item; |
|
|
|
} |
|
|
|
|
|
|
|
static gboolean |
|
|
|
_check_class_removal (gpointer key, XfcePanelItemClass *class) |
|
|
|
{ |
|
|
|
if (!g_file_test (class->file, G_FILE_TEST_EXISTS)) |
|
|
|
{ |
|
|
|
if (class->is_external) |
|
|
|
return TRUE; |
|
|
|
|
|
|
|
if (!class->use_count) |
|
|
|
return TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
static int |
|
|
|
_compare_classes (gpointer *a, gpointer *b) |
|
|
|
{ |
|
|
|
XfcePanelItemClass *class_a, *class_b; |
|
|
|
|
|
|
|
if (!a || !(*a)) |
|
|
|
return 1; |
|
|
|
|
|
|
|
if (!b || !(*b)) |
|
|
|
return -1; |
|
|
|
|
|
|
|
if (*a == *b) |
|
|
|
return 0; |
|
|
|
|
|
|
|
class_a = *a; |
|
|
|
class_b = *b; |
|
|
|
|
|
|
|
if (!strcmp (class_a->plugin_name, "launcher")) |
|
|
|
return -1; |
|
|
|
|
|
|
|
if (!strcmp (class_b->plugin_name, "launcher")) |
|
|
|
return 1; |
|
|
|
|
|
|
|
return strcmp (class_a->name ? class_a->name : "x", |
|
|
|
class_b->name ? class_b->name : "x"); |
|
|
|
} |
|
|
|
|
|
|
|
GPtrArray * |
|
|
|
xfce_panel_item_manager_get_item_info_list (void) |
|
|
|
{ |
|
|
|
GPtrArray *array; |
|
|
|
|
|
|
|
_update_plugin_list (); |
|
|
|
update_plugin_list (); |
|
|
|
|
|
|
|
g_hash_table_foreach_remove (plugin_classes, (GHRFunc)_check_class_removal, |
|
|
|
NULL); |
|
|
|
g_hash_table_foreach_remove (plugin_classes, |
|
|
|
(GHRFunc)check_class_removal, NULL); |
|
|
|
|
|
|
|
array = g_ptr_array_sized_new (g_hash_table_size (plugin_classes)); |
|
|
|
|
|
|
|
g_hash_table_foreach (plugin_classes, (GHFunc)_add_item_info_to_array, |
|
|
|
array); |
|
|
|
g_hash_table_foreach (plugin_classes, |
|
|
|
(GHFunc)add_item_info_to_array, array); |
|
|
|
|
|
|
|
g_ptr_array_sort (array, (GCompareFunc)_compare_classes); |
|
|
|
g_ptr_array_sort (array, (GCompareFunc)compare_classes); |
|
|
|
|
|
|
|
return array; |
|
|
|
} |
|
|
|