~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-desklet-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
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
 
2
/*
 
3
** Login : <ctaf42@gmail.com>
 
4
** Started on  Sun Jan 27 18:35:38 2008 Cedric GESTES
 
5
** $Id$
 
6
**
 
7
** Author(s)
 
8
**  - Cedric GESTES <ctaf42@gmail.com>
 
9
**  - Fabrice REY
 
10
**
 
11
** Copyright (C) 2008 Cedric GESTES
 
12
** This program is free software; you can redistribute it and/or modify
 
13
** it under the terms of the GNU General Public License as published by
 
14
** the Free Software Foundation; either version 3 of the License, or
 
15
** (at your option) any later version.
 
16
**
 
17
** This program is distributed in the hope that it will be useful,
 
18
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
** GNU General Public License for more details.
 
21
**
 
22
** You should have received a copy of the GNU General Public License
 
23
** along with this program; if not, write to the Free Software
 
24
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
25
*/
 
26
 
 
27
 
 
28
#include <stdlib.h>
 
29
#include <string.h>
 
30
#include <math.h>
 
31
 
 
32
#include <gtk/gtkgl.h>
 
33
#include <GL/gl.h> 
 
34
#include <GL/glu.h> 
 
35
#include <GL/glx.h> 
 
36
#include <gdk/x11/gdkglx.h>
 
37
#include <gdk/gdkx.h>
 
38
 
 
39
#include "../config.h"
 
40
#include "cairo-dock-draw.h"
 
41
#include "cairo-dock-modules.h"
 
42
#include "cairo-dock-dialog-manager.h"
 
43
#include "cairo-dock-icons.h"
 
44
#include "cairo-dock-config.h"
 
45
#include "cairo-dock-X-manager.h"
 
46
#include "cairo-dock-notifications.h"
 
47
#include "cairo-dock-log.h"
 
48
#include "cairo-dock-container.h"
 
49
#include "cairo-dock-X-utilities.h"
 
50
#include "cairo-dock-surface-factory.h"
 
51
#include "cairo-dock-backends-manager.h"
 
52
#include "cairo-dock-draw-opengl.h"
 
53
#include "cairo-dock-load.h"
 
54
#include "cairo-dock-animations.h"
 
55
#include "cairo-dock-internal-desklets.h"
 
56
#include "cairo-dock-gui-manager.h"
 
57
#include "cairo-dock-launcher-manager.h"
 
58
#include "cairo-dock-desklet-factory.h"
 
59
#include "cairo-dock-desklet-manager.h"
 
60
 
 
61
extern gboolean g_bUseOpenGL;
 
62
extern CairoDock *g_pMainDock;
 
63
 
 
64
static CairoDockImageBuffer s_pRotateButtonBuffer;
 
65
static CairoDockImageBuffer s_pRetachButtonBuffer;
 
66
static CairoDockImageBuffer s_pDepthRotateButtonBuffer;
 
67
static CairoDockImageBuffer s_pNoInputButtonBuffer;
 
68
static GList *s_pDeskletList = NULL;
 
69
 
 
70
static gboolean _cairo_dock_update_desklet_notification (gpointer data, CairoDesklet *pDesklet, gboolean *bContinueAnimation);
 
71
static gboolean _cairo_dock_enter_leave_desklet_notification (gpointer data, CairoDesklet *pDesklet, gboolean *bStartAnimation);
 
72
static gboolean _cairo_dock_render_desklet_notification (gpointer pUserData, CairoDesklet *pDesklet, cairo_t *pCairoContext);
 
73
 
 
74
#define CD_NB_ITER_FOR_ENTER_ANIMATION 10
 
75
#define _no_input_button_alpha(pDesklet) (pDesklet->bNoInput ? .4+.6*pDesklet->fButtonsAlpha : pDesklet->fButtonsAlpha)
 
76
 
 
77
 
 
78
void cairo_dock_init_desklet_manager (void)
 
79
{
 
80
        memset (&s_pRotateButtonBuffer, 0, sizeof (CairoDockImageBuffer));
 
81
        memset (&s_pRetachButtonBuffer, 0, sizeof (CairoDockImageBuffer));
 
82
        memset (&s_pDepthRotateButtonBuffer, 0, sizeof (CairoDockImageBuffer));
 
83
        memset (&s_pNoInputButtonBuffer, 0, sizeof (CairoDockImageBuffer));
 
84
        
 
85
        cairo_dock_register_notification (CAIRO_DOCK_UPDATE_DESKLET,
 
86
                (CairoDockNotificationFunc) _cairo_dock_update_desklet_notification,
 
87
                CAIRO_DOCK_RUN_FIRST, NULL);
 
88
        cairo_dock_register_notification (CAIRO_DOCK_ENTER_DESKLET,
 
89
                (CairoDockNotificationFunc) _cairo_dock_enter_leave_desklet_notification,
 
90
                CAIRO_DOCK_RUN_FIRST, NULL);
 
91
        cairo_dock_register_notification (CAIRO_DOCK_LEAVE_DESKLET,
 
92
                (CairoDockNotificationFunc) _cairo_dock_enter_leave_desklet_notification,
 
93
                CAIRO_DOCK_RUN_FIRST, NULL);
 
94
        cairo_dock_register_notification (CAIRO_DOCK_RENDER_DESKLET,
 
95
                (CairoDockNotificationFunc) _cairo_dock_render_desklet_notification,
 
96
                CAIRO_DOCK_RUN_FIRST, NULL);
 
97
}
 
98
 
 
99
void cairo_dock_load_desklet_buttons (void)
 
100
{
 
101
        //g_print ("%s ()\n", __func__);
 
102
        if (myDesklets.cRotateButtonImage != NULL)
 
103
        {
 
104
                cairo_dock_load_image_buffer (&s_pRotateButtonBuffer,
 
105
                        myDesklets.cRotateButtonImage,
 
106
                        myDesklets.iDeskletButtonSize,
 
107
                        myDesklets.iDeskletButtonSize,
 
108
                        CAIRO_DOCK_FILL_SPACE);
 
109
        }
 
110
        if (s_pRotateButtonBuffer.pSurface == NULL)
 
111
        {
 
112
                cairo_dock_load_image_buffer (&s_pRotateButtonBuffer,
 
113
                        CAIRO_DOCK_SHARE_DATA_DIR"/rotate-desklet.svg",
 
114
                        myDesklets.iDeskletButtonSize,
 
115
                        myDesklets.iDeskletButtonSize,
 
116
                        CAIRO_DOCK_FILL_SPACE);
 
117
        }
 
118
        
 
119
        if (myDesklets.cRetachButtonImage != NULL)
 
120
        {
 
121
                cairo_dock_load_image_buffer (&s_pRetachButtonBuffer,
 
122
                        myDesklets.cRetachButtonImage,
 
123
                        myDesklets.iDeskletButtonSize,
 
124
                        myDesklets.iDeskletButtonSize,
 
125
                        CAIRO_DOCK_FILL_SPACE);
 
126
        }
 
127
        if (s_pRetachButtonBuffer.pSurface == NULL)
 
128
        {
 
129
                cairo_dock_load_image_buffer (&s_pRetachButtonBuffer,
 
130
                        CAIRO_DOCK_SHARE_DATA_DIR"/retach-desklet.svg",
 
131
                        myDesklets.iDeskletButtonSize,
 
132
                        myDesklets.iDeskletButtonSize,
 
133
                        CAIRO_DOCK_FILL_SPACE);
 
134
        }
 
135
 
 
136
        if (myDesklets.cDepthRotateButtonImage != NULL)
 
137
        {
 
138
                cairo_dock_load_image_buffer (&s_pDepthRotateButtonBuffer,
 
139
                        myDesklets.cDepthRotateButtonImage,
 
140
                        myDesklets.iDeskletButtonSize,
 
141
                        myDesklets.iDeskletButtonSize,
 
142
                        CAIRO_DOCK_FILL_SPACE);
 
143
        }
 
144
        if (s_pDepthRotateButtonBuffer.pSurface == NULL)
 
145
        {
 
146
                cairo_dock_load_image_buffer (&s_pDepthRotateButtonBuffer,
 
147
                        CAIRO_DOCK_SHARE_DATA_DIR"/depth-rotate-desklet.svg",
 
148
                        myDesklets.iDeskletButtonSize,
 
149
                        myDesklets.iDeskletButtonSize,
 
150
                        CAIRO_DOCK_FILL_SPACE);
 
151
        }
 
152
        
 
153
        if (myDesklets.cNoInputButtonImage != NULL)
 
154
        {
 
155
                cairo_dock_load_image_buffer (&s_pNoInputButtonBuffer,
 
156
                        myDesklets.cNoInputButtonImage,
 
157
                        myDesklets.iDeskletButtonSize,
 
158
                        myDesklets.iDeskletButtonSize,
 
159
                        CAIRO_DOCK_FILL_SPACE);
 
160
        }
 
161
        if (s_pNoInputButtonBuffer.pSurface == NULL)
 
162
        {
 
163
                cairo_dock_load_image_buffer (&s_pNoInputButtonBuffer,
 
164
                        CAIRO_DOCK_SHARE_DATA_DIR"/no-input-desklet.png",
 
165
                        myDesklets.iDeskletButtonSize,
 
166
                        myDesklets.iDeskletButtonSize,
 
167
                        CAIRO_DOCK_FILL_SPACE);
 
168
        }
 
169
}
 
170
 
 
171
void cairo_dock_unload_desklet_buttons (void)
 
172
{
 
173
        //g_print ("%s ()\n", __func__);
 
174
        cairo_dock_unload_image_buffer (&s_pRotateButtonBuffer);
 
175
        cairo_dock_unload_image_buffer (&s_pRetachButtonBuffer);
 
176
        cairo_dock_unload_image_buffer (&s_pDepthRotateButtonBuffer);
 
177
        cairo_dock_unload_image_buffer (&s_pNoInputButtonBuffer);
 
178
}
 
179
 
 
180
 
 
181
  ///////////////
 
182
 /// DRAWING ///
 
183
///////////////
 
184
 
 
185
static inline double _compute_zoom_for_rotation (CairoDesklet *pDesklet)
 
186
{
 
187
        double w = pDesklet->container.iWidth/2, h = pDesklet->container.iHeight/2;
 
188
        double alpha = atan2 (h, w);
 
189
        double theta = fabs (pDesklet->fRotation);
 
190
        if (theta > G_PI/2)
 
191
                theta -= G_PI/2;
 
192
        
 
193
        double d = sqrt (w * w + h * h);
 
194
        double xmax = d * MAX (fabs (cos (alpha + theta)), fabs (cos (alpha - theta)));
 
195
        double ymax = d * MAX (fabs (sin (alpha + theta)), fabs (sin (alpha - theta)));
 
196
        double fZoom = MIN (w / xmax, h / ymax);
 
197
        return fZoom;
 
198
}
 
199
 
 
200
static inline void _render_desklet_cairo (CairoDesklet *pDesklet, cairo_t *pCairoContext)
 
201
{
 
202
        cairo_save (pCairoContext);
 
203
        
 
204
        if (pDesklet->container.fRatio != 1)
 
205
        {
 
206
                //g_print (" desklet zoom : %.2f (%dx%d)\n", pDesklet->container.fRatio, pDesklet->container.iWidth, pDesklet->container.iHeight);
 
207
                cairo_translate (pCairoContext,
 
208
                        pDesklet->container.iWidth * (1 - pDesklet->container.fRatio)/2,
 
209
                        pDesklet->container.iHeight * (1 - pDesklet->container.fRatio)/2);
 
210
                cairo_scale (pCairoContext, pDesklet->container.fRatio, pDesklet->container.fRatio);
 
211
        }
 
212
        
 
213
        if (pDesklet->fRotation != 0)
 
214
        {
 
215
                double fZoom = _compute_zoom_for_rotation (pDesklet);
 
216
                
 
217
                cairo_translate (pCairoContext,
 
218
                        .5*pDesklet->container.iWidth,
 
219
                        .5*pDesklet->container.iHeight);
 
220
                
 
221
                cairo_rotate (pCairoContext, pDesklet->fRotation);
 
222
                
 
223
                cairo_scale (pCairoContext, fZoom, fZoom);
 
224
                
 
225
                cairo_translate (pCairoContext,
 
226
                        -.5*pDesklet->container.iWidth,
 
227
                        -.5*pDesklet->container.iHeight);
 
228
        }
 
229
        
 
230
        if (pDesklet->backGroundImageBuffer.pSurface != NULL)
 
231
        {
 
232
                cairo_set_source_surface (pCairoContext,
 
233
                        pDesklet->backGroundImageBuffer.pSurface,
 
234
                        0.,
 
235
                        0.);
 
236
                        cairo_paint (pCairoContext);
 
237
        }
 
238
        
 
239
        cairo_save (pCairoContext);
 
240
        if (pDesklet->iLeftSurfaceOffset != 0 || pDesklet->iTopSurfaceOffset != 0 || pDesklet->iRightSurfaceOffset != 0 || pDesklet->iBottomSurfaceOffset != 0)
 
241
        {
 
242
                cairo_translate (pCairoContext, pDesklet->iLeftSurfaceOffset, pDesklet->iTopSurfaceOffset);
 
243
                cairo_scale (pCairoContext,
 
244
                        1. - 1.*(pDesklet->iLeftSurfaceOffset + pDesklet->iRightSurfaceOffset) / pDesklet->container.iWidth,
 
245
                        1. - 1.*(pDesklet->iTopSurfaceOffset + pDesklet->iBottomSurfaceOffset) / pDesklet->container.iHeight);
 
246
        }
 
247
        
 
248
        if (pDesklet->pRenderer != NULL && pDesklet->pRenderer->render != NULL)  // un moteur de rendu specifique a ete fourni.
 
249
        {
 
250
                pDesklet->pRenderer->render (pCairoContext, pDesklet);
 
251
        }
 
252
        cairo_restore (pCairoContext);
 
253
        
 
254
        if (pDesklet->foreGroundImageBuffer.pSurface != NULL)
 
255
        {
 
256
                cairo_set_source_surface (pCairoContext,
 
257
                        pDesklet->foreGroundImageBuffer.pSurface,
 
258
                        0.,
 
259
                        0.);
 
260
                        cairo_paint (pCairoContext);
 
261
        }
 
262
        
 
263
        if (! pDesklet->rotating)  // si on est en train de tourner, les boutons suivent le mouvement, sinon ils sont dans les coins.
 
264
        {
 
265
                cairo_restore (pCairoContext);
 
266
                cairo_save (pCairoContext);
 
267
        }
 
268
        if ((pDesklet->container.bInside || pDesklet->rotating || pDesklet->fButtonsAlpha != 0) && cairo_dock_desklet_is_free (pDesklet))
 
269
        {
 
270
                if (s_pRotateButtonBuffer.pSurface != NULL)
 
271
                {
 
272
                        cairo_set_source_surface (pCairoContext, s_pRotateButtonBuffer.pSurface, 0., 0.);
 
273
                        cairo_paint_with_alpha (pCairoContext, pDesklet->fButtonsAlpha);
 
274
                }
 
275
                if (s_pRetachButtonBuffer.pSurface != NULL && g_pMainDock)
 
276
                {
 
277
                        cairo_set_source_surface (pCairoContext, s_pRetachButtonBuffer.pSurface, pDesklet->container.iWidth - myDesklets.iDeskletButtonSize, 0.);
 
278
                        cairo_paint_with_alpha (pCairoContext, pDesklet->fButtonsAlpha);
 
279
                }
 
280
        }
 
281
        if ((pDesklet->container.bInside || pDesklet->bNoInput || pDesklet->fButtonsAlpha) && s_pNoInputButtonBuffer.pSurface != NULL && pDesklet->bAllowNoClickable)
 
282
        {
 
283
                cairo_set_source_surface (pCairoContext, s_pNoInputButtonBuffer.pSurface, pDesklet->container.iWidth - myDesklets.iDeskletButtonSize, pDesklet->container.iHeight - myDesklets.iDeskletButtonSize);
 
284
                cairo_paint_with_alpha (pCairoContext, _no_input_button_alpha (pDesklet));
 
285
        }
 
286
        cairo_restore (pCairoContext);
 
287
}
 
288
 
 
289
static inline void _cairo_dock_set_desklet_matrix (CairoDesklet *pDesklet)
 
290
{
 
291
        glTranslatef (0., 0., -pDesklet->container.iHeight * sqrt(3)/2 - 
 
292
                .45 * MAX (pDesklet->container.iWidth * fabs (sin (pDesklet->fDepthRotationY)),
 
293
                        pDesklet->container.iHeight * fabs (sin (pDesklet->fDepthRotationX)))
 
294
                );  // avec 60 deg de perspective
 
295
        
 
296
        if (pDesklet->container.fRatio != 1)
 
297
        {
 
298
                glScalef (pDesklet->container.fRatio, pDesklet->container.fRatio, 1.);
 
299
        }
 
300
        
 
301
        if (pDesklet->fRotation != 0)
 
302
        {
 
303
                double fZoom = _compute_zoom_for_rotation (pDesklet);
 
304
                glScalef (fZoom, fZoom, 1.);
 
305
                glRotatef (- pDesklet->fRotation / G_PI * 180., 0., 0., 1.);
 
306
        }
 
307
        
 
308
        if (pDesklet->fDepthRotationY != 0)
 
309
        {
 
310
                glRotatef (- pDesklet->fDepthRotationY / G_PI * 180., 0., 1., 0.);
 
311
        }
 
312
        
 
313
        if (pDesklet->fDepthRotationX != 0)
 
314
        {
 
315
                glRotatef (- pDesklet->fDepthRotationX / G_PI * 180., 1., 0., 0.);
 
316
        }
 
317
}
 
318
 
 
319
static inline void _render_desklet_opengl (CairoDesklet *pDesklet)
 
320
{
 
321
        glPushMatrix ();
 
322
        ///glTranslatef (0*pDesklet->container.iWidth/2, 0*pDesklet->container.iHeight/2, 0.);  // avec une perspective ortho.
 
323
        ///glTranslatef (0*pDesklet->container.iWidth/2, 0*pDesklet->container.iHeight/2, -pDesklet->container.iWidth*(1.87 +.35*fabs (sin(pDesklet->fDepthRotationY))));  // avec 30 deg de perspective
 
324
        _cairo_dock_set_desklet_matrix (pDesklet);
 
325
        
 
326
        _cairo_dock_enable_texture ();
 
327
        _cairo_dock_set_blend_pbuffer ();
 
328
        
 
329
        if (pDesklet->backGroundImageBuffer.iTexture != 0/** && pDesklet->fBackGroundAlpha != 0*/)
 
330
        {
 
331
                _cairo_dock_apply_texture_at_size_with_alpha (pDesklet->backGroundImageBuffer.iTexture, pDesklet->container.iWidth, pDesklet->container.iHeight, 1./**pDesklet->fBackGroundAlpha*/);
 
332
        }
 
333
        
 
334
        glPushMatrix ();
 
335
        if (pDesklet->iLeftSurfaceOffset != 0 || pDesklet->iTopSurfaceOffset != 0 || pDesklet->iRightSurfaceOffset != 0 || pDesklet->iBottomSurfaceOffset != 0)
 
336
        {
 
337
                glTranslatef ((pDesklet->iLeftSurfaceOffset - pDesklet->iRightSurfaceOffset)/2, (pDesklet->iBottomSurfaceOffset - pDesklet->iTopSurfaceOffset)/2, 0.);
 
338
                glScalef (1. - 1.*(pDesklet->iLeftSurfaceOffset + pDesklet->iRightSurfaceOffset) / pDesklet->container.iWidth,
 
339
                        1. - 1.*(pDesklet->iTopSurfaceOffset + pDesklet->iBottomSurfaceOffset) / pDesklet->container.iHeight,
 
340
                        1.);
 
341
        }
 
342
        
 
343
        if (pDesklet->pRenderer != NULL && pDesklet->pRenderer->render_opengl != NULL)  // un moteur de rendu specifique a ete fourni.
 
344
        {
 
345
                _cairo_dock_set_alpha (1.);
 
346
                pDesklet->pRenderer->render_opengl (pDesklet);
 
347
        }
 
348
        glPopMatrix ();
 
349
        
 
350
        _cairo_dock_enable_texture ();
 
351
        _cairo_dock_set_blend_pbuffer ();
 
352
        if (pDesklet->foreGroundImageBuffer.iTexture != 0/** && pDesklet->fForeGroundAlpha != 0*/)
 
353
        {
 
354
                _cairo_dock_apply_texture_at_size_with_alpha (pDesklet->foreGroundImageBuffer.iTexture, pDesklet->container.iWidth, pDesklet->container.iHeight, 1./**pDesklet->fForeGroundAlpha*/);
 
355
        }
 
356
        
 
357
        //if (pDesklet->container.bInside && cairo_dock_desklet_is_free (pDesklet))
 
358
        {
 
359
                if (! pDesklet->rotating && ! pDesklet->rotatingY && ! pDesklet->rotatingX)
 
360
                {
 
361
                        glPopMatrix ();
 
362
                        glPushMatrix ();
 
363
                        glTranslatef (0., 0., -pDesklet->container.iHeight*(sqrt(3)/2));
 
364
                }
 
365
        }
 
366
        
 
367
        if ((pDesklet->container.bInside || pDesklet->fButtonsAlpha != 0 || pDesklet->rotating || pDesklet->rotatingY || pDesklet->rotatingX) && cairo_dock_desklet_is_free (pDesklet))
 
368
        {
 
369
                _cairo_dock_set_blend_alpha ();
 
370
                _cairo_dock_set_alpha (sqrt(pDesklet->fButtonsAlpha));
 
371
                if (s_pRotateButtonBuffer.iTexture != 0)
 
372
                {
 
373
                        glPushMatrix ();
 
374
                        glTranslatef (-pDesklet->container.iWidth/2 + myDesklets.iDeskletButtonSize/2,
 
375
                                pDesklet->container.iHeight/2 - myDesklets.iDeskletButtonSize/2,
 
376
                                0.);
 
377
                        _cairo_dock_apply_texture_at_size (s_pRotateButtonBuffer.iTexture, myDesklets.iDeskletButtonSize, myDesklets.iDeskletButtonSize);
 
378
                        glPopMatrix ();
 
379
                }
 
380
                if (s_pRetachButtonBuffer.iTexture != 0 && g_pMainDock)
 
381
                {
 
382
                        glPushMatrix ();
 
383
                        glTranslatef (pDesklet->container.iWidth/2 - myDesklets.iDeskletButtonSize/2,
 
384
                                pDesklet->container.iHeight/2 - myDesklets.iDeskletButtonSize/2,
 
385
                                0.);
 
386
                        _cairo_dock_apply_texture_at_size (s_pRetachButtonBuffer.iTexture, myDesklets.iDeskletButtonSize, myDesklets.iDeskletButtonSize);
 
387
                        glPopMatrix ();
 
388
                }
 
389
                if (s_pDepthRotateButtonBuffer.iTexture != 0)
 
390
                {
 
391
                        glPushMatrix ();
 
392
                        glTranslatef (0.,
 
393
                                pDesklet->container.iHeight/2 - myDesklets.iDeskletButtonSize/2,
 
394
                                0.);
 
395
                        _cairo_dock_apply_texture_at_size (s_pDepthRotateButtonBuffer.iTexture, myDesklets.iDeskletButtonSize, myDesklets.iDeskletButtonSize);
 
396
                        glPopMatrix ();
 
397
                        
 
398
                        glPushMatrix ();
 
399
                        glRotatef (90., 0., 0., 1.);
 
400
                        glTranslatef (0.,
 
401
                                pDesklet->container.iWidth/2 - myDesklets.iDeskletButtonSize/2,
 
402
                                0.);
 
403
                        _cairo_dock_apply_texture_at_size (s_pDepthRotateButtonBuffer.iTexture, myDesklets.iDeskletButtonSize, myDesklets.iDeskletButtonSize);
 
404
                        glPopMatrix ();
 
405
                }
 
406
        }
 
407
        if ((pDesklet->container.bInside || pDesklet->fButtonsAlpha != 0 || pDesklet->bNoInput) && s_pNoInputButtonBuffer.iTexture != 0 && pDesklet->bAllowNoClickable)
 
408
        {
 
409
                _cairo_dock_set_blend_alpha ();
 
410
                _cairo_dock_set_alpha (_no_input_button_alpha(pDesklet));
 
411
                glPushMatrix ();
 
412
                glTranslatef (pDesklet->container.iWidth/2 - myDesklets.iDeskletButtonSize/2,
 
413
                        - pDesklet->container.iHeight/2 + myDesklets.iDeskletButtonSize/2,
 
414
                        0.);
 
415
                _cairo_dock_apply_texture_at_size (s_pNoInputButtonBuffer.iTexture, myDesklets.iDeskletButtonSize, myDesklets.iDeskletButtonSize);
 
416
                glPopMatrix ();
 
417
        }
 
418
        
 
419
        _cairo_dock_disable_texture ();
 
420
        glPopMatrix ();
 
421
}
 
422
 
 
423
static gboolean _cairo_dock_render_desklet_notification (gpointer pUserData, CairoDesklet *pDesklet, cairo_t *pCairoContext)
 
424
{
 
425
        if (pCairoContext != NULL)
 
426
                _render_desklet_cairo (pDesklet, pCairoContext);
 
427
        else
 
428
                _render_desklet_opengl (pDesklet);
 
429
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
430
}
 
431
 
 
432
static gboolean _cairo_dock_enter_leave_desklet_notification (gpointer data, CairoDesklet *pDesklet, gboolean *bStartAnimation)
 
433
{
 
434
        pDesklet->bButtonsApparition = TRUE;
 
435
        *bStartAnimation = TRUE;
 
436
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
437
}
 
438
 
 
439
static gboolean _cairo_dock_update_desklet_notification (gpointer data, CairoDesklet *pDesklet, gboolean *bContinueAnimation)
 
440
{
 
441
        if (!pDesklet->bButtonsApparition && !pDesklet->bGrowingUp)
 
442
                return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
443
        
 
444
        if (pDesklet->bButtonsApparition)
 
445
        {
 
446
                pDesklet->fButtonsAlpha += (pDesklet->container.bInside ? .1 : -.1);
 
447
                //g_print ("fButtonsAlpha <- %.2f\n", pDesklet->fButtonsAlpha);
 
448
                
 
449
                if (pDesklet->fButtonsAlpha <= 0 || pDesklet->fButtonsAlpha >= 1)
 
450
                {
 
451
                        pDesklet->bButtonsApparition = FALSE;
 
452
                        if (pDesklet->fButtonsAlpha < 0)
 
453
                                pDesklet->fButtonsAlpha = 0.;
 
454
                        else if (pDesklet->fButtonsAlpha > 1)
 
455
                                pDesklet->fButtonsAlpha = 1.;
 
456
                }
 
457
                else
 
458
                {
 
459
                        *bContinueAnimation = TRUE;
 
460
                }
 
461
        }
 
462
        
 
463
        if (pDesklet->bGrowingUp)
 
464
        {
 
465
                pDesklet->container.fRatio += .04;
 
466
                //g_print ("pDesklet->container.fRatio:%.2f\n", pDesklet->container.fRatio);
 
467
                
 
468
                if (pDesklet->container.fRatio >= 1.1)  // la derniere est a x1.1
 
469
                {
 
470
                        pDesklet->container.fRatio = 1;
 
471
                        pDesklet->bGrowingUp = FALSE;
 
472
                }
 
473
                else
 
474
                {
 
475
                        *bContinueAnimation = TRUE;
 
476
                }
 
477
        }
 
478
        
 
479
        gtk_widget_queue_draw (pDesklet->container.pWidget);
 
480
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
481
}
 
482
 
 
483
  ///////////////
 
484
 /// MANAGER ///
 
485
///////////////
 
486
 
 
487
CairoDesklet *cairo_dock_create_desklet (Icon *pIcon, CairoDeskletAttribute *pAttributes)
 
488
{
 
489
        CairoDesklet *pDesklet = cairo_dock_new_desklet ();
 
490
        pDesklet->pIcon = pIcon;
 
491
        
 
492
        if (pAttributes != NULL)
 
493
                cairo_dock_configure_desklet (pDesklet, pAttributes);
 
494
        
 
495
        if (s_pRotateButtonBuffer.pSurface == NULL)
 
496
        {
 
497
                cairo_dock_load_desklet_buttons ();
 
498
        }
 
499
        
 
500
        s_pDeskletList = g_list_prepend (s_pDeskletList, pDesklet);
 
501
        return pDesklet;
 
502
}
 
503
 
 
504
void cairo_dock_destroy_desklet (CairoDesklet *pDesklet)
 
505
{
 
506
        cairo_dock_free_desklet (pDesklet);
 
507
        s_pDeskletList = g_list_remove (s_pDeskletList, pDesklet);
 
508
}
 
509
 
 
510
 
 
511
CairoDesklet *cairo_dock_foreach_desklet (CairoDockForeachDeskletFunc pCallback, gpointer user_data)
 
512
{
 
513
        gpointer data[3] = {pCallback, user_data, NULL};
 
514
        CairoDesklet *pDesklet;
 
515
        GList *dl;
 
516
        for (dl = s_pDeskletList; dl != NULL; dl = dl->next)
 
517
        {
 
518
                pDesklet = dl->data;
 
519
                if (pCallback (pDesklet, user_data))
 
520
                        return pDesklet;
 
521
        }
 
522
        
 
523
        return NULL;
 
524
}
 
525
 
 
526
static gboolean _cairo_dock_reload_one_desklet_decorations (CairoDesklet *pDesklet, gpointer data)
 
527
{
 
528
        gboolean bDefaultThemeOnly = GPOINTER_TO_INT (data);
 
529
        
 
530
        if (bDefaultThemeOnly)
 
531
        {
 
532
                if (pDesklet->cDecorationTheme == NULL || strcmp (pDesklet->cDecorationTheme, "default") == 0)
 
533
                {
 
534
                        cd_debug ("on recharge les decorations de ce desklet");
 
535
                        cairo_dock_load_desklet_decorations (pDesklet);
 
536
                }
 
537
        }
 
538
        else  // tous ceux qui ne sont pas encore charges et qui ont leur taille definitive.
 
539
        {
 
540
                if (pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0 && pDesklet->iSidWriteSize == 0 && pDesklet->backGroundImageBuffer.pSurface == NULL && pDesklet->foreGroundImageBuffer.pSurface == NULL)
 
541
                {
 
542
                        cd_debug ("ce desklet a saute le chargement de ses deco => on l'aide.");
 
543
                        cairo_dock_load_desklet_decorations (pDesklet);
 
544
                }
 
545
        }
 
546
        return FALSE;
 
547
}
 
548
void cairo_dock_reload_desklets_decorations (gboolean bDefaultThemeOnly)  // tous ou bien seulement ceux avec "default".
 
549
{
 
550
        cd_message ("%s (%d)", __func__, bDefaultThemeOnly);
 
551
        CairoDesklet *pDesklet;
 
552
        GList *dl;
 
553
        for (dl = s_pDeskletList; dl != NULL; dl = dl->next)
 
554
        {
 
555
                pDesklet = dl->data;
 
556
                _cairo_dock_reload_one_desklet_decorations (pDesklet, GINT_TO_POINTER (bDefaultThemeOnly));
 
557
        }
 
558
}
 
559
 
 
560
static void _cairo_dock_set_one_desklet_visible (CairoDesklet *pDesklet, gpointer data)
 
561
{
 
562
        gboolean bOnWidgetLayerToo = GPOINTER_TO_INT (data);
 
563
        Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
 
564
        gboolean bIsOnWidgetLayer = cairo_dock_window_is_utility (Xid);
 
565
        if (bOnWidgetLayerToo || ! bIsOnWidgetLayer)
 
566
        {
 
567
                cd_debug ("%s (%d)", __func__, Xid);
 
568
                if (bIsOnWidgetLayer)  // on le passe sur la couche visible.
 
569
                        cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_NORMAL");
 
570
                
 
571
                gtk_window_set_keep_below (GTK_WINDOW (pDesklet->container.pWidget), FALSE);
 
572
                
 
573
                cairo_dock_show_desklet (pDesklet);
 
574
        }
 
575
}
 
576
void cairo_dock_set_all_desklets_visible (gboolean bOnWidgetLayerToo)
 
577
{
 
578
        cd_debug ("%s (%d)", __func__, bOnWidgetLayerToo);
 
579
        CairoDesklet *pDesklet;
 
580
        GList *dl;
 
581
        for (dl = s_pDeskletList; dl != NULL; dl = dl->next)
 
582
        {
 
583
                pDesklet = dl->data;
 
584
                _cairo_dock_set_one_desklet_visible (pDesklet, GINT_TO_POINTER (bOnWidgetLayerToo));
 
585
        }
 
586
}
 
587
 
 
588
static void _cairo_dock_set_one_desklet_visibility_to_default (CairoDesklet *pDesklet, CairoDockMinimalAppletConfig *pMinimalConfig)
 
589
{
 
590
        if (pDesklet->pIcon != NULL)
 
591
        {
 
592
                CairoDockModuleInstance *pInstance = pDesklet->pIcon->pModuleInstance;
 
593
                GKeyFile *pKeyFile = cairo_dock_pre_read_module_instance_config (pInstance, pMinimalConfig);
 
594
                g_key_file_free (pKeyFile);
 
595
                
 
596
                cairo_dock_set_desklet_accessibility (pDesklet, pMinimalConfig->deskletAttribute.iVisibility, FALSE);
 
597
        }
 
598
        pDesklet->bAllowMinimize = FALSE;  /// utile ?...
 
599
}
 
600
void cairo_dock_set_desklets_visibility_to_default (void)
 
601
{
 
602
        CairoDockMinimalAppletConfig minimalConfig;
 
603
        CairoDesklet *pDesklet;
 
604
        GList *dl;
 
605
        for (dl = s_pDeskletList; dl != NULL; dl = dl->next)
 
606
        {
 
607
                pDesklet = dl->data;
 
608
                _cairo_dock_set_one_desklet_visibility_to_default (pDesklet, &minimalConfig);
 
609
        }
 
610
}
 
611
 
 
612
CairoDesklet *cairo_dock_get_desklet_by_Xid (Window Xid)
 
613
{
 
614
        CairoDesklet *pDesklet;
 
615
        GList *dl;
 
616
        for (dl = s_pDeskletList; dl != NULL; dl = dl->next)
 
617
        {
 
618
                pDesklet = dl->data;
 
619
                if (GDK_WINDOW_XID (pDesklet->container.pWidget->window) == Xid)
 
620
                        return pDesklet;
 
621
        }
 
622
        return NULL;
 
623
}
 
624
 
 
625
 
 
626
static Icon *_cairo_dock_pick_icon_on_opengl_desklet (CairoDesklet *pDesklet)
 
627
{
 
628
        GLuint selectBuf[4];
 
629
        GLint hits=0;
 
630
        GLint viewport[4];
 
631
        
 
632
        GdkGLContext* pGlContext = gtk_widget_get_gl_context (pDesklet->container.pWidget);
 
633
        GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pDesklet->container.pWidget);
 
634
        if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
 
635
                return NULL;
 
636
        
 
637
        glGetIntegerv (GL_VIEWPORT, viewport);
 
638
        glSelectBuffer (4, selectBuf);
 
639
        
 
640
        glRenderMode(GL_SELECT);
 
641
        glInitNames();
 
642
        glPushName(0);
 
643
        
 
644
        glMatrixMode (GL_PROJECTION);
 
645
        glPushMatrix ();
 
646
        glLoadIdentity ();
 
647
        gluPickMatrix ((GLdouble) pDesklet->container.iMouseX, (GLdouble) (viewport[3] - pDesklet->container.iMouseY), 2.0, 2.0, viewport);
 
648
        gluPerspective (60.0, 1.0*(GLfloat)pDesklet->container.iWidth/(GLfloat)pDesklet->container.iHeight, 1., 4*pDesklet->container.iHeight);
 
649
        
 
650
        glMatrixMode (GL_MODELVIEW);
 
651
        glPushMatrix ();
 
652
        glLoadIdentity ();
 
653
        
 
654
        _cairo_dock_set_desklet_matrix (pDesklet);
 
655
        
 
656
        if (pDesklet->iLeftSurfaceOffset != 0 || pDesklet->iTopSurfaceOffset != 0 || pDesklet->iRightSurfaceOffset != 0 || pDesklet->iBottomSurfaceOffset != 0)
 
657
        {
 
658
                glTranslatef ((pDesklet->iLeftSurfaceOffset - pDesklet->iRightSurfaceOffset)/2, (pDesklet->iBottomSurfaceOffset - pDesklet->iTopSurfaceOffset)/2, 0.);
 
659
                glScalef (1. - 1.*(pDesklet->iLeftSurfaceOffset + pDesklet->iRightSurfaceOffset) / pDesklet->container.iWidth,
 
660
                        1. - 1.*(pDesklet->iTopSurfaceOffset + pDesklet->iBottomSurfaceOffset) / pDesklet->container.iHeight,
 
661
                        1.);
 
662
        }
 
663
        
 
664
        glPolygonMode (GL_FRONT, GL_FILL);
 
665
        glColor4f (1., 1., 1., 1.);
 
666
        
 
667
        pDesklet->iPickedObject = 0;
 
668
        if (pDesklet->render_bounding_box != NULL)  // surclasse la fonction du moteur de rendu.
 
669
        {
 
670
                pDesklet->render_bounding_box (pDesklet);
 
671
        }
 
672
        else if (pDesklet->pRenderer && pDesklet->pRenderer->render_bounding_box != NULL)
 
673
        {
 
674
                pDesklet->pRenderer->render_bounding_box (pDesklet);
 
675
        }
 
676
        else  // on le fait nous-memes a partir des coordonnees des icones.
 
677
        {
 
678
                glTranslatef (-pDesklet->container.iWidth/2, -pDesklet->container.iHeight/2, 0.);
 
679
                
 
680
                double x, y, w, h;
 
681
                Icon *pIcon;
 
682
                
 
683
                pIcon = pDesklet->pIcon;
 
684
                if (pIcon != NULL && pIcon->iIconTexture != 0)
 
685
                {
 
686
                        w = pIcon->fWidth/2;
 
687
                        h = pIcon->fHeight/2;
 
688
                        x = pIcon->fDrawX + w;
 
689
                        y = pDesklet->container.iHeight - pIcon->fDrawY - h;
 
690
                        
 
691
                        glLoadName(pIcon->iIconTexture);
 
692
                        
 
693
                        glBegin(GL_QUADS);
 
694
                        glVertex3f(x-w, y+h, 0.);
 
695
                        glVertex3f(x+w, y+h, 0.);
 
696
                        glVertex3f(x+w, y-h, 0.);
 
697
                        glVertex3f(x-w, y-h, 0.);
 
698
                        glEnd();
 
699
                }
 
700
                
 
701
                GList *ic;
 
702
                for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
 
703
                {
 
704
                        pIcon = ic->data;
 
705
                        if (pIcon->iIconTexture == 0)
 
706
                                continue;
 
707
                        
 
708
                        w = pIcon->fWidth/2;
 
709
                        h = pIcon->fHeight/2;
 
710
                        x = pIcon->fDrawX + w;
 
711
                        y = pDesklet->container.iHeight - pIcon->fDrawY - h;
 
712
                        
 
713
                        glLoadName(pIcon->iIconTexture);
 
714
                        
 
715
                        glBegin(GL_QUADS);
 
716
                        glVertex3f(x-w, y+h, 0.);
 
717
                        glVertex3f(x+w, y+h, 0.);
 
718
                        glVertex3f(x+w, y-h, 0.);
 
719
                        glVertex3f(x-w, y-h, 0.);
 
720
                        glEnd();
 
721
                }
 
722
        }
 
723
        
 
724
        glPopName();
 
725
        
 
726
        hits = glRenderMode (GL_RENDER);
 
727
 
 
728
        glMatrixMode (GL_PROJECTION);
 
729
        glPopMatrix ();
 
730
        glMatrixMode(GL_MODELVIEW);
 
731
        glPopMatrix ();
 
732
        
 
733
        Icon *pFoundIcon = NULL;
 
734
        if (hits != 0)
 
735
        {
 
736
                GLuint id = selectBuf[3];
 
737
                Icon *pIcon;
 
738
                
 
739
                if (pDesklet->render_bounding_box != NULL)
 
740
                {
 
741
                        pDesklet->iPickedObject = id;
 
742
                        //g_print ("iPickedObject <- %d\n", id);
 
743
                        pFoundIcon = pDesklet->pIcon;  // il faut mettre qqch, sinon la notification est filtree par la macro CD_APPLET_ON_CLICK_BEGIN.
 
744
                }
 
745
                else
 
746
                {
 
747
                        pIcon = pDesklet->pIcon;
 
748
                        if (pIcon != NULL && pIcon->iIconTexture != 0)
 
749
                        {
 
750
                                if (pIcon->iIconTexture == id)
 
751
                                {
 
752
                                        pFoundIcon = pIcon;
 
753
                                }
 
754
                        }
 
755
                        
 
756
                        if (pFoundIcon == NULL)
 
757
                        {
 
758
                                GList *ic;
 
759
                                for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
 
760
                                {
 
761
                                        pIcon = ic->data;
 
762
                                        if (pIcon->iIconTexture == id)
 
763
                                        {
 
764
                                                pFoundIcon = pIcon;
 
765
                                                break ;
 
766
                                        }
 
767
                                }
 
768
                        }
 
769
                }
 
770
        }
 
771
        
 
772
        gdk_gl_drawable_gl_end (pGlDrawable);
 
773
        return pFoundIcon;
 
774
}
 
775
Icon *cairo_dock_find_clicked_icon_in_desklet (CairoDesklet *pDesklet)
 
776
{
 
777
        if (g_bUseOpenGL && pDesklet->pRenderer && pDesklet->pRenderer->render_opengl)
 
778
        {
 
779
                return _cairo_dock_pick_icon_on_opengl_desklet (pDesklet);
 
780
        }
 
781
        
 
782
        int iMouseX = pDesklet->container.iMouseX, iMouseY = pDesklet->container.iMouseY;
 
783
        if (pDesklet->fRotation != 0)
 
784
        {
 
785
                //g_print (" clic en (%d;%d) rotations : %.2frad\n", iMouseX, iMouseY, pDesklet->fRotation);
 
786
                double x, y;  // par rapport au centre du desklet.
 
787
                x = iMouseX - pDesklet->container.iWidth/2;
 
788
                y = pDesklet->container.iHeight/2 - iMouseY;
 
789
                
 
790
                double r, t;  // coordonnees polaires.
 
791
                r = sqrt (x*x + y*y);
 
792
                t = atan2 (y, x);
 
793
                
 
794
                double z = _compute_zoom_for_rotation (pDesklet);
 
795
                r /= z;
 
796
                
 
797
                x = r * cos (t + pDesklet->fRotation);  // la rotation de cairo est dans le sene horaire.
 
798
                y = r * sin (t + pDesklet->fRotation);
 
799
                
 
800
                iMouseX = x + pDesklet->container.iWidth/2;
 
801
                iMouseY = pDesklet->container.iHeight/2 - y;
 
802
                //g_print (" => (%d;%d)\n", iMouseX, iMouseY);
 
803
        }
 
804
        pDesklet->iMouseX2d = iMouseX;
 
805
        pDesklet->iMouseY2d = iMouseY;
 
806
        
 
807
        Icon *icon = pDesklet->pIcon;
 
808
        g_return_val_if_fail (icon != NULL, NULL);  // peut arriver au tout debut, car on associe l'icone au desklet _apres_ l'avoir cree, et on fait tourner la gtk_main entre-temps (pour le redessiner invisible).
 
809
        if (icon->fDrawX < iMouseX && icon->fDrawX + icon->fWidth * icon->fScale > iMouseX && icon->fDrawY < iMouseY && icon->fDrawY + icon->fHeight * icon->fScale > iMouseY)
 
810
        {
 
811
                return icon;
 
812
        }
 
813
        
 
814
        if (pDesklet->icons != NULL)
 
815
        {
 
816
                GList* ic;
 
817
                for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
 
818
                {
 
819
                        icon = ic->data;
 
820
                        if (icon->fDrawX < iMouseX && icon->fDrawX + icon->fWidth * icon->fScale > iMouseX && icon->fDrawY < iMouseY && icon->fDrawY + icon->fHeight * icon->fScale > iMouseY)
 
821
                        {
 
822
                                return icon;
 
823
                        }
 
824
                }
 
825
        }
 
826
        return NULL;
 
827
}