1 /* 2 * Copyright (C) 2006-2008 Hong Jen Yee (PCMan) <pcman.tw@gmail.com> 3 * 2006-2008 Jim Huang <jserv.tw@gmail.com> 4 * 2009-2010 Marty Jack <martyj19@comcast.net> 5 * 2014-2016 Andriy Grytsenko <andrej@rep.kiev.ua> 6 * 2015 Hanno Zulla <hhz@users.sf.net> 7 * 8 * This file is a part of LXPanel project. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software Foundation, 22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 23 */ 24 25 #ifndef __PLUGIN_H__ 26 #define __PLUGIN_H__ 1 27 28 #include <libfm/fm.h> 29 30 #include "panel.h" 31 #include "conf.h" 32 33 G_BEGIN_DECLS 34 35 /* New plugins style which uses FmModule loader, our module type is "lxpanel_gtk" */ 36 37 #define FM_MODULE_lxpanel_gtk_VERSION 1 /* version of this API */ 38 39 /** 40 * LXPanelPluginInit: 41 * @init: (allow-none): callback on lxpanel start 42 * @finalize: (allow-none): callback on lxpanel exit 43 * @name: name to represent plugin in lists 44 * @description: tooltip on the plugin in lists 45 * @new_instance: callback to create new plugin instance in panel 46 * @config: (allow-none): callback to show configuration dialog 47 * @reconfigure: (allow-none): callback to apply panel configuration change 48 * @button_press_event: (allow-none): callback on "button-press-event" signal 49 * @show_system_menu: (allow-none): callback to queue show system menu 50 * @update_context_menu: (allow-none): callback to update context menu 51 * @control: (allow-none): callback to pass messages from lxpanelctl 52 * @gettext_package: (allow-none): additional catalog to read translations 53 * 54 * Callback @init is called on module loading, only once per application 55 * lifetime. 56 * 57 * Callback @new_instance is called when panel tries to add some plugin. 58 * It should initialize instance data, prepare widget, and return the 59 * widget or %NULL if something went wrong. The @panel and @settings data 60 * are guaranteed to be valid until gtk_widget_destroy() is called on the 61 * instance. Instance own data should be attached to the instance using 62 * lxpanel_plugin_set_data(). 63 * 64 * Callback @config is called when user tries to configure the instance 65 * (either via context menu or from plugins selection dialog). It should 66 * create dialog window with instance configuration options. Returned 67 * dialog will be destroyed on responce or on instance destroy and any 68 * changed settings will be saved to the panel configuration file. See 69 * also lxpanel_generic_config_dlg(). 70 * 71 * Callback @reconfigure is called when panel configuration was changed 72 * in the panel configuration dialog so the instance may change layout of 73 * own subwidgets appropriately to new geometry. 74 * 75 * Callback @button_press_event is a handler for "button-press-event" 76 * signal on the plugin instance. This callback would never receive any 77 * right-clicks without modifier keys because panel itself will handle it 78 * showing context menu. This callback should never return %TRUE for the 79 * button 2 (middle-click) because that will disrupt the plugins movement 80 * feature of panel (drag & drop) for that plugin. 81 * 82 * Callback @show_system_menu is called when lxpanel received a message 83 * by 'lxpanelctl menu' command. It will be sent to each instance if more 84 * than one with this callback available exists. 85 * 86 * Callback @update_context_menu is called when panel context menu being 87 * composed. The @menu contains only item for plugin instance config. The 88 * callback can append or prepend own items to the menu. The callback 89 * should return %TRUE if panel's common menu should be moved into the 90 * submenu 'Panel' (therefore context menu will contain 'Settings' item, 91 * any added ones, and 'Panel') and %FALSE if panel's common menu items 92 * should be in this menu after separator. 93 * 94 * Callback @control is called when command was sent via the lxpanelctl. 95 * The message will be sent to only one instance of plugin. Some messages 96 * are handled by lxpanel: "DEL" will remove plugin from panel, "ADD" 97 * will create new instance if there is no instance yet. Due to design 98 * limitations of XClientMessageEvent the size of plugin type and command 99 * cannot exceed 18 characters in total. 100 * 101 * If @gettext_package is not %NULL then it will be used for translation 102 * of @name and @description. (Since: 0.9.0) 103 */ 104 typedef struct { 105 /*< public >*/ 106 void (*init)(void); /* optional startup */ 107 void (*finalize)(void); /* optional finalize */ 108 char *name; /* name to represent in lists */ 109 char *description; /* tooltip text */ 110 GtkWidget *(*new_instance)(LXPanel *panel, config_setting_t *settings); 111 GtkWidget *(*config)(LXPanel *panel, GtkWidget *instance); 112 void (*reconfigure)(LXPanel *panel, GtkWidget *instance); 113 gboolean (*button_press_event)(GtkWidget *widget, GdkEventButton *event, LXPanel *panel); 114 void (*show_system_menu)(GtkWidget *widget); 115 gboolean (*update_context_menu)(GtkWidget *plugin, GtkMenu *menu); 116 gboolean (*control)(GtkWidget *plugin, const char *cmd); 117 char *gettext_package; /* optional: gettext package used to translate name and description */ 118 /*< private >*/ 119 gpointer _reserved1; 120 gpointer _reserved2; 121 /*< public >*/ 122 int one_per_system : 1; /* True to disable more than one instance */ 123 int expand_available : 1; /* True if "stretch" option is available */ 124 int expand_default : 1; /* True if "stretch" option is default */ 125 int superseded : 1; /* True if plugin was superseded by another */ 126 } LXPanelPluginInit; /* constant data */ 127 128 /* 129 * This descriptor instance should be defined in each plugin code as main 130 * entry point for plugin creation. Primitive plugin example follows: 131 * 132 * #include <lxpanel/plugin.h> 133 * 134 * GtkWidget *test_new_instance(LXPanel *panel, config_setting_t *settings) 135 * { 136 * return gtk_image_new_from_stock(GTK_STOCK_OK, panel_get_icon_size(panel)); 137 * } 138 * 139 * FM_DEFINE_MODULE(lxpanel_gtk, test) 140 * 141 * LXPanelPluginInit fm_module_init_lxpanel_gtk = { 142 * .name = "Test plugin", 143 * .description = "An image with OK icon", 144 * .new_instance = test_new_instance 145 * } 146 */ 147 extern LXPanelPluginInit fm_module_init_lxpanel_gtk; 148 149 extern GQuark lxpanel_plugin_qdata; /* access to plugin private data */ 150 /** 151 * lxpanel_plugin_get_data 152 * @_i: instance widget 153 * 154 * Retrieves instance data attached to the widget. 155 * 156 * Returns: (transfer none): pointer to the data. 157 */ 158 #define lxpanel_plugin_get_data(_i) g_object_get_qdata(G_OBJECT(_i),lxpanel_plugin_qdata) 159 160 /** 161 * lxpanel_plugin_set_data 162 * @_i: instance widget 163 * @_data: instance data 164 * @_destructor: (allow-none): destructor for @_data 165 * 166 * Attaches data to the widget instance. The @_destructor callback will 167 * be called on @_data when @_i is destroyed and therefore it should free 168 * any allocated data. The instance widget at that moment is already not 169 * available to use in any way so not rely on it or its children. 170 */ 171 #define lxpanel_plugin_set_data(_i,_data,_destructor) g_object_set_qdata_full(G_OBJECT(_i),lxpanel_plugin_qdata,_data,_destructor) 172 173 /** 174 * lxpanel_register_plugin_type 175 * @name: name of new plugin type 176 * @init: plugin-specific type descriptor 177 * 178 * Register new plugin type. Can be called from plugins init() callback too. 179 * 180 * Returns: %TRUE in case of success. 181 */ 182 extern gboolean lxpanel_register_plugin_type(const char *name, const LXPanelPluginInit *init); 183 184 /** 185 * lxpanel_get_plugin_menu 186 * @panel: panel instance pointer 187 * @plugin: plugin instance pointer 188 * @use_sub_menu: %TRUE if panel management options should be in separated submenu 189 * 190 * Creates context menu for given @panel and @plugin. 191 * 192 * Returns: (transfer full): new menu widget. 193 */ 194 extern GtkMenu* lxpanel_get_plugin_menu(LXPanel* panel, GtkWidget* plugin, gboolean use_sub_menu); 195 196 /** 197 * lxpanel_plugin_adjust_popup_position 198 * @popup: a widget to adjust position 199 * @plugin: a plugin instance 200 * 201 * Adjusts the position of a @popup window to ensure that it is not hidden 202 * by the panel and moves @popup near @plugin if possible. 203 */ 204 extern void lxpanel_plugin_adjust_popup_position(GtkWidget * popup, GtkWidget * plugin); 205 206 /** 207 * lxpanel_plugin_popup_set_position_helper 208 * @p: a panel instance 209 * @near: a widget to position the popup 210 * @popup: a widget to calculate position 211 * @px: (out): pointer to receive X coordinate 212 * @py: (out): pointer to receive Y coordinate 213 * 214 * Calculates desired position of @popup to be placed right to the widget 215 * @near accordingly to position of panel @p and returns its coordinates. 216 * Can be used in position-calculation callback for popup menus. 217 */ 218 extern void lxpanel_plugin_popup_set_position_helper(LXPanel * p, GtkWidget * near, GtkWidget * popup, gint * px, gint * py); 219 220 /** 221 * plugin_widget_set_background 222 * @widget: a widget 223 * @p: a panel instance 224 * 225 * Recursively set the background of @widget and its children. Can be 226 * used on a panel background configuration change. 227 */ 228 extern void plugin_widget_set_background(GtkWidget * widget, LXPanel * p); 229 230 /** 231 * lxpanel_launch_path 232 * @panel: a panel instance 233 * @path: a path to launch 234 * 235 * Launches the @path either itself, or using default application. 236 * 237 * Returns: %TRUE if launch was successful. 238 */ 239 extern gboolean lxpanel_launch_path(LXPanel *panel, FmPath *path); 240 241 /** 242 * lxpanel_plugin_show_config_dialog 243 * @plugin: a plugin instance 244 * 245 * Calls config() callback and shows configuration window. 246 */ 247 extern void lxpanel_plugin_show_config_dialog(GtkWidget* plugin); 248 249 /** 250 * PluginConfType: 251 * @CONF_TYPE_STR: string entry, pointer is char ** 252 * @CONF_TYPE_INT: spin entry (range 0...1000), pointer is gint * 253 * @CONF_TYPE_BOOL: check button, pointer is gboolean * 254 * @CONF_TYPE_FILE: file chooser, pointer is char ** 255 * @CONF_TYPE_FILE_ENTRY: file path entry, pointer is char ** 256 * @CONF_TYPE_DIRECTORY_ENTRY: directory path entry, pointer is char ** 257 * @CONF_TYPE_TRIM: just a text in italic, pointer is ignored 258 * @CONF_TYPE_EXTERNAL: (since 0.8) provided by caller, pointer is GtkWidget * 259 * 260 * Type of variable passed to lxpanel_generic_config_dlg(). 261 */ 262 typedef enum { 263 CONF_TYPE_STR, 264 CONF_TYPE_INT, 265 CONF_TYPE_BOOL, 266 CONF_TYPE_FILE, 267 CONF_TYPE_FILE_ENTRY, 268 CONF_TYPE_DIRECTORY_ENTRY, 269 CONF_TYPE_TRIM, 270 CONF_TYPE_EXTERNAL 271 } PluginConfType; 272 273 /** 274 * lxpanel_generic_config_dlg 275 * @title: (allow-none): optional title of dialog window 276 * @panel: a panel instance 277 * @apply_func: (allow-none): function to apply changes to the plugin 278 * @plugin: (allow-none): an argument for @apply_func 279 * @name: variable-size list of options to configure, terminated with %NULL 280 * 281 * Creates a generic dialog widget to configure the plugin parameters. 282 * The dialog widget may be used for plugin's callback config() then. 283 * Variable-size list of options consists of three arguments for each 284 * option: 285 * - const char* name: text representing the option in dialog 286 * - gpointer ret_value: (in out): pointer to the option value 287 * - PluginConfType type: type of the option 288 * Note that for type CONF_TYPE_EXTERNAL the name argument is ignored and 289 * therefore empty string ("") have to be passed. 290 * 291 * Returns: (tranfer full): new created dialog widget. 292 */ 293 /* Parameters: const char* name, gpointer ret_value, PluginConfType type, ....NULL */ 294 extern GtkWidget *lxpanel_generic_config_dlg(const char *title, LXPanel *panel, 295 GSourceFunc apply_func, 296 GtkWidget *plugin, 297 const char *name, ...); 298 299 /** 300 * panel_config_int_button_new 301 * @name: text representing the option in dialog 302 * @min: minimal spin button value 303 * @max: maximal spin button value 304 * @val: (in out): pointer to the option value 305 * 306 * Widget to use as CONF_TYPE_EXTERNAL instead of CONF_TYPE_INT if plugin 307 * wants to customize range for lxpanel_generic_config_dlg(). The default 308 * widget uses range 0...1000 and here you can set custom range. This API 309 * should be never used outside of lxpanel_generic_config_dlg() arguments 310 * since it uses callbacks specific to that API. 311 * 312 * See also: lxpanel_generic_config_dlg(). 313 * 314 * Returns: (transfer full): new widget. 315 * 316 * Since: 0.8.0 317 */ 318 extern GtkWidget *panel_config_int_button_new(const char *name, gint *val, 319 gint min, gint max); 320 321 /* 322 * panel_config_hotkey_button_new 323 * @label: text representing the option in dialog 324 * @hotkey: (allow-none): current hotkey 325 * 326 * Creates a #GtkFrame derived widget which can select hotkey binding. 327 * The widget emits "changed" signal when some new combination selected 328 * gboolean callback(PanelCfgInputButton *, char *, gpointer); 329 * Caller should test if keybinding can be used in the callback and then 330 * return test result as %TRUE or %FALSE. 331 * Widget can be used for lxpanel_generic_config_dlg as CONF_TYPE_EXTERNAL 332 * 333 * Returns: (transfer full): a created widget. 334 * 335 * Since: 0.8.0 336 */ 337 extern GtkWidget *panel_config_hotkey_button_new(const char *label, const char *hotkey); 338 extern GtkWidget *panel_config_click_button_new(const char *label, const char *click); 339 340 /** 341 * lxpanel_apply_hotkey 342 * @hkptr: (in out) (transfer full): pointer to hotkey string 343 * @keystring: (allow-none): new hotkey 344 * @handler: callback to assign to hotkey 345 * @user_data: data to provide for @handler 346 * @show_error: %TRUE to show error window if assignment failed 347 * 348 * Function designed to use in callback on "changed" signal from widget 349 * created by panel_config_hotkey_button_new(). Should be also used on 350 * initial binding and on unbinding when module unloaded (in latter case 351 * @keystring should be %NULL). In case of success returns %TRUE, unbinds 352 * previous hotkey from @hkptr, and updates @hkptr. The @hkptr contains 353 * allocated string. 354 * 355 * Returns: %TRUE on success. 356 * 357 * Since: 0.8.0 358 */ 359 extern gboolean lxpanel_apply_hotkey(char **hkptr, const char *keystring, 360 void (*handler)(const char *keystring, gpointer user_data), 361 gpointer user_data, gboolean show_error); 362 363 /** 364 * panel_config_click_parse 365 * @keystring: string to parse 366 * @mods: (out): return location for modifier 367 * 368 * Parses click string received in "changed" signal emission of widget 369 * created with panel_config_click_button_new() and returns button and 370 * modifier that can be compared with GdkEventButton data when required. 371 * 372 * Returns: button number or 0 if @keystring is invalid. 373 * 374 * Since: 0.8.0 375 */ 376 extern guint panel_config_click_parse(const char *keystring, GdkModifierType *mods); 377 378 /* Add/remove plugin to/from panel */ 379 GtkWidget *lxpanel_add_plugin(LXPanel *p, const char *name, config_setting_t *cfg, gint at); 380 void lxpanel_remove_plugin(LXPanel *p, GtkWidget *plugin); 381 382 G_END_DECLS 383 384 #endif /* __PLUGIN_H__ */ 385