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 #include <glib.h>
21 #include <dbus/dbus-glib.h>
22 #include <dbus/dbus-glib-bindings.h>
23
24 #include "applet-dbus.h"
25 #include "interface-applet-methods.h"
26 #include "interface-applet-object.h"
27 #include "interface-applet-signals.h"
28
29 static guint s_iSignals[NB_SIGNALS] = { 0 };
30 static guint s_iSubSignals[NB_SIGNALS] = { 0 };
31
32
cd_dbus_applet_init_signals_once(dbusAppletClass * klass)33 void cd_dbus_applet_init_signals_once (dbusAppletClass *klass)
34 {
35 static gboolean bFirst = TRUE;
36 if (! bFirst)
37 return;
38 bFirst = FALSE;
39
40 // Enregistrement des marshaller specifique aux signaux.
41 dbus_g_object_register_marshaller(cd_dbus_marshal_VOID__VALUE,
42 G_TYPE_NONE, G_TYPE_VALUE, G_TYPE_INVALID); // answer
43 dbus_g_object_register_marshaller(cd_dbus_marshal_VOID__INT_VALUE,
44 G_TYPE_NONE, G_TYPE_INT, G_TYPE_VALUE, G_TYPE_INVALID); // answer_dialog
45
46 // on definit les signaux dont on aura besoin.
47 s_iSignals[CLIC] =
48 g_signal_new("on_click",
49 G_OBJECT_CLASS_TYPE(klass),
50 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
51 0,
52 NULL, NULL,
53 cd_dbus_marshal_VOID__INT,
54 G_TYPE_NONE, 1, G_TYPE_INT);
55 s_iSignals[MIDDLE_CLIC] =
56 g_signal_new("on_middle_click",
57 G_OBJECT_CLASS_TYPE(klass),
58 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
59 0,
60 NULL, NULL,
61 cd_dbus_marshal_VOID__VOID,
62 G_TYPE_NONE, 0, G_TYPE_NONE);
63 s_iSignals[SCROLL] =
64 g_signal_new("on_scroll",
65 G_OBJECT_CLASS_TYPE(klass),
66 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
67 0,
68 NULL, NULL,
69 cd_dbus_marshal_VOID__BOOLEAN,
70 G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
71 s_iSignals[BUILD_MENU] =
72 g_signal_new("on_build_menu",
73 G_OBJECT_CLASS_TYPE(klass),
74 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
75 0,
76 NULL, NULL,
77 cd_dbus_marshal_VOID__VOID,
78 G_TYPE_NONE, 0, G_TYPE_NONE);
79 s_iSignals[MENU_SELECT] =
80 g_signal_new("on_menu_select",
81 G_OBJECT_CLASS_TYPE(klass),
82 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
83 0,
84 NULL, NULL,
85 cd_dbus_marshal_VOID__INT,
86 G_TYPE_NONE, 1, G_TYPE_INT);
87 s_iSignals[DROP_DATA] =
88 g_signal_new("on_drop_data",
89 G_OBJECT_CLASS_TYPE(klass),
90 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
91 0,
92 NULL, NULL,
93 cd_dbus_marshal_VOID__STRING,
94 G_TYPE_NONE, 1, G_TYPE_STRING);
95 s_iSignals[CHANGE_FOCUS] =
96 g_signal_new("on_change_focus",
97 G_OBJECT_CLASS_TYPE(klass),
98 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
99 0,
100 NULL, NULL,
101 cd_dbus_marshal_VOID__BOOLEAN,
102 G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
103 s_iSignals[ANSWER] =
104 g_signal_new("on_answer",
105 G_OBJECT_CLASS_TYPE(klass),
106 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
107 0,
108 NULL, NULL,
109 cd_dbus_marshal_VOID__VALUE,
110 G_TYPE_NONE, 1, G_TYPE_VALUE); // deprecated
111 s_iSignals[ANSWER_DIALOG] =
112 g_signal_new("on_answer_dialog",
113 G_OBJECT_CLASS_TYPE(klass),
114 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
115 0,
116 NULL, NULL,
117 cd_dbus_marshal_VOID__INT_VALUE,
118 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_VALUE);
119 s_iSignals[SHORTKEY] =
120 g_signal_new("on_shortkey",
121 G_OBJECT_CLASS_TYPE(klass),
122 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
123 0,
124 NULL, NULL,
125 cd_dbus_marshal_VOID__STRING,
126 G_TYPE_NONE, 1, G_TYPE_STRING);
127 s_iSignals[INIT_MODULE] =
128 g_signal_new("on_init_module",
129 G_OBJECT_CLASS_TYPE(klass),
130 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
131 0,
132 NULL, NULL,
133 cd_dbus_marshal_VOID__VOID,
134 G_TYPE_NONE, 0, G_TYPE_NONE);
135 s_iSignals[STOP_MODULE] =
136 g_signal_new("on_stop_module",
137 G_OBJECT_CLASS_TYPE(klass),
138 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
139 0,
140 NULL, NULL,
141 cd_dbus_marshal_VOID__VOID,
142 G_TYPE_NONE, 0, G_TYPE_NONE);
143 s_iSignals[RELOAD_MODULE] =
144 g_signal_new("on_reload_module",
145 G_OBJECT_CLASS_TYPE(klass),
146 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
147 0,
148 NULL, NULL,
149 cd_dbus_marshal_VOID__BOOLEAN,
150 G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
151
152 // Add signals
153 DBusGProxy *pProxy = cairo_dock_get_main_proxy ();
154 if (pProxy != NULL)
155 {
156 dbus_g_proxy_add_signal(pProxy, "on_click",
157 G_TYPE_INT, G_TYPE_INVALID);
158 dbus_g_proxy_add_signal(pProxy, "on_middle_click",
159 G_TYPE_INVALID);
160 dbus_g_proxy_add_signal(pProxy, "on_scroll",
161 G_TYPE_BOOLEAN, G_TYPE_INVALID);
162 dbus_g_proxy_add_signal(pProxy, "on_build_menu",
163 G_TYPE_INVALID);
164 dbus_g_proxy_add_signal(pProxy, "on_menu_select",
165 G_TYPE_INT, G_TYPE_INVALID);
166 dbus_g_proxy_add_signal(pProxy, "on_drop_data",
167 G_TYPE_STRING, G_TYPE_INVALID);
168 dbus_g_proxy_add_signal(pProxy, "on_change_focus",
169 G_TYPE_BOOLEAN, G_TYPE_INVALID);
170 dbus_g_proxy_add_signal(pProxy, "on_answer",
171 G_TYPE_VALUE, G_TYPE_INVALID); // deprecated
172 dbus_g_proxy_add_signal(pProxy, "on_answer_dialog",
173 G_TYPE_VALUE, G_TYPE_INVALID);
174 dbus_g_proxy_add_signal(pProxy, "on_shortkey",
175 G_TYPE_VALUE, G_TYPE_INVALID);
176 dbus_g_proxy_add_signal(pProxy, "on_init_module",
177 G_TYPE_INVALID);
178 dbus_g_proxy_add_signal(pProxy, "on_stop_module",
179 G_TYPE_INVALID);
180 dbus_g_proxy_add_signal(pProxy, "on_reload_module",
181 G_TYPE_BOOLEAN, G_TYPE_INVALID);
182 }
183 }
184
cd_dbus_sub_applet_init_signals_once(dbusSubAppletClass * klass)185 void cd_dbus_sub_applet_init_signals_once (dbusSubAppletClass *klass)
186 {
187 static gboolean bFirst = TRUE;
188 if (! bFirst)
189 return;
190 bFirst = FALSE;
191
192 // Enregistrement des marshaller specifique aux signaux.
193 dbus_g_object_register_marshaller(cd_dbus_marshal_VOID__INT_STRING,
194 G_TYPE_NONE, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID); // clic
195 dbus_g_object_register_marshaller(cd_dbus_marshal_VOID__BOOLEAN_STRING,
196 G_TYPE_NONE, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_INVALID); // scroll
197 dbus_g_object_register_marshaller(cd_dbus_marshal_VOID__STRING_STRING,
198 G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); // drop
199 dbus_g_object_register_marshaller(cd_dbus_marshal_VOID__VALUE_STRING,
200 G_TYPE_NONE, G_TYPE_VALUE, G_TYPE_STRING, G_TYPE_INVALID); // answer
201
202 // on definit les signaux dont on aura besoin.
203 s_iSubSignals[CLIC] =
204 g_signal_new("on_click_sub_icon",
205 G_OBJECT_CLASS_TYPE(klass),
206 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
207 0,
208 NULL, NULL,
209 cd_dbus_marshal_VOID__INT_STRING,
210 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING);
211 s_iSubSignals[MIDDLE_CLIC] =
212 g_signal_new("on_middle_click_sub_icon",
213 G_OBJECT_CLASS_TYPE(klass),
214 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
215 0,
216 NULL, NULL,
217 cd_dbus_marshal_VOID__STRING,
218 G_TYPE_NONE, 1, G_TYPE_STRING);
219 s_iSubSignals[SCROLL] =
220 g_signal_new("on_scroll_sub_icon",
221 G_OBJECT_CLASS_TYPE(klass),
222 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
223 0,
224 NULL, NULL,
225 cd_dbus_marshal_VOID__BOOLEAN_STRING,
226 G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_STRING);
227 s_iSubSignals[BUILD_MENU] =
228 g_signal_new("on_build_menu_sub_icon",
229 G_OBJECT_CLASS_TYPE(klass),
230 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
231 0,
232 NULL, NULL,
233 cd_dbus_marshal_VOID__STRING,
234 G_TYPE_NONE, 1, G_TYPE_STRING);
235 s_iSubSignals[DROP_DATA] =
236 g_signal_new("on_drop_data_sub_icon",
237 G_OBJECT_CLASS_TYPE(klass),
238 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
239 0,
240 NULL, NULL,
241 cd_dbus_marshal_VOID__STRING_STRING,
242 G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
243
244 // Add signals
245 DBusGProxy *pProxy = cairo_dock_get_main_proxy ();
246 if (pProxy != NULL)
247 {
248 dbus_g_proxy_add_signal(pProxy, "on_click_sub_icon",
249 G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID);
250 dbus_g_proxy_add_signal(pProxy, "on_middle_click_icon",
251 G_TYPE_STRING, G_TYPE_INVALID);
252 dbus_g_proxy_add_signal(pProxy, "on_scroll_sub_icon",
253 G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_INVALID);
254 dbus_g_proxy_add_signal(pProxy, "on_build_menu_sub_icon",
255 G_TYPE_STRING, G_TYPE_INVALID);
256 dbus_g_proxy_add_signal(pProxy, "on_drop_data_sub_icon",
257 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
258 }
259 }
260
261 #define CAIRO_DOCK_IS_EXTERNAL_APPLET(pIcon) (CAIRO_DOCK_IS_APPLET (pIcon) && pIcon->pModuleInstance->pModule->pInterface->stopModule == cd_dbus_emit_on_stop_module)
262
_get_main_icon_from_clicked_icon(Icon * pIcon,GldiContainer * pContainer)263 static inline Icon *_get_main_icon_from_clicked_icon (Icon *pIcon, GldiContainer *pContainer)
264 {
265 Icon *pMainIcon = NULL;
266 if (CAIRO_DOCK_IS_DESKLET (pContainer))
267 {
268 pMainIcon = CAIRO_DESKLET (pContainer)->pIcon;
269 }
270 else if (CAIRO_DOCK_IS_DOCK (pContainer))
271 {
272 if (CAIRO_DOCK (pContainer)->iRefCount == 0 || CAIRO_DOCK_IS_APPLET (pIcon)) // gere donc le cas ou l'applet est placee dans un sous-dock.
273 {
274 pMainIcon = pIcon;
275 }
276 else
277 {
278 pMainIcon = cairo_dock_search_icon_pointing_on_dock (CAIRO_DOCK (pContainer), NULL);
279 }
280 }
281 return pMainIcon;
282 }
283
cd_dbus_applet_emit_on_click_icon(gpointer data,Icon * pClickedIcon,GldiContainer * pClickedContainer,guint iButtonState)284 gboolean cd_dbus_applet_emit_on_click_icon (gpointer data, Icon *pClickedIcon, GldiContainer *pClickedContainer, guint iButtonState)
285 {
286 if (pClickedIcon == NULL)
287 return GLDI_NOTIFICATION_LET_PASS;
288 Icon *pAppletIcon = _get_main_icon_from_clicked_icon (pClickedIcon, pClickedContainer);
289 if (! CAIRO_DOCK_IS_EXTERNAL_APPLET (pAppletIcon))
290 return GLDI_NOTIFICATION_LET_PASS;
291
292 //g_print ("%s (%s, %d)\n", __func__, pAppletIcon->pModuleInstance->pModule->pVisitCard->cModuleName, iButtonState);
293 dbusApplet *pDbusApplet = cd_dbus_get_dbus_applet_from_instance (pAppletIcon->pModuleInstance);
294 g_return_val_if_fail (pDbusApplet != NULL, GLDI_NOTIFICATION_LET_PASS);
295
296 if (pClickedIcon == pAppletIcon)
297 {
298 //g_print ("emit clic on main icon\n");
299 g_signal_emit (pDbusApplet, s_iSignals[CLIC], 0, iButtonState);
300 }
301 else if (pDbusApplet->pSubApplet != NULL)
302 {
303 //g_print ("emit clic on sub icon\n");
304 g_signal_emit (pDbusApplet->pSubApplet, s_iSubSignals[CLIC], 0, iButtonState, pClickedIcon->cCommand);
305 }
306
307 // if the applet acts as a launcher, assume it launches the program it controls on click
308 // Note: if one day it poses a problem, we can either make a new attribute, or add a dbus method (or even reuse the "Animate" method with a pseudo "launching" animation).
309 if (pAppletIcon->pModuleInstance->pModule->pVisitCard->bActAsLauncher
310 && pClickedIcon->pAppli == NULL) // if the icon already controls a window, don't notify; most probably, the action the applet will take is to show/minimize this window
311 gldi_class_startup_notify (pClickedIcon);
312 return GLDI_NOTIFICATION_INTERCEPT;
313 }
314
cd_dbus_applet_emit_on_middle_click_icon(gpointer data,Icon * pClickedIcon,GldiContainer * pClickedContainer)315 gboolean cd_dbus_applet_emit_on_middle_click_icon (gpointer data, Icon *pClickedIcon, GldiContainer *pClickedContainer)
316 {
317 if (pClickedIcon == NULL)
318 return GLDI_NOTIFICATION_LET_PASS;
319 Icon *pAppletIcon = _get_main_icon_from_clicked_icon (pClickedIcon, pClickedContainer);
320 if (! CAIRO_DOCK_IS_EXTERNAL_APPLET (pAppletIcon))
321 return GLDI_NOTIFICATION_LET_PASS;
322
323 //g_print ("%s (%s)\n", __func__, pAppletIcon->pModuleInstance->pModule->pVisitCard->cModuleName);
324 dbusApplet *pDbusApplet = cd_dbus_get_dbus_applet_from_instance (pAppletIcon->pModuleInstance);
325 g_return_val_if_fail (pDbusApplet != NULL, GLDI_NOTIFICATION_LET_PASS);
326
327 if (pClickedIcon == pAppletIcon)
328 g_signal_emit (pDbusApplet, s_iSignals[MIDDLE_CLIC], 0, NULL);
329 else if (pDbusApplet->pSubApplet != NULL)
330 g_signal_emit (pDbusApplet->pSubApplet, s_iSubSignals[MIDDLE_CLIC], 0, pClickedIcon->cCommand);
331 return GLDI_NOTIFICATION_INTERCEPT;
332 }
333
cd_dbus_applet_emit_on_scroll_icon(gpointer data,Icon * pClickedIcon,GldiContainer * pClickedContainer,int iDirection)334 gboolean cd_dbus_applet_emit_on_scroll_icon (gpointer data, Icon *pClickedIcon, GldiContainer *pClickedContainer, int iDirection)
335 {
336 if (pClickedIcon == NULL)
337 return GLDI_NOTIFICATION_LET_PASS;
338 Icon *pAppletIcon = _get_main_icon_from_clicked_icon (pClickedIcon, pClickedContainer);
339 if (! CAIRO_DOCK_IS_EXTERNAL_APPLET (pAppletIcon))
340 return GLDI_NOTIFICATION_LET_PASS;
341
342 //g_print ("%s (%s, %d)\n", __func__, pAppletIcon->pModuleInstance->pModule->pVisitCard->cModuleName, iDirection);
343 dbusApplet *pDbusApplet = cd_dbus_get_dbus_applet_from_instance (pAppletIcon->pModuleInstance);
344 g_return_val_if_fail (pDbusApplet != NULL, GLDI_NOTIFICATION_LET_PASS);
345
346 if (pClickedIcon == pAppletIcon)
347 g_signal_emit (pDbusApplet, s_iSignals[SCROLL], 0, (iDirection == GDK_SCROLL_UP));
348 else if (pDbusApplet->pSubApplet != NULL)
349 g_signal_emit (pDbusApplet->pSubApplet, s_iSubSignals[SCROLL], 0, (iDirection == GDK_SCROLL_UP), pClickedIcon->cCommand);
350 return GLDI_NOTIFICATION_INTERCEPT;
351 }
352
_delete_menu(GtkMenuShell * menu,GldiModuleInstance * myApplet)353 static void _delete_menu (GtkMenuShell *menu, GldiModuleInstance *myApplet)
354 {
355 ///myData.pModuleSubMenu = NULL;
356 myData.pModuleMainMenu = NULL;
357 }
cd_dbus_applet_emit_on_build_menu(gpointer data,Icon * pClickedIcon,GldiContainer * pClickedContainer,GtkWidget * pAppletMenu)358 gboolean cd_dbus_applet_emit_on_build_menu (gpointer data, Icon *pClickedIcon, GldiContainer *pClickedContainer, GtkWidget *pAppletMenu)
359 {
360 if (pClickedIcon == NULL)
361 return GLDI_NOTIFICATION_LET_PASS;
362 Icon *pAppletIcon = _get_main_icon_from_clicked_icon (pClickedIcon, pClickedContainer);
363 if (! CAIRO_DOCK_IS_EXTERNAL_APPLET (pAppletIcon))
364 return GLDI_NOTIFICATION_LET_PASS;
365
366 myData.pModuleMainMenu = pAppletMenu;
367 /**myData.pModuleSubMenu = cairo_dock_create_sub_menu (pAppletIcon->pModuleInstance->pModule->pVisitCard->cModuleName,
368 pAppletMenu,
369 pAppletIcon->pModuleInstance->pModule->pVisitCard->cIconFilePath);
370
371 cairo_dock_add_in_menu_with_stock_and_data (_("Applet's Handbook"),
372 GLDI_ICON_NAME_ABOUT,
373 G_CALLBACK (cairo_dock_pop_up_about_applet),
374 myData.pModuleSubMenu,
375 pAppletIcon->pModuleInstance);*/
376
377 g_signal_connect (G_OBJECT (pAppletMenu),
378 "deactivate",
379 G_CALLBACK (_delete_menu),
380 myApplet);
381
382 //g_print ("%s (%s)\n", __func__, pAppletIcon->pModuleInstance->pModule->pVisitCard->cModuleName);
383 dbusApplet *pDbusApplet = cd_dbus_get_dbus_applet_from_instance (pAppletIcon->pModuleInstance);
384 g_return_val_if_fail (pDbusApplet != NULL, GLDI_NOTIFICATION_LET_PASS);
385 myData.pCurrentMenuDbusApplet = pDbusApplet;
386
387 GList *pChildren = gtk_container_get_children (GTK_CONTAINER (pAppletMenu));
388 myData.iMenuPosition = g_list_length (pChildren);
389 g_list_free (pChildren);
390
391 if (pClickedIcon == pAppletIcon)
392 g_signal_emit (pDbusApplet, s_iSignals[BUILD_MENU], 0);
393 else if (pDbusApplet->pSubApplet != NULL)
394 g_signal_emit (pDbusApplet->pSubApplet, s_iSubSignals[BUILD_MENU], 0, pClickedIcon->cCommand);
395 return (pClickedIcon == pAppletIcon ? GLDI_NOTIFICATION_LET_PASS : GLDI_NOTIFICATION_INTERCEPT);
396 }
397
cd_dbus_emit_on_menu_select(GtkMenuItem * pMenuItem,gpointer data)398 void cd_dbus_emit_on_menu_select (GtkMenuItem *pMenuItem, gpointer data)
399 {
400 g_return_if_fail (myData.pCurrentMenuDbusApplet != NULL);
401 if (GTK_IS_RADIO_MENU_ITEM (pMenuItem))
402 {
403 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (pMenuItem)))
404 return ;
405 }
406
407 int iNumEntry = GPOINTER_TO_INT (data);
408 g_signal_emit (myData.pCurrentMenuDbusApplet, s_iSignals[MENU_SELECT], 0, iNumEntry); // since there can only be 1 menu at once, and the applet knows when the menu is raised, there is no need to pass the icon in the signal: the applet can remember the clicked icon when it received the 'build-menu' event.
409 }
410
cd_dbus_applet_emit_on_drop_data(G_GNUC_UNUSED gpointer data,const gchar * cReceivedData,Icon * pClickedIcon,double fPosition,GldiContainer * pClickedContainer)411 gboolean cd_dbus_applet_emit_on_drop_data (G_GNUC_UNUSED gpointer data, const gchar *cReceivedData, Icon *pClickedIcon, double fPosition, GldiContainer *pClickedContainer)
412 {
413 //\________________ On gere le cas d'une applet tierce-partie en provenance de nos depots.
414 if (cReceivedData && strncmp (cReceivedData, "http://", 7) == 0 && g_str_has_suffix (cReceivedData, ".tar.gz") && (g_strstr_len (cReceivedData, -1, "glxdock") || g_strstr_len (cReceivedData, -1, "glx-dock")))
415 {
416 //\________________ On telecharge l'archive de l'applet et on l'installe/la met a jour.
417 GError *erreur = NULL;
418 //g_print ("dropped a distant applet\n");
419 gchar *cExtractTo = g_strdup_printf ("%s/%s", g_cCairoDockDataDir, CD_DBUS_APPLETS_FOLDER);
420 gchar *cAppletDirPath = cairo_dock_download_archive (cReceivedData, cExtractTo);
421 if (erreur != NULL)
422 {
423 cd_warning (erreur->message);
424 g_error_free (erreur);
425 }
426 if (cAppletDirPath == NULL)
427 {
428 gldi_dialog_show_general_message (D_("Sorry, this module couldn't be added."), 10000);
429 }
430 else
431 {
432 //\________________ On la supprime totalement si elle existe deja (mise a jour).
433 gchar *cAppletName = g_path_get_basename (cAppletDirPath);
434 gchar *str = strchr (cAppletName, '_');
435 if (str) // on enleve les numeros de version (launchpad, solution temporaire).
436 {
437 if (g_ascii_isdigit (*(str+1)))
438 *str = '\0';
439 }
440
441 GldiModule *pModule = gldi_module_get (cAppletName);
442 gboolean bUpdate = FALSE;
443 if (pModule != NULL) // on va totalement supprimer le module pour le recharger de zero.
444 {
445 bUpdate = TRUE;
446 gldi_object_unref (GLDI_OBJECT(pModule));
447 pModule = NULL;
448 }
449
450 //\________________ On l'enregistre et on la (re)lance.
451 cd_dbus_register_module_in_dir (cAppletName, cExtractTo);
452 pModule = gldi_module_get (cAppletName);
453
454 gldi_module_activate (pModule);
455
456 //\________________ On balance un petit message a l'utilisateur.
457 if (!pModule)
458 {
459 gldi_dialog_show_general_message (D_("Sorry, this module couldn't be added."), 10000);
460 }
461 else if (!pModule->pInstancesList)
462 {
463 gldi_dialog_show_general_message (D_("The module has been added, but couldn't be launched."), 10000);
464 }
465 else
466 {
467 GldiModuleInstance *pInstance = pModule->pInstancesList->data;
468 if (!pInstance->pIcon || !pInstance->pContainer)
469 gldi_dialog_show_general_message (D_("The module has been added, but couldn't be launched."), 10000);
470 else
471 {
472 gldi_dialog_show_temporary_with_icon_printf (bUpdate ? D_("The applet '%s' has been succefully updated and automatically reloaded") : D_("The applet '%s' has been succefully installed and automatically launched"),
473 pInstance->pIcon,
474 pInstance->pContainer,
475 10000,
476 "same icon",
477 cAppletName);
478 }
479 }
480 g_free (cAppletName);
481 }
482 g_free (cExtractTo);
483 return GLDI_NOTIFICATION_INTERCEPT;
484 }
485
486 //\________________ Sinon on notifie l'applet du drop.
487 Icon *pAppletIcon = _get_main_icon_from_clicked_icon (pClickedIcon, pClickedContainer);
488 if (! CAIRO_DOCK_IS_EXTERNAL_APPLET (pAppletIcon))
489 return GLDI_NOTIFICATION_LET_PASS;
490
491 cd_debug (" %s --> sur le bus !", cReceivedData);
492 dbusApplet *pDbusApplet = cd_dbus_get_dbus_applet_from_instance (pAppletIcon->pModuleInstance);
493 g_return_val_if_fail (pDbusApplet != NULL, GLDI_NOTIFICATION_LET_PASS);
494
495 if (pClickedIcon == pAppletIcon)
496 g_signal_emit (pDbusApplet, s_iSignals[DROP_DATA], 0, cReceivedData);
497 else if (pDbusApplet->pSubApplet != NULL)
498 g_signal_emit (pDbusApplet->pSubApplet, s_iSubSignals[DROP_DATA], 0, cReceivedData, pClickedIcon->cCommand);
499 return GLDI_NOTIFICATION_INTERCEPT;
500 }
501
_on_window_destroyed(G_GNUC_UNUSED gpointer data,GldiWindowActor * actor)502 static gboolean _on_window_destroyed (G_GNUC_UNUSED gpointer data, GldiWindowActor *actor)
503 {
504 if (actor == myData.pActiveWindow)
505 myData.pActiveWindow = NULL;
506 return GLDI_NOTIFICATION_LET_PASS;
507 }
cd_dbus_applet_emit_on_change_focus(G_GNUC_UNUSED gpointer data,GldiWindowActor * pNewActiveWindow)508 gboolean cd_dbus_applet_emit_on_change_focus (G_GNUC_UNUSED gpointer data, GldiWindowActor *pNewActiveWindow)
509 {
510 // on emet le signal sur l'icone qui avait le focus.
511 if (myData.pActiveWindow != NULL)
512 {
513 Icon *pPrevActiveIcon = cairo_dock_get_appli_icon (myData.pActiveWindow);
514 if (pPrevActiveIcon && pPrevActiveIcon->cParentDockName == NULL)
515 pPrevActiveIcon = cairo_dock_get_inhibitor (pPrevActiveIcon, FALSE);
516 if (CAIRO_DOCK_IS_EXTERNAL_APPLET (pPrevActiveIcon))
517 {
518 dbusApplet *pDbusApplet = cd_dbus_get_dbus_applet_from_instance (pPrevActiveIcon->pModuleInstance);
519 g_return_val_if_fail (pDbusApplet != NULL, GLDI_NOTIFICATION_LET_PASS);
520 g_signal_emit (pDbusApplet, s_iSignals[CHANGE_FOCUS], 0, FALSE);
521 }
522 }
523
524 // on emet le signal sur l'icone qui a desormais le focus.
525 //g_print ("DBUS : new active window : %ld\n", *xNewActiveWindow);
526 if (pNewActiveWindow != NULL)
527 {
528 Icon *pNewActiveIcon = cairo_dock_get_appli_icon (pNewActiveWindow);
529 if (pNewActiveIcon && pNewActiveIcon->cParentDockName == NULL)
530 pNewActiveIcon = cairo_dock_get_inhibitor (pNewActiveIcon, FALSE);
531 if (CAIRO_DOCK_IS_EXTERNAL_APPLET (pNewActiveIcon))
532 {
533 dbusApplet *pDbusApplet = cd_dbus_get_dbus_applet_from_instance (pNewActiveIcon->pModuleInstance);
534 g_return_val_if_fail (pDbusApplet != NULL, GLDI_NOTIFICATION_LET_PASS);
535 g_signal_emit (pDbusApplet, s_iSignals[CHANGE_FOCUS], 0, TRUE);
536 }
537 }
538
539 myData.pActiveWindow = pNewActiveWindow;
540 if (pNewActiveWindow)
541 gldi_object_register_notification (pNewActiveWindow, NOTIFICATION_DESTROY, (GldiNotificationFunc)_on_window_destroyed, GLDI_RUN_AFTER, NULL);
542 return GLDI_NOTIFICATION_LET_PASS;
543 }
544
545
546 // deprecated
_emit_answer(dbusApplet * pDbusApplet,CairoDialog * pDialog,GValue * v)547 static inline void _emit_answer (dbusApplet *pDbusApplet, CairoDialog *pDialog, GValue *v)
548 {
549 g_signal_emit (pDbusApplet, s_iSignals[ANSWER], 0, v); // same remark as for the menu: 1 dialog at once, the applet knows when the dialog is raised, so it can just remember the clicked icon; we don't need to tell it.
550
551 pDbusApplet->pDialog = NULL;
552 }
cd_dbus_applet_emit_on_answer_question(int iClickedButton,GtkWidget * pInteractiveWidget,dbusApplet * pDbusApplet,CairoDialog * pDialog)553 void cd_dbus_applet_emit_on_answer_question (int iClickedButton, GtkWidget *pInteractiveWidget, dbusApplet *pDbusApplet, CairoDialog *pDialog)
554 {
555 gboolean bYes = (iClickedButton == 0 || iClickedButton == -1);
556 GValue v = G_VALUE_INIT;
557 g_value_init (&v, G_TYPE_BOOLEAN);
558 g_value_set_boolean (&v, bYes);
559
560 _emit_answer (pDbusApplet, pDialog, &v);
561 }
562
cd_dbus_applet_emit_on_answer_value(int iClickedButton,GtkWidget * pInteractiveWidget,dbusApplet * pDbusApplet,CairoDialog * pDialog)563 void cd_dbus_applet_emit_on_answer_value (int iClickedButton, GtkWidget *pInteractiveWidget, dbusApplet *pDbusApplet, CairoDialog *pDialog)
564 {
565 double fValue = (iClickedButton == 0 || iClickedButton == -1 ? gtk_range_get_value (GTK_RANGE (pInteractiveWidget)) : -1);
566 GValue v = G_VALUE_INIT;
567 g_value_init (&v, G_TYPE_DOUBLE);
568 g_value_set_double (&v, fValue);
569
570 _emit_answer (pDbusApplet, pDialog, &v);
571 }
572
cd_dbus_applet_emit_on_answer_text(int iClickedButton,GtkWidget * pInteractiveWidget,dbusApplet * pDbusApplet,CairoDialog * pDialog)573 void cd_dbus_applet_emit_on_answer_text (int iClickedButton, GtkWidget *pInteractiveWidget, dbusApplet *pDbusApplet, CairoDialog *pDialog)
574 {
575 const gchar *cAnswer = (iClickedButton == 0 || iClickedButton == -1 ? gtk_entry_get_text (GTK_ENTRY (pInteractiveWidget)) : NULL);
576 GValue v = G_VALUE_INIT;
577 g_value_init (&v, G_TYPE_STRING);
578 g_value_set_string (&v, cAnswer);
579
580 _emit_answer (pDbusApplet, pDialog, &v);
581 }
582 // end of deprecated
583
584
_emit_answer_dialog(dbusApplet * pDbusApplet,CairoDialog * pDialog,int iClickedButton,GValue * v)585 static inline void _emit_answer_dialog (dbusApplet *pDbusApplet, CairoDialog *pDialog, int iClickedButton, GValue *v)
586 {
587 g_signal_emit (pDbusApplet, s_iSignals[ANSWER_DIALOG], 0, iClickedButton, v); // same remark as for the menu: 1 dialog at once, the applet knows when the dialog is raised, so it can just remember the clicked icon; we don't need to tell it.
588
589 pDbusApplet->pDialog = NULL;
590 }
cd_dbus_applet_emit_on_answer_buttons(int iClickedButton,GtkWidget * pInteractiveWidget,dbusApplet * pDbusApplet,CairoDialog * pDialog)591 void cd_dbus_applet_emit_on_answer_buttons (int iClickedButton, GtkWidget *pInteractiveWidget, dbusApplet *pDbusApplet, CairoDialog *pDialog)
592 {
593 GValue v = G_VALUE_INIT;
594 g_value_init (&v, G_TYPE_INT);
595 g_value_set_int (&v, iClickedButton);
596
597 _emit_answer_dialog (pDbusApplet, pDialog, iClickedButton, &v);
598 }
599
cd_dbus_applet_emit_on_answer_text_entry(int iClickedButton,GtkWidget * pInteractiveWidget,dbusApplet * pDbusApplet,CairoDialog * pDialog)600 void cd_dbus_applet_emit_on_answer_text_entry (int iClickedButton, GtkWidget *pInteractiveWidget, dbusApplet *pDbusApplet, CairoDialog *pDialog)
601 {
602 GValue v = G_VALUE_INIT;
603 g_value_init (&v, G_TYPE_STRING);
604
605 GtkWidget *pEntry = g_object_get_data (G_OBJECT (pInteractiveWidget), "cd-widget");
606 g_return_if_fail (pEntry != NULL);
607 /**GtkWidget *pEntry;
608 if (GTK_IS_ENTRY (pInteractiveWidget))
609 {
610 pEntry = pInteractiveWidget;
611 }
612 else
613 {
614 GList *children = gtk_container_get_children (GTK_CONTAINER (pInteractiveWidget));
615 g_return_if_fail (children != NULL);
616 pEntry = children->data;
617 }*/
618
619 const gchar *cText = gtk_entry_get_text (GTK_ENTRY (pEntry));
620 //g_print (" -> %s\n", cText);
621 g_value_set_string (&v, cText);
622 _emit_answer_dialog (pDbusApplet, pDialog, iClickedButton, &v);
623 }
624
cd_dbus_applet_emit_on_answer_text_view(int iClickedButton,GtkWidget * pInteractiveWidget,dbusApplet * pDbusApplet,CairoDialog * pDialog)625 void cd_dbus_applet_emit_on_answer_text_view (int iClickedButton, GtkWidget *pInteractiveWidget, dbusApplet *pDbusApplet, CairoDialog *pDialog)
626 {
627 GValue v = G_VALUE_INIT;
628 g_value_init (&v, G_TYPE_STRING);
629
630 GtkWidget *pTextView = g_object_get_data (G_OBJECT (pInteractiveWidget), "cd-widget");
631 g_return_if_fail (pTextView != NULL);
632 /**if (GTK_IS_TEXT_VIEW (pInteractiveWidget))
633 {
634 pTextView = pInteractiveWidget;
635 }
636 else
637 {
638 GList *children = gtk_container_get_children (GTK_CONTAINER (pInteractiveWidget));
639 g_return_if_fail (children != NULL);
640 pTextView = children->data;
641 }*/
642 GtkTextBuffer *pBuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (pTextView));
643 GtkTextIter start, end;
644 gtk_text_buffer_get_start_iter (pBuffer, &start);
645 gtk_text_buffer_get_end_iter (pBuffer, &end);
646 gchar *cText = gtk_text_buffer_get_text (pBuffer,
647 &start,
648 &end,
649 FALSE);
650
651 g_value_set_string (&v, cText);
652 _emit_answer_dialog (pDbusApplet, pDialog, iClickedButton, &v);
653 g_free (cText);
654 }
655
cd_dbus_applet_emit_on_answer_scale(int iClickedButton,GtkWidget * pInteractiveWidget,dbusApplet * pDbusApplet,CairoDialog * pDialog)656 void cd_dbus_applet_emit_on_answer_scale (int iClickedButton, GtkWidget *pInteractiveWidget, dbusApplet *pDbusApplet, CairoDialog *pDialog)
657 {
658 GValue v = G_VALUE_INIT;
659 g_value_init (&v, G_TYPE_DOUBLE);
660
661 GtkWidget *pScale = g_object_get_data (G_OBJECT (pInteractiveWidget), "cd-widget");
662 g_return_if_fail (pScale != NULL);
663 /**GtkWidget *pScale;
664 if (GTK_IS_RANGE (pInteractiveWidget))
665 {
666 pScale = pInteractiveWidget;
667 }
668 else
669 {
670 GList *children = gtk_container_get_children (GTK_CONTAINER (pInteractiveWidget));
671 g_return_if_fail (children != NULL && children->next != NULL);
672 pScale = children->next->data;
673 }*/
674
675 double x = gtk_range_get_value (GTK_RANGE (pScale));
676 g_value_set_double (&v, x);
677 _emit_answer_dialog (pDbusApplet, pDialog, iClickedButton, &v);
678 }
679
cd_dbus_applet_emit_on_answer_combo_entry(int iClickedButton,GtkWidget * pInteractiveWidget,dbusApplet * pDbusApplet,CairoDialog * pDialog)680 void cd_dbus_applet_emit_on_answer_combo_entry (int iClickedButton, GtkWidget *pInteractiveWidget, dbusApplet *pDbusApplet, CairoDialog *pDialog)
681 {
682 GValue v = G_VALUE_INIT;
683 g_value_init (&v, G_TYPE_STRING);
684
685 GtkWidget *pEntry = gtk_bin_get_child (GTK_BIN (pInteractiveWidget));
686 const gchar *cText = gtk_entry_get_text (GTK_ENTRY (pEntry));
687
688 g_value_set_string (&v, cText);
689 _emit_answer_dialog (pDbusApplet, pDialog, iClickedButton, &v);
690 }
691
cd_dbus_applet_emit_on_answer_combo(int iClickedButton,GtkWidget * pInteractiveWidget,dbusApplet * pDbusApplet,CairoDialog * pDialog)692 void cd_dbus_applet_emit_on_answer_combo (int iClickedButton, GtkWidget *pInteractiveWidget, dbusApplet *pDbusApplet, CairoDialog *pDialog)
693 {
694 GValue v = G_VALUE_INIT;
695 g_value_init (&v, G_TYPE_INT);
696
697 int iSelectedItem = gtk_combo_box_get_active (GTK_COMBO_BOX (pInteractiveWidget));
698
699 g_value_set_int (&v, iSelectedItem);
700 _emit_answer_dialog (pDbusApplet, pDialog, iClickedButton, &v);
701 }
702
cd_dbus_applet_emit_on_shortkey(const gchar * cShortkey,dbusApplet * pDbusApplet)703 void cd_dbus_applet_emit_on_shortkey (const gchar *cShortkey, dbusApplet *pDbusApplet)
704 {
705 g_signal_emit (pDbusApplet, s_iSignals[SHORTKEY], 0, cShortkey);
706 }
707
708
cd_dbus_action_on_init_module(GldiModuleInstance * pModuleInstance)709 void cd_dbus_action_on_init_module (GldiModuleInstance *pModuleInstance)
710 {
711 GldiVisitCard *pVisitCard = pModuleInstance->pModule->pVisitCard;
712 if (pModuleInstance->pDesklet)
713 {
714 cairo_dock_set_desklet_renderer_by_name (pModuleInstance->pDesklet,
715 "Simple",
716 (CairoDeskletRendererConfigPtr) NULL);
717 }
718
719 Icon *pIcon = pModuleInstance->pIcon;
720 if (pIcon && pIcon->cFileName == NULL && pIcon->image.pSurface)
721 {
722 cairo_t *pDrawContext = cairo_create (pIcon->image.pSurface);
723 cairo_dock_set_image_on_icon (pDrawContext, pVisitCard->cIconFilePath, pIcon, pModuleInstance->pContainer);
724 cairo_destroy (pDrawContext);
725 gtk_widget_queue_draw (pModuleInstance->pContainer->pWidget);
726 }
727 }
728
729
cd_dbus_action_on_stop_module(GldiModuleInstance * pModuleInstance)730 void cd_dbus_action_on_stop_module (GldiModuleInstance *pModuleInstance)
731 {
732 if (pModuleInstance->pIcon->pSubDock != NULL)
733 {
734 gldi_object_unref (GLDI_OBJECT(pModuleInstance->pIcon->pSubDock));
735 pModuleInstance->pIcon->pSubDock = NULL;
736 }
737
738 cairo_dock_remove_data_renderer_on_icon (pModuleInstance->pIcon);
739
740 if (pModuleInstance->pDesklet != NULL && pModuleInstance->pDesklet->icons != NULL) // idem, version desklet.
741 {
742 g_list_foreach (pModuleInstance->pDesklet->icons, (GFunc) gldi_object_unref, NULL);
743 g_list_free (pModuleInstance->pDesklet->icons);
744 pModuleInstance->pDesklet->icons = NULL;
745 }
746 }
747
cd_dbus_emit_on_stop_module(GldiModuleInstance * pModuleInstance)748 void cd_dbus_emit_on_stop_module (GldiModuleInstance *pModuleInstance)
749 {
750 //g_print ("%s (%s)\n", __func__, pModuleInstance->pModule->pVisitCard->cModuleName);
751 dbusApplet *pDbusApplet = cd_dbus_get_dbus_applet_from_instance (pModuleInstance);
752 if (pDbusApplet != NULL)
753 g_signal_emit (pDbusApplet,
754 s_iSignals[STOP_MODULE],
755 0,
756 NULL);
757
758 cd_dbus_action_on_stop_module (pModuleInstance);
759
760 cd_dbus_delete_remote_applet_object (pDbusApplet);
761 }
762
cd_dbus_emit_on_reload_module(GldiModuleInstance * pModuleInstance,GldiContainer * pOldContainer,GKeyFile * pKeyFile)763 gboolean cd_dbus_emit_on_reload_module (GldiModuleInstance *pModuleInstance, GldiContainer *pOldContainer, GKeyFile *pKeyFile)
764 {
765 //g_print ("%s ()\n", __func__);
766 GldiVisitCard *pVisitCard = pModuleInstance->pModule->pVisitCard;
767 dbusApplet *pDbusApplet = cd_dbus_get_dbus_applet_from_instance (pModuleInstance);
768 g_return_val_if_fail (pDbusApplet != NULL, FALSE);
769 g_signal_emit (pDbusApplet,
770 s_iSignals[RELOAD_MODULE],
771 0,
772 pKeyFile != NULL);
773
774 if (pModuleInstance->pDesklet)
775 {
776 if (pModuleInstance->pDesklet->icons == NULL)
777 {
778 cairo_dock_set_desklet_renderer_by_name (pModuleInstance->pDesklet,
779 "Simple",
780 (CairoDeskletRendererConfigPtr) NULL);
781 }
782 else
783 {
784 gpointer data[2] = {GINT_TO_POINTER (TRUE), GINT_TO_POINTER (FALSE)};
785 cairo_dock_set_desklet_renderer_by_name (pModuleInstance->pDesklet,
786 "Caroussel",
787 (CairoDeskletRendererConfigPtr) data);
788 }
789 }
790
791 Icon *pIcon = pModuleInstance->pIcon;
792 if (pIcon && pIcon->cFileName == NULL && pIcon->image.pSurface && (pIcon->pDataRenderer == NULL || pIcon->pDataRenderer->bUseOverlay))
793 {
794 cairo_t *pDrawContext = cairo_create (pIcon->image.pSurface);
795 cairo_dock_set_image_on_icon (pDrawContext, pVisitCard->cIconFilePath, pIcon, pModuleInstance->pContainer);
796 cairo_destroy (pDrawContext);
797 gtk_widget_queue_draw (pModuleInstance->pContainer->pWidget);
798 }
799
800 if (pKeyFile == NULL)
801 {
802 CairoDataRenderer *pDataRenderer = cairo_dock_get_icon_data_renderer (pIcon);
803 if (pDataRenderer != NULL)
804 {
805 CairoDataToRenderer *pData = cairo_data_renderer_get_data (pDataRenderer);
806 if (pData->iMemorySize > 2)
807 cairo_dock_resize_data_renderer_history (pIcon, pIcon->fWidth);
808 }
809 }
810
811 return TRUE;
812 }
813