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 <math.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 #include <gtk/gtk.h>
26 #include <glib/gstdio.h>
27 
28 #include <cairo.h>
29 
30 
31 #include "cairo-dock-struct.h"
32 #include "cairo-dock-dialog-manager.h"  // gldi_dialogs_foreach
33 #include "cairo-dock-dialog-factory.h"
34 #include "cairo-dock-module-instance-manager.h"  // GldiModuleInstance
35 #include "cairo-dock-dock-facility.h"
36 #include "cairo-dock-dock-manager.h"
37 #include "cairo-dock-utils.h"  // cairo_dock_launch_command_full
38 #include "cairo-dock-class-manager.h"  // gldi_class_startup_notify
39 #include "cairo-dock-indicator-manager.h"
40 #include "cairo-dock-applications-manager.h"  // GLDI_OBJECT_IS_APPLI_ICON
41 #include "cairo-dock-applet-manager.h"  // GLDI_OBJECT_IS_APPLET_ICON
42 #include "cairo-dock-separator-manager.h"  // GLDI_OBJECT_IS_SEPARATOR_ICON
43 #include "cairo-dock-themes-manager.h"  // cairo_dock_update_conf_file
44 #include "cairo-dock-log.h"
45 #include "cairo-dock-draw-opengl.h"
46 #include "cairo-dock-draw.h"
47 #include "cairo-dock-animations.h"  // CairoDockHidingEffect
48 #include "cairo-dock-icon-facility.h"
49 
50 extern gchar *g_cCurrentLaunchersPath;
51 extern CairoDockHidingEffect *g_pHidingBackend;
52 
53 extern CairoDockImageBuffer g_pIconBackgroundBuffer;
54 
55 
gldi_icon_set_appli(Icon * pIcon,GldiWindowActor * pAppli)56 void gldi_icon_set_appli (Icon *pIcon, GldiWindowActor *pAppli)
57 {
58 	if (pIcon->pAppli == pAppli)  // nothing to do
59 		return;
60 
61 	// unset the current appli if any
62 	if (pIcon->pAppli != NULL)
63 		gldi_object_unref (GLDI_OBJECT (pIcon->pAppli));
64 
65 	// set the appli
66 	if (pAppli)
67 		gldi_object_ref (GLDI_OBJECT (pAppli));
68 	pIcon->pAppli = pAppli;
69 }
70 
cairo_dock_get_icon_type(Icon * icon)71 CairoDockIconGroup cairo_dock_get_icon_type (Icon *icon)
72 {
73 	/*CairoDockIconGroup iGroup;
74 	if (GLDI_OBJECT_IS_SEPARATOR_ICON (icon))
75 		iGroup = CAIRO_DOCK_SEPARATOR12;
76 	else
77 		iGroup = (icon->iGroup < CAIRO_DOCK_NB_GROUPS ? icon->iGroup : icon->iGroup & 1);
78 	return iGroup;*/
79 	return (icon->iGroup < CAIRO_DOCK_NB_GROUPS ? icon->iGroup : icon->iGroup & 1);
80 }
81 
82 
cairo_dock_compare_icons_order(Icon * icon1,Icon * icon2)83 int cairo_dock_compare_icons_order (Icon *icon1, Icon *icon2)
84 {
85 	int iOrder1 = cairo_dock_get_icon_order (icon1);
86 	int iOrder2 = cairo_dock_get_icon_order (icon2);
87 	if (iOrder1 < iOrder2)
88 		return -1;
89 	else if (iOrder1 > iOrder2)
90 		return 1;
91 	else
92 	{
93 		if (icon1->fOrder < icon2->fOrder)
94 			return -1;
95 		else if (icon1->fOrder > icon2->fOrder)
96 			return 1;
97 		else
98 			return 0;
99 	}
100 }
cairo_dock_compare_icons_name(Icon * icon1,Icon * icon2)101 int cairo_dock_compare_icons_name (Icon *icon1, Icon *icon2)
102 {
103 	int iOrder1 = cairo_dock_get_icon_order (icon1);
104 	int iOrder2 = cairo_dock_get_icon_order (icon2);
105 	if (iOrder1 < iOrder2)
106 		return -1;
107 	else if (iOrder1 > iOrder2)
108 		return 1;
109 
110 	if (icon1->cName == NULL)
111 		return -1;
112 	if (icon2->cName == NULL)
113 		return 1;
114 	gchar *cURI_1 = g_ascii_strdown (icon1->cName, -1);
115 	gchar *cURI_2 = g_ascii_strdown (icon2->cName, -1);
116 	int iOrder = strcmp (cURI_1, cURI_2);
117 	g_free (cURI_1);
118 	g_free (cURI_2);
119 	return iOrder;
120 }
121 
cairo_dock_compare_icons_extension(Icon * icon1,Icon * icon2)122 int cairo_dock_compare_icons_extension (Icon *icon1, Icon *icon2)
123 {
124 	int iOrder1 = cairo_dock_get_icon_order (icon1);
125 	int iOrder2 = cairo_dock_get_icon_order (icon2);
126 	if (iOrder1 < iOrder2)
127 		return -1;
128 	else if (iOrder1 > iOrder2)
129 		return 1;
130 
131 	if (icon1->cBaseURI == NULL)
132 		return -1;
133 	if (icon2->cBaseURI == NULL)
134 		return 1;
135 
136 	gchar *ext1 = strrchr (icon1->cBaseURI, '.');
137 	gchar *ext2 = strrchr (icon2->cBaseURI, '.');
138 	if (ext1 == NULL)
139 		return -1;
140 	if (ext2 == NULL)
141 		return 1;
142 
143 	ext1 = g_ascii_strdown (ext1+1, -1);
144 	ext2 = g_ascii_strdown (ext2+1, -1);
145 
146 	int iOrder = strcmp (ext1, ext2);
147 	g_free (ext1);
148 	g_free (ext2);
149 	return iOrder;
150 }
151 
cairo_dock_sort_icons_by_order(GList * pIconList)152 GList *cairo_dock_sort_icons_by_order (GList *pIconList)
153 {
154 	return g_list_sort (pIconList, (GCompareFunc) cairo_dock_compare_icons_order);
155 }
156 
cairo_dock_sort_icons_by_name(GList * pIconList)157 GList *cairo_dock_sort_icons_by_name (GList *pIconList)
158 {
159 	GList *pSortedIconList = g_list_sort (pIconList, (GCompareFunc) cairo_dock_compare_icons_name);
160 
161 	guint iCurrentGroup = -1;
162 	double fCurrentOrder = 0.;
163 	Icon *icon;
164 	GList *ic;
165 	for (ic = pSortedIconList; ic != NULL; ic = ic->next)
166 	{
167 		icon = ic->data;
168 		if (icon->iGroup != iCurrentGroup)
169 		{
170 			iCurrentGroup = icon->iGroup;
171 			fCurrentOrder = 0.;
172 		}
173 		icon->fOrder = fCurrentOrder++;
174 	}
175 	return pSortedIconList;
176 }
177 
178 
179 
cairo_dock_get_first_icon(GList * pIconList)180 Icon* cairo_dock_get_first_icon (GList *pIconList)
181 {
182 	GList *pListHead = g_list_first(pIconList);
183 	return (pListHead != NULL ? pListHead->data : NULL);
184 }
185 
cairo_dock_get_last_icon(GList * pIconList)186 Icon* cairo_dock_get_last_icon (GList *pIconList)
187 {
188 	GList *pListTail = g_list_last(pIconList);
189 	return (pListTail != NULL ? pListTail->data : NULL);
190 }
191 
cairo_dock_get_first_icon_of_group(GList * pIconList,CairoDockIconGroup iGroup)192 Icon* cairo_dock_get_first_icon_of_group (GList *pIconList, CairoDockIconGroup iGroup)
193 {
194 	GList* ic;
195 	Icon *icon;
196 	for (ic = pIconList; ic != NULL; ic = ic->next)
197 	{
198 		icon = ic->data;
199 		if (icon->iGroup == iGroup)
200 			return icon;
201 	}
202 	return NULL;
203 }
cairo_dock_get_last_icon_of_group(GList * pIconList,CairoDockIconGroup iGroup)204 Icon* cairo_dock_get_last_icon_of_group (GList *pIconList, CairoDockIconGroup iGroup)
205 {
206 	GList* ic;
207 	Icon *icon;
208 	for (ic = g_list_last (pIconList); ic != NULL; ic = ic->prev)
209 	{
210 		icon = ic->data;
211 		if (icon->iGroup == iGroup)
212 			return icon;
213 	}
214 	return NULL;
215 }
cairo_dock_get_first_icon_of_order(GList * pIconList,CairoDockIconGroup iGroup)216 Icon* cairo_dock_get_first_icon_of_order (GList *pIconList, CairoDockIconGroup iGroup)
217 {
218 	CairoDockIconGroup iGroupOrder = cairo_dock_get_group_order (iGroup);
219 	GList* ic;
220 	Icon *icon;
221 	for (ic = pIconList; ic != NULL; ic = ic->next)
222 	{
223 		icon = ic->data;
224 		if (cairo_dock_get_icon_order (icon) == iGroupOrder)
225 			return icon;
226 	}
227 	return NULL;
228 }
cairo_dock_get_last_icon_of_order(GList * pIconList,CairoDockIconGroup iGroup)229 Icon* cairo_dock_get_last_icon_of_order (GList *pIconList, CairoDockIconGroup iGroup)
230 {
231 	CairoDockIconGroup iGroupOrder = cairo_dock_get_group_order (iGroup);
232 	GList* ic;
233 	Icon *icon;
234 	for (ic = g_list_last (pIconList); ic != NULL; ic = ic->prev)
235 	{
236 		icon = ic->data;
237 		if (cairo_dock_get_icon_order (icon) == iGroupOrder)
238 			return icon;
239 	}
240 	return NULL;
241 }
242 
cairo_dock_get_pointed_icon(GList * pIconList)243 Icon* cairo_dock_get_pointed_icon (GList *pIconList)
244 {
245 	GList* ic;
246 	Icon *icon;
247 	for (ic = pIconList; ic != NULL; ic = ic->next)
248 	{
249 		icon = ic->data;
250 		if (icon->bPointed)
251 			return icon;
252 	}
253 	return NULL;
254 }
255 
256 
cairo_dock_get_next_icon(GList * pIconList,Icon * pIcon)257 Icon *cairo_dock_get_next_icon (GList *pIconList, Icon *pIcon)
258 {
259 	GList* ic;
260 	Icon *icon;
261 	for (ic = pIconList; ic != NULL; ic = ic->next)
262 	{
263 		icon = ic->data;
264 		if (icon == pIcon)
265 		{
266 			if (ic->next != NULL)
267 				return ic->next->data;
268 			else
269 				return NULL;
270 		}
271 	}
272 	return NULL;
273 }
274 
cairo_dock_get_previous_icon(GList * pIconList,Icon * pIcon)275 Icon *cairo_dock_get_previous_icon (GList *pIconList, Icon *pIcon)
276 {
277 	GList* ic;
278 	Icon *icon;
279 	for (ic = pIconList; ic != NULL; ic = ic->next)
280 	{
281 		icon = ic->data;
282 		if (icon == pIcon)
283 		{
284 			if (ic->prev != NULL)
285 				return ic->prev->data;
286 			else
287 				return NULL;
288 		}
289 	}
290 	return NULL;
291 }
292 
cairo_dock_get_icon_with_command(GList * pIconList,const gchar * cCommand)293 Icon *cairo_dock_get_icon_with_command (GList *pIconList, const gchar *cCommand)
294 {
295 	g_return_val_if_fail (cCommand != NULL, NULL);
296 	GList* ic;
297 	Icon *icon;
298 	for (ic = pIconList; ic != NULL; ic = ic->next)
299 	{
300 		icon = ic->data;
301 		if (icon->cCommand != NULL && strncmp (icon->cCommand, cCommand, MIN (strlen (icon->cCommand), strlen (cCommand))) == 0)
302 			return icon;
303 	}
304 	return NULL;
305 }
306 
cairo_dock_get_icon_with_base_uri(GList * pIconList,const gchar * cBaseURI)307 Icon *cairo_dock_get_icon_with_base_uri (GList *pIconList, const gchar *cBaseURI)
308 {
309 	g_return_val_if_fail (cBaseURI != NULL, NULL);
310 	GList* ic;
311 	Icon *icon;
312 	for (ic = pIconList; ic != NULL; ic = ic->next)
313 	{
314 		icon = ic->data;
315 		//cd_message ("  icon->cBaseURI : %s", icon->cBaseURI);
316 		if (icon->cBaseURI != NULL && strcmp (icon->cBaseURI, cBaseURI) == 0)
317 			return icon;
318 	}
319 	return NULL;
320 }
321 
cairo_dock_get_icon_with_name(GList * pIconList,const gchar * cName)322 Icon *cairo_dock_get_icon_with_name (GList *pIconList, const gchar *cName)
323 {
324 	g_return_val_if_fail (cName != NULL, NULL);
325 	GList* ic;
326 	Icon *icon;
327 	for (ic = pIconList; ic != NULL; ic = ic->next)
328 	{
329 		icon = ic->data;
330 		//cd_message ("  icon->cName : %s", icon->cName);
331 		if (icon->cName != NULL && strcmp (icon->cName, cName) == 0)
332 			return icon;
333 	}
334 	return NULL;
335 }
336 
cairo_dock_get_icon_with_subdock(GList * pIconList,CairoDock * pSubDock)337 Icon *cairo_dock_get_icon_with_subdock (GList *pIconList, CairoDock *pSubDock)
338 {
339 	GList* ic;
340 	Icon *icon;
341 	for (ic = pIconList; ic != NULL; ic = ic->next)
342 	{
343 		icon = ic->data;
344 		if (icon->pSubDock == pSubDock)
345 			return icon;
346 	}
347 	return NULL;
348 }
349 
_has_dialog(CairoDialog * pDialog,Icon * pIcon)350 static gboolean _has_dialog (CairoDialog *pDialog, Icon *pIcon)
351 {
352 	return (pDialog->pIcon == pIcon);
353 }
gldi_icon_has_dialog(Icon * pIcon)354 gboolean gldi_icon_has_dialog (Icon *pIcon)
355 {
356 	CairoDialog *pDialog = gldi_dialogs_foreach ((GCompareFunc)_has_dialog, pIcon);
357 	return (pDialog != NULL);
358 }
359 
gldi_icons_get_without_dialog(GList * pIconList)360 Icon *gldi_icons_get_without_dialog (GList *pIconList)
361 {
362 	if (pIconList == NULL)
363 		return NULL;
364 
365 	Icon *pIcon = cairo_dock_get_first_icon_of_group (pIconList, CAIRO_DOCK_SEPARATOR12);
366 	if (pIcon != NULL && ! gldi_icon_has_dialog (pIcon) && pIcon->cParentDockName != NULL && ! cairo_dock_icon_is_being_removed (pIcon))
367 		return pIcon;
368 
369 	pIcon = cairo_dock_get_pointed_icon (pIconList);
370 	if (pIcon != NULL && ! CAIRO_DOCK_IS_NORMAL_APPLI (pIcon) && ! GLDI_OBJECT_IS_APPLET_ICON (pIcon) && ! gldi_icon_has_dialog (pIcon) && pIcon->cParentDockName != NULL && ! cairo_dock_icon_is_being_removed (pIcon))
371 		return pIcon;
372 
373 	GList *ic;
374 	for (ic = pIconList; ic != NULL; ic = ic->next)
375 	{
376 		pIcon = ic->data;
377 		if (! gldi_icon_has_dialog (pIcon) && ! CAIRO_DOCK_IS_NORMAL_APPLI (pIcon) && ! GLDI_OBJECT_IS_APPLET_ICON (pIcon) && pIcon->cParentDockName != NULL && ! cairo_dock_icon_is_being_removed (pIcon))
378 			return pIcon;
379 	}
380 
381 	pIcon = cairo_dock_get_first_icon (pIconList);
382 	return pIcon;
383 }
384 
cairo_dock_get_icon_extent(Icon * pIcon,int * iWidth,int * iHeight)385 void cairo_dock_get_icon_extent (Icon *pIcon, int *iWidth, int *iHeight)
386 {
387 	*iWidth = pIcon->image.iWidth;
388 	*iHeight = pIcon->image.iHeight;
389 }
390 
cairo_dock_get_current_icon_size(Icon * pIcon,GldiContainer * pContainer,double * fSizeX,double * fSizeY)391 void cairo_dock_get_current_icon_size (Icon *pIcon, GldiContainer *pContainer, double *fSizeX, double *fSizeY)
392 {
393 	if (pContainer->bIsHorizontal)
394 	{
395 		if (myIconsParam.bConstantSeparatorSize && GLDI_OBJECT_IS_SEPARATOR_ICON (pIcon))
396 		{
397 			*fSizeX = pIcon->fWidth;
398 			*fSizeY = pIcon->fHeight;
399 		}
400 		else
401 		{
402 			*fSizeX = pIcon->fWidth * pIcon->fWidthFactor * pIcon->fScale * pIcon->fGlideScale;
403 			*fSizeY = pIcon->fHeight * pIcon->fHeightFactor * pIcon->fScale * pIcon->fGlideScale;
404 		}
405 	}
406 	else
407 	{
408 		if (myIconsParam.bConstantSeparatorSize && GLDI_OBJECT_IS_SEPARATOR_ICON (pIcon))
409 		{
410 			*fSizeX = pIcon->fHeight;
411 			*fSizeY = pIcon->fWidth;
412 		}
413 		else
414 		{
415 			*fSizeX = pIcon->fHeight * pIcon->fHeightFactor * pIcon->fScale * pIcon->fGlideScale;
416 			*fSizeY = pIcon->fWidth * pIcon->fWidthFactor * pIcon->fScale * pIcon->fGlideScale;
417 		}
418 	}
419 }
420 
cairo_dock_compute_icon_area(Icon * icon,GldiContainer * pContainer,GdkRectangle * pArea)421 void cairo_dock_compute_icon_area (Icon *icon, GldiContainer *pContainer, GdkRectangle *pArea)
422 {
423 	double fReflectSize = 0;
424 	if (pContainer->bUseReflect)
425 	{
426 		fReflectSize = /**myIconsParam.fReflectSize*/icon->fHeight * myIconsParam.fReflectHeightRatio * icon->fScale * fabs (icon->fHeightFactor) + icon->fDeltaYReflection + myDocksParam.iFrameMargin;  // un peu moyen le iFrameMargin mais bon ...
427 	}
428 	if (! myIndicatorsParam.bIndicatorOnIcon)
429 		fReflectSize = MAX (fReflectSize, myIndicatorsParam.fIndicatorDeltaY * icon->fHeight);
430 
431 	double fX = icon->fDrawX;
432 	fX += icon->fWidth * icon->fScale * (1 - fabs (icon->fWidthFactor))/2 + icon->fGlideOffset * icon->fWidth * icon->fScale;
433 
434 	double fY = icon->fDrawY;
435 	if (CAIRO_DOCK_IS_DOCK (pContainer))
436 	{
437 		CairoDock *pDock = CAIRO_DOCK (pContainer);
438 		if (cairo_dock_is_hidden (pDock) && (g_pHidingBackend == NULL || !g_pHidingBackend->bCanDisplayHiddenDock))
439 		{
440 			fY = (pDock->container.bDirectionUp ? pDock->container.iHeight - icon->fHeight * icon->fScale : 0.);
441 		}
442 	}
443 	fY += (pContainer->bDirectionUp ? icon->fHeight * icon->fScale * (1 - icon->fHeightFactor)/2 : - fReflectSize);
444 	if (fY < 0)
445 		fY = 0;
446 
447 	if (pContainer->bIsHorizontal)
448 	{
449 		pArea->x = (int) floor (fX) - 1;
450 		pArea->y = (int) floor (fY);
451 		pArea->width = (int) ceil (icon->fWidth * icon->fScale * fabs (icon->fWidthFactor)) + 2;
452 		pArea->height = (int) ceil (icon->fHeight * icon->fScale * fabs (icon->fHeightFactor) + fReflectSize);
453 	}
454 	else
455 	{
456 		pArea->x = (int) floor (fY);
457 		pArea->y = (int) floor (fX) - 1;
458 		pArea->width = ((int) ceil (icon->fHeight * icon->fScale * fabs (icon->fHeightFactor) + fReflectSize));
459 		pArea->height = (int) ceil (icon->fWidth * icon->fScale * fabs (icon->fWidthFactor)) + 2;
460 	}
461 	//g_print ("redraw : %d;%d %dx%d (%s)\n", pArea->x, pArea->y, pArea->width,pArea->height, icon->cName);
462 }
463 
464 
465 
cairo_dock_normalize_icons_order(GList * pIconList,CairoDockIconGroup iGroup)466 void cairo_dock_normalize_icons_order (GList *pIconList, CairoDockIconGroup iGroup)
467 {
468 	cd_message ("%s (%d)", __func__, iGroup);
469 	int iOrder = 1;
470 	CairoDockIconGroup iGroupOrder = cairo_dock_get_group_order (iGroup);
471 	GString *sDesktopFilePath = g_string_new ("");
472 	GList* ic;
473 	Icon *icon;
474 	for (ic = pIconList; ic != NULL; ic = ic->next)
475 	{
476 		icon = ic->data;
477 		if (cairo_dock_get_icon_order (icon) != iGroupOrder)
478 			continue;
479 
480 		icon->fOrder = iOrder ++;
481 		if (icon->cDesktopFileName != NULL)
482 		{
483 			g_string_printf (sDesktopFilePath, "%s/%s", g_cCurrentLaunchersPath, icon->cDesktopFileName);
484 			cairo_dock_update_conf_file (sDesktopFilePath->str,
485 				G_TYPE_DOUBLE, "Desktop Entry", "Order", icon->fOrder,
486 				G_TYPE_INVALID);
487 		}
488 		else if (CAIRO_DOCK_IS_APPLET (icon))
489 		{
490 			cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
491 				G_TYPE_DOUBLE, "Icon", "order", icon->fOrder,
492 				G_TYPE_INVALID);
493 		}
494 	}
495 	g_string_free (sDesktopFilePath, TRUE);
496 }
497 
cairo_dock_move_icon_after_icon(CairoDock * pDock,Icon * icon1,Icon * icon2)498 void cairo_dock_move_icon_after_icon (CairoDock *pDock, Icon *icon1, Icon *icon2)  // move icon1 after icon2,or at the beginning of the dock/group if icon2 is NULL.
499 {
500 	//g_print ("%s (%s, %.2f, %x)\n", __func__, icon1->cName, icon1->fOrder, icon2);
501 	if ((icon2 != NULL) && fabs (cairo_dock_get_icon_order (icon1) - cairo_dock_get_icon_order (icon2)) > 1)
502 		return ;
503 	//\_________________ On change l'ordre de l'icone.
504 	gboolean bForceUpdate = FALSE;
505 	if (icon2 != NULL)
506 	{
507 		Icon *pNextIcon = cairo_dock_get_next_icon (pDock->icons, icon2);
508 		if (pNextIcon != NULL && fabs (pNextIcon->fOrder - icon2->fOrder) < 1e-2)
509 		{
510 			bForceUpdate = TRUE;
511 		}
512 		if (pNextIcon == NULL || cairo_dock_get_icon_order (pNextIcon) != cairo_dock_get_icon_order (icon2))
513 			icon1->fOrder = icon2->fOrder + 1;
514 		else
515 			icon1->fOrder = (pNextIcon->fOrder - icon2->fOrder > 1 ? icon2->fOrder + 1 : (pNextIcon->fOrder + icon2->fOrder) / 2);
516 	}
517 	else
518 	{
519 		Icon *pFirstIcon = cairo_dock_get_first_icon_of_order (pDock->icons, icon1->iGroup);
520 		if (pFirstIcon != NULL)
521 			icon1->fOrder = pFirstIcon->fOrder - 1;
522 		else
523 			icon1->fOrder = 1;
524 	}
525 	//g_print ("icon1->fOrder:%.2f\n", icon1->fOrder);
526 
527 	//\_________________ On change l'ordre dans le fichier du lanceur 1.
528 	gldi_theme_icon_write_order_in_conf_file (icon1, icon1->fOrder);
529 
530 	//\_________________ On change sa place dans la liste.
531 	pDock->icons = g_list_remove (pDock->icons, icon1);
532 	pDock->icons = g_list_insert_sorted (pDock->icons,
533 		icon1,
534 		(GCompareFunc) cairo_dock_compare_icons_order);
535 
536 	//\_________________ On recalcule la largeur max, qui peut avoir ete influencee par le changement d'ordre.
537 	cairo_dock_trigger_update_dock_size (pDock);
538 
539 	if (icon1->pSubDock != NULL && icon1->cClass != NULL)
540 	{
541 		cairo_dock_trigger_set_WM_icons_geometry (icon1->pSubDock);
542 	}
543 
544 	if (pDock->iRefCount != 0)
545 	{
546 		cairo_dock_redraw_subdock_content (pDock);
547 	}
548 
549 	if (bForceUpdate)
550 		cairo_dock_normalize_icons_order (pDock->icons, icon1->iGroup);
551 
552 	//\_________________ Notify everybody.
553 	gldi_object_notify (pDock, NOTIFICATION_ICON_MOVED, icon1, pDock);
554 }
555 
556 
gldi_icon_set_name(Icon * pIcon,const gchar * cIconName)557 void gldi_icon_set_name (Icon *pIcon, const gchar *cIconName)  // fonction proposee par Necropotame.
558 {
559 	g_return_if_fail (pIcon != NULL);  // le contexte sera verifie plus loin.
560 	gchar *cUniqueName = NULL;
561 
562 	if (pIcon->pSubDock != NULL)
563 	{
564 		cUniqueName = cairo_dock_get_unique_dock_name (cIconName);
565 		cIconName = cUniqueName;
566 		gldi_dock_rename (pIcon->pSubDock, cUniqueName);
567 	}
568 	if (pIcon->cName != cIconName)
569 	{
570 		g_free (pIcon->cName);
571 		pIcon->cName = g_strdup (cIconName);
572 	}
573 
574 	g_free (cUniqueName);
575 
576 	cairo_dock_load_icon_text (pIcon);
577 
578 	if (pIcon->pContainer && pIcon->pContainer->bInside)  // for a dock, in this case the label will be visible.
579 		cairo_dock_redraw_container (pIcon->pContainer);  // this is not really optimized, ideally the view should provide a way to redraw the label area only...
580 }
581 
gldi_icon_set_name_printf(Icon * pIcon,const gchar * cIconNameFormat,...)582 void gldi_icon_set_name_printf (Icon *pIcon, const gchar *cIconNameFormat, ...)
583 {
584 	va_list args;
585 	va_start (args, cIconNameFormat);
586 	gchar *cFullText = g_strdup_vprintf (cIconNameFormat, args);
587 	gldi_icon_set_name (pIcon, cFullText);
588 	g_free (cFullText);
589 	va_end (args);
590 }
591 
gldi_icon_set_quick_info(Icon * pIcon,const gchar * cQuickInfo)592 void gldi_icon_set_quick_info (Icon *pIcon, const gchar *cQuickInfo)
593 {
594 	g_return_if_fail (pIcon != NULL);
595 
596 	if (pIcon->cQuickInfo != cQuickInfo)  // be paranoid, in case one passes pIcon->cQuickInfo to the function
597 	{
598 		if (g_strcmp0 (cQuickInfo, pIcon->cQuickInfo) == 0)  // if the text is the same, no need to reload it.
599 			return;
600 		g_free (pIcon->cQuickInfo);
601 		pIcon->cQuickInfo = g_strdup (cQuickInfo);
602 	}
603 
604 	cairo_dock_load_icon_quickinfo (pIcon);
605 }
606 
gldi_icon_set_quick_info_printf(Icon * pIcon,const gchar * cQuickInfoFormat,...)607 void gldi_icon_set_quick_info_printf (Icon *pIcon, const gchar *cQuickInfoFormat, ...)
608 {
609 	va_list args;
610 	va_start (args, cQuickInfoFormat);
611 	gchar *cFullText = g_strdup_vprintf (cQuickInfoFormat, args);
612 	gldi_icon_set_quick_info (pIcon, cFullText);
613 	g_free (cFullText);
614 	va_end (args);
615 }
616 
617 
cairo_dock_icon_buffer_to_pixbuf(Icon * icon)618 GdkPixbuf *cairo_dock_icon_buffer_to_pixbuf (Icon *icon)
619 {
620 	g_return_val_if_fail (icon != NULL, NULL);
621 
622 	return cairo_dock_image_buffer_to_pixbuf (&icon->image, 24, 24);
623 }
624 
cairo_dock_begin_draw_icon_cairo(Icon * pIcon,gint iRenderingMode,cairo_t * pCairoContext)625 cairo_t *cairo_dock_begin_draw_icon_cairo (Icon *pIcon, gint iRenderingMode, cairo_t *pCairoContext)
626 {
627 	/*if (pIcon->pContainer)
628 		// g_print ("= %s %dx%d\n", pIcon->cName, pIcon->pContainer->iWidth, pIcon->pContainer->iHeight);
629 	else
630 		// g_print ("= %s no container yet\n", pIcon->cName); // e.g. 'indicator' applets -> maybe a return is needed?
631 	*/
632 
633 	cairo_t *ctx = cairo_dock_begin_draw_image_buffer_cairo (&pIcon->image, iRenderingMode, pCairoContext);
634 
635 	if (ctx && iRenderingMode != 1)
636 	{
637 		if (g_pIconBackgroundBuffer.pSurface != NULL
638 		&& ! GLDI_OBJECT_IS_SEPARATOR_ICON (pIcon))
639 		{
640 			int iWidth, iHeight;
641 			cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
642 			cairo_dock_apply_image_buffer_surface_at_size (&g_pIconBackgroundBuffer, ctx, iWidth, iHeight, 0, 0, 1);
643 			pIcon->bNeedApplyBackground = FALSE;
644 		}
645 	}
646 
647 	return ctx;
648 }
649 
cairo_dock_end_draw_icon_cairo(Icon * pIcon)650 void cairo_dock_end_draw_icon_cairo (Icon *pIcon)
651 {
652 	cairo_dock_end_draw_image_buffer_cairo (&pIcon->image);
653 }
654 
cairo_dock_begin_draw_icon(Icon * pIcon,gint iRenderingMode)655 gboolean cairo_dock_begin_draw_icon (Icon *pIcon, gint iRenderingMode)
656 {
657 	gboolean r = cairo_dock_begin_draw_image_buffer_opengl (&pIcon->image, pIcon->pContainer, iRenderingMode);
658 
659 	if (r && iRenderingMode != 1)
660 	{
661 		if (g_pIconBackgroundBuffer.iTexture != 0
662 		&& ! GLDI_OBJECT_IS_SEPARATOR_ICON (pIcon))
663 		{
664 			int iWidth, iHeight;
665 			cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
666 			_cairo_dock_enable_texture ();
667 			_cairo_dock_set_blend_pbuffer ();
668 			_cairo_dock_set_alpha (1.);
669 			_cairo_dock_apply_texture_at_size (g_pIconBackgroundBuffer.iTexture, iWidth, iHeight);
670 			_cairo_dock_disable_texture ();
671 			pIcon->bNeedApplyBackground = FALSE;
672 		}
673 	}
674 
675 	pIcon->bDamaged = !r;
676 
677 	return r;
678 }
679 
cairo_dock_end_draw_icon(Icon * pIcon)680 void cairo_dock_end_draw_icon (Icon *pIcon)
681 {
682 	cairo_dock_end_draw_image_buffer_opengl (&pIcon->image, pIcon->pContainer);
683 }
684 
685 
gldi_theme_icon_write_container_name_in_conf_file(Icon * pIcon,const gchar * cParentDockName)686 void gldi_theme_icon_write_container_name_in_conf_file (Icon *pIcon, const gchar *cParentDockName)
687 {
688 	if (GLDI_OBJECT_IS_USER_ICON (pIcon))
689 	{
690 		g_return_if_fail (pIcon->cDesktopFileName != NULL);
691 		gchar *cDesktopFilePath = *pIcon->cDesktopFileName == '/' ? g_strdup (pIcon->cDesktopFileName) : g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, pIcon->cDesktopFileName);
692 		cairo_dock_update_conf_file (cDesktopFilePath,
693 			G_TYPE_STRING, "Desktop Entry", "Container", cParentDockName,
694 			G_TYPE_INVALID);
695 		g_free (cDesktopFilePath);
696 	}
697 	else if (GLDI_OBJECT_IS_APPLET_ICON (pIcon))
698 	{
699 		cairo_dock_update_conf_file (pIcon->pModuleInstance->cConfFilePath,
700 			G_TYPE_STRING, "Icon", "dock name", cParentDockName,
701 			G_TYPE_INVALID);
702 	}
703 }
704 
gldi_theme_icon_write_order_in_conf_file(Icon * pIcon,double fOrder)705 void gldi_theme_icon_write_order_in_conf_file (Icon *pIcon, double fOrder)
706 {
707 	if (GLDI_OBJECT_IS_USER_ICON (pIcon))
708 	{
709 		g_return_if_fail (pIcon->cDesktopFileName != NULL);
710 		gchar *cDesktopFilePath = *pIcon->cDesktopFileName == '/' ? g_strdup (pIcon->cDesktopFileName) : g_strdup_printf ("%s/%s", g_cCurrentLaunchersPath, pIcon->cDesktopFileName);
711 		cairo_dock_update_conf_file (cDesktopFilePath,
712 			G_TYPE_DOUBLE, "Desktop Entry", "Order", fOrder,
713 			G_TYPE_INVALID);
714 		g_free (cDesktopFilePath);
715 	}
716 	else if (GLDI_OBJECT_IS_APPLET_ICON (pIcon))
717 	{
718 		cairo_dock_update_conf_file (pIcon->pModuleInstance->cConfFilePath,
719 			G_TYPE_DOUBLE, "Icon", "order", fOrder,
720 			G_TYPE_INVALID);
721 	}
722 }
723 
724 
725 
gldi_icon_launch_command(Icon * pIcon)726 gboolean gldi_icon_launch_command (Icon *pIcon)
727 {
728 	// notify startup
729 	gldi_class_startup_notify (pIcon);
730 
731 	// launch command
732 	const gchar *cCommand = pIcon->cCommand;
733 	const gchar *cWorkingDirectory = pIcon->cWorkingDirectory;
734 	if (! cCommand)
735 		cCommand = cairo_dock_get_class_command (pIcon->cClass);
736 
737 	gboolean bSuccess = cairo_dock_launch_command_full (cCommand, cWorkingDirectory);
738 	if (! bSuccess)
739 		gldi_class_startup_notify_end (pIcon->cClass);
740 	return bSuccess;
741 }
742