2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
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.
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/>.
25
#include "cairo-dock-load.h"
26
#include "cairo-dock-draw.h"
27
#include "cairo-dock-config.h"
28
#include "cairo-dock-launcher-manager.h"
29
#include "cairo-dock-surface-factory.h"
30
#include "cairo-dock-animations.h"
31
#include "cairo-dock-packages.h"
32
#include "cairo-dock-keyfile-utilities.h"
33
#include "cairo-dock-applet-factory.h"
34
#include "cairo-dock-log.h"
35
#include "cairo-dock-dock-factory.h"
36
#include "cairo-dock-callbacks.h"
37
#include "cairo-dock-dock-manager.h"
38
#include "cairo-dock-draw-opengl.h"
39
#include "cairo-dock-icons.h"
40
#include "cairo-dock-container.h"
41
#include "cairo-dock-gui-manager.h"
42
#include "cairo-dock-internal-icons.h"
43
#include "cairo-dock-backends-manager.h"
44
#include "cairo-dock-dock-facility.h"
45
#include "cairo-dock-applet-facility.h"
47
extern gchar *g_cExtrasDirPath;
48
extern CairoDockImageBuffer g_pIconBackgroundBuffer;
50
extern gboolean g_bUseOpenGL;
53
void cairo_dock_set_icon_surface_full (cairo_t *pIconContext, cairo_surface_t *pSurface, double fScale, double fAlpha, Icon *pIcon, CairoContainer *pContainer)
55
g_return_if_fail (cairo_status (pIconContext) == CAIRO_STATUS_SUCCESS);
57
//\________________ On efface l'ancienne image.
58
cairo_dock_erase_cairo_context (pIconContext);
60
//\________________ On met le background de l'icone si necessaire
62
pIcon->pIconBuffer != NULL &&
63
g_pIconBackgroundBuffer.pSurface != NULL &&
64
(! CAIRO_DOCK_IS_SEPARATOR (pIcon)))
66
//cd_message (">>> %s prendra un fond d'icone", pIcon->cName);
67
cairo_save (pIconContext);
69
cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
70
cairo_scale(pIconContext,
71
iWidth / g_pIconBackgroundBuffer.iWidth,
72
iHeight / g_pIconBackgroundBuffer.iHeight);
73
cairo_set_source_surface (pIconContext,
74
g_pIconBackgroundBuffer.pSurface,
77
cairo_set_operator (pIconContext, CAIRO_OPERATOR_DEST_OVER);
78
cairo_paint (pIconContext);
79
cairo_restore (pIconContext);
82
//\________________ On applique la nouvelle image.
83
if (pSurface != NULL && fScale > 0)
85
cairo_save (pIconContext);
86
if (fScale != 1 && pIcon != NULL)
89
cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
90
cairo_translate (pIconContext, .5 * iWidth * (1 - fScale) , .5 * iHeight * (1 - fScale));
91
cairo_scale (pIconContext, fScale, fScale);
94
cairo_set_source_surface (
101
cairo_paint_with_alpha (pIconContext, fAlpha);
103
cairo_paint (pIconContext);
104
cairo_restore (pIconContext);
107
cairo_dock_update_icon_texture (pIcon);
111
void cairo_dock_set_icon_surface_with_reflect (cairo_t *pIconContext, cairo_surface_t *pSurface, Icon *pIcon, CairoContainer *pContainer)
113
cairo_dock_set_icon_surface_full (pIconContext, pSurface, 1., 1., pIcon, pContainer);
115
cairo_dock_add_reflection_to_icon (pIcon, pContainer);
118
void cairo_dock_set_image_on_icon (cairo_t *pIconContext, const gchar *cImagePath, Icon *pIcon, CairoContainer *pContainer)
120
if (cImagePath != pIcon->cFileName)
122
g_free (pIcon->cFileName);
123
pIcon->cFileName = g_strdup (cImagePath);
126
cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
127
cairo_surface_t *pImageSurface = cairo_dock_create_surface_for_icon (cImagePath,
131
cairo_dock_set_icon_surface_with_reflect (pIconContext, pImageSurface, pIcon, pContainer);
133
cairo_surface_destroy (pImageSurface);
136
void cairo_dock_set_icon_surface_with_bar (cairo_t *pIconContext, cairo_surface_t *pSurface, double fValue, Icon *pIcon)
138
g_return_if_fail (cairo_status (pIconContext) == CAIRO_STATUS_SUCCESS);
140
//\________________ On efface l'ancienne image.
141
cairo_dock_erase_cairo_context (pIconContext);
143
//\________________ On applique la nouvelle image.
144
if (pSurface != NULL)
146
cairo_set_source_surface (
151
cairo_paint (pIconContext);
154
//\________________ On dessine la barre.
155
cairo_dock_draw_bar_on_icon (pIconContext, fValue, pIcon);
158
cairo_dock_update_icon_texture (pIcon);
161
void cairo_dock_draw_bar_on_icon (cairo_t *pIconContext, double fValue, Icon *pIcon)
163
int iWidth = pIcon->iImageWidth;
164
int iHeight = pIcon->iImageHeight;
166
cairo_pattern_t *pGradationPattern = cairo_pattern_create_linear (0.,
169
0.); // de gauche a droite.
170
g_return_if_fail (cairo_pattern_status (pGradationPattern) == CAIRO_STATUS_SUCCESS);
172
cairo_pattern_set_extend (pGradationPattern, CAIRO_EXTEND_NONE);
173
cairo_pattern_add_color_stop_rgba (pGradationPattern,
174
(fValue >= 0 ? 0. : 1.),
179
cairo_pattern_add_color_stop_rgba (pGradationPattern,
180
(fValue >= 0 ? 1. : 0.),
186
cairo_save (pIconContext);
187
cairo_set_operator (pIconContext, CAIRO_OPERATOR_OVER);
189
cairo_set_line_width (pIconContext, 6);
190
cairo_set_line_cap (pIconContext, CAIRO_LINE_CAP_ROUND);
192
cairo_move_to (pIconContext, 3, iHeight - 3);
193
cairo_rel_line_to (pIconContext, (iWidth - 6) * fabs (fValue), 0);
195
cairo_set_source (pIconContext, pGradationPattern);
196
cairo_stroke (pIconContext);
198
cairo_pattern_destroy (pGradationPattern);
199
cairo_restore (pIconContext);
202
void cairo_dock_set_hours_minutes_as_quick_info (Icon *pIcon, CairoContainer *pContainer, int iTimeInSeconds)
204
int hours = iTimeInSeconds / 3600;
205
int minutes = (iTimeInSeconds % 3600) / 60;
207
cairo_dock_set_quick_info_printf (pIcon, pContainer, "%dh%02d", hours, abs (minutes));
209
cairo_dock_set_quick_info_printf (pIcon, pContainer, "%dmn", minutes);
212
void cairo_dock_set_minutes_secondes_as_quick_info (Icon *pIcon, CairoContainer *pContainer, int iTimeInSeconds)
214
int minutes = iTimeInSeconds / 60;
215
int secondes = iTimeInSeconds % 60;
216
cd_debug ("%s (%d:%d)\n", __func__, minutes, secondes);
218
cairo_dock_set_quick_info_printf (pIcon, pContainer, "%d:%02d", minutes, abs (secondes));
220
cairo_dock_set_quick_info_printf (pIcon, pContainer, "%s0:%02d", (secondes < 0 ? "-" : ""), abs (secondes));
223
gchar *cairo_dock_get_human_readable_size (long long int iSizeInBytes)
226
if (iSizeInBytes >> 10 == 0)
228
return g_strdup_printf ("%dB", (int) iSizeInBytes);
230
else if (iSizeInBytes >> 20 == 0)
232
fValue = (double) (iSizeInBytes) / 1024.;
233
return g_strdup_printf (fValue < 10 ? "%.1fK" : "%.0fK", fValue);
235
else if (iSizeInBytes >> 30 == 0)
237
fValue = (double) (iSizeInBytes >> 10) / 1024.;
238
return g_strdup_printf (fValue < 10 ? "%.1fM" : "%.0fM", fValue);
240
else if (iSizeInBytes >> 40 == 0)
242
fValue = (double) (iSizeInBytes >> 20) / 1024.;
243
return g_strdup_printf (fValue < 10 ? "%.1fG" : "%.0fG", fValue);
247
fValue = (double) (iSizeInBytes >> 30) / 1024.;
248
return g_strdup_printf (fValue < 10 ? "%.1fT" : "%.0fT", fValue);
252
void cairo_dock_set_size_as_quick_info (Icon *pIcon, CairoContainer *pContainer, long long int iSizeInBytes)
254
gchar *cSize = cairo_dock_get_human_readable_size (iSizeInBytes);
255
cairo_dock_set_quick_info (pIcon, pContainer, cSize);
261
gchar *cairo_dock_get_theme_path_for_module (const gchar *cAppletConfFilePath, GKeyFile *pKeyFile, const gchar *cGroupName, const gchar *cKeyName, gboolean *bFlushConfFileNeeded, const gchar *cDefaultThemeName, const gchar *cShareThemesDir, const gchar *cExtraDirName)
263
gchar *cThemeName = cairo_dock_get_string_key_value (pKeyFile, cGroupName, cKeyName, bFlushConfFileNeeded, cDefaultThemeName, NULL, NULL);
265
gchar *cUserThemesDir = (cExtraDirName != NULL ? g_strdup_printf ("%s/%s", g_cExtrasDirPath, cExtraDirName) : NULL);
266
CairoDockPackageType iType = cairo_dock_extract_package_type_from_name (cThemeName);
267
gchar *cThemePath = cairo_dock_get_package_path (cThemeName, cShareThemesDir, cUserThemesDir, cExtraDirName, iType);
269
if (iType != CAIRO_DOCK_ANY_PACKAGE)
271
g_key_file_set_string (pKeyFile, cGroupName, cKeyName, cThemeName);
272
cairo_dock_write_keys_to_file (pKeyFile, cAppletConfFilePath);
275
g_free (cUserThemesDir);
280
GtkWidget *cairo_dock_create_sub_menu (const gchar *cLabel, GtkWidget *pMenu, const gchar *cImage)
282
GtkWidget *pMenuItem, *image, *pSubMenu = gtk_menu_new ();
285
pMenuItem = gtk_menu_item_new_with_label (cLabel);
289
pMenuItem = gtk_image_menu_item_new_with_label (cLabel);
292
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size (cImage, 24, 24, NULL);
293
image = gtk_image_new_from_pixbuf (pixbuf);
294
g_object_unref (pixbuf);
298
image = gtk_image_new_from_stock (cImage, GTK_ICON_SIZE_MENU);
300
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (pMenuItem), image);
302
gtk_menu_shell_append (GTK_MENU_SHELL (pMenu), pMenuItem);
303
gtk_menu_item_set_submenu (GTK_MENU_ITEM (pMenuItem), pSubMenu);
309
//Utile pour jouer des fichiers son depuis le dock.
310
//A utiliser avec l'Objet UI 'u' dans les .conf
311
void cairo_dock_play_sound (const gchar *cSoundPath)
313
cd_debug ("%s (%s)", __func__, cSoundPath);
314
if (cSoundPath == NULL)
316
cd_warning ("No sound to play, skip.");
320
GError *erreur = NULL;
321
gchar *cSoundCommand = NULL;
322
if (g_file_test ("/usr/bin/play", G_FILE_TEST_EXISTS))
323
cSoundCommand = g_strdup_printf("play \"%s\"", cSoundPath);
325
else if (g_file_test ("/usr/bin/aplay", G_FILE_TEST_EXISTS))
326
cSoundCommand = g_strdup_printf("aplay \"%s\"", cSoundPath);
328
else if (g_file_test ("/usr/bin/paplay", G_FILE_TEST_EXISTS))
329
cSoundCommand = g_strdup_printf("paplay \"%s\"", cSoundPath);
331
cairo_dock_launch_command (cSoundCommand);
333
g_free (cSoundCommand);
336
void cairo_dock_get_gnome_version (int *iMajor, int *iMinor, int *iMicro) {
337
gchar *cContent = NULL;
339
GError *erreur = NULL;
340
g_file_get_contents ("/usr/share/gnome-about/gnome-version.xml", &cContent, &length, &erreur);
342
if (erreur != NULL) {
343
cd_warning (erreur->message);
344
g_error_free (erreur);
352
gchar **cLineList = g_strsplit (cContent, "\n", -1);
353
gchar *cOneLine = NULL, *cMajor = NULL, *cMinor = NULL, *cMicro = NULL;
354
int i, iMaj = 0, iMin = 0, iMic = 0;
355
for (i = 0; cLineList[i] != NULL; i ++) {
356
cOneLine = cLineList[i];
357
if (*cOneLine == '\0')
361
cMajor = g_strstr_len (cOneLine, -1, "<platform>"); //<platform>2</platform>
362
if (cMajor != NULL) {
363
cMajor += 10; //On saute <platform>
364
gchar *str = strchr (cMajor, '<');
366
*str = '\0'; //On bloque a </platform>
367
iMaj = atoi (cMajor);
369
else { //Gutsy xml's doesn't have <platform> but <major>
370
cMajor = g_strstr_len (cOneLine, -1, "<major>"); //<major>2</major>
371
if (cMajor != NULL) {
372
cMajor += 7; //On saute <major>
373
gchar *str = strchr (cMajor, '<');
375
*str = '\0'; //On bloque a </major>
376
iMaj = atoi (cMajor);
381
cMinor = g_strstr_len (cOneLine, -1, "<minor>"); //<minor>22</minor>
382
if (cMinor != NULL) {
383
cMinor += 7; //On saute <minor>
384
gchar *str = strchr (cMinor, '<');
386
*str = '\0'; //On bloque a </minor>
387
iMin = atoi (cMinor);
391
cMicro = g_strstr_len (cOneLine, -1, "<micro>"); //<micro>3</micro>
392
if (cMicro != NULL) {
393
cMicro += 7; //On saute <micro>
394
gchar *str = strchr (cMicro, '<');
396
*str = '\0'; //On bloque a </micro>
397
iMic = atoi (cMicro);
400
if (iMaj != 0 && iMin != 0 && iMic != 0)
401
break; //On s'enfou du reste
404
cd_debug ("Gnome Version %d.%d.%d", iMaj, iMin, iMic);
411
g_strfreev (cLineList);
414
void cairo_dock_pop_up_about_applet (GtkMenuItem *menu_item, CairoDockModuleInstance *pModuleInstance)
416
cairo_dock_popup_module_instance_description (pModuleInstance);
420
void cairo_dock_open_module_config_on_demand (int iClickedButton, GtkWidget *pInteractiveWidget, CairoDockModuleInstance *pModuleInstance, CairoDialog *pDialog)
422
if (iClickedButton == 0 || iClickedButton == -1) // bouton OK ou touche Entree.
424
cairo_dock_show_module_instance_gui (pModuleInstance, -1);
429
void cairo_dock_insert_icons_in_applet (CairoDockModuleInstance *pInstance, GList *pIconsList, const gchar *cDockRenderer, const gchar *cDeskletRenderer, gpointer pDeskletRendererData)
431
Icon *pIcon = pInstance->pIcon;
432
g_return_if_fail (pIcon != NULL);
434
CairoContainer *pContainer = pInstance->pContainer;
435
g_return_if_fail (pContainer != NULL);
437
if (pInstance->pDock)
439
if (pIcon->pSubDock == NULL)
441
if (pIcon->cName == NULL)
442
cairo_dock_set_icon_name (pInstance->pModule->pVisitCard->cModuleName, pIcon, pContainer);
443
if (cairo_dock_check_unique_subdock_name (pIcon))
444
cairo_dock_set_icon_name (pIcon->cName, pIcon, pContainer);
445
pIcon->pSubDock = cairo_dock_create_subdock_from_scratch (pIconsList, pIcon->cName, pInstance->pDock);
447
pIcon->pSubDock->bPreventDraggingIcons = TRUE; // par defaut pour toutes les applets on empeche de pouvoir deplacer/supprimer les icones a la souris.
448
if (pIcon->iSubdockViewType != 0)
449
cairo_dock_trigger_redraw_subdock_content_on_icon (pIcon);
455
for (ic = pIconsList; ic != NULL; ic = ic->next)
458
cairo_dock_insert_icon_in_dock (pOneIcon, pIcon->pSubDock, ! CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
459
pOneIcon->cParentDockName = g_strdup (pIcon->cName);
460
cairo_dock_trigger_load_icon_buffers (pOneIcon, CAIRO_CONTAINER (pIcon->pSubDock));
462
g_list_free (pIconsList);
464
cairo_dock_set_renderer (pIcon->pSubDock, cDockRenderer);
465
cairo_dock_update_dock_size (pIcon->pSubDock);
467
else if (pInstance->pDesklet)
469
if (pIcon->pSubDock != NULL) // precaution.
471
cairo_dock_destroy_dock (pIcon->pSubDock, pIcon->cName);
472
pIcon->pSubDock = NULL;
474
pInstance->pDesklet->icons = g_list_concat (pInstance->pDesklet->icons, pIconsList);
475
cairo_dock_set_desklet_renderer_by_name (pInstance->pDesklet, cDeskletRenderer, (CairoDeskletRendererConfigPtr) pDeskletRendererData);
476
cairo_dock_redraw_container (pInstance->pContainer);
481
void cairo_dock_insert_icon_in_applet (CairoDockModuleInstance *pInstance, Icon *pOneIcon)
483
Icon *pIcon = pInstance->pIcon;
484
g_return_if_fail (pIcon != NULL);
486
CairoContainer *pContainer = pInstance->pContainer;
487
g_return_if_fail (pContainer != NULL);
489
if (pInstance->pDock)
491
if (pIcon->pSubDock == NULL)
493
if (pIcon->cName == NULL)
494
cairo_dock_set_icon_name (pInstance->pModule->pVisitCard->cModuleName, pIcon, pContainer);
495
if (cairo_dock_check_unique_subdock_name (pIcon))
496
cairo_dock_set_icon_name (pIcon->cName, pIcon, pContainer);
497
pIcon->pSubDock = cairo_dock_create_subdock_from_scratch (NULL, pIcon->cName, pInstance->pDock);
499
pIcon->pSubDock->bPreventDraggingIcons = TRUE; // par defaut pour toutes les applets on empeche de pouvoir deplacer/supprimer les icones a la souris.
501
if (pOneIcon->fOrder == CAIRO_DOCK_LAST_ORDER)
503
Icon *pLastIcon = cairo_dock_get_last_icon (pIcon->pSubDock->icons);
504
pOneIcon->fOrder = (pLastIcon ? pLastIcon->fOrder + 1 : 0);
506
cairo_dock_trigger_load_icon_buffers (pOneIcon, CAIRO_CONTAINER (pIcon->pSubDock));
507
cairo_dock_insert_icon_in_dock (pOneIcon, pIcon->pSubDock, CAIRO_DOCK_UPDATE_DOCK_SIZE, ! CAIRO_DOCK_ANIMATE_ICON);
508
pOneIcon->cParentDockName = g_strdup (pIcon->cName);
510
else if (pInstance->pDesklet)
512
if (pIcon->pSubDock != NULL) // precaution.
514
cairo_dock_destroy_dock (pIcon->pSubDock, pIcon->cName);
515
pIcon->pSubDock = NULL;
518
if (pOneIcon->fOrder == CAIRO_DOCK_LAST_ORDER)
520
Icon *pLastIcon = cairo_dock_get_last_icon (pInstance->pDesklet->icons);
521
pOneIcon->fOrder = (pLastIcon ? pLastIcon->fOrder + 1 : 0);
523
cairo_dock_insert_icon_in_desklet (pOneIcon, pInstance->pDesklet);
527
gboolean cairo_dock_detach_icon_from_applet (CairoDockModuleInstance *pInstance, Icon *pOneIcon)
529
Icon *pIcon = pInstance->pIcon;
530
g_return_val_if_fail (pIcon != NULL, FALSE);
532
CairoContainer *pContainer = pInstance->pContainer;
533
g_return_val_if_fail (pContainer != NULL, FALSE);
535
if (pOneIcon == NULL)
538
gboolean bRemoved = FALSE;
539
GList *pIconsList = (pInstance->pDock ? (pIcon->pSubDock ? pIcon->pSubDock->icons : NULL) : pInstance->pDesklet->icons);
540
if (pInstance->pDock)
542
if (pIcon->pSubDock != NULL)
544
bRemoved = cairo_dock_detach_icon_from_dock (pOneIcon, pIcon->pSubDock, FALSE);
545
cairo_dock_update_dock_size (pIcon->pSubDock);
548
else if (pInstance->pDesklet)
550
bRemoved = cairo_dock_detach_icon_from_desklet (pOneIcon, pInstance->pDesklet);
555
gboolean cairo_dock_remove_icon_from_applet (CairoDockModuleInstance *pInstance, Icon *pOneIcon)
557
gboolean r = cairo_dock_detach_icon_from_applet (pInstance, pOneIcon);
558
cairo_dock_free_icon (pOneIcon);
562
void cairo_dock_remove_all_icons_from_applet (CairoDockModuleInstance *pInstance)
564
Icon *pIcon = pInstance->pIcon;
565
g_return_if_fail (pIcon != NULL);
567
CairoContainer *pContainer = pInstance->pContainer;
568
g_return_if_fail (pContainer != NULL);
570
g_print ("%s (%s)\n", __func__, pInstance->pModule->pVisitCard->cModuleName);
571
if (pInstance->pDesklet && pInstance->pDesklet->icons != NULL)
573
g_print (" destroy desklet icons\n");
574
g_list_foreach (pInstance->pDesklet->icons, (GFunc) cairo_dock_free_icon, NULL);
575
g_list_free (pInstance->pDesklet->icons);
576
pInstance->pDesklet->icons = NULL;
577
cairo_dock_redraw_container (pInstance->pContainer);
579
if (pIcon->pSubDock != NULL)
581
if (pInstance->pDock) // optimisation : on ne detruit pas le sous-dock.
583
g_print (" destroy sub-dock icons\n");
584
g_list_foreach (pIcon->pSubDock->icons, (GFunc) cairo_dock_free_icon, NULL);
585
g_list_free (pIcon->pSubDock->icons);
586
pIcon->pSubDock->icons = NULL;
587
pIcon->pSubDock->pFirstDrawnElement = NULL;
589
else // precaution pas chere
591
g_print (" destroy sub-dock\n");
592
cairo_dock_destroy_dock (pIcon->pSubDock, pIcon->cName);
593
pIcon->pSubDock = NULL;