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/>.
28
#include <glitz-glx.h>
29
#include <cairo-glitz.h>
32
#include <gtk/gtkgl.h>
34
#include "cairo-dock-draw.h"
35
#include "cairo-dock-icons.h"
36
#include "cairo-dock-surface-factory.h"
37
#include "cairo-dock-launcher-manager.h"
38
#include "cairo-dock-separator-manager.h"
39
#include "cairo-dock-applet-manager.h"
40
#include "cairo-dock-dock-factory.h"
41
#include "cairo-dock-modules.h"
42
#include "cairo-dock-log.h"
43
#include "cairo-dock-dock-manager.h"
44
#include "cairo-dock-class-manager.h"
45
#include "cairo-dock-X-utilities.h"
46
#include "cairo-dock-draw-opengl.h"
47
#include "cairo-dock-internal-taskbar.h"
48
#include "cairo-dock-internal-indicators.h"
49
#include "cairo-dock-internal-labels.h"
50
#include "cairo-dock-internal-background.h"
51
#include "cairo-dock-internal-icons.h"
52
#include "cairo-dock-container.h"
53
#include "cairo-dock-desklet-factory.h"
54
#include "cairo-dock-dialog-manager.h"
55
#include "cairo-dock-data-renderer.h"
56
#include "cairo-dock-flying-container.h"
57
#include "cairo-dock-emblem.h"
58
#include "cairo-dock-X-manager.h"
59
#include "cairo-dock-applications-manager.h"
60
#include "cairo-dock-icon-loader.h"
61
#include "cairo-dock-indicator-manager.h"
62
#include "cairo-dock-load.h"
64
#define CAIRO_DOCK_DEFAULT_APPLI_ICON_NAME "default-icon-appli.svg"
66
GLuint g_pGradationTexture[2]={0, 0};
68
extern CairoDockDesktopGeometry g_desktopGeometry;
69
extern CairoDockDesktopBackground *g_pFakeTransparencyDesktopBg;
71
extern gchar *g_cCurrentThemePath;
73
extern GLuint g_pGradationTexture[2];
75
extern gboolean g_bUseOpenGL;
77
static CairoDockDesktopBackground *s_pDesktopBg = NULL; // une fois alloue, le pointeur restera le meme tout le temps.
79
void cairo_dock_free_label_description (CairoDockLabelDescription *pTextDescription)
81
if (pTextDescription == NULL)
83
g_free (pTextDescription->cFont);
84
g_free (pTextDescription);
87
void cairo_dock_copy_label_description (CairoDockLabelDescription *pDestTextDescription, CairoDockLabelDescription *pOrigTextDescription)
89
g_return_if_fail (pOrigTextDescription != NULL && pDestTextDescription != NULL);
90
memcpy (pDestTextDescription, pOrigTextDescription, sizeof (CairoDockLabelDescription));
91
pDestTextDescription->cFont = g_strdup (pOrigTextDescription->cFont);
94
CairoDockLabelDescription *cairo_dock_duplicate_label_description (CairoDockLabelDescription *pOrigTextDescription)
96
g_return_val_if_fail (pOrigTextDescription != NULL, NULL);
97
CairoDockLabelDescription *pTextDescription = g_memdup (pOrigTextDescription, sizeof (CairoDockLabelDescription));
98
pTextDescription->cFont = g_strdup (pOrigTextDescription->cFont);
99
return pTextDescription;
102
gchar *cairo_dock_generate_file_path (const gchar *cImageFile)
104
g_return_val_if_fail (cImageFile != NULL, NULL);
106
if (*cImageFile == '~')
108
cImagePath = g_strdup_printf ("%s%s", getenv("HOME"), cImageFile + 1);
110
else if (*cImageFile == '/')
112
cImagePath = g_strdup (cImageFile);
116
cImagePath = g_strdup_printf ("%s/%s", g_cCurrentThemePath, cImageFile);
122
void cairo_dock_load_image_buffer_full (CairoDockImageBuffer *pImage, const gchar *cImageFile, int iWidth, int iHeight, CairoDockLoadImageModifier iLoadModifier, double fAlpha)
124
if (cImageFile == NULL)
126
gchar *cImagePath = cairo_dock_generate_file_path (cImageFile);
128
pImage->pSurface = cairo_dock_create_surface_from_image (
143
cairo_surface_t *pNewSurfaceAlpha = cairo_dock_create_blank_surface (
146
cairo_t *pCairoContext = cairo_create (pNewSurfaceAlpha);
148
cairo_set_source_surface (pCairoContext, pImage->pSurface, 0, 0);
149
cairo_paint_with_alpha (pCairoContext, fAlpha);
150
cairo_destroy (pCairoContext);
152
cairo_surface_destroy (pImage->pSurface);
153
pImage->pSurface = pNewSurfaceAlpha;
157
pImage->iTexture = cairo_dock_create_texture_from_surface (pImage->pSurface);
162
void cairo_dock_load_image_buffer_from_surface (CairoDockImageBuffer *pImage, cairo_surface_t *pSurface, int iWidth, int iHeight)
164
pImage->pSurface = pSurface;
165
pImage->iWidth = iWidth;
166
pImage->iHeight = iHeight;
170
pImage->iTexture = cairo_dock_create_texture_from_surface (pImage->pSurface);
173
CairoDockImageBuffer *cairo_dock_create_image_buffer (const gchar *cImageFile, int iWidth, int iHeight, CairoDockLoadImageModifier iLoadModifier)
175
CairoDockImageBuffer *pImage = g_new0 (CairoDockImageBuffer, 1);
177
cairo_dock_load_image_buffer (pImage, cImageFile, iWidth, iHeight, iLoadModifier);
182
void cairo_dock_unload_image_buffer (CairoDockImageBuffer *pImage)
184
if (pImage->pSurface != NULL)
186
cairo_surface_destroy (pImage->pSurface);
188
if (pImage->iTexture != 0)
190
_cairo_dock_delete_texture (pImage->iTexture);
192
memset (pImage, 0, sizeof (CairoDockImageBuffer));
195
void cairo_dock_free_image_buffer (CairoDockImageBuffer *pImage)
199
cairo_dock_unload_image_buffer (pImage);
204
///////////////////////
205
/// DOCK BACKGROUND ///
206
///////////////////////
208
static cairo_surface_t *_cairo_dock_make_stripes_background (int iWidth, int iHeight, double *fStripesColorBright, double *fStripesColorDark, int iNbStripes, double fStripesWidth, double fStripesAngle)
210
cairo_pattern_t *pStripesPattern;
211
double fWidth = iWidth;
212
if (fabs (fStripesAngle) != 90)
213
pStripesPattern = cairo_pattern_create_linear (0.0f,
216
iWidth * tan (fStripesAngle * G_PI/180.));
218
pStripesPattern = cairo_pattern_create_linear (0.0f,
221
(fStripesAngle == 90) ? iHeight : - iHeight);
222
g_return_val_if_fail (cairo_pattern_status (pStripesPattern) == CAIRO_STATUS_SUCCESS, NULL);
224
cairo_pattern_set_extend (pStripesPattern, CAIRO_EXTEND_REPEAT);
230
for (i = 0; i < iNbStripes+1; i ++)
232
fStep = (double)i / iNbStripes;
233
cairo_pattern_add_color_stop_rgba (pStripesPattern,
234
fStep - fStripesWidth / 2.,
235
fStripesColorBright[0],
236
fStripesColorBright[1],
237
fStripesColorBright[2],
238
fStripesColorBright[3]);
239
cairo_pattern_add_color_stop_rgba (pStripesPattern,
241
fStripesColorDark[0],
242
fStripesColorDark[1],
243
fStripesColorDark[2],
244
fStripesColorDark[3]);
245
cairo_pattern_add_color_stop_rgba (pStripesPattern,
246
fStep + fStripesWidth / 2.,
247
fStripesColorBright[0],
248
fStripesColorBright[1],
249
fStripesColorBright[2],
250
fStripesColorBright[3]);
255
cairo_pattern_add_color_stop_rgba (pStripesPattern,
257
fStripesColorDark[0],
258
fStripesColorDark[1],
259
fStripesColorDark[2],
260
fStripesColorDark[3]);
261
cairo_pattern_add_color_stop_rgba (pStripesPattern,
263
fStripesColorBright[0],
264
fStripesColorBright[1],
265
fStripesColorBright[2],
266
fStripesColorBright[3]);
269
cairo_surface_t *pNewSurface = cairo_dock_create_blank_surface (
272
cairo_t *pImageContext = cairo_create (pNewSurface);
273
cairo_set_source (pImageContext, pStripesPattern);
274
cairo_paint (pImageContext);
276
cairo_pattern_destroy (pStripesPattern);
277
cairo_destroy (pImageContext);
281
static void _cairo_dock_load_default_background (CairoDockImageBuffer *pImage, int iWidth, int iHeight)
283
//g_print ("%s (%s, %d)\n", __func__, myBackground.cBackgroundImageFile, myBackground.bBackgroundImageRepeat);
284
if (myBackground.cBackgroundImageFile != NULL)
286
if (myBackground.bBackgroundImageRepeat)
288
cairo_surface_t *pBgSurface = cairo_dock_create_surface_from_pattern (myBackground.cBackgroundImageFile,
291
myBackground.fBackgroundImageAlpha);
292
cairo_dock_load_image_buffer_from_surface (pImage,
299
cairo_dock_load_image_buffer_full (pImage,
300
myBackground.cBackgroundImageFile,
303
CAIRO_DOCK_FILL_SPACE,
304
myBackground.fBackgroundImageAlpha);
307
if (pImage->pSurface == NULL)
309
cairo_surface_t *pBgSurface = _cairo_dock_make_stripes_background (
312
myBackground.fStripesColorBright,
313
myBackground.fStripesColorDark,
314
myBackground.iNbStripes,
315
myBackground.fStripesWidth,
316
myBackground.fStripesAngle);
317
cairo_dock_load_image_buffer_from_surface (pImage,
324
void cairo_dock_load_dock_background (CairoDock *pDock)
326
cairo_dock_unload_image_buffer (&pDock->backgroundBuffer);
328
int iWidth = pDock->iDecorationsWidth;
329
int iHeight = pDock->iDecorationsHeight;
331
if (pDock->bGlobalBg || pDock->iRefCount > 0)
333
_cairo_dock_load_default_background (&pDock->backgroundBuffer, iWidth, iHeight);
335
else if (pDock->cBgImagePath != NULL)
337
cairo_dock_load_image_buffer (&pDock->backgroundBuffer, pDock->cBgImagePath, iWidth, iHeight, CAIRO_DOCK_FILL_SPACE);
339
if (pDock->backgroundBuffer.pSurface == NULL)
341
cairo_surface_t *pSurface = _cairo_dock_make_stripes_background (iWidth, iHeight, pDock->fBgColorBright, pDock->fBgColorDark, 0, 0., 90);
342
cairo_dock_load_image_buffer_from_surface (&pDock->backgroundBuffer, pSurface, iWidth, iHeight);
346
static gboolean _load_background_idle (CairoDock *pDock)
348
cairo_dock_load_dock_background (pDock);
350
pDock->iSidLoadBg = 0;
353
void cairo_dock_trigger_load_dock_background (CairoDock *pDock)
355
if (pDock->iDecorationsWidth == pDock->backgroundBuffer.iWidth && pDock->iDecorationsHeight == pDock->backgroundBuffer.iHeight) // mise a jour inutile.
357
if (pDock->iSidLoadBg == 0)
358
pDock->iSidLoadBg = g_idle_add ((GSourceFunc)_load_background_idle, pDock);
366
static cairo_surface_t *_cairo_dock_create_surface_from_desktop_bg (void) // attention : fonction lourde.
368
cd_debug ("%s ()", __func__);
369
Pixmap iRootPixmapID = cairo_dock_get_window_background_pixmap (cairo_dock_get_root_id ());
370
g_return_val_if_fail (iRootPixmapID != 0, NULL);
372
cairo_surface_t *pDesktopBgSurface = NULL;
373
GdkPixbuf *pBgPixbuf = cairo_dock_get_pixbuf_from_pixmap (iRootPixmapID, FALSE); // FALSE <=> on n'y ajoute pas de transparence.
374
if (pBgPixbuf != NULL)
376
if (gdk_pixbuf_get_height (pBgPixbuf) == 1 && gdk_pixbuf_get_width (pBgPixbuf) == 1) // couleur unie.
378
guchar *pixels = gdk_pixbuf_get_pixels (pBgPixbuf);
379
cd_debug ("c'est une couleur unie (%.2f, %.2f, %.2f)", (double) pixels[0] / 255, (double) pixels[1] / 255, (double) pixels[2] / 255);
381
pDesktopBgSurface = cairo_dock_create_blank_surface (
382
g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL],
383
g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
385
cairo_t *pCairoContext = cairo_create (pDesktopBgSurface);
386
cairo_set_source_rgb (pCairoContext,
387
(double) pixels[0] / 255,
388
(double) pixels[1] / 255,
389
(double) pixels[2] / 255);
390
cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
391
cairo_paint (pCairoContext);
392
cairo_destroy (pCairoContext);
396
double fWidth, fHeight;
397
cairo_surface_t *pBgSurface = cairo_dock_create_surface_from_pixbuf (pBgPixbuf,
406
if (fWidth < g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] || fHeight < g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
408
cd_debug ("c'est un degrade ou un motif (%dx%d)", (int) fWidth, (int) fHeight);
409
pDesktopBgSurface = cairo_dock_create_blank_surface (
410
g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL],
411
g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
412
cairo_t *pCairoContext = cairo_create (pDesktopBgSurface);
414
cairo_pattern_t *pPattern = cairo_pattern_create_for_surface (pBgSurface);
415
g_return_val_if_fail (cairo_pattern_status (pPattern) == CAIRO_STATUS_SUCCESS, NULL);
416
cairo_pattern_set_extend (pPattern, CAIRO_EXTEND_REPEAT);
418
cairo_set_source (pCairoContext, pPattern);
419
cairo_paint (pCairoContext);
421
cairo_destroy (pCairoContext);
422
cairo_pattern_destroy (pPattern);
423
cairo_surface_destroy (pBgSurface);
427
cd_debug ("c'est un fond d'ecran de taille %dx%d", (int) fWidth, (int) fHeight);
428
pDesktopBgSurface = pBgSurface;
432
g_object_unref (pBgPixbuf);
434
return pDesktopBgSurface;
437
CairoDockDesktopBackground *cairo_dock_get_desktop_background (gboolean bWithTextureToo)
439
cd_message ("%s (%d, %d)", __func__, bWithTextureToo, s_pDesktopBg?s_pDesktopBg->iRefCount:-1);
440
if (s_pDesktopBg == NULL)
442
s_pDesktopBg = g_new0 (CairoDockDesktopBackground, 1);
444
if (s_pDesktopBg->iRefCount == 0)
446
s_pDesktopBg->pSurface = _cairo_dock_create_surface_from_desktop_bg ();
448
if (s_pDesktopBg->iTexture == 0 && bWithTextureToo)
450
s_pDesktopBg->iTexture = cairo_dock_create_texture_from_surface (s_pDesktopBg->pSurface);
453
s_pDesktopBg->iRefCount ++;
454
if (s_pDesktopBg->iSidDestroyBg != 0)
456
g_source_remove (s_pDesktopBg->iSidDestroyBg);
457
s_pDesktopBg->iSidDestroyBg = 0;
462
static gboolean _destroy_bg (CairoDockDesktopBackground *pDesktopBg)
464
cd_message ("%s ()", __func__);
465
g_return_val_if_fail (pDesktopBg != NULL, 0);
466
if (pDesktopBg->pSurface != NULL)
468
cairo_surface_destroy (pDesktopBg->pSurface);
469
pDesktopBg->pSurface = NULL;
471
if (pDesktopBg->iTexture != 0)
473
_cairo_dock_delete_texture (pDesktopBg->iTexture);
474
pDesktopBg->iTexture = 0;
476
pDesktopBg->iSidDestroyBg = 0;
479
void cairo_dock_destroy_desktop_background (CairoDockDesktopBackground *pDesktopBg)
481
g_return_if_fail (pDesktopBg != NULL);
482
if (pDesktopBg->iRefCount > 0)
483
pDesktopBg->iRefCount --;
484
if (pDesktopBg->iRefCount == 0 && pDesktopBg->iSidDestroyBg == 0)
486
pDesktopBg->iSidDestroyBg = g_timeout_add_seconds (3, (GSourceFunc)_destroy_bg, pDesktopBg);
490
cairo_surface_t *cairo_dock_get_desktop_bg_surface (CairoDockDesktopBackground *pDesktopBg)
492
g_return_val_if_fail (pDesktopBg != NULL, NULL);
493
return pDesktopBg->pSurface;
496
GLuint cairo_dock_get_desktop_bg_texture (CairoDockDesktopBackground *pDesktopBg)
498
g_return_val_if_fail (pDesktopBg != NULL, 0);
499
return pDesktopBg->iTexture;
502
void cairo_dock_reload_desktop_background (void)
504
cd_message ("%s ()", __func__);
505
if (s_pDesktopBg == NULL) // rien a recharger.
507
if (s_pDesktopBg->pSurface == NULL && s_pDesktopBg->iTexture == 0) // rien a recharger.
510
if (s_pDesktopBg->pSurface != NULL)
511
cairo_surface_destroy (s_pDesktopBg->pSurface);
512
s_pDesktopBg->pSurface = _cairo_dock_create_surface_from_desktop_bg ();
514
if (s_pDesktopBg->iTexture != 0)
516
_cairo_dock_delete_texture (s_pDesktopBg->iTexture);
517
s_pDesktopBg->iTexture = cairo_dock_create_texture_from_surface (s_pDesktopBg->pSurface);
522
void cairo_dock_unload_additionnal_textures (void)
525
if (s_pDesktopBg) // on decharge le desktop-bg de force.
527
_destroy_bg (s_pDesktopBg); // detruit ses ressources immediatement, mais pas le pointeur.
528
if (s_pDesktopBg->iSidDestroyBg != 0)
530
g_source_remove (s_pDesktopBg->iSidDestroyBg);
531
s_pDesktopBg->iSidDestroyBg = 0;
533
s_pDesktopBg->iRefCount = 0;
535
g_pFakeTransparencyDesktopBg = NULL;
536
cairo_dock_unload_desklet_buttons ();
537
cairo_dock_unload_dialog_buttons ();
538
cairo_dock_unload_icon_textures ();
539
cairo_dock_unload_indicator_textures ();
540
if (g_pGradationTexture[0] != 0)
542
_cairo_dock_delete_texture (g_pGradationTexture[0]);
543
g_pGradationTexture[0] = 0;
545
if (g_pGradationTexture[1] != 0)
547
_cairo_dock_delete_texture (g_pGradationTexture[1]);
548
g_pGradationTexture[1] = 0;
550
if (s_pDesktopBg != NULL && s_pDesktopBg->iTexture != 0)
552
_cairo_dock_delete_texture (s_pDesktopBg->iTexture);
553
s_pDesktopBg->iTexture = 0;
555
///cairo_dock_destroy_icon_pbuffer ();
556
cairo_dock_destroy_icon_fbo ();
557
cairo_dock_unload_default_data_renderer_font ();
558
cairo_dock_unload_flying_container_textures ();
559
cairo_dock_reset_source_context ();