Merge branch 'use-libfm'
authorAndriy Grytsenko <andrej@rep.kiev.ua>
Sat, 15 Feb 2014 11:51:29 +0000 (13:51 +0200)
committerAndriy Grytsenko <andrej@rep.kiev.ua>
Sat, 15 Feb 2014 11:51:29 +0000 (13:51 +0200)
Conflicts:
src/plugin.h

1  2 
data/Makefile.am
src/plugin.c
src/plugins/xkb/xkb-plugin.c
src/plugins/xkb/xkb.h
src/private.h

diff --combined data/Makefile.am
@@@ -19,18 -19,16 +19,17 @@@ uidir=$(datadir)/lxpanel/u
  ui_in_files= \
        ui/panel-pref.glade \
        ui/launchbar.glade \
 +      ui/launchtaskbar.glade \
        ui/netstatus.glade
  
  ui_DATA = $(ui_in_files:.glade=.ui)
  
- # Generate GtkBuilder UI files from Glade files
- %.ui: %.glade
-       cp $< $@
-       $(top_builddir)/src/xml-purge $@
+ # Purge GtkBuilder UI files
+ .glade.ui:
+       sed 's/<!--.*-->//' < $< | sed ':a;N;$$!ba;s/ *\n *</</g' > $@
  
  CLEANFILES = \
-         $(ui_DATA)
+       $(ui_DATA)
  
  
  lxpanel_images_DATA = \
diff --combined src/plugin.c
@@@ -1,5 -1,5 +1,5 @@@
  /**
-  * Copyright (c) 2006 LxDE Developers, see the file AUTHORS for details.
+  * Copyright (c) 2006-2014 LxDE Developers, see the file AUTHORS for details.
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
@@@ -20,7 -20,7 +20,7 @@@
  #include "config.h"
  #endif
  
- #include "plugin.h"
+ #include "private.h"
  
  #include <gdk-pixbuf/gdk-pixbuf.h>
  #include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
  #include "bg.h"
  
  #include <glib-object.h>
+ #include <glib/gi18n.h>
+ #include <libfm/fm-gtk.h>
  
  //#define DEBUG
  #include "dbg.h"
  
- static GList * pcl = NULL;                    /* List of PluginClass structures */
  static void register_plugin_class(PluginClass * pc, gboolean dynamic);
  static void init_plugin_class_list(void);
- static PluginClass * plugin_find_class(const char * type);
- static PluginClass * plugin_load_dynamic(const char * type, const gchar * path);
  static void plugin_class_unref(PluginClass * pc);
  
+ GQuark lxpanel_plugin_qdata;
+ static GHashTable *_all_types = NULL;
  /* Dynamic parameter for static (built-in) plugins must be FALSE so we will not try to unload them */
  #define REGISTER_STATIC_PLUGIN_CLASS(pc) \
  do {\
      register_plugin_class(&pc, FALSE);\
  } while (0)
  
+ /* The same for new plugins type - they will be not unloaded by FmModule */
+ #define REGISTER_STATIC_MODULE(pc) do { \
+     extern LXPanelPluginInit lxpanel_static_plugin_##pc; \
+     lxpanel_register_plugin_type(#pc, &lxpanel_static_plugin_##pc); } while (0)
+ static inline LXPanelPluginInit *_find_plugin(const char *name)
+ {
+     return g_hash_table_lookup(_all_types, name);
+ }
+ static void _old_plugin_config(Panel *panel, GtkWidget *instance, GtkWindow *parent)
+ {
+     LXPanelPluginInit *init = PLUGIN_CLASS(instance);
+     Plugin * plugin;
+     g_return_if_fail(init != NULL && init->new_instance == NULL);
+     plugin = lxpanel_plugin_get_data(instance);
+     if (plugin->class->config)
+         plugin->class->config(plugin, parent);
+ }
+ static void _old_plugin_reconfigure(Panel *panel, GtkWidget *instance)
+ {
+     LXPanelPluginInit *init = PLUGIN_CLASS(instance);
+     Plugin * plugin;
+     g_return_if_fail(init != NULL && init->new_instance == NULL);
+     plugin = lxpanel_plugin_get_data(instance);
+     if (plugin->class->panel_configuration_changed)
+         plugin->class->panel_configuration_changed(plugin);
+ }
  /* Register a PluginClass. */
  static void register_plugin_class(PluginClass * pc, gboolean dynamic)
  {
-     pcl = g_list_append(pcl, pc);
+     LXPanelPluginInit *init = g_new0(LXPanelPluginInit, 1);
+     init->_reserved1 = pc;
+     init->name = pc->name;
+     init->description = pc->description;
+     if (pc->config)
+         init->config = _old_plugin_config;
+     if (pc->panel_configuration_changed)
+         init->reconfigure = _old_plugin_reconfigure;
+     init->one_per_system = pc->one_per_system;
+     init->expand_available = pc->expand_available;
+     init->expand_default = pc->expand_default;
      pc->dynamic = dynamic;
+     g_hash_table_insert(_all_types, g_strdup(pc->type), init);
  }
  
  /* Initialize the static plugins. */
  static void init_plugin_class_list(void)
  {
  #ifdef STATIC_SEPARATOR
-     REGISTER_STATIC_PLUGIN_CLASS(separator_plugin_class);
+     REGISTER_STATIC_MODULE(separator);
  #endif
  
  #ifdef STATIC_LAUNCHBAR
-     REGISTER_STATIC_PLUGIN_CLASS(launchbar_plugin_class);
+     REGISTER_STATIC_MODULE(launchbar);
  #endif
  
 +#ifdef STATIC_LAUNCHTASKBAR
 +    REGISTER_STATIC_PLUGIN_CLASS(launchtaskbar_plugin_class);
 +#endif
 +
  #ifdef STATIC_DCLOCK
-     REGISTER_STATIC_PLUGIN_CLASS(dclock_plugin_class);
+     REGISTER_STATIC_MODULE(dclock);
  #endif
  
  #ifdef STATIC_WINCMD
-     REGISTER_STATIC_PLUGIN_CLASS(wincmd_plugin_class);
+     REGISTER_STATIC_MODULE(wincmd);
  #endif
  
  #ifdef STATIC_DIRMENU
-     REGISTER_STATIC_PLUGIN_CLASS(dirmenu_plugin_class);
+     REGISTER_STATIC_MODULE(dirmenu);
  #endif
  
  #ifdef STATIC_TASKBAR
  #endif
  
  #ifdef STATIC_SPACE
-     REGISTER_STATIC_PLUGIN_CLASS(space_plugin_class);
+     REGISTER_STATIC_MODULE(space);
  #endif
  }
  
- /* Look up a plugin class by name. */
- static PluginClass * plugin_find_class(const char * type)
- {
-     GList * tmp;
-     for (tmp = pcl; tmp != NULL; tmp = g_list_next(tmp))
-     {
-         PluginClass * pc = (PluginClass *) tmp->data;
-         if (g_ascii_strcasecmp(type, pc->type) == 0)
-             return pc;
-     }
-     return NULL;
- }
  /* Load a dynamic plugin. */
- static PluginClass * plugin_load_dynamic(const char * type, const gchar * path)
+ static void plugin_load_dynamic(const char * type, const gchar * path)
  {
      PluginClass * pc = NULL;
  
          {
              g_module_close(m);
              ERR("%s.so is not a lxpanel plugin\n", type);
-             return NULL;
+             return;
          }
  
          /* Register the newly loaded and valid plugin. */
          pc->gmodule = m;
          register_plugin_class(pc, TRUE);
+         pc->count = 1;
      }
-     return pc;
- }
- /* Create an instance of a plugin with a specified name, loading it if external. */
- Plugin * plugin_load(char * type)
- {
-     /* Initialize static plugins on first call. */
-     if (pcl == NULL)
-         init_plugin_class_list();
-     /* Look up the PluginClass. */
-     PluginClass * pc = plugin_find_class(type);
- #ifndef DISABLE_PLUGINS_LOADING
-     /* If not found and dynamic loading is available, try to locate an external plugin. */
-     if ((pc == NULL) && (g_module_supported()))
-     {
-         gchar path[PATH_MAX];
-         g_snprintf(path, sizeof(path), PACKAGE_LIB_DIR "/lxpanel/plugins/%s.so", type);
-         pc = plugin_load_dynamic(type, path);
-     }
- #endif  /* DISABLE_PLUGINS_LOADING */
-     /* If not found, return failure. */
-     if (pc == NULL)
-         return NULL;
-     /* Instantiate the plugin */
-     Plugin * plug = g_new0(Plugin, 1);
-     plug->class = pc;
-     pc->count += 1;
-     return plug;
- }
- /* Configure and start a plugin by calling its constructor. */
- int plugin_start(Plugin * pl, char ** fp)
- {
-     /* Call the constructor.
-      * It is responsible for parsing the parameters, and setting "pwid" to the top level widget. */
-     if ( ! pl->class->constructor(pl, fp))
-         return 0;
-     /* If this plugin can only be instantiated once, count the instantiation.
-      * This causes the configuration system to avoid displaying the plugin as one that can be added. */
-     if (pl->class->one_per_system)
-         pl->class->one_per_system_instantiated = TRUE;
-     /* If the plugin has a top level widget, add it to the panel's container. */
-     if (pl->pwid != NULL)
-     {
-         gtk_widget_set_name(pl->pwid, pl->class->type);
-         gtk_box_pack_start(GTK_BOX(pl->panel->box), pl->pwid, pl->expand, TRUE, pl->padding);
-         gtk_container_set_border_width(GTK_CONTAINER(pl->pwid), pl->border);
-         gtk_widget_show(pl->pwid);
-     }
-     return 1;
- }
- /* Unload a plugin if initialization fails. */
- void plugin_unload(Plugin * pl)
- {
-     plugin_class_unref(pl->class);
-     g_free(pl);
- }
- /* Delete a plugin. */
- void plugin_delete(Plugin * pl)
- {
-     Panel * p = pl->panel;
-     PluginClass * pc = pl->class;
-     /* If a plugin configuration dialog is open, close it. */
-     if (p->plugin_pref_dialog != NULL)
-     {
-         gtk_widget_destroy(p->plugin_pref_dialog);
-         p->plugin_pref_dialog = NULL;
-     }
-     /* Run the destructor and then destroy the top level widget.
-      * This prevents problems with the plugin destroying child widgets. */
-     pc->destructor(pl);
-     if (pl->pwid != NULL)
-         gtk_widget_destroy(pl->pwid);
-     /* Data structure bookkeeping. */
-     pc->one_per_system_instantiated = FALSE;
-     plugin_class_unref(pc);
-     /* Free the Plugin structure. */
-     g_free(pl);
  }
  
  /* Unreference a dynamic plugin. */
@@@ -253,29 -191,15 +195,15 @@@ static void plugin_class_unref(PluginCl
      && (pc->dynamic)
      && ( ! pc->not_unloadable))
      {
-         pcl = g_list_remove(pcl, pc);
          g_module_close(pc->gmodule);
      }
  }
  
- /* Get a list of all available plugin classes.
-  * Returns a newly allocated GList which should be freed with plugin_class_list_free(list). */
- GList * plugin_get_available_classes(void)
+ /* Loads all available old type plugins. Should be removed in future releases. */
+ static void plugin_get_available_classes(void)
  {
      /* Initialize static plugins on first call. */
-     if (pcl == NULL)
-         init_plugin_class_list();
-     /* Loop over all classes to formulate the result.
-      * Increase the reference count; it will be decreased in plugin_class_list_free. */
-     GList * classes = NULL;
-     GList * l;
-     for (l = pcl; l != NULL; l = l->next)
-     {
-         PluginClass * pc = (PluginClass *) l->data;
-         classes = g_list_prepend(classes, pc);
-         pc->count += 1;
-     }
+     init_plugin_class_list();
  
  #ifndef DISABLE_PLUGINS_LOADING
      GDir * dir = g_dir_open(PACKAGE_LIB_DIR "/lxpanel/plugins", 0, NULL);
              if (g_str_has_suffix(file, ".so"))
              {
                  char * type = g_strndup(file, strlen(file) - 3);
-                 if (plugin_find_class(type) == NULL)
+                 if (_find_plugin(type) == NULL)
                  {
                      /* If it has not been loaded, do it.  If successful, add it to the result. */
                      char * path = g_build_filename(PACKAGE_LIB_DIR "/lxpanel/plugins", file, NULL );
-                     PluginClass * pc = plugin_load_dynamic(type, path);
-                     if (pc != NULL)
-                     {
-                         pc->count += 1;
-                         classes = g_list_prepend(classes, pc);
-                     }
+                     plugin_load_dynamic(type, path);
                      g_free(path);
                  }
                  g_free(type);
          g_dir_close(dir);
      }
  #endif
-     return classes;
- }
- /* Free the list allocated by plugin_get_available_classes. */
- void plugin_class_list_free(GList * list)
- {
-    g_list_foreach(list, (GFunc) plugin_class_unref, NULL);
-    g_list_free(list);
  }
  
  /* Recursively set the background of all widgets on a panel background configuration change. */
@@@ -359,19 -270,25 +274,25 @@@ void plugin_widget_set_background(GtkWi
  
  /* Handler for "button_press_event" signal with Plugin as parameter.
   * External so can be used from a plugin. */
- gboolean plugin_button_press_event(GtkWidget *widget, GdkEventButton *event, Plugin *plugin)
+ gboolean lxpanel_plugin_button_press_event(GtkWidget *plugin, GdkEventButton *event, Panel *panel)
  {
-     if (event->button == 3)    /* right button */
+     if (event->button == 3) /* right button */
      {
-         GtkMenu* popup = (GtkMenu*) lxpanel_get_panel_menu(plugin->panel, plugin, FALSE);
+         GtkMenu* popup = (GtkMenu*)lxpanel_get_plugin_menu(panel, plugin, FALSE);
          gtk_menu_popup(popup, NULL, NULL, NULL, NULL, event->button, event->time);
          return TRUE;
-     }    
+     }
      return FALSE;
  }
  
+ /* for old plugins compatibility */
+ gboolean plugin_button_press_event(GtkWidget *widget, GdkEventButton *event, Plugin *plugin)
+ {
+     return lxpanel_plugin_button_press_event(plugin->pwid, event, PLUGIN_PANEL(plugin->pwid));
+ }
  /* Helper for position-calculation callback for popup menus. */
- void plugin_popup_set_position_helper(Plugin * p, GtkWidget * near, GtkWidget * popup, GtkRequisition * popup_req, gint * px, gint * py)
+ void lxpanel_plugin_popup_set_position_helper(Panel * p, GtkWidget * near, GtkWidget * popup, GtkRequisition * popup_req, gint * px, gint * py)
  {
      /* Get the origin of the requested-near widget in screen coordinates. */
      gint x, y;
  
      /* Dispatch on edge to lay out the popup menu with respect to the button.
       * Also set "push-in" to avoid any case where it might flow off screen. */
-     switch (p->panel->edge)
+     switch (p->edge)
      {
          case EDGE_TOP:          y += near->allocation.height;         break;
          case EDGE_BOTTOM:       y -= popup_req->height;                break;
      *py = y;
  }
  
+ /* for old plugins compatibility */
+ void plugin_popup_set_position_helper(Plugin * p, GtkWidget * near, GtkWidget * popup, GtkRequisition * popup_req, gint * px, gint * py)
+ {
+     lxpanel_plugin_popup_set_position_helper(p->panel, near, popup, popup_req, px, py);
+ }
  /* Adjust the position of a popup window to ensure that it is not hidden by the panel.
   * It is observed that some window managers do not honor the strut that is set on the panel. */
- void plugin_adjust_popup_position(GtkWidget * popup, Plugin * plugin)
+ void lxpanel_plugin_adjust_popup_position(GtkWidget * popup, GtkWidget * parent)
  {
      /* Initialize. */
-     Panel * p = plugin->panel;
-     GtkWidget * parent = plugin->pwid;
+     Panel * p = PLUGIN_PANEL(parent);
  
      /* Get the coordinates of the plugin top level widget. */
      int x = p->cx + parent->allocation.x;
      /* Move the popup to position. */
      gdk_window_move(popup->window, x, y);
  }
+ /* for old plugins compatibility */
+ void plugin_adjust_popup_position(GtkWidget * popup, Plugin * plugin)
+ {
+     lxpanel_plugin_adjust_popup_position(popup, plugin->pwid);
+ }
+ /* Open a specified path in a file manager. */
+ static gboolean _open_dir_in_file_manager(GAppLaunchContext* ctx, GList* folder_infos,
+                                           gpointer user_data, GError** err)
+ {
+     FmFileInfo *fi = folder_infos->data; /* only first is used */
+     GAppInfo *app = g_app_info_get_default_for_type("inode/directory", TRUE);
+     GFile *gf;
+     gboolean ret;
+     if (app == NULL)
+     {
+         g_set_error_literal(err, G_SHELL_ERROR, G_SHELL_ERROR_EMPTY_STRING,
+                             _("No file manager is configured."));
+         return FALSE;
+     }
+     gf = fm_path_to_gfile(fm_file_info_get_path(fi));
+     folder_infos = g_list_prepend(NULL, gf);
+     ret = fm_app_info_launch(app, folder_infos, ctx, err);
+     g_list_free(folder_infos);
+     g_object_unref(gf);
+     g_object_unref(app);
+     return ret;
+ }
+ gboolean lxpanel_launch_path(Panel *panel, FmPath *path)
+ {
+     return fm_launch_path_simple(NULL, NULL, path, _open_dir_in_file_manager, NULL);
+ }
+ #if GLIB_CHECK_VERSION(2, 32, 0)
+ static GRecMutex _mutex;
+ #else
+ static GStaticRecMutex _mutex = G_STATIC_REC_MUTEX_INIT;
+ #endif
+ #ifndef DISABLE_PLUGINS_LOADING
+ FM_MODULE_DEFINE_TYPE(lxpanel_gtk, LXPanelPluginInit, 1)
+ static gboolean fm_module_callback_lxpanel_gtk(const char *name, gpointer init, int ver)
+ {
+     /* ignore ver for now, only 1 exists */
+     return lxpanel_register_plugin_type(name, init);
+ }
+ #endif
+ static gboolean old_plugins_loaded = FALSE;
+ void _prepare_modules(void)
+ {
+     _all_types = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+     lxpanel_plugin_qdata = g_quark_from_static_string("LXPanel::plugin-data");
+     lxpanel_plugin_qinit = g_quark_from_static_string("LXPanel::plugin-init");
+     lxpanel_plugin_qconf = g_quark_from_static_string("LXPanel::plugin-conf");
+     lxpanel_plugin_qpanel = g_quark_from_static_string("LXPanel::plugin-panel");
+ #ifndef DISABLE_PLUGINS_LOADING
+     fm_modules_add_directory(PACKAGE_LIB_DIR "/lxpanel/plugins");
+     fm_module_register_lxpanel_gtk();
+ #endif
+ }
+ void _unload_modules(void)
+ {
+     GHashTableIter iter;
+     gpointer key, val;
+ #ifndef DISABLE_PLUGINS_LOADING
+     fm_module_unregister_type("lxpanel_gtk");
+ #endif
+     g_hash_table_iter_init(&iter, _all_types);
+     while(g_hash_table_iter_next(&iter, &key, &val))
+     {
+         register LXPanelPluginInit *init = val;
+         if (init->new_instance == NULL) /* old type of plugin */
+         {
+             plugin_class_unref(init->_reserved1);
+             g_free(val);
+         }
+     }
+     g_hash_table_destroy(_all_types);
+     old_plugins_loaded = FALSE;
+ }
+ gboolean lxpanel_register_plugin_type(const char *name, LXPanelPluginInit *init)
+ {
+     LXPanelPluginInit *data;
+     /* validate it */
+     if (init->new_instance == NULL || name == NULL || name[0] == '\0')
+         return FALSE;
+ #if GLIB_CHECK_VERSION(2, 32, 0)
+     g_rec_mutex_lock(&_mutex);
+ #else
+     g_static_rec_mutex_lock(&_mutex);
+ #endif
+     /* test if it's registered already */
+     data = _find_plugin(name);
+     if (data == NULL)
+     {
+         if (init->init)
+             init->init();
+         g_hash_table_insert(_all_types, g_strdup(name), init);
+     }
+ #if GLIB_CHECK_VERSION(2, 32, 0)
+     g_rec_mutex_unlock(&_mutex);
+ #else
+     g_static_rec_mutex_unlock(&_mutex);
+ #endif
+     return (data == NULL);
+ }
+ static void _old_plugin_save_hook(const config_setting_t * setting, FILE * f, gpointer user_data)
+ {
+     Plugin *pl = user_data;
+     PluginClass *pc = pl->class;
+     if (pc->save)
+         pc->save(pl, f);
+ }
+ /* This is called right before Plugin instance is destroyed */
+ static void _old_plugin_destroy(gpointer data)
+ {
+     Plugin *pl = data;
+     /* Run the destructor. */
+     pl->class->destructor(pl);
+     plugin_class_unref(pl->class);
+     /* Free the Plugin structure. */
+     g_free(pl);
+ }
+ //static void on_size_allocate(GtkWidget *widget, GdkRectangle *allocation, Panel *p)
+ //{
+ //    _queue_panel_calculate_size(p);
+ //}
+ GtkWidget *lxpanel_add_plugin(Panel *p, const char *name, config_setting_t *cfg, gint at)
+ {
+     LXPanelPluginInit *init;
+     GtkWidget *widget;
+     config_setting_t *s, *pconf;
+     gint expand, padding = 0, border = 0, i;
+     CHECK_MODULES();
+     if (!old_plugins_loaded)
+         plugin_get_available_classes();
+     old_plugins_loaded = TRUE;
+     init = _find_plugin(name);
+     if (init == NULL)
+         return NULL;
+     /* prepare widget settings */
+     if (!init->expand_available)
+         expand = 0;
+     else if ((s = config_setting_get_member(cfg, "expand")))
+         expand = config_setting_get_int(s);
+     else
+         expand = init->expand_default;
+     s = config_setting_get_member(cfg, "padding");
+     if (s)
+         padding = config_setting_get_int(s);
+     s = config_setting_get_member(cfg, "border");
+     if (s)
+         border = config_setting_get_int(s);
+     /* prepare config and create it if need */
+     s = config_setting_add(cfg, "", PANEL_CONF_TYPE_LIST);
+     for (i = 0; (pconf = config_setting_get_elem(s, i)); i++)
+         if (strcmp(config_setting_get_name(pconf), "Config") == 0)
+             break;
+     if (!pconf)
+         pconf = config_setting_add(s, "Config", PANEL_CONF_TYPE_GROUP);
+     /* If this plugin can only be instantiated once, count the instantiation.
+      * This causes the configuration system to avoid displaying the plugin as one that can be added. */
+     if (init->new_instance) /* new style of plugin */
+     {
+         widget = init->new_instance(p, pconf);
+         if (widget == NULL)
+             return widget;
+         if (init->button_press_event)
+             g_signal_connect(widget, "button-press-event",
+                              G_CALLBACK(init->button_press_event), p);
+         else
+             g_signal_connect(widget, "button-press-event",
+                              G_CALLBACK(lxpanel_plugin_button_press_event), p);
+     }
+     else
+     {
+         Plugin *pl = g_new0(Plugin, 1);
+         PluginClass *pc = init->_reserved1;
+         char *conf = config_setting_to_string(pconf), *fp;
+         pl->class = pc;
+         pl->panel = p;
+         widget = NULL;
+         fp = &conf[9]; /* skip "Config {\n" */
+         /* g_debug("created conf: %s",conf); */
+     /* Call the constructor.
+      * It is responsible for parsing the parameters, and setting "pwid" to the top level widget. */
+         if (pc->constructor(pl, &fp))
+             widget = pl->pwid;
+         g_free(conf);
+         if (widget == NULL) /* failed */
+         {
+             g_free(pl);
+             return widget;
+         }
+         pc->count += 1;
+         config_setting_set_save_hook(pconf, _old_plugin_save_hook, pl);
+         lxpanel_plugin_set_data(widget, pl, _old_plugin_destroy);
+     }
+     gtk_widget_set_name(widget, init->name);
+     gtk_box_pack_start(GTK_BOX(p->box), widget, expand, TRUE, padding);
+     gtk_container_set_border_width(GTK_CONTAINER(widget), border);
+ //    g_signal_connect(widget, "size-allocate", G_CALLBACK(on_size_allocate), p);
+     gtk_widget_show(widget);
+     g_object_set_qdata(G_OBJECT(widget), lxpanel_plugin_qconf, cfg);
+     g_object_set_qdata(G_OBJECT(widget), lxpanel_plugin_qinit, init);
+     g_object_set_qdata(G_OBJECT(widget), lxpanel_plugin_qpanel, p);
+     return widget;
+ }
+ /* transfer none - note that not all fields are valid there */
+ GHashTable *lxpanel_get_all_types(void)
+ {
+     return _all_types;
+ }
@@@ -51,22 -51,18 +51,20 @@@ enu
  
  enum
  {
 -    COLUMN_MODEL_NAME,
 +    COLUMN_MODEL_ID,
      COLUMN_MODEL_DESC,
      NUM_MODEL_COLUMNS
  };
  
  enum
  {
 -    COLUMN_CHANGE_NAME,
 +    COLUMN_CHANGE_ID,
      COLUMN_CHANGE_DESC,
 +    COLUMN_CHANGE_INCL,
 +    COLUMN_CHANGE_WEIGHT,
      NUM_CHANGE_COLUMNS
  };
  
- void panel_config_save(Panel * panel);   /* defined in configurator.c */
  static int   xkb_constructor(Plugin * p_plugin, char ** fp);
  static void  xkb_destructor(Plugin * p_plugin);
  static void  xkb_configure(Plugin * p, GtkWindow * parent);
@@@ -346,7 -342,7 +344,7 @@@ static int xkb_constructor(Plugin * p_p
          p_xkb->kbd_layouts = g_strdup(symbol_name_lowercase);
          g_free(symbol_name_lowercase);
          p_xkb->kbd_variants = g_strdup(",");
 -        p_xkb->kbd_change_option = g_strdup("shift_caps_toggle");
 +        p_xkb->kbd_change_option = g_strdup("grp:shift_caps_toggle");
          
          xkb_mechanism_destructor(p_xkb);
      }
@@@ -568,30 -564,6 +566,30 @@@ static void on_dialog_config_response(G
      p_xkb->p_dialog_config = NULL;
  }
  
 +static void  on_cell_renderer_layout_change_incl_toggled(GtkCellRendererToggle *cell,
 +                                                        gchar                 *path_str,
 +                                                        gpointer               data)
 +{
 +    GtkTreeModel *p_model = (GtkTreeModel *)data;
 +    GtkTreeIter  tree_iter;
 +    GtkTreePath *p_tree_path = gtk_tree_path_new_from_string(path_str);
 +    gboolean     included;
 +    
 +    /* get toggled iter */
 +    gtk_tree_model_get_iter(p_model, &tree_iter, p_tree_path);
 +    gtk_tree_model_get(p_model, &tree_iter, COLUMN_CHANGE_INCL, &included, -1);
 +    
 +    /* do something with the value */
 +    included = !included;
 +    
 +    /* set new value */
 +    gtk_list_store_set(GTK_LIST_STORE(p_model), &tree_iter, COLUMN_CHANGE_INCL, included, -1);
 +    gtk_list_store_set(GTK_LIST_STORE(p_model), &tree_iter, COLUMN_CHANGE_WEIGHT, included ? PANGO_WEIGHT_ULTRAHEAVY : PANGO_WEIGHT_NORMAL, -1);
 +    
 +    /* clean up */
 +    gtk_tree_path_free(p_tree_path);
 +}
 +
  static gboolean  on_treeviews_lists_button_press_event(GtkWidget *p_widget,
                                                         GdkEventButton *p_event,
                                                         gpointer p_data)
@@@ -648,18 -620,17 +646,18 @@@ static void on_button_kbd_model_clicked
      gtk_container_add(GTK_CONTAINER(p_scrolledwindow_kbd_model), p_treeview_kbd_model);
      GtkCellRenderer *p_renderer;
      GtkTreeViewColumn *p_column;
 -    // model
 +    // model desc
      p_renderer = gtk_cell_renderer_text_new();
 -    p_column = gtk_tree_view_column_new_with_attributes(_("Model"), p_renderer, "text", COLUMN_CHANGE_NAME, NULL);
 -    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_CHANGE_NAME);
 +    p_column = gtk_tree_view_column_new_with_attributes(_("Description"), p_renderer, "text", COLUMN_MODEL_DESC, NULL);
 +    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_MODEL_DESC);
      gtk_tree_view_append_column(GTK_TREE_VIEW(p_treeview_kbd_model), p_column);
 -    // desc
 +    // model id
      p_renderer = gtk_cell_renderer_text_new();
 -    p_column = gtk_tree_view_column_new_with_attributes(_("Description"), p_renderer, "text", COLUMN_CHANGE_DESC, NULL);
 -    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_CHANGE_DESC);
 +    p_column = gtk_tree_view_column_new_with_attributes(_("Id"), p_renderer, "text", COLUMN_MODEL_ID, NULL);
 +    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_MODEL_ID);
      gtk_tree_view_append_column(GTK_TREE_VIEW(p_treeview_kbd_model), p_column);
      
 +    
      // populate model
      GKeyFile *p_keyfile = g_key_file_new();
      gchar *xkbcfg_filepath = g_strdup_printf("%s/models.cfg", XKBCONFDIR);
              p_model_desc = g_key_file_get_string(p_keyfile, "MODELS", keys_models[model_idx], NULL);
              gtk_list_store_append(p_liststore_kbd_model, &tree_iter);
              gtk_list_store_set(p_liststore_kbd_model, &tree_iter,
 -                                COLUMN_MODEL_NAME, keys_models[model_idx],
 +                                COLUMN_MODEL_ID, keys_models[model_idx],
                                  COLUMN_MODEL_DESC, p_model_desc,
                                  -1);
              g_free(p_model_desc);
          {
              gchar *kbd_model_new;
              gtk_tree_model_get(GTK_TREE_MODEL(p_liststore_kbd_model),
 -                               &tree_iter_sel, COLUMN_MODEL_NAME, &kbd_model_new, -1);
 +                               &tree_iter_sel, COLUMN_MODEL_ID, &kbd_model_new, -1);
              g_free(p_xkb->kbd_model);
              p_xkb->kbd_model = g_strdup(kbd_model_new);
              gtk_button_set_label(GTK_BUTTON(p_xkb->p_button_kbd_model), p_xkb->kbd_model);
      gtk_widget_destroy(p_dialog);
  }
  
 +static gboolean  change_opt_tree_model_foreach(GtkTreeModel *p_model,
 +                                               GtkTreePath *p_path,
 +                                               GtkTreeIter *p_iter,
 +                                               gpointer p_data)
 +{
 +    XkbPlugin *p_xkb = (XkbPlugin *)p_data;
 +    
 +    gboolean  included;
 +    
 +    gtk_tree_model_get(p_model, p_iter, COLUMN_CHANGE_INCL, &included,  -1);
 +    if(included)
 +    {
 +        gchar  *change_opt_id;
 +        gtk_tree_model_get(p_model, p_iter, COLUMN_CHANGE_ID, &change_opt_id,  -1);
 +        if(strlen(p_xkb->p_gstring_change_opt_partial->str))
 +        {
 +            g_string_append_c(p_xkb->p_gstring_change_opt_partial, ',');
 +        }
 +        g_string_append(p_xkb->p_gstring_change_opt_partial, change_opt_id);
 +        
 +        //g_printf("\npartial change opt = '%s'\n", p_xkb->p_gstring_change_opt_partial->str);
 +        
 +        g_free(change_opt_id);
 +    }
 +    return FALSE;
 +}
 +
  static void on_button_kbd_change_layout_clicked(GtkButton *p_button, gpointer *p_data)
  {
      XkbPlugin *p_xkb = (XkbPlugin *)p_data;
      gtk_box_pack_start(GTK_BOX(GTK_DIALOG(p_dialog)->vbox), p_scrolledwindow_kbd_change, TRUE, TRUE, 2);
      
      // liststore
 -    GtkListStore *p_liststore_kbd_change = gtk_list_store_new(NUM_CHANGE_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
 +    GtkListStore *p_liststore_kbd_change = gtk_list_store_new(NUM_CHANGE_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT);
      GtkWidget *p_treeview_kbd_change = gtk_tree_view_new_with_model(GTK_TREE_MODEL(p_liststore_kbd_change));
      g_object_unref(G_OBJECT(p_liststore_kbd_change));
      gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(p_treeview_kbd_change), TRUE);
      gtk_container_add(GTK_CONTAINER(p_scrolledwindow_kbd_change), p_treeview_kbd_change);
      GtkCellRenderer *p_renderer;
      GtkTreeViewColumn *p_column;
 -    // model
 +    // change included
 +    p_renderer = gtk_cell_renderer_toggle_new();
 +    g_signal_connect(p_renderer, "toggled", G_CALLBACK(on_cell_renderer_layout_change_incl_toggled), p_liststore_kbd_change);
 +    p_column = gtk_tree_view_column_new_with_attributes("", p_renderer, "active", COLUMN_CHANGE_INCL, NULL);
 +    gtk_tree_view_append_column(GTK_TREE_VIEW(p_treeview_kbd_change), p_column);
 +    // change desc
      p_renderer = gtk_cell_renderer_text_new();
 -    p_column = gtk_tree_view_column_new_with_attributes(_("Change Type"), p_renderer, "text", COLUMN_CHANGE_NAME, NULL);
 +    p_column = gtk_tree_view_column_new_with_attributes(_("Description"), p_renderer, "text", COLUMN_CHANGE_DESC,
 +                                                                                      "weight", COLUMN_CHANGE_WEIGHT,
 +                                                                                      NULL);
 +    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_CHANGE_DESC);
      gtk_tree_view_append_column(GTK_TREE_VIEW(p_treeview_kbd_change), p_column);
 -    // desc
 +    // change id
      p_renderer = gtk_cell_renderer_text_new();
 -    p_column = gtk_tree_view_column_new_with_attributes(_("Description"), p_renderer, "text", COLUMN_CHANGE_DESC, NULL);
 +    p_column = gtk_tree_view_column_new_with_attributes(_("Id"), p_renderer, "text", COLUMN_CHANGE_ID,
 +                                                                             "weight", COLUMN_CHANGE_WEIGHT,
 +                                                                             NULL);
 +    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_CHANGE_ID);
      gtk_tree_view_append_column(GTK_TREE_VIEW(p_treeview_kbd_change), p_column);
      
      // populate model
      gchar *xkbcfg_filepath = g_strdup_printf("%s/toggle.cfg", XKBCONFDIR);
      if(g_key_file_load_from_file(p_keyfile, xkbcfg_filepath, 0, NULL))
      {
 +        char **change_opts = g_strsplit_set(p_xkb->kbd_change_option, ",", 0);
 +        int    num_change_opts;
          gchar **keys_changes = g_key_file_get_keys(p_keyfile, "TOGGLE", NULL, NULL);
          guint   change_idx = 0;
          GtkTreeIter  tree_iter;
          {
              p_change_desc = g_key_file_get_string(p_keyfile, "TOGGLE", keys_changes[change_idx], NULL);
              gtk_list_store_append(p_liststore_kbd_change, &tree_iter);
 +            gboolean  included = FALSE;
 +            num_change_opts = 0;
 +            while(change_opts[num_change_opts] != NULL)
 +            {
 +                if(strcmp(change_opts[num_change_opts], keys_changes[change_idx]) == 0)
 +                {
 +                    included = TRUE;
 +                    break;
 +                }
 +                num_change_opts++;
 +            }
              gtk_list_store_set(p_liststore_kbd_change, &tree_iter,
 -                                COLUMN_CHANGE_NAME, keys_changes[change_idx],
 +                                COLUMN_CHANGE_ID, keys_changes[change_idx],
                                  COLUMN_CHANGE_DESC, p_change_desc,
 +                                COLUMN_CHANGE_INCL, included,
 +                                COLUMN_CHANGE_WEIGHT, included ? PANGO_WEIGHT_ULTRAHEAVY : PANGO_WEIGHT_NORMAL,
                                  -1);
              g_free(p_change_desc);
              change_idx++;
          }
          g_strfreev(keys_changes);
          g_key_file_free(p_keyfile);
 +        g_strfreev(change_opts);
      }
      g_free(xkbcfg_filepath);
      
      // callback for double click
 -    g_signal_connect(p_treeview_kbd_change, "button-press-event",
 -                     G_CALLBACK(on_treeviews_lists_button_press_event),
 -                     gtk_dialog_get_widget_for_response(GTK_DIALOG(p_dialog), GTK_RESPONSE_OK));
 +    //g_signal_connect(p_treeview_kbd_change, "button-press-event",
 +                     //G_CALLBACK(on_treeviews_lists_button_press_event),
 +                     //gtk_dialog_get_widget_for_response(GTK_DIALOG(p_dialog), GTK_RESPONSE_OK));
      gtk_widget_set_size_request(p_dialog, 700, 500);
      gtk_widget_show_all(GTK_WIDGET(p_scrolledwindow_kbd_change));
      gint  response = gtk_dialog_run(GTK_DIALOG(p_dialog));
      if(response == GTK_RESPONSE_OK)
      {
 -        GtkTreeIter  tree_iter_sel;
 -        GtkTreeSelection *p_treeselection_kbd_change = gtk_tree_view_get_selection(GTK_TREE_VIEW(p_treeview_kbd_change));
 -        if(gtk_tree_selection_get_selected(p_treeselection_kbd_change,
 -                                           (GtkTreeModel **)(&p_liststore_kbd_change),
 -                                           &tree_iter_sel))
 +        p_xkb->p_gstring_change_opt_partial = g_string_new("");
 +        gtk_tree_model_foreach(GTK_TREE_MODEL(p_liststore_kbd_change),
 +                               change_opt_tree_model_foreach,
 +                               p_xkb);
 +        if(!strlen(p_xkb->p_gstring_change_opt_partial->str))
          {
 -            gchar *kbd_change_new;
 -            gtk_tree_model_get(GTK_TREE_MODEL(p_liststore_kbd_change),
 -                               &tree_iter_sel, COLUMN_CHANGE_NAME, &kbd_change_new, -1);
 -            g_free(p_xkb->kbd_change_option);
 -            p_xkb->kbd_change_option = g_strdup(kbd_change_new);
 -            gtk_button_set_label(GTK_BUTTON(p_xkb->p_button_change_layout), p_xkb->kbd_change_option);
 -            g_free(kbd_change_new);
 -            xkb_setxkbmap(p_xkb);
 -            xkb_redraw(p_xkb);
 +            g_string_append_c(p_xkb->p_gstring_change_opt_partial, ',');
          }
 +        g_free(p_xkb->kbd_change_option);
 +        p_xkb->kbd_change_option = g_strdup(p_xkb->p_gstring_change_opt_partial->str);
 +        g_string_free(p_xkb->p_gstring_change_opt_partial, TRUE/*free also gstring->str*/);
 +        
 +        gtk_button_set_label(GTK_BUTTON(p_xkb->p_button_change_layout), p_xkb->kbd_change_option);
 +        xkb_setxkbmap(p_xkb);
 +        xkb_redraw(p_xkb);
      }
      gtk_widget_destroy(p_dialog);
  }
@@@ -1093,7 -1011,7 +1091,7 @@@ void xkb_setxkbmap(XkbPlugin *p_xkb
      
      GString *p_gstring_syscmd = g_string_new("");
      g_string_printf(p_gstring_syscmd,
 -                    "setxkbmap -model %s -layout %s -variant %s -option grp:%s",
 +                    "setxkbmap -model %s -layout %s -variant %s -option %s",
                      p_xkb->kbd_model, p_xkb->kbd_layouts, p_xkb->kbd_variants,
                      p_xkb->kbd_change_option);
      if( (p_xkb->kbd_advanced_options != NULL) && strlen(p_xkb->kbd_advanced_options) )
      g_string_free(p_gstring_syscmd, TRUE/*free also gstring->str*/);
  }
  
 -static gboolean layouts_tree_model_foreach(GtkTreeModel *p_model,
 -                                           GtkTreePath *p_path,
 -                                           GtkTreeIter *p_iter,
 -                                           gpointer p_data)
 +static gboolean  layouts_tree_model_foreach(GtkTreeModel *p_model,
 +                                            GtkTreePath *p_path,
 +                                            GtkTreeIter *p_iter,
 +                                            gpointer p_data)
  {
      XkbPlugin *p_xkb = (XkbPlugin *)p_data;
      gchar *layout_val;
diff --combined src/plugins/xkb/xkb.h
@@@ -24,7 -24,7 +24,7 @@@
  #include <gtk/gtk.h>
  #include <glib.h>
  
- #include "plugin.h"
+ #include "private.h"
  #include "misc.h"
  #include "panel.h"
  #include "ev.h"
@@@ -74,7 -74,6 +74,7 @@@ typedef struct 
      guchar    flag_size;
      GString  *p_gstring_layouts_partial;
      GString  *p_gstring_variants_partial;
 +    GString  *p_gstring_change_opt_partial;
      int       num_layouts;
      gboolean  cust_dir_exists;
  
diff --combined src/private.h
index 0000000,6c2bd33..b7a44af
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,325 +1,326 @@@
+ /**
+  * Copyright (c) 2006 LxDE Developers, see the file AUTHORS for details.
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License as published by
+  * the Free Software Foundation; either version 2 of the License, or
+  * (at your option) any later version.
+  *
+  * This program is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU General Public License for more details.
+  *
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+  */
+ #ifndef PRIVATE_H
+ #define PRIVATE_H
+ #include "plugin.h"
+ #include "conf.h"
+ #include <gmodule.h>
+ #include <gtk/gtk.h>
+ #include <gdk/gdk.h>
+ #include <stdio.h>
+ #include "panel.h"
+ #include <gdk/gdk.h>
+ #include "bg.h"
+ #include "ev.h"
+ /* -----------------------------------------------------------------------------
+  *   Definitions used by lxpanel main code internally */
+ /* Extracted from panel.h */
+ enum { ALLIGN_NONE, ALLIGN_LEFT, ALLIGN_CENTER, ALLIGN_RIGHT  };
+ enum { EDGE_NONE=0, EDGE_LEFT, EDGE_RIGHT, EDGE_TOP, EDGE_BOTTOM };
+ enum { WIDTH_NONE, WIDTH_REQUEST, WIDTH_PIXEL, WIDTH_PERCENT };
+ enum { HEIGHT_NONE, HEIGHT_PIXEL, HEIGHT_REQUEST };
+ #define PANEL_ICON_SIZE               24      /* Default size of panel icons */
+ #define PANEL_HEIGHT_DEFAULT          26      /* Default height of horizontal panel */
+ #define PANEL_WIDTH_DEFAULT           150     /* Default "height" of vertical panel */
+ #define PANEL_HEIGHT_MAX              200     /* Maximum height of panel */
+ #define PANEL_HEIGHT_MIN              16      /* Minimum height of panel */
+ #define PANEL_ICON_HIGHLIGHT          0x202020        /* Constant to pass to icon loader */
+ /* to check if we are in LXDE */
+ extern gboolean is_in_lxde;
+ /* Context of a panel on a given edge. */
+ struct _Panel {
+     char* name;
+     GtkWidget * topgwin;              /* Main panel window */
+     Window topxwin;                   /* Main panel's X window   */
+     GdkDisplay * display;             /* Main panel's GdkDisplay */
+     GtkStyle * defstyle;
+     GtkIconTheme* icon_theme; /*Default icon theme*/
+     GtkWidget * box;                  /* Top level widget */
+     GtkRequisition requisition;
+     GtkWidget *(*my_box_new) (gboolean, gint);
+     GtkWidget *(*my_separator_new) ();
+     FbBg *bg;
+     int alpha;
+     guint32 tintcolor;
+     guint32 fontcolor;
+     GdkColor gtintcolor;
+     GdkColor gfontcolor;
+     int ax, ay, aw, ah;  /* prefferd allocation of a panel */
+     int cx, cy, cw, ch;  /* current allocation (as reported by configure event) allocation */
+     int allign, edge, margin;
+     guint orientation;
+     int widthtype, width;
+     int heighttype, height;
+     gint monitor;
+     gulong strut_size;                        /* Values for WM_STRUT_PARTIAL */
+     gulong strut_lower;
+     gulong strut_upper;
+     int strut_edge;
+     guint config_changed : 1;
+     guint self_destroy : 1;
+     guint setdocktype : 1;
+     guint setstrut : 1;
+     guint round_corners : 1;
+     guint usefontcolor : 1;
+     guint usefontsize : 1;
+     guint fontsize;    
+     guint transparent : 1;
+     guint background : 1;
+     guint spacing;
+     guint autohide : 1;
+     guint visible : 1;
+     int height_when_hidden;
+     guint hide_timeout;
+     int icon_size;                    /* Icon size */
+     int desknum;
+     int curdesk;
+     guint32 *workarea;
+     int wa_len;
+     char* background_file;
+     PanelConf * config;                 /* Panel configuration data */
+     GSList * system_menus;            /* List of plugins having menus */
+     GtkWidget* plugin_pref_dialog;    /* Plugin preference dialog */
+     GtkWidget* pref_dialog;           /* preference dialog */
+     GtkWidget* margin_control;                /* Margin control in preference dialog */
+     GtkWidget* height_label;          /* Label of height control */
+     GtkWidget* width_label;           /* Label of width control */
+     GtkWidget* alignment_left_label;  /* Label of alignment: left control */
+     GtkWidget* alignment_right_label; /* Label of alignment: right control */
+     GtkWidget* height_control;                /* Height control in preference dialog */
+     GtkWidget* width_control;         /* Width control in preference dialog */
+     //gint dyn_space;                     /* Space for expandable plugins */
+     //guint calculate_size_idle;          /* The idle handler for dyn_space calc */
+ };
+ typedef struct {
+     char *name;
+     char *disp_name;
+     void (*cmd)(void);
+ } Command;
+ extern Command commands[];
+ extern FbEv *fbev;
+ #define FBPANEL_WIN(win)  gdk_window_lookup(win)
+ /* Extracted from misc.h */
+ typedef struct {
+     int num;
+     gchar *str;
+ } pair;
+ extern pair allign_pair[];
+ extern pair edge_pair[];
+ extern pair width_pair[];
+ extern pair height_pair[];
+ extern pair bool_pair[];
+ int str2num(pair *p, const gchar *str, int defval);
+ const gchar *num2str(pair *p, int num, const gchar *defval);
+ char* get_config_file( const char* profile, const char* file_name, gboolean is_global );
+ //void _queue_panel_calculate_size(Panel *panel);
+ /* FIXME: optional definitions */
+ #define STATIC_SEPARATOR
+ #define STATIC_LAUNCHBAR
++#define STATIC_LAUNCHTASKBAR
+ #define STATIC_DCLOCK
+ #define STATIC_WINCMD
+ #define STATIC_DIRMENU
+ #define STATIC_TASKBAR
+ #define STATIC_PAGER
+ #define STATIC_TRAY
+ #define STATIC_MENU
+ #define STATIC_SPACE
+ #define STATIC_ICONS
+ /* Plugins management - new style */
+ void _prepare_modules(void);
+ void _unload_modules(void);
+ GtkWidget *lxpanel_add_plugin(Panel *p, const char *name, config_setting_t *cfg, gint at);
+ GHashTable *lxpanel_get_all_types(void); /* transfer none */
+ GQuark lxpanel_plugin_qinit; /* access to LXPanelPluginInit data */
+ #define PLUGIN_CLASS(_i) ((LXPanelPluginInit*)g_object_get_qdata(G_OBJECT(_i),lxpanel_plugin_qinit))
+ GQuark lxpanel_plugin_qconf; /* access to congig_setting_t data */
+ GQuark lxpanel_plugin_qpanel; /* access to Panel */
+ #define PLUGIN_PANEL(_i) ((Panel*)g_object_get_qdata(G_OBJECT(_i),lxpanel_plugin_qpanel))
+ gboolean _class_is_present(LXPanelPluginInit *init);
+ /* -----------------------------------------------------------------------------
+  *   Deprecated declarations. Kept for compatibility with old code plugins.
+  *   Should be removed and appropriate code cleaned on some of next releases. */
+ /* Extracted from panel.h */
+ extern int verbose;
+ /* if current window manager is EWMH conforming. */
+ extern gboolean is_ewmh_supported;
+ /*
+  This function is used to re-create a new box with different
+  orientation from the old one, add all children of the old one to
+  the new one, and then destroy the old box.
+  It's mainly used when we need to change the orientation of the panel or
+  any plugin with a layout box. Since GtkHBox cannot be changed to GtkVBox,
+  recreating a new box to replace the old one is required.
+ */
+ GtkWidget* recreate_box( GtkBox* oldbox, GtkOrientation orientation );
+ extern const char* lxpanel_get_file_manager();
+ /* Extracted from misc.h */
+ typedef struct _Plugin Plugin;
+ enum { LINE_NONE, LINE_BLOCK_START, LINE_BLOCK_END, LINE_VAR };
+ typedef struct {
+     int num, len, type;
+     gchar str[256];
+     gchar *t[3];
+ } line;
+ extern int lxpanel_get_line(char **fp, line *s);
+ extern int lxpanel_put_line(FILE* fp, const char* format, ...);
+ #define lxpanel_put_str(fp, name, val) (G_UNLIKELY( !(val) || !*(val) )) ? 0 : lxpanel_put_line(fp, "%s=%s", name, val)
+ #define lxpanel_put_bool(fp, name, val) lxpanel_put_line(fp, "%s=%c", name, (val) ? '1' : '0')
+ #define lxpanel_put_int(fp, name, val) lxpanel_put_line(fp, "%s=%d", name, val)
+ GtkWidget *_gtk_image_new_from_file_scaled(const gchar *file, gint width,
+                                            gint height, gboolean keep_ratio);
+ GtkWidget * fb_button_new_from_file(
+     const gchar * image_file, int width, int height, gulong highlight_color, gboolean keep_ratio);
+ GtkWidget * fb_button_new_from_file_with_label(
+     const gchar * image_file, int width, int height, gulong highlight_color, gboolean keep_ratio, Panel * panel, gchar * label);
+ void fb_button_set_from_file(GtkWidget* btn, const char* img_file, gint width, gint height, gboolean keep_ratio);
+ char* translate_exec_to_cmd( const char* exec, const char* icon,
+                              const char* title, const char* fpath );
+ void show_error( GtkWindow* parent_win, const char* msg );
+ gboolean spawn_command_async(GtkWindow *parent_window, gchar const* workdir,
+         gchar const* cmd);
+ /* Parameters: const char* name, gpointer ret_value, GType type, ....NULL */
+ GtkWidget* create_generic_config_dlg( const char* title, GtkWidget* parent,
+                               GSourceFunc apply_func, Plugin * plugin,
+                       const char* name, ... );
+ extern GtkMenu* lxpanel_get_panel_menu( Panel* panel, Plugin* plugin, gboolean use_sub_menu );
+ gboolean lxpanel_launch_app(const char* exec, GList* files, gboolean in_terminal, char const* in_workdir);
+ extern GdkPixbuf* lxpanel_load_icon( const char* name, int width, int height, gboolean use_fallback );
+ /* Extracted from plugin.h */
+ struct _Plugin;
+ /* Support for external plugin versioning.
+  * Plugins must invoke PLUGINCLASS_VERSIONING when they instantiate PluginClass. */
+ #define PLUGINCLASS_VERSION 1
+ #define PLUGINCLASS_VERSIONING \
+     .structure_size = sizeof(PluginClass), \
+     .structure_version = PLUGINCLASS_VERSION
+ /* Representative of an available plugin. */
+ typedef struct {
+     /* Keep these first.  Do not make unnecessary changes in structure layout. */
+     unsigned short structure_size;            /* Structure size, for versioning support */
+     unsigned short structure_version;         /* Structure version, for versioning support */
+     char * fname;                             /* Plugin file pathname */
+     int count;                                        /* Reference count */
+     GModule * gmodule;                                /* Associated GModule structure */
+     int dynamic : 1;                          /* True if dynamically loaded */
+     int unused_invisible : 1;                 /* Unused; reserved bit */
+     int not_unloadable : 1;                   /* Not unloadable due to GModule restriction */
+     int one_per_system : 1;                   /* Special: only one possible per system, such as system tray */
+     int one_per_system_instantiated : 1;      /* True if one instance exists */
+     int expand_available : 1;                 /* True if "stretch" option is available */
+     int expand_default : 1;                   /* True if "stretch" option is default */
+     /* These fields point within the plugin image. */
+     char * type;                              /* Internal name of plugin, to match external filename */
+     char * name;                              /* Display name of plugin for selection UI */
+     char * version;                           /* Version of plugin */
+     char * description;                               /* Brief textual description of plugin for selection UI */
+     int (*constructor)(struct _Plugin * plugin, char ** fp);          /* Create an instance of the plugin */
+     void (*destructor)(struct _Plugin * plugin);                      /* Destroy an instance of the plugin */
+     void (*config)(struct _Plugin * plugin, GtkWindow * parent);      /* Request the plugin to display its configuration dialog */
+     void (*save)(struct _Plugin * plugin, FILE * fp);                 /* Request the plugin to save its configuration to a file */
+     void (*panel_configuration_changed)(struct _Plugin * plugin);     /* Request the plugin to do a full redraw after a panel configuration change */
+ } PluginClass;
+ /* Representative of a loaded and active plugin attached to a panel. */
+ struct _Plugin {
+     PluginClass * class;                      /* Back pointer to PluginClass */
+     Panel * panel;                            /* Back pointer to Panel */
+     GtkWidget * pwid;                         /* Top level widget; plugin allocates, but plugin mechanism, not plugin itself, destroys this */
+     int expand;                                       /* Expand ("stretch") setting for container */
+     int padding;                              /* Padding setting for container */
+     int border;                                       /* Border setting for container */
+     gpointer priv;                            /* Private context for plugin; plugin frees this in its destructor */
+ };
+ /* Plugins management - deprecated style, for backward compatibility */
+ extern gboolean plugin_button_press_event(GtkWidget *widget, GdkEventButton *event, Plugin *plugin);
+                                                         /* Handler for "button_press_event" signal with Plugin as parameter */
+ extern void plugin_adjust_popup_position(GtkWidget * popup, Plugin * plugin);
+                                                       /* Helper to move popup windows away from the panel */
+ extern void plugin_popup_set_position_helper(Plugin * p, GtkWidget * near, GtkWidget * popup, GtkRequisition * popup_req, gint * px, gint * py);
+                                                       /* Helper for position-calculation callback for popup menus */
+ #endif