Browse Source

* Fix use of mmap for config file.

* Minor code cleanup and layout update.


(Old svn revision: 24080)
upstream/xfce4-panel-4.10.1
Jasper Huijsmans 17 years ago
parent
commit
dfbbbb3f53
  1. 3
      configure.ac.in
  2. 19
      panel/panel-app-messages.c
  3. 170
      panel/panel-app.c
  4. 193
      panel/panel-config.c
  5. 5
      panel/panel-dialogs.c
  6. 406
      panel/panel-item-manager.c

3
configure.ac.in

@ -60,8 +60,9 @@ AC_SUBST([LIBXFCE4PANEL_VERINFO])
dnl Check for standard header files
AC_HEADER_STDC
AC_CHECK_HEADERS([signal.h stddef.h sys/wait.h time.h string.h])
AC_CHECK_HEADERS([signal.h stddef.h sys/wait.h time.h string.h sys/mman.h])
AC_CHECK_FUNCS([sigaction])
AC_FUNC_MMAP()
dnl Check for i18n support
XDT_I18N([@LINGUAS@])

19
panel/panel-app-messages.c

@ -41,7 +41,8 @@
/* client messages */
static gboolean
client_event_received (GtkWidget *win, GdkEventClient *ev)
client_event_received (GtkWidget *win,
GdkEventClient *ev)
{
GdkAtom atom = gdk_atom_intern (PANEL_APP_ATOM, FALSE);
@ -103,19 +104,19 @@ panel_app_send (PanelAppMessage message)
if (win)
{
GdkEventClient gev;
GtkWidget *invisible;
GdkEventClient gev;
GtkWidget *invisible;
invisible = gtk_invisible_new ();
gtk_widget_realize (invisible);
gev.type = GDK_CLIENT_EVENT;
gev.window = invisible->window;
gev.send_event = TRUE;
gev.type = GDK_CLIENT_EVENT;
gev.window = invisible->window;
gev.send_event = TRUE;
gev.message_type = gdk_atom_intern (PANEL_APP_ATOM, FALSE);
gev.data_format = 16;
gev.data.s[0] = message;
gev.data.s[1] = 0;
gev.data_format = 16;
gev.data.s[0] = message;
gev.data.s[1] = 0;
gdk_event_send_client_message ((GdkEvent *) & gev,
(GdkNativeWindow) win);

170
panel/panel-app.c

@ -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
@ -59,8 +59,10 @@
#if defined(TIMER) && defined(G_HAVE_ISO_VARARGS)
void
xfce_panel_program_log (const char *file, const int line,
const char *format, ...)
xfce_panel_program_log (const char *file,
const int line,
const char *format,
...)
{
va_list args;
gchar *formatted;
@ -96,25 +98,24 @@ typedef struct _PanelApp PanelApp;
struct _PanelApp
{
GtkWidget *gtk_ipc_window;
Window ipc_window;
GtkWidget *gtk_ipc_window;
Window ipc_window;
SessionClient *session_client;
PanelRunState runstate;
GPtrArray *panel_list;
GPtrArray *monitor_list;
PanelRunState runstate;
GPtrArray *panel_list;
GPtrArray *monitor_list;
int save_id;
int save_id;
int current_panel;
GList *dialogs;
int current_panel;
/* Initialization. Also unset before cleanup. */
guint initialized:1;
GList *dialogs;
guint initialized:1; /* also unset before cleanup */
/* check whether monitors in Xinerama are aligned */
guint xinerama_and_equal_width:1;
guint xinerama_and_equal_height:1;
/* Check whether monitors in Xinerama are aligned. */
guint xinerama_and_equal_width:1;
guint xinerama_and_equal_height:1;
};
static PanelApp panel_app = {0};
@ -126,7 +127,7 @@ static int signal_pipe[2];
static void
cleanup_panels (void)
{
int i;
int i;
GList *l;
if (!panel_app.initialized)
@ -202,10 +203,10 @@ sighandler (int sig)
}
static gboolean
check_signal_state (void)
check_run_state (void)
{
static int recursive = 0;
gboolean quit = FALSE;
gboolean quit = FALSE;
/* micro-optimization */
if (G_LIKELY (panel_app.runstate == PANEL_RUN_STATE_NORMAL))
@ -223,9 +224,11 @@ check_signal_state (void)
panel_app_save ();
quit = TRUE;
break;
case PANEL_RUN_STATE_QUIT_NOSAVE:
quit = TRUE;
break;
default:
if (panel_app.session_client)
{
@ -261,11 +264,13 @@ check_signal_state (void)
}
static gboolean
set_signal_state (GIOChannel * source, GIOCondition cond, gpointer data)
set_run_state (GIOChannel *source,
GIOCondition cond,
gpointer data)
{
GError *error = NULL;
GIOStatus status;
gsize bytes_read;
GError *error = NULL;
GIOStatus status;
gsize bytes_read;
/*
* There is no g_io_channel_read or g_io_channel_read_int, so we read
* char's and use a union to recover the unix signal number.
@ -273,19 +278,18 @@ set_signal_state (GIOChannel * source, GIOCondition cond, gpointer data)
union
{
gchar chars[sizeof (int)];
int signal;
int signal;
} buf;
while ((status =
g_io_channel_read_chars (source, buf.chars, sizeof (int),
&bytes_read, &error)
while ((status = g_io_channel_read_chars (source, buf.chars, sizeof (int),
&bytes_read, &error)
) == G_IO_STATUS_NORMAL)
{
if (bytes_read != sizeof (int))
{
g_printerr ("lost data in signal pipe: expected %d, receieved %d",
sizeof (int), bytes_read);
/* always at least quite if we receieved data */
/* always at least quit if we received data */
panel_app.runstate = PANEL_RUN_STATE_QUIT_NOCONFIRM;
continue;
}
@ -326,14 +330,17 @@ set_signal_state (GIOChannel * source, GIOCondition cond, gpointer data)
panel_app.runstate = PANEL_RUN_STATE_QUIT_NOCONFIRM;
}
return check_signal_state ();
return check_run_state ();
}
/* session */
static void
session_save_yourself (gpointer data, int save_style, gboolean shutdown,
int interact_style, gboolean fast)
session_save_yourself (gpointer data,
int save_style,
gboolean shutdown,
int interact_style,
gboolean fast)
{
panel_app_save ();
}
@ -348,9 +355,9 @@ session_die (gpointer client_data)
static void
monitor_size_changed (GdkScreen *screen)
{
int i;
int i;
XfceMonitor *monitor;
GtkWidget *panel;
GtkWidget *panel;
for (i = 0; i < panel_app.monitor_list->len; ++i)
{
@ -375,11 +382,14 @@ monitor_size_changed (GdkScreen *screen)
static void
create_monitor_list (void)
{
GdkDisplay *display;
GdkScreen *screen;
GdkDisplay *display;
GdkScreen *screen;
XfceMonitor *monitor;
int n_screens, n_monitors = 0, i, j, w = 0, h = 0;
gboolean equal_w, equal_h;
int n_screens;
int n_monitors = 0;
int i, j;
int w = 0, h = 0;
gboolean equal_w, equal_h;
panel_app.monitor_list = g_ptr_array_new ();
@ -440,15 +450,14 @@ create_monitor_list (void)
}
/* check layout */
/* TODO: can this be optimized? does it need to be? */
for (i = 0; i < panel_app.monitor_list->len; ++i)
{
XfceMonitor *mon1 = g_ptr_array_index (panel_app.monitor_list, i);
XfceMonitor *mon1, *mon2;
mon1 = g_ptr_array_index (panel_app.monitor_list, i);
for (j = 0; j < panel_app.monitor_list->len; ++j)
{
XfceMonitor *mon2;
if (j == i)
continue;
@ -519,9 +528,10 @@ unregister_dialog (GtkWidget *dialog)
int
panel_app_init (void)
{
Atom selection_atom, manager_atom;
GtkWidget *invisible;
XClientMessageEvent xev;
Atom selection_atom;
Atom manager_atom;
GtkWidget *invisible;
XClientMessageEvent xev;
if (panel_app.initialized)
return 0;
@ -529,7 +539,6 @@ panel_app_init (void)
panel_app.initialized = TRUE;
selection_atom = XInternAtom (GDK_DISPLAY (), SELECTION_NAME, False);
panel_app.ipc_window = XGetSelectionOwner (GDK_DISPLAY (), selection_atom);
if (panel_app.ipc_window)
@ -556,15 +565,15 @@ panel_app_init (void)
manager_atom = XInternAtom (GDK_DISPLAY (), "MANAGER", False);
xev.type = ClientMessage;
xev.window = GDK_ROOT_WINDOW ();
xev.type = ClientMessage;
xev.window = GDK_ROOT_WINDOW ();
xev.message_type = manager_atom;
xev.format = 32;
xev.data.l[0] = GDK_CURRENT_TIME;
xev.data.l[1] = selection_atom;
xev.data.l[2] = panel_app.ipc_window;
xev.data.l[3] = 0; /* manager specific data */
xev.data.l[4] = 0; /* manager specific data */
xev.format = 32;
xev.data.l[0] = GDK_CURRENT_TIME;
xev.data.l[1] = selection_atom;
xev.data.l[2] = panel_app.ipc_window;
xev.data.l[3] = 0; /* manager specific data */
xev.data.l[4] = 0; /* manager specific data */
XSendEvent (GDK_DISPLAY (), GDK_ROOT_WINDOW (), False,
StructureNotifyMask, (XEvent *) & xev);
@ -605,14 +614,15 @@ panel_app_init_panel (GtkWidget *panel)
* Returns: 1 to restart and 0 to quit.
**/
int
panel_app_run (int argc, char **argv)
panel_app_run (int argc,
char **argv)
{
#ifdef HAVE_SIGACTION
struct sigaction act;
struct sigaction act;
#endif
GIOChannel *g_signal_in;
GError *error = NULL;
long fd_flags;
GIOChannel *g_signal_in;
GError *error = NULL;
long fd_flags;
/* create pipe and set writing end in non-blocking mode */
if (pipe (signal_pipe))
@ -655,7 +665,7 @@ panel_app_run (int argc, char **argv)
}
/* register the reading end with the event loop */
g_io_add_watch (g_signal_in, G_IO_IN | G_IO_PRI, set_signal_state, NULL);
g_io_add_watch (g_signal_in, G_IO_IN | G_IO_PRI, set_run_state, NULL);
/* register signals */
#ifdef HAVE_SIGACTION
@ -666,19 +676,19 @@ panel_app_run (int argc, char **argv)
#else
act.sa_flags = 0;
#endif
sigaction (SIGHUP, &act, NULL);
sigaction (SIGHUP, &act, NULL);
sigaction (SIGUSR1, &act, NULL);
sigaction (SIGUSR2, &act, NULL);
sigaction (SIGINT, &act, NULL);
sigaction (SIGINT, &act, NULL);
sigaction (SIGABRT, &act, NULL);
sigaction (SIGTERM, &act, NULL);
act.sa_handler = sigchld_handler;
sigaction (SIGCHLD, &act, NULL);
#else
signal (SIGHUP, sighandler);
signal (SIGHUP, sighandler);
signal (SIGUSR1, sighandler);
signal (SIGUSR2, sighandler);
signal (SIGINT, sighandler);
signal (SIGINT, sighandler);
signal (SIGABRT, sighandler);
signal (SIGTERM, sighandler);
signal (SIGCHLD, sigchld_handler);
@ -694,7 +704,7 @@ panel_app_run (int argc, char **argv)
SESSION_RESTART_IF_RUNNING, 40);
panel_app.session_client->save_yourself = session_save_yourself;
panel_app.session_client->die = session_die;
panel_app.session_client->die = session_die;
TIMER_ELAPSED("connect to session manager");
if (!session_init (panel_app.session_client))
@ -723,6 +733,7 @@ panel_app_run (int argc, char **argv)
TIMER_ELAPSED("start main loop");
gtk_main ();
/* cleanup */
g_free (panel_app.session_client);
panel_app.session_client = NULL;
@ -792,28 +803,28 @@ void
panel_app_restart (void)
{
panel_app.runstate = PANEL_RUN_STATE_RESTART;
check_signal_state ();
check_run_state ();
}
void
panel_app_quit (void)
{
panel_app.runstate = PANEL_RUN_STATE_QUIT;
check_signal_state ();
check_run_state ();
}
void
panel_app_quit_noconfirm (void)
{
panel_app.runstate = PANEL_RUN_STATE_QUIT_NOCONFIRM;
check_signal_state ();
check_run_state ();
}
void
panel_app_quit_nosave (void)
{
panel_app.runstate = PANEL_RUN_STATE_QUIT_NOSAVE;
check_signal_state ();
check_run_state ();
}
void
@ -846,7 +857,8 @@ panel_app_add_panel (void)
void
panel_app_remove_panel (GtkWidget *panel)
{
int response = GTK_RESPONSE_NONE, n;
int response = GTK_RESPONSE_NONE;
int n;
char *first;
if (!xfce_allow_panel_customization())
@ -917,13 +929,13 @@ void
panel_app_about (GtkWidget *panel)
{
XfceAboutInfo *info;
GtkWidget *dlg;
GdkPixbuf *pb;
GtkWidget *dlg;
GdkPixbuf *pb;
info = xfce_about_info_new (_("Xfce Panel"), "", _("Xfce Panel"),
XFCE_COPYRIGHT_TEXT ("2005",
"Jasper Huijsmans"),
XFCE_LICENSE_GPL);
info =
xfce_about_info_new (_("Xfce Panel"), "", _("Xfce Panel"),
XFCE_COPYRIGHT_TEXT ("2006", "Jasper Huijsmans"),
XFCE_LICENSE_GPL);
xfce_about_info_set_homepage (info, "http://www.xfce.org");
@ -935,16 +947,14 @@ panel_app_about (GtkWidget *panel)
pb = xfce_themed_icon_load ("xfce4-panel", 48);
dlg = xfce_about_dialog_new_with_values (NULL, info, pb);
gtk_window_set_screen (GTK_WINDOW (dlg),
gtk_widget_get_screen (panel));
g_object_unref (G_OBJECT (pb));
gtk_window_set_screen (GTK_WINDOW (dlg), gtk_widget_get_screen (panel));
gtk_widget_set_size_request (dlg, 400, 300);
gtk_dialog_run (GTK_DIALOG (dlg));
gtk_widget_destroy (dlg);
xfce_about_info_free (info);
}

193
panel/panel-config.c

@ -33,6 +33,10 @@
#include <gdk/gdkx.h>
#include <gtk/gtkenums.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <libxfce4util/libxfce4util.h>
#include <libxfce4panel/xfce-panel-macros.h>
#include <libxfce4panel/xfce-panel-convenience.h>
@ -51,7 +55,8 @@
static GPtrArray *config_parse_file (const char *filename);
static gboolean config_save_to_file (GPtrArray *panels, const char *filename);
static gboolean config_save_to_file (GPtrArray *panels,
const char *filename);
/* fallback panel */
@ -60,7 +65,7 @@ static GPtrArray *
create_fallback_panel_array (void)
{
GPtrArray *array;
Panel *panel;
Panel *panel;
DBG ("No suitable panel configuration was found.");
@ -77,36 +82,18 @@ create_fallback_panel_array (void)
return array;
}
/* parsing the config file */
static GPtrArray *
create_panel_array_from_config (const char *file)
{
GPtrArray *array;
array = config_parse_file (file);
if (!array)
array = create_fallback_panel_array ();
return array;
}
/* public API */
GPtrArray *
panel_config_create_panels (void)
{
gboolean use_user_config;
char *file = NULL;
GPtrArray *array = NULL;
const char *path = "xfce4" G_DIR_SEPARATOR_S
"panel" G_DIR_SEPARATOR_S
"panels.xml";
use_user_config = xfce_allow_panel_customization ();
if (G_UNLIKELY (!use_user_config))
if (G_UNLIKELY (!xfce_allow_panel_customization ()))
{
file = g_build_filename (SYSCONFDIR, "xdg", path, NULL);
@ -135,12 +122,14 @@ panel_config_create_panels (void)
}
if (file)
array = create_panel_array_from_config (file);
else
{
array = config_parse_file (file);
g_free (file);
}
if (!array)
array = create_fallback_panel_array ();
g_free (file);
DBG ("Successfully configured %d panel(s).", array->len);
return array;
@ -149,15 +138,12 @@ panel_config_create_panels (void)
gboolean
panel_config_save_panels (GPtrArray * panels)
{
char *file = NULL;
gboolean failed = FALSE;
gboolean use_user_config;
use_user_config = xfce_allow_panel_customization ();
if (use_user_config)
if (xfce_allow_panel_customization ())
{
int i;
int i;
char *file = NULL;
const char *path = "xfce4" G_DIR_SEPARATOR_S
"panel" G_DIR_SEPARATOR_S
"panels.xml";
@ -195,24 +181,23 @@ ParserState;
typedef struct _ConfigParser ConfigParser;
struct _ConfigParser
{
GPtrArray *panels;
Panel *current_panel;
ParserState state;
GPtrArray *panels;
Panel *current_panel;
ParserState state;
gboolean properties_set;
gboolean monitor_set;
gboolean properties_set;
gboolean monitor_set;
/* properties */
int size;
int monitor;
int screen_position;
int full_width;
int xoffset;
int yoffset;
int handle_style;
gboolean autohide;
int transparency;
gboolean activetrans;
int size;
int monitor;
int screen_position;
int full_width;
int xoffset;
int yoffset;
int handle_style;
gboolean autohide;
int transparency;
gboolean activetrans;
};
static void
@ -235,7 +220,8 @@ init_properties (ConfigParser *parser)
static void
config_set_property (ConfigParser *parser,
const char *name, const char *value)
const char *name,
const char *value)
{
g_return_if_fail (name != NULL && value != NULL);
@ -285,17 +271,17 @@ config_set_property (ConfigParser *parser,
}
static void
start_element_handler (GMarkupParseContext * context,
const char *element_name,
const char **attribute_names,
const char **attribute_values,
gpointer user_data,
GError ** error)
start_element_handler (GMarkupParseContext *context,
const char *element_name,
const char **attribute_names,
const char **attribute_values,
gpointer user_data,
GError **error)
{
ConfigParser *parser = user_data;
char *name = NULL;
char *value = NULL;
int i = 0;
char *name = NULL;
char *value = NULL;
int i = 0;
switch (parser->state)
{
@ -305,6 +291,7 @@ start_element_handler (GMarkupParseContext * context,
parser->state = PANELS;
}
break;
case PANELS:
if (strcmp (element_name, "panel") == 0)
{
@ -394,10 +381,10 @@ start_element_handler (GMarkupParseContext * context,
}
static void
end_element_handler (GMarkupParseContext * context,
const char *element_name,
gpointer user_data,
GError ** error)
end_element_handler (GMarkupParseContext *context,
const char *element_name,
gpointer user_data,
GError **error)
{
ConfigParser *parser = user_data;
@ -406,10 +393,12 @@ end_element_handler (GMarkupParseContext * context,
case START:
g_warning ("end unexpected element: \"%s\"", element_name);
break;
case PANELS:
if (strcmp ("panels", element_name) == 0)
parser->state = START;
break;
case PANEL:
if (strcmp ("panel", element_name) == 0)
{
@ -434,18 +423,17 @@ end_element_handler (GMarkupParseContext * context,
parser->monitor = DefaultScreen (GDK_DISPLAY());
}
g_object_set (G_OBJECT (parser->current_panel),
"size", parser->size,
"monitor", parser->monitor,
"size", parser->size,
"monitor", parser->monitor,
"screen-position", parser->screen_position,
"fullwidth", parser->full_width,
"xoffset", parser->xoffset,
"yoffset", parser->yoffset,
"handle-style", parser->handle_style,
"autohide", parser->autohide,
"transparency", parser->transparency,
"activetrans", parser->activetrans,
"fullwidth", parser->full_width,
"xoffset", parser->xoffset,
"yoffset", parser->yoffset,
"handle-style", parser->handle_style,
"autohide", parser->autohide,
"transparency", parser->transparency,
"activetrans", parser->activetrans,
NULL);
}
TIMER_ELAPSED(" ++ end properties");
@ -477,16 +465,16 @@ static GMarkupParser markup_parser = {
static GPtrArray *
config_parse_file (const char *filename)
{
GPtrArray *array = NULL;
char *contents;
GError *error;
GPtrArray *array = NULL;
char *contents;
GError *error;
GMarkupParseContext *context;
ConfigParser parser;
struct stat sb;
size_t bytes;
int fd, rc;
ConfigParser parser;
struct stat sb;
size_t bytes;
int fd, rc;
#ifdef HAVE_MMAP
void *addr;
void *addr;
#endif
g_return_val_if_fail (filename != NULL && strlen (filename) > 0, NULL);
@ -586,9 +574,8 @@ finished:
{
if (munmap (addr, sb.st_size) < 0)
{
g_critical ("Unable to unmap file %s with contents for channel "
"\"%s\": %s. This should not happen!",
filename, channel_name, g_strerror (errno));
g_critical ("Unable to unmap file %s: %s. This should not happen!",
filename, g_strerror (errno));
}
contents = NULL;
@ -617,8 +604,8 @@ gboolean
config_save_to_file (GPtrArray *array, const char *filename)
{
FILE *fp;
char tmp_path[PATH_MAX];
int i;
char tmp_path[PATH_MAX];
int i;
g_return_val_if_fail (array != NULL, FALSE);
g_return_val_if_fail (filename != NULL || (strlen (filename) > 0), FALSE);
@ -642,31 +629,35 @@ config_save_to_file (GPtrArray *array, const char *filename)
for (i = 0; i < array->len; ++i)
{
Panel *panel;
int size, monitor, screen_position, xoffset, yoffset, handle_style,
transparency, fullwidth, j;
gboolean autohide, activetrans;
XfcePanelItemConfig *configlist;
Panel *panel;
int size = 0;
int monitor = 0;
int screen_position = 0;
int fullwidth = 0;
int xoffset = 0;
int yoffset = 0;
int handle_style = 0;
int transparency = 0;
gboolean autohide = FALSE;
gboolean activetrans = FALSE;
int j;
DBG ("Saving panel %d", i + 1);
panel = g_ptr_array_index (array, i);
size = monitor = screen_position = xoffset = yoffset =
transparency = fullwidth = 0;
autohide = activetrans = FALSE;
g_object_get (G_OBJECT (panel),
"size", &size,
"monitor", &monitor,
"size", &size,
"monitor", &monitor,
"screen-position", &screen_position,
"fullwidth", &fullwidth,
"xoffset", &xoffset,
"yoffset", &yoffset,
"handle-style", &handle_style,
"autohide", &autohide,
"transparency", &transparency,
"activetrans", &activetrans,
"fullwidth", &fullwidth,
"xoffset", &xoffset,
"yoffset", &yoffset,
"handle-style", &handle_style,
"transparency", &transparency,
"autohide", &autohide,
"activetrans", &activetrans,
NULL);
/* grouping */

5
panel/panel-dialogs.c

@ -653,9 +653,8 @@ add_items_dialog (GPtrArray *panels, GtkWidget *active_item)
g_ptr_array_foreach (panels, (GFunc)item_dialog_opened, NULL);
gtk_window_stick(GTK_WINDOW (dlg));
/* Note sure why this is set to type UTILITY, but it's causing more bad than good.
gtk_window_set_type_hint (GTK_WINDOW (dlg), GDK_WINDOW_TYPE_HINT_UTILITY);
*/
gtk_widget_realize (dlg);
gdk_x11_window_set_user_time (GTK_WIDGET (dlg)->window,
gdk_x11_get_server_time (GTK_WIDGET (dlg)->window));
xfce_gtk_window_center_on_monitor_with_pointer (GTK_WINDOW (dlg));

406
panel/panel-item-manager.c

@ -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;
}

Loading…
Cancel
Save