~ubuntu-branches/ubuntu/maverick/cairo-dock/maverick

« back to all changes in this revision

Viewing changes to src/cairo-dock-desklet.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe)
  • Date: 2010-08-09 23:26:12 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20100809232612-yp4c6ig3jt1bzpdv
Tags: 2.2.0~0beta4-0ubuntu1
* New Upstream Version (LP: #614624)
* Fixed a few bugs on LP:
 - LP: #518453: Dock appears under all windows
                 (Compiz - fullscreen window)
 - LP: #521369: Separator are not removed when closing
                 grouped windows
 - LP: #521762: Some sentences are not correct
 - LP: #526466: Icons of apps with same class shouldn't
                 be stacked by default
 - LP: #535083: Dialogues looks ugly when a lot of them
                 appears at the same time
 - More details on the 'ChangeLog' file
* debian/rules:
 - Autotools has been replaced by CMake
 - Man pages are now included in the source code
* debian/copyright:
 - Updated with the new pathes and new files
* debian/control:
 - Autotools has been replaced by CMake
 - Added libcurl4-gnutls-dev as Build-deps
 - Bump Standard-Version to 3.9.1
* debian/cairo-dock-core.install:
 - Man pages are now included in the source code
 - All sonames are now installed into lib32 or lib64
* debian/cairo-dock-dev.install:
 - pkgconfig is now installed into lib32 or lib64

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
 
 
38
 
#include <gdk/gdkx.h>
39
 
#include "cairo-dock-draw.h"
40
 
#include "cairo-dock-modules.h"
41
 
#include "cairo-dock-dialogs.h"
42
 
#include "cairo-dock-icons.h"
43
 
#include "cairo-dock-config.h"
44
 
#include "cairo-dock-applications-manager.h"
45
 
#include "cairo-dock-notifications.h"
46
 
#include "cairo-dock-log.h"
47
 
#include "cairo-dock-menu.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-renderer-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-desklet.h"
58
 
 
59
 
extern int g_iXScreenWidth[2], g_iXScreenHeight[2];
60
 
extern gboolean g_bUseOpenGL;
61
 
extern int g_iNbDesktops;
62
 
extern int g_iNbViewportX,g_iNbViewportY ;
63
 
 
64
 
static CairoDockImageBuffer s_pRotateButtonBuffer = {0};
65
 
static CairoDockImageBuffer s_pRetachButtonBuffer = {0};
66
 
static CairoDockImageBuffer s_pDepthRotateButtonBuffer = {0};
67
 
static CairoDockImageBuffer s_pNoInputButtonBuffer = {0};
68
 
 
69
 
#define CD_NB_ITER_FOR_GRADUATION 10
70
 
#define _cairo_dock_desklet_is_free(pDesklet) (! (pDesklet->bPositionLocked || pDesklet->bFixedAttitude))
71
 
 
72
 
 
73
 
void cairo_dock_init_desklet_manager (void)
74
 
{
75
 
        memset (&s_pRotateButtonBuffer, 0, sizeof (CairoDockImageBuffer));
76
 
        memset (&s_pRetachButtonBuffer, 0, sizeof (CairoDockImageBuffer));
77
 
        memset (&s_pDepthRotateButtonBuffer, 0, sizeof (CairoDockImageBuffer));
78
 
        memset (&s_pNoInputButtonBuffer, 0, sizeof (CairoDockImageBuffer));
79
 
}
80
 
 
81
 
void cairo_dock_load_desklet_buttons (void)
82
 
{
83
 
        //g_print ("%s ()\n", __func__);
84
 
        if (myDesklets.cRotateButtonImage != NULL)
85
 
        {
86
 
                cairo_dock_load_image_buffer (&s_pRotateButtonBuffer,
87
 
                        myDesklets.cRotateButtonImage,
88
 
                        myDesklets.iDeskletButtonSize,
89
 
                        myDesklets.iDeskletButtonSize,
90
 
                        CAIRO_DOCK_FILL_SPACE);
91
 
        }
92
 
        if (s_pRotateButtonBuffer.pSurface == NULL)
93
 
        {
94
 
                cairo_dock_load_image_buffer (&s_pRotateButtonBuffer,
95
 
                        CAIRO_DOCK_SHARE_DATA_DIR"/rotate-desklet.svg",
96
 
                        myDesklets.iDeskletButtonSize,
97
 
                        myDesklets.iDeskletButtonSize,
98
 
                        CAIRO_DOCK_FILL_SPACE);
99
 
        }
100
 
        
101
 
        if (myDesklets.cRetachButtonImage != NULL)
102
 
        {
103
 
                cairo_dock_load_image_buffer (&s_pRetachButtonBuffer,
104
 
                        myDesklets.cRetachButtonImage,
105
 
                        myDesklets.iDeskletButtonSize,
106
 
                        myDesklets.iDeskletButtonSize,
107
 
                        CAIRO_DOCK_FILL_SPACE);
108
 
        }
109
 
        if (s_pRetachButtonBuffer.pSurface == NULL)
110
 
        {
111
 
                cairo_dock_load_image_buffer (&s_pRetachButtonBuffer,
112
 
                        CAIRO_DOCK_SHARE_DATA_DIR"/retach-desklet.svg",
113
 
                        myDesklets.iDeskletButtonSize,
114
 
                        myDesklets.iDeskletButtonSize,
115
 
                        CAIRO_DOCK_FILL_SPACE);
116
 
        }
117
 
 
118
 
        if (myDesklets.cDepthRotateButtonImage != NULL)
119
 
        {
120
 
                cairo_dock_load_image_buffer (&s_pDepthRotateButtonBuffer,
121
 
                        myDesklets.cDepthRotateButtonImage,
122
 
                        myDesklets.iDeskletButtonSize,
123
 
                        myDesklets.iDeskletButtonSize,
124
 
                        CAIRO_DOCK_FILL_SPACE);
125
 
        }
126
 
        if (s_pDepthRotateButtonBuffer.pSurface == NULL)
127
 
        {
128
 
                cairo_dock_load_image_buffer (&s_pDepthRotateButtonBuffer,
129
 
                        CAIRO_DOCK_SHARE_DATA_DIR"/depth-rotate-desklet.svg",
130
 
                        myDesklets.iDeskletButtonSize,
131
 
                        myDesklets.iDeskletButtonSize,
132
 
                        CAIRO_DOCK_FILL_SPACE);
133
 
        }
134
 
        
135
 
        /*if (myDesklets.cNoInputButtonImage != NULL)
136
 
        {
137
 
                cairo_dock_load_image_buffer (&s_pNoInputButtonBuffer,
138
 
                        myDesklets.cNoInputButtonImage,
139
 
                        myDesklets.iDeskletButtonSize,
140
 
                        myDesklets.iDeskletButtonSize,
141
 
                        CAIRO_DOCK_FILL_SPACE);
142
 
        }
143
 
        if (s_pNoInputButtonBuffer.pSurface == NULL)
144
 
        {
145
 
                cairo_dock_load_image_buffer (&s_pNoInputButtonBuffer,
146
 
                        CAIRO_DOCK_SHARE_DATA_DIR"/no-input-desklet.svg",
147
 
                        myDesklets.iDeskletButtonSize,
148
 
                        myDesklets.iDeskletButtonSize,
149
 
                        CAIRO_DOCK_FILL_SPACE);
150
 
        }*/  // 2.1.4
151
 
}
152
 
 
153
 
void cairo_dock_unload_desklet_buttons (void)
154
 
{
155
 
        //g_print ("%s ()\n", __func__);
156
 
        cairo_dock_unload_image_buffer (&s_pRotateButtonBuffer);
157
 
        cairo_dock_unload_image_buffer (&s_pRetachButtonBuffer);
158
 
        cairo_dock_unload_image_buffer (&s_pDepthRotateButtonBuffer);
159
 
        cairo_dock_unload_image_buffer (&s_pNoInputButtonBuffer);
160
 
}
161
 
 
162
 
static void _cairo_dock_load_desklet_decorations (CairoDesklet *pDesklet, cairo_t *pSourceContext)
163
 
{
164
 
        if (pDesklet->pBackGroundSurface != NULL)
165
 
        {
166
 
                cairo_surface_destroy (pDesklet->pBackGroundSurface);
167
 
                pDesklet->pBackGroundSurface = NULL;
168
 
        }
169
 
        if (pDesklet->pForeGroundSurface != NULL)
170
 
        {
171
 
                cairo_surface_destroy (pDesklet->pForeGroundSurface);
172
 
                pDesklet->pForeGroundSurface = NULL;
173
 
        }
174
 
        if (pDesklet->iBackGroundTexture != 0)
175
 
        {
176
 
                _cairo_dock_delete_texture (pDesklet->iBackGroundTexture);
177
 
                pDesklet->iBackGroundTexture = 0;
178
 
        }
179
 
        if (pDesklet->iForeGroundTexture != 0)
180
 
        {
181
 
                _cairo_dock_delete_texture (pDesklet->iForeGroundTexture);
182
 
                pDesklet->iForeGroundTexture = 0;
183
 
        }
184
 
        
185
 
        CairoDeskletDecoration *pDeskletDecorations;
186
 
        //cd_debug ("%s (%s)", __func__, pDesklet->cDecorationTheme);
187
 
        if (pDesklet->cDecorationTheme == NULL || strcmp (pDesklet->cDecorationTheme, "personnal") == 0)
188
 
                pDeskletDecorations = pDesklet->pUserDecoration;
189
 
        else if (strcmp (pDesklet->cDecorationTheme, "default") == 0)
190
 
                pDeskletDecorations = cairo_dock_get_desklet_decoration (myDesklets.cDeskletDecorationsName);
191
 
        else
192
 
                pDeskletDecorations = cairo_dock_get_desklet_decoration (pDesklet->cDecorationTheme);
193
 
        if (pDeskletDecorations == NULL)  // peut arriver si rendering n'a pas encore charge ses decorations.
194
 
                return ;
195
 
        //cd_debug ("pDeskletDecorations : %s (%x)", pDesklet->cDecorationTheme, pDeskletDecorations);
196
 
        
197
 
        double fZoomX = 0., fZoomY = 0.;
198
 
        if  (pDeskletDecorations->cBackGroundImagePath != NULL && pDeskletDecorations->fBackGroundAlpha > 0)
199
 
        {
200
 
                //cd_debug ("bg : %s", pDeskletDecorations->cBackGroundImagePath);
201
 
                gchar *cPath = cairo_dock_generate_file_path (pDeskletDecorations->cBackGroundImagePath);
202
 
                pDesklet->pBackGroundSurface = cairo_dock_create_surface_from_image (cPath,
203
 
                        pSourceContext,
204
 
                        1.,  // cairo_dock_get_max_scale (pDesklet)
205
 
                        pDesklet->container.iWidth, pDesklet->container.iHeight,
206
 
                        pDeskletDecorations->iLoadingModifier,
207
 
                        &pDesklet->fImageWidth, &pDesklet->fImageHeight,
208
 
                        &fZoomX, &fZoomY);
209
 
                g_free (cPath);
210
 
        }
211
 
        if (pDeskletDecorations->cForeGroundImagePath != NULL && pDeskletDecorations->fForeGroundAlpha > 0)
212
 
        {
213
 
                //cd_debug ("fg : %s", pDeskletDecorations->cForeGroundImagePath);
214
 
                gchar *cPath = cairo_dock_generate_file_path (pDeskletDecorations->cForeGroundImagePath);
215
 
                pDesklet->pForeGroundSurface = cairo_dock_create_surface_from_image (cPath,
216
 
                        pSourceContext,
217
 
                        1.,  // cairo_dock_get_max_scale (pDesklet)
218
 
                        pDesklet->container.iWidth, pDesklet->container.iHeight,
219
 
                        pDeskletDecorations->iLoadingModifier,
220
 
                        &pDesklet->fImageWidth, &pDesklet->fImageHeight,
221
 
                        &fZoomX, &fZoomY);
222
 
                g_free (cPath);
223
 
        }
224
 
        //cd_debug ("image : %.2fx%.2f ; zoom : %.2fx%.2f", pDesklet->fImageWidth, pDesklet->fImageHeight, fZoomX, fZoomY);
225
 
        pDesklet->iLeftSurfaceOffset = pDeskletDecorations->iLeftMargin * fZoomX;
226
 
        pDesklet->iTopSurfaceOffset = pDeskletDecorations->iTopMargin * fZoomY;
227
 
        pDesklet->iRightSurfaceOffset = pDeskletDecorations->iRightMargin * fZoomX;
228
 
        pDesklet->iBottomSurfaceOffset = pDeskletDecorations->iBottomMargin * fZoomY;
229
 
        pDesklet->fBackGroundAlpha = pDeskletDecorations->fBackGroundAlpha;
230
 
        pDesklet->fForeGroundAlpha = pDeskletDecorations->fForeGroundAlpha;
231
 
        //cd_debug ("%d;%d;%d;%d ; %.2f;%.2f", pDesklet->iLeftSurfaceOffset, pDesklet->iTopSurfaceOffset, pDesklet->iRightSurfaceOffset, pDesklet->iBottomSurfaceOffset, pDesklet->fBackGroundAlpha, pDesklet->fForeGroundAlpha);
232
 
        if (g_bUseOpenGL)
233
 
        {
234
 
                if (pDesklet->pBackGroundSurface != NULL)
235
 
                        pDesklet->iBackGroundTexture = cairo_dock_create_texture_from_surface (pDesklet->pBackGroundSurface);
236
 
                if (pDesklet->pForeGroundSurface != NULL)
237
 
                        pDesklet->iForeGroundTexture = cairo_dock_create_texture_from_surface (pDesklet->pForeGroundSurface);
238
 
        }
239
 
}
240
 
 
241
 
static gboolean _cairo_dock_reload_one_desklet_decorations (CairoDesklet *pDesklet, CairoDockModuleInstance *pInstance, gpointer *data)
242
 
{
243
 
        gboolean bDefaultThemeOnly = GPOINTER_TO_INT (data[0]);
244
 
        cairo_t *pSourceContext = data[1];
245
 
        
246
 
        if (bDefaultThemeOnly)
247
 
        {
248
 
                if (pDesklet->cDecorationTheme == NULL || strcmp (pDesklet->cDecorationTheme, "default") == 0)
249
 
                {
250
 
                        cd_debug ("on recharge les decorations de ce desklet");
251
 
                        _cairo_dock_load_desklet_decorations (pDesklet, pSourceContext);
252
 
                }
253
 
        }
254
 
        else  // tous ceux qui ne sont pas encore charges et qui ont leur taille definitive.
255
 
        {
256
 
                //cd_debug ("pouet %dx%d ; %d ; %x;%x", pDesklet->iDesiredWidth, pDesklet->iDesiredHeight, pDesklet->iSidWriteSize, pDesklet->pBackGroundSurface, pDesklet->pForeGroundSurface);
257
 
                if (pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0 && pDesklet->iSidWriteSize == 0 && pDesklet->pBackGroundSurface == NULL && pDesklet->pForeGroundSurface == NULL)
258
 
                {
259
 
                        cd_debug ("ce desklet a saute le chargement de ses deco => on l'aide.");
260
 
                        _cairo_dock_load_desklet_decorations (pDesklet, pSourceContext);
261
 
                }
262
 
        }
263
 
        return FALSE;
264
 
}
265
 
void cairo_dock_reload_desklets_decorations (gboolean bDefaultThemeOnly, cairo_t *pSourceContext)  // tous ou bien seulement ceux avec "default".
266
 
{
267
 
        cd_message ("%s (%d)", __func__, bDefaultThemeOnly);
268
 
        gpointer data[2] = {GINT_TO_POINTER (bDefaultThemeOnly), pSourceContext};
269
 
        cairo_dock_foreach_desklet ((CairoDockForeachDeskletFunc)_cairo_dock_reload_one_desklet_decorations, data);
270
 
}
271
 
 
272
 
void cairo_dock_free_desklet_decoration (CairoDeskletDecoration *pDecoration)
273
 
{
274
 
        if (pDecoration == NULL)
275
 
                return ;
276
 
        g_free (pDecoration->cBackGroundImagePath);
277
 
        g_free (pDecoration->cForeGroundImagePath);
278
 
        g_free (pDecoration);
279
 
}
280
 
 
281
 
 
282
 
 
283
 
static inline double _compute_zoom_for_rotation (CairoDesklet *pDesklet)
284
 
{
285
 
        double w = pDesklet->container.iWidth/2, h = pDesklet->container.iHeight/2;
286
 
        double alpha = atan2 (h, w);
287
 
        double theta = fabs (pDesklet->fRotation);
288
 
        if (theta > G_PI/2)
289
 
                theta -= G_PI/2;
290
 
        
291
 
        double d = sqrt (w * w + h * h);
292
 
        double xmax = d * MAX (fabs (cos (alpha + theta)), fabs (cos (alpha - theta)));
293
 
        double ymax = d * MAX (fabs (sin (alpha + theta)), fabs (sin (alpha - theta)));
294
 
        double fZoom = MIN (w / xmax, h / ymax);
295
 
        return fZoom;
296
 
}
297
 
 
298
 
static inline void _render_desklet_cairo (CairoDesklet *pDesklet, cairo_t *pCairoContext)
299
 
{
300
 
        // en attendant de trouver l'equivalent opengl.
301
 
        #if 0
302
 
        double fColor[4] = {1., 1., 1., 0.};
303
 
        if (! gtk_window_is_active (GTK_WINDOW (pDesklet->container.pWidget)))
304
 
                fColor[3] = 0.;
305
 
        else
306
 
                fColor[3] = 1.*pDesklet->iGradationCount / CD_NB_ITER_FOR_GRADUATION;
307
 
        
308
 
        if (fColor[3] != 0)
309
 
        {
310
 
                cairo_save (pCairoContext);
311
 
                cairo_pattern_t *pPattern = cairo_pattern_create_radial (.5*pDesklet->container.iWidth,
312
 
                        .5*pDesklet->container.iHeight,
313
 
                        0.,
314
 
                        .5*pDesklet->container.iWidth,
315
 
                        .5*pDesklet->container.iHeight,
316
 
                        .5*MIN (pDesklet->container.iWidth, pDesklet->container.iHeight));
317
 
                cairo_pattern_set_extend (pPattern, CAIRO_EXTEND_NONE);
318
 
                
319
 
                cairo_pattern_add_color_stop_rgba   (pPattern,
320
 
                        0.,
321
 
                        fColor[0], fColor[1], fColor[2], fColor[3]);
322
 
                cairo_pattern_add_color_stop_rgba   (pPattern,
323
 
                        1.,
324
 
                        fColor[0], fColor[1], fColor[2], 0.);
325
 
                cairo_set_source (pCairoContext, pPattern);
326
 
                cairo_paint (pCairoContext);
327
 
                cairo_pattern_destroy (pPattern);
328
 
                cairo_restore (pCairoContext);
329
 
        }
330
 
        #endif
331
 
        
332
 
        cairo_save (pCairoContext);
333
 
        
334
 
        if (pDesklet->container.fRatio != 1)
335
 
        {
336
 
                //g_print (" desklet zoom : %.2f (%dx%d)\n", pDesklet->container.fRatio, pDesklet->container.iWidth, pDesklet->container.iHeight);
337
 
                cairo_translate (pCairoContext,
338
 
                        pDesklet->container.iWidth * (1 - pDesklet->container.fRatio)/2,
339
 
                        pDesklet->container.iHeight * (1 - pDesklet->container.fRatio)/2);
340
 
                cairo_scale (pCairoContext, pDesklet->container.fRatio, pDesklet->container.fRatio);
341
 
        }
342
 
        
343
 
        if (pDesklet->fRotation != 0)
344
 
        {
345
 
                double fZoom = _compute_zoom_for_rotation (pDesklet);
346
 
                
347
 
                cairo_translate (pCairoContext,
348
 
                        .5*pDesklet->container.iWidth,
349
 
                        .5*pDesklet->container.iHeight);
350
 
                
351
 
                cairo_rotate (pCairoContext, pDesklet->fRotation);
352
 
                
353
 
                cairo_scale (pCairoContext, fZoom, fZoom);
354
 
                
355
 
                cairo_translate (pCairoContext,
356
 
                        -.5*pDesklet->container.iWidth,
357
 
                        -.5*pDesklet->container.iHeight);
358
 
        }
359
 
        
360
 
        if (pDesklet->pBackGroundSurface != NULL && pDesklet->fBackGroundAlpha != 0)
361
 
        {
362
 
                cairo_set_source_surface (pCairoContext,
363
 
                        pDesklet->pBackGroundSurface,
364
 
                        0.,
365
 
                        0.);
366
 
                if (pDesklet->fBackGroundAlpha == 1)
367
 
                        cairo_paint (pCairoContext);
368
 
                else
369
 
                        cairo_paint_with_alpha (pCairoContext, pDesklet->fBackGroundAlpha);
370
 
        }
371
 
        
372
 
        cairo_save (pCairoContext);
373
 
        if (pDesklet->iLeftSurfaceOffset != 0 || pDesklet->iTopSurfaceOffset != 0 || pDesklet->iRightSurfaceOffset != 0 || pDesklet->iBottomSurfaceOffset != 0)
374
 
        {
375
 
                cairo_translate (pCairoContext, pDesklet->iLeftSurfaceOffset, pDesklet->iTopSurfaceOffset);
376
 
                cairo_scale (pCairoContext,
377
 
                        1. - 1.*(pDesklet->iLeftSurfaceOffset + pDesklet->iRightSurfaceOffset) / pDesklet->container.iWidth,
378
 
                        1. - 1.*(pDesklet->iTopSurfaceOffset + pDesklet->iBottomSurfaceOffset) / pDesklet->container.iHeight);
379
 
        }
380
 
        
381
 
        if (pDesklet->pRenderer != NULL && pDesklet->pRenderer->render != NULL)  // un moteur de rendu specifique a ete fourni.
382
 
        {
383
 
                pDesklet->pRenderer->render (pCairoContext, pDesklet);
384
 
        }
385
 
        cairo_restore (pCairoContext);
386
 
        
387
 
        if (pDesklet->pForeGroundSurface != NULL && pDesklet->fForeGroundAlpha != 0)
388
 
        {
389
 
                cairo_set_source_surface (pCairoContext,
390
 
                        pDesklet->pForeGroundSurface,
391
 
                        0.,
392
 
                        0.);
393
 
                if (pDesklet->fForeGroundAlpha == 1)
394
 
                        cairo_paint (pCairoContext);
395
 
                else
396
 
                        cairo_paint_with_alpha (pCairoContext, pDesklet->fForeGroundAlpha);
397
 
        }
398
 
        
399
 
        if (! pDesklet->rotating)  // si on est en train de tourner, les boutons suivent le mouvement, sinon ils sont dans les coins.
400
 
        {
401
 
                cairo_restore (pCairoContext);
402
 
                cairo_save (pCairoContext);
403
 
        }
404
 
        if ((pDesklet->container.bInside || pDesklet->rotating) && _cairo_dock_desklet_is_free (pDesklet))
405
 
        {
406
 
                if (s_pRotateButtonBuffer.pSurface != NULL)
407
 
                {
408
 
                        cairo_set_source_surface (pCairoContext, s_pRotateButtonBuffer.pSurface, 0., 0.);
409
 
                        cairo_paint (pCairoContext);
410
 
                }
411
 
                if (s_pRetachButtonBuffer.pSurface != NULL)
412
 
                {
413
 
                        cairo_set_source_surface (pCairoContext, s_pRetachButtonBuffer.pSurface, pDesklet->container.iWidth - myDesklets.iDeskletButtonSize, 0.);
414
 
                        cairo_paint (pCairoContext);
415
 
                }
416
 
        }
417
 
        /*if ((pDesklet->container.bInside || pDesklet->bNoInput) && s_pNoInputButtonBuffer.pSurface != NULL)
418
 
        {
419
 
                cairo_set_source_surface (pCairoContext, s_pNoInputButtonBuffer.pSurface, pDesklet->container.iWidth - myDesklets.iDeskletButtonSize, pDesklet->container.iHeight - myDesklets.iDeskletButtonSize);
420
 
                cairo_paint (pCairoContext);
421
 
        }*/  // 2.1.4
422
 
        cairo_restore (pCairoContext);
423
 
}
424
 
 
425
 
static inline void _cairo_dock_set_desklet_matrix (CairoDesklet *pDesklet)
426
 
{
427
 
        glTranslatef (0., 0., -pDesklet->container.iHeight * sqrt(3)/2 - 
428
 
                .45 * MAX (pDesklet->container.iWidth * fabs (sin (pDesklet->fDepthRotationY)),
429
 
                        pDesklet->container.iHeight * fabs (sin (pDesklet->fDepthRotationX)))
430
 
                );  // avec 60 deg de perspective
431
 
        
432
 
        if (pDesklet->container.fRatio != 1)
433
 
        {
434
 
                glScalef (pDesklet->container.fRatio, pDesklet->container.fRatio, 1.);
435
 
        }
436
 
        
437
 
        if (pDesklet->fRotation != 0)
438
 
        {
439
 
                double fZoom = _compute_zoom_for_rotation (pDesklet);
440
 
                glScalef (fZoom, fZoom, 1.);
441
 
                glRotatef (- pDesklet->fRotation / G_PI * 180., 0., 0., 1.);
442
 
        }
443
 
        
444
 
        if (pDesklet->fDepthRotationY != 0)
445
 
        {
446
 
                glRotatef (- pDesklet->fDepthRotationY / G_PI * 180., 0., 1., 0.);
447
 
        }
448
 
        
449
 
        if (pDesklet->fDepthRotationX != 0)
450
 
        {
451
 
                glRotatef (- pDesklet->fDepthRotationX / G_PI * 180., 1., 0., 0.);
452
 
        }
453
 
}
454
 
 
455
 
static inline void _render_desklet_opengl (CairoDesklet *pDesklet)
456
 
{
457
 
        glPushMatrix ();
458
 
        ///glTranslatef (0*pDesklet->container.iWidth/2, 0*pDesklet->container.iHeight/2, 0.);  // avec une perspective ortho.
459
 
        ///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
460
 
        _cairo_dock_set_desklet_matrix (pDesklet);
461
 
        
462
 
        _cairo_dock_enable_texture ();
463
 
        _cairo_dock_set_blend_pbuffer ();
464
 
        
465
 
        if (pDesklet->iBackGroundTexture != 0 && pDesklet->fBackGroundAlpha != 0)
466
 
        {
467
 
                _cairo_dock_apply_texture_at_size_with_alpha (pDesklet->iBackGroundTexture, pDesklet->container.iWidth, pDesklet->container.iHeight, pDesklet->fBackGroundAlpha);
468
 
        }
469
 
        
470
 
        glPushMatrix ();
471
 
        if (pDesklet->iLeftSurfaceOffset != 0 || pDesklet->iTopSurfaceOffset != 0 || pDesklet->iRightSurfaceOffset != 0 || pDesklet->iBottomSurfaceOffset != 0)
472
 
        {
473
 
                glTranslatef ((pDesklet->iLeftSurfaceOffset - pDesklet->iRightSurfaceOffset)/2, (pDesklet->iBottomSurfaceOffset - pDesklet->iTopSurfaceOffset)/2, 0.);
474
 
                glScalef (1. - 1.*(pDesklet->iLeftSurfaceOffset + pDesklet->iRightSurfaceOffset) / pDesklet->container.iWidth,
475
 
                        1. - 1.*(pDesklet->iTopSurfaceOffset + pDesklet->iBottomSurfaceOffset) / pDesklet->container.iHeight,
476
 
                        1.);
477
 
        }
478
 
        
479
 
        if (pDesklet->pRenderer != NULL && pDesklet->pRenderer->render_opengl != NULL)  // un moteur de rendu specifique a ete fourni.
480
 
        {
481
 
                _cairo_dock_set_alpha (1.);
482
 
                pDesklet->pRenderer->render_opengl (pDesklet);
483
 
        }
484
 
        glPopMatrix ();
485
 
        
486
 
        _cairo_dock_enable_texture ();
487
 
        _cairo_dock_set_blend_pbuffer ();
488
 
        if (pDesklet->iForeGroundTexture != 0 && pDesklet->fForeGroundAlpha != 0)
489
 
        {
490
 
                _cairo_dock_apply_texture_at_size_with_alpha (pDesklet->iForeGroundTexture, pDesklet->container.iWidth, pDesklet->container.iHeight, pDesklet->fForeGroundAlpha);
491
 
        }
492
 
        
493
 
        //if (pDesklet->container.bInside && _cairo_dock_desklet_is_free (pDesklet))
494
 
        {
495
 
                if (! pDesklet->rotating && ! pDesklet->rotatingY && ! pDesklet->rotatingX)
496
 
                {
497
 
                        glPopMatrix ();
498
 
                        glPushMatrix ();
499
 
                        glTranslatef (0., 0., -pDesklet->container.iHeight*(sqrt(3)/2));
500
 
                }
501
 
        }
502
 
        
503
 
        if ((pDesklet->container.bInside || pDesklet->rotating || pDesklet->rotatingY || pDesklet->rotatingX) && _cairo_dock_desklet_is_free (pDesklet))
504
 
        {
505
 
                _cairo_dock_set_alpha (1.);
506
 
                if (s_pRotateButtonBuffer.iTexture != 0)
507
 
                {
508
 
                        glPushMatrix ();
509
 
                        glTranslatef (-pDesklet->container.iWidth/2 + myDesklets.iDeskletButtonSize/2,
510
 
                                pDesklet->container.iHeight/2 - myDesklets.iDeskletButtonSize/2,
511
 
                                0.);
512
 
                        _cairo_dock_apply_texture_at_size (s_pRotateButtonBuffer.iTexture, myDesklets.iDeskletButtonSize, myDesklets.iDeskletButtonSize);
513
 
                        glPopMatrix ();
514
 
                }
515
 
                if (s_pRetachButtonBuffer.iTexture != 0)
516
 
                {
517
 
                        glPushMatrix ();
518
 
                        glTranslatef (pDesklet->container.iWidth/2 - myDesklets.iDeskletButtonSize/2,
519
 
                                pDesklet->container.iHeight/2 - myDesklets.iDeskletButtonSize/2,
520
 
                                0.);
521
 
                        _cairo_dock_apply_texture_at_size (s_pRetachButtonBuffer.iTexture, myDesklets.iDeskletButtonSize, myDesklets.iDeskletButtonSize);
522
 
                        glPopMatrix ();
523
 
                }
524
 
                if (s_pDepthRotateButtonBuffer.iTexture != 0)
525
 
                {
526
 
                        glPushMatrix ();
527
 
                        glTranslatef (0.,
528
 
                                pDesklet->container.iHeight/2 - myDesklets.iDeskletButtonSize/2,
529
 
                                0.);
530
 
                        _cairo_dock_apply_texture_at_size (s_pDepthRotateButtonBuffer.iTexture, myDesklets.iDeskletButtonSize, myDesklets.iDeskletButtonSize);
531
 
                        glPopMatrix ();
532
 
                        
533
 
                        glPushMatrix ();
534
 
                        glRotatef (90., 0., 0., 1.);
535
 
                        glTranslatef (0.,
536
 
                                pDesklet->container.iWidth/2 - myDesklets.iDeskletButtonSize/2,
537
 
                                0.);
538
 
                        _cairo_dock_apply_texture_at_size (s_pDepthRotateButtonBuffer.iTexture, myDesklets.iDeskletButtonSize, myDesklets.iDeskletButtonSize);
539
 
                        glPopMatrix ();
540
 
                }
541
 
        }
542
 
        /*if ((pDesklet->container.bInside || pDesklet->bNoInput) && s_pNoInputButtonBuffer.iTexture != 0)
543
 
        {
544
 
                _cairo_dock_set_alpha (1.);
545
 
                glPushMatrix ();
546
 
                glTranslatef (pDesklet->container.iWidth/2 - myDesklets.iDeskletButtonSize/2,
547
 
                        - pDesklet->container.iHeight/2 + myDesklets.iDeskletButtonSize/2,
548
 
                        0.);
549
 
                _cairo_dock_apply_texture_at_size (s_pNoInputButtonBuffer.iTexture, myDesklets.iDeskletButtonSize, myDesklets.iDeskletButtonSize);
550
 
                glPopMatrix ();
551
 
        }*/  // 2.1.4
552
 
        
553
 
        _cairo_dock_disable_texture ();
554
 
        glPopMatrix ();
555
 
}
556
 
 
557
 
gboolean cairo_dock_render_desklet_notification (gpointer pUserData, CairoDesklet *pDesklet, cairo_t *pCairoContext)
558
 
{
559
 
        if (pCairoContext != NULL)
560
 
                _render_desklet_cairo (pDesklet, pCairoContext);
561
 
        else
562
 
                _render_desklet_opengl (pDesklet);
563
 
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
564
 
}
565
 
 
566
 
static gboolean on_expose_desklet(GtkWidget *pWidget,
567
 
        GdkEventExpose *pExpose,
568
 
        CairoDesklet *pDesklet)
569
 
{
570
 
        if (pDesklet->iDesiredWidth != 0 && pDesklet->iDesiredHeight != 0 && (pDesklet->iKnownWidth != pDesklet->iDesiredWidth || pDesklet->iKnownHeight != pDesklet->iDesiredHeight))
571
 
        {
572
 
                //g_print ("on saute le dessin\n");
573
 
                if (g_bUseOpenGL)
574
 
                {
575
 
                        // dessiner la fausse transparence.
576
 
                }
577
 
                else
578
 
                {
579
 
                        cairo_t *pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDesklet));
580
 
                        cairo_destroy (pCairoContext);
581
 
                }
582
 
                return FALSE;
583
 
        }
584
 
        
585
 
        pDesklet->iDesiredWidth = 0;  /// ???
586
 
        pDesklet->iDesiredHeight = 0;
587
 
        
588
 
        if (g_bUseOpenGL && pDesklet->pRenderer && pDesklet->pRenderer->render_opengl)
589
 
        {
590
 
                GdkGLContext *pGlContext = gtk_widget_get_gl_context (pDesklet->container.pWidget);
591
 
                GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (pDesklet->container.pWidget);
592
 
                if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
593
 
                        return FALSE;
594
 
                
595
 
                glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
596
 
                glLoadIdentity ();
597
 
                
598
 
                cairo_dock_apply_desktop_background_opengl (CAIRO_CONTAINER (pDesklet));
599
 
                
600
 
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_RENDER_DESKLET, pDesklet, NULL);
601
 
                
602
 
                if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
603
 
                        gdk_gl_drawable_swap_buffers (pGlDrawable);
604
 
                else
605
 
                        glFlush ();
606
 
                gdk_gl_drawable_gl_end (pGlDrawable);
607
 
        }
608
 
        else
609
 
        {
610
 
                cairo_t *pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDesklet));
611
 
                
612
 
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_RENDER_DESKLET, pDesklet, pCairoContext);
613
 
                
614
 
                cairo_destroy (pCairoContext);
615
 
        }
616
 
        
617
 
        return FALSE;
618
 
}
619
 
 
620
 
 
621
 
/*static void _cairo_dock_set_desklet_input_shape (CairoDesklet *pDesklet)
622
 
{
623
 
        gtk_widget_input_shape_combine_mask (pDesklet->container.pWidget,
624
 
                NULL,
625
 
                0,
626
 
                0);
627
 
        if (pDesklet->bNoInput)
628
 
        {
629
 
                GdkBitmap *pShapeBitmap = (GdkBitmap*) gdk_pixmap_new (NULL,
630
 
                        pDesklet->container.iWidth,
631
 
                        pDesklet->container.iHeight,
632
 
                        1);
633
 
                
634
 
                cairo_t *pCairoContext = gdk_cairo_create (pShapeBitmap);
635
 
                cairo_set_source_rgba (pCairoContext, 0.0f, 0.0f, 0.0f, 0.0f);
636
 
                cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
637
 
                cairo_paint (pCairoContext);
638
 
                cairo_set_source_rgba (pCairoContext, 1., 1., 1., 1.);
639
 
                cairo_rectangle (pCairoContext,
640
 
                        pDesklet->container.iWidth - myDesklets.iDeskletButtonSize,
641
 
                        pDesklet->container.iHeight - myDesklets.iDeskletButtonSize,
642
 
                        myDesklets.iDeskletButtonSize,
643
 
                        myDesklets.iDeskletButtonSize);
644
 
                cairo_fill (pCairoContext);
645
 
                cairo_destroy (pCairoContext);
646
 
                gtk_widget_input_shape_combine_mask (pDesklet->container.pWidget,
647
 
                        pShapeBitmap,
648
 
                        0,
649
 
                        0);
650
 
                g_object_unref (pShapeBitmap);
651
 
                g_print ("input shape : %dx%d", pDesklet->container.iWidth, pDesklet->container.iHeight);
652
 
        }
653
 
}*/  // 2.1.4
654
 
 
655
 
static gboolean _cairo_dock_write_desklet_size (CairoDesklet *pDesklet)
656
 
{
657
 
        if ((pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0) && pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
658
 
        {
659
 
                gchar *cSize = g_strdup_printf ("%d;%d", pDesklet->container.iWidth, pDesklet->container.iHeight);
660
 
                cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
661
 
                        G_TYPE_STRING, "Desklet", "size", cSize,
662
 
                        G_TYPE_INVALID);
663
 
                g_free (cSize);
664
 
                cairo_dock_update_desklet_size_in_gui (pDesklet->pIcon->pModuleInstance,
665
 
                        pDesklet->container.iWidth,
666
 
                        pDesklet->container.iHeight);
667
 
        }
668
 
        pDesklet->iSidWriteSize = 0;
669
 
        pDesklet->iKnownWidth = pDesklet->container.iWidth;
670
 
        pDesklet->iKnownHeight = pDesklet->container.iHeight;
671
 
        if (((pDesklet->iDesiredWidth != 0 || pDesklet->iDesiredHeight != 0) && pDesklet->iDesiredWidth == pDesklet->container.iWidth && pDesklet->iDesiredHeight == pDesklet->container.iHeight) || (pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0))
672
 
        {
673
 
                pDesklet->iDesiredWidth = 0;
674
 
                pDesklet->iDesiredHeight = 0;
675
 
                
676
 
                cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDesklet));
677
 
                _cairo_dock_load_desklet_decorations (pDesklet, pCairoContext);
678
 
                cairo_destroy (pCairoContext);
679
 
                
680
 
                if (pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
681
 
                {
682
 
                        //g_print ("RELOAD\n");
683
 
                        cairo_dock_reload_module_instance (pDesklet->pIcon->pModuleInstance, FALSE);
684
 
                        gtk_widget_queue_draw (pDesklet->container.pWidget);  // sinon on ne redessine que l'interieur.
685
 
                }
686
 
                
687
 
                Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
688
 
                if (/*cairo_dock_window_is_dock (Xid) || */pDesklet->bSpaceReserved)
689
 
                {
690
 
                        cairo_dock_reserve_space_for_desklet (pDesklet, TRUE);
691
 
                }
692
 
        }
693
 
        
694
 
        //g_print ("iWidth <- %d;iHeight <- %d ; (%dx%d) (%x)\n", pDesklet->container.iWidth, pDesklet->container.iHeight, pDesklet->iKnownWidth, pDesklet->iKnownHeight, pDesklet->pIcon);
695
 
        return FALSE;
696
 
}
697
 
static gboolean _cairo_dock_write_desklet_position (CairoDesklet *pDesklet)
698
 
{
699
 
        if (pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
700
 
        {
701
 
                int iRelativePositionX = (pDesklet->container.iWindowPositionX + pDesklet->container.iWidth/2 <= g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL]/2 ? pDesklet->container.iWindowPositionX : pDesklet->container.iWindowPositionX - g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL]);
702
 
                int iRelativePositionY = (pDesklet->container.iWindowPositionY + pDesklet->container.iHeight/2 <= g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]/2 ? pDesklet->container.iWindowPositionY : pDesklet->container.iWindowPositionY - g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
703
 
                
704
 
                Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
705
 
                int iNumDesktop = -1;
706
 
                if (! cairo_dock_xwindow_is_sticky (Xid))
707
 
                {
708
 
                        int iDesktop = cairo_dock_get_xwindow_desktop (Xid);
709
 
                        int iGlobalPositionX, iGlobalPositionY, iWidthExtent, iHeightExtent;
710
 
                        cairo_dock_get_xwindow_geometry (Xid, &iGlobalPositionX, &iGlobalPositionY, &iWidthExtent, &iHeightExtent);
711
 
                        if (iGlobalPositionX < 0)
712
 
                                iGlobalPositionX += g_iNbViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
713
 
                        if (iGlobalPositionY < 0)
714
 
                                iGlobalPositionY += g_iNbViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
715
 
                        
716
 
                        int iViewportX = iGlobalPositionX / g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
717
 
                        int iViewportY = iGlobalPositionY / g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
718
 
                        
719
 
                        int iCurrentDesktop, iCurrentViewportX, iCurrentViewportY;
720
 
                        cairo_dock_get_current_desktop_and_viewport (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
721
 
                        
722
 
                        iViewportX += iCurrentViewportX;
723
 
                        if (iViewportX >= g_iNbViewportX)
724
 
                                iViewportX -= g_iNbViewportX;
725
 
                        iViewportY += iCurrentViewportY;
726
 
                        if (iViewportY >= g_iNbViewportY)
727
 
                                iViewportY -= g_iNbViewportY;
728
 
                        //g_print ("position : %d,%d,%d / %d,%d,%d\n", iDesktop, iViewportX, iViewportY, iCurrentDesktop, iCurrentViewportX, iCurrentViewportY);
729
 
                        
730
 
                        iNumDesktop = iDesktop * g_iNbViewportX * g_iNbViewportY + iViewportX * g_iNbViewportY + iViewportY;
731
 
                        //g_print ("desormais on place le desklet sur le bureau (%d,%d,%d)\n", iDesktop, iViewportX, iViewportY);
732
 
                }
733
 
                
734
 
                cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
735
 
                        G_TYPE_INT, "Desklet", "x position", iRelativePositionX,
736
 
                        G_TYPE_INT, "Desklet", "y position", iRelativePositionY,
737
 
                        G_TYPE_INT, "Desklet", "num desktop", iNumDesktop,
738
 
                        G_TYPE_INVALID);
739
 
                cairo_dock_update_desklet_position_in_gui (pDesklet->pIcon->pModuleInstance,
740
 
                        iRelativePositionX,
741
 
                        iRelativePositionY);
742
 
        }
743
 
        
744
 
        if (pDesklet->bSpaceReserved)
745
 
        {
746
 
                cairo_dock_reserve_space_for_desklet (pDesklet, TRUE);
747
 
        }
748
 
        if (pDesklet->pIcon && cairo_dock_icon_has_dialog (pDesklet->pIcon))
749
 
        {
750
 
                cairo_dock_replace_all_dialogs ();
751
 
        }
752
 
        pDesklet->iSidWritePosition = 0;
753
 
        return FALSE;
754
 
}
755
 
static gboolean on_configure_desklet (GtkWidget* pWidget,
756
 
        GdkEventConfigure* pEvent,
757
 
        CairoDesklet *pDesklet)
758
 
{
759
 
        //g_print (" >>>>>>>>> %s (%dx%d, %d;%d)", __func__, pEvent->width, pEvent->height, pEvent->x, pEvent->y);
760
 
        if (pDesklet->container.iWidth != pEvent->width || pDesklet->container.iHeight != pEvent->height)
761
 
        {
762
 
                if ((pEvent->width < pDesklet->container.iWidth || pEvent->height < pDesklet->container.iHeight) && (pDesklet->iDesiredWidth != 0 && pDesklet->iDesiredHeight != 0))
763
 
                {
764
 
                        gdk_window_resize (pDesklet->container.pWidget->window,
765
 
                                pDesklet->iDesiredWidth,
766
 
                                pDesklet->iDesiredHeight);
767
 
                }
768
 
                
769
 
                pDesklet->container.iWidth = pEvent->width;
770
 
                pDesklet->container.iHeight = pEvent->height;
771
 
                
772
 
                if (g_bUseOpenGL)
773
 
                {
774
 
                        GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
775
 
                        GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
776
 
                        GLsizei w = pEvent->width;
777
 
                        GLsizei h = pEvent->height;
778
 
                        if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
779
 
                                return FALSE;
780
 
                        
781
 
                        glViewport(0, 0, w, h);
782
 
                        
783
 
                        cairo_dock_set_perspective_view (w, h);
784
 
                        
785
 
                        gdk_gl_drawable_gl_end (pGlDrawable);
786
 
                }
787
 
                
788
 
                /*if (pDesklet->bNoInput)
789
 
                        _cairo_dock_set_desklet_input_shape (pDesklet);*/  // 2.1.4
790
 
                
791
 
                if (pDesklet->iSidWriteSize != 0)
792
 
                {
793
 
                        g_source_remove (pDesklet->iSidWriteSize);
794
 
                }
795
 
                pDesklet->iSidWriteSize = g_timeout_add (500, (GSourceFunc) _cairo_dock_write_desklet_size, (gpointer) pDesklet);
796
 
        }
797
 
        
798
 
        int x = pEvent->x, y = pEvent->y;
799
 
        //g_print ("new desklet position : (%d;%d)", x, y);
800
 
        while (x < 0)  // on passe au referentiel du viewport de la fenetre; inutile de connaitre sa position, puisqu'ils ont tous la meme taille.
801
 
                x += g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
802
 
        while (x >= g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL])
803
 
                x -= g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
804
 
        while (y < 0)
805
 
                y += g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
806
 
        while (y >= g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
807
 
                y -= g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
808
 
        //g_print (" => (%d;%d)\n", x, y);
809
 
        if (pDesklet->container.iWindowPositionX != x || pDesklet->container.iWindowPositionY != y)
810
 
        {
811
 
                pDesklet->container.iWindowPositionX = x;
812
 
                pDesklet->container.iWindowPositionY = y;
813
 
 
814
 
                if (pDesklet->iSidWritePosition != 0)
815
 
                {
816
 
                        g_source_remove (pDesklet->iSidWritePosition);
817
 
                }
818
 
                pDesklet->iSidWritePosition = g_timeout_add (500, (GSourceFunc) _cairo_dock_write_desklet_position, (gpointer) pDesklet);
819
 
        }
820
 
        pDesklet->moving = FALSE;
821
 
 
822
 
        return FALSE;
823
 
}
824
 
 
825
 
gboolean on_scroll_desklet (GtkWidget* pWidget,
826
 
        GdkEventScroll* pScroll,
827
 
        CairoDesklet *pDesklet)
828
 
{
829
 
        //g_print ("scroll\n");
830
 
        if (! (pScroll->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)))
831
 
        {
832
 
                Icon *icon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
833
 
                if (icon != NULL)
834
 
                {
835
 
                        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_SCROLL_ICON, icon, pDesklet, pScroll->direction);
836
 
                }
837
 
        }
838
 
        return FALSE;
839
 
}
840
 
 
841
 
gboolean on_unmap_desklet (GtkWidget* pWidget,
842
 
        GdkEvent *pEvent,
843
 
        CairoDesklet *pDesklet)
844
 
{
845
 
        g_print ("unmap desklet (bAllowMinimize:%d)\n", pDesklet->bAllowMinimize);
846
 
        Window Xid = GDK_WINDOW_XID (pWidget->window);
847
 
        if (cairo_dock_window_is_utility (Xid))  // sur la couche des widgets, on ne fait rien.
848
 
                return FALSE;
849
 
        if (! pDesklet->bAllowMinimize)
850
 
        {
851
 
                if (pDesklet->pUnmapTimer)
852
 
                {
853
 
                        double fElapsedTime = g_timer_elapsed (pDesklet->pUnmapTimer, NULL);
854
 
                        g_print ("fElapsedTime : %fms\n", fElapsedTime);
855
 
                        g_timer_destroy (pDesklet->pUnmapTimer);
856
 
                        pDesklet->pUnmapTimer = NULL;
857
 
                        if (fElapsedTime < .2)
858
 
                                return TRUE;
859
 
                }
860
 
                gtk_window_present (GTK_WINDOW (pWidget));
861
 
        }
862
 
        else
863
 
        {
864
 
                pDesklet->bAllowMinimize = FALSE;
865
 
                if (pDesklet->pUnmapTimer == NULL)
866
 
                        pDesklet->pUnmapTimer = g_timer_new ();  // starts the timer.
867
 
        }
868
 
        return TRUE;  // stops other handlers from being invoked for the event.
869
 
}
870
 
 
871
 
Icon *cairo_dock_pick_icon_on_opengl_desklet (CairoDesklet *pDesklet)
872
 
{
873
 
        GLuint selectBuf[4];
874
 
    GLint hits=0;
875
 
    GLint viewport[4];
876
 
        
877
 
        GdkGLContext* pGlContext = gtk_widget_get_gl_context (pDesklet->container.pWidget);
878
 
        GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pDesklet->container.pWidget);
879
 
        if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
880
 
                return NULL;
881
 
        
882
 
        glGetIntegerv (GL_VIEWPORT, viewport);
883
 
        glSelectBuffer (4, selectBuf);
884
 
        
885
 
        glRenderMode(GL_SELECT);
886
 
        glInitNames();
887
 
        glPushName(0);
888
 
        
889
 
        glMatrixMode (GL_PROJECTION);
890
 
        glPushMatrix ();
891
 
        glLoadIdentity ();
892
 
    gluPickMatrix ((GLdouble) pDesklet->container.iMouseX, (GLdouble) (viewport[3] - pDesklet->container.iMouseY), 2.0, 2.0, viewport);
893
 
        gluPerspective (60.0, 1.0*(GLfloat)pDesklet->container.iWidth/(GLfloat)pDesklet->container.iHeight, 1., 4*pDesklet->container.iHeight);
894
 
        
895
 
        glMatrixMode (GL_MODELVIEW);
896
 
        glPushMatrix ();
897
 
        glLoadIdentity ();
898
 
        
899
 
        _cairo_dock_set_desklet_matrix (pDesklet);
900
 
        
901
 
        if (pDesklet->iLeftSurfaceOffset != 0 || pDesklet->iTopSurfaceOffset != 0 || pDesklet->iRightSurfaceOffset != 0 || pDesklet->iBottomSurfaceOffset != 0)
902
 
        {
903
 
                glTranslatef ((pDesklet->iLeftSurfaceOffset - pDesklet->iRightSurfaceOffset)/2, (pDesklet->iBottomSurfaceOffset - pDesklet->iTopSurfaceOffset)/2, 0.);
904
 
                glScalef (1. - 1.*(pDesklet->iLeftSurfaceOffset + pDesklet->iRightSurfaceOffset) / pDesklet->container.iWidth,
905
 
                        1. - 1.*(pDesklet->iTopSurfaceOffset + pDesklet->iBottomSurfaceOffset) / pDesklet->container.iHeight,
906
 
                        1.);
907
 
        }
908
 
        
909
 
        glPolygonMode (GL_FRONT, GL_FILL);
910
 
        glColor4f (1., 1., 1., 1.);
911
 
        
912
 
        pDesklet->iPickedObject = 0;
913
 
        if (pDesklet->render_bounding_box != NULL)  // surclasse la fonction du moteur de rendu.
914
 
        {
915
 
                pDesklet->render_bounding_box (pDesklet);
916
 
        }
917
 
        else if (pDesklet->pRenderer && pDesklet->pRenderer->render_bounding_box != NULL)
918
 
        {
919
 
                pDesklet->pRenderer->render_bounding_box (pDesklet);
920
 
        }
921
 
        else  // on le fait nous-memes a partir des coordonnees des icones.
922
 
        {
923
 
                glTranslatef (-pDesklet->container.iWidth/2, -pDesklet->container.iHeight/2, 0.);
924
 
                
925
 
                double x, y, w, h;
926
 
                Icon *pIcon;
927
 
                
928
 
                pIcon = pDesklet->pIcon;
929
 
                if (pIcon != NULL && pIcon->iIconTexture != 0)
930
 
                {
931
 
                        w = pIcon->fWidth/2;
932
 
                        h = pIcon->fHeight/2;
933
 
                        x = pIcon->fDrawX + w;
934
 
                        y = pDesklet->container.iHeight - pIcon->fDrawY - h;
935
 
                        
936
 
                        glLoadName(pIcon->iIconTexture);
937
 
                        
938
 
                        glBegin(GL_QUADS);
939
 
                        glVertex3f(x-w, y+h, 0.);
940
 
                        glVertex3f(x+w, y+h, 0.);
941
 
                        glVertex3f(x+w, y-h, 0.);
942
 
                        glVertex3f(x-w, y-h, 0.);
943
 
                        glEnd();
944
 
                }
945
 
                
946
 
                GList *ic;
947
 
                for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
948
 
                {
949
 
                        pIcon = ic->data;
950
 
                        if (pIcon->iIconTexture == 0)
951
 
                                continue;
952
 
                        
953
 
                        w = pIcon->fWidth/2;
954
 
                        h = pIcon->fHeight/2;
955
 
                        x = pIcon->fDrawX + w;
956
 
                        y = pDesklet->container.iHeight - pIcon->fDrawY - h;
957
 
                        
958
 
                        glLoadName(pIcon->iIconTexture);
959
 
                        
960
 
                        glBegin(GL_QUADS);
961
 
                        glVertex3f(x-w, y+h, 0.);
962
 
                        glVertex3f(x+w, y+h, 0.);
963
 
                        glVertex3f(x+w, y-h, 0.);
964
 
                        glVertex3f(x-w, y-h, 0.);
965
 
                        glEnd();
966
 
                }
967
 
        }
968
 
        
969
 
        glPopName();
970
 
        
971
 
        hits = glRenderMode (GL_RENDER);
972
 
 
973
 
        glMatrixMode (GL_PROJECTION);
974
 
        glPopMatrix ();
975
 
        glMatrixMode(GL_MODELVIEW);
976
 
        glPopMatrix ();
977
 
        
978
 
        Icon *pFoundIcon = NULL;
979
 
        if (hits != 0)
980
 
        {
981
 
                GLuint id = selectBuf[3];
982
 
                Icon *pIcon;
983
 
                
984
 
                if (pDesklet->render_bounding_box != NULL)
985
 
                {
986
 
                        pDesklet->iPickedObject = id;
987
 
                        //g_print ("iPickedObject <- %d\n", id);
988
 
                        pFoundIcon = pDesklet->pIcon;  // il faut mettre qqch, sinon la notification est filtree par la macro CD_APPLET_ON_CLICK_BEGIN.
989
 
                }
990
 
                else
991
 
                {
992
 
                        pIcon = pDesklet->pIcon;
993
 
                        if (pIcon != NULL && pIcon->iIconTexture != 0)
994
 
                        {
995
 
                                if (pIcon->iIconTexture == id)
996
 
                                {
997
 
                                        pFoundIcon = pIcon;
998
 
                                }
999
 
                        }
1000
 
                        
1001
 
                        if (pFoundIcon == NULL)
1002
 
                        {
1003
 
                                GList *ic;
1004
 
                                for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
1005
 
                                {
1006
 
                                        pIcon = ic->data;
1007
 
                                        if (pIcon->iIconTexture == id)
1008
 
                                        {
1009
 
                                                pFoundIcon = pIcon;
1010
 
                                                break ;
1011
 
                                        }
1012
 
                                }
1013
 
                        }
1014
 
                }
1015
 
        }
1016
 
        
1017
 
        gdk_gl_drawable_gl_end (pGlDrawable);
1018
 
        return pFoundIcon;
1019
 
}
1020
 
 
1021
 
 
1022
 
Icon *cairo_dock_find_clicked_icon_in_desklet (CairoDesklet *pDesklet)
1023
 
{
1024
 
        if (g_bUseOpenGL && pDesklet->pRenderer && pDesklet->pRenderer->render_opengl)
1025
 
        {
1026
 
                return cairo_dock_pick_icon_on_opengl_desklet (pDesklet);
1027
 
        }
1028
 
        
1029
 
        int iMouseX = pDesklet->container.iMouseX, iMouseY = pDesklet->container.iMouseY;
1030
 
        if (pDesklet->fRotation != 0)
1031
 
        {
1032
 
                //g_print (" clic en (%d;%d) rotations : %.2frad\n", iMouseX, iMouseY, pDesklet->fRotation);
1033
 
                double x, y;  // par rapport au centre du desklet.
1034
 
                x = iMouseX - pDesklet->container.iWidth/2;
1035
 
                y = pDesklet->container.iHeight/2 - iMouseY;
1036
 
                
1037
 
                double r, t;  // coordonnees polaires.
1038
 
                r = sqrt (x*x + y*y);
1039
 
                t = atan2 (y, x);
1040
 
                
1041
 
                double z = _compute_zoom_for_rotation (pDesklet);
1042
 
                r /= z;
1043
 
                
1044
 
                x = r * cos (t + pDesklet->fRotation);  // la rotation de cairo est dans le sene horaire.
1045
 
                y = r * sin (t + pDesklet->fRotation);
1046
 
                
1047
 
                iMouseX = x + pDesklet->container.iWidth/2;
1048
 
                iMouseY = pDesklet->container.iHeight/2 - y;
1049
 
                //g_print (" => (%d;%d)\n", iMouseX, iMouseY);
1050
 
        }
1051
 
        pDesklet->iMouseX2d = iMouseX;
1052
 
        pDesklet->iMouseY2d = iMouseY;
1053
 
        
1054
 
        Icon *icon = pDesklet->pIcon;
1055
 
        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).
1056
 
        if (icon->fDrawX < iMouseX && icon->fDrawX + icon->fWidth * icon->fScale > iMouseX && icon->fDrawY < iMouseY && icon->fDrawY + icon->fHeight * icon->fScale > iMouseY)
1057
 
        {
1058
 
                return icon;
1059
 
        }
1060
 
        
1061
 
        if (pDesklet->icons != NULL)
1062
 
        {
1063
 
                GList* ic;
1064
 
                for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
1065
 
                {
1066
 
                        icon = ic->data;
1067
 
                        if (icon->fDrawX < iMouseX && icon->fDrawX + icon->fWidth * icon->fScale > iMouseX && icon->fDrawY < iMouseY && icon->fDrawY + icon->fHeight * icon->fScale > iMouseY)
1068
 
                        {
1069
 
                                return icon;
1070
 
                        }
1071
 
                }
1072
 
        }
1073
 
        return NULL;
1074
 
}
1075
 
 
1076
 
static gboolean on_button_press_desklet(GtkWidget *pWidget,
1077
 
        GdkEventButton *pButton,
1078
 
        CairoDesklet *pDesklet)
1079
 
{
1080
 
        if (pButton->button == 1)  // clic gauche.
1081
 
        {
1082
 
                if (pButton->type == GDK_BUTTON_PRESS)
1083
 
                {
1084
 
                        pDesklet->bClicked = TRUE;
1085
 
                        if (_cairo_dock_desklet_is_free (pDesklet))
1086
 
                        {
1087
 
                                pDesklet->container.iMouseX = pButton->x;  // pour le deplacement manuel.
1088
 
                                pDesklet->container.iMouseY = pButton->y;
1089
 
                                
1090
 
                                if (pButton->x < myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)
1091
 
                                        pDesklet->rotating = TRUE;
1092
 
                                else if (pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)
1093
 
                                        pDesklet->retaching = TRUE;
1094
 
                                else if (pButton->x > (pDesklet->container.iWidth - myDesklets.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDesklets.iDeskletButtonSize)/2 && pButton->y < myDesklets.iDeskletButtonSize)
1095
 
                                        pDesklet->rotatingY = TRUE;
1096
 
                                else if (pButton->y > (pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)/2 && pButton->y < (pDesklet->container.iHeight + myDesklets.iDeskletButtonSize)/2 && pButton->x < myDesklets.iDeskletButtonSize)
1097
 
                                        pDesklet->rotatingX = TRUE;
1098
 
                                else
1099
 
                                        pDesklet->time = pButton->time;
1100
 
                        }
1101
 
                        /*if (pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y > pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)
1102
 
                                pDesklet->making_transparent = TRUE;*/  // 2.1.4
1103
 
                }
1104
 
                else if (pButton->type == GDK_BUTTON_RELEASE)
1105
 
                {
1106
 
                        if (!pDesklet->bClicked)  // on n'accepte le release que si on avait clique sur le desklet avant (on peut recevoir le release si on avat clique sur un dialogue qui chevauchait notre desklet et qui a disparu au clic).
1107
 
                        {
1108
 
                                return FALSE;
1109
 
                        }
1110
 
                        pDesklet->bClicked = FALSE;
1111
 
                        cd_debug ("GDK_BUTTON_RELEASE");
1112
 
                        if (pDesklet->moving)
1113
 
                        {
1114
 
                                pDesklet->moving = FALSE;
1115
 
                        }
1116
 
                        else if (pDesklet->rotating)
1117
 
                        {
1118
 
                                pDesklet->rotating = FALSE;
1119
 
                                cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
1120
 
                                        G_TYPE_INT, "Desklet", "rotation", (int) (pDesklet->fRotation / G_PI * 180.),
1121
 
                                        G_TYPE_INVALID);
1122
 
                                gtk_widget_queue_draw (pDesklet->container.pWidget);
1123
 
                        }
1124
 
                        else if (pDesklet->retaching)
1125
 
                        {
1126
 
                                pDesklet->retaching = FALSE;
1127
 
                                if (pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)  // on verifie qu'on est encore dedans.
1128
 
                                {
1129
 
                                        Icon *icon = pDesklet->pIcon;
1130
 
                                        g_return_val_if_fail (CAIRO_DOCK_IS_APPLET (icon), FALSE);
1131
 
                                        cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
1132
 
                                                G_TYPE_BOOLEAN, "Desklet", "initially detached", FALSE,
1133
 
                                                G_TYPE_INVALID);
1134
 
                                        cairo_dock_update_desklet_detached_state_in_gui (icon->pModuleInstance, FALSE);
1135
 
                                        cairo_dock_reload_module_instance (icon->pModuleInstance, TRUE);
1136
 
                                        return TRUE;  // interception du signal.
1137
 
                                }
1138
 
                        }
1139
 
                        /*else if (pDesklet->making_transparent)
1140
 
                        {
1141
 
                                g_print ("pDesklet->making_transparent\n");
1142
 
                                pDesklet->making_transparent = FALSE;
1143
 
                                if (pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y > pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)  // on verifie qu'on est encore dedans.
1144
 
                                {
1145
 
                                        Icon *icon = pDesklet->pIcon;
1146
 
                                        g_return_val_if_fail (CAIRO_DOCK_IS_APPLET (icon), FALSE);
1147
 
                                        pDesklet->bNoInput = ! pDesklet->bNoInput;
1148
 
                                        g_print ("no input : %d (%s)\n", pDesklet->bNoInput, icon->pModuleInstance->cConfFilePath);
1149
 
                                        cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
1150
 
                                                G_TYPE_BOOLEAN, "Desklet", "no input", pDesklet->bNoInput,
1151
 
                                                G_TYPE_INVALID);
1152
 
                                        _cairo_dock_set_desklet_input_shape (pDesklet);
1153
 
                                        gtk_widget_queue_draw (pDesklet->container.pWidget);
1154
 
                                }
1155
 
                        }*/  // 2.1.4
1156
 
                        else if (pDesklet->rotatingY)
1157
 
                        {
1158
 
                                pDesklet->rotatingY = FALSE;
1159
 
                                cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
1160
 
                                        G_TYPE_INT, "Desklet", "depth rotation y", (int) (pDesklet->fDepthRotationY / G_PI * 180.),
1161
 
                                        G_TYPE_INVALID);
1162
 
                                gtk_widget_queue_draw (pDesklet->container.pWidget);
1163
 
                        }
1164
 
                        else if (pDesklet->rotatingX)
1165
 
                        {
1166
 
                                pDesklet->rotatingX = FALSE;
1167
 
                                cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
1168
 
                                        G_TYPE_INT, "Desklet", "depth rotation x", (int) (pDesklet->fDepthRotationX / G_PI * 180.),
1169
 
                                        G_TYPE_INVALID);
1170
 
                                gtk_widget_queue_draw (pDesklet->container.pWidget);
1171
 
                        }
1172
 
                        else
1173
 
                        {
1174
 
                                Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
1175
 
                                cairo_dock_notify (CAIRO_DOCK_CLICK_ICON, pClickedIcon, pDesklet, pButton->state);
1176
 
                        }
1177
 
                }
1178
 
                else if (pButton->type == GDK_2BUTTON_PRESS)
1179
 
                {
1180
 
                        if (! (pButton->x < myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize) && ! (pButton->x > (pDesklet->container.iWidth - myDesklets.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDesklets.iDeskletButtonSize)/2 && pButton->y < myDesklets.iDeskletButtonSize))
1181
 
                        {
1182
 
                                Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
1183
 
                                cairo_dock_notify (CAIRO_DOCK_DOUBLE_CLICK_ICON, pClickedIcon, pDesklet);
1184
 
                        }
1185
 
                }
1186
 
        }
1187
 
        else if (pButton->button == 3 && pButton->type == GDK_BUTTON_PRESS)  // clique droit.
1188
 
        {
1189
 
                Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
1190
 
                GtkWidget *menu = cairo_dock_build_menu (pClickedIcon, CAIRO_CONTAINER (pDesklet));  // genere un CAIRO_DOCK_BUILD_ICON_MENU.
1191
 
                gtk_widget_show_all (menu);
1192
 
                gtk_menu_popup (GTK_MENU (menu),
1193
 
                        NULL,
1194
 
                        NULL,
1195
 
                        NULL,
1196
 
                        NULL,
1197
 
                        1,
1198
 
                        gtk_get_current_event_time ());
1199
 
                pDesklet->container.bInside = FALSE;
1200
 
                pDesklet->iGradationCount = 0;  // on force le fond a redevenir transparent.
1201
 
                gtk_widget_queue_draw (pDesklet->container.pWidget);
1202
 
        }
1203
 
        else if (pButton->button == 2 && pButton->type == GDK_BUTTON_PRESS)  // clique milieu.
1204
 
        {
1205
 
                if (pButton->x < myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)
1206
 
                {
1207
 
                        pDesklet->fRotation = 0.;
1208
 
                        gtk_widget_queue_draw (pDesklet->container.pWidget);
1209
 
                        cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
1210
 
                                G_TYPE_INT, "Desklet", "rotation", 0,
1211
 
                                G_TYPE_INVALID);
1212
 
                }
1213
 
                else if (pButton->x > (pDesklet->container.iWidth - myDesklets.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDesklets.iDeskletButtonSize)/2 && pButton->y < myDesklets.iDeskletButtonSize)
1214
 
                {
1215
 
                        pDesklet->fDepthRotationY = 0.;
1216
 
                        gtk_widget_queue_draw (pDesklet->container.pWidget);
1217
 
                        cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
1218
 
                                G_TYPE_INT, "Desklet", "depth rotation y", 0,
1219
 
                                G_TYPE_INVALID);
1220
 
                }
1221
 
                else if (pButton->y > (pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)/2 && pButton->y < (pDesklet->container.iHeight + myDesklets.iDeskletButtonSize)/2 && pButton->x < myDesklets.iDeskletButtonSize)
1222
 
                {
1223
 
                        pDesklet->fDepthRotationX = 0.;
1224
 
                        gtk_widget_queue_draw (pDesklet->container.pWidget);
1225
 
                        cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
1226
 
                                G_TYPE_INT, "Desklet", "depth rotation x", 0,
1227
 
                                G_TYPE_INVALID);
1228
 
                }
1229
 
                else
1230
 
                {
1231
 
                        cairo_dock_notify (CAIRO_DOCK_MIDDLE_CLICK_ICON, pDesklet->pIcon, pDesklet);
1232
 
                }
1233
 
        }
1234
 
        return FALSE;
1235
 
}
1236
 
 
1237
 
void on_drag_data_received_desklet (GtkWidget *pWidget, GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data, guint info, guint t, CairoDesklet *pDesklet)
1238
 
{
1239
 
        //g_print ("%s (%dx%d)\n", __func__, x, y);
1240
 
        
1241
 
        //\_________________ On recupere l'URI.
1242
 
        gchar *cReceivedData = (gchar *) selection_data->data;
1243
 
        g_return_if_fail (cReceivedData != NULL);
1244
 
        
1245
 
        pDesklet->container.iMouseX = x;
1246
 
        pDesklet->container.iMouseY = y;
1247
 
        Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
1248
 
        cairo_dock_notify_drop_data (cReceivedData, pClickedIcon, 0, CAIRO_CONTAINER (pDesklet));
1249
 
}
1250
 
 
1251
 
static gboolean on_motion_notify_desklet(GtkWidget *pWidget,
1252
 
        GdkEventMotion* pMotion,
1253
 
        CairoDesklet *pDesklet)
1254
 
{
1255
 
        if (pMotion->state & GDK_BUTTON1_MASK && _cairo_dock_desklet_is_free (pDesklet))
1256
 
        {
1257
 
                cd_debug ("root : %d;%d", (int) pMotion->x_root, (int) pMotion->y_root);
1258
 
                /*pDesklet->moving = TRUE;
1259
 
                gtk_window_move (GTK_WINDOW (pWidget),
1260
 
                        pMotion->x_root + pDesklet->diff_x,
1261
 
                        pMotion->y_root + pDesklet->diff_y);*/
1262
 
        }
1263
 
        else  // le 'press-button' est local au sous-widget clique, alors que le 'motion-notify' est global a la fenetre; c'est donc par lui qu'on peut avoir a coup sur les coordonnees du curseur (juste avant le clic).
1264
 
        {
1265
 
                pDesklet->container.iMouseX = pMotion->x;
1266
 
                pDesklet->container.iMouseY = pMotion->y;
1267
 
                gboolean bStartAnimation = FALSE;
1268
 
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_MOUSE_MOVED, pDesklet, &bStartAnimation);
1269
 
                if (bStartAnimation)
1270
 
                        cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
1271
 
        }
1272
 
        
1273
 
        if (pDesklet->rotating && _cairo_dock_desklet_is_free (pDesklet))
1274
 
        {
1275
 
                double alpha = atan2 (pDesklet->container.iHeight, - pDesklet->container.iWidth);
1276
 
                pDesklet->fRotation = alpha - atan2 (.5*pDesklet->container.iHeight - pMotion->y, pMotion->x - .5*pDesklet->container.iWidth);
1277
 
                while (pDesklet->fRotation > G_PI)
1278
 
                        pDesklet->fRotation -= 2 * G_PI;
1279
 
                while (pDesklet->fRotation <= - G_PI)
1280
 
                        pDesklet->fRotation += 2 * G_PI;
1281
 
                gtk_widget_queue_draw(pDesklet->container.pWidget);
1282
 
        }
1283
 
        else if (pDesklet->rotatingY && _cairo_dock_desklet_is_free (pDesklet))
1284
 
        {
1285
 
                pDesklet->fDepthRotationY = G_PI * (pMotion->x - .5*pDesklet->container.iWidth) / pDesklet->container.iWidth;
1286
 
                gtk_widget_queue_draw(pDesklet->container.pWidget);
1287
 
        }
1288
 
        else if (pDesklet->rotatingX && _cairo_dock_desklet_is_free (pDesklet))
1289
 
        {
1290
 
                pDesklet->fDepthRotationX = G_PI * (pMotion->y - .5*pDesklet->container.iHeight) / pDesklet->container.iHeight;
1291
 
                gtk_widget_queue_draw(pDesklet->container.pWidget);
1292
 
        }
1293
 
        else if (pMotion->state & GDK_BUTTON1_MASK && _cairo_dock_desklet_is_free (pDesklet) && ! pDesklet->moving)
1294
 
        {
1295
 
                gtk_window_begin_move_drag (GTK_WINDOW (gtk_widget_get_toplevel (pWidget)),
1296
 
                        1/*pButton->button*/,
1297
 
                        pMotion->x_root/*pButton->x_root*/,
1298
 
                        pMotion->y_root/*pButton->y_root*/,
1299
 
                        pDesklet->time/*pButton->time*/);
1300
 
                pDesklet->moving = TRUE;
1301
 
        }
1302
 
        else
1303
 
        {
1304
 
                gboolean bStartAnimation = FALSE;
1305
 
                Icon *pIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
1306
 
                if (pIcon != NULL)
1307
 
                {
1308
 
                        if (! pIcon->bPointed)
1309
 
                        {
1310
 
                                Icon *pPointedIcon = cairo_dock_get_pointed_icon (pDesklet->icons);
1311
 
                                if (pPointedIcon != NULL)
1312
 
                                        pPointedIcon->bPointed = FALSE;
1313
 
                                pIcon->bPointed = TRUE;
1314
 
                                
1315
 
                                //g_print ("on survole %s\n", pIcon->cName);
1316
 
                                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_ENTER_ICON, pIcon, pDesklet, &bStartAnimation);
1317
 
                        }
1318
 
                }
1319
 
                else
1320
 
                {
1321
 
                        Icon *pPointedIcon = cairo_dock_get_pointed_icon (pDesklet->icons);
1322
 
                        if (pPointedIcon != NULL)
1323
 
                        {
1324
 
                                pPointedIcon->bPointed = FALSE;
1325
 
                                
1326
 
                                //g_print ("kedal\n");
1327
 
                                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_ENTER_ICON, pPointedIcon, pDesklet, &bStartAnimation);
1328
 
 
1329
 
                        }
1330
 
                }
1331
 
                if (bStartAnimation)
1332
 
                {
1333
 
                        cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
1334
 
                }
1335
 
        }
1336
 
        
1337
 
        gdk_device_get_state (pMotion->device, pMotion->window, NULL, NULL);  // pour recevoir d'autres MotionNotify.
1338
 
        return FALSE;
1339
 
}
1340
 
 
1341
 
 
1342
 
static gboolean on_focus_in_out_desklet(GtkWidget *widget,
1343
 
        GdkEventFocus *event,
1344
 
        CairoDesklet *pDesklet)
1345
 
{
1346
 
        if (pDesklet)
1347
 
                gtk_widget_queue_draw(pDesklet->container.pWidget);
1348
 
        return FALSE;
1349
 
}
1350
 
 
1351
 
static gboolean _cairo_dock_desklet_gradation (CairoDesklet *pDesklet)
1352
 
{
1353
 
        pDesklet->iGradationCount += (pDesklet->container.bInside ? 1 : -1);
1354
 
        gtk_widget_queue_draw (pDesklet->container.pWidget);
1355
 
        
1356
 
        if (pDesklet->iGradationCount <= 0 || pDesklet->iGradationCount >= CD_NB_ITER_FOR_GRADUATION)
1357
 
        {
1358
 
                if (pDesklet->iGradationCount < 0)
1359
 
                        pDesklet->iGradationCount = 0;
1360
 
                else if (pDesklet->iGradationCount > CD_NB_ITER_FOR_GRADUATION)
1361
 
                        pDesklet->iGradationCount = CD_NB_ITER_FOR_GRADUATION;
1362
 
                pDesklet->iSidGradationOnEnter = 0;
1363
 
                return FALSE;
1364
 
        }
1365
 
        return TRUE;
1366
 
}
1367
 
static gboolean on_enter_desklet (GtkWidget* pWidget,
1368
 
        GdkEventCrossing* pEvent,
1369
 
        CairoDesklet *pDesklet)
1370
 
{
1371
 
        //g_print ("%s (%d)\n", __func__, pDesklet->container.bInside);
1372
 
        if (! pDesklet->container.bInside)  // avant on etait dehors, on redessine donc.
1373
 
        {
1374
 
                pDesklet->container.bInside = TRUE;
1375
 
                /**if (pDesklet->iSidGradationOnEnter == 0)
1376
 
                {
1377
 
                        pDesklet->iSidGradationOnEnter = g_timeout_add (50, (GSourceFunc) _cairo_dock_desklet_gradation, (gpointer) pDesklet);
1378
 
                }*/
1379
 
                gtk_widget_queue_draw (pWidget);  // redessin des boutons.
1380
 
                
1381
 
                if (g_bUseOpenGL/* && pDesklet->pRenderer && pDesklet->pRenderer->render_opengl != NULL*/)
1382
 
                {
1383
 
                        gboolean bStartAnimation = FALSE;
1384
 
                        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_ENTER_DESKLET, pDesklet, &bStartAnimation);
1385
 
                        if (bStartAnimation)
1386
 
                                cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
1387
 
                }
1388
 
        }
1389
 
        return FALSE;
1390
 
}
1391
 
static gboolean on_leave_desklet (GtkWidget* pWidget,
1392
 
        GdkEventCrossing* pEvent,
1393
 
        CairoDesklet *pDesklet)
1394
 
{
1395
 
        //g_print ("%s (%d)\n", __func__, pDesklet->container.bInside);
1396
 
        int iMouseX, iMouseY;
1397
 
        gdk_window_get_pointer (pWidget->window, &iMouseX, &iMouseY, NULL);
1398
 
        if (gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget)) != NULL && iMouseX > 0 && iMouseX < pDesklet->container.iWidth && iMouseY > 0 && iMouseY < pDesklet->container.iHeight)  // en fait on est dans un widget fils, donc on ne fait rien.
1399
 
        {
1400
 
                return FALSE;
1401
 
        }
1402
 
 
1403
 
        pDesklet->container.bInside = FALSE;
1404
 
        /**if (pDesklet->iSidGradationOnEnter == 0)
1405
 
        {
1406
 
                pDesklet->iSidGradationOnEnter = g_timeout_add (50, (GSourceFunc) _cairo_dock_desklet_gradation, (gpointer) pDesklet);
1407
 
        }*/
1408
 
        gtk_widget_queue_draw (pWidget);  // redessin des boutons.
1409
 
        
1410
 
        gboolean bStartAnimation = FALSE;
1411
 
        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_LEAVE_DESKLET, pDesklet, &bStartAnimation);
1412
 
        if (bStartAnimation)
1413
 
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
1414
 
        
1415
 
        return FALSE;
1416
 
}
1417
 
 
1418
 
 
1419
 
CairoDesklet *cairo_dock_create_desklet (Icon *pIcon, GtkWidget *pInteractiveWidget, CairoDeskletAccessibility iAccessibility)
1420
 
{
1421
 
        cd_message ("%s ()", __func__);
1422
 
        CairoDesklet *pDesklet = g_new0(CairoDesklet, 1);
1423
 
        pDesklet->container.iType = CAIRO_DOCK_TYPE_DESKLET;
1424
 
        pDesklet->container.bIsHorizontal = TRUE;
1425
 
        pDesklet->container.bDirectionUp = TRUE;
1426
 
        pDesklet->container.fRatio = 1;
1427
 
        
1428
 
        GtkWidget* pWindow = cairo_dock_create_container_window ();
1429
 
        if (iAccessibility == CAIRO_DESKLET_ON_WIDGET_LAYER)
1430
 
                gtk_window_set_type_hint (GTK_WINDOW (pWindow), GDK_WINDOW_TYPE_HINT_UTILITY);
1431
 
        else if (iAccessibility == CAIRO_DESKLET_RESERVE_SPACE)
1432
 
                gtk_window_set_type_hint (GTK_WINDOW (pWindow), GDK_WINDOW_TYPE_HINT_DOCK);
1433
 
                
1434
 
        pDesklet->container.pWidget = pWindow;
1435
 
        pDesklet->pIcon = pIcon;
1436
 
        
1437
 
        gtk_window_set_title (GTK_WINDOW(pWindow), "cairo-dock-desklet");
1438
 
        gtk_widget_add_events( pWindow, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_FOCUS_CHANGE_MASK);
1439
 
        gtk_container_set_border_width(GTK_CONTAINER(pWindow), 3);  // comme ca.
1440
 
        gtk_window_set_default_size(GTK_WINDOW(pWindow), 10, 10);  // idem.
1441
 
 
1442
 
        g_signal_connect (G_OBJECT (pWindow),
1443
 
                "expose-event",
1444
 
                G_CALLBACK (on_expose_desklet),
1445
 
                pDesklet);
1446
 
        g_signal_connect (G_OBJECT (pWindow),
1447
 
                "configure-event",
1448
 
                G_CALLBACK (on_configure_desklet),
1449
 
                pDesklet);
1450
 
        g_signal_connect (G_OBJECT (pWindow),
1451
 
                "motion-notify-event",
1452
 
                G_CALLBACK (on_motion_notify_desklet),
1453
 
                pDesklet);
1454
 
        g_signal_connect (G_OBJECT (pWindow),
1455
 
                "button-press-event",
1456
 
                G_CALLBACK (on_button_press_desklet),
1457
 
                pDesklet);
1458
 
        g_signal_connect (G_OBJECT (pWindow),
1459
 
                "button-release-event",
1460
 
                G_CALLBACK (on_button_press_desklet),
1461
 
                pDesklet);
1462
 
        g_signal_connect (G_OBJECT (pWindow),
1463
 
                "focus-in-event",
1464
 
                G_CALLBACK (on_focus_in_out_desklet),
1465
 
                pDesklet);
1466
 
        g_signal_connect (G_OBJECT (pWindow),
1467
 
                "focus-out-event",
1468
 
                G_CALLBACK (on_focus_in_out_desklet),
1469
 
                pDesklet);
1470
 
        g_signal_connect (G_OBJECT (pWindow),
1471
 
                "enter-notify-event",
1472
 
                G_CALLBACK (on_enter_desklet),
1473
 
                pDesklet);
1474
 
        g_signal_connect (G_OBJECT (pWindow),
1475
 
                "leave-notify-event",
1476
 
                G_CALLBACK (on_leave_desklet),
1477
 
                pDesklet);
1478
 
        g_signal_connect (G_OBJECT (pWindow),
1479
 
                "unmap-event",
1480
 
                G_CALLBACK (on_unmap_desklet),
1481
 
                pDesklet);
1482
 
        g_signal_connect (G_OBJECT (pWindow),
1483
 
                "scroll-event",
1484
 
                G_CALLBACK (on_scroll_desklet),
1485
 
                pDesklet);
1486
 
        cairo_dock_allow_widget_to_receive_data (pWindow, G_CALLBACK (on_drag_data_received_desklet), pDesklet);
1487
 
 
1488
 
        //user widget
1489
 
        if (pInteractiveWidget != NULL)
1490
 
        {
1491
 
                cd_debug ("ref = %d", pInteractiveWidget->object.parent_instance.ref_count);
1492
 
                cairo_dock_add_interactive_widget_to_desklet (pInteractiveWidget, pDesklet);
1493
 
                cd_debug ("pack -> ref = %d", pInteractiveWidget->object.parent_instance.ref_count);
1494
 
        }
1495
 
        
1496
 
        gtk_widget_show_all(pWindow);
1497
 
        
1498
 
        if (s_pRotateButtonBuffer.pSurface == NULL)
1499
 
        {
1500
 
                cairo_dock_load_desklet_buttons ();
1501
 
        }
1502
 
        
1503
 
        return pDesklet;
1504
 
}
1505
 
 
1506
 
void cairo_dock_configure_desklet (CairoDesklet *pDesklet, CairoDeskletAttribute *pAttribute)
1507
 
{
1508
 
        cd_debug ("%s (%dx%d ; (%d,%d) ; %d)", __func__, pAttribute->iDeskletWidth, pAttribute->iDeskletHeight, pAttribute->iDeskletPositionX, pAttribute->iDeskletPositionY, pAttribute->iAccessibility);
1509
 
        if (pAttribute->bDeskletUseSize && (pAttribute->iDeskletWidth != pDesklet->container.iWidth || pAttribute->iDeskletHeight != pDesklet->container.iHeight))
1510
 
        {
1511
 
                pDesklet->iDesiredWidth = pAttribute->iDeskletWidth;
1512
 
                pDesklet->iDesiredHeight = pAttribute->iDeskletHeight;
1513
 
                gdk_window_resize (pDesklet->container.pWidget->window,
1514
 
                        pAttribute->iDeskletWidth,
1515
 
                        pAttribute->iDeskletHeight);
1516
 
        }
1517
 
        if (! pAttribute->bDeskletUseSize)
1518
 
                gtk_container_set_border_width (GTK_CONTAINER (pDesklet->container.pWidget), 0);
1519
 
        
1520
 
        int iAbsolutePositionX = (pAttribute->iDeskletPositionX < 0 ? g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] + pAttribute->iDeskletPositionX : pAttribute->iDeskletPositionX);
1521
 
        iAbsolutePositionX = MAX (0, MIN (g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - pAttribute->iDeskletWidth, iAbsolutePositionX));
1522
 
        int iAbsolutePositionY = (pAttribute->iDeskletPositionY < 0 ? g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] + pAttribute->iDeskletPositionY : pAttribute->iDeskletPositionY);
1523
 
        iAbsolutePositionY = MAX (0, MIN (g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - pAttribute->iDeskletHeight, iAbsolutePositionY));
1524
 
        
1525
 
        if (pAttribute->bOnAllDesktops)
1526
 
                gdk_window_move(pDesklet->container.pWidget->window,
1527
 
                        iAbsolutePositionX,
1528
 
                        iAbsolutePositionY);
1529
 
        //g_print (" let's place the deklet at (%d;%d)", iAbsolutePositionX, iAbsolutePositionY);
1530
 
 
1531
 
        gtk_window_set_keep_below (GTK_WINDOW (pDesklet->container.pWidget), pAttribute->iAccessibility == CAIRO_DESKLET_KEEP_BELOW);
1532
 
        gtk_window_set_keep_above (GTK_WINDOW (pDesklet->container.pWidget), pAttribute->iAccessibility == CAIRO_DESKLET_KEEP_ABOVE);
1533
 
 
1534
 
        Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
1535
 
        if (pAttribute->iAccessibility == CAIRO_DESKLET_ON_WIDGET_LAYER)
1536
 
                cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_UTILITY");  // le hide-show le fait deconner completement, il perd son skip_task_bar ! au moins sous KDE3.
1537
 
        else
1538
 
                cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_NORMAL");
1539
 
        
1540
 
        if (pAttribute->iAccessibility == CAIRO_DESKLET_RESERVE_SPACE)
1541
 
        {
1542
 
                if (! pDesklet->bSpaceReserved)
1543
 
                        cairo_dock_reserve_space_for_desklet (pDesklet, pAttribute->iAccessibility == CAIRO_DESKLET_RESERVE_SPACE);  // sinon inutile de le refaire maintenant, ce sera declenche par le changement de taille/position s'il y'en a.
1544
 
                pDesklet->bSpaceReserved = TRUE;
1545
 
        }
1546
 
        else
1547
 
                pDesklet->bSpaceReserved = FALSE;
1548
 
        
1549
 
        if (pAttribute->bOnAllDesktops)
1550
 
        {
1551
 
                gtk_window_stick (GTK_WINDOW (pDesklet->container.pWidget));
1552
 
        }
1553
 
        else
1554
 
        {
1555
 
                gtk_window_unstick (GTK_WINDOW (pDesklet->container.pWidget));
1556
 
                Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
1557
 
                if (g_iNbViewportX > 0 && g_iNbViewportY > 0)
1558
 
                {
1559
 
                        int iNumDesktop, iNumViewportX, iNumViewportY;
1560
 
                        iNumDesktop = pAttribute->iNumDesktop / (g_iNbViewportX * g_iNbViewportY);
1561
 
                        int index2 = pAttribute->iNumDesktop % (g_iNbViewportX * g_iNbViewportY);
1562
 
                        iNumViewportX = index2 / g_iNbViewportY;
1563
 
                        iNumViewportY = index2 % g_iNbViewportY;
1564
 
                        
1565
 
                        int iCurrentDesktop, iCurrentViewportX, iCurrentViewportY;
1566
 
                        cairo_dock_get_current_desktop_and_viewport (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
1567
 
                        g_print (">>> on fixe le desklet sur le bureau (%d,%d,%d) (cur : %d,%d,%d)\n", iNumDesktop, iNumViewportX, iNumViewportY, iCurrentDesktop, iCurrentViewportX, iCurrentViewportY);
1568
 
                        
1569
 
                        iNumViewportX -= iCurrentViewportX;
1570
 
                        iNumViewportY -= iCurrentViewportY;
1571
 
                        
1572
 
                        g_print ("on le place en %d + %d\n", iNumViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL], iAbsolutePositionX);
1573
 
                        cairo_dock_move_xwindow_to_absolute_position (Xid, iNumDesktop, iNumViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] + iAbsolutePositionX, iNumViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] + iAbsolutePositionY);
1574
 
                }
1575
 
        }
1576
 
        pDesklet->bPositionLocked = pAttribute->bPositionLocked;
1577
 
        /*pDesklet->bNoInput = pAttribute->bNoInput;*/  // 2.1.4
1578
 
        pDesklet->fRotation = pAttribute->iRotation / 180. * G_PI ;
1579
 
        pDesklet->fDepthRotationY = pAttribute->iDepthRotationY / 180. * G_PI ;
1580
 
        pDesklet->fDepthRotationX = pAttribute->iDepthRotationX / 180. * G_PI ;
1581
 
        
1582
 
        g_free (pDesklet->cDecorationTheme);
1583
 
        pDesklet->cDecorationTheme = pAttribute->cDecorationTheme;
1584
 
        pAttribute->cDecorationTheme = NULL;
1585
 
        cairo_dock_free_desklet_decoration (pDesklet->pUserDecoration);
1586
 
        pDesklet->pUserDecoration = pAttribute->pUserDecoration;
1587
 
        pAttribute->pUserDecoration = NULL;
1588
 
        
1589
 
        //cd_debug ("%s (%dx%d ; %d)", __func__, pDesklet->iDesiredWidth, pDesklet->iDesiredHeight, pDesklet->iSidWriteSize);
1590
 
        if (pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0 && pDesklet->iSidWriteSize == 0)
1591
 
        {
1592
 
                cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDesklet));
1593
 
                _cairo_dock_load_desklet_decorations (pDesklet, pCairoContext);
1594
 
                cairo_destroy (pCairoContext);
1595
 
        }
1596
 
}
1597
 
 
1598
 
void cairo_dock_free_desklet (CairoDesklet *pDesklet)
1599
 
{
1600
 
        if (pDesklet == NULL)
1601
 
                return;
1602
 
 
1603
 
        if (pDesklet->iSidWriteSize != 0)
1604
 
                g_source_remove (pDesklet->iSidWriteSize);
1605
 
        if (pDesklet->iSidWritePosition != 0)
1606
 
                g_source_remove (pDesklet->iSidWritePosition);
1607
 
        if (pDesklet->iSidGrowUp != 0)
1608
 
                g_source_remove (pDesklet->iSidGrowUp);
1609
 
        if (pDesklet->container.iSidGLAnimation != 0)
1610
 
                g_source_remove (pDesklet->container.iSidGLAnimation);
1611
 
        if (pDesklet->iSidGradationOnEnter != 0)
1612
 
                g_source_remove (pDesklet->iSidGradationOnEnter);
1613
 
        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_STOP_DESKLET, pDesklet);
1614
 
        
1615
 
        cairo_dock_steal_interactive_widget_from_desklet (pDesklet);
1616
 
 
1617
 
        gtk_widget_destroy (pDesklet->container.pWidget);
1618
 
        pDesklet->container.pWidget = NULL;
1619
 
        
1620
 
        if (pDesklet->pRenderer != NULL)
1621
 
        {
1622
 
                if (pDesklet->pRenderer->free_data != NULL)
1623
 
                {
1624
 
                        pDesklet->pRenderer->free_data (pDesklet);
1625
 
                        pDesklet->pRendererData = NULL;
1626
 
                }
1627
 
        }
1628
 
        
1629
 
        if (pDesklet->icons != NULL)
1630
 
        {
1631
 
                g_list_foreach (pDesklet->icons, (GFunc) cairo_dock_free_icon, NULL);
1632
 
                g_list_free (pDesklet->icons);
1633
 
                pDesklet->icons = NULL;
1634
 
        }
1635
 
        
1636
 
        g_free (pDesklet->cDecorationTheme);
1637
 
        cairo_dock_free_desklet_decoration (pDesklet->pUserDecoration);
1638
 
        
1639
 
        if (pDesklet->pBackGroundSurface != NULL)
1640
 
                cairo_surface_destroy (pDesklet->pBackGroundSurface);
1641
 
        if (pDesklet->pForeGroundSurface != NULL)
1642
 
                cairo_surface_destroy (pDesklet->pForeGroundSurface);
1643
 
        if (pDesklet->iBackGroundTexture != 0)
1644
 
                _cairo_dock_delete_texture (pDesklet->iBackGroundTexture);
1645
 
        if (pDesklet->iForeGroundTexture != 0)
1646
 
                _cairo_dock_delete_texture (pDesklet->iForeGroundTexture);
1647
 
        
1648
 
        g_free(pDesklet);
1649
 
}
1650
 
 
1651
 
 
1652
 
 
1653
 
void cairo_dock_add_interactive_widget_to_desklet_full (GtkWidget *pInteractiveWidget, CairoDesklet *pDesklet, int iRightMargin)
1654
 
{
1655
 
        g_return_if_fail (pDesklet != NULL && pInteractiveWidget != NULL);
1656
 
        if (pDesklet->pInteractiveWidget != NULL || gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget)) != NULL)
1657
 
        {
1658
 
                cd_warning ("This desklet already has an interactive widget !");
1659
 
                return;
1660
 
        }
1661
 
        
1662
 
        //gtk_container_add (GTK_CONTAINER (pDesklet->container.pWidget), pInteractiveWidget);
1663
 
        GtkWidget *pHBox = gtk_hbox_new (FALSE, 0);
1664
 
        gtk_container_add (GTK_CONTAINER (pDesklet->container.pWidget), pHBox);
1665
 
        
1666
 
        gtk_box_pack_start (GTK_BOX (pHBox), pInteractiveWidget, TRUE, TRUE, 0);
1667
 
        pDesklet->pInteractiveWidget = pInteractiveWidget;
1668
 
        
1669
 
        if (iRightMargin != 0)
1670
 
        {
1671
 
                GtkWidget *pMarginBox = gtk_vbox_new (FALSE, 0);
1672
 
                gtk_widget_set (pMarginBox, "width-request", iRightMargin, NULL);
1673
 
                gtk_box_pack_start (GTK_BOX (pHBox), pMarginBox, FALSE, FALSE, 0);  // a tester ...
1674
 
        }
1675
 
        
1676
 
        gtk_widget_show_all (pHBox);
1677
 
}
1678
 
 
1679
 
void cairo_dock_set_desklet_margin (CairoDesklet *pDesklet, int iRightMargin)
1680
 
{
1681
 
        g_return_if_fail (pDesklet != NULL && pDesklet->pInteractiveWidget != NULL);
1682
 
        
1683
 
        GtkWidget *pHBox = gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget));
1684
 
        if (pHBox && pHBox != pDesklet->pInteractiveWidget)  // precaution.
1685
 
        {
1686
 
                GList *pChildList = gtk_container_get_children (GTK_CONTAINER (pHBox));
1687
 
                if (pChildList != NULL)
1688
 
                {
1689
 
                        if (pChildList->next != NULL)
1690
 
                        {
1691
 
                                GtkWidget *pMarginBox = GTK_WIDGET (pChildList->next->data);
1692
 
                                gtk_widget_set (pMarginBox, "width-request", iRightMargin, NULL);
1693
 
                        }
1694
 
                        else  // on rajoute le widget de la marge.
1695
 
                        {
1696
 
                                GtkWidget *pMarginBox = gtk_vbox_new (FALSE, 0);
1697
 
                                gtk_widget_set (pMarginBox, "width-request", iRightMargin, NULL);
1698
 
                                gtk_box_pack_start (GTK_BOX (pHBox), pMarginBox, FALSE, FALSE, 0);
1699
 
                        }
1700
 
                        g_list_free (pChildList);
1701
 
                }
1702
 
        }
1703
 
}
1704
 
 
1705
 
GtkWidget *cairo_dock_steal_interactive_widget_from_desklet (CairoDesklet *pDesklet)
1706
 
{
1707
 
        if (pDesklet == NULL)
1708
 
                return NULL;
1709
 
 
1710
 
        GtkWidget *pInteractiveWidget = pDesklet->pInteractiveWidget;
1711
 
        if (pInteractiveWidget != NULL)
1712
 
        {
1713
 
                pInteractiveWidget = cairo_dock_steal_widget_from_its_container (pInteractiveWidget);
1714
 
                pDesklet->pInteractiveWidget = NULL;
1715
 
                GtkWidget *pBox = gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget));
1716
 
                if (pBox != NULL)
1717
 
                        gtk_widget_destroy (pBox);
1718
 
        }
1719
 
        return pInteractiveWidget;
1720
 
}
1721
 
 
1722
 
 
1723
 
 
1724
 
void cairo_dock_hide_desklet (CairoDesklet *pDesklet)
1725
 
{
1726
 
        if (pDesklet)
1727
 
        {
1728
 
                pDesklet->bAllowMinimize = TRUE;
1729
 
                gtk_widget_hide (pDesklet->container.pWidget);
1730
 
        }
1731
 
}
1732
 
 
1733
 
void cairo_dock_show_desklet (CairoDesklet *pDesklet)
1734
 
{
1735
 
        if (pDesklet)
1736
 
        {
1737
 
                gtk_window_present(GTK_WINDOW(pDesklet->container.pWidget));
1738
 
                gtk_window_move (GTK_WINDOW(pDesklet->container.pWidget), pDesklet->container.iWindowPositionX, pDesklet->container.iWindowPositionY);  // sinon le WM le place n'importe ou.
1739
 
        }
1740
 
}
1741
 
 
1742
 
 
1743
 
static gboolean _cairo_dock_set_one_desklet_visible (CairoDesklet *pDesklet, CairoDockModuleInstance *pInstance, gpointer data)
1744
 
{
1745
 
        gboolean bOnWidgetLayerToo = GPOINTER_TO_INT (data);
1746
 
        Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
1747
 
        gboolean bIsOnWidgetLayer = cairo_dock_window_is_utility (Xid);
1748
 
        if (bOnWidgetLayerToo || ! bIsOnWidgetLayer)
1749
 
        {
1750
 
                cd_debug ("%s (%d)", __func__, Xid);
1751
 
                
1752
 
                if (bIsOnWidgetLayer)  // on le passe sur la couche visible.
1753
 
                        cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_NORMAL");
1754
 
                
1755
 
                gtk_window_set_keep_below (GTK_WINDOW (pDesklet->container.pWidget), FALSE);
1756
 
                
1757
 
                cairo_dock_show_desklet (pDesklet);
1758
 
        }
1759
 
        return FALSE;
1760
 
}
1761
 
void cairo_dock_set_all_desklets_visible (gboolean bOnWidgetLayerToo)
1762
 
{
1763
 
        cd_debug ("%s (%d)", __func__, bOnWidgetLayerToo);
1764
 
        cairo_dock_foreach_desklet (_cairo_dock_set_one_desklet_visible, GINT_TO_POINTER (bOnWidgetLayerToo));
1765
 
}
1766
 
 
1767
 
static gboolean _cairo_dock_set_one_desklet_visibility_to_default (CairoDesklet *pDesklet, CairoDockModuleInstance *pInstance, CairoDockMinimalAppletConfig *pMinimalConfig)
1768
 
{
1769
 
        GKeyFile *pKeyFile = cairo_dock_pre_read_module_instance_config (pInstance, pMinimalConfig);
1770
 
        g_key_file_free (pKeyFile);
1771
 
        
1772
 
        gtk_window_set_keep_below (GTK_WINDOW (pDesklet->container.pWidget), pMinimalConfig->deskletAttribute.iAccessibility == CAIRO_DESKLET_KEEP_BELOW);
1773
 
        gtk_window_set_keep_above (GTK_WINDOW (pDesklet->container.pWidget), pMinimalConfig->deskletAttribute.iAccessibility == CAIRO_DESKLET_KEEP_ABOVE);
1774
 
        
1775
 
        Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
1776
 
        if (pMinimalConfig->deskletAttribute.iAccessibility == CAIRO_DESKLET_ON_WIDGET_LAYER)
1777
 
                cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_UTILITY");
1778
 
        else if (pMinimalConfig->deskletAttribute.iAccessibility == CAIRO_DESKLET_RESERVE_SPACE)
1779
 
        {
1780
 
                if (! pDesklet->bSpaceReserved)
1781
 
                {
1782
 
                        cairo_dock_reserve_space_for_desklet (pDesklet, TRUE);
1783
 
                        pDesklet->bSpaceReserved = TRUE;
1784
 
                }
1785
 
                //cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_DOCK");
1786
 
        }
1787
 
        else
1788
 
                cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_NORMAL");
1789
 
        pDesklet->bAllowMinimize = FALSE;
1790
 
        
1791
 
        return FALSE;
1792
 
}
1793
 
void cairo_dock_set_desklets_visibility_to_default (void)
1794
 
{
1795
 
        CairoDockMinimalAppletConfig minimalConfig;
1796
 
        cairo_dock_foreach_desklet ((CairoDockForeachDeskletFunc) _cairo_dock_set_one_desklet_visibility_to_default, &minimalConfig);
1797
 
}
1798
 
 
1799
 
static gboolean _cairo_dock_test_one_desklet_Xid (CairoDesklet *pDesklet, CairoDockModuleInstance *pInstance, Window *pXid)
1800
 
{
1801
 
        return (GDK_WINDOW_XID (pDesklet->container.pWidget->window) == *pXid);
1802
 
}
1803
 
CairoDesklet *cairo_dock_get_desklet_by_Xid (Window Xid)
1804
 
{
1805
 
        CairoDockModuleInstance *pInstance = cairo_dock_foreach_desklet ((CairoDockForeachDeskletFunc) _cairo_dock_test_one_desklet_Xid, &Xid);
1806
 
        return (pInstance != NULL ? pInstance->pDesklet : NULL);
1807
 
}
1808
 
 
1809
 
 
1810
 
static gboolean _cairo_dock_grow_up_desklet (CairoDesklet *pDesklet)
1811
 
{
1812
 
        pDesklet->container.fRatio += .1;
1813
 
        gtk_widget_queue_draw (pDesklet->container.pWidget);
1814
 
        
1815
 
        if (pDesklet->container.fRatio >= 1.11)  // la derniere est a x1.1
1816
 
        {
1817
 
                pDesklet->container.fRatio = 1;
1818
 
                pDesklet->iSidGrowUp = 0;
1819
 
                return FALSE;
1820
 
        }
1821
 
        return TRUE;
1822
 
}
1823
 
void cairo_dock_zoom_out_desklet (CairoDesklet *pDesklet)
1824
 
{
1825
 
        g_return_if_fail (pDesklet != NULL);
1826
 
        pDesklet->container.fRatio = 0;
1827
 
        pDesklet->iSidGrowUp = g_timeout_add (50, (GSourceFunc) _cairo_dock_grow_up_desklet, (gpointer) pDesklet);
1828
 
}
1829
 
 
1830
 
 
1831
 
 
1832
 
void cairo_dock_reserve_space_for_desklet (CairoDesklet *pDesklet, gboolean bReserve)
1833
 
{
1834
 
        g_print ("%s (%d)\n", __func__, bReserve);
1835
 
        Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
1836
 
        int left=0, right=0, top=0, bottom=0;
1837
 
        int left_start_y=0, left_end_y=0, right_start_y=0, right_end_y=0, top_start_x=0, top_end_x=0, bottom_start_x=0, bottom_end_x=0;
1838
 
        int iHeight = pDesklet->container.iHeight, iWidth = pDesklet->container.iWidth;
1839
 
        int iX = pDesklet->container.iWindowPositionX, iY = pDesklet->container.iWindowPositionY;
1840
 
        if (bReserve)
1841
 
        {
1842
 
                int iTopOffset, iBottomOffset, iRightOffset, iLeftOffset;
1843
 
                iTopOffset = iY;
1844
 
                iBottomOffset = g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - 1 - (iY + iHeight);
1845
 
                iLeftOffset = iX;
1846
 
                iRightOffset = g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - 1 - (iX + iWidth);
1847
 
                
1848
 
                if (iBottomOffset < MIN (iLeftOffset, iRightOffset))  // en bas.
1849
 
                {
1850
 
                        bottom = iHeight + iBottomOffset;
1851
 
                        bottom_start_x = iX;
1852
 
                        bottom_end_x = iX + iWidth;
1853
 
                }
1854
 
                else if (iTopOffset < MIN (iLeftOffset, iRightOffset))  // en haut.
1855
 
                {
1856
 
                        top = iHeight + iTopOffset;
1857
 
                        top_start_x = iX;
1858
 
                        top_end_x = iX + iWidth;
1859
 
                }
1860
 
                else if (iLeftOffset < iRightOffset)  // a gauche.
1861
 
                {
1862
 
                        left = iWidth + iLeftOffset;
1863
 
                        left_start_y = iY;
1864
 
                        left_end_y = iY + iHeight;
1865
 
                }
1866
 
                else  // a droite.
1867
 
                {
1868
 
                        right = iWidth + iRightOffset;
1869
 
                        right_start_y = iY;
1870
 
                        right_end_y = iY + iHeight;
1871
 
                }
1872
 
        }
1873
 
 
1874
 
        cairo_dock_set_strut_partial (Xid, left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x);
1875
 
}