1 /*
2  * Copyright (C) 2014-2016 Andriy Grytsenko <andrej@rep.kiev.ua>
3  *
4  * This file is a part of LXPanel project.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #ifndef PRIVATE_H
22 #define PRIVATE_H
23 
24 #include "plugin.h"
25 #include "conf.h"
26 #include "lxpanelctl.h"
27 
28 #include <gmodule.h>
29 
30 #include <gtk/gtk.h>
31 #include <gdk/gdk.h>
32 #include <stdio.h>
33 #include "panel.h"
34 
35 #include <gdk/gdk.h>
36 
37 #include "ev.h"
38 
39 #if !GLIB_CHECK_VERSION(2, 40, 0)
40 # define g_info(...) g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, __VA_ARGS__)
41 #endif
42 
43 /* -----------------------------------------------------------------------------
44  *   Definitions used by lxpanel main code internally */
45 
46 /* Extracted from panel.h */
47 enum { ALIGN_NONE, ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT  };
48 enum { WIDTH_NONE, WIDTH_REQUEST, WIDTH_PIXEL, WIDTH_PERCENT };
49 enum { HEIGHT_NONE, HEIGHT_PIXEL, HEIGHT_REQUEST };
50 
51 #define PANEL_ICON_SIZE               24	/* Default size of panel icons */
52 #define PANEL_HEIGHT_DEFAULT          26	/* Default height of horizontal panel */
53 #define PANEL_WIDTH_DEFAULT           150	/* Default "height" of vertical panel */
54 #define PANEL_HEIGHT_MAX              200	/* Maximum height of panel */
55 #define PANEL_HEIGHT_MIN              16	/* Minimum height of panel */
56 #define PANEL_ICON_HIGHLIGHT          0x202020	/* Constant to pass to icon loader */
57 
58 typedef enum {
59     PANEL_MOVE_STOP, /* initial state */
60     PANEL_MOVE_DETECT, /* button pressed, detect drag */
61     PANEL_MOVE_MOVING /* moving the plugin */
62 } PanelPluginMoveState;
63 
64 typedef struct {
65     int space_size;         /* size of space plugin if expandable */
66     int plugin_center;      /* position of center of prev no-space plugin */
67     GtkWidget * space;
68     GtkWidget * plugin;
69 } PanelPluginMoveData;
70 
71 /* to check if we are in LXDE */
72 extern gboolean is_in_lxde;
73 
74 extern gchar *cprofile;
75 
76 extern GSList* all_panels;
77 
78 /* Context of a panel on a given edge. */
79 struct _Panel {
80     char* name;
81     LXPanel * topgwin;			/* Main panel window */
82     Window topxwin;			/* Main panel's X window   */
83     GdkDisplay * display;		/* Main panel's GdkDisplay */
84     GtkStyle * defstyle;
85     GtkIconTheme* icon_theme; /*Default icon theme*/
86 
87     GtkWidget * box;			/* Top level widget */
88 
89     GtkRequisition requisition;
90     GtkWidget *(*my_box_new) (gboolean, gint);
91     GtkWidget *(*my_separator_new) (void);
92 
93     void *bg; /* unused since 0.8.0 */
94     int alpha;
95     guint32 tintcolor;
96     guint32 fontcolor;
97     GdkColor gtintcolor;
98     GdkColor gfontcolor;
99 
100     int ax, ay, aw, ah;  /* prefferd allocation of a panel */
101     int cx, cy, cw, ch;  /* current allocation (as reported by configure event) allocation */
102     int align, edge, margin;
103     guint orientation;
104     int widthtype, width;
105     int heighttype, height;
106     gint monitor;
107     gulong strut_size;			/* Values for WM_STRUT_PARTIAL */
108     gulong strut_lower;
109     gulong strut_upper;
110     int strut_edge;
111 
112     guint config_changed : 1;
113     guint self_destroy : 1;
114     guint setdocktype : 1;
115     guint setstrut : 1;
116     guint round_corners : 1;
117     guint usefontcolor : 1;
118     guint usefontsize : 1;
119     guint fontsize;
120     guint transparent : 1;
121     guint background : 1;
122     guint spacing;
123 
124     guint autohide : 1;
125     guint visible : 1;
126     int height_when_hidden;
127     guint hide_timeout;
128     int icon_size;			/* Icon size */
129 
130     int desknum;
131     int curdesk;
132     gulong *workarea; /* unused since 0.8.0 */
133     int wa_len; /* unused since 0.8.0 */
134 
135     char* background_file;
136 
137     PanelConf * config;                 /* Panel configuration data */
138     GSList * system_menus;		/* List of plugins having menus: deprecated */
139 
140     GtkWidget* plugin_pref_dialog;	/* Plugin preference dialog */
141     GtkWidget* pref_dialog;		/* preference dialog */
142     GtkWidget* margin_control;		/* Margin control in preference dialog */
143     GtkWidget* height_label;		/* Label of height control */
144     GtkWidget* width_label;		/* Label of width control */
145     GtkWidget* alignment_left_label;	/* Label of alignment: left control */
146     GtkWidget* alignment_right_label;	/* Label of alignment: right control */
147     GtkWidget* height_control;		/* Height control in preference dialog */
148     GtkWidget* width_control;		/* Width control in preference dialog */
149     GtkWidget* strut_control;		/* Reserve space in preference dialog */
150     GtkWidget* edge_bottom_button;
151     GtkWidget* edge_top_button;
152     GtkWidget* edge_left_button;
153     GtkWidget* edge_right_button;
154 
155     guint initialized : 1;              /* Should be grouped better later, */
156     guint ah_far : 1;                   /* placed here for binary compatibility */
157     guint ah_state : 3;
158     guint background_update_queued;
159     guint strut_update_queued;
160     guint mouse_timeout;
161     guint reconfigure_queued;
162     //gint dyn_space;                     /* Space for expandable plugins */
163     //guint calculate_size_idle;          /* The idle handler for dyn_space calc */
164     cairo_surface_t *surface;           /* Panel background */
165 
166     PanelPluginMoveState move_state;    /* Plugin movement (drag&drop) support */
167     int move_x, move_y;
168     int move_diff;
169     GdkDevice * move_device;
170     GtkWidget * move_plugin;            /* widgets involved in movement */
171     PanelPluginMoveData move_before;
172     PanelPluginMoveData move_after;
173 };
174 
175 typedef struct {
176     char *name;
177     char *disp_name;
178     void (*cmd)(void);
179 } Command;
180 
181 #define FBPANEL_WIN(win)  gdk_window_lookup(win)
182 
183 /* Extracted from misc.h */
184 typedef struct {
185     int num;
186     gchar *str;
187 } pair;
188 
189 extern pair allign_pair[];
190 extern pair edge_pair[];
191 extern pair width_pair[];
192 extern pair height_pair[];
193 extern pair bool_pair[];
194 
195 int str2num(pair *p, const gchar *str, int defval);
196 const gchar *num2str(pair *p, int num, const gchar *defval);
197 
198 #ifdef __LXPANEL_INTERNALS__
_system_config_file_name(const char * dir,const char * file_name)199 static inline char *_system_config_file_name(const char *dir, const char *file_name)
200 {
201     return g_build_filename(dir, "lxpanel", cprofile, file_name, NULL);
202 }
203 
_old_system_config_file_name(const char * file_name)204 static inline char *_old_system_config_file_name(const char *file_name)
205 {
206     return g_build_filename(PACKAGE_DATA_DIR "/profile", cprofile, file_name, NULL);
207 }
208 
_user_config_file_name(const char * name1,const char * name2)209 static inline char *_user_config_file_name(const char *name1, const char *name2)
210 {
211     return g_build_filename(g_get_user_config_dir(), "lxpanel", cprofile, name1,
212                             name2, NULL);
213 }
214 #endif
215 
216 //void _queue_panel_calculate_size(Panel *panel);
217 
218 /* FIXME: optional definitions */
219 #define STATIC_SEPARATOR
220 #define STATIC_LAUNCHBAR
221 #define STATIC_LAUNCHTASKBAR
222 #define STATIC_DCLOCK
223 #define STATIC_WINCMD
224 #define STATIC_DIRMENU
225 #define STATIC_TASKBAR
226 #define STATIC_PAGER
227 #define STATIC_TRAY
228 #define STATIC_MENU
229 #define STATIC_ICONS
230 
231 /* Plugins management - new style */
232 void lxpanel_prepare_modules(void);
233 void lxpanel_unload_modules(void);
234 
235 GHashTable *lxpanel_get_all_types(void); /* transfer none */
236 void _lxpanel_remove_plugin(LXPanel *p, GtkWidget *plugin); /* no destroy dialog */
237 
238 extern GQuark lxpanel_plugin_qinit; /* access to LXPanelPluginInit data */
239 #define PLUGIN_CLASS(_i) ((LXPanelPluginInit*)g_object_get_qdata(G_OBJECT(_i),lxpanel_plugin_qinit))
240 
241 extern GQuark lxpanel_plugin_qconf; /* access to congig_setting_t data */
242 
243 #define PLUGIN_PANEL(_i) ((LXPanel*)gtk_widget_get_toplevel(_i))
244 
245 gboolean _class_is_present(const LXPanelPluginInit *init);
246 
247 LXPanel* panel_new(const char* config_file, const char* config_name);
248 
249 void _panel_show_config_dialog(LXPanel *panel, GtkWidget *p, GtkWidget *dlg);
250 
251 void _calculate_position(LXPanel *panel, GdkRectangle *rect);
252 
253 void _panel_establish_autohide(LXPanel *p);
254 void _panel_set_wm_strut(LXPanel *p);
255 void _panel_set_panel_configuration_changed(LXPanel *p);
256 void _panel_queue_update_background(LXPanel *p);
257 void _panel_emit_icon_size_changed(LXPanel *p);
258 void _panel_emit_font_changed(LXPanel *p);
259 
260 void panel_configure(LXPanel* p, int sel_page);
261 gboolean panel_edge_available(Panel* p, int edge, gint monitor);
262 gboolean _panel_edge_can_strut(LXPanel *panel, int edge, gint monitor, gulong *size);
263 void restart(void);
264 void logout(void);
265 void gtk_run(void);
266 
267 /* two huge callbacks used for plugins movement within panel */
268 gboolean _lxpanel_button_release(GtkWidget *widget, GdkEventButton *event);
269 gboolean _lxpanel_motion_notify(GtkWidget *widget, GdkEventMotion *event);
270 
271 
272 /* -----------------------------------------------------------------------------
273  *   Deprecated declarations. Kept for compatibility with old code plugins.
274  *   Should be removed and appropriate code cleaned on some of next releases. */
275 
276 extern Command commands[];
277 
278 /* Extracted from panel.h */
279 extern int verbose;
280 
281 extern void panel_destroy(Panel *p);
282 extern void panel_adjust_geometry_terminology(Panel *p);
283 extern void panel_determine_background_pixmap(Panel * p, GtkWidget * widget, GdkWindow * window);
284 extern void panel_draw_label_text(Panel * p, GtkWidget * label, const char * text,
285                                   gboolean bold, float custom_size_factor,
286                                   gboolean custom_color);
287 extern void panel_establish_autohide(Panel *p);
288 extern void panel_image_set_from_file(Panel * p, GtkWidget * image, const char * file);
289 extern gboolean panel_image_set_icon_theme(Panel * p, GtkWidget * image, const gchar * icon);
290 extern void panel_set_wm_strut(Panel *p);
291 extern void panel_set_dock_type(Panel *p);
292 extern void panel_set_panel_configuration_changed(Panel *p);
293 extern void panel_update_background( Panel* p );
294 
295 /* if current window manager is EWMH conforming. */
296 extern gboolean is_ewmh_supported;
297 
298 void get_button_spacing(GtkRequisition *req, GtkContainer *parent, gchar *name);
299 
300 /*
301  This function is used to re-create a new box with different
302  orientation from the old one, add all children of the old one to
303  the new one, and then destroy the old box.
304  It's mainly used when we need to change the orientation of the panel or
305  any plugin with a layout box. Since GtkHBox cannot be changed to GtkVBox,
306  recreating a new box to replace the old one is required.
307 */
308 GtkWidget* recreate_box( GtkBox* oldbox, GtkOrientation orientation );
309 
310 extern const char* lxpanel_get_file_manager();
311 
312 
313 /* Extracted from misc.h */
314 typedef struct _Plugin Plugin;
315 
316 enum { LINE_NONE, LINE_BLOCK_START, LINE_BLOCK_END, LINE_VAR };
317 
318 typedef struct {
319     int num, len, type;
320     gchar str[256];
321     gchar *t[3];
322 } line;
323 
324 void calculate_position(Panel *np);
325 
326 extern int lxpanel_get_line(char **fp, line *s);
327 extern int lxpanel_put_line(FILE* fp, const char* format, ...);
328 #define lxpanel_put_str(fp, name, val) (G_UNLIKELY( !(val) || !*(val) )) ? 0 : lxpanel_put_line(fp, "%s=%s", name, val)
329 #define lxpanel_put_bool(fp, name, val) lxpanel_put_line(fp, "%s=%c", name, (val) ? '1' : '0')
330 #define lxpanel_put_int(fp, name, val) lxpanel_put_line(fp, "%s=%d", name, val)
331 
332 GtkWidget *_gtk_image_new_from_file_scaled(const gchar *file, gint width,
333                                            gint height, gboolean keep_ratio);
334 
335 GtkWidget * fb_button_new_from_file(
336     const gchar * image_file, int width, int height, gulong highlight_color, gboolean keep_ratio);
337 GtkWidget * fb_button_new_from_file_with_label(
338     const gchar * image_file, int width, int height, gulong highlight_color, gboolean keep_ratio, Panel * panel, const gchar * label);
339 
340 void fb_button_set_from_file(GtkWidget* btn, const char* img_file, gint width, gint height, gboolean keep_ratio);
341 
342 char* translate_exec_to_cmd( const char* exec, const char* icon,
343                              const char* title, const char* fpath );
344 
345 void show_error( GtkWindow* parent_win, const char* msg );
346 
347 gboolean spawn_command_async(GtkWindow *parent_window, gchar const* workdir,
348         gchar const* cmd);
349 
350 /* Parameters: const char* name, gpointer ret_value, GType type, ....NULL */
351 GtkWidget* create_generic_config_dlg( const char* title, GtkWidget* parent,
352                               GSourceFunc apply_func, Plugin * plugin,
353                       const char* name, ... );
354 
355 extern GtkMenu* lxpanel_get_panel_menu( Panel* panel, Plugin* plugin, gboolean use_sub_menu );
356 
357 gboolean lxpanel_launch_app(const char* exec, GList* files, gboolean in_terminal, char const* in_workdir);
358 
359 extern GdkPixbuf* lxpanel_load_icon( const char* name, int width, int height, gboolean use_fallback );
360 
361 void Xclimsg(Window win, Atom type, long l0, long l1, long l2, long l3, long l4);
362 
363 
364 /* Extracted from plugin.h */
365 struct _Plugin;
366 
367 /* Support for external plugin versioning.
368  * Plugins must invoke PLUGINCLASS_VERSIONING when they instantiate PluginClass. */
369 #define PLUGINCLASS_VERSION 1
370 #define PLUGINCLASS_VERSIONING \
371     .structure_size = sizeof(PluginClass), \
372     .structure_version = PLUGINCLASS_VERSION
373 
374 /* Representative of an available plugin. */
375 typedef struct {
376 
377     /* Keep these first.  Do not make unnecessary changes in structure layout. */
378     unsigned short structure_size;		/* Structure size, for versioning support */
379     unsigned short structure_version;		/* Structure version, for versioning support */
380 
381     char * fname;				/* Plugin file pathname */
382     int count;					/* Reference count */
383     GModule * gmodule;				/* Associated GModule structure */
384 
385     int dynamic : 1;				/* True if dynamically loaded */
386     int unused_invisible : 1;			/* Unused; reserved bit */
387     int not_unloadable : 1;			/* Not unloadable due to GModule restriction */
388     int one_per_system : 1;			/* Special: only one possible per system, such as system tray */
389     int one_per_system_instantiated : 1;	/* True if one instance exists */
390     int expand_available : 1;			/* True if "stretch" option is available */
391     int expand_default : 1;			/* True if "stretch" option is default */
392 
393     /* These fields point within the plugin image. */
394     char * type;				/* Internal name of plugin, to match external filename */
395     char * name;				/* Display name of plugin for selection UI */
396     char * version;				/* Version of plugin */
397     char * description;				/* Brief textual description of plugin for selection UI */
398 
399     int (*constructor)(struct _Plugin * plugin, char ** fp);		/* Create an instance of the plugin */
400     void (*destructor)(struct _Plugin * plugin);			/* Destroy an instance of the plugin */
401     void (*config)(struct _Plugin * plugin, GtkWindow * parent);	/* Request the plugin to display its configuration dialog */
402     void (*save)(struct _Plugin * plugin, FILE * fp);			/* Request the plugin to save its configuration to a file */
403     void (*panel_configuration_changed)(struct _Plugin * plugin);	/* Request the plugin to do a full redraw after a panel configuration change */
404 } PluginClass;
405 
406 /* Representative of a loaded and active plugin attached to a panel. */
407 struct _Plugin {
408     PluginClass * class;			/* Back pointer to PluginClass */
409     Panel * panel;				/* Back pointer to Panel */
410     GtkWidget * pwid;				/* Top level widget; plugin allocates, but plugin mechanism, not plugin itself, destroys this */
411     int expand;					/* Expand ("stretch") setting for container */
412     int padding;				/* Padding setting for container */
413     int border;					/* Border setting for container */
414     gpointer priv;				/* Private context for plugin; plugin frees this in its destructor */
415 };
416 
417 /* Plugins management - deprecated style, for backward compatibility */
418 extern gboolean plugin_button_press_event(GtkWidget *widget, GdkEventButton *event, Plugin *plugin);
419                                                         /* Handler for "button_press_event" signal with Plugin as parameter */
420 extern void plugin_adjust_popup_position(GtkWidget * popup, Plugin * plugin);
421 							/* Helper to move popup windows away from the panel */
422 extern void plugin_popup_set_position_helper(Plugin * p, GtkWidget * near, GtkWidget * popup, GtkRequisition * popup_req, gint * px, gint * py);
423 							/* Helper for position-calculation callback for popup menus */
424 
425 /**
426  * lxpanel_image_set_from_file
427  * @p: a panel instance
428  * @image: a #GtkImage widget
429  * @file: image file path
430  *
431  * Applies icon from @file to @image in accordance with icon size setting
432  * on panel @p.
433  */
434 extern void lxpanel_image_set_from_file(LXPanel * p, GtkWidget * image, const char * file);
435 
436 /**
437  * lxpanel_image_set_icon_theme
438  * @p: a panel instance
439  * @image: a #GtkImage widget
440  * @icon: icon name
441  *
442  * Applies icon size and theme from settings of @p to @image using @icon
443  * name to select icon.
444  */
445 extern gboolean lxpanel_image_set_icon_theme(LXPanel * p, GtkWidget * image, const gchar * icon);
446 
447 #endif
448