~ubuntu-branches/ubuntu/oneiric/cairo-dock/oneiric

« back to all changes in this revision

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

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
 
2
/*
 
3
** Login : <ctaf42@gmail.com>
 
4
** Started on  Sun Jan 27 18:35:38 2008 Cedric GESTES
 
5
** $Id$
 
6
**
 
7
** Author(s)
 
8
**  - Cedric GESTES <ctaf42@gmail.com>
 
9
**  - Fabrice REY
 
10
**
 
11
** Copyright (C) 2008 Cedric GESTES
 
12
** This program is free software; you can redistribute it and/or modify
 
13
** it under the terms of the GNU General Public License as published by
 
14
** the Free Software Foundation; either version 3 of the License, or
 
15
** (at your option) any later version.
 
16
**
 
17
** This program is distributed in the hope that it will be useful,
 
18
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
** GNU General Public License for more details.
 
21
**
 
22
** You should have received a copy of the GNU General Public License
 
23
** along with this program; if not, write to the Free Software
 
24
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
25
*/
 
26
 
 
27
#include <stdlib.h>
 
28
#include <string.h>
 
29
#include <math.h>
 
30
 
 
31
#include <gtk/gtkgl.h>
 
32
#include <GL/gl.h> 
 
33
#include <GL/glu.h> 
 
34
#include <GL/glx.h> 
 
35
#include <gdk/x11/gdkglx.h>
 
36
 
 
37
#include <gdk/gdkx.h>
 
38
#include "cairo-dock-draw.h"
 
39
#include "cairo-dock-modules.h"
 
40
#include "cairo-dock-dialog-manager.h"
 
41
#include "cairo-dock-icons.h"
 
42
#include "cairo-dock-config.h"
 
43
#include "cairo-dock-X-manager.h"
 
44
#include "cairo-dock-notifications.h"
 
45
#include "cairo-dock-log.h"
 
46
#include "cairo-dock-container.h"
 
47
#include "cairo-dock-X-utilities.h"
 
48
#include "cairo-dock-surface-factory.h"
 
49
#include "cairo-dock-backends-manager.h"
 
50
#include "cairo-dock-draw-opengl.h"
 
51
#include "cairo-dock-load.h"
 
52
#include "cairo-dock-animations.h"
 
53
#include "cairo-dock-internal-desklets.h"
 
54
#include "cairo-dock-gui-manager.h"
 
55
#include "cairo-dock-launcher-manager.h"
 
56
#include "cairo-dock-desklet-factory.h"
 
57
 
 
58
extern gboolean g_bUseOpenGL;
 
59
extern CairoDockDesktopGeometry g_desktopGeometry;
 
60
 
 
61
static void _cairo_dock_reserve_space_for_desklet (CairoDesklet *pDesklet, gboolean bReserve);
 
62
static void on_drag_data_received_desklet (GtkWidget *pWidget, GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data, guint info, guint t, CairoDesklet *pDesklet);
 
63
 
 
64
  ///////////////
 
65
 /// SIGNALS ///
 
66
///////////////
 
67
 
 
68
static gboolean on_expose_desklet(GtkWidget *pWidget,
 
69
        GdkEventExpose *pExpose,
 
70
        CairoDesklet *pDesklet)
 
71
{
 
72
        if (pDesklet->iDesiredWidth != 0 && pDesklet->iDesiredHeight != 0 && (pDesklet->iKnownWidth != pDesklet->iDesiredWidth || pDesklet->iKnownHeight != pDesklet->iDesiredHeight))
 
73
        {
 
74
                //g_print ("on saute le dessin\n");
 
75
                if (g_bUseOpenGL)
 
76
                {
 
77
                        // dessiner la fausse transparence.
 
78
                }
 
79
                else
 
80
                {
 
81
                        cairo_t *pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDesklet));
 
82
                        cairo_destroy (pCairoContext);
 
83
                }
 
84
                return FALSE;
 
85
        }
 
86
        
 
87
        if (g_bUseOpenGL && pDesklet->pRenderer && pDesklet->pRenderer->render_opengl)
 
88
        {
 
89
                GdkGLContext *pGlContext = gtk_widget_get_gl_context (pDesklet->container.pWidget);
 
90
                GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (pDesklet->container.pWidget);
 
91
                if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
 
92
                        return FALSE;
 
93
                
 
94
                glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
95
                glLoadIdentity ();
 
96
                
 
97
                cairo_dock_apply_desktop_background_opengl (CAIRO_CONTAINER (pDesklet));
 
98
                
 
99
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_RENDER_DESKLET, pDesklet, NULL);
 
100
                
 
101
                if (gdk_gl_drawable_is_double_buffered (pGlDrawable))
 
102
                        gdk_gl_drawable_swap_buffers (pGlDrawable);
 
103
                else
 
104
                        glFlush ();
 
105
                gdk_gl_drawable_gl_end (pGlDrawable);
 
106
        }
 
107
        else
 
108
        {
 
109
                cairo_t *pCairoContext = cairo_dock_create_drawing_context_on_container (CAIRO_CONTAINER (pDesklet));
 
110
                
 
111
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_RENDER_DESKLET, pDesklet, pCairoContext);
 
112
                
 
113
                cairo_destroy (pCairoContext);
 
114
        }
 
115
        
 
116
        return FALSE;
 
117
}
 
118
 
 
119
static void _cairo_dock_set_desklet_input_shape (CairoDesklet *pDesklet)
 
120
{
 
121
        gtk_widget_input_shape_combine_mask (pDesklet->container.pWidget,
 
122
                NULL,
 
123
                0,
 
124
                0);
 
125
        if (pDesklet->bNoInput)
 
126
        {
 
127
                GdkBitmap *pShapeBitmap = (GdkBitmap*) gdk_pixmap_new (NULL,
 
128
                        pDesklet->container.iWidth,
 
129
                        pDesklet->container.iHeight,
 
130
                        1);
 
131
                
 
132
                cairo_t *pCairoContext = gdk_cairo_create (pShapeBitmap);
 
133
                cairo_set_source_rgba (pCairoContext, 0.0f, 0.0f, 0.0f, 0.0f);
 
134
                cairo_set_operator (pCairoContext, CAIRO_OPERATOR_SOURCE);
 
135
                cairo_paint (pCairoContext);
 
136
                cairo_set_source_rgba (pCairoContext, 1., 1., 1., 1.);
 
137
                cairo_rectangle (pCairoContext,
 
138
                        pDesklet->container.iWidth - myDesklets.iDeskletButtonSize,
 
139
                        pDesklet->container.iHeight - myDesklets.iDeskletButtonSize,
 
140
                        myDesklets.iDeskletButtonSize,
 
141
                        myDesklets.iDeskletButtonSize);
 
142
                cairo_fill (pCairoContext);
 
143
                cairo_destroy (pCairoContext);
 
144
                gtk_widget_input_shape_combine_mask (pDesklet->container.pWidget,
 
145
                        pShapeBitmap,
 
146
                        0,
 
147
                        0);
 
148
                g_object_unref (pShapeBitmap);
 
149
                //g_print ("input shape : %dx%d\n", pDesklet->container.iWidth, pDesklet->container.iHeight);
 
150
        }
 
151
}
 
152
 
 
153
static gboolean _cairo_dock_write_desklet_size (CairoDesklet *pDesklet)
 
154
{
 
155
        if ((pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0) && pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
 
156
        {
 
157
                gchar *cSize = g_strdup_printf ("%d;%d", pDesklet->container.iWidth, pDesklet->container.iHeight);
 
158
                cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
 
159
                        G_TYPE_STRING, "Desklet", "size", cSize,
 
160
                        G_TYPE_INVALID);
 
161
                g_free (cSize);
 
162
                cairo_dock_update_desklet_size_in_gui (pDesklet->pIcon->pModuleInstance,
 
163
                        pDesklet->container.iWidth,
 
164
                        pDesklet->container.iHeight);
 
165
        }
 
166
        pDesklet->iSidWriteSize = 0;
 
167
        pDesklet->iKnownWidth = pDesklet->container.iWidth;
 
168
        pDesklet->iKnownHeight = pDesklet->container.iHeight;
 
169
        if (((pDesklet->iDesiredWidth != 0 || pDesklet->iDesiredHeight != 0) && pDesklet->iDesiredWidth == pDesklet->container.iWidth && pDesklet->iDesiredHeight == pDesklet->container.iHeight) || (pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0))
 
170
        {
 
171
                pDesklet->iDesiredWidth = 0;
 
172
                pDesklet->iDesiredHeight = 0;
 
173
                
 
174
                cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDesklet));
 
175
                cairo_dock_load_desklet_decorations (pDesklet);
 
176
                cairo_destroy (pCairoContext);
 
177
                
 
178
                if (pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
 
179
                {
 
180
                        // on recalcule la vue du desklet a la nouvelle dimension.
 
181
                        CairoDeskletRenderer *pRenderer = pDesklet->pRenderer;
 
182
                        if (pRenderer)
 
183
                        {
 
184
                                // on calcule les icones et les parametres internes de la vue.
 
185
                                if (pRenderer->calculate_icons != NULL)
 
186
                                        pRenderer->calculate_icons (pDesklet);
 
187
                                
 
188
                                // on recharge l'icone principale.
 
189
                                Icon* pIcon = pDesklet->pIcon;
 
190
                                if (pIcon)
 
191
                                {
 
192
                                        pIcon->iImageWidth = pIcon->fWidth;
 
193
                                        pIcon->iImageHeight = pIcon->fHeight;
 
194
                                        if (pIcon->iImageWidth > 0)
 
195
                                                cairo_dock_load_icon_buffers (pIcon, CAIRO_CONTAINER (pDesklet));  // pas de trigger, car on veut pouvoir associer un contexte a l'icone principale tout de suite.
 
196
                                }
 
197
                                
 
198
                                // on recharge chaque icone.
 
199
                                GList* ic;
 
200
                                for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
 
201
                                {
 
202
                                        pIcon = ic->data;
 
203
                                        if ((int)pIcon->fWidth != pIcon->iImageWidth || (int)pIcon->fHeight != pIcon->iImageHeight)
 
204
                                        {
 
205
                                                pIcon->iImageWidth = pIcon->fWidth;
 
206
                                                pIcon->iImageHeight = pIcon->fHeight;
 
207
                                                cairo_dock_trigger_load_icon_buffers (pIcon, CAIRO_CONTAINER (pDesklet));
 
208
                                        }
 
209
                                }
 
210
                                
 
211
                                // on recharge les buffers de la vue.
 
212
                                if (pRenderer->load_data != NULL)
 
213
                                        pRenderer->load_data (pDesklet);
 
214
                        }
 
215
                        
 
216
                        // on recharge le module associe.
 
217
                        cairo_dock_reload_module_instance (pDesklet->pIcon->pModuleInstance, FALSE);
 
218
                        
 
219
                        gtk_widget_queue_draw (pDesklet->container.pWidget);  // sinon on ne redessine que l'interieur.
 
220
                }
 
221
                
 
222
                Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
 
223
                if (pDesklet->bSpaceReserved)  // l'espace est reserve, on reserve la nouvelle taille.
 
224
                {
 
225
                        _cairo_dock_reserve_space_for_desklet (pDesklet, TRUE);
 
226
                }
 
227
        }
 
228
        
 
229
        //g_print ("iWidth <- %d;iHeight <- %d ; (%dx%d) (%x)\n", pDesklet->container.iWidth, pDesklet->container.iHeight, pDesklet->iKnownWidth, pDesklet->iKnownHeight, pDesklet->pIcon);
 
230
        return FALSE;
 
231
}
 
232
static gboolean _cairo_dock_write_desklet_position (CairoDesklet *pDesklet)
 
233
{
 
234
        if (pDesklet->pIcon != NULL && pDesklet->pIcon->pModuleInstance != NULL)
 
235
        {
 
236
                int iRelativePositionX = (pDesklet->container.iWindowPositionX + pDesklet->container.iWidth/2 <= g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL]/2 ? pDesklet->container.iWindowPositionX : pDesklet->container.iWindowPositionX - g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL]);
 
237
                int iRelativePositionY = (pDesklet->container.iWindowPositionY + pDesklet->container.iHeight/2 <= g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]/2 ? pDesklet->container.iWindowPositionY : pDesklet->container.iWindowPositionY - g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
 
238
                
 
239
                Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
 
240
                int iNumDesktop = -1;
 
241
                if (! cairo_dock_xwindow_is_sticky (Xid))
 
242
                {
 
243
                        int iDesktop = cairo_dock_get_xwindow_desktop (Xid);
 
244
                        int iGlobalPositionX, iGlobalPositionY, iWidthExtent, iHeightExtent;
 
245
                        cairo_dock_get_xwindow_geometry (Xid, &iGlobalPositionX, &iGlobalPositionY, &iWidthExtent, &iHeightExtent);
 
246
                        if (iGlobalPositionX < 0)
 
247
                                iGlobalPositionX += g_desktopGeometry.iNbViewportX * g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
248
                        if (iGlobalPositionY < 0)
 
249
                                iGlobalPositionY += g_desktopGeometry.iNbViewportY * g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
250
                        
 
251
                        int iViewportX = iGlobalPositionX / g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
252
                        int iViewportY = iGlobalPositionY / g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
253
                        
 
254
                        int iCurrentDesktop, iCurrentViewportX, iCurrentViewportY;
 
255
                        cairo_dock_get_current_desktop_and_viewport (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
 
256
                        
 
257
                        iViewportX += iCurrentViewportX;
 
258
                        if (iViewportX >= g_desktopGeometry.iNbViewportX)
 
259
                                iViewportX -= g_desktopGeometry.iNbViewportX;
 
260
                        iViewportY += iCurrentViewportY;
 
261
                        if (iViewportY >= g_desktopGeometry.iNbViewportY)
 
262
                                iViewportY -= g_desktopGeometry.iNbViewportY;
 
263
                        //g_print ("position : %d,%d,%d / %d,%d,%d\n", iDesktop, iViewportX, iViewportY, iCurrentDesktop, iCurrentViewportX, iCurrentViewportY);
 
264
                        
 
265
                        iNumDesktop = iDesktop * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY + iViewportX * g_desktopGeometry.iNbViewportY + iViewportY;
 
266
                        //g_print ("desormais on place le desklet sur le bureau (%d,%d,%d)\n", iDesktop, iViewportX, iViewportY);
 
267
                }
 
268
                
 
269
                cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
 
270
                        G_TYPE_INT, "Desklet", "x position", iRelativePositionX,
 
271
                        G_TYPE_INT, "Desklet", "y position", iRelativePositionY,
 
272
                        G_TYPE_INT, "Desklet", "num desktop", iNumDesktop,
 
273
                        G_TYPE_INVALID);
 
274
                cairo_dock_update_desklet_position_in_gui (pDesklet->pIcon->pModuleInstance,
 
275
                        iRelativePositionX,
 
276
                        iRelativePositionY);
 
277
        }
 
278
        
 
279
        if (pDesklet->bSpaceReserved)  // l'espace est reserve, on reserve a la nouvelle position.
 
280
        {
 
281
                _cairo_dock_reserve_space_for_desklet (pDesklet, TRUE);
 
282
        }
 
283
        if (pDesklet->pIcon && cairo_dock_icon_has_dialog (pDesklet->pIcon))
 
284
        {
 
285
                cairo_dock_replace_all_dialogs ();
 
286
        }
 
287
        pDesklet->iSidWritePosition = 0;
 
288
        return FALSE;
 
289
}
 
290
static gboolean on_configure_desklet (GtkWidget* pWidget,
 
291
        GdkEventConfigure* pEvent,
 
292
        CairoDesklet *pDesklet)
 
293
{
 
294
        //g_print (" >>>>>>>>> %s (%dx%d, %d;%d)", __func__, pEvent->width, pEvent->height, pEvent->x, pEvent->y);
 
295
        if (pDesklet->container.iWidth != pEvent->width || pDesklet->container.iHeight != pEvent->height)
 
296
        {
 
297
                if ((pEvent->width < pDesklet->container.iWidth || pEvent->height < pDesklet->container.iHeight) && (pDesklet->iDesiredWidth != 0 && pDesklet->iDesiredHeight != 0))
 
298
                {
 
299
                        gdk_window_resize (pDesklet->container.pWidget->window,
 
300
                                pDesklet->iDesiredWidth,
 
301
                                pDesklet->iDesiredHeight);
 
302
                }
 
303
                
 
304
                pDesklet->container.iWidth = pEvent->width;
 
305
                pDesklet->container.iHeight = pEvent->height;
 
306
                
 
307
                if (g_bUseOpenGL)
 
308
                {
 
309
                        GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
 
310
                        GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
 
311
                        GLsizei w = pEvent->width;
 
312
                        GLsizei h = pEvent->height;
 
313
                        if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
 
314
                                return FALSE;
 
315
                        
 
316
                        glViewport(0, 0, w, h);
 
317
                        
 
318
                        cairo_dock_set_perspective_view (CAIRO_CONTAINER (pDesklet));
 
319
                        
 
320
                        gdk_gl_drawable_gl_end (pGlDrawable);
 
321
                }
 
322
                
 
323
                if (pDesklet->bNoInput)
 
324
                        _cairo_dock_set_desklet_input_shape (pDesklet);
 
325
                
 
326
                if (pDesklet->iSidWriteSize != 0)
 
327
                {
 
328
                        g_source_remove (pDesklet->iSidWriteSize);
 
329
                }
 
330
                pDesklet->iSidWriteSize = g_timeout_add (500, (GSourceFunc) _cairo_dock_write_desklet_size, (gpointer) pDesklet);
 
331
        }
 
332
        
 
333
        int x = pEvent->x, y = pEvent->y;
 
334
        //g_print ("new desklet position : (%d;%d)", x, y);
 
335
        while (x < 0)  // on passe au referentiel du viewport de la fenetre; inutile de connaitre sa position, puisqu'ils ont tous la meme taille.
 
336
                x += g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
337
        while (x >= g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL])
 
338
                x -= g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
339
        while (y < 0)
 
340
                y += g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
341
        while (y >= g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
 
342
                y -= g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
343
        //g_print (" => (%d;%d)\n", x, y);
 
344
        if (pDesklet->container.iWindowPositionX != x || pDesklet->container.iWindowPositionY != y)
 
345
        {
 
346
                pDesklet->container.iWindowPositionX = x;
 
347
                pDesklet->container.iWindowPositionY = y;
 
348
 
 
349
                if (pDesklet->iSidWritePosition != 0)
 
350
                {
 
351
                        g_source_remove (pDesklet->iSidWritePosition);
 
352
                }
 
353
                pDesklet->iSidWritePosition = g_timeout_add (500, (GSourceFunc) _cairo_dock_write_desklet_position, (gpointer) pDesklet);
 
354
        }
 
355
        pDesklet->moving = FALSE;
 
356
 
 
357
        return FALSE;
 
358
}
 
359
 
 
360
static gboolean on_scroll_desklet (GtkWidget* pWidget,
 
361
        GdkEventScroll* pScroll,
 
362
        CairoDesklet *pDesklet)
 
363
{
 
364
        //g_print ("scroll\n");
 
365
        if (! (pScroll->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)))
 
366
        {
 
367
                Icon *icon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
 
368
                if (icon != NULL)
 
369
                {
 
370
                        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_SCROLL_ICON, icon, pDesklet, pScroll->direction);
 
371
                }
 
372
        }
 
373
        return FALSE;
 
374
}
 
375
 
 
376
static gboolean on_unmap_desklet (GtkWidget* pWidget,
 
377
        GdkEvent *pEvent,
 
378
        CairoDesklet *pDesklet)
 
379
{
 
380
        cd_debug ("unmap desklet (bAllowMinimize:%d)\n", pDesklet->bAllowMinimize);
 
381
        Window Xid = GDK_WINDOW_XID (pWidget->window);
 
382
        if (cairo_dock_window_is_utility (Xid))  // sur la couche des widgets, on ne fait rien.
 
383
                return FALSE;
 
384
        if (! pDesklet->bAllowMinimize)
 
385
        {
 
386
                if (pDesklet->pUnmapTimer)
 
387
                {
 
388
                        double fElapsedTime = g_timer_elapsed (pDesklet->pUnmapTimer, NULL);
 
389
                        cd_debug ("fElapsedTime : %fms\n", fElapsedTime);
 
390
                        g_timer_destroy (pDesklet->pUnmapTimer);
 
391
                        pDesklet->pUnmapTimer = NULL;
 
392
                        if (fElapsedTime < .2)
 
393
                                return TRUE;
 
394
                }
 
395
                gtk_window_present (GTK_WINDOW (pWidget));
 
396
        }
 
397
        else
 
398
        {
 
399
                pDesklet->bAllowMinimize = FALSE;
 
400
                if (pDesklet->pUnmapTimer == NULL)
 
401
                        pDesklet->pUnmapTimer = g_timer_new ();  // starts the timer.
 
402
        }
 
403
        return TRUE;  // stops other handlers from being invoked for the event.
 
404
}
 
405
 
 
406
static gboolean on_button_press_desklet(GtkWidget *pWidget,
 
407
        GdkEventButton *pButton,
 
408
        CairoDesklet *pDesklet)
 
409
{
 
410
        if (pButton->button == 1)  // clic gauche.
 
411
        {
 
412
                if (pButton->type == GDK_BUTTON_PRESS)
 
413
                {
 
414
                        pDesklet->bClicked = TRUE;
 
415
                        if (cairo_dock_desklet_is_free (pDesklet))
 
416
                        {
 
417
                                pDesklet->container.iMouseX = pButton->x;  // pour le deplacement manuel.
 
418
                                pDesklet->container.iMouseY = pButton->y;
 
419
                                
 
420
                                if (pButton->x < myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)
 
421
                                        pDesklet->rotating = TRUE;
 
422
                                else if (pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)
 
423
                                        pDesklet->retaching = TRUE;
 
424
                                else if (pButton->x > (pDesklet->container.iWidth - myDesklets.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDesklets.iDeskletButtonSize)/2 && pButton->y < myDesklets.iDeskletButtonSize)
 
425
                                        pDesklet->rotatingY = TRUE;
 
426
                                else if (pButton->y > (pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)/2 && pButton->y < (pDesklet->container.iHeight + myDesklets.iDeskletButtonSize)/2 && pButton->x < myDesklets.iDeskletButtonSize)
 
427
                                        pDesklet->rotatingX = TRUE;
 
428
                                else
 
429
                                        pDesklet->time = pButton->time;
 
430
                        }
 
431
                        if (pDesklet->bAllowNoClickable && pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y > pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)
 
432
                                pDesklet->making_transparent = TRUE;
 
433
                }
 
434
                else if (pButton->type == GDK_BUTTON_RELEASE)
 
435
                {
 
436
                        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).
 
437
                        {
 
438
                                return FALSE;
 
439
                        }
 
440
                        pDesklet->bClicked = FALSE;
 
441
                        cd_debug ("GDK_BUTTON_RELEASE");
 
442
                        if (pDesklet->moving)
 
443
                        {
 
444
                                pDesklet->moving = FALSE;
 
445
                        }
 
446
                        else if (pDesklet->rotating)
 
447
                        {
 
448
                                pDesklet->rotating = FALSE;
 
449
                                cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
 
450
                                        G_TYPE_INT, "Desklet", "rotation", (int) (pDesklet->fRotation / G_PI * 180.),
 
451
                                        G_TYPE_INVALID);
 
452
                                gtk_widget_queue_draw (pDesklet->container.pWidget);
 
453
                        }
 
454
                        else if (pDesklet->retaching)
 
455
                        {
 
456
                                pDesklet->retaching = FALSE;
 
457
                                if (pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)  // on verifie qu'on est encore dedans.
 
458
                                {
 
459
                                        Icon *icon = pDesklet->pIcon;
 
460
                                        g_return_val_if_fail (CAIRO_DOCK_IS_APPLET (icon), FALSE);
 
461
                                        cairo_dock_detach_module_instance (icon->pModuleInstance);
 
462
                                        return TRUE;  // interception du signal.
 
463
                                }
 
464
                        }
 
465
                        else if (pDesklet->making_transparent)
 
466
                        {
 
467
                                cd_debug ("pDesklet->making_transparent\n");
 
468
                                pDesklet->making_transparent = FALSE;
 
469
                                if (pButton->x > pDesklet->container.iWidth - myDesklets.iDeskletButtonSize && pButton->y > pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)  // on verifie qu'on est encore dedans.
 
470
                                {
 
471
                                        Icon *icon = pDesklet->pIcon;
 
472
                                        g_return_val_if_fail (CAIRO_DOCK_IS_APPLET (icon), FALSE);
 
473
                                        pDesklet->bNoInput = ! pDesklet->bNoInput;
 
474
                                        cd_debug ("no input : %d (%s)\n", pDesklet->bNoInput, icon->pModuleInstance->cConfFilePath);
 
475
                                        cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
 
476
                                                G_TYPE_BOOLEAN, "Desklet", "no input", pDesklet->bNoInput,
 
477
                                                G_TYPE_INVALID);
 
478
                                        _cairo_dock_set_desklet_input_shape (pDesklet);
 
479
                                        gtk_widget_queue_draw (pDesklet->container.pWidget);
 
480
                                        if (pDesklet->bNoInput)
 
481
                                                cairo_dock_allow_widget_to_receive_data (pDesklet->container.pWidget, G_CALLBACK (on_drag_data_received_desklet), pDesklet);
 
482
                                        else
 
483
                                                cairo_dock_disallow_widget_to_receive_data (pDesklet->container.pWidget);
 
484
                                }
 
485
                        }
 
486
                        else if (pDesklet->rotatingY)
 
487
                        {
 
488
                                pDesklet->rotatingY = FALSE;
 
489
                                cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
 
490
                                        G_TYPE_INT, "Desklet", "depth rotation y", (int) (pDesklet->fDepthRotationY / G_PI * 180.),
 
491
                                        G_TYPE_INVALID);
 
492
                                gtk_widget_queue_draw (pDesklet->container.pWidget);
 
493
                        }
 
494
                        else if (pDesklet->rotatingX)
 
495
                        {
 
496
                                pDesklet->rotatingX = FALSE;
 
497
                                cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
 
498
                                        G_TYPE_INT, "Desklet", "depth rotation x", (int) (pDesklet->fDepthRotationX / G_PI * 180.),
 
499
                                        G_TYPE_INVALID);
 
500
                                gtk_widget_queue_draw (pDesklet->container.pWidget);
 
501
                        }
 
502
                        else
 
503
                        {
 
504
                                Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
 
505
                                cairo_dock_notify (CAIRO_DOCK_CLICK_ICON, pClickedIcon, pDesklet, pButton->state);
 
506
                        }
 
507
                }
 
508
                else if (pButton->type == GDK_2BUTTON_PRESS)
 
509
                {
 
510
                        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))
 
511
                        {
 
512
                                Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
 
513
                                cairo_dock_notify (CAIRO_DOCK_DOUBLE_CLICK_ICON, pClickedIcon, pDesklet);
 
514
                        }
 
515
                }
 
516
        }
 
517
        else if (pButton->button == 3 && pButton->type == GDK_BUTTON_PRESS)  // clique droit.
 
518
        {
 
519
                Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
 
520
                GtkWidget *menu = cairo_dock_build_menu (pClickedIcon, CAIRO_CONTAINER (pDesklet));  // genere un CAIRO_DOCK_BUILD_ICON_MENU.
 
521
                gtk_widget_show_all (menu);
 
522
                gtk_menu_popup (GTK_MENU (menu),
 
523
                        NULL,
 
524
                        NULL,
 
525
                        NULL,
 
526
                        NULL,
 
527
                        1,
 
528
                        gtk_get_current_event_time ());
 
529
                pDesklet->container.bInside = FALSE;
 
530
                ///pDesklet->iGradationCount = 0;  // on force le fond a redevenir transparent.
 
531
                gtk_widget_queue_draw (pDesklet->container.pWidget);
 
532
        }
 
533
        else if (pButton->button == 2 && pButton->type == GDK_BUTTON_PRESS)  // clique milieu.
 
534
        {
 
535
                if (pButton->x < myDesklets.iDeskletButtonSize && pButton->y < myDesklets.iDeskletButtonSize)
 
536
                {
 
537
                        pDesklet->fRotation = 0.;
 
538
                        gtk_widget_queue_draw (pDesklet->container.pWidget);
 
539
                        cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
 
540
                                G_TYPE_INT, "Desklet", "rotation", 0,
 
541
                                G_TYPE_INVALID);
 
542
                }
 
543
                else if (pButton->x > (pDesklet->container.iWidth - myDesklets.iDeskletButtonSize)/2 && pButton->x < (pDesklet->container.iWidth + myDesklets.iDeskletButtonSize)/2 && pButton->y < myDesklets.iDeskletButtonSize)
 
544
                {
 
545
                        pDesklet->fDepthRotationY = 0.;
 
546
                        gtk_widget_queue_draw (pDesklet->container.pWidget);
 
547
                        cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
 
548
                                G_TYPE_INT, "Desklet", "depth rotation y", 0,
 
549
                                G_TYPE_INVALID);
 
550
                }
 
551
                else if (pButton->y > (pDesklet->container.iHeight - myDesklets.iDeskletButtonSize)/2 && pButton->y < (pDesklet->container.iHeight + myDesklets.iDeskletButtonSize)/2 && pButton->x < myDesklets.iDeskletButtonSize)
 
552
                {
 
553
                        pDesklet->fDepthRotationX = 0.;
 
554
                        gtk_widget_queue_draw (pDesklet->container.pWidget);
 
555
                        cairo_dock_update_conf_file (pDesklet->pIcon->pModuleInstance->cConfFilePath,
 
556
                                G_TYPE_INT, "Desklet", "depth rotation x", 0,
 
557
                                G_TYPE_INVALID);
 
558
                }
 
559
                else
 
560
                {
 
561
                        cairo_dock_notify (CAIRO_DOCK_MIDDLE_CLICK_ICON, pDesklet->pIcon, pDesklet);
 
562
                }
 
563
        }
 
564
        return FALSE;
 
565
}
 
566
 
 
567
static void on_drag_data_received_desklet (GtkWidget *pWidget, GdkDragContext *dc, gint x, gint y, GtkSelectionData *selection_data, guint info, guint t, CairoDesklet *pDesklet)
 
568
{
 
569
        //g_print ("%s (%dx%d)\n", __func__, x, y);
 
570
        
 
571
        //\_________________ On recupere l'URI.
 
572
        gchar *cReceivedData = (gchar *) selection_data->data;  // gtk_selection_data_get_text
 
573
        g_return_if_fail (cReceivedData != NULL);
 
574
        int length = strlen (cReceivedData);
 
575
        if (cReceivedData[length-1] == '\n')
 
576
                cReceivedData[--length] = '\0';  // on vire le retour chariot final.
 
577
        if (cReceivedData[length-1] == '\r')
 
578
                cReceivedData[--length] = '\0';
 
579
        
 
580
        pDesklet->container.iMouseX = x;
 
581
        pDesklet->container.iMouseY = y;
 
582
        Icon *pClickedIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
 
583
        cairo_dock_notify_drop_data (cReceivedData, pClickedIcon, 0, CAIRO_CONTAINER (pDesklet));
 
584
}
 
585
 
 
586
static gboolean on_motion_notify_desklet(GtkWidget *pWidget,
 
587
        GdkEventMotion* pMotion,
 
588
        CairoDesklet *pDesklet)
 
589
{
 
590
        if (pMotion->state & GDK_BUTTON1_MASK && cairo_dock_desklet_is_free (pDesklet))
 
591
        {
 
592
                cd_debug ("root : %d;%d", (int) pMotion->x_root, (int) pMotion->y_root);
 
593
                /*pDesklet->moving = TRUE;
 
594
                gtk_window_move (GTK_WINDOW (pWidget),
 
595
                        pMotion->x_root + pDesklet->diff_x,
 
596
                        pMotion->y_root + pDesklet->diff_y);*/
 
597
        }
 
598
        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).
 
599
        {
 
600
                pDesklet->container.iMouseX = pMotion->x;
 
601
                pDesklet->container.iMouseY = pMotion->y;
 
602
                gboolean bStartAnimation = FALSE;
 
603
                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_MOUSE_MOVED, pDesklet, &bStartAnimation);
 
604
                if (bStartAnimation)
 
605
                        cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
 
606
        }
 
607
        
 
608
        if (pDesklet->rotating && cairo_dock_desklet_is_free (pDesklet))
 
609
        {
 
610
                double alpha = atan2 (pDesklet->container.iHeight, - pDesklet->container.iWidth);
 
611
                pDesklet->fRotation = alpha - atan2 (.5*pDesklet->container.iHeight - pMotion->y, pMotion->x - .5*pDesklet->container.iWidth);
 
612
                while (pDesklet->fRotation > G_PI)
 
613
                        pDesklet->fRotation -= 2 * G_PI;
 
614
                while (pDesklet->fRotation <= - G_PI)
 
615
                        pDesklet->fRotation += 2 * G_PI;
 
616
                gtk_widget_queue_draw(pDesklet->container.pWidget);
 
617
        }
 
618
        else if (pDesklet->rotatingY && cairo_dock_desklet_is_free (pDesklet))
 
619
        {
 
620
                pDesklet->fDepthRotationY = G_PI * (pMotion->x - .5*pDesklet->container.iWidth) / pDesklet->container.iWidth;
 
621
                gtk_widget_queue_draw(pDesklet->container.pWidget);
 
622
        }
 
623
        else if (pDesklet->rotatingX && cairo_dock_desklet_is_free (pDesklet))
 
624
        {
 
625
                pDesklet->fDepthRotationX = G_PI * (pMotion->y - .5*pDesklet->container.iHeight) / pDesklet->container.iHeight;
 
626
                gtk_widget_queue_draw(pDesklet->container.pWidget);
 
627
        }
 
628
        else if (pMotion->state & GDK_BUTTON1_MASK && cairo_dock_desklet_is_free (pDesklet) && ! pDesklet->moving)
 
629
        {
 
630
                gtk_window_begin_move_drag (GTK_WINDOW (gtk_widget_get_toplevel (pWidget)),
 
631
                        1/*pButton->button*/,
 
632
                        pMotion->x_root/*pButton->x_root*/,
 
633
                        pMotion->y_root/*pButton->y_root*/,
 
634
                        pDesklet->time/*pButton->time*/);
 
635
                pDesklet->moving = TRUE;
 
636
        }
 
637
        else
 
638
        {
 
639
                gboolean bStartAnimation = FALSE;
 
640
                Icon *pIcon = cairo_dock_find_clicked_icon_in_desklet (pDesklet);
 
641
                if (pIcon != NULL)
 
642
                {
 
643
                        if (! pIcon->bPointed)
 
644
                        {
 
645
                                Icon *pPointedIcon = cairo_dock_get_pointed_icon (pDesklet->icons);
 
646
                                if (pPointedIcon != NULL)
 
647
                                        pPointedIcon->bPointed = FALSE;
 
648
                                pIcon->bPointed = TRUE;
 
649
                                
 
650
                                //g_print ("on survole %s\n", pIcon->cName);
 
651
                                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_ENTER_ICON, pIcon, pDesklet, &bStartAnimation);
 
652
                        }
 
653
                }
 
654
                else
 
655
                {
 
656
                        Icon *pPointedIcon = cairo_dock_get_pointed_icon (pDesklet->icons);
 
657
                        if (pPointedIcon != NULL)
 
658
                        {
 
659
                                pPointedIcon->bPointed = FALSE;
 
660
                                
 
661
                                //g_print ("kedal\n");
 
662
                                cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_ENTER_ICON, pPointedIcon, pDesklet, &bStartAnimation);
 
663
 
 
664
                        }
 
665
                }
 
666
                if (bStartAnimation)
 
667
                {
 
668
                        cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
 
669
                }
 
670
        }
 
671
        
 
672
        gdk_device_get_state (pMotion->device, pMotion->window, NULL, NULL);  // pour recevoir d'autres MotionNotify.
 
673
        return FALSE;
 
674
}
 
675
 
 
676
 
 
677
static gboolean on_focus_in_out_desklet(GtkWidget *widget,
 
678
        GdkEventFocus *event,
 
679
        CairoDesklet *pDesklet)
 
680
{
 
681
        gtk_widget_queue_draw(pDesklet->container.pWidget);
 
682
        return FALSE;
 
683
}
 
684
 
 
685
static gboolean on_enter_desklet (GtkWidget* pWidget,
 
686
        GdkEventCrossing* pEvent,
 
687
        CairoDesklet *pDesklet)
 
688
{
 
689
        //g_print ("%s (%d)\n", __func__, pDesklet->container.bInside);
 
690
        if (! pDesklet->container.bInside)  // avant on etait dehors, on redessine donc.
 
691
        {
 
692
                pDesklet->container.bInside = TRUE;
 
693
                gtk_widget_queue_draw (pWidget);  // redessin des boutons.
 
694
                
 
695
                ///if (g_bUseOpenGL)
 
696
                {
 
697
                        gboolean bStartAnimation = FALSE;
 
698
                        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_ENTER_DESKLET, pDesklet, &bStartAnimation);
 
699
                        if (bStartAnimation)
 
700
                                cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
 
701
                }
 
702
        }
 
703
        return FALSE;
 
704
}
 
705
static gboolean on_leave_desklet (GtkWidget* pWidget,
 
706
        GdkEventCrossing* pEvent,
 
707
        CairoDesklet *pDesklet)
 
708
{
 
709
        //g_print ("%s (%d)\n", __func__, pDesklet->container.bInside);
 
710
        int iMouseX, iMouseY;
 
711
        gdk_window_get_pointer (pWidget->window, &iMouseX, &iMouseY, NULL);
 
712
        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.
 
713
        {
 
714
                return FALSE;
 
715
        }
 
716
 
 
717
        pDesklet->container.bInside = FALSE;
 
718
        gtk_widget_queue_draw (pWidget);  // redessin des boutons.
 
719
        
 
720
        gboolean bStartAnimation = FALSE;
 
721
        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_LEAVE_DESKLET, pDesklet, &bStartAnimation);
 
722
        if (bStartAnimation)
 
723
                cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
 
724
        
 
725
        return FALSE;
 
726
}
 
727
 
 
728
 
 
729
  ///////////////
 
730
 /// FACTORY ///
 
731
///////////////
 
732
 
 
733
static void _cairo_dock_set_icon_size (CairoContainer *pContainer, Icon *icon)
 
734
{
 
735
        CairoDesklet *pDesklet = CAIRO_DESKLET (pContainer);
 
736
        /**if (pDesklet->pRenderer && pDesklet->pRenderer->set_icon_size)
 
737
                pDesklet->pRenderer->set_icon_size (pDesklet, icon);*/
 
738
}
 
739
 
 
740
CairoDesklet *cairo_dock_new_desklet (void)
 
741
{
 
742
        cd_message ("%s ()", __func__);
 
743
        CairoDesklet *pDesklet = g_new0(CairoDesklet, 1);
 
744
        pDesklet->container.iType = CAIRO_DOCK_TYPE_DESKLET;
 
745
        pDesklet->container.bIsHorizontal = TRUE;
 
746
        pDesklet->container.bDirectionUp = TRUE;
 
747
        pDesklet->container.fRatio = 1;
 
748
        pDesklet->container.fRatio = 1;
 
749
        
 
750
        pDesklet->container.iface.set_icon_size = _cairo_dock_set_icon_size;
 
751
        
 
752
        GtkWidget* pWindow = cairo_dock_init_container (CAIRO_CONTAINER (pDesklet));
 
753
        
 
754
        gtk_window_set_title (GTK_WINDOW(pWindow), "cairo-dock-desklet");
 
755
        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);
 
756
        gtk_container_set_border_width(GTK_CONTAINER(pWindow), 2);  // comme ca.
 
757
        gtk_window_set_default_size(GTK_WINDOW(pWindow), 10, 10);  // idem.
 
758
 
 
759
        g_signal_connect (G_OBJECT (pWindow),
 
760
                "expose-event",
 
761
                G_CALLBACK (on_expose_desklet),
 
762
                pDesklet);
 
763
        g_signal_connect (G_OBJECT (pWindow),
 
764
                "configure-event",
 
765
                G_CALLBACK (on_configure_desklet),
 
766
                pDesklet);
 
767
        g_signal_connect (G_OBJECT (pWindow),
 
768
                "motion-notify-event",
 
769
                G_CALLBACK (on_motion_notify_desklet),
 
770
                pDesklet);
 
771
        g_signal_connect (G_OBJECT (pWindow),
 
772
                "button-press-event",
 
773
                G_CALLBACK (on_button_press_desklet),
 
774
                pDesklet);
 
775
        g_signal_connect (G_OBJECT (pWindow),
 
776
                "button-release-event",
 
777
                G_CALLBACK (on_button_press_desklet),
 
778
                pDesklet);
 
779
        g_signal_connect (G_OBJECT (pWindow),
 
780
                "focus-in-event",
 
781
                G_CALLBACK (on_focus_in_out_desklet),
 
782
                pDesklet);
 
783
        g_signal_connect (G_OBJECT (pWindow),
 
784
                "focus-out-event",
 
785
                G_CALLBACK (on_focus_in_out_desklet),
 
786
                pDesklet);
 
787
        g_signal_connect (G_OBJECT (pWindow),
 
788
                "enter-notify-event",
 
789
                G_CALLBACK (on_enter_desklet),
 
790
                pDesklet);
 
791
        g_signal_connect (G_OBJECT (pWindow),
 
792
                "leave-notify-event",
 
793
                G_CALLBACK (on_leave_desklet),
 
794
                pDesklet);
 
795
        g_signal_connect (G_OBJECT (pWindow),
 
796
                "unmap-event",
 
797
                G_CALLBACK (on_unmap_desklet),
 
798
                pDesklet);
 
799
        g_signal_connect (G_OBJECT (pWindow),
 
800
                "scroll-event",
 
801
                G_CALLBACK (on_scroll_desklet),
 
802
                pDesklet);
 
803
        cairo_dock_allow_widget_to_receive_data (pWindow, G_CALLBACK (on_drag_data_received_desklet), pDesklet);
 
804
        
 
805
        gtk_widget_show_all(pWindow);
 
806
        
 
807
        return pDesklet;
 
808
}
 
809
 
 
810
void cairo_dock_free_desklet (CairoDesklet *pDesklet)
 
811
{
 
812
        if (pDesklet == NULL)
 
813
                return;
 
814
 
 
815
        if (pDesklet->iSidWriteSize != 0)
 
816
                g_source_remove (pDesklet->iSidWriteSize);
 
817
        if (pDesklet->iSidWritePosition != 0)
 
818
                g_source_remove (pDesklet->iSidWritePosition);
 
819
        cairo_dock_notify_on_container (CAIRO_CONTAINER (pDesklet), CAIRO_DOCK_STOP_DESKLET, pDesklet);
 
820
        
 
821
        cairo_dock_steal_interactive_widget_from_desklet (pDesklet);
 
822
 
 
823
        cairo_dock_finish_container (CAIRO_CONTAINER (pDesklet));
 
824
        
 
825
        if (pDesklet->pRenderer != NULL)
 
826
        {
 
827
                if (pDesklet->pRenderer->free_data != NULL)
 
828
                {
 
829
                        pDesklet->pRenderer->free_data (pDesklet);
 
830
                        pDesklet->pRendererData = NULL;
 
831
                }
 
832
        }
 
833
        
 
834
        if (pDesklet->icons != NULL)
 
835
        {
 
836
                g_list_foreach (pDesklet->icons, (GFunc) cairo_dock_free_icon, NULL);
 
837
                g_list_free (pDesklet->icons);
 
838
        }
 
839
        
 
840
        g_free (pDesklet->cDecorationTheme);
 
841
        cairo_dock_free_desklet_decoration (pDesklet->pUserDecoration);
 
842
        
 
843
        cairo_dock_unload_image_buffer (&pDesklet->backGroundImageBuffer);
 
844
        cairo_dock_unload_image_buffer (&pDesklet->foreGroundImageBuffer);
 
845
        
 
846
        g_free(pDesklet);
 
847
}
 
848
 
 
849
 
 
850
void cairo_dock_configure_desklet (CairoDesklet *pDesklet, CairoDeskletAttribute *pAttribute)
 
851
{
 
852
        //g_print ("%s (%dx%d ; (%d,%d) ; %d)\n", __func__, pAttribute->iDeskletWidth, pAttribute->iDeskletHeight, pAttribute->iDeskletPositionX, pAttribute->iDeskletPositionY, pAttribute->iVisibility);
 
853
        if (pAttribute->bDeskletUseSize && (pAttribute->iDeskletWidth != pDesklet->container.iWidth || pAttribute->iDeskletHeight != pDesklet->container.iHeight))
 
854
        {
 
855
                pDesklet->iDesiredWidth = pAttribute->iDeskletWidth;
 
856
                pDesklet->iDesiredHeight = pAttribute->iDeskletHeight;
 
857
                gdk_window_resize (pDesklet->container.pWidget->window,
 
858
                        pAttribute->iDeskletWidth,
 
859
                        pAttribute->iDeskletHeight);
 
860
        }
 
861
        if (! pAttribute->bDeskletUseSize)
 
862
        {
 
863
                gtk_container_set_border_width (GTK_CONTAINER (pDesklet->container.pWidget), 0);
 
864
                gtk_window_set_resizable (GTK_WINDOW(pDesklet->container.pWidget), FALSE);
 
865
        }
 
866
        
 
867
        int iAbsolutePositionX = (pAttribute->iDeskletPositionX < 0 ? g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] + pAttribute->iDeskletPositionX : pAttribute->iDeskletPositionX);
 
868
        iAbsolutePositionX = MAX (0, MIN (g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - pAttribute->iDeskletWidth, iAbsolutePositionX));
 
869
        int iAbsolutePositionY = (pAttribute->iDeskletPositionY < 0 ? g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] + pAttribute->iDeskletPositionY : pAttribute->iDeskletPositionY);
 
870
        iAbsolutePositionY = MAX (0, MIN (g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - pAttribute->iDeskletHeight, iAbsolutePositionY));
 
871
        
 
872
        if (pAttribute->bOnAllDesktops)
 
873
                gdk_window_move(pDesklet->container.pWidget->window,
 
874
                        iAbsolutePositionX,
 
875
                        iAbsolutePositionY);
 
876
        //g_print (" let's place the deklet at (%d;%d)", iAbsolutePositionX, iAbsolutePositionY);
 
877
 
 
878
        cairo_dock_set_desklet_accessibility (pDesklet, pAttribute->iVisibility, FALSE);
 
879
        
 
880
        if (pAttribute->bOnAllDesktops)
 
881
        {
 
882
                gtk_window_stick (GTK_WINDOW (pDesklet->container.pWidget));
 
883
        }
 
884
        else
 
885
        {
 
886
                gtk_window_unstick (GTK_WINDOW (pDesklet->container.pWidget));
 
887
                Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
 
888
                if (g_desktopGeometry.iNbViewportX > 0 && g_desktopGeometry.iNbViewportY > 0)
 
889
                {
 
890
                        int iNumDesktop, iNumViewportX, iNumViewportY;
 
891
                        iNumDesktop = pAttribute->iNumDesktop / (g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY);
 
892
                        int index2 = pAttribute->iNumDesktop % (g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY);
 
893
                        iNumViewportX = index2 / g_desktopGeometry.iNbViewportY;
 
894
                        iNumViewportY = index2 % g_desktopGeometry.iNbViewportY;
 
895
                        
 
896
                        int iCurrentDesktop, iCurrentViewportX, iCurrentViewportY;
 
897
                        cairo_dock_get_current_desktop_and_viewport (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
 
898
                        cd_debug (">>> on fixe le desklet sur le bureau (%d,%d,%d) (cur : %d,%d,%d)\n", iNumDesktop, iNumViewportX, iNumViewportY, iCurrentDesktop, iCurrentViewportX, iCurrentViewportY);
 
899
                        
 
900
                        iNumViewportX -= iCurrentViewportX;
 
901
                        iNumViewportY -= iCurrentViewportY;
 
902
                        
 
903
                        cd_debug ("on le place en %d + %d\n", iNumViewportX * g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL], iAbsolutePositionX);
 
904
                        cairo_dock_move_xwindow_to_absolute_position (Xid, iNumDesktop, iNumViewportX * g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] + iAbsolutePositionX, iNumViewportY * g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] + iAbsolutePositionY);
 
905
                }
 
906
        }
 
907
        pDesklet->bPositionLocked = pAttribute->bPositionLocked;
 
908
        pDesklet->bNoInput = pAttribute->bNoInput;
 
909
        if (pDesklet->bNoInput)
 
910
                cairo_dock_disallow_widget_to_receive_data (pDesklet->container.pWidget);
 
911
        pDesklet->fRotation = pAttribute->iRotation / 180. * G_PI ;
 
912
        pDesklet->fDepthRotationY = pAttribute->iDepthRotationY / 180. * G_PI ;
 
913
        pDesklet->fDepthRotationX = pAttribute->iDepthRotationX / 180. * G_PI ;
 
914
        
 
915
        g_free (pDesklet->cDecorationTheme);
 
916
        pDesklet->cDecorationTheme = pAttribute->cDecorationTheme;
 
917
        pAttribute->cDecorationTheme = NULL;
 
918
        cairo_dock_free_desklet_decoration (pDesklet->pUserDecoration);
 
919
        pDesklet->pUserDecoration = pAttribute->pUserDecoration;
 
920
        pAttribute->pUserDecoration = NULL;
 
921
        
 
922
        //cd_debug ("%s (%dx%d ; %d)", __func__, pDesklet->iDesiredWidth, pDesklet->iDesiredHeight, pDesklet->iSidWriteSize);
 
923
        if (pDesklet->iDesiredWidth == 0 && pDesklet->iDesiredHeight == 0 && pDesklet->iSidWriteSize == 0)
 
924
        {
 
925
                cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (pDesklet));
 
926
                cairo_dock_load_desklet_decorations (pDesklet);
 
927
                cairo_destroy (pCairoContext);
 
928
        }
 
929
}
 
930
 
 
931
void cairo_dock_load_desklet_decorations (CairoDesklet *pDesklet)
 
932
{
 
933
        cairo_dock_unload_image_buffer (&pDesklet->backGroundImageBuffer);
 
934
        cairo_dock_unload_image_buffer (&pDesklet->foreGroundImageBuffer);
 
935
        
 
936
        CairoDeskletDecoration *pDeskletDecorations;
 
937
        //cd_debug ("%s (%s)", __func__, pDesklet->cDecorationTheme);
 
938
        if (pDesklet->cDecorationTheme == NULL || strcmp (pDesklet->cDecorationTheme, "personnal") == 0)
 
939
                pDeskletDecorations = pDesklet->pUserDecoration;
 
940
        else if (strcmp (pDesklet->cDecorationTheme, "default") == 0)
 
941
                pDeskletDecorations = cairo_dock_get_desklet_decoration (myDesklets.cDeskletDecorationsName);
 
942
        else
 
943
                pDeskletDecorations = cairo_dock_get_desklet_decoration (pDesklet->cDecorationTheme);
 
944
        if (pDeskletDecorations == NULL)  // peut arriver si rendering n'a pas encore charge ses decorations.
 
945
                return ;
 
946
        //cd_debug ("pDeskletDecorations : %s (%x)", pDesklet->cDecorationTheme, pDeskletDecorations);
 
947
        
 
948
        double fZoomX = 0., fZoomY = 0.;
 
949
        if  (pDeskletDecorations->cBackGroundImagePath != NULL && pDeskletDecorations->fBackGroundAlpha > 0)
 
950
        {
 
951
                //cd_debug ("bg : %s", pDeskletDecorations->cBackGroundImagePath);
 
952
                cairo_dock_load_image_buffer_full (&pDesklet->backGroundImageBuffer,
 
953
                        pDeskletDecorations->cBackGroundImagePath,
 
954
                        pDesklet->container.iWidth,
 
955
                        pDesklet->container.iHeight,
 
956
                        pDeskletDecorations->iLoadingModifier,
 
957
                        pDeskletDecorations->fBackGroundAlpha);
 
958
                fZoomX = pDesklet->backGroundImageBuffer.fZoomX;
 
959
                fZoomY = pDesklet->backGroundImageBuffer.fZoomY;
 
960
        }
 
961
        if (pDeskletDecorations->cForeGroundImagePath != NULL && pDeskletDecorations->fForeGroundAlpha > 0)
 
962
        {
 
963
                //cd_debug ("fg : %s", pDeskletDecorations->cForeGroundImagePath);
 
964
                cairo_dock_load_image_buffer_full (&pDesklet->foreGroundImageBuffer,
 
965
                        pDeskletDecorations->cForeGroundImagePath,
 
966
                        pDesklet->container.iWidth,
 
967
                        pDesklet->container.iHeight,
 
968
                        pDeskletDecorations->iLoadingModifier,
 
969
                        pDeskletDecorations->fForeGroundAlpha);
 
970
                fZoomX = pDesklet->foreGroundImageBuffer.fZoomX;
 
971
                fZoomY = pDesklet->foreGroundImageBuffer.fZoomY;
 
972
        }
 
973
        pDesklet->iLeftSurfaceOffset = pDeskletDecorations->iLeftMargin * fZoomX;
 
974
        pDesklet->iTopSurfaceOffset = pDeskletDecorations->iTopMargin * fZoomY;
 
975
        pDesklet->iRightSurfaceOffset = pDeskletDecorations->iRightMargin * fZoomX;
 
976
        pDesklet->iBottomSurfaceOffset = pDeskletDecorations->iBottomMargin * fZoomY;
 
977
        //g_print ("%d;%d;%d;%d ; %.2f;%.2f\n", pDesklet->iLeftSurfaceOffset, pDesklet->iTopSurfaceOffset, pDesklet->iRightSurfaceOffset, pDesklet->iBottomSurfaceOffset, fZoomX, fZoomY);
 
978
}
 
979
 
 
980
void cairo_dock_free_desklet_decoration (CairoDeskletDecoration *pDecoration)
 
981
{
 
982
        if (pDecoration == NULL)
 
983
                return ;
 
984
        g_free (pDecoration->cBackGroundImagePath);
 
985
        g_free (pDecoration->cForeGroundImagePath);
 
986
        g_free (pDecoration);
 
987
}
 
988
 
 
989
  ////////////////
 
990
 /// FACILITY ///
 
991
////////////////
 
992
 
 
993
void cairo_dock_add_interactive_widget_to_desklet_full (GtkWidget *pInteractiveWidget, CairoDesklet *pDesklet, int iRightMargin)
 
994
{
 
995
        g_return_if_fail (pDesklet != NULL && pInteractiveWidget != NULL);
 
996
        if (pDesklet->pInteractiveWidget != NULL || gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget)) != NULL)
 
997
        {
 
998
                cd_warning ("This desklet already has an interactive widget !");
 
999
                return;
 
1000
        }
 
1001
        
 
1002
        //gtk_container_add (GTK_CONTAINER (pDesklet->container.pWidget), pInteractiveWidget);
 
1003
        GtkWidget *pHBox = gtk_hbox_new (FALSE, 0);
 
1004
        gtk_container_add (GTK_CONTAINER (pDesklet->container.pWidget), pHBox);
 
1005
        
 
1006
        gtk_box_pack_start (GTK_BOX (pHBox), pInteractiveWidget, TRUE, TRUE, 0);
 
1007
        pDesklet->pInteractiveWidget = pInteractiveWidget;
 
1008
        
 
1009
        if (iRightMargin != 0)
 
1010
        {
 
1011
                GtkWidget *pMarginBox = gtk_vbox_new (FALSE, 0);
 
1012
                gtk_widget_set (pMarginBox, "width-request", iRightMargin, NULL);
 
1013
                gtk_box_pack_start (GTK_BOX (pHBox), pMarginBox, FALSE, FALSE, 0);  // a tester ...
 
1014
        }
 
1015
        
 
1016
        gtk_widget_show_all (pHBox);
 
1017
}
 
1018
 
 
1019
void cairo_dock_set_desklet_margin (CairoDesklet *pDesklet, int iRightMargin)
 
1020
{
 
1021
        g_return_if_fail (pDesklet != NULL && pDesklet->pInteractiveWidget != NULL);
 
1022
        
 
1023
        GtkWidget *pHBox = gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget));
 
1024
        if (pHBox && pHBox != pDesklet->pInteractiveWidget)  // precaution.
 
1025
        {
 
1026
                GList *pChildList = gtk_container_get_children (GTK_CONTAINER (pHBox));
 
1027
                if (pChildList != NULL)
 
1028
                {
 
1029
                        if (pChildList->next != NULL)
 
1030
                        {
 
1031
                                GtkWidget *pMarginBox = GTK_WIDGET (pChildList->next->data);
 
1032
                                gtk_widget_set (pMarginBox, "width-request", iRightMargin, NULL);
 
1033
                        }
 
1034
                        else  // on rajoute le widget de la marge.
 
1035
                        {
 
1036
                                GtkWidget *pMarginBox = gtk_vbox_new (FALSE, 0);
 
1037
                                gtk_widget_set (pMarginBox, "width-request", iRightMargin, NULL);
 
1038
                                gtk_box_pack_start (GTK_BOX (pHBox), pMarginBox, FALSE, FALSE, 0);
 
1039
                        }
 
1040
                        g_list_free (pChildList);
 
1041
                }
 
1042
        }
 
1043
}
 
1044
 
 
1045
GtkWidget *cairo_dock_steal_interactive_widget_from_desklet (CairoDesklet *pDesklet)
 
1046
{
 
1047
        if (pDesklet == NULL)
 
1048
                return NULL;
 
1049
 
 
1050
        GtkWidget *pInteractiveWidget = pDesklet->pInteractiveWidget;
 
1051
        if (pInteractiveWidget != NULL)
 
1052
        {
 
1053
                pInteractiveWidget = cairo_dock_steal_widget_from_its_container (pInteractiveWidget);
 
1054
                pDesklet->pInteractiveWidget = NULL;
 
1055
                GtkWidget *pBox = gtk_bin_get_child (GTK_BIN (pDesklet->container.pWidget));
 
1056
                if (pBox != NULL)
 
1057
                        gtk_widget_destroy (pBox);
 
1058
        }
 
1059
        return pInteractiveWidget;
 
1060
}
 
1061
 
 
1062
 
 
1063
 
 
1064
void cairo_dock_hide_desklet (CairoDesklet *pDesklet)
 
1065
{
 
1066
        if (pDesklet)
 
1067
        {
 
1068
                pDesklet->bAllowMinimize = TRUE;
 
1069
                gtk_widget_hide (pDesklet->container.pWidget);
 
1070
        }
 
1071
}
 
1072
 
 
1073
void cairo_dock_show_desklet (CairoDesklet *pDesklet)
 
1074
{
 
1075
        if (pDesklet)
 
1076
        {
 
1077
                gtk_window_present(GTK_WINDOW(pDesklet->container.pWidget));
 
1078
                gtk_window_move (GTK_WINDOW(pDesklet->container.pWidget), pDesklet->container.iWindowPositionX, pDesklet->container.iWindowPositionY);  // sinon le WM le place n'importe ou.
 
1079
        }
 
1080
}
 
1081
 
 
1082
void cairo_dock_zoom_out_desklet (CairoDesklet *pDesklet)
 
1083
{
 
1084
        g_return_if_fail (pDesklet != NULL);
 
1085
        pDesklet->container.fRatio = 0.1;
 
1086
        pDesklet->bGrowingUp = TRUE;
 
1087
        cairo_dock_launch_animation (CAIRO_CONTAINER (pDesklet));
 
1088
}
 
1089
 
 
1090
static void _cairo_dock_reserve_space_for_desklet (CairoDesklet *pDesklet, gboolean bReserve)
 
1091
{
 
1092
        cd_debug ("%s (%d)\n", __func__, bReserve);
 
1093
        Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
 
1094
        int left=0, right=0, top=0, bottom=0;
 
1095
        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;
 
1096
        int iHeight = pDesklet->container.iHeight, iWidth = pDesklet->container.iWidth;
 
1097
        int iX = pDesklet->container.iWindowPositionX, iY = pDesklet->container.iWindowPositionY;
 
1098
        if (bReserve)
 
1099
        {
 
1100
                int iTopOffset, iBottomOffset, iRightOffset, iLeftOffset;
 
1101
                iTopOffset = iY;
 
1102
                iBottomOffset = g_desktopGeometry.iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - 1 - (iY + iHeight);
 
1103
                iLeftOffset = iX;
 
1104
                iRightOffset = g_desktopGeometry.iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - 1 - (iX + iWidth);
 
1105
                
 
1106
                if (iBottomOffset < MIN (iLeftOffset, iRightOffset))  // en bas.
 
1107
                {
 
1108
                        bottom = iHeight + iBottomOffset;
 
1109
                        bottom_start_x = iX;
 
1110
                        bottom_end_x = iX + iWidth;
 
1111
                }
 
1112
                else if (iTopOffset < MIN (iLeftOffset, iRightOffset))  // en haut.
 
1113
                {
 
1114
                        top = iHeight + iTopOffset;
 
1115
                        top_start_x = iX;
 
1116
                        top_end_x = iX + iWidth;
 
1117
                }
 
1118
                else if (iLeftOffset < iRightOffset)  // a gauche.
 
1119
                {
 
1120
                        left = iWidth + iLeftOffset;
 
1121
                        left_start_y = iY;
 
1122
                        left_end_y = iY + iHeight;
 
1123
                }
 
1124
                else  // a droite.
 
1125
                {
 
1126
                        right = iWidth + iRightOffset;
 
1127
                        right_start_y = iY;
 
1128
                        right_end_y = iY + iHeight;
 
1129
                }
 
1130
        }
 
1131
        //cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_DOCK");
 
1132
        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);
 
1133
        pDesklet->bSpaceReserved = bReserve;
 
1134
}
 
1135
 
 
1136
//for compiz fusion "widget layer"
 
1137
//set behaviour in compiz to: (class=Cairo-dock & type=utility)
 
1138
void cairo_dock_set_desklet_accessibility (CairoDesklet *pDesklet, CairoDeskletVisibility iVisibility, gboolean bSaveState)
 
1139
{
 
1140
        //g_print ("%s (%d)\n", __func__, iVisibility);
 
1141
        
 
1142
        //\_________________ On applique la nouvelle accessibilite.
 
1143
        gtk_window_set_keep_below (GTK_WINDOW (pDesklet->container.pWidget), iVisibility == CAIRO_DESKLET_KEEP_BELOW);
 
1144
        gtk_window_set_keep_above (GTK_WINDOW (pDesklet->container.pWidget), iVisibility == CAIRO_DESKLET_KEEP_ABOVE);
 
1145
 
 
1146
        Window Xid = GDK_WINDOW_XID (pDesklet->container.pWidget->window);
 
1147
        if (iVisibility == CAIRO_DESKLET_ON_WIDGET_LAYER)
 
1148
                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.
 
1149
        else
 
1150
                cairo_dock_set_xwindow_type_hint (Xid, "_NET_WM_WINDOW_TYPE_NORMAL");
 
1151
        
 
1152
        if (iVisibility == CAIRO_DESKLET_RESERVE_SPACE)
 
1153
        {
 
1154
                if (! pDesklet->bSpaceReserved)
 
1155
                        _cairo_dock_reserve_space_for_desklet (pDesklet, TRUE);  // sinon inutile de le refaire, s'il y'a un changement de taille ce sera fait lors du configure-event.
 
1156
        }
 
1157
        else if (pDesklet->bSpaceReserved)
 
1158
        {
 
1159
                _cairo_dock_reserve_space_for_desklet (pDesklet, FALSE);
 
1160
        }
 
1161
        
 
1162
        //\_________________ On enregistre le nouvel etat.
 
1163
        Icon *icon = pDesklet->pIcon;
 
1164
        if (bSaveState && CAIRO_DOCK_IS_APPLET (icon))
 
1165
                cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
 
1166
                        G_TYPE_INT, "Desklet", "accessibility", iVisibility,
 
1167
                        G_TYPE_INVALID);
 
1168
        
 
1169
        //\_________________ On verifie que la regle de Compiz est correcte.
 
1170
        if (iVisibility == CAIRO_DESKLET_ON_WIDGET_LAYER && bSaveState)
 
1171
        {
 
1172
                // pour activer le plug-in, recuperer la liste, y rajouter widget-layer, puis envoyer :
 
1173
                //dbus-send --print-reply --type=method_call  --dest=org.freedesktop.compiz  /org/freedesktop/compiz/core/allscreens/active_plugins  org.freedesktop.compiz.get
 
1174
                // dbus-send --print-reply --type=method_call  --dest=org.freedesktop.compiz  /org/freedesktop/compiz/core/allscreens/active_plugins  org.freedesktop.compiz.set array:string:"foo",string:"fum"
 
1175
                
 
1176
                // on recupere la regle
 
1177
                gchar *cDbusAnswer = cairo_dock_launch_command_sync ("dbus-send --print-reply --type=method_call --dest=org.freedesktop.compiz /org/freedesktop/compiz/widget/screen0/match org.freedesktop.compiz.get");
 
1178
                cd_debug ("cDbusAnswer : '%s'", cDbusAnswer);
 
1179
                gchar *cRule = NULL;
 
1180
                gchar *str = (cDbusAnswer ? strchr (cDbusAnswer, '\n') : NULL);
 
1181
                if (str)
 
1182
                {
 
1183
                        str ++;
 
1184
                        while (*str == ' ')
 
1185
                                str ++;
 
1186
                        if (strncmp (str, "string", 6) == 0)
 
1187
                        {
 
1188
                                str += 6;
 
1189
                                while (*str == ' ')
 
1190
                                        str ++;
 
1191
                                if (*str == '"')
 
1192
                                {
 
1193
                                        str ++;
 
1194
                                        gchar *ptr = strrchr (str, '"');
 
1195
                                        if (ptr)
 
1196
                                        {
 
1197
                                                *ptr = '\0';
 
1198
                                                cRule = g_strdup (str);
 
1199
                                        }
 
1200
                                }
 
1201
                        }
 
1202
                }
 
1203
                g_free (cDbusAnswer);
 
1204
                cd_debug ("got rule : '%s'", cRule);
 
1205
                
 
1206
                if (cRule == NULL)  /// on ne sait pas le distinguer d'une regle vide...
 
1207
                {
 
1208
                        cd_warning ("couldn't get Widget Layer rule from Compiz");
 
1209
                }
 
1210
                
 
1211
                // on complete la regle si necessaire.
 
1212
                if (cRule == NULL || *cRule == '\0' || (g_strstr_len (cRule, -1, "class=Cairo-dock & type=utility") == NULL && g_strstr_len (cRule, -1, "(class=Cairo-dock) & (type=utility)") == NULL && g_strstr_len (cRule, -1, "name=cairo-dock & type=utility") == NULL))
 
1213
                {
 
1214
                        gchar *cNewRule = (cRule == NULL || *cRule == '\0' ?
 
1215
                                g_strdup ("(class=Cairo-dock & type=utility)") :
 
1216
                                g_strdup_printf ("(%s) | (class=Cairo-dock & type=utility)", cRule));
 
1217
                        cd_debug ("set rule : %s", cNewRule);
 
1218
                        gchar *cCommand = g_strdup_printf ("dbus-send --print-reply --type=method_call --dest=org.freedesktop.compiz /org/freedesktop/compiz/widget/screen0/match org.freedesktop.compiz.set string:\"%s\"", cNewRule);
 
1219
                        cairo_dock_launch_command_sync (cCommand);
 
1220
                        g_free (cCommand);
 
1221
                        g_free (cNewRule);
 
1222
                }
 
1223
                g_free (cRule);
 
1224
        }
 
1225
}
 
1226
 
 
1227
void cairo_dock_set_desklet_sticky (CairoDesklet *pDesklet, gboolean bSticky)
 
1228
{
 
1229
        //g_print ("%s (%d)\n", __func__, bSticky);
 
1230
        int iNumDesktop;
 
1231
        if (bSticky)
 
1232
        {
 
1233
                gtk_window_stick (GTK_WINDOW (pDesklet->container.pWidget));
 
1234
                iNumDesktop = -1;
 
1235
        }
 
1236
        else
 
1237
        {
 
1238
                gtk_window_unstick (GTK_WINDOW (pDesklet->container.pWidget));
 
1239
                int iCurrentDesktop, iCurrentViewportX, iCurrentViewportY;
 
1240
                cairo_dock_get_current_desktop_and_viewport (&iCurrentDesktop, &iCurrentViewportX, &iCurrentViewportY);
 
1241
                iNumDesktop = iCurrentDesktop * g_desktopGeometry.iNbViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportX * g_desktopGeometry.iNbViewportY + iCurrentViewportY;
 
1242
                cd_debug (">>> on colle ce desklet sur le bureau %d", iNumDesktop);
 
1243
        }
 
1244
        
 
1245
        //\_________________ On enregistre le nouvel etat.
 
1246
        Icon *icon = pDesklet->pIcon;
 
1247
        if (CAIRO_DOCK_IS_APPLET (icon))
 
1248
                cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
 
1249
                        G_TYPE_BOOLEAN, "Desklet", "sticky", bSticky,
 
1250
                        G_TYPE_INT, "Desklet", "num desktop", iNumDesktop,
 
1251
                        G_TYPE_INVALID);
 
1252
}
 
1253
 
 
1254
void cairo_dock_lock_desklet_position (CairoDesklet *pDesklet, gboolean bPositionLocked)
 
1255
{
 
1256
        //g_print ("%s (%d)\n", __func__, bPositionLocked);
 
1257
        pDesklet->bPositionLocked = bPositionLocked;
 
1258
        
 
1259
        //\_________________ On enregistre le nouvel etat.
 
1260
        Icon *icon = pDesklet->pIcon;
 
1261
        if (CAIRO_DOCK_IS_APPLET (icon))
 
1262
                cairo_dock_update_conf_file (icon->pModuleInstance->cConfFilePath,
 
1263
                        G_TYPE_BOOLEAN, "Desklet", "locked", pDesklet->bPositionLocked,
 
1264
                        G_TYPE_INVALID);
 
1265
}
 
1266
 
 
1267
 
 
1268
void cairo_dock_update_desklet_icons (CairoDesklet *pDesklet)
 
1269
{
 
1270
        // compute icons size
 
1271
        if (pDesklet->pRenderer && pDesklet->pRenderer->calculate_icons != NULL)
 
1272
                pDesklet->pRenderer->calculate_icons (pDesklet);
 
1273
        
 
1274
        // trigger load if changed
 
1275
        Icon* pIcon = pDesklet->pIcon;
 
1276
        if (pIcon)
 
1277
                cairo_dock_load_icon_buffers (pIcon, CAIRO_CONTAINER (pDesklet));
 
1278
        
 
1279
        GList* ic;
 
1280
        for (ic = pDesklet->icons; ic != NULL; ic = ic->next)
 
1281
        {
 
1282
                pIcon = ic->data;
 
1283
                if ((int)pIcon->fWidth != pIcon->iImageWidth || (int)pIcon->fHeight != pIcon->iImageHeight)
 
1284
                {
 
1285
                        pIcon->iImageWidth = pIcon->fWidth;
 
1286
                        pIcon->iImageHeight = pIcon->fHeight;
 
1287
                        cairo_dock_trigger_load_icon_buffers (pIcon, CAIRO_CONTAINER (pDesklet));
 
1288
                }
 
1289
        }
 
1290
        
 
1291
        // redraw
 
1292
        cairo_dock_redraw_container (CAIRO_CONTAINER (pDesklet));
 
1293
}
 
1294
 
 
1295
void cairo_dock_insert_icon_in_desklet (Icon *icon, CairoDesklet *pDesklet)
 
1296
{
 
1297
        g_return_if_fail (icon != NULL);
 
1298
        if (g_list_find (pDesklet->icons, icon) != NULL)  // elle est deja dans ce desklet.
 
1299
                return ;
 
1300
        
 
1301
        // insert icon
 
1302
        pDesklet->icons = g_list_insert_sorted (pDesklet->icons,
 
1303
                icon,
 
1304
                (GCompareFunc)cairo_dock_compare_icons_order);
 
1305
        icon->pContainerForLoad = CAIRO_CONTAINER (pDesklet);
 
1306
        
 
1307
        // calculate icons
 
1308
        cairo_dock_update_desklet_icons (pDesklet);
 
1309
}
 
1310
 
 
1311
gboolean cairo_dock_detach_icon_from_desklet (Icon *icon, CairoDesklet *pDesklet)
 
1312
{
 
1313
        if (pDesklet == NULL)
 
1314
                return FALSE;
 
1315
        
 
1316
        GList *ic = g_list_find (pDesklet->icons, icon);
 
1317
        if (! ic)
 
1318
                return FALSE;
 
1319
        
 
1320
        // remove icon
 
1321
        pDesklet->icons = g_list_delete_link (pDesklet->icons, ic);
 
1322
        ic =  NULL;
 
1323
        icon->pContainerForLoad = NULL;
 
1324
        
 
1325
        // calculate icons
 
1326
        cairo_dock_update_desklet_icons (pDesklet);
 
1327
}