~cairo-dock-team/ubuntu/oneiric/cairo-dock/2.3.0-3

« back to all changes in this revision

Viewing changes to src/gldit/cairo-dock-indicator-manager.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20100809232612-pocdxliaxjdetm37
Tags: upstream-2.2.0~0beta4
ImportĀ upstreamĀ versionĀ 2.2.0~0beta4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <stdlib.h>
 
23
 
 
24
#include <gtk/gtk.h>
 
25
 
 
26
#ifdef HAVE_GLITZ
 
27
#include <gdk/gdkx.h>
 
28
#include <glitz-glx.h>
 
29
#include <cairo-glitz.h>
 
30
#endif
 
31
 
 
32
#include <gtk/gtkgl.h>
 
33
 
 
34
//#include "../config.h"
 
35
#include "cairo-dock-draw.h"
 
36
#include "cairo-dock-icons.h"
 
37
#include "cairo-dock-surface-factory.h"
 
38
#include "cairo-dock-launcher-manager.h"
 
39
#include "cairo-dock-separator-manager.h"
 
40
#include "cairo-dock-applet-manager.h"
 
41
#include "cairo-dock-dock-factory.h"
 
42
#include "cairo-dock-modules.h"
 
43
#include "cairo-dock-log.h"
 
44
#include "cairo-dock-dock-manager.h"
 
45
#include "cairo-dock-class-manager.h"
 
46
#include "cairo-dock-X-utilities.h"
 
47
#include "cairo-dock-draw-opengl.h"
 
48
#include "cairo-dock-internal-taskbar.h"
 
49
#include "cairo-dock-internal-indicators.h"
 
50
#include "cairo-dock-internal-background.h"
 
51
#include "cairo-dock-internal-labels.h"
 
52
#include "cairo-dock-internal-icons.h"
 
53
#include "cairo-dock-container.h"
 
54
#include "cairo-dock-desklet-factory.h"
 
55
#include "cairo-dock-dialog-manager.h"
 
56
#include "cairo-dock-data-renderer.h"
 
57
#include "cairo-dock-flying-container.h"
 
58
#include "cairo-dock-emblem.h"
 
59
#include "cairo-dock-X-manager.h"
 
60
#include "cairo-dock-applications-manager.h"
 
61
#include "cairo-dock-load.h"
 
62
#include "cairo-dock-icon-loader.h"
 
63
#include "cairo-dock-notifications.h"
 
64
#include "cairo-dock-indicator-manager.h"
 
65
 
 
66
extern CairoDock *g_pMainDock;
 
67
 
 
68
static CairoDockImageBuffer s_indicatorBuffer;
 
69
static CairoDockImageBuffer s_activeIndicatorBuffer;
 
70
static CairoDockImageBuffer s_classIndicatorBuffer;
 
71
 
 
72
static gboolean cairo_dock_pre_render_indicator_notification (gpointer pUserData, Icon *icon, CairoDock *pDock, cairo_t *pCairoContext);
 
73
static gboolean cairo_dock_render_indicator_notification (gpointer pUserData, Icon *icon, CairoDock *pDock, gboolean *bHasBeenRendered, cairo_t *pCairoContext);
 
74
 
 
75
 
 
76
  ///////////////
 
77
 /// MANAGER ///
 
78
///////////////
 
79
 
 
80
void cairo_dock_init_indicator_manager (void)
 
81
{
 
82
        memset (&s_indicatorBuffer, 0, sizeof (CairoDockImageBuffer));
 
83
        memset (&s_activeIndicatorBuffer, 0, sizeof (CairoDockImageBuffer));
 
84
        memset (&s_classIndicatorBuffer, 0, sizeof (CairoDockImageBuffer));
 
85
        cairo_dock_register_notification (CAIRO_DOCK_PRE_RENDER_ICON,
 
86
                (CairoDockNotificationFunc) cairo_dock_pre_render_indicator_notification,
 
87
                CAIRO_DOCK_RUN_FIRST, NULL);
 
88
        cairo_dock_register_notification (CAIRO_DOCK_RENDER_ICON,
 
89
                (CairoDockNotificationFunc) cairo_dock_render_indicator_notification,
 
90
                CAIRO_DOCK_RUN_AFTER, NULL);
 
91
}
 
92
 
 
93
 
 
94
static inline void cairo_dock_load_task_indicator (const gchar *cIndicatorImagePath, double fMaxScale, double fIndicatorRatio)
 
95
{
 
96
        cairo_dock_unload_image_buffer (&s_indicatorBuffer);
 
97
        
 
98
        double fLauncherWidth = (myIcons.tIconAuthorizedWidth[CAIRO_DOCK_LAUNCHER] != 0 ? myIcons.tIconAuthorizedWidth[CAIRO_DOCK_LAUNCHER] : 48);
 
99
        double fLauncherHeight = (myIcons.tIconAuthorizedHeight[CAIRO_DOCK_LAUNCHER] != 0 ? myIcons.tIconAuthorizedHeight[CAIRO_DOCK_LAUNCHER] : 48);
 
100
        double fScale = (myIndicators.bIndicatorOnIcon ? fMaxScale : 1.) * fIndicatorRatio;
 
101
        
 
102
        cairo_dock_load_image_buffer (&s_indicatorBuffer,
 
103
                cIndicatorImagePath,
 
104
                fLauncherWidth * fScale,
 
105
                fLauncherHeight * fScale,
 
106
                CAIRO_DOCK_KEEP_RATIO);
 
107
}
 
108
static inline void cairo_dock_load_active_window_indicator (const gchar *cImagePath, double fMaxScale, double fCornerRadius, double fLineWidth, double *fActiveColor)
 
109
{
 
110
        cairo_dock_unload_image_buffer (&s_activeIndicatorBuffer);
 
111
        
 
112
        int iWidth = MAX (myIcons.tIconAuthorizedWidth[CAIRO_DOCK_LAUNCHER], myIcons.tIconAuthorizedWidth[CAIRO_DOCK_APPLI]);
 
113
        int iHeight = MAX (myIcons.tIconAuthorizedHeight[CAIRO_DOCK_APPLI], myIcons.tIconAuthorizedHeight[CAIRO_DOCK_APPLI]);
 
114
        if (iWidth == 0)
 
115
                iWidth = 48;
 
116
        if (iHeight == 0)
 
117
                iHeight = 48;
 
118
        iWidth *= fMaxScale;
 
119
        iHeight *= fMaxScale;
 
120
        
 
121
        if (cImagePath != NULL)
 
122
        {
 
123
                cairo_dock_load_image_buffer (&s_activeIndicatorBuffer,
 
124
                        cImagePath,
 
125
                        iWidth,
 
126
                        iHeight,
 
127
                        CAIRO_DOCK_FILL_SPACE);
 
128
        }
 
129
        else if (fActiveColor[3] > 0)
 
130
        {
 
131
                cairo_surface_t *pSurface = cairo_dock_create_blank_surface (iWidth, iHeight);
 
132
                cairo_t *pCairoContext = cairo_create (pSurface);
 
133
                
 
134
                fCornerRadius = MIN (fCornerRadius, (iWidth - fLineWidth) / 2);
 
135
                double fFrameWidth = iWidth - (2 * fCornerRadius + fLineWidth);
 
136
                double fFrameHeight = iHeight - 2 * fLineWidth;
 
137
                double fDockOffsetX = fCornerRadius + fLineWidth/2;
 
138
                double fDockOffsetY = fLineWidth/2;
 
139
                cairo_dock_draw_frame (pCairoContext, fCornerRadius, fLineWidth, fFrameWidth, fFrameHeight, fDockOffsetX, fDockOffsetY, 1, 0., CAIRO_DOCK_HORIZONTAL, TRUE);
 
140
                
 
141
                cairo_set_source_rgba (pCairoContext, fActiveColor[0], fActiveColor[1], fActiveColor[2], fActiveColor[3]);
 
142
                if (fLineWidth > 0)
 
143
                {
 
144
                        cairo_set_line_width (pCairoContext, fLineWidth);
 
145
                        cairo_stroke (pCairoContext);
 
146
                }
 
147
                else
 
148
                {
 
149
                        cairo_fill (pCairoContext);
 
150
                }
 
151
                cairo_destroy (pCairoContext);
 
152
                
 
153
                cairo_dock_load_image_buffer_from_surface (&s_activeIndicatorBuffer,
 
154
                        pSurface,
 
155
                        iWidth,
 
156
                        iHeight);
 
157
        }
 
158
}
 
159
static inline void cairo_dock_load_class_indicator (const gchar *cIndicatorImagePath, double fMaxScale)
 
160
{
 
161
        cairo_dock_unload_image_buffer (&s_classIndicatorBuffer);
 
162
        
 
163
        double fLauncherWidth = (myIcons.tIconAuthorizedWidth[CAIRO_DOCK_LAUNCHER] != 0 ? myIcons.tIconAuthorizedWidth[CAIRO_DOCK_LAUNCHER] : 48);
 
164
        double fLauncherHeight = (myIcons.tIconAuthorizedHeight[CAIRO_DOCK_LAUNCHER] != 0 ? myIcons.tIconAuthorizedHeight[CAIRO_DOCK_LAUNCHER] : 48);
 
165
        
 
166
        cairo_dock_load_image_buffer (&s_classIndicatorBuffer,
 
167
                cIndicatorImagePath,
 
168
                fLauncherWidth/3,
 
169
                fLauncherHeight/3,
 
170
                CAIRO_DOCK_KEEP_RATIO);
 
171
}
 
172
void cairo_dock_load_indicator_textures (void)
 
173
{
 
174
        double fMaxScale = cairo_dock_get_max_scale (g_pMainDock);
 
175
        
 
176
        cairo_dock_load_task_indicator (myTaskBar.bShowAppli && (myTaskBar.bMixLauncherAppli || myIndicators.bDrawIndicatorOnAppli) ? myIndicators.cIndicatorImagePath : NULL, fMaxScale, myIndicators.fIndicatorRatio);
 
177
        
 
178
        cairo_dock_load_active_window_indicator (myIndicators.cActiveIndicatorImagePath, fMaxScale, myIndicators.iActiveCornerRadius, myIndicators.iActiveLineWidth, myIndicators.fActiveColor);
 
179
        
 
180
        cairo_dock_load_class_indicator (myTaskBar.bShowAppli && myTaskBar.bGroupAppliByClass ? myIndicators.cClassIndicatorImagePath : NULL, fMaxScale);
 
181
}
 
182
 
 
183
 
 
184
void cairo_dock_unload_indicator_textures (void)
 
185
{
 
186
        cairo_dock_unload_image_buffer (&s_indicatorBuffer);
 
187
        cairo_dock_unload_image_buffer (&s_activeIndicatorBuffer);
 
188
        cairo_dock_unload_image_buffer (&s_classIndicatorBuffer);
 
189
}
 
190
 
 
191
 
 
192
static void _set_indicator (Icon *pIcon, CairoContainer *pContainer, gpointer data)
 
193
{
 
194
        pIcon->bHasIndicator = GPOINTER_TO_INT (data);
 
195
}
 
196
void cairo_dock_reload_indicators (CairoConfigIndicators *pPrevIndicators, CairoConfigIndicators *pIndicators)
 
197
{
 
198
        double fMaxScale = cairo_dock_get_max_scale (g_pMainDock);
 
199
        
 
200
        if (cairo_dock_strings_differ (pPrevIndicators->cIndicatorImagePath, pIndicators->cIndicatorImagePath) ||
 
201
                pPrevIndicators->bIndicatorOnIcon != pIndicators->bIndicatorOnIcon ||
 
202
                pPrevIndicators->fIndicatorRatio != pIndicators->fIndicatorRatio)
 
203
        {
 
204
                cairo_dock_load_task_indicator (myTaskBar.bShowAppli && (myTaskBar.bMixLauncherAppli || myIndicators.bDrawIndicatorOnAppli) ? pIndicators->cIndicatorImagePath : NULL, fMaxScale, pIndicators->fIndicatorRatio);
 
205
        }
 
206
        
 
207
        if (cairo_dock_strings_differ (pPrevIndicators->cActiveIndicatorImagePath, pIndicators->cActiveIndicatorImagePath) ||
 
208
                pPrevIndicators->iActiveCornerRadius != pIndicators->iActiveCornerRadius ||
 
209
                pPrevIndicators->iActiveLineWidth != pIndicators->iActiveLineWidth ||
 
210
                cairo_dock_colors_differ (pPrevIndicators->fActiveColor, pIndicators->fActiveColor))
 
211
        {
 
212
                cairo_dock_load_active_window_indicator (pIndicators->cActiveIndicatorImagePath,
 
213
                        fMaxScale,
 
214
                        pIndicators->iActiveCornerRadius,
 
215
                        pIndicators->iActiveLineWidth,
 
216
                        pIndicators->fActiveColor);
 
217
        }
 
218
        
 
219
        if (cairo_dock_strings_differ (pPrevIndicators->cClassIndicatorImagePath, pIndicators->cClassIndicatorImagePath) ||
 
220
                pPrevIndicators->bUseClassIndic != pIndicators->bUseClassIndic)
 
221
        {
 
222
                cairo_dock_load_class_indicator (myTaskBar.bShowAppli && myTaskBar.bGroupAppliByClass ? pIndicators->cClassIndicatorImagePath : NULL, fMaxScale);
 
223
                
 
224
                if (pPrevIndicators->bUseClassIndic != pIndicators->bUseClassIndic && g_pMainDock)  // on recharge les icones pointant sur une classe (qui sont dans le main dock).
 
225
                {
 
226
                        Icon *icon;
 
227
                        GList *ic;
 
228
                        for (ic = g_pMainDock->icons; ic != NULL; ic = ic->next)
 
229
                        {
 
230
                                icon = ic->data;
 
231
                                if (CAIRO_DOCK_IS_MULTI_APPLI (icon))
 
232
                                {
 
233
                                        cairo_dock_load_icon_image (icon, CAIRO_CONTAINER (g_pMainDock));
 
234
                                        if (!pIndicators->bUseClassIndic)
 
235
                                                cairo_dock_draw_subdock_content_on_icon (icon, g_pMainDock);
 
236
                                }
 
237
                        }
 
238
                }
 
239
        }
 
240
        
 
241
        if (cairo_dock_application_manager_is_running () &&
 
242
                pPrevIndicators->bDrawIndicatorOnAppli != pIndicators->bDrawIndicatorOnAppli)
 
243
        {
 
244
                cairo_dock_foreach_applis ((CairoDockForeachIconFunc) _set_indicator, FALSE, GINT_TO_POINTER (pIndicators->bDrawIndicatorOnAppli));
 
245
        }
 
246
        
 
247
        cairo_dock_redraw_root_docks (FALSE);  // tous les docks (main dock et les autres qui peuvent contenir des applets avec un indicateur).
 
248
}
 
249
 
 
250
 
 
251
  /////////////////
 
252
 /// RENDERING ///
 
253
/////////////////
 
254
 
 
255
static inline double _compute_delta_y (Icon *icon, double py, gboolean bOnIcon, double fRatio, gboolean bUseReflect)
 
256
{
 
257
        double dy;
 
258
        if (bOnIcon)  // decalage vers le haut et zoom avec l'icone.
 
259
                dy = py * icon->fHeight * icon->fScale + icon->fDeltaYReflection;
 
260
        else  // decalage vers le bas sans zoom.
 
261
                dy = - py * ((bUseReflect ? myIcons.fReflectSize * fRatio : 0.) + myBackground.iFrameMargin + .5*myBackground.iDockLineWidth);
 
262
        return dy;
 
263
}
 
264
 
 
265
static void _cairo_dock_draw_appli_indicator_opengl (Icon *icon, CairoDock *pDock)
 
266
{
 
267
        gboolean bIsHorizontal = pDock->container.bIsHorizontal;
 
268
        gboolean bDirectionUp = pDock->container.bDirectionUp;
 
269
        double fRatio = pDock->container.fRatio;
 
270
        if (! myIndicators.bRotateWithDock)
 
271
                bDirectionUp = bIsHorizontal = TRUE;
 
272
        
 
273
        //\__________________ On calcule l'offset et le zoom.
 
274
        double w = s_indicatorBuffer.iWidth;
 
275
        double h = s_indicatorBuffer.iHeight;
 
276
        double fMaxScale = cairo_dock_get_max_scale (pDock);
 
277
        double z = (myIndicators.bIndicatorOnIcon ? icon->fScale / fMaxScale : 1.) * fRatio;  // on divise par fMaxScale car l'indicateur est charge a la taille max des icones.
 
278
        double fY = _compute_delta_y (icon, myIndicators.fIndicatorDeltaY, myIndicators.bIndicatorOnIcon, fRatio, pDock->container.bUseReflect);
 
279
        fY += - icon->fHeight * icon->fScale/2 + h*z/2;  // a 0, le bas de l'indicateur correspond au bas de l'icone.
 
280
        
 
281
        //\__________________ On place l'indicateur.
 
282
        glPushMatrix ();
 
283
        if (bIsHorizontal)
 
284
        {
 
285
                if (! bDirectionUp)
 
286
                        fY = - fY;
 
287
                glTranslatef (0., fY, 0.);
 
288
        }
 
289
        else
 
290
        {
 
291
                if (bDirectionUp)
 
292
                        fY = - fY;
 
293
                glTranslatef (fY, 0., 0.);
 
294
                glRotatef (90, 0., 0., 1.);
 
295
        }
 
296
        glScalef (w * z, (bDirectionUp ? 1:-1) * h * z, 1.);
 
297
        /**double z = 1 + myIcons.fAmplitude;
 
298
        double w = s_indicatorBuffer.iWidth;
 
299
        double h = s_indicatorBuffer.iHeight;
 
300
        double dy = myIndicators.iIndicatorDeltaY / z;
 
301
        double fY;
 
302
        if (myIndicators.bLinkIndicatorWithIcon)  // il se deforme et rebondit avec l'icone.
 
303
        {
 
304
                w /= z;
 
305
                h /= z;
 
306
                fY = - icon->fHeight * icon->fScale/2
 
307
                        + (h/2 - dy) * fRatio * icon->fScale;
 
308
                
 
309
                if (bIsHorizontal)
 
310
                {
 
311
                        if (! bDirectionUp)
 
312
                                fY = - fY;
 
313
                        glTranslatef (0., fY, 0.);
 
314
                        glScalef (w * fRatio * icon->fScale * icon->fWidthFactor, (bDirectionUp ? 1:-1) * h * fRatio * icon->fScale * icon->fHeightFactor, 1.);
 
315
                }
 
316
                else
 
317
                {
 
318
                        if (bDirectionUp)
 
319
                                fY = - fY;
 
320
                        glTranslatef (fY, 0., 0.);
 
321
                        glRotatef (90, 0., 0., 1.);
 
322
                        glScalef (w * fRatio * icon->fScale * icon->fWidthFactor, (bDirectionUp ? 1:-1) * h * fRatio * icon->fScale * icon->fHeightFactor, 1.);
 
323
                }
 
324
                
 
325
        }
 
326
        else  // il est fixe, en bas de l'icone.
 
327
        {
 
328
                fY = - icon->fHeight * icon->fScale/2
 
329
                        + (h/2 - dy) * fRatio;
 
330
                if (bIsHorizontal)
 
331
                {
 
332
                        if (! bDirectionUp)
 
333
                                fY = - fY;
 
334
                        glTranslatef (0., fY, 1.);
 
335
                        glScalef (w * fRatio * 1., (bDirectionUp ? 1:-1) * h * fRatio * 1., 1.);
 
336
                }
 
337
                else
 
338
                {
 
339
                        if (bDirectionUp)
 
340
                                fY = - fY;
 
341
                        glTranslatef (fY, 0., 1.);
 
342
                        glRotatef (90, 0., 0., 1.);
 
343
                        glScalef (w * fRatio * 1., (bDirectionUp ? 1:-1) * h * fRatio * 1., 1.);
 
344
                }
 
345
        }*/
 
346
        
 
347
        //\__________________ On dessine l'indicateur.
 
348
        cairo_dock_draw_texture_with_alpha (s_indicatorBuffer.iTexture, 1., 1., 1.);
 
349
        glPopMatrix ();
 
350
}
 
351
static void _cairo_dock_draw_active_window_indicator_opengl (Icon *icon, CairoDock *pDock, double fRatio)
 
352
{
 
353
        if (s_activeIndicatorBuffer.iTexture == 0)
 
354
                return ;
 
355
        glPushMatrix ();
 
356
        cairo_dock_set_icon_scale (icon, CAIRO_CONTAINER (pDock), 1.);
 
357
        
 
358
        _cairo_dock_enable_texture ();
 
359
        
 
360
        _cairo_dock_set_blend_pbuffer ();  // rend mieux que les 2 autres.
 
361
        
 
362
        _cairo_dock_apply_texture_at_size_with_alpha (s_activeIndicatorBuffer.iTexture, 1., 1., 1.);
 
363
        
 
364
        _cairo_dock_disable_texture ();
 
365
        glPopMatrix ();
 
366
        
 
367
}
 
368
static void _cairo_dock_draw_class_indicator_opengl (Icon *icon, gboolean bIsHorizontal, double fRatio, gboolean bDirectionUp)
 
369
{
 
370
        glPushMatrix ();
 
371
        if (myIndicators.bZoomClassIndicator)
 
372
                fRatio *= icon->fScale;
 
373
        double w = s_classIndicatorBuffer.iWidth;
 
374
        double h = s_classIndicatorBuffer.iHeight;
 
375
        
 
376
        if (! bIsHorizontal)
 
377
                glRotatef (90., 0., 0., 1.);
 
378
        if (! bDirectionUp)
 
379
                glScalef (1., -1., 1.);
 
380
        glTranslatef (icon->fWidth * icon->fScale/2 - w * fRatio/2,
 
381
                icon->fHeight * icon->fScale/2 - h * fRatio/2,
 
382
                0.);
 
383
        
 
384
        cairo_dock_draw_texture_with_alpha (s_classIndicatorBuffer.iTexture,
 
385
                w * fRatio,
 
386
                h * fRatio,
 
387
                1.);
 
388
        glPopMatrix ();
 
389
}
 
390
 
 
391
static void _cairo_dock_draw_appli_indicator (Icon *icon, CairoDock *pDock, cairo_t *pCairoContext)
 
392
{
 
393
        gboolean bIsHorizontal = pDock->container.bIsHorizontal;
 
394
        gboolean bDirectionUp = pDock->container.bDirectionUp;
 
395
        double fRatio = pDock->container.fRatio;
 
396
        if (! myIndicators.bRotateWithDock)
 
397
                bDirectionUp = bIsHorizontal = TRUE;
 
398
        
 
399
        //\__________________ On calcule l'offset et le zoom.
 
400
        double w = s_indicatorBuffer.iWidth;
 
401
        double h = s_indicatorBuffer.iHeight;
 
402
        double fMaxScale = cairo_dock_get_max_scale (pDock);
 
403
        double z = (myIndicators.bIndicatorOnIcon ? icon->fScale / fMaxScale : 1.) * fRatio;  // on divise par fMaxScale car l'indicateur est charge a la taille max des icones.
 
404
        double fY = - _compute_delta_y (icon, myIndicators.fIndicatorDeltaY, myIndicators.bIndicatorOnIcon, fRatio, pDock->container.bUseReflect);  // a 0, le bas de l'indicateur correspond au bas de l'icone.
 
405
        
 
406
        //\__________________ On place l'indicateur.
 
407
        cairo_save (pCairoContext);
 
408
        if (bIsHorizontal)
 
409
        {
 
410
                cairo_translate (pCairoContext,
 
411
                        icon->fWidth * icon->fScale / 2 - w * z/2,
 
412
                        (bDirectionUp ?
 
413
                                icon->fHeight * icon->fScale - h * z + fY :
 
414
                                - fY));
 
415
                cairo_scale (pCairoContext,
 
416
                        z,
 
417
                        z);
 
418
        }
 
419
        else
 
420
        {
 
421
                cairo_translate (pCairoContext,
 
422
                        (bDirectionUp ?
 
423
                                icon->fHeight * icon->fScale - h * z + fY :
 
424
                                - fY),
 
425
                        icon->fWidth * icon->fScale / 2 - (w * z/2));
 
426
                cairo_scale (pCairoContext,
 
427
                        z,
 
428
                        z);
 
429
        }
 
430
        /**double dy = myIndicators.iIndicatorDeltaY / z;
 
431
        if (myIndicators.bLinkIndicatorWithIcon)
 
432
        {
 
433
                w /= z;
 
434
                h /= z;
 
435
                if (bIsHorizontal)
 
436
                {
 
437
                        cairo_translate (pCairoContext,
 
438
                                (icon->fWidth - w * fRatio) * icon->fWidthFactor * icon->fScale / 2,
 
439
                                (bDirectionUp ?
 
440
                                        (icon->fHeight - (h - dy) * fRatio) * icon->fScale :
 
441
                                        - dy * icon->fScale * fRatio));
 
442
                        cairo_scale (pCairoContext,
 
443
                                fRatio * icon->fWidthFactor * icon->fScale / z,
 
444
                                fRatio * icon->fHeightFactor * icon->fScale / z * (bDirectionUp ? 1 : -1));
 
445
                }
 
446
                else
 
447
                {
 
448
                        cairo_translate (pCairoContext,
 
449
                                (bDirectionUp ?
 
450
                                        (icon->fHeight - (h - dy) * fRatio) * icon->fScale :
 
451
                                        - dy * icon->fScale * fRatio),
 
452
                                        (icon->fWidth - (bDirectionUp ? 0 : w * fRatio)) * icon->fWidthFactor * icon->fScale / 2);
 
453
                        cairo_scale (pCairoContext,
 
454
                                fRatio * icon->fHeightFactor * icon->fScale / z * (bDirectionUp ? 1 : -1),
 
455
                                fRatio * icon->fWidthFactor * icon->fScale / z);
 
456
                }
 
457
        }
 
458
        else
 
459
        {
 
460
                if (bIsHorizontal)
 
461
                {
 
462
                        cairo_translate (pCairoContext,
 
463
                                (icon->fWidth * icon->fScale - w * fRatio) / 2,
 
464
                                (bDirectionUp ? 
 
465
                                        (icon->fHeight * icon->fScale - (h - dy) * fRatio) :
 
466
                                        - dy * fRatio));
 
467
                        cairo_scale (pCairoContext,
 
468
                                fRatio,
 
469
                                fRatio);
 
470
                }
 
471
                else
 
472
                {
 
473
                        cairo_translate (pCairoContext,
 
474
                                (bDirectionUp ? 
 
475
                                        icon->fHeight * icon->fScale - (h - dy) * fRatio : 
 
476
                                        - dy * 1 * fRatio),
 
477
                                (icon->fWidth * icon->fScale - w * fRatio) / 2);
 
478
                        cairo_scale (pCairoContext,
 
479
                                fRatio,
 
480
                                fRatio);
 
481
                }
 
482
        }*/
 
483
        
 
484
        cairo_dock_draw_surface (pCairoContext, s_indicatorBuffer.pSurface, w, h, bDirectionUp, bIsHorizontal, 1.);
 
485
        cairo_restore (pCairoContext);
 
486
}
 
487
static void _cairo_dock_draw_active_window_indicator (cairo_t *pCairoContext, Icon *icon)
 
488
{
 
489
        cairo_save (pCairoContext);
 
490
        cairo_scale (pCairoContext,
 
491
                icon->fWidth * icon->fWidthFactor / s_activeIndicatorBuffer.iWidth * icon->fScale,
 
492
                icon->fHeight * icon->fHeightFactor / s_activeIndicatorBuffer.iHeight * icon->fScale);
 
493
        cairo_set_source_surface (pCairoContext, s_activeIndicatorBuffer.pSurface, 0., 0.);
 
494
        cairo_paint (pCairoContext);
 
495
        cairo_restore (pCairoContext);
 
496
}
 
497
static void _cairo_dock_draw_class_indicator (cairo_t *pCairoContext, Icon *icon, gboolean bIsHorizontal, double fRatio, gboolean bDirectionUp)
 
498
{
 
499
        cairo_save (pCairoContext);
 
500
        double w = s_classIndicatorBuffer.iWidth;
 
501
        double h = s_classIndicatorBuffer.iHeight;
 
502
        if (bIsHorizontal)
 
503
        {
 
504
                if (bDirectionUp)
 
505
                        cairo_translate (pCairoContext,
 
506
                                (icon->fWidth - w * fRatio) * icon->fScale,
 
507
                                0.);
 
508
                else
 
509
                        cairo_translate (pCairoContext,
 
510
                                (icon->fWidth - w * fRatio) * icon->fScale,
 
511
                                (icon->fHeight - h * fRatio) * icon->fScale);
 
512
        }
 
513
        else
 
514
        {
 
515
                if (bDirectionUp)
 
516
                        cairo_translate (pCairoContext,
 
517
                                0.,
 
518
                                (icon->fWidth - w * fRatio) * icon->fScale);
 
519
                else
 
520
                        cairo_translate (pCairoContext,
 
521
                                (icon->fHeight - h * fRatio) * icon->fScale,
 
522
                                (icon->fWidth - w * fRatio) * icon->fScale);
 
523
        }
 
524
        cairo_scale (pCairoContext, fRatio * icon->fScale, fRatio * icon->fScale);
 
525
        cairo_dock_draw_surface (pCairoContext, s_classIndicatorBuffer.pSurface, w, h, bDirectionUp, bIsHorizontal, 1.);
 
526
        cairo_restore (pCairoContext);
 
527
}
 
528
 
 
529
static inline gboolean _active_indicator_is_visible (Icon *icon)
 
530
{
 
531
        gboolean bIsActive = FALSE;
 
532
        if (icon->Xid)
 
533
        {
 
534
                Window xActiveId = cairo_dock_get_current_active_window ();
 
535
                if (xActiveId != 0)
 
536
                {
 
537
                        bIsActive = (icon->Xid == xActiveId);
 
538
                        if (!bIsActive && icon->pSubDock != NULL)
 
539
                        {
 
540
                                Icon *subicon;
 
541
                                GList *ic;
 
542
                                for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
 
543
                                {
 
544
                                        subicon = ic->data;
 
545
                                        if (subicon->Xid == xActiveId)
 
546
                                        {
 
547
                                                bIsActive = TRUE;
 
548
                                                break;
 
549
                                        }
 
550
                                }
 
551
                        }
 
552
                }
 
553
        }
 
554
        return bIsActive;
 
555
}
 
556
 
 
557
static gboolean cairo_dock_pre_render_indicator_notification (gpointer pUserData, Icon *icon, CairoDock *pDock, cairo_t *pCairoContext)
 
558
{
 
559
        gboolean bIsActive = (myIndicators.bActiveIndicatorAbove ? FALSE : _active_indicator_is_visible (icon));
 
560
        
 
561
        if (pCairoContext != NULL)
 
562
        {
 
563
                if (icon->bHasIndicator && ! myIndicators.bIndicatorAbove && s_indicatorBuffer.pSurface != NULL)
 
564
                {
 
565
                        _cairo_dock_draw_appli_indicator (icon, pDock, pCairoContext);
 
566
                }
 
567
                
 
568
                if (bIsActive && s_activeIndicatorBuffer.pSurface != NULL)
 
569
                {
 
570
                        _cairo_dock_draw_active_window_indicator (pCairoContext, icon);
 
571
                }
 
572
        }
 
573
        else
 
574
        {
 
575
                if (icon->bHasIndicator && ! myIndicators.bIndicatorAbove)
 
576
                {
 
577
                        //glPushMatrix ();
 
578
                        _cairo_dock_draw_appli_indicator_opengl (icon, pDock);
 
579
                        //glPopMatrix ();
 
580
                }
 
581
                
 
582
                if (bIsActive)
 
583
                {
 
584
                        //glPushMatrix ();
 
585
                        _cairo_dock_draw_active_window_indicator_opengl (icon, pDock, pDock->container.fRatio);
 
586
                        //glPopMatrix ();
 
587
                }
 
588
        }
 
589
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
590
}
 
591
 
 
592
static gboolean cairo_dock_render_indicator_notification (gpointer pUserData, Icon *icon, CairoDock *pDock, gboolean *bHasBeenRendered, cairo_t *pCairoContext)
 
593
{
 
594
        gboolean bIsActive = (myIndicators.bActiveIndicatorAbove ? _active_indicator_is_visible (icon) : FALSE);
 
595
        
 
596
        if (pCairoContext != NULL)
 
597
        {
 
598
                if (bIsActive)
 
599
                {
 
600
                        _cairo_dock_draw_active_window_indicator (pCairoContext, icon);
 
601
                }
 
602
                if (icon->bHasIndicator && myIndicators.bIndicatorAbove && s_indicatorBuffer.pSurface != NULL)
 
603
                {
 
604
                        _cairo_dock_draw_appli_indicator (icon, pDock, pCairoContext);
 
605
                }
 
606
                if (icon->pSubDock != NULL && icon->cClass != NULL && s_classIndicatorBuffer.pSurface != NULL && icon->Xid == 0)  // le dernier test est de la paranoia.
 
607
                {
 
608
                        _cairo_dock_draw_class_indicator (pCairoContext, icon, pDock->container.bIsHorizontal, pDock->container.fRatio, pDock->container.bDirectionUp);
 
609
                }
 
610
        }
 
611
        else
 
612
        {
 
613
                if (icon->bHasIndicator && myIndicators.bIndicatorAbove)
 
614
                {
 
615
                        //glPushMatrix ();
 
616
                        //glTranslatef (0., 0., icon->fHeight * (1+myIcons.fAmplitude) -1);  // avant-plan
 
617
                        _cairo_dock_draw_appli_indicator_opengl (icon, pDock);
 
618
                        //glPopMatrix ();
 
619
                }
 
620
                if (bIsActive)
 
621
                {
 
622
                        //glPushMatrix ();
 
623
                        //glTranslatef (0., 0., icon->fHeight * (1+myIcons.fAmplitude) -1);  // avant-plan
 
624
                        _cairo_dock_draw_active_window_indicator_opengl (icon, pDock, pDock->container.fRatio);
 
625
                        //glPopMatrix ();
 
626
                }
 
627
                if (icon->pSubDock != NULL && icon->cClass != NULL && s_classIndicatorBuffer.iTexture != 0 && icon->Xid == 0)  // le dernier test est de la paranoia.
 
628
                {
 
629
                        //glPushMatrix ();
 
630
                        //glTranslatef (0., 0., icon->fHeight * (1+myIcons.fAmplitude) -1);  // avant-plan
 
631
                        _cairo_dock_draw_class_indicator_opengl (icon, pDock->container.bIsHorizontal, pDock->container.fRatio, pDock->container.bDirectionUp);
 
632
                        //glPopMatrix ();
 
633
                }
 
634
        }
 
635
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
636
}