1 /**
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * E-mail    : see the 'copyright' file.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /******************************************************************************
21 exemples :
22 ----------
23 
24 dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.SetQuickInfo string:123 string:"class=firefox"
25 
26 dbus-send --session --dest=org.cairodock.CairoDock /org/cairodock/CairoDock org.cairodock.CairoDock.Animate string:default int32:2 string:"class=firefox"
27 
28 ******************************************************************************/
29 
30 #include <unistd.h>
31 #include <glib.h>
32 
33 #include <cairo-dock.h>
34 #include <cairo-dock-module-instance-manager.h>
35 #include "interface-main-query.h"
36 #include "interface-main-methods.h"
37 
38 
39 #define nullify_argument(string) do {\
40 	if (string != NULL && (*string == '\0' || strcmp (string, "any") == 0 || strcmp (string, "none") == 0))\
41 		string = NULL; } while (0)
42 
43 static gboolean dbus_deskletVisible = FALSE;
44 
cd_dbus_main_reboot(dbusMainObject * pDbusCallback,GError ** error)45 gboolean cd_dbus_main_reboot(dbusMainObject *pDbusCallback, GError **error)
46 {
47 	if (! myConfig.bEnableReboot)
48 		return FALSE;
49 	cairo_dock_load_current_theme ();
50 	return TRUE;
51 }
52 
cd_dbus_main_quit(dbusMainObject * pDbusCallback,GError ** error)53 gboolean cd_dbus_main_quit (dbusMainObject *pDbusCallback, GError **error)
54 {
55 	if (! myConfig.bEnableQuit)
56 		return FALSE;
57 	gtk_main_quit ();
58 	return TRUE;
59 }
60 
_show_hide_one_dock(const gchar * cDockName,CairoDock * pDock,gpointer data)61 static void _show_hide_one_dock (const gchar *cDockName, CairoDock *pDock, gpointer data)
62 {
63 	if (pDock->iRefCount != 0)
64 		return ;
65 	gboolean bShow = GPOINTER_TO_INT (data);
66 	if (bShow)
67 	{
68 		///cairo_dock_pop_up (pDock);
69 		///if (pDock->bAutoHide)
70 			cairo_dock_emit_enter_signal (CAIRO_CONTAINER (pDock));
71 	}
72 	else
73 	{
74 		///cairo_dock_pop_down (pDock);  // ne fait rien s'il n'etait pas "popped".
75 		///if (pDock->bAutoHide)
76 			cairo_dock_emit_leave_signal (CAIRO_CONTAINER (pDock));
77 	}
78 }
cd_dbus_main_show_dock(dbusMainObject * pDbusCallback,gint iVisibiliy,GError ** error)79 gboolean cd_dbus_main_show_dock (dbusMainObject *pDbusCallback, gint iVisibiliy, GError **error)
80 {
81 	if (! myConfig.bEnableShowDock)
82 		return FALSE;
83 
84 	if (g_pMainDock == NULL)
85 		return FALSE;
86 
87 	gboolean bShow;
88 	switch (iVisibiliy)
89 	{
90 		case 0:  // hide
91 			bShow = FALSE;
92 		break;
93 		case 1:  // show
94 			bShow = TRUE;
95 		break;
96 		case 2:  // toggle
97 		default:
98 			bShow = (g_pMainDock->bIsBelow || (g_pMainDock->bAutoHide && g_pMainDock->fHideOffset == 1));
99 		break;
100 	}
101 
102 	if (bShow)
103 		cairo_dock_stop_quick_hide ();
104 
105 	gldi_docks_foreach ((GHFunc) _show_hide_one_dock, GINT_TO_POINTER (bShow));
106 
107 	if (! bShow)
108 		cairo_dock_quick_hide_all_docks ();
109 
110 	return TRUE;
111 }
112 
cd_dbus_main_show_desklet(dbusMainObject * pDbusCallback,gboolean * widgetLayer,GError ** error)113 gboolean cd_dbus_main_show_desklet (dbusMainObject *pDbusCallback, gboolean *widgetLayer, GError **error)
114 {
115 	if (! myConfig.bEnableDesklets)
116 		return FALSE;
117 	if (dbus_deskletVisible)
118 	{
119 		gldi_desklets_set_visibility_to_default ();
120 	}
121 	else
122 	{
123 		gldi_desklets_set_visible (widgetLayer != NULL ? *widgetLayer : FALSE);
124 	}
125 	dbus_deskletVisible = !dbus_deskletVisible;
126 	return TRUE;
127 }
128 
129 
130   ///////////////////
131  /// SET ON ICON ///
132 ///////////////////
133 
cd_dbus_main_set_quick_info(dbusMainObject * pDbusCallback,const gchar * cQuickInfo,gchar * cIconQuery,GError ** error)134 gboolean cd_dbus_main_set_quick_info (dbusMainObject *pDbusCallback, const gchar *cQuickInfo, gchar *cIconQuery, GError **error)
135 {
136 	if (! myConfig.bEnableSetQuickInfo)
137 		return FALSE;
138 
139 	GList *pList = cd_dbus_find_matching_icons (cIconQuery);
140 	if (pList == NULL)
141 		return TRUE;
142 
143 	nullify_argument (cQuickInfo);
144 
145 	Icon *pIcon;
146 	GldiContainer *pContainer;
147 	GList *ic;
148 	for (ic = pList; ic != NULL; ic = ic->next)
149 	{
150 		pIcon = ic->data;
151 		pContainer = cairo_dock_get_icon_container (pIcon);
152 		if (pContainer == NULL)
153 			continue;
154 
155 		gldi_icon_set_quick_info (pIcon, cQuickInfo);
156 		cairo_dock_redraw_icon (pIcon);
157 	}
158 
159 	g_list_free (pList);
160 	return TRUE;
161 }
162 
cd_dbus_main_set_label(dbusMainObject * pDbusCallback,const gchar * cLabel,gchar * cIconQuery,GError ** error)163 gboolean cd_dbus_main_set_label (dbusMainObject *pDbusCallback, const gchar *cLabel, gchar *cIconQuery, GError **error)
164 {
165 	if (! myConfig.bEnableSetLabel)
166 		return FALSE;
167 
168 	GList *pList = cd_dbus_find_matching_icons (cIconQuery);
169 	if (pList == NULL)
170 		return TRUE;
171 
172 	nullify_argument (cLabel);
173 
174 	Icon *pIcon;
175 	GldiContainer *pContainer;
176 	GList *ic;
177 	for (ic = pList; ic != NULL; ic = ic->next)
178 	{
179 		pIcon = ic->data;
180 		pContainer = cairo_dock_get_icon_container (pIcon);
181 		if (pContainer == NULL)
182 			continue;
183 
184 		gldi_icon_set_name (pIcon, cLabel);
185 	}
186 
187 	g_list_free (pList);
188 	return TRUE;
189 }
190 
cd_dbus_main_set_icon(dbusMainObject * pDbusCallback,const gchar * cImage,gchar * cIconQuery,GError ** error)191 gboolean cd_dbus_main_set_icon (dbusMainObject *pDbusCallback, const gchar *cImage, gchar *cIconQuery, GError **error)
192 {
193 	if (! myConfig.bEnableSetIcon)
194 		return FALSE;
195 
196 	GList *pList = cd_dbus_find_matching_icons (cIconQuery);
197 	if (pList == NULL)
198 		return TRUE;
199 
200 	Icon *pIcon;
201 	GldiContainer *pContainer;
202 	GList *ic;
203 	for (ic = pList; ic != NULL; ic = ic->next)
204 	{
205 		pIcon = ic->data;
206 		if (pIcon->image.pSurface == NULL)
207 			continue;
208 
209 		pContainer = cairo_dock_get_icon_container (pIcon);
210 		if (pContainer == NULL)
211 			continue;
212 
213 		cairo_t *pIconContext = cairo_create (pIcon->image.pSurface);
214 		cairo_dock_set_image_on_icon (pIconContext, cImage, pIcon, pContainer);
215 		cairo_destroy (pIconContext);
216 		cairo_dock_redraw_icon (pIcon);
217 	}
218 
219 	g_list_free (pList);
220 	return TRUE;
221 }
222 
cd_dbus_main_set_emblem(dbusMainObject * pDbusCallback,const gchar * cImage,gint iPosition,gchar * cIconQuery,GError ** error)223 gboolean cd_dbus_main_set_emblem (dbusMainObject *pDbusCallback, const gchar *cImage, gint iPosition, gchar *cIconQuery, GError **error)
224 {
225 	if (! myConfig.bEnableSetIcon)
226 		return FALSE;
227 
228 	GList *pList = cd_dbus_find_matching_icons (cIconQuery);
229 	if (pList == NULL)
230 		return TRUE;
231 
232 	Icon *pIcon;
233 	GldiContainer *pContainer;
234 	GList *ic;
235 	for (ic = pList; ic != NULL; ic = ic->next)
236 	{
237 		pIcon = ic->data;
238 		if (pIcon->image.pSurface == NULL)
239 			continue;
240 
241 		pContainer = cairo_dock_get_icon_container (pIcon);
242 		if (pContainer == NULL)
243 			continue;
244 
245 		if (cImage == NULL || *cImage == '\0' || strcmp (cImage, "none") == 0)
246 		{
247 			cairo_dock_remove_overlay_at_position (pIcon, iPosition < CAIRO_OVERLAY_NB_POSITIONS ? iPosition : iPosition - CAIRO_OVERLAY_NB_POSITIONS, myApplet);  // for ease of use, handle both case similarily.
248 		}
249 		else
250 		{
251 			if (iPosition >= CAIRO_OVERLAY_NB_POSITIONS)  // [N; 2N-1] => print the overlay
252 				cairo_dock_print_overlay_on_icon_from_image (pIcon, cImage, iPosition - CAIRO_OVERLAY_NB_POSITIONS);
253 			else  // [0, N-1] => add it
254 				cairo_dock_add_overlay_from_image (pIcon, cImage, iPosition, myApplet);  // use 'myApplet' to identify the overlays set by the Dbus plug-in (since the plug-in can't be deactivated, 'myApplet' is constant).
255 		}
256 
257 		cairo_dock_redraw_icon (pIcon);
258 	}
259 
260 	g_list_free (pList);
261 	return TRUE;
262 }
263 
cd_dbus_main_animate(dbusMainObject * pDbusCallback,const gchar * cAnimation,gint iNbRounds,gchar * cIconQuery,GError ** error)264 gboolean cd_dbus_main_animate (dbusMainObject *pDbusCallback, const gchar *cAnimation, gint iNbRounds, gchar *cIconQuery, GError **error)
265 {
266 	if (! myConfig.bEnableAnimateIcon || cAnimation == NULL)
267 		return FALSE;
268 
269 	GList *pList = cd_dbus_find_matching_icons (cIconQuery);
270 	if (pList == NULL)
271 		return TRUE;
272 
273 	Icon *pIcon;
274 	GldiContainer *pContainer;
275 	GList *ic;
276 	for (ic = pList; ic != NULL; ic = ic->next)
277 	{
278 		pIcon = ic->data;
279 		pContainer = cairo_dock_get_icon_container (pIcon);
280 		if (! CAIRO_DOCK_IS_DOCK (pContainer))
281 			continue;
282 		gldi_icon_request_animation (pIcon, cAnimation, iNbRounds);
283 	}
284 
285 	g_list_free (pList);
286 	return TRUE;
287 }
288 
cd_dbus_main_demands_attention(dbusMainObject * pDbusCallback,gboolean bStart,const gchar * cAnimation,gchar * cIconQuery,GError ** error)289 gboolean cd_dbus_main_demands_attention (dbusMainObject *pDbusCallback, gboolean bStart, const gchar *cAnimation, gchar *cIconQuery, GError **error)
290 {
291 	if (! myConfig.bEnableAnimateIcon)
292 		return FALSE;
293 
294 	GList *pList = cd_dbus_find_matching_icons (cIconQuery);
295 	if (pList == NULL)
296 		return TRUE;
297 
298 	Icon *pIcon;
299 	GldiContainer *pContainer;
300 	GList *ic;
301 	for (ic = pList; ic != NULL; ic = ic->next)
302 	{
303 		pIcon = ic->data;
304 		pContainer = cairo_dock_get_icon_container (pIcon);
305 		if (! CAIRO_DOCK_IS_DOCK (pContainer))
306 			continue;
307 
308 		if (bStart)
309 		{
310 			gldi_icon_request_attention (pIcon, cAnimation, 0);  // 0 <=> non-stop.
311 		}
312 		else if (pIcon->bIsDemandingAttention)
313 		{
314 			gldi_icon_stop_attention (pIcon);
315 		}
316 	}
317 
318 	g_list_free (pList);
319 	return TRUE;
320 }
321 
cd_dbus_main_show_dialog(dbusMainObject * pDbusCallback,const gchar * message,gint iDuration,gchar * cIconQuery,GError ** error)322 gboolean cd_dbus_main_show_dialog (dbusMainObject *pDbusCallback, const gchar *message, gint iDuration, gchar *cIconQuery, GError **error)
323 {
324 	if (! myConfig.bEnablePopUp)
325 		return FALSE;
326 	g_return_val_if_fail (message != NULL, FALSE);
327 
328 	GList *pList = cd_dbus_find_matching_icons (cIconQuery);
329 
330 	Icon *pIcon;
331 	GldiContainer *pContainer;
332 	GList *ic;
333 	for (ic = pList; ic != NULL; ic = ic->next)
334 	{
335 		pIcon = ic->data;
336 		pContainer = cairo_dock_get_icon_container (pIcon);
337 		if (! CAIRO_DOCK_IS_DOCK (pContainer))
338 			continue;
339 		gldi_dialog_show_temporary_with_icon (message, pIcon, pContainer, 1000 * iDuration, "same icon");
340 		break;  // only show 1 dialog.
341 	}
342 
343 	if (ic == NULL)  // empty list, or didn't find a valid icon.
344 		gldi_dialog_show_general_message (message, 1000 * iDuration);
345 
346 	g_list_free (pList);
347 	return TRUE;
348 }
349 
350 
351 #ifdef DBUSMENU_GTK_FOUND
_on_menu_destroyed(GtkWidget * menu,CDIconData * pData)352 static void _on_menu_destroyed (GtkWidget *menu, CDIconData *pData)
353 {
354 	//g_print ("\n+++ %s ()\n\n", __func__);
355 	if (pData != NULL && pData->menu_items_list != NULL)
356 	{
357 		GList *mi;
358 		for (mi = pData->menu_items_list; mi != NULL; mi = mi->next)
359 		{
360 			DbusmenuMenuitem *pDbusMenuItem = mi->data;
361 			GtkMenuItem *pMenuItem = dbusmenu_gtkclient_menuitem_get (pData->client, pDbusMenuItem);
362 			if (gtk_widget_get_parent (GTK_WIDGET (pMenuItem)) != NULL)  // it might not be in the menu if it has been added after the menu was built.
363 				gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (pMenuItem));
364 		}
365 	}
366 }
cd_dbus_main_emit_on_build_menu(gpointer data,Icon * pClickedIcon,GldiContainer * pClickedContainer,GtkWidget * pMenu)367 static gboolean cd_dbus_main_emit_on_build_menu (gpointer data, Icon *pClickedIcon, GldiContainer *pClickedContainer, GtkWidget *pMenu)
368 {
369 	if (pClickedIcon == NULL)
370 		return GLDI_NOTIFICATION_LET_PASS;
371 
372 	CDIconData *pData = CD_APPLET_GET_MY_ICON_DATA (pClickedIcon);
373 	if (pData != NULL && pData->menu_items_list != NULL)
374 	{
375 		GList *mi;
376 		for (mi = pData->menu_items_list; mi != NULL; mi = mi->next)
377 		{
378 			DbusmenuMenuitem *pDbusMenuItem = mi->data;
379 			GtkMenuItem *pMenuItem = dbusmenu_gtkclient_menuitem_get (pData->client, pDbusMenuItem);
380 			gtk_menu_shell_append (GTK_MENU_SHELL(pMenu), GTK_WIDGET (pMenuItem));
381 			gtk_widget_show (GTK_WIDGET (pMenuItem));
382 		}
383 
384 		// when the menu is destroyed, the menu-items are destroyed too (even if we set a reference on them, their content will be unvalidated); so we must remove them from the menu before that happens.
385 		g_signal_connect (G_OBJECT (pMenu),
386 			"destroy",
387 			G_CALLBACK (_on_menu_destroyed),
388 			pData);
389 	}
390 	return GLDI_NOTIFICATION_LET_PASS;
391 }
392 
393 
root_child_added(DbusmenuMenuitem * root,DbusmenuMenuitem * child,guint position,CDIconData * pData)394 static void root_child_added (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint position, CDIconData *pData)
395 {
396 	cd_debug ("%s (%d)", __func__, position);
397 	pData->menu_items_list = g_list_insert (pData->menu_items_list, child, position);  // simply add it to the list, the associated menu-item will appear in the menu the next time the user right-clicks (we don't bother to refresh the menu in real-time).
398 }
399 
root_child_moved(DbusmenuMenuitem * root,DbusmenuMenuitem * child,guint newposition,guint oldposition,CDIconData * pData)400 static void root_child_moved (DbusmenuMenuitem * root, DbusmenuMenuitem * child, guint newposition, guint oldposition, CDIconData *pData)
401 {
402 	cd_debug ("%s (%d -> %d)", __func__, oldposition, newposition);
403 	GList *mi = g_list_nth (pData->menu_items_list, oldposition);
404 	pData->menu_items_list = g_list_remove_link (pData->menu_items_list, mi);
405 	pData->menu_items_list = g_list_insert (pData->menu_items_list, child, newposition);  // same remark
406 }
407 
root_child_delete(DbusmenuMenuitem * root,DbusmenuMenuitem * child,CDIconData * pData)408 static void root_child_delete (DbusmenuMenuitem * root, DbusmenuMenuitem * child, CDIconData *pData)
409 {
410 	cd_debug ("%s ()", __func__);
411 	pData->menu_items_list = g_list_remove (pData->menu_items_list, child);  // same remark
412 }
413 
root_changed(DbusmenuGtkClient * client,DbusmenuMenuitem * newroot,CDIconData * pData)414 static void root_changed (DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, CDIconData *pData)
415 {
416 	cd_debug ("%s (%p", __func__, newroot);
417 	if (newroot == NULL)
418 	{
419 		return;
420 	}
421 
422 	// get the current childs
423 	GList * child = NULL;
424 	for (child = dbusmenu_menuitem_get_children(newroot); child != NULL; child = g_list_next(child))
425 	{
426 		pData->menu_items_list = g_list_append (pData->menu_items_list, child->data);
427 	}
428 
429 	// watch for any new/updated/removed child
430 	g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_ADDED, G_CALLBACK(root_child_added), pData);
431 	g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_MOVED, G_CALLBACK(root_child_moved), pData);
432 	g_signal_connect(G_OBJECT(newroot), DBUSMENU_MENUITEM_SIGNAL_CHILD_REMOVED, G_CALLBACK(root_child_delete), pData);
433 }
434 
cd_dbus_main_set_menu(dbusMainObject * pDbusCallback,const gchar * cBusName,const gchar * cMenuPath,gchar * cIconQuery,GError ** error)435 gboolean cd_dbus_main_set_menu (dbusMainObject *pDbusCallback, const gchar *cBusName, const gchar *cMenuPath, gchar *cIconQuery, GError **error)
436 {
437 	GList *pList = cd_dbus_find_matching_icons (cIconQuery);
438 	if (pList == NULL)
439 		return TRUE;
440 
441 	cd_debug ("%s (%s , %s)", __func__, cBusName, cMenuPath);
442 	static gboolean s_bInit = FALSE;
443 	if (! s_bInit)  // register for right-click events once.
444 	{
445 		s_bInit = TRUE;
446 		gldi_object_register_notification (&myContainerObjectMgr,
447 			NOTIFICATION_BUILD_ICON_MENU,
448 			(GldiNotificationFunc) cd_dbus_main_emit_on_build_menu,
449 			GLDI_RUN_FIRST,
450 			NULL);
451 	}
452 
453 	if (cBusName && *cBusName == '\0')  // nullify empty object and path
454 		cBusName = NULL;
455 	if (cMenuPath && *cMenuPath == '\0')
456 		cMenuPath = NULL;
457 
458 	Icon *pIcon;
459 	GList *ic;
460 	for (ic = pList; ic != NULL; ic = ic->next)
461 	{
462 		pIcon = ic->data;
463 		CDIconData *pData = CD_APPLET_GET_MY_ICON_DATA (pIcon);
464 		if (pData == NULL)
465 		{
466 			pData = g_new0 (CDIconData, 1);
467 			CD_APPLET_SET_MY_ICON_DATA (pIcon, pData);
468 		}
469 
470 		if (! cairo_dock_strings_differ (pData->cMenuPath, cMenuPath)
471 		&& ! cairo_dock_strings_differ (pData->cBusName, cBusName))
472 			continue;  // same menu -> nothing to do
473 
474 		// remove any previous menu
475 		if (pData->cBusName)
476 		{
477 			cd_debug ("menu %s (%s) is removed", pData->cBusName, pData->cMenuPath);
478 			g_free (pData->cBusName);
479 			g_free (pData->cMenuPath);
480 
481 			g_list_free (pData->menu_items_list);
482 			pData->menu_items_list = NULL;
483 
484 			g_object_unref (pData->client);
485 			pData->client = NULL;
486 		}
487 
488 		// remember the current menu
489 		pData->cBusName = g_strdup (cBusName);
490 		pData->cMenuPath = g_strdup (cMenuPath);
491 
492 		// if a menu is set, build the client and wait for the root child to appear on our side of the bus.
493 		if (cBusName && cMenuPath && *cMenuPath != '\0')
494 		{
495 			cd_debug ("new menu %s (%s)", cBusName, cMenuPath);
496 			pData->client = dbusmenu_gtkclient_new(pData->cBusName, pData->cMenuPath);
497 			g_signal_connect(G_OBJECT(pData->client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(root_changed), pData);
498 		}
499 	}
500 
501 	g_list_free (pList);
502 	return TRUE;
503 }
504 #else
cd_dbus_main_set_menu(dbusMainObject * pDbusCallback,const gchar * cBusName,const gchar * cMenuPath,gchar * cIconQuery,GError ** error)505 gboolean cd_dbus_main_set_menu (dbusMainObject *pDbusCallback, const gchar *cBusName, const gchar *cMenuPath, gchar *cIconQuery, GError **error)
506 {
507 	g_set_error (error, 1, 1, "Cairo-Dock has not been compiled with DbusMenu support, so The 'SetMenu' method won't work.");
508 	return FALSE;
509 }
510 #endif
511 
512 
cd_dbus_main_set_progress(dbusMainObject * dbusMainObject,double fPercent,gchar * cIconQuery,GError ** error)513 gboolean cd_dbus_main_set_progress (dbusMainObject *dbusMainObject, double fPercent, gchar *cIconQuery, GError **error)
514 {
515 	GList *pList = cd_dbus_find_matching_icons (cIconQuery);
516 	if (pList == NULL)
517 		return TRUE;
518 
519 	Icon *pIcon;
520 	GList *ic;
521 	for (ic = pList; ic != NULL; ic = ic->next)
522 	{
523 		pIcon = ic->data;
524 
525 		if (cairo_dock_get_icon_data_renderer (pIcon) == NULL)
526 		{
527 			CairoProgressBarAttribute attr;
528 			memset (&attr, 0, sizeof (CairoProgressBarAttribute));
529 			CairoDataRendererAttribute *pRenderAttr = CAIRO_DATA_RENDERER_ATTRIBUTE (&attr);
530 			pRenderAttr->cModelName = "progressbar";
531 			cairo_dock_add_new_data_renderer_on_icon (pIcon, pIcon->pContainer, pRenderAttr);
532 		}
533 
534 		if (fPercent < 0)
535 			fPercent = CAIRO_DATA_RENDERER_UNDEF_VALUE;
536 		cairo_dock_render_new_data_on_icon (pIcon, pIcon->pContainer, NULL, &fPercent);
537 	}
538 	g_list_free (pList);
539 	return TRUE;
540 }
541 
542 
543   ///////////
544  /// ADD ///
545 ///////////
546 
cd_dbus_main_add(dbusMainObject * pDbusCallback,GHashTable * pProperties,gchar ** cConfigFile,GError ** error)547 gboolean cd_dbus_main_add (dbusMainObject *pDbusCallback, GHashTable *pProperties, gchar **cConfigFile, GError **error)
548 {
549 	GValue *v;
550 	const gchar *cType = "";
551 	v = g_hash_table_lookup (pProperties, "type");
552 	if (v && G_VALUE_HOLDS_STRING (v))
553 		cType = g_value_get_string (v);
554 	CDMainType iType = cd_dbus_get_main_type (cType, -1);
555 
556 	switch (iType)
557 	{
558 		case CD_MAIN_TYPE_ICON:
559 		{
560 			// get the dock
561 			const gchar *cDockName = NULL;
562 			v = g_hash_table_lookup (pProperties, "container");
563 			if (v && G_VALUE_HOLDS_STRING (v))
564 				cDockName = g_value_get_string (v);
565 			if (cDockName == NULL)
566 				cDockName = CAIRO_DOCK_MAIN_DOCK_NAME;
567 			CairoDock *pParentDock = gldi_dock_get (cDockName);
568 			if (pParentDock == NULL)
569 			{
570 				cd_warning ("dock %s does not exist", cDockName);
571 				pParentDock = g_pMainDock;
572 			}
573 
574 			// get the order
575 			double fOrder = 0;
576 			v = g_hash_table_lookup (pProperties, "order");
577 			if (v)
578 			{
579 				if (G_VALUE_HOLDS_DOUBLE (v))
580 					fOrder = g_value_get_double (v);
581 				else if (G_VALUE_HOLDS_INT (v))
582 					fOrder = g_value_get_int (v);
583 				if (fOrder < 0)
584 					fOrder = CAIRO_DOCK_LAST_ORDER;
585 			}
586 			else  // no order defined, look for a position
587 			{
588 				v = g_hash_table_lookup (pProperties, "position");  // this option is especially useful for tests, when you need to know exactly where an icon will be
589 				if (v && G_VALUE_HOLDS_INT (v))
590 				{
591 					int iPosition = g_value_get_int (v);
592 					if (iPosition >= 0)
593 					{
594 						int i;
595 						GList *ic;
596 						Icon *icon;
597 						for (ic = pParentDock->icons, i = 0; ic != NULL && i < iPosition; ic = ic->next)
598 						{
599 							icon = ic->data;
600 							if (GLDI_OBJECT_IS_AUTO_SEPARATOR_ICON (icon))
601 								continue;
602 							i ++;
603 						}
604 						if (ic != NULL)
605 						{
606 							Icon *pPrevIcon = (ic->prev ? ic->prev->data : NULL);
607 							Icon *pNextIcon = ic->data;
608 							if (pPrevIcon == NULL)
609 								fOrder = pNextIcon->fOrder - 1;
610 							else if (cairo_dock_get_icon_order (pNextIcon) != cairo_dock_get_icon_order (pPrevIcon))
611 								fOrder = pPrevIcon->fOrder + 1;
612 							else
613 								fOrder = (pNextIcon->fOrder + pPrevIcon->fOrder) / 2;
614 						}
615 						else  // at the end
616 							fOrder = CAIRO_DOCK_LAST_ORDER;
617 					}
618 				}
619 			}
620 
621 			Icon *pNewIcon = NULL;
622 			if (strcmp (cType, CD_TYPE_LAUNCHER) == 0)
623 			{
624 				const gchar *cDesktopFile = NULL;
625 				v = g_hash_table_lookup (pProperties, "config-file");
626 				if (v && G_VALUE_HOLDS_STRING (v))
627 					cDesktopFile = g_value_get_string (v);
628 
629 				if (cDesktopFile != NULL)
630 				{
631 					pNewIcon = gldi_launcher_add_new (cDesktopFile, pParentDock, fOrder);
632 				}
633 				else
634 				{
635 					pNewIcon = gldi_launcher_add_new (NULL, pParentDock, fOrder);
636 
637 					// get additional properties
638 					const gchar *cName = NULL;
639 					v = g_hash_table_lookup (pProperties, "name");
640 					if (v && G_VALUE_HOLDS_STRING (v))
641 						cName = g_value_get_string (v);
642 					const gchar *cIcon = NULL;
643 					v = g_hash_table_lookup (pProperties, "icon");
644 					if (v && G_VALUE_HOLDS_STRING (v))
645 						cIcon = g_value_get_string (v);
646 					const gchar *cCommand = NULL;
647 					v = g_hash_table_lookup (pProperties, "command");
648 					if (v && G_VALUE_HOLDS_STRING (v))
649 						cCommand = g_value_get_string (v);
650 					const gchar *cClass = NULL;
651 					v = g_hash_table_lookup (pProperties, "class");
652 					if (v && G_VALUE_HOLDS_STRING (v))
653 						cClass = g_value_get_string (v);
654 
655 					// open the conf-file and set the fields.
656 					gchar *cConfFilePath = (*pNewIcon->cDesktopFileName == '/' ? g_strdup (pNewIcon->cDesktopFileName) : g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, pNewIcon->cDesktopFileName));
657 					GKeyFile *pKeyFile = cairo_dock_open_key_file (cConfFilePath);
658 
659 					if (cName)
660 						g_key_file_set_string (pKeyFile, "Desktop Entry", "Name", cName);
661 
662 					if (cIcon)
663 						g_key_file_set_string (pKeyFile, "Desktop Entry", "Icon", cIcon);
664 
665 					if (cCommand)
666 						g_key_file_set_string (pKeyFile, "Desktop Entry", "Exec", cCommand);
667 
668 					if (cClass)
669 						g_key_file_set_string (pKeyFile, "Desktop Entry", "StartupWMClass", cClass);
670 
671 					cairo_dock_write_keys_to_file (pKeyFile, cConfFilePath);
672 
673 					g_key_file_free (pKeyFile);
674 					g_free (cConfFilePath);
675 					gldi_object_reload (GLDI_OBJECT(pNewIcon), TRUE);
676 				}
677 			}
678 			else if (strcmp (cType, CD_TYPE_SEPARATOR) == 0)
679 			{
680 				pNewIcon = gldi_separator_icon_add_new (pParentDock, fOrder);
681 			}
682 			else if (strcmp (cType, CD_TYPE_STACK_ICON) == 0)
683 			{
684 				pNewIcon = gldi_stack_icon_add_new (pParentDock, fOrder);
685 
686 				// get additional properties
687 				const gchar *cName = NULL;
688 				v = g_hash_table_lookup (pProperties, "name");
689 				if (v && G_VALUE_HOLDS_STRING (v))
690 					cName = g_value_get_string (v);
691 				const gchar *cIcon = NULL;
692 				v = g_hash_table_lookup (pProperties, "icon");
693 				if (v && G_VALUE_HOLDS_STRING (v))
694 					cIcon = g_value_get_string (v);
695 
696 				// open the conf-file and set the fields.
697 				gchar *cConfFilePath = (*pNewIcon->cDesktopFileName == '/' ? g_strdup (pNewIcon->cDesktopFileName) : g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, pNewIcon->cDesktopFileName));
698 				GKeyFile *pKeyFile = cairo_dock_open_key_file (cConfFilePath);
699 
700 				if (cName)
701 					g_key_file_set_string (pKeyFile, "Desktop Entry", "Name", cName);
702 
703 				if (cIcon)
704 					g_key_file_set_string (pKeyFile, "Desktop Entry", "Icon", cIcon);
705 
706 				cairo_dock_write_keys_to_file (pKeyFile, cConfFilePath);
707 
708 				g_key_file_free (pKeyFile);
709 				g_free (cConfFilePath);
710 				gldi_object_reload (GLDI_OBJECT(pNewIcon), TRUE);
711 			}
712 			else
713 			{
714 				g_set_error (error, 1, 1, "can't add an icon of type '%s'", cType);
715 				return FALSE;
716 			}
717 			if (pNewIcon != NULL && pNewIcon->cDesktopFileName != NULL)
718 				*cConfigFile = (*pNewIcon->cDesktopFileName == '/' ? g_strdup (pNewIcon->cDesktopFileName) : g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, pNewIcon->cDesktopFileName));
719 		}
720 		break;
721 
722 		case CD_MAIN_TYPE_CONTAINER:
723 		{
724 			if (strcmp (cType, CD_TYPE_DOCK) == 0)
725 			{
726 				gchar *cDockName = gldi_dock_add_conf_file ();
727 				CairoDock *pDock = gldi_dock_new (cDockName);
728 				if (!pDock)
729 					return FALSE;
730 				*cConfigFile = g_strdup_printf ("%s/%s.conf", g_cCurrentThemePath, cDockName);
731 				g_free (cDockName);
732 			}
733 			else
734 			{
735 				g_set_error (error, 1, 1, "can't add a desklet, add a module-instance instead");
736 				return FALSE;
737 			}
738 		}
739 		break;
740 		case CD_MAIN_TYPE_MODULE:
741 		{
742 			const gchar *cModuleName = NULL;
743 			v = g_hash_table_lookup (pProperties, "module");
744 			if (v && G_VALUE_HOLDS_STRING (v))
745 				cModuleName = g_value_get_string (v);
746 
747 			GldiModule *pModule = gldi_module_get (cModuleName);
748 			if (pModule == NULL)
749 			{
750 				g_set_error (error, 1, 1, "no such module (%s)", cModuleName);
751 				return FALSE;
752 			}
753 			if (pModule->pInstancesList == NULL)
754 				gldi_module_activate (pModule);
755 		}
756 		break;
757 		case CD_MAIN_TYPE_MODULE_INSTANCE:
758 		{
759 			const gchar *cModuleName = NULL;
760 			v = g_hash_table_lookup (pProperties, "module");
761 			if (v && G_VALUE_HOLDS_STRING (v))
762 				cModuleName = g_value_get_string (v);
763 
764 			GldiModule *pModule = gldi_module_get (cModuleName);
765 			if (pModule == NULL)
766 			{
767 				g_set_error (error, 1, 1, "no such module (%s)", cModuleName);
768 				return FALSE;
769 			}
770 
771 			if (pModule->pInstancesList == NULL)
772 			{
773 				gldi_module_activate (pModule);
774 			}
775 			else if (pModule->pVisitCard->bMultiInstance)
776 			{
777 				gldi_module_add_instance (pModule);
778 			}
779 			if (pModule->pInstancesList)
780 			{
781 				GldiModuleInstance *pModuleInstance = pModule->pInstancesList->data;  // prepend
782 				*cConfigFile = g_strdup (pModuleInstance->cConfFilePath);
783 			}
784 		}
785 		break;
786 		default:
787 			g_set_error (error, 1, 1, "Unknown type (%s)", cType);
788 			return FALSE;
789 		break;
790 	}
791 
792 	return TRUE;
793 }
794 
795 
796   //////////////
797  /// RELOAD ///
798 //////////////
799 
cd_dbus_main_reload(dbusMainObject * pDbusCallback,gchar * cQuery,GError ** error)800 gboolean cd_dbus_main_reload (dbusMainObject *pDbusCallback, gchar *cQuery, GError **error)
801 {
802 	GList *pObjects = cd_dbus_find_matching_objects (cQuery);
803 	GList *o;
804 	GldiObject *obj;
805 	for (o = pObjects; o != NULL; o = o->next)
806 	{
807 		obj = o->data;
808 		gldi_object_reload (obj, TRUE);
809 	}
810 	g_list_free (pObjects);
811 	return TRUE;
812 }
813 
814 
815   //////////////
816  /// REMOVE ///
817 //////////////
818 
_on_object_deleted(GList * o,G_GNUC_UNUSED GldiObject * obj)819 static gboolean _on_object_deleted (GList *o, G_GNUC_UNUSED GldiObject *obj)
820 {
821 	o->data = NULL;
822 	return GLDI_NOTIFICATION_LET_PASS;
823 }
cd_dbus_main_remove(dbusMainObject * pDbusCallback,gchar * cQuery,GError ** error)824 gboolean cd_dbus_main_remove (dbusMainObject *pDbusCallback, gchar *cQuery, GError **error)
825 {
826 	GList *pObjects = cd_dbus_find_matching_objects (cQuery);
827 
828 	// first connect to the "delete" signal, to not destroy 2 times an icon (case of an icon in a sub-dock that is destroyed just before).
829 	GldiObject *obj;
830 	GList *o;
831 	for (o = pObjects; o != NULL; o = o->next)
832 	{
833 		obj = o->data;
834 		gldi_object_register_notification (obj,
835 			NOTIFICATION_DESTROY,
836 			(GldiNotificationFunc) _on_object_deleted,
837 			GLDI_RUN_FIRST, o);
838 	}
839 
840 	for (o = pObjects; o != NULL; o = o->next)
841 	{
842 		obj = o->data;
843 		if (! obj)  // has been deleted by a previous object destruction
844 			continue;
845 		gldi_object_delete (obj);
846 	}
847 	g_list_free (pObjects);
848 	return TRUE;
849 }
850 
851 
852   //////////////////
853  /// PROPERTIES ///
854 //////////////////
855 
_add_icon_properties(Icon * pIcon,GPtrArray * pTab)856 static void _add_icon_properties (Icon *pIcon, GPtrArray *pTab)
857 {
858 	GldiContainer *pContainer = cairo_dock_get_icon_container (pIcon);
859 
860 	GHashTable *h = g_hash_table_new_full (g_str_hash,
861 		g_str_equal,
862 		NULL,
863 		g_free);
864 	g_ptr_array_add (pTab, h);
865 
866 	GValue *v;
867 	int iPosition;
868 	const gchar *cType;
869 	const gchar *cContainerName;
870 	const gchar *cDesktopFile;
871 
872 	if (CAIRO_DOCK_ICON_TYPE_IS_LAUNCHER (pIcon))
873 		cType = CD_TYPE_LAUNCHER;
874 	else if (CAIRO_DOCK_ICON_TYPE_IS_APPLI (pIcon))
875 		cType = CD_TYPE_APPLICATION;
876 	else if (CAIRO_DOCK_ICON_TYPE_IS_APPLET (pIcon))
877 		cType = CD_TYPE_APPLET;
878 	else if (CAIRO_DOCK_ICON_TYPE_IS_SEPARATOR (pIcon))
879 		cType = CD_TYPE_SEPARATOR;
880 	else if (CAIRO_DOCK_ICON_TYPE_IS_CONTAINER (pIcon))
881 		cType = CD_TYPE_STACK_ICON;
882 	else if (CAIRO_DOCK_ICON_TYPE_IS_CLASS_CONTAINER (pIcon))
883 		cType = CD_TYPE_CLASS_ICON;
884 	else
885 		cType = CD_TYPE_ICON_OTHER;
886 	v = g_new0 (GValue, 1);
887 	g_value_init (v, G_TYPE_STRING);
888 	g_value_set_string (v, cType);
889 	g_hash_table_insert (h, "type", v);
890 
891 	cDesktopFile = "";
892 	if (pIcon->cDesktopFileName != NULL)
893 		cDesktopFile = pIcon->cDesktopFileName;
894 	else if (CAIRO_DOCK_IS_APPLET (pIcon))
895 		cDesktopFile = pIcon->pModuleInstance->cConfFilePath;
896 	v = g_new0 (GValue, 1);
897 	g_value_init (v, G_TYPE_STRING);
898 	g_value_set_string (v, cDesktopFile);
899 	g_hash_table_insert (h, "config-file", v);
900 
901 	if (CAIRO_DOCK_IS_APPLET (pIcon))
902 	{
903 		v = g_new0 (GValue, 1);
904 		g_value_init (v, G_TYPE_STRING);
905 		g_value_set_string (v, pIcon->pModuleInstance->pModule->pVisitCard->cModuleName);
906 		g_hash_table_insert (h, "module", v);
907 	}
908 
909 	v = g_new0 (GValue, 1);
910 	g_value_init (v, G_TYPE_STRING);
911 	g_value_set_string (v, pIcon->cName);  /// g_value_set_static_string ?...
912 	g_hash_table_insert (h, "name", v);
913 
914 	v = g_new0 (GValue, 1);
915 	g_value_init (v, G_TYPE_STRING);
916 	g_value_set_string (v, pIcon->cCommand);
917 	g_hash_table_insert (h, "command", v);
918 
919 	v = g_new0 (GValue, 1);
920 	g_value_init (v, G_TYPE_STRING);
921 	g_value_set_string (v, pIcon->cClass);
922 	g_hash_table_insert (h, "class", v);
923 
924 	v = g_new0 (GValue, 1);
925 	g_value_init (v, G_TYPE_STRING);
926 	g_value_set_string (v, pIcon->cFileName);
927 	g_hash_table_insert (h, "icon", v);
928 
929 	v = g_new0 (GValue, 1);
930 	g_value_init (v, G_TYPE_STRING);
931 	g_value_set_string (v, pIcon->cQuickInfo);
932 	g_hash_table_insert (h, "quick-info", v);
933 
934 	v = g_new0 (GValue, 1);
935 	g_value_init (v, G_TYPE_UINT);
936 	int id = gldi_window_get_id (pIcon->pAppli);
937 	g_value_set_uint (v, GPOINTER_TO_INT(id));
938 	g_hash_table_insert (h, "Xid", v);
939 
940 	iPosition = -1;
941 	cContainerName = "";
942 	if (CAIRO_DOCK_IS_DOCK (pContainer))
943 	{
944 		CairoDock *pDock = CAIRO_DOCK (pContainer);
945 		iPosition = g_list_index (pDock->icons, pIcon);
946 		cContainerName = gldi_dock_get_name (pDock);
947 	}
948 	else if (CAIRO_DOCK_IS_DESKLET (pContainer))
949 	{
950 		CairoDesklet *pDesklet = CAIRO_DESKLET (pContainer);
951 		if (pDesklet->pIcon == pIcon)
952 			iPosition = 0;
953 		else
954 			iPosition = g_list_index (pDesklet->icons, pIcon);
955 		if (CAIRO_DOCK_IS_APPLET (pDesklet->pIcon))
956 			cContainerName = pDesklet->pIcon->pModuleInstance->pModule->pVisitCard->cModuleName;
957 	}
958 	v = g_new0 (GValue, 1);
959 	g_value_init (v, G_TYPE_INT);
960 	g_value_set_int (v, iPosition);
961 	g_hash_table_insert (h, "position", v);
962 
963 	v = g_new0 (GValue, 1);
964 	g_value_init (v, G_TYPE_STRING);
965 	g_value_set_string (v, cContainerName);
966 	g_hash_table_insert (h, "container", v);
967 
968 	v = g_new0 (GValue, 1);
969 	g_value_init (v, G_TYPE_DOUBLE);
970 	g_value_set_double (v, pIcon->fOrder);
971 	g_hash_table_insert (h, "order", v);
972 }
973 
_add_module_properties(GldiModule * pModule,GPtrArray * pTab)974 static void _add_module_properties (GldiModule *pModule, GPtrArray *pTab)
975 {
976 	GHashTable *h = g_hash_table_new_full (g_str_hash,
977 		g_str_equal,
978 		NULL,
979 		g_free);
980 	g_ptr_array_add (pTab, h);
981 
982 	GValue *v;
983 
984 	v = g_new0 (GValue, 1);
985 	g_value_init (v, G_TYPE_STRING);
986 	g_value_set_string (v, "Module");
987 	g_hash_table_insert (h, "type", v);
988 
989 	v = g_new0 (GValue, 1);
990 	g_value_init (v, G_TYPE_STRING);
991 	g_value_set_string (v, pModule->pVisitCard->cModuleName);
992 	g_hash_table_insert (h, "name", v);
993 
994 	v = g_new0 (GValue, 1);
995 	g_value_init (v, G_TYPE_UINT);
996 	g_value_set_uint (v, pModule->pVisitCard->iContainerType);
997 	g_hash_table_insert (h, "module-type", v);
998 
999 	v = g_new0 (GValue, 1);
1000 	g_value_init (v, G_TYPE_UINT);
1001 	g_value_set_uint (v, pModule->pVisitCard->iCategory);
1002 	g_hash_table_insert (h, "category", v);
1003 
1004 	v = g_new0 (GValue, 1);
1005 	g_value_init (v, G_TYPE_STRING);
1006 	g_value_set_string (v, pModule->pVisitCard->cTitle);
1007 	g_hash_table_insert (h, "title", v);
1008 
1009 	v = g_new0 (GValue, 1);
1010 	g_value_init (v, G_TYPE_STRING);
1011 	g_value_set_string (v, pModule->pVisitCard->cIconFilePath);
1012 	g_hash_table_insert (h, "icon", v);
1013 
1014 	v = g_new0 (GValue, 1);
1015 	g_value_init (v, G_TYPE_STRING);
1016 	g_value_set_string (v, pModule->pVisitCard->cPreviewFilePath);
1017 	g_hash_table_insert (h, "preview", v);
1018 
1019 	v = g_new0 (GValue, 1);
1020 	g_value_init (v, G_TYPE_STRING);
1021 	g_value_set_string (v, dgettext (pModule->pVisitCard->cGettextDomain, pModule->pVisitCard->cDescription));
1022 	g_hash_table_insert (h, "description", v);
1023 
1024 	v = g_new0 (GValue, 1);
1025 	g_value_init (v, G_TYPE_STRING);
1026 	g_value_set_string (v, pModule->pVisitCard->cAuthor);
1027 	g_hash_table_insert (h, "author", v);
1028 
1029 	v = g_new0 (GValue, 1);
1030 	g_value_init (v, G_TYPE_BOOLEAN);
1031 	g_value_set_boolean (v, pModule->pVisitCard->bMultiInstance);
1032 	g_hash_table_insert (h, "is-multi-instance", v);
1033 
1034 	cd_debug ("list instances ...");
1035 	gchar **pInstances = g_new0 (gchar*, g_list_length (pModule->pInstancesList)+1);
1036 	GldiModuleInstance *pInstance;
1037 	int i = 0;
1038 	GList *mi;
1039 	for (mi = pModule->pInstancesList; mi != NULL; mi = mi->next)
1040 	{
1041 		pInstance = mi->data;
1042 		pInstances[i++] = g_strdup (pInstance->cConfFilePath);
1043 	}
1044 	cd_debug ("write instances ...");
1045 	v = g_new0 (GValue, 1);
1046 	g_value_init (v, G_TYPE_STRV);
1047 	g_value_set_boxed (v, pInstances);
1048 	g_hash_table_insert (h, "instances", v);
1049 	cd_debug ("done.");
1050 }
1051 
_add_manager_properties(GldiManager * pManager,GPtrArray * pTab)1052 static void _add_manager_properties (GldiManager *pManager, GPtrArray *pTab)
1053 {
1054 	GHashTable *h = g_hash_table_new_full (g_str_hash,
1055 		g_str_equal,
1056 		NULL,
1057 		g_free);
1058 	g_ptr_array_add (pTab, h);
1059 
1060 	GValue *v;
1061 
1062 	v = g_new0 (GValue, 1);
1063 	g_value_init (v, G_TYPE_STRING);
1064 	g_value_set_string (v, CD_TYPE_MANAGER);
1065 	g_hash_table_insert (h, "type", v);
1066 
1067 	v = g_new0 (GValue, 1);
1068 	g_value_init (v, G_TYPE_STRING);
1069 	g_value_set_string (v, pManager->cModuleName);
1070 	g_hash_table_insert (h, "name", v);
1071 
1072 	v = g_new0 (GValue, 1);
1073 	g_value_init (v, G_TYPE_STRING);
1074 	g_value_set_string (v, g_cConfFile);
1075 	g_hash_table_insert (h, "config-file", v);
1076 }
1077 
_set_container_properties(GldiContainer * pContainer,GHashTable * h)1078 static void _set_container_properties (GldiContainer *pContainer, GHashTable *h)
1079 {
1080 	GValue *v;
1081 	int x, y, w, ht;
1082 	if (pContainer->bIsHorizontal)
1083 	{
1084 		x = pContainer->iWindowPositionX;
1085 		y = pContainer->iWindowPositionY;
1086 		w = pContainer->iWidth;
1087 		ht = pContainer->iHeight;
1088 	}
1089 	else
1090 	{
1091 		y = pContainer->iWindowPositionX;
1092 		x = pContainer->iWindowPositionY;
1093 		ht = pContainer->iWidth;
1094 		w = pContainer->iHeight;
1095 	}
1096 	v = g_new0 (GValue, 1);
1097 	g_value_init (v, G_TYPE_INT);
1098 	g_value_set_int (v, x);
1099 	g_hash_table_insert (h, "x", v);
1100 
1101 	v = g_new0 (GValue, 1);
1102 	g_value_init (v, G_TYPE_INT);
1103 	g_value_set_int (v, y);
1104 	g_hash_table_insert (h, "y", v);
1105 
1106 	v = g_new0 (GValue, 1);
1107 	g_value_init (v, G_TYPE_INT);
1108 	g_value_set_int (v, w);
1109 	g_hash_table_insert (h, "width", v);
1110 
1111 	v = g_new0 (GValue, 1);
1112 	g_value_init (v, G_TYPE_INT);
1113 	g_value_set_int (v, ht);
1114 	g_hash_table_insert (h, "height", v);
1115 
1116 	CairoDockPositionType iScreenBorder = ((! pContainer->bIsHorizontal) << 1) | (! pContainer->bDirectionUp);
1117 	v = g_new0 (GValue, 1);
1118 	g_value_init (v, G_TYPE_UINT);
1119 	g_value_set_uint (v, iScreenBorder);
1120 	g_hash_table_insert (h, "orientation", v);
1121 }
1122 
_add_dock_properties(CairoDock * pDock,GPtrArray * pTab)1123 static void _add_dock_properties (CairoDock *pDock, GPtrArray *pTab)
1124 {
1125 	GHashTable *h = g_hash_table_new_full (g_str_hash,
1126 		g_str_equal,
1127 		NULL,
1128 		g_free);
1129 	g_ptr_array_add (pTab, h);
1130 
1131 	GValue *v;
1132 
1133 	v = g_new0 (GValue, 1);
1134 	g_value_init (v, G_TYPE_STRING);
1135 	g_value_set_string (v, CD_TYPE_DOCK);
1136 	g_hash_table_insert (h, "type", v);
1137 
1138 	const gchar *cDockName = gldi_dock_get_name (pDock);
1139 	v = g_new0 (GValue, 1);
1140 	g_value_init (v, G_TYPE_STRING);
1141 	g_value_set_string (v, cDockName);
1142 	g_hash_table_insert (h, "name", v);
1143 
1144 	v = g_new0 (GValue, 1);
1145 	g_value_init (v, G_TYPE_BOOLEAN);
1146 	g_value_set_boolean (v, (pDock->iRefCount > 0));
1147 	g_hash_table_insert (h, "is-sub-dock", v);
1148 
1149 	v = g_new0 (GValue, 1);
1150 	g_value_init (v, G_TYPE_INT);
1151 	g_value_set_int (v, g_list_length (pDock->icons));
1152 	g_hash_table_insert (h, "nb-icons", v);
1153 
1154 	if (pDock->iRefCount == 0 && ! pDock->bIsMainDock)
1155 	{
1156 		gchar *cConfFilePath = g_strdup_printf ("%s/%s.conf", g_cCurrentThemePath, cDockName);
1157 		v = g_new0 (GValue, 1);
1158 		g_value_init (v, G_TYPE_STRING);
1159 		g_value_set_string (v, cConfFilePath);
1160 		g_hash_table_insert (h, "config-file", v);
1161 		g_free (cConfFilePath);
1162 	}
1163 
1164 	_set_container_properties (CAIRO_CONTAINER (pDock), h);
1165 }
1166 
_add_desklet_properties(CairoDesklet * pDesklet,GPtrArray * pTab)1167 static void _add_desklet_properties (CairoDesklet *pDesklet, GPtrArray *pTab)
1168 {
1169 	GHashTable *h = g_hash_table_new_full (g_str_hash,
1170 		g_str_equal,
1171 		NULL,
1172 		g_free);
1173 	g_ptr_array_add (pTab, h);
1174 
1175 	GValue *v;
1176 
1177 	v = g_new0 (GValue, 1);
1178 	g_value_init (v, G_TYPE_STRING);
1179 	g_value_set_string (v, CD_TYPE_DESKLET);
1180 	g_hash_table_insert (h, "type", v);
1181 
1182 	v = g_new0 (GValue, 1);
1183 	g_value_init (v, G_TYPE_STRING);
1184 	g_value_set_string (v, CAIRO_DOCK_IS_APPLET (pDesklet->pIcon) ? pDesklet->pIcon->pModuleInstance->pModule->pVisitCard->cModuleName : "");
1185 	g_hash_table_insert (h, "name", v);
1186 
1187 	v = g_new0 (GValue, 1);
1188 	g_value_init (v, G_TYPE_INT);
1189 	g_value_set_int (v, 1 + g_list_length (pDesklet->icons));
1190 	g_hash_table_insert (h, "nb-icons", v);
1191 
1192 	_set_container_properties (CAIRO_CONTAINER (pDesklet), h);
1193 }
1194 
_add_module_instance_properties(GldiModuleInstance * pModuleInstance,GPtrArray * pTab)1195 static void _add_module_instance_properties (GldiModuleInstance *pModuleInstance, GPtrArray *pTab)
1196 {
1197 	GHashTable *h = g_hash_table_new_full (g_str_hash,
1198 		g_str_equal,
1199 		NULL,
1200 		g_free);
1201 	g_ptr_array_add (pTab, h);
1202 
1203 	GValue *v;
1204 
1205 	v = g_new0 (GValue, 1);
1206 	g_value_init (v, G_TYPE_STRING);
1207 	g_value_set_string (v, CD_TYPE_MODULE_INSTANCE);
1208 	g_hash_table_insert (h, "type", v);
1209 
1210 	v = g_new0 (GValue, 1);
1211 	g_value_init (v, G_TYPE_STRING);
1212 	g_value_set_string (v, pModuleInstance->pModule->pVisitCard->cModuleName);
1213 	g_hash_table_insert (h, "name", v);
1214 
1215 	v = g_new0 (GValue, 1);
1216 	g_value_init (v, G_TYPE_STRING);
1217 	g_value_set_string (v, pModuleInstance->cConfFilePath);
1218 	g_hash_table_insert (h, "config-file", v);
1219 }
1220 
cd_dbus_main_get_properties(dbusMainObject * pDbusCallback,gchar * cQuery,GPtrArray ** pAttributes,GError ** error)1221 gboolean cd_dbus_main_get_properties (dbusMainObject *pDbusCallback, gchar *cQuery, GPtrArray **pAttributes, GError **error)
1222 {
1223 	GPtrArray *pTab = g_ptr_array_new ();
1224 	*pAttributes = pTab;
1225 
1226 	GList *pObjects = cd_dbus_find_matching_objects (cQuery);
1227 	GList *o;
1228 	GldiObject *obj;
1229 	for (o = pObjects; o != NULL; o = o->next)
1230 	{
1231 		obj = o->data;
1232 		if (CAIRO_DOCK_IS_ICON (obj))
1233 		{
1234 			Icon *pIcon = (Icon*)obj;
1235 			_add_icon_properties (pIcon, pTab);
1236 		}
1237 		else if (CAIRO_DOCK_IS_CONTAINER (obj))
1238 		{
1239 			if (CAIRO_DOCK_IS_DOCK (obj))
1240 			{
1241 				CairoDock *pDock = CAIRO_DOCK (obj);
1242 				_add_dock_properties (pDock, pTab);
1243 			}
1244 			else if (CAIRO_DOCK_IS_DESKLET (obj))
1245 			{
1246 				CairoDesklet *pDesklet = CAIRO_DESKLET (obj);
1247 				_add_desklet_properties (pDesklet, pTab);
1248 			}
1249 		}
1250 		else if (GLDI_OBJECT_IS_MODULE (obj))
1251 		{
1252 			GldiModule *pModule = (GldiModule *)obj;
1253 			_add_module_properties (pModule, pTab);
1254 		}
1255 		else if (GLDI_OBJECT_IS_MANAGER (obj))
1256 		{
1257 			GldiManager *pManager = (GldiManager *)obj;
1258 			_add_manager_properties (pManager, pTab);
1259 		}
1260 		else if (GLDI_OBJECT_IS_MODULE_INSTANCE (obj))
1261 		{
1262 			GldiModuleInstance *pModuleInstance = (GldiModuleInstance *)obj;
1263 			_add_module_instance_properties (pModuleInstance, pTab);
1264 		}
1265 	}
1266 	g_list_free (pObjects);
1267 	return TRUE;
1268 }
1269