~ubuntu-branches/ubuntu/vivid/cairo-dock-plug-ins/vivid

« back to all changes in this revision

Viewing changes to switcher/src/applet-draw.c

Tags: upstream-2.0.9
ImportĀ upstreamĀ versionĀ 2.0.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
* This file is a part of the Cairo-Dock project
3
 
*
4
 
* Copyright : (C) see the 'copyright' file.
5
 
* E-mail    : see the 'copyright' file.
6
 
*
7
 
* This program is free software; you can redistribute it and/or
8
 
* modify it under the terms of the GNU General Public License
9
 
* as published by the Free Software Foundation; either version 3
10
 
* of the License, or (at your option) any later version.
11
 
*
12
 
* This program is distributed in the hope that it will be useful,
13
 
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
* GNU General Public License for more details.
16
 
* You should have received a copy of the GNU General Public License
17
 
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
*/
19
 
 
20
 
/************************************************************************************
21
 
 
22
 
This file is a part of the cairo-dock program, 
23
 
released under the terms of the GNU General Public License.
24
 
 
25
 
Written by Cchumi & Fabrice Rey (for any bug report, please mail me to fabounet@users.berlios.de)
26
 
 
27
 
************************************************************************************/
28
 
#include <string.h>
29
 
#include <glib/gstdio.h>
30
 
#include <math.h>
31
 
 
32
 
#include "applet-struct.h"
33
 
#include "applet-load-icons.h"
34
 
#include "applet-draw.h"
35
 
 
36
 
gboolean my_bRotateIconsOnEllipse = TRUE;
37
 
 
38
 
 
39
 
static void _cd_switcher_draw_windows_on_viewport (Icon *pIcon, gint *data)
40
 
{
41
 
        if (pIcon == NULL || pIcon->fPersonnalScale > 0)
42
 
                return ;
43
 
        if (pIcon->bIsHidden && ! myConfig.bDisplayHiddenWindows)
44
 
                return ;
45
 
        int iNumDesktop = data[0];
46
 
        int iNumViewportX = data[1];
47
 
        int iNumViewportY = data[2];
48
 
        int iOneViewportWidth = data[3];
49
 
        int iOneViewportHeight = data[4];
50
 
        cairo_t *pCairoContext = GINT_TO_POINTER (data[5]);
51
 
        
52
 
        // On calcule les coordonnees en repere absolu.
53
 
        int x = pIcon->windowGeometry.x;  // par rapport au viewport courant.
54
 
        x += myData.switcher.iCurrentViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];  // repere absolu
55
 
        if (x < 0)
56
 
                x += g_iNbViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
57
 
        int y = pIcon->windowGeometry.y;
58
 
        y += myData.switcher.iCurrentViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
59
 
        if (y < 0)
60
 
                y += g_iNbViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
61
 
        int w = pIcon->windowGeometry.width, h = pIcon->windowGeometry.height;
62
 
        
63
 
        // test d'intersection avec le viewport donne.
64
 
        //g_print (" %s : (%d;%d) %dx%d\n", pIcon->acName, x, y, w, h);
65
 
        if ((pIcon->iNumDesktop != -1 && pIcon->iNumDesktop != iNumDesktop) ||
66
 
                x + w <= iNumViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] ||
67
 
                x >= (iNumViewportX + 1) * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] ||
68
 
                y + h <= iNumViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] ||
69
 
                y >= (iNumViewportY + 1) * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
70
 
                return ;
71
 
        //g_print (" > on la dessine (%x)\n", pIcon->pIconBuffer);
72
 
        
73
 
        // on dessine ses traits.
74
 
        cairo_save (pCairoContext);
75
 
        
76
 
        cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
77
 
        cairo_rectangle (pCairoContext,
78
 
                (1.*x/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - iNumViewportX)*iOneViewportWidth,
79
 
                (1.*y/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - iNumViewportY)*iOneViewportHeight,
80
 
                1.*w/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL]*iOneViewportWidth,
81
 
                1.*h/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]*iOneViewportHeight);
82
 
        if (pIcon->Xid == cairo_dock_get_current_active_window ())
83
 
        {
84
 
                //g_print (" %s est la fenetre active\n", pIcon->acName);
85
 
                cairo_fill (pCairoContext);
86
 
        }
87
 
        else
88
 
        {
89
 
                cairo_stroke (pCairoContext);
90
 
        }
91
 
        
92
 
        if (pIcon->pIconBuffer != NULL)
93
 
        {
94
 
                CairoDock *pParentDock = NULL;
95
 
                pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
96
 
                if (pParentDock == NULL)
97
 
                        pParentDock = g_pMainDock;
98
 
                int iWidth, iHeight;
99
 
                cairo_dock_get_icon_extent (pIcon, pParentDock, &iWidth, &iHeight);
100
 
                double fZoomX = (double) w/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL]*iOneViewportWidth / iWidth;
101
 
                double fZoomY = (double) h/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]*iOneViewportHeight / iHeight;
102
 
                double fZoom = MIN (fZoomX, fZoomY);  // on garde le ratio.
103
 
                
104
 
                cairo_translate (pCairoContext,
105
 
                        (1.*x/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - iNumViewportX)*iOneViewportWidth + (fZoomX - fZoom) * iWidth/2,
106
 
                        (1.*y/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - iNumViewportY)*iOneViewportHeight + (fZoomY - fZoom) * iHeight/2);
107
 
                cairo_scale (pCairoContext,
108
 
                        fZoom,
109
 
                        fZoom);
110
 
                cairo_set_source_surface (pCairoContext,
111
 
                        pIcon->pIconBuffer,
112
 
                        0.,
113
 
                        0.);
114
 
                cairo_paint (pCairoContext);
115
 
        }
116
 
        
117
 
        cairo_restore (pCairoContext);
118
 
}
119
 
 
120
 
 
121
 
static int _compare_icons_stack_order (Icon *icon1, Icon *icon2)
122
 
{
123
 
        if (icon1 == NULL)  // les icones nulles vont a la fin.
124
 
                return 1;
125
 
        if (icon2 == NULL)
126
 
                return -1;
127
 
        if (icon1->iStackOrder < icon2->iStackOrder)  // ordre petit => dessus => dessinee en dernier.
128
 
                return -1;
129
 
        else
130
 
                return 1;
131
 
}
132
 
void cd_switcher_draw_main_icon_compact_mode (void)
133
 
{
134
 
        //cd_debug ("%s (%d;%d)", __func__, myData.switcher.iCurrentLine, myData.switcher.iCurrentColumn);
135
 
        // On efface l'icone.
136
 
        cairo_dock_erase_cairo_context (myDrawContext);
137
 
        
138
 
        // definition des parametres de dessin.
139
 
        //double fRatio = (myDock ? myDock->fRatio : 1.);
140
 
        //double fMaxScale = cairo_dock_get_max_scale (myContainer); //coefficient Max icone Width
141
 
        int iWidth, iHeight;
142
 
        CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
143
 
        myData.switcher.fOneViewportHeight = (iHeight - 2 * myConfig.iLineSize - (myData.switcher.iNbLines - 1) * myConfig.iInLineSize) / myData.switcher.iNbLines; //hauteur d'un bureau/viewport sans compter les lignes exterieures et interieures.
144
 
        myData.switcher.fOneViewportWidth = (iWidth - 2 * myConfig.iLineSize - (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize) / myData.switcher.iNbColumns; //largeur d'un bureau/viewport sans compter les lignes exterieures et interieures.
145
 
        
146
 
        cairo_surface_t *pSurface = NULL;
147
 
        double fZoomX, fZoomY;
148
 
        if (myConfig.bMapWallpaper)
149
 
        {
150
 
                pSurface = cairo_dock_get_desktop_bg_surface ();
151
 
                fZoomX = (double) myData.switcher.fOneViewportWidth / g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
152
 
                fZoomY= (double) myData.switcher.fOneViewportHeight / g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
153
 
        }
154
 
        if (pSurface == NULL)
155
 
        {
156
 
                pSurface = myData.pDefaultMapSurface;
157
 
                fZoomX = (double) myData.switcher.fOneViewportWidth / iWidth;
158
 
                fZoomY = (double) myData.switcher.fOneViewportHeight / iHeight;
159
 
        }
160
 
        
161
 
        // cadre exterieur.
162
 
        cairo_set_line_width (myDrawContext,myConfig.iLineSize);
163
 
        cairo_set_source_rgba(myDrawContext,myConfig.RGBLineColors[0],myConfig.RGBLineColors[1],myConfig.RGBLineColors[2],myConfig.RGBLineColors[3]);
164
 
        cairo_rectangle(myDrawContext,
165
 
                .5*myConfig.iLineSize,
166
 
                .5*myConfig.iLineSize,
167
 
                iWidth - myConfig.iLineSize,
168
 
                iHeight - myConfig.iLineSize);
169
 
 
170
 
        cairo_stroke (myDrawContext);
171
 
        
172
 
        // lignes interieures.
173
 
        cairo_set_line_width (myDrawContext,myConfig.iInLineSize);
174
 
        cairo_set_source_rgba(myDrawContext,myConfig.RGBInLineColors[0],myConfig.RGBInLineColors[1],myConfig.RGBInLineColors[2],myConfig.RGBInLineColors[3]);
175
 
        double xi, yj;
176
 
        int i, j;
177
 
        for (i = 1; i <myData.switcher.iNbColumns; i ++)  // lignes verticales.
178
 
        {
179
 
                xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
180
 
                cairo_move_to (myDrawContext, xi, myConfig.iLineSize);
181
 
                cairo_rel_line_to (myDrawContext, 0, iHeight - 2*myConfig.iLineSize);
182
 
                cairo_stroke (myDrawContext);
183
 
        }
184
 
        for (j = 1; j < myData.switcher.iNbLines; j ++)  // lignes horizontales.
185
 
        {
186
 
                yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
187
 
                cairo_move_to (myDrawContext, myConfig.iLineSize, yj);
188
 
                cairo_rel_line_to (myDrawContext, iWidth - 2*myConfig.iLineSize, 0);
189
 
                cairo_stroke (myDrawContext);
190
 
        }
191
 
        
192
 
        GList *pWindowList = NULL;
193
 
        if (myConfig.bDrawWindows)
194
 
        {
195
 
                pWindowList = cairo_dock_get_current_applis_list ();
196
 
                pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
197
 
        }
198
 
        
199
 
        // chaque bureau/viewport.
200
 
        int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
201
 
        for (j = 0; j < myData.switcher.iNbLines; j ++)
202
 
        {
203
 
                for (i = 0; i < myData.switcher.iNbColumns; i ++)
204
 
                {
205
 
                        cairo_save (myDrawContext);
206
 
 
207
 
                        xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize);
208
 
                        yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize);
209
 
 
210
 
                        cairo_translate (myDrawContext,
211
 
                                xi,
212
 
                                yj);
213
 
 
214
 
                        cairo_scale (myDrawContext,
215
 
                                fZoomX,
216
 
                                fZoomY);
217
 
                        cairo_set_source_surface (myDrawContext,
218
 
                                pSurface,
219
 
                                0.,
220
 
                                0.);
221
 
                        cairo_paint(myDrawContext);
222
 
                        
223
 
                        cairo_restore (myDrawContext);
224
 
                        
225
 
                        if (myConfig.iDrawCurrentDesktopMode == SWICTHER_FILL_INVERTED && (i != myData.switcher.iCurrentColumn || j != myData.switcher.iCurrentLine))
226
 
                        {
227
 
                                cairo_save (myDrawContext);
228
 
                                
229
 
                                cairo_set_source_rgba (myDrawContext, myConfig.RGBIndColors[0], myConfig.RGBIndColors[1], myConfig.RGBIndColors[2], myConfig.RGBIndColors[3]);
230
 
                                cairo_rectangle(myDrawContext,
231
 
                                        xi - .5*myConfig.iLineSize,
232
 
                                        yj - .5*myConfig.iLineSize,
233
 
                                        myData.switcher.fOneViewportWidth + myConfig.iLineSize,
234
 
                                        myData.switcher.fOneViewportHeight + myConfig.iLineSize);
235
 
                                cairo_fill (myDrawContext);
236
 
                                
237
 
                                cairo_restore (myDrawContext);
238
 
                        }
239
 
                        
240
 
                        if (myConfig.bDrawWindows)
241
 
                        {
242
 
                                cairo_save (myDrawContext);
243
 
                                
244
 
                                cairo_translate (myDrawContext,
245
 
                                        xi,
246
 
                                        yj);
247
 
                                cairo_set_line_width (myDrawContext, 1.);
248
 
                                cairo_rectangle (myDrawContext,
249
 
                                        0.,
250
 
                                        0.,
251
 
                                        myData.switcher.fOneViewportWidth,
252
 
                                        myData.switcher.fOneViewportHeight);
253
 
                                cairo_clip (myDrawContext);
254
 
                                
255
 
                                //g_print (" dessin des fenetres du bureau (%d;%d;%d) ...\n", iNumDesktop, iNumViewportX, iNumViewportY);
256
 
                                gint data[6] = {iNumDesktop, iNumViewportX, iNumViewportY, (int) myData.switcher.fOneViewportWidth, (int) myData.switcher.fOneViewportHeight, GPOINTER_TO_INT (myDrawContext)};
257
 
                                g_list_foreach (pWindowList, (GFunc) _cd_switcher_draw_windows_on_viewport, data);
258
 
                                
259
 
                                cairo_restore (myDrawContext);
260
 
                        }
261
 
                        
262
 
                        iNumViewportX ++;
263
 
                        if (iNumViewportX == g_iNbViewportX)
264
 
                        {
265
 
                                iNumViewportY ++;
266
 
                                if (iNumViewportY == g_iNbViewportY)
267
 
                                        iNumDesktop ++;
268
 
                        }
269
 
                }
270
 
        }
271
 
        
272
 
        // dessin de l'indicateur sur le bureau courant (on le fait maintenant car dans le cas ou la ligne interieure est plus petite que la ligne de l'indicateur, les surfaces suivantes recouvreraient en partie la ligne.
273
 
        if (myConfig.iDrawCurrentDesktopMode != SWICTHER_FILL_INVERTED)
274
 
        {
275
 
                i = myData.switcher.iCurrentColumn;
276
 
                j = myData.switcher.iCurrentLine;
277
 
                xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize);
278
 
                yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize);
279
 
                
280
 
                cairo_set_line_width (myDrawContext,myConfig.iLineSize);
281
 
                cairo_set_source_rgba (myDrawContext,myConfig.RGBIndColors[0],myConfig.RGBIndColors[1],myConfig.RGBIndColors[2],myConfig.RGBIndColors[3]);
282
 
                cairo_rectangle(myDrawContext,
283
 
                        xi - .5*myConfig.iLineSize,
284
 
                        yj - .5*myConfig.iLineSize,
285
 
                        myData.switcher.fOneViewportWidth + myConfig.iLineSize,
286
 
                        myData.switcher.fOneViewportHeight + myConfig.iLineSize);
287
 
                
288
 
                if (myConfig.iDrawCurrentDesktopMode == SWICTHER_FILL)
289
 
                        cairo_fill (myDrawContext);
290
 
                else
291
 
                        cairo_stroke(myDrawContext);
292
 
        }
293
 
        
294
 
        g_list_free (pWindowList);  // le contenu appartient a la hash table, mais pas la liste.
295
 
        
296
 
        if (CD_APPLET_MY_CONTAINER_IS_OPENGL)
297
 
                cairo_dock_update_icon_texture (myIcon);
298
 
        else
299
 
                CD_APPLET_UPDATE_REFLECT_ON_MY_ICON;
300
 
}
301
 
 
302
 
 
303
 
void cd_switcher_draw_main_icon_expanded_mode (void)
304
 
{
305
 
        // definition des parametres de dessin.
306
 
        int iWidth, iHeight;
307
 
        CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
308
 
        //double fRatio = (myDock ? myDock->fRatio : 1.);
309
 
        //double fMaxScale = cairo_dock_get_max_scale (myContainer); //coefficient Max icone Width
310
 
        myData.switcher.fOneViewportHeight = (iHeight - 2 * myConfig.iLineSize - (myData.switcher.iNbLines - 1) * myConfig.iInLineSize) / myData.switcher.iNbLines; //hauteur d'un bureau/viewport sans compter les lignes exterieures et interieures.
311
 
        myData.switcher.fOneViewportWidth = (iWidth - 2 * myConfig.iLineSize - (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize) / myData.switcher.iNbColumns; //largeur d'un bureau/viewport sans compter les lignes exterieures et interieures.
312
 
 
313
 
        cairo_surface_t *pSurface = NULL;
314
 
        double fZoomX, fZoomY;
315
 
        if (myConfig.bMapWallpaper)
316
 
        {
317
 
                cairo_dock_erase_cairo_context (myDrawContext);
318
 
                
319
 
                pSurface = cairo_dock_get_desktop_bg_surface ();
320
 
                fZoomX = 1. * iWidth / g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
321
 
                fZoomY= 1. * iHeight / g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
322
 
                cairo_translate (myDrawContext,
323
 
                        0.,
324
 
                        0.);
325
 
 
326
 
                cairo_save (myDrawContext);
327
 
                cairo_scale (myDrawContext,
328
 
                        fZoomX ,
329
 
                        fZoomY );
330
 
                cairo_set_source_surface (myDrawContext,
331
 
                        pSurface,
332
 
                        0.,
333
 
                        0.);
334
 
                cairo_paint(myDrawContext);
335
 
                cairo_restore (myDrawContext);
336
 
                
337
 
                if (CD_APPLET_MY_CONTAINER_IS_OPENGL)
338
 
                        cairo_dock_update_icon_texture (myIcon);
339
 
                else
340
 
                        CD_APPLET_UPDATE_REFLECT_ON_MY_ICON;
341
 
        }
342
 
        else
343
 
        {
344
 
                CD_APPLET_SET_LOCAL_IMAGE_ON_MY_ICON (MY_APPLET_ICON_FILE);
345
 
        }
346
 
 
347
 
        if (myConfig.bDrawWindows)
348
 
        {
349
 
                GList *pWindowList = cairo_dock_get_current_applis_list ();
350
 
                pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
351
 
                
352
 
                //fMaxScale = (myIcon->pSubDock != NULL ? cairo_dock_get_max_scale (myIcon->pSubDock) : 1);
353
 
                //fRatio = (myIcon->pSubDock != NULL ? myIcon->pSubDock->fRatio : 1);
354
 
                gint data[6];
355
 
                int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
356
 
                cairo_t *pCairoContext;
357
 
                Icon *pIcon;
358
 
                CairoContainer *pContainer = CD_APPLET_MY_ICONS_LIST_CONTAINER;
359
 
                GList *pIconsList = CD_APPLET_MY_ICONS_LIST;
360
 
                GList *ic;
361
 
                for (ic = pIconsList; ic != NULL; ic = ic->next)
362
 
                {
363
 
                        pIcon = ic->data;
364
 
                        cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
365
 
                        
366
 
                        data[0] = iNumDesktop;
367
 
                        data[1] = iNumViewportX;
368
 
                        data[2] = iNumViewportY;
369
 
                        data[3] = iWidth;
370
 
                        data[4] = iHeight;
371
 
                        pCairoContext = cairo_create (pIcon->pIconBuffer);
372
 
                        data[5] = GPOINTER_TO_INT (pCairoContext);
373
 
                        cairo_set_line_width (pCairoContext, 1.);
374
 
                        cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
375
 
                
376
 
                        g_list_foreach (pWindowList, (GFunc) _cd_switcher_draw_windows_on_viewport, data);
377
 
                        
378
 
                        iNumViewportX ++;
379
 
                        if (iNumViewportX == g_iNbViewportX)
380
 
                        {
381
 
                                iNumViewportY ++;
382
 
                                if (iNumViewportY == g_iNbViewportY)
383
 
                                        iNumDesktop ++;
384
 
                        }
385
 
                        cairo_destroy (pCairoContext);
386
 
                }
387
 
                g_list_free (pWindowList);  // le contenu appartient a la hash table, mais pas la liste.
388
 
        }
389
 
}
390
 
 
391
 
/*Fonction de base pour toutes les autres*/
392
 
void cd_switcher_draw_main_icon (void)
393
 
{
394
 
        cd_message ("%s (%d)", __func__, myConfig.bCompactView);
395
 
        if (myConfig.bCompactView)
396
 
        {
397
 
                cd_switcher_draw_main_icon_compact_mode ();
398
 
        }
399
 
        else
400
 
        {
401
 
                cd_switcher_draw_main_icon_expanded_mode ();
402
 
        }
403
 
        
404
 
        CD_APPLET_REDRAW_MY_ICON;
405
 
}
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
7
* This program is free software; you can redistribute it and/or
 
8
* modify it under the terms of the GNU General Public License
 
9
* as published by the Free Software Foundation; either version 3
 
10
* of the License, or (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
16
* You should have received a copy of the GNU General Public License
 
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
#include <string.h>
 
21
#include <glib/gstdio.h>
 
22
#include <math.h>
 
23
 
 
24
#include "applet-struct.h"
 
25
#include "applet-load-icons.h"
 
26
#include "applet-draw.h"
 
27
 
 
28
gboolean my_bRotateIconsOnEllipse = TRUE;
 
29
 
 
30
 
 
31
static void _cd_switcher_draw_windows_on_viewport (Icon *pIcon, gint *data)
 
32
{
 
33
        if (pIcon == NULL || pIcon->fPersonnalScale > 0)
 
34
                return ;
 
35
        if (pIcon->bIsHidden && ! myConfig.bDisplayHiddenWindows)
 
36
                return ;
 
37
        int iNumDesktop = data[0];
 
38
        int iNumViewportX = data[1];
 
39
        int iNumViewportY = data[2];
 
40
        int iOneViewportWidth = data[3];
 
41
        int iOneViewportHeight = data[4];
 
42
        cairo_t *pCairoContext = GINT_TO_POINTER (data[5]);
 
43
        
 
44
        // On calcule les coordonnees en repere absolu.
 
45
        int x = pIcon->windowGeometry.x;  // par rapport au viewport courant.
 
46
        x += myData.switcher.iCurrentViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];  // repere absolu
 
47
        if (x < 0)
 
48
                x += g_iNbViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
49
        int y = pIcon->windowGeometry.y;
 
50
        y += myData.switcher.iCurrentViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
51
        if (y < 0)
 
52
                y += g_iNbViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
53
        int w = pIcon->windowGeometry.width, h = pIcon->windowGeometry.height;
 
54
        
 
55
        // test d'intersection avec le viewport donne.
 
56
        //g_print (" %s : (%d;%d) %dx%d\n", pIcon->cName, x, y, w, h);
 
57
        if ((pIcon->iNumDesktop != -1 && pIcon->iNumDesktop != iNumDesktop) ||
 
58
                x + w <= iNumViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] ||
 
59
                x >= (iNumViewportX + 1) * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] ||
 
60
                y + h <= iNumViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] ||
 
61
                y >= (iNumViewportY + 1) * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
 
62
                return ;
 
63
        //g_print (" > on la dessine (%x)\n", pIcon->pIconBuffer);
 
64
        
 
65
        // on dessine ses traits.
 
66
        cairo_save (pCairoContext);
 
67
        
 
68
        cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
 
69
        cairo_rectangle (pCairoContext,
 
70
                (1.*x/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - iNumViewportX)*iOneViewportWidth,
 
71
                (1.*y/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - iNumViewportY)*iOneViewportHeight,
 
72
                1.*w/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL]*iOneViewportWidth,
 
73
                1.*h/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]*iOneViewportHeight);
 
74
        if (pIcon->Xid == cairo_dock_get_current_active_window ())
 
75
        {
 
76
                //g_print (" %s est la fenetre active\n", pIcon->cName);
 
77
                cairo_fill (pCairoContext);
 
78
        }
 
79
        else
 
80
        {
 
81
                cairo_stroke (pCairoContext);
 
82
        }
 
83
        
 
84
        if (pIcon->pIconBuffer != NULL)
 
85
        {
 
86
                CairoDock *pParentDock = NULL;
 
87
                pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
 
88
                if (pParentDock == NULL)
 
89
                        pParentDock = g_pMainDock;
 
90
                int iWidth, iHeight;
 
91
                cairo_dock_get_icon_extent (pIcon, CAIRO_CONTAINER (pParentDock), &iWidth, &iHeight);
 
92
                double fZoomX = (double) w/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL]*iOneViewportWidth / iWidth;
 
93
                double fZoomY = (double) h/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]*iOneViewportHeight / iHeight;
 
94
                double fZoom = MIN (fZoomX, fZoomY);  // on garde le ratio.
 
95
                
 
96
                cairo_translate (pCairoContext,
 
97
                        (1.*x/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] - iNumViewportX)*iOneViewportWidth + (fZoomX - fZoom) * iWidth/2,
 
98
                        (1.*y/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] - iNumViewportY)*iOneViewportHeight + (fZoomY - fZoom) * iHeight/2);
 
99
                cairo_scale (pCairoContext,
 
100
                        fZoom,
 
101
                        fZoom);
 
102
                cairo_set_source_surface (pCairoContext,
 
103
                        pIcon->pIconBuffer,
 
104
                        0.,
 
105
                        0.);
 
106
                cairo_paint (pCairoContext);
 
107
        }
 
108
        
 
109
        cairo_restore (pCairoContext);
 
110
}
 
111
 
 
112
 
 
113
static int _compare_icons_stack_order (Icon *icon1, Icon *icon2)
 
114
{
 
115
        if (icon1 == NULL)  // les icones nulles vont a la fin.
 
116
                return 1;
 
117
        if (icon2 == NULL)
 
118
                return -1;
 
119
        if (icon1->iStackOrder < icon2->iStackOrder)  // ordre petit => dessus => dessinee en dernier.
 
120
                return -1;
 
121
        else
 
122
                return 1;
 
123
}
 
124
void cd_switcher_draw_main_icon_compact_mode (void)
 
125
{
 
126
        //cd_debug ("%s (%d;%d)", __func__, myData.switcher.iCurrentLine, myData.switcher.iCurrentColumn);
 
127
        // On efface l'icone.
 
128
        cairo_dock_erase_cairo_context (myDrawContext);
 
129
        
 
130
        // definition des parametres de dessin.
 
131
        //double fRatio = (myDock ? myDock->container.fRatio : 1.);
 
132
        //double fMaxScale = cairo_dock_get_max_scale (myContainer); //coefficient Max icone Width
 
133
        int iWidth, iHeight;
 
134
        CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
 
135
        
 
136
        myData.switcher.fOneViewportHeight = (iHeight - 2 * myConfig.iLineSize - (myData.switcher.iNbLines - 1) * myConfig.iInLineSize) / myData.switcher.iNbLines; //hauteur d'un bureau/viewport sans compter les lignes exterieures et interieures.
 
137
        myData.switcher.fOneViewportWidth = (iWidth - 2 * myConfig.iLineSize - (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize) / myData.switcher.iNbColumns; //largeur d'un bureau/viewport sans compter les lignes exterieures et interieures.
 
138
        double dx=0, dy=0;
 
139
        double w = iWidth, h = iHeight;
 
140
        if (myConfig.bPreserveScreenRatio)
 
141
        {
 
142
                double r = (double) g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] / g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
143
                double r_ = myData.switcher.fOneViewportWidth / myData.switcher.fOneViewportHeight;
 
144
                if (r_ > r)  // on etire trop en largeur.
 
145
                {
 
146
                        myData.switcher.fOneViewportWidth /= r_ / r;
 
147
                        dx = iWidth/2 * (1 - r / r_);
 
148
                        w /= r_ / r;
 
149
                }
 
150
                else
 
151
                {
 
152
                        myData.switcher.fOneViewportHeight /= r / r_;
 
153
                        dy = iHeight/2 * (1 - r_ / r);
 
154
                        h /= r / r_;
 
155
                }
 
156
        }
 
157
        myData.switcher.fOffsetX = dx;
 
158
        myData.switcher.fOffsetY = dy;
 
159
        
 
160
        cairo_save (myDrawContext);
 
161
        cairo_translate (myDrawContext, dx, dy);
 
162
        
 
163
        cairo_surface_t *pSurface = NULL;
 
164
        double fZoomX, fZoomY;
 
165
        if (myConfig.bMapWallpaper)
 
166
        {
 
167
                pSurface = cairo_dock_get_desktop_bg_surface ();
 
168
                fZoomX = (double) myData.switcher.fOneViewportWidth / g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
169
                fZoomY= (double) myData.switcher.fOneViewportHeight / g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
170
        }
 
171
        if (pSurface == NULL)
 
172
        {
 
173
                pSurface = myData.pDefaultMapSurface;
 
174
                fZoomX = (double) myData.switcher.fOneViewportWidth / iWidth;
 
175
                fZoomY = (double) myData.switcher.fOneViewportHeight / iHeight;
 
176
        }
 
177
        
 
178
        // cadre exterieur.
 
179
        cairo_set_line_width (myDrawContext,myConfig.iLineSize);
 
180
        cairo_set_source_rgba(myDrawContext,myConfig.RGBLineColors[0],myConfig.RGBLineColors[1],myConfig.RGBLineColors[2],myConfig.RGBLineColors[3]);
 
181
        cairo_rectangle(myDrawContext,
 
182
                .5*myConfig.iLineSize,
 
183
                .5*myConfig.iLineSize,
 
184
                w - myConfig.iLineSize,
 
185
                h - myConfig.iLineSize);
 
186
 
 
187
        cairo_stroke (myDrawContext);
 
188
        
 
189
        // lignes interieures.
 
190
        cairo_set_line_width (myDrawContext,myConfig.iInLineSize);
 
191
        cairo_set_source_rgba(myDrawContext,myConfig.RGBInLineColors[0],myConfig.RGBInLineColors[1],myConfig.RGBInLineColors[2],myConfig.RGBInLineColors[3]);
 
192
        double xi, yj;
 
193
        int i, j;
 
194
        for (i = 1; i < myData.switcher.iNbColumns; i ++)  // lignes verticales.
 
195
        {
 
196
                xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
 
197
                cairo_move_to (myDrawContext, xi, myConfig.iLineSize);
 
198
                cairo_rel_line_to (myDrawContext, 0, h - 2*myConfig.iLineSize);
 
199
                cairo_stroke (myDrawContext);
 
200
        }
 
201
        for (j = 1; j < myData.switcher.iNbLines; j ++)  // lignes horizontales.
 
202
        {
 
203
                yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
 
204
                cairo_move_to (myDrawContext, myConfig.iLineSize, yj);
 
205
                cairo_rel_line_to (myDrawContext, w - 2*myConfig.iLineSize, 0);
 
206
                cairo_stroke (myDrawContext);
 
207
        }
 
208
        
 
209
        GList *pWindowList = NULL;
 
210
        if (myConfig.bDrawWindows)
 
211
        {
 
212
                pWindowList = cairo_dock_get_current_applis_list ();
 
213
                pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
 
214
        }
 
215
        
 
216
        // chaque bureau/viewport.
 
217
        int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
 
218
        int k = 0, N = g_iNbDesktops * g_iNbViewportX * g_iNbViewportY;
 
219
        for (j = 0; j < myData.switcher.iNbLines; j ++)
 
220
        {
 
221
                for (i = 0; i < myData.switcher.iNbColumns; i ++)
 
222
                {
 
223
                        cairo_save (myDrawContext);
 
224
 
 
225
                        xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize);
 
226
                        yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize);
 
227
 
 
228
                        cairo_translate (myDrawContext,
 
229
                                xi,
 
230
                                yj);
 
231
 
 
232
                        cairo_scale (myDrawContext,
 
233
                                fZoomX,
 
234
                                fZoomY);
 
235
                        cairo_set_source_surface (myDrawContext,
 
236
                                pSurface,
 
237
                                0.,
 
238
                                0.);
 
239
                        cairo_paint(myDrawContext);
 
240
                        
 
241
                        cairo_restore (myDrawContext);
 
242
                        
 
243
                        if (myConfig.iDrawCurrentDesktopMode == SWICTHER_FILL_INVERTED && (i != myData.switcher.iCurrentColumn || j != myData.switcher.iCurrentLine))
 
244
                        {
 
245
                                cairo_save (myDrawContext);
 
246
                                
 
247
                                cairo_set_source_rgba (myDrawContext, myConfig.RGBIndColors[0], myConfig.RGBIndColors[1], myConfig.RGBIndColors[2], myConfig.RGBIndColors[3]);
 
248
                                cairo_rectangle(myDrawContext,
 
249
                                        xi - .5*myConfig.iLineSize,
 
250
                                        yj - .5*myConfig.iLineSize,
 
251
                                        myData.switcher.fOneViewportWidth + myConfig.iLineSize,
 
252
                                        myData.switcher.fOneViewportHeight + myConfig.iLineSize);
 
253
                                cairo_fill (myDrawContext);
 
254
                                
 
255
                                cairo_restore (myDrawContext);
 
256
                        }
 
257
                        
 
258
                        if (myConfig.bDrawWindows)
 
259
                        {
 
260
                                cairo_save (myDrawContext);
 
261
                                
 
262
                                cairo_translate (myDrawContext,
 
263
                                        xi,
 
264
                                        yj);
 
265
                                cairo_set_line_width (myDrawContext, 1.);
 
266
                                cairo_rectangle (myDrawContext,
 
267
                                        0.,
 
268
                                        0.,
 
269
                                        myData.switcher.fOneViewportWidth,
 
270
                                        myData.switcher.fOneViewportHeight);
 
271
                                cairo_clip (myDrawContext);
 
272
                                
 
273
                                //g_print (" dessin des fenetres du bureau (%d;%d;%d) ...\n", iNumDesktop, iNumViewportX, iNumViewportY);
 
274
                                gint data[6] = {iNumDesktop, iNumViewportX, iNumViewportY, (int) myData.switcher.fOneViewportWidth, (int) myData.switcher.fOneViewportHeight, GPOINTER_TO_INT (myDrawContext)};
 
275
                                g_list_foreach (pWindowList, (GFunc) _cd_switcher_draw_windows_on_viewport, data);
 
276
                                
 
277
                                cairo_restore (myDrawContext);
 
278
                        }
 
279
                        
 
280
                        iNumViewportX ++;
 
281
                        if (iNumViewportX == g_iNbViewportX)
 
282
                        {
 
283
                                iNumViewportY ++;
 
284
                                if (iNumViewportY == g_iNbViewportY)
 
285
                                        iNumDesktop ++;
 
286
                        }
 
287
                        k ++;
 
288
                        if (k == N)
 
289
                                break ;
 
290
                }
 
291
        }
 
292
        
 
293
        // dessin de l'indicateur sur le bureau courant (on le fait maintenant car dans le cas ou la ligne interieure est plus petite que la ligne de l'indicateur, les surfaces suivantes recouvreraient en partie la ligne.
 
294
        if (myConfig.iDrawCurrentDesktopMode != SWICTHER_FILL_INVERTED)
 
295
        {
 
296
                i = myData.switcher.iCurrentColumn;
 
297
                j = myData.switcher.iCurrentLine;
 
298
                xi = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize);
 
299
                yj = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize);
 
300
                
 
301
                cairo_set_line_width (myDrawContext,myConfig.iLineSize);
 
302
                cairo_set_source_rgba (myDrawContext,myConfig.RGBIndColors[0],myConfig.RGBIndColors[1],myConfig.RGBIndColors[2],myConfig.RGBIndColors[3]);
 
303
                cairo_rectangle(myDrawContext,
 
304
                        xi - .5*myConfig.iLineSize,
 
305
                        yj - .5*myConfig.iLineSize,
 
306
                        myData.switcher.fOneViewportWidth + myConfig.iLineSize,
 
307
                        myData.switcher.fOneViewportHeight + myConfig.iLineSize);
 
308
                
 
309
                if (myConfig.iDrawCurrentDesktopMode == SWICTHER_FILL)
 
310
                        cairo_fill (myDrawContext);
 
311
                else
 
312
                        cairo_stroke(myDrawContext);
 
313
        }
 
314
        
 
315
        cairo_restore (myDrawContext);
 
316
        g_list_free (pWindowList);  // le contenu appartient a la hash table, mais pas la liste.
 
317
        
 
318
        if (CD_APPLET_MY_CONTAINER_IS_OPENGL)
 
319
                cairo_dock_update_icon_texture (myIcon);
 
320
        else
 
321
                CD_APPLET_UPDATE_REFLECT_ON_MY_ICON;
 
322
}
 
323
 
 
324
 
 
325
void cd_switcher_draw_main_icon_expanded_mode (void)
 
326
{
 
327
        // definition des parametres de dessin.
 
328
        int iWidth, iHeight;
 
329
        CD_APPLET_GET_MY_ICON_EXTENT (&iWidth, &iHeight);
 
330
        //double fRatio = (myDock ? myDock->container.fRatio : 1.);
 
331
        //double fMaxScale = cairo_dock_get_max_scale (myContainer); //coefficient Max icone Width
 
332
        myData.switcher.fOneViewportHeight = (iHeight - 2 * myConfig.iLineSize - (myData.switcher.iNbLines - 1) * myConfig.iInLineSize) / myData.switcher.iNbLines; //hauteur d'un bureau/viewport sans compter les lignes exterieures et interieures.
 
333
        myData.switcher.fOneViewportWidth = (iWidth - 2 * myConfig.iLineSize - (myData.switcher.iNbColumns - 1) * myConfig.iInLineSize) / myData.switcher.iNbColumns; //largeur d'un bureau/viewport sans compter les lignes exterieures et interieures.
 
334
 
 
335
        cairo_surface_t *pSurface = NULL;
 
336
        double fZoomX, fZoomY;
 
337
        if (myConfig.bMapWallpaper)
 
338
        {
 
339
                cairo_dock_erase_cairo_context (myDrawContext);
 
340
                
 
341
                pSurface = cairo_dock_get_desktop_bg_surface ();
 
342
                fZoomX = 1. * iWidth / g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
343
                fZoomY= 1. * iHeight / g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
344
                cairo_translate (myDrawContext,
 
345
                        0.,
 
346
                        0.);
 
347
 
 
348
                cairo_save (myDrawContext);
 
349
                cairo_scale (myDrawContext,
 
350
                        fZoomX ,
 
351
                        fZoomY );
 
352
                cairo_set_source_surface (myDrawContext,
 
353
                        pSurface,
 
354
                        0.,
 
355
                        0.);
 
356
                cairo_paint(myDrawContext);
 
357
                cairo_restore (myDrawContext);
 
358
                
 
359
                if (CD_APPLET_MY_CONTAINER_IS_OPENGL)
 
360
                        cairo_dock_update_icon_texture (myIcon);
 
361
                else
 
362
                        CD_APPLET_UPDATE_REFLECT_ON_MY_ICON;
 
363
        }
 
364
        else
 
365
        {
 
366
                CD_APPLET_SET_LOCAL_IMAGE_ON_MY_ICON (MY_APPLET_ICON_FILE);
 
367
        }
 
368
 
 
369
        if (myConfig.bDrawWindows)
 
370
        {
 
371
                GList *pWindowList = cairo_dock_get_current_applis_list ();
 
372
                pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
 
373
                
 
374
                //fMaxScale = (myIcon->pSubDock != NULL ? cairo_dock_get_max_scale (myIcon->pSubDock) : 1);
 
375
                //fRatio = (myIcon->pSubDock != NULL ? myIcon->pSubDock->container.fRatio : 1);
 
376
                gint data[6];
 
377
                int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
 
378
                cairo_t *pCairoContext;
 
379
                Icon *pIcon;
 
380
                CairoContainer *pContainer = CD_APPLET_MY_ICONS_LIST_CONTAINER;
 
381
                GList *pIconsList = CD_APPLET_MY_ICONS_LIST;
 
382
                GList *ic;
 
383
                for (ic = pIconsList; ic != NULL; ic = ic->next)
 
384
                {
 
385
                        pIcon = ic->data;
 
386
                        cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
 
387
                        
 
388
                        data[0] = iNumDesktop;
 
389
                        data[1] = iNumViewportX;
 
390
                        data[2] = iNumViewportY;
 
391
                        data[3] = iWidth;
 
392
                        data[4] = iHeight;
 
393
                        pCairoContext = cairo_create (pIcon->pIconBuffer);
 
394
                        data[5] = GPOINTER_TO_INT (pCairoContext);
 
395
                        cairo_set_line_width (pCairoContext, 1.);
 
396
                        cairo_set_source_rgba (pCairoContext, myConfig.RGBWLineColors[0], myConfig.RGBWLineColors[1], myConfig.RGBWLineColors[2], myConfig.RGBWLineColors[3]);
 
397
                
 
398
                        g_list_foreach (pWindowList, (GFunc) _cd_switcher_draw_windows_on_viewport, data);
 
399
                        
 
400
                        iNumViewportX ++;
 
401
                        if (iNumViewportX == g_iNbViewportX)
 
402
                        {
 
403
                                iNumViewportY ++;
 
404
                                if (iNumViewportY == g_iNbViewportY)
 
405
                                        iNumDesktop ++;
 
406
                        }
 
407
                        cairo_destroy (pCairoContext);
 
408
                }
 
409
                g_list_free (pWindowList);  // le contenu appartient a la hash table, mais pas la liste.
 
410
        }
 
411
}
 
412
 
 
413
/*Fonction de base pour toutes les autres*/
 
414
void cd_switcher_draw_main_icon (void)
 
415
{
 
416
        cd_message ("%s (%d)", __func__, myConfig.bCompactView);
 
417
        if (myConfig.bCompactView)
 
418
        {
 
419
                cd_switcher_draw_main_icon_compact_mode ();
 
420
        }
 
421
        else
 
422
        {
 
423
                cd_switcher_draw_main_icon_expanded_mode ();
 
424
        }
 
425
        
 
426
        CD_APPLET_REDRAW_MY_ICON;
 
427
}
 
428
 
 
429
 
 
430
void cd_switcher_draw_desktops_bounding_box (CairoDesklet *pDesklet)
 
431
{
 
432
        //g_print ("%s ()\n", __func__);
 
433
        double x, y, w, h;
 
434
        glTranslatef (-pDesklet->container.iWidth/2, -pDesklet->container.iHeight/2, 0.);
 
435
        
 
436
        w = myData.switcher.fOneViewportWidth/2;
 
437
        h = myData.switcher.fOneViewportHeight/2;
 
438
        int i, j;
 
439
        int k = 0, N = g_iNbDesktops * g_iNbViewportX * g_iNbViewportY;
 
440
        
 
441
        for (j = 0; j < myData.switcher.iNbLines; j ++)  // lignes horizontales.
 
442
        {
 
443
                y = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
 
444
                y = pDesklet->container.iHeight - (y + h + myData.switcher.fOffsetY);   
 
445
                
 
446
                for (i = 0; i < myData.switcher.iNbColumns; i ++)  // lignes verticales.
 
447
                {
 
448
                        x = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
 
449
                        x += w + myData.switcher.fOffsetX;
 
450
                        
 
451
                        glLoadName(i * myData.switcher.iNbLines + j + 1);  // +1 pour ne pas avoir 0.
 
452
                        
 
453
                        glBegin(GL_QUADS);
 
454
                        glVertex3f(x-w, y+h, 0.);
 
455
                        glVertex3f(x+w, y+h, 0.);
 
456
                        glVertex3f(x+w, y-h, 0.);
 
457
                        glVertex3f(x-w, y-h, 0.);
 
458
                        glEnd();
 
459
                        
 
460
                        k ++;
 
461
                        if (k == N)
 
462
                                break;
 
463
                }
 
464
        }
 
465
}
 
466
 
 
467
void cd_switcher_extract_viewport_coords_from_picked_object (CairoDesklet *pDesklet, int *iCoordX, int *iCoordY)
 
468
{
 
469
        //g_print ("%s (%d)\n", __func__, pDesklet->iPickedObject);
 
470
        if (pDesklet->iPickedObject != 0)
 
471
        {
 
472
                pDesklet->iPickedObject --;  // cf le +1
 
473
                int i, j;
 
474
                i = pDesklet->iPickedObject / myData.switcher.iNbLines;
 
475
                j = pDesklet->iPickedObject % myData.switcher.iNbLines;
 
476
                //g_print ("bureau (%d;%d)\n", i, j);
 
477
                
 
478
                double x, y, w, h;
 
479
                w = myData.switcher.fOneViewportWidth/2;
 
480
                h = myData.switcher.fOneViewportHeight/2;
 
481
                x = myConfig.iLineSize + i * (myData.switcher.fOneViewportWidth + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
 
482
                x += w + myData.switcher.fOffsetX;
 
483
                y = myConfig.iLineSize + j * (myData.switcher.fOneViewportHeight + myConfig.iInLineSize) - .5*myConfig.iInLineSize;
 
484
                y += h + myData.switcher.fOffsetY;
 
485
                *iCoordX = x;
 
486
                *iCoordY = y;
 
487
        }
 
488
}
 
489
 
 
490
 
 
491
static void _show_window (GtkMenuItem *menu_item, Icon *pIcon)
 
492
{
 
493
        cairo_dock_show_xwindow (pIcon->Xid);
 
494
}
 
495
static void _cd_switcher_list_windows_on_viewport (Icon *pIcon, gint *pData)
 
496
{
 
497
        if (pIcon == NULL || pIcon->fPersonnalScale > 0)
 
498
                return ;
 
499
        int iNumDesktop = pData[0];
 
500
        int iNumViewportX = pData[1];
 
501
        int iNumViewportY = pData[2];
 
502
        int iOneViewportWidth = pData[3];
 
503
        int iOneViewportHeight = pData[4];
 
504
        GtkWidget *pMenu = GINT_TO_POINTER (pData[5]);
 
505
        
 
506
        // On calcule les coordonnees en repere absolu.
 
507
        int x = pIcon->windowGeometry.x;  // par rapport au viewport courant.
 
508
        x += myData.switcher.iCurrentViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];  // repere absolu
 
509
        if (x < 0)
 
510
                x += g_iNbViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL];
 
511
        int y = pIcon->windowGeometry.y;
 
512
        y += myData.switcher.iCurrentViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
513
        if (y < 0)
 
514
                y += g_iNbViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL];
 
515
        int w = pIcon->windowGeometry.width, h = pIcon->windowGeometry.height;
 
516
        
 
517
        // test d'intersection avec le viewport donne.
 
518
        if ((pIcon->iNumDesktop != -1 && pIcon->iNumDesktop != iNumDesktop) ||
 
519
                x + w <= iNumViewportX * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] ||
 
520
                x >= (iNumViewportX + 1) * g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL] ||
 
521
                y + h <= iNumViewportY * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL] ||
 
522
                y >= (iNumViewportY + 1) * g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL])
 
523
                return ;
 
524
        if (!pIcon->pIconBuffer)
 
525
                return ;
 
526
        
 
527
        g_print ("%s\n", pIcon->cName);
 
528
        CairoDock *pParentDock = NULL;
 
529
        pParentDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
 
530
        if (pParentDock == NULL)
 
531
                pParentDock = g_pMainDock;
 
532
        int iWidth, iHeight;
 
533
        cairo_dock_get_icon_extent (pIcon, CAIRO_CONTAINER (pParentDock), &iWidth, &iHeight);
 
534
        
 
535
        w = 24, h = w;
 
536
        cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
 
537
                w,
 
538
                h);
 
539
        cairo_t *pCairoContext = cairo_create (surface);
 
540
        cairo_scale (pCairoContext, (double)w/iWidth, (double)h/iHeight);
 
541
        cairo_set_source_surface (pCairoContext, pIcon->pIconBuffer, 0., 0.);
 
542
        cairo_paint (pCairoContext);
 
543
        cairo_destroy (pCairoContext);
 
544
        guchar *d, *data = cairo_image_surface_get_data (surface);
 
545
        int r = cairo_image_surface_get_stride (surface);
 
546
        
 
547
        GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
 
548
                TRUE,
 
549
                8,
 
550
                w,
 
551
                h);
 
552
        guchar *p, *pixels = gdk_pixbuf_get_pixels (pixbuf);
 
553
        int iNbChannels = gdk_pixbuf_get_n_channels (pixbuf);
 
554
        int iRowstride = gdk_pixbuf_get_rowstride (pixbuf);
 
555
        
 
556
        int red, green, blue;
 
557
        float fAlphaFactor;
 
558
        for (y = 0; y < h; y ++)
 
559
        {
 
560
                for (x = 0; x < w; x ++)
 
561
                {
 
562
                        p = pixels + y * iRowstride + x * iNbChannels;
 
563
                        d = data + y * r + x * 4;
 
564
                        
 
565
                        fAlphaFactor = (float) d[3] / 255;
 
566
                        if (fAlphaFactor != 0)
 
567
                        {
 
568
                                red = d[0] / fAlphaFactor;
 
569
                                green = d[1] / fAlphaFactor;
 
570
                                blue = d[2] / fAlphaFactor;
 
571
                        }
 
572
                        else
 
573
                        {
 
574
                                red = blue = green = 0;
 
575
                        }
 
576
                        p[0] = blue;
 
577
                        p[1] = green;
 
578
                        p[2] = red;
 
579
                        p[3] = d[3];
 
580
                }
 
581
        }
 
582
        
 
583
        cairo_surface_destroy (surface);
 
584
        
 
585
        GtkWidget *pMenuItem = gtk_image_menu_item_new_with_label (pIcon->cName);
 
586
        GtkWidget *image = gtk_image_new_from_pixbuf (pixbuf);
 
587
        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (pMenuItem), image);
 
588
        gtk_menu_shell_append  (GTK_MENU_SHELL (pMenu), pMenuItem);
 
589
        g_signal_connect (G_OBJECT (pMenuItem), "activate", G_CALLBACK (_show_window), pIcon);
 
590
        
 
591
        g_object_unref (pixbuf);
 
592
}
 
593
void cd_switcher_build_windows_list (GtkWidget *pMenu)
 
594
{
 
595
        GList *pWindowList = NULL;
 
596
        pWindowList = cairo_dock_get_current_applis_list ();
 
597
        pWindowList = g_list_sort (pWindowList, (GCompareFunc) _compare_icons_stack_order);
 
598
        
 
599
        // chaque bureau/viewport.
 
600
        int iNumDesktop=0, iNumViewportX=0, iNumViewportY=0;
 
601
        int k = 0, N = g_iNbDesktops * g_iNbViewportX * g_iNbViewportY;
 
602
        int i, j;
 
603
        for (j = 0; j < myData.switcher.iNbLines; j ++)
 
604
        {
 
605
                for (i = 0; i < myData.switcher.iNbColumns; i ++)
 
606
                {
 
607
                        g_print (" listing des fenetres du bureau (%d;%d;%d) ...\n", iNumDesktop, iNumViewportX, iNumViewportY);
 
608
                        gint data[6] = {iNumDesktop, iNumViewportX, iNumViewportY, (int) myData.switcher.fOneViewportWidth, (int) myData.switcher.fOneViewportHeight, GPOINTER_TO_INT (pMenu)};
 
609
                        g_list_foreach (pWindowList, (GFunc) _cd_switcher_list_windows_on_viewport, data);
 
610
                        
 
611
                        GtkWidget *pMenuItem = gtk_separator_menu_item_new ();
 
612
                        gtk_menu_shell_append(GTK_MENU_SHELL (pMenu), pMenuItem);  /// recuperer les noms des bureaux...
 
613
                        g_print ("-----------------\n");
 
614
                        
 
615
                        iNumViewportX ++;
 
616
                        if (iNumViewportX == g_iNbViewportX)
 
617
                        {
 
618
                                
 
619
                                /// _NET_DESKTOP_NAMES, UTF8_STRING
 
620
                                
 
621
                                iNumViewportY ++;
 
622
                                if (iNumViewportY == g_iNbViewportY)
 
623
                                        iNumDesktop ++;
 
624
                        }
 
625
                        k ++;
 
626
                        if (k == N)
 
627
                                break ;
 
628
                }
 
629
        }
 
630
}