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

« back to all changes in this revision

Viewing changes to src/cairo-dock-draw-opengl.c

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

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
* This file is a part of the Cairo-Dock project
3
 
*
4
 
* Copyright : (C) see the 'copyright' file.
5
 
* E-mail    : see the 'copyright' file.
6
 
*
7
 
* This program is free software; you can redistribute it and/or
8
 
* modify it under the terms of the GNU General Public License
9
 
* as published by the Free Software Foundation; either version 3
10
 
* of the License, or (at your option) any later version.
11
 
*
12
 
* This program is distributed in the hope that it will be useful,
13
 
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
* GNU General Public License for more details.
16
 
* You should have received a copy of the GNU General Public License
17
 
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 
*/
19
 
 
20
 
#include <math.h>
21
 
#include <string.h>
22
 
#include <stdio.h>
23
 
#include <stdlib.h>
24
 
#include <iconv.h>
25
 
 
26
 
#include <glib/gstdio.h>
27
 
#include <gtk/gtk.h>
28
 
#include <gdk/gdkx.h>
29
 
 
30
 
#include <cairo.h>
31
 
#include <pango/pango.h>
32
 
#include <librsvg/rsvg.h>
33
 
#include <librsvg/rsvg-cairo.h>
34
 
 
35
 
#ifdef HAVE_GLITZ
36
 
#include <glitz-glx.h>
37
 
#include <cairo-glitz.h>
38
 
#endif
39
 
 
40
 
#include <X11/extensions/Xrender.h>
41
 
#include <GL/glx.h>
42
 
#include <GL/glxext.h>
43
 
 
44
 
#include "cairo-dock-load.h"
45
 
#include "cairo-dock-surface-factory.h"
46
 
#include "cairo-dock-icons.h"
47
 
#include "cairo-dock-load.h"
48
 
#include "cairo-dock-draw.h"
49
 
#include "cairo-dock-notifications.h"
50
 
#include "cairo-dock-applications-manager.h"
51
 
#include "cairo-dock-renderer-manager.h"
52
 
#include "cairo-dock-internal-system.h"
53
 
#include "cairo-dock-internal-taskbar.h"
54
 
#include "cairo-dock-internal-indicators.h"
55
 
#include "cairo-dock-internal-labels.h"
56
 
#include "cairo-dock-internal-icons.h"
57
 
#include "cairo-dock-internal-background.h"
58
 
#include "cairo-dock-internal-accessibility.h"
59
 
#include "cairo-dock-log.h"
60
 
#include "cairo-dock-X-utilities.h"
61
 
#include "cairo-dock-container.h"
62
 
#include "cairo-dock-dock-facility.h"
63
 
#include "cairo-dock-dock-manager.h"
64
 
#include "cairo-dock-animations.h"
65
 
#include "cairo-dock-draw-opengl.h"
66
 
 
67
 
#include "texture-gradation.h"
68
 
#define RADIAN (G_PI / 180.0)  // Conversion Radian/Degres
69
 
#define DELTA_ROUND_DEGREE 3
70
 
 
71
 
extern GLuint g_pGradationTexture[2];
72
 
 
73
 
extern CairoDock *g_pMainDock;
74
 
 
75
 
extern CairoDockImageBuffer g_pIndicatorBuffer;
76
 
extern CairoDockImageBuffer g_pActiveIndicatorBuffer;
77
 
extern CairoDockImageBuffer g_pClassIndicatorBuffer;
78
 
extern CairoDockImageBuffer g_pIconBackgroundImageBuffer;
79
 
extern CairoDockImageBuffer g_pVisibleZoneBuffer;
80
 
 
81
 
extern gboolean g_bUseOpenGL;
82
 
extern CairoDockGLConfig g_openglConfig;
83
 
 
84
 
extern gboolean g_bEasterEggs;
85
 
 
86
 
static void _cairo_dock_draw_appli_indicator_opengl (Icon *icon, gboolean bIsHorizontal, double fRatio, gboolean bDirectionUp)
87
 
{
88
 
        if (! myIndicators.bRotateWithDock)
89
 
                bDirectionUp = bIsHorizontal = TRUE;
90
 
        
91
 
        //\__________________ On place l'indicateur.
92
 
        if (icon->fOrientation != 0)
93
 
        {
94
 
                glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
95
 
                glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
96
 
                glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
97
 
        }
98
 
        double z = 1 + myIcons.fAmplitude;
99
 
        double w = g_pIndicatorBuffer.iWidth;
100
 
        double h = g_pIndicatorBuffer.iHeight;
101
 
        double dy = myIndicators.iIndicatorDeltaY / z;
102
 
        double fY;
103
 
        if (myIndicators.bLinkIndicatorWithIcon)  // il se deforme et rebondit avec l'icone.
104
 
        {
105
 
                w /= z;
106
 
                h /= z;
107
 
                fY = - icon->fHeight * icon->fScale/2
108
 
                        + (h/2 - dy) * fRatio * icon->fScale;
109
 
                
110
 
                if (bIsHorizontal)
111
 
                {
112
 
                        if (! bDirectionUp)
113
 
                                fY = - fY;
114
 
                        glTranslatef (0., fY, 0.);
115
 
                        glScalef (w * fRatio * icon->fScale * icon->fWidthFactor, (bDirectionUp ? 1:-1) * h * fRatio * icon->fScale * icon->fHeightFactor, 1.);
116
 
                }
117
 
                else
118
 
                {
119
 
                        if (bDirectionUp)
120
 
                                fY = - fY;
121
 
                        glTranslatef (fY, 0., 0.);
122
 
                        glRotatef (90, 0., 0., 1.);
123
 
                        glScalef (w * fRatio * icon->fScale * icon->fWidthFactor, (bDirectionUp ? 1:-1) * h * fRatio * icon->fScale * icon->fHeightFactor, 1.);
124
 
                }
125
 
                
126
 
        }
127
 
        else  // il est fixe, en bas de l'icone.
128
 
        {
129
 
                fY = - icon->fHeight * icon->fScale/2
130
 
                        + (h/2 - dy) * fRatio;
131
 
                if (bIsHorizontal)
132
 
                {
133
 
                        if (! bDirectionUp)
134
 
                                fY = - fY;
135
 
                        glTranslatef (0., fY, 1.);
136
 
                        glScalef (w * fRatio * 1., (bDirectionUp ? 1:-1) * h * fRatio * 1., 1.);
137
 
                }
138
 
                else
139
 
                {
140
 
                        if (bDirectionUp)
141
 
                                fY = - fY;
142
 
                        glTranslatef (fY, 0., 1.);
143
 
                        glRotatef (90, 0., 0., 1.);
144
 
                        glScalef (w * fRatio * 1., (bDirectionUp ? 1:-1) * h * fRatio * 1., 1.);
145
 
                }
146
 
        }
147
 
 
148
 
        //\__________________ On dessine l'indicateur.
149
 
        cairo_dock_draw_texture_with_alpha (g_pIndicatorBuffer.iTexture, 1., 1., 1.);
150
 
}
151
 
static void _cairo_dock_draw_active_window_indicator_opengl (Icon *icon, CairoDock *pDock, double fRatio)
152
 
{
153
 
        if (icon->fOrientation != 0)
154
 
        {
155
 
                glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
156
 
                glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
157
 
                glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
158
 
        }
159
 
        
160
 
        cairo_dock_set_icon_scale (icon, CAIRO_CONTAINER (pDock), 1.);
161
 
        
162
 
        _cairo_dock_enable_texture ();
163
 
        
164
 
        _cairo_dock_set_blend_pbuffer ();  // rend mieux que les 2 autres.
165
 
        
166
 
        _cairo_dock_apply_texture_at_size_with_alpha (g_pActiveIndicatorBuffer.iTexture, 1., 1., 1.);
167
 
        
168
 
        _cairo_dock_disable_texture ();
169
 
        
170
 
}
171
 
static void _cairo_dock_draw_class_indicator_opengl (Icon *icon, gboolean bIsHorizontal, double fRatio, gboolean bDirectionUp)
172
 
{
173
 
        if (icon->fOrientation != 0)
174
 
        {
175
 
                glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
176
 
                glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
177
 
                glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
178
 
        }
179
 
        
180
 
        if (myIndicators.bZoomClassIndicator)
181
 
                fRatio *= icon->fScale;
182
 
        double w = g_pClassIndicatorBuffer.iWidth;
183
 
        double h = g_pClassIndicatorBuffer.iHeight;
184
 
        
185
 
        if (! bIsHorizontal)
186
 
                glRotatef (90., 0., 0., 1.);
187
 
        if (! bDirectionUp)
188
 
                glScalef (1., -1., 1.);
189
 
        glTranslatef (icon->fWidth * icon->fScale/2 - w * fRatio/2,
190
 
                icon->fHeight * icon->fScale/2 - h * fRatio/2,
191
 
                0.);
192
 
        
193
 
        cairo_dock_draw_texture_with_alpha (g_pClassIndicatorBuffer.iTexture,
194
 
                w * fRatio,
195
 
                h * fRatio,
196
 
                1.);
197
 
}
198
 
 
199
 
void cairo_dock_set_icon_scale (Icon *pIcon, CairoContainer *pContainer, double fZoomFactor)
200
 
{
201
 
        double fSizeX, fSizeY;
202
 
        cairo_dock_get_current_icon_size (pIcon, pContainer, &fSizeX, &fSizeY);
203
 
        glScalef (fSizeX * fZoomFactor, fSizeY * fZoomFactor, fSizeY * fZoomFactor);
204
 
}
205
 
 
206
 
 
207
 
void cairo_dock_combine_argb_argb (void)  // taken from glitz 0.5.6
208
 
{
209
 
        glEnable(GL_BLEND);
210
 
        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
211
 
        
212
 
        glActiveTexture (GL_TEXTURE0);
213
 
        glEnable(GL_TEXTURE_2D);
214
 
        glColor4f(0., 0., 0., 1.);
215
 
        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
216
 
        
217
 
        glActiveTexture (GL_TEXTURE1);
218
 
        glEnable(GL_TEXTURE_2D);
219
 
        glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
220
 
        
221
 
        glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
222
 
        glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
223
 
        glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
224
 
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
225
 
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA);
226
 
        
227
 
        glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
228
 
        glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
229
 
        glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
230
 
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
231
 
        glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
232
 
}
233
 
 
234
 
void cairo_dock_draw_icon_opengl (Icon *pIcon, CairoDock *pDock)
235
 
{
236
 
        //\_____________________ On dessine l'icone.
237
 
        double fSizeX, fSizeY;
238
 
        cairo_dock_get_current_icon_size (pIcon, CAIRO_CONTAINER (pDock), &fSizeX, &fSizeY);
239
 
        
240
 
        _cairo_dock_enable_texture ();
241
 
        if (pIcon->fAlpha == 1)
242
 
                _cairo_dock_set_blend_over ();
243
 
        else
244
 
                _cairo_dock_set_blend_alpha ();
245
 
        
246
 
        _cairo_dock_apply_texture_at_size_with_alpha (pIcon->iIconTexture, fSizeX, fSizeY, pIcon->fAlpha);
247
 
        
248
 
        //\_____________________ On dessine son reflet.
249
 
        if (pDock->container.bUseReflect)
250
 
        {
251
 
                if (pDock->pRenderer->bUseStencil)
252
 
                {
253
 
                        glEnable (GL_STENCIL_TEST);
254
 
                        glStencilFunc (GL_EQUAL, 1, 1);
255
 
                        glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
256
 
                }
257
 
                glPushMatrix ();
258
 
                double x0, y0, x1, y1;
259
 
                double fScale = ((myIcons.bConstantSeparatorSize && CAIRO_DOCK_IS_SEPARATOR (pIcon)) ? 1. : pIcon->fScale);
260
 
                double fReflectSize = MIN (myIcons.fReflectSize, pIcon->fHeight/pDock->container.fRatio*fScale);
261
 
                double fReflectRatio = fReflectSize * pDock->container.fRatio / pIcon->fHeight / fScale  / pIcon->fHeightFactor;
262
 
                double fOffsetY = pIcon->fHeight * fScale/2 + fReflectSize * pDock->container.fRatio/2 + pIcon->fDeltaYReflection;
263
 
                if (pDock->container.bIsHorizontal)
264
 
                {
265
 
                        if (pDock->container.bDirectionUp)
266
 
                        {
267
 
                                glTranslatef (0., - fOffsetY, 0.);
268
 
                                glScalef (pIcon->fWidth * pIcon->fWidthFactor * fScale, - fReflectSize * pDock->container.fRatio, 1.);  // taille du reflet et on se retourne.
269
 
                                x0 = 0.;
270
 
                                y0 = 1. - fReflectRatio;
271
 
                                x1 = 1.;
272
 
                                y1 = 1.;
273
 
                        }
274
 
                        else
275
 
                        {
276
 
                                glTranslatef (0., fOffsetY, 0.);
277
 
                                glScalef (pIcon->fWidth * pIcon->fWidthFactor * fScale, fReflectSize * pDock->container.fRatio, 1.);
278
 
                                x0 = 0.;
279
 
                                y0 = fReflectRatio;
280
 
                                x1 = 1.;
281
 
                                y1 = 0.;
282
 
                        }
283
 
                }
284
 
                else
285
 
                {
286
 
                        if (pDock->container.bDirectionUp)
287
 
                        {
288
 
                                glTranslatef (fOffsetY, 0., 0.);
289
 
                                glScalef (- fReflectSize * pDock->container.fRatio, pIcon->fWidth * pIcon->fWidthFactor * fScale, 1.);
290
 
                                x0 = 1. - fReflectRatio;
291
 
                                y0 = 0.;
292
 
                                x1 = 1.;
293
 
                                y1 = 1.;
294
 
                        }
295
 
                        else
296
 
                        {
297
 
                                glTranslatef (- fOffsetY, 0., 0.);
298
 
                                glScalef (fReflectSize * pDock->container.fRatio, pIcon->fWidth * pIcon->fWidthFactor * fScale, 1.);
299
 
                                x0 = fReflectRatio;
300
 
                                y0 = 0.;
301
 
                                x1 = 0.;
302
 
                                y1 = 1.;
303
 
                        }
304
 
                }
305
 
                
306
 
                glEnable(GL_TEXTURE_2D);
307
 
                glBindTexture(GL_TEXTURE_2D, pIcon->iIconTexture);
308
 
                glEnable(GL_BLEND);
309
 
                _cairo_dock_set_blend_alpha ();
310
 
                glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
311
 
                
312
 
                //glBlendColor(1., 1., 1., 1.);  // utile ?
313
 
                
314
 
                glPolygonMode (GL_FRONT, GL_FILL);
315
 
                glColor4f(1., 1., 1., 1.);
316
 
                
317
 
                glBegin(GL_QUADS);
318
 
                
319
 
                double fReflectAlpha = myIcons.fAlbedo * pIcon->fAlpha;
320
 
                if (pDock->container.bIsHorizontal)
321
 
                {
322
 
                        glTexCoord2f (x0, y0);
323
 
                        glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
324
 
                        glVertex3f (-.5, .5, 0.);  // Bottom Left Of The Texture and Quad
325
 
                        
326
 
                        glTexCoord2f (x1, y0);
327
 
                        glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
328
 
                        glVertex3f (.5, .5, 0.);  // Bottom Right Of The Texture and Quad
329
 
                        
330
 
                        glTexCoord2f (x1, y1);
331
 
                        glColor4f (1., 1., 1., fReflectAlpha);
332
 
                        glVertex3f (.5, -.5, 0.);  // Top Right Of The Texture and Quad
333
 
                        
334
 
                        glTexCoord2f (x0, y1);
335
 
                        glColor4f (1., 1., 1., fReflectAlpha);
336
 
                        glVertex3f (-.5, -.5, 0.);  // Top Left Of The Texture and Quad
337
 
                }
338
 
                else
339
 
                {
340
 
                        glTexCoord2f (x0, y0);
341
 
                        glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
342
 
                        glVertex3f (-.5, .5, 0.);  // Bottom Left Of The Texture and Quad
343
 
                        
344
 
                        glTexCoord2f (x1, y0);
345
 
                        glColor4f (1., 1., 1., fReflectAlpha);
346
 
                        glVertex3f (.5, .5, 0.);  // Bottom Right Of The Texture and Quad
347
 
                        
348
 
                        glTexCoord2f (x1, y1);
349
 
                        glColor4f (1., 1., 1., fReflectAlpha);
350
 
                        glVertex3f (.5, -.5, 0.);  // Top Right Of The Texture and Quad
351
 
                        
352
 
                        glTexCoord2f (x0, y1);
353
 
                        glColor4f (1., 1., 1., fReflectAlpha * pIcon->fReflectShading);
354
 
                        glVertex3f (-.5, -.5, 0.);  // Top Left Of The Texture and Quad
355
 
                }
356
 
                glEnd();
357
 
                
358
 
                glPopMatrix ();
359
 
                if (pDock->pRenderer->bUseStencil)
360
 
                {
361
 
                        glDisable (GL_STENCIL_TEST);
362
 
                }
363
 
        }
364
 
        
365
 
        _cairo_dock_disable_texture ();
366
 
}
367
 
 
368
 
 
369
 
static inline void _compute_icon_coordinate (Icon *icon, CairoContainer *pContainer, double fDockMagnitude, double *pX, double *pY)
370
 
{
371
 
        double fX=0, fY=0;
372
 
        double fRatio = pContainer->fRatio;
373
 
        double fGlideScale;
374
 
        if (icon->fGlideOffset != 0)
375
 
        {
376
 
                double fPhase =  icon->fPhase + icon->fGlideOffset * icon->fWidth / fRatio / myIcons.iSinusoidWidth * G_PI;
377
 
                if (fPhase < 0)
378
 
                {
379
 
                        fPhase = 0;
380
 
                }
381
 
                else if (fPhase > G_PI)
382
 
                {
383
 
                        fPhase = G_PI;
384
 
                }
385
 
                fGlideScale = (1 + fDockMagnitude * myIcons.fAmplitude * sin (fPhase)) / icon->fScale;  // c'est un peu hacky ... il faudrait passer l'icone precedente en parametre ...
386
 
                if (! pContainer->bDirectionUp)
387
 
                        if (pContainer->bIsHorizontal)
388
 
                                fY = (1-fGlideScale)*icon->fHeight*icon->fScale;
389
 
                        else
390
 
                                fX = (1-fGlideScale)*icon->fHeight*icon->fScale;
391
 
        }
392
 
        else
393
 
                fGlideScale = 1;
394
 
        icon->fGlideScale = fGlideScale;
395
 
        
396
 
        if (pContainer->bIsHorizontal)
397
 
        {
398
 
                fY += pContainer->iHeight - icon->fDrawY;  // ordonnee du haut de l'icone.
399
 
                fX += icon->fDrawX + icon->fWidth * icon->fScale/2 + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1);  // abscisse du milieu de l'icone.
400
 
        }
401
 
        else
402
 
        {
403
 
                fY += icon->fDrawY;  // ordonnee du haut de l'icone.
404
 
                fX +=  pContainer->iWidth - (icon->fDrawX + icon->fWidth * icon->fScale/2 + icon->fGlideOffset * icon->fWidth * icon->fScale * (icon->fGlideOffset < 0 ? fGlideScale : 1));
405
 
        }
406
 
        *pX = fX;
407
 
        *pY = fY;
408
 
}
409
 
 
410
 
void cairo_dock_translate_on_icon_opengl (Icon *icon, CairoContainer *pContainer, double fDockMagnitude)
411
 
{
412
 
        double fX=0, fY=0;
413
 
        _compute_icon_coordinate (icon, pContainer, fDockMagnitude, &fX, &fY);
414
 
        
415
 
        if (pContainer->bIsHorizontal)
416
 
                glTranslatef (floor (fX), floor (fY - icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2)), - icon->fHeight * (1+myIcons.fAmplitude));
417
 
        else
418
 
                glTranslatef (floor (fY + icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2)), floor (fX), - icon->fHeight * (1+myIcons.fAmplitude));
419
 
}
420
 
 
421
 
void cairo_dock_render_one_icon_opengl (Icon *icon, CairoDock *pDock, double fDockMagnitude, gboolean bUseText)
422
 
{
423
 
        if (icon->iIconTexture == 0)
424
 
                return ;
425
 
        double fRatio = pDock->container.fRatio;
426
 
        
427
 
        if (g_pGradationTexture[pDock->container.bIsHorizontal] == 0)
428
 
        {
429
 
                //g_pGradationTexture[pDock->container.bIsHorizontal] = cairo_dock_load_local_texture (pDock->container.bIsHorizontal ? "texture-gradation-vert.png" : "texture-gradation-horiz.png", CAIRO_DOCK_SHARE_DATA_DIR);
430
 
                g_pGradationTexture[pDock->container.bIsHorizontal] = cairo_dock_load_texture_from_raw_data (gradationTex,
431
 
                        pDock->container.bIsHorizontal ? 1:48,
432
 
                        pDock->container.bIsHorizontal ? 48:1);
433
 
                cd_debug ("g_pGradationTexture(%d) <- %d", pDock->container.bIsHorizontal, g_pGradationTexture[pDock->container.bIsHorizontal]);
434
 
        }
435
 
        if (CAIRO_DOCK_IS_APPLI (icon) && myTaskBar.fVisibleAppliAlpha != 0 && ! CAIRO_DOCK_IS_APPLET (icon) && !(icon->iBackingPixmap != 0 && icon->bIsHidden))
436
 
        {
437
 
                double fAlpha = (icon->bIsHidden ? MIN (1 - myTaskBar.fVisibleAppliAlpha, 1) : MIN (myTaskBar.fVisibleAppliAlpha + 1, 1));
438
 
                if (fAlpha != 1)
439
 
                        icon->fAlpha = fAlpha;  // astuce bidon pour pas multiplier 2 fois.
440
 
        }
441
 
        
442
 
        //\_____________________ On se place au centre de l'icone.
443
 
        double fX=0, fY=0;
444
 
        _compute_icon_coordinate (icon, CAIRO_CONTAINER (pDock), fDockMagnitude, &fX, &fY);
445
 
        
446
 
        glPushMatrix ();
447
 
        if (pDock->container.bIsHorizontal)
448
 
                glTranslatef (fX, fY - icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2), - icon->fHeight * (1+myIcons.fAmplitude));
449
 
        else
450
 
                glTranslatef (fY + icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2), fX, - icon->fHeight * (1+myIcons.fAmplitude));
451
 
        
452
 
        //\_____________________ On dessine les indicateur derriere.
453
 
        if (icon->bHasIndicator && ! myIndicators.bIndicatorAbove /*&& g_iIndicatorTexture != 0*/)
454
 
        {
455
 
                glPushMatrix ();
456
 
                _cairo_dock_draw_appli_indicator_opengl (icon, pDock->container.bIsHorizontal, fRatio, pDock->container.bDirectionUp);
457
 
                glPopMatrix ();
458
 
        }
459
 
        gboolean bIsActive = FALSE;
460
 
        Window xActiveId = cairo_dock_get_current_active_window ();
461
 
        if (xActiveId != 0 && g_pActiveIndicatorBuffer.pSurface != NULL)
462
 
        {
463
 
                bIsActive = (icon->Xid == xActiveId);
464
 
                if (!bIsActive && icon->pSubDock != NULL)
465
 
                {
466
 
                        Icon *subicon;
467
 
                        GList *ic;
468
 
                        for (ic = icon->pSubDock->icons; ic != NULL; ic = ic->next)
469
 
                        {
470
 
                                subicon = ic->data;
471
 
                                if (subicon->Xid == xActiveId)
472
 
                                {
473
 
                                        bIsActive = TRUE;
474
 
                                        break;
475
 
                                }
476
 
                        }
477
 
                }
478
 
        }
479
 
        if (bIsActive && ! myIndicators.bActiveIndicatorAbove)
480
 
        {
481
 
                glPushMatrix ();
482
 
                _cairo_dock_draw_active_window_indicator_opengl (icon, pDock, fRatio);
483
 
                glPopMatrix ();
484
 
        }
485
 
        
486
 
        //\_____________________ On positionne l'icone.
487
 
        glPushMatrix ();
488
 
        if (myIcons.bConstantSeparatorSize && CAIRO_DOCK_IS_SEPARATOR (icon))
489
 
        {
490
 
                if (pDock->container.bIsHorizontal)
491
 
                {
492
 
                        glTranslatef (0., (pDock->container.bDirectionUp ? icon->fHeight * (- icon->fScale + 1)/2 : icon->fHeight * (icon->fScale - 1)/2), 0.);
493
 
                }
494
 
                else
495
 
                {
496
 
                        glTranslatef ((!pDock->container.bDirectionUp ? icon->fHeight * (- icon->fScale + 1)/2 : icon->fHeight * (icon->fScale - 1)/2), 0., 0.);
497
 
                }
498
 
        }
499
 
        glTranslatef (0., 0., - icon->fHeight * (1+myIcons.fAmplitude));
500
 
        if (icon->fOrientation != 0)
501
 
        {
502
 
                glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
503
 
                glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
504
 
                glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
505
 
        }
506
 
        if (icon->iRotationX != 0)
507
 
                glRotatef (icon->iRotationX, 1., 0., 0.);
508
 
        if (icon->iRotationY != 0)
509
 
                glRotatef (icon->iRotationY, 0., 1., 0.);
510
 
        
511
 
        //\_____________________ On dessine l'icone.
512
 
        gboolean bIconHasBeenDrawn = FALSE;
513
 
        cairo_dock_notify (CAIRO_DOCK_PRE_RENDER_ICON, icon, pDock);
514
 
        cairo_dock_notify (CAIRO_DOCK_RENDER_ICON, icon, pDock, &bIconHasBeenDrawn, NULL);
515
 
        
516
 
        glPopMatrix ();  // retour juste apres la translation au milieu de l'icone.
517
 
        
518
 
        //\_____________________ On dessine les indicateurs devant.
519
 
        if (icon->bHasIndicator && myIndicators.bIndicatorAbove/* && g_iIndicatorTexture != 0*/)
520
 
        {
521
 
                glPushMatrix ();
522
 
                glTranslatef (0., 0., icon->fHeight * (1+myIcons.fAmplitude) -1);  // avant-plan
523
 
                _cairo_dock_draw_appli_indicator_opengl (icon, pDock->container.bIsHorizontal, fRatio, pDock->container.bDirectionUp);
524
 
                glPopMatrix ();
525
 
        }
526
 
        if (bIsActive && myIndicators.bActiveIndicatorAbove)
527
 
        {
528
 
                glPushMatrix ();
529
 
                glTranslatef (0., 0., icon->fHeight * (1+myIcons.fAmplitude) -1);  // avant-plan
530
 
                _cairo_dock_draw_active_window_indicator_opengl (icon, pDock, fRatio);
531
 
                glPopMatrix ();
532
 
        }
533
 
        if (icon->pSubDock != NULL && icon->cClass != NULL && g_pClassIndicatorBuffer.pSurface != NULL && icon->Xid == 0)  // le dernier test est de la paranoia.
534
 
        {
535
 
                glPushMatrix ();
536
 
                glTranslatef (0., 0., icon->fHeight * (1+myIcons.fAmplitude) -1);  // avant-plan
537
 
                _cairo_dock_draw_class_indicator_opengl (icon, pDock->container.bIsHorizontal, fRatio, pDock->container.bDirectionUp);
538
 
                glPopMatrix ();
539
 
        }
540
 
        
541
 
        //\_____________________ On dessine les infos additionnelles.
542
 
        if (icon->iQuickInfoTexture != 0)
543
 
        {
544
 
                glPushMatrix ();
545
 
                glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
546
 
                glTranslatef (0., (- icon->fHeight + icon->iQuickInfoHeight * fRatio) * icon->fScale/2, 0.);
547
 
                
548
 
                cairo_dock_draw_texture_with_alpha (icon->iQuickInfoTexture,
549
 
                        icon->iQuickInfoWidth * fRatio * icon->fScale,
550
 
                        icon->iQuickInfoHeight * fRatio * icon->fScale,
551
 
                        icon->fAlpha);
552
 
                
553
 
                glPopMatrix ();
554
 
        }
555
 
        
556
 
        //\_____________________ On dessine les etiquettes, avec un alpha proportionnel au facteur d'echelle de leur icone.
557
 
        glPopMatrix ();  // retour au debut de la fonction.
558
 
        if (bUseText && icon->iLabelTexture != 0 && (icon->fScale > 1.01 || myIcons.fAmplitude == 0) && (! myLabels.bLabelForPointedIconOnly || icon->bPointed))  // 1.01 car sin(pi) = 1+epsilon :-/  //  && icon->iAnimationState < CAIRO_DOCK_STATE_CLICKED
559
 
        {
560
 
                glPushMatrix ();
561
 
                if (pDock->container.bIsHorizontal)
562
 
                        glTranslatef (floor (fX), floor (fY - icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2)), - icon->fHeight * (1+myIcons.fAmplitude));
563
 
                else
564
 
                        glTranslatef (floor (fY + icon->fHeight * icon->fScale * (1 - icon->fGlideScale/2)), floor (fX), - icon->fHeight * (1+myIcons.fAmplitude));
565
 
                
566
 
                double fOffsetX = 0.;
567
 
                if (icon->fDrawX + icon->fWidth * icon->fScale/2 - icon->iTextWidth/2 < 0)
568
 
                        fOffsetX = icon->iTextWidth/2 - (icon->fDrawX + icon->fWidth * icon->fScale/2);
569
 
                else if (icon->fDrawX + icon->fWidth * icon->fScale/2 + icon->iTextWidth/2 > pDock->container.iWidth)
570
 
                        fOffsetX = pDock->container.iWidth - (icon->fDrawX + icon->fWidth * icon->fScale/2 + icon->iTextWidth/2);
571
 
                if (icon->fOrientation != 0 && ! mySystem.bTextAlwaysHorizontal)
572
 
                {
573
 
                        glTranslatef (-icon->fWidth * icon->fScale/2, icon->fHeight * icon->fScale/2, 0.);
574
 
                        glRotatef (-icon->fOrientation/G_PI*180., 0., 0., 1.);
575
 
                        glTranslatef (icon->fWidth * icon->fScale/2, -icon->fHeight * icon->fScale/2, 0.);
576
 
                }
577
 
                
578
 
                double dx = .5 * (icon->iTextWidth & 1);  // on decale la texture pour la coller sur la grille des coordonnees entieres.
579
 
                if (! pDock->container.bIsHorizontal && mySystem.bTextAlwaysHorizontal)
580
 
                {
581
 
                        glTranslatef (ceil (-icon->fHeight * icon->fScale/2 - (pDock->container.bDirectionUp ? myLabels.iLabelSize : (pDock->container.bUseReflect ? myIcons.fReflectSize : 0.)) + icon->iTextWidth / 2 - myLabels.iconTextDescription.iMargin + 1) + dx,
582
 
                                floor ((icon->fWidth * icon->fScale + icon->iTextHeight) / 2) + dx,
583
 
                                0.);
584
 
                }
585
 
                else if (pDock->container.bIsHorizontal)
586
 
                {
587
 
                        glTranslatef (floor (fOffsetX) + dx, floor ((pDock->container.bDirectionUp ? 1:-1) * (icon->fHeight * icon->fScale/2 + myLabels.iLabelSize - icon->iTextHeight / 2)) + dx, 0.);
588
 
                }
589
 
                else
590
 
                {
591
 
                        glTranslatef (floor ((pDock->container.bDirectionUp ? -.5:.5) * (icon->fHeight * icon->fScale + icon->iTextHeight)) + dx,
592
 
                                floor (fOffsetX) + dx,
593
 
                                0.);
594
 
                        glRotatef (pDock->container.bDirectionUp ? 90 : -90, 0., 0., 1.);
595
 
                }
596
 
                
597
 
                double fMagnitude;
598
 
                if (myLabels.bLabelForPointedIconOnly)
599
 
                {
600
 
                        fMagnitude = fDockMagnitude;  // (icon->fScale - 1) / myIcons.fAmplitude / sin (icon->fPhase);  // sin (phi ) != 0 puisque fScale > 1.
601
 
                }
602
 
                else
603
 
                {
604
 
                        fMagnitude = (icon->fScale - 1) / myIcons.fAmplitude;  /// il faudrait diviser par pDock->fMagnitudeMax ...
605
 
                        fMagnitude = pow (fMagnitude, mySystem.fLabelAlphaThreshold);
606
 
                        ///fMagnitude *= (fMagnitude * mySystem.fLabelAlphaThreshold + 1) / (mySystem.fLabelAlphaThreshold + 1);
607
 
                }
608
 
                
609
 
                cairo_dock_draw_texture_with_alpha (icon->iLabelTexture,
610
 
                        icon->iTextWidth,
611
 
                        icon->iTextHeight,
612
 
                        fMagnitude);
613
 
                
614
 
                glPopMatrix ();
615
 
        }
616
 
}
617
 
 
618
 
 
619
 
void cairo_dock_render_hidden_dock_opengl (CairoDock *pDock)
620
 
{
621
 
        //g_print ("%s (%d, %x)\n", __func__, pDock->bIsMainDock, g_pVisibleZoneSurface);
622
 
        //\_____________________ on dessine la zone de rappel.
623
 
        glLoadIdentity ();  // annule l'offset de cachage.
624
 
        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | (pDock->pRenderer->bUseStencil ? GL_STENCIL_BUFFER_BIT : 0));
625
 
        cairo_dock_apply_desktop_background_opengl (CAIRO_CONTAINER (pDock));
626
 
        
627
 
        if (g_pVisibleZoneBuffer.iTexture != 0)
628
 
        {
629
 
                _cairo_dock_enable_texture ();
630
 
                _cairo_dock_set_blend_over ();
631
 
                _cairo_dock_set_alpha (myBackground.fVisibleZoneAlpha);
632
 
                int w = MIN (myAccessibility.iVisibleZoneWidth, pDock->container.iWidth);
633
 
                int h = MIN (myAccessibility.iVisibleZoneHeight, pDock->container.iHeight);
634
 
                cd_debug ("%s (%dx%d)", __func__, w, h);
635
 
                
636
 
                if (pDock->container.bIsHorizontal)
637
 
                {
638
 
                        if (pDock->container.bDirectionUp)
639
 
                                glTranslatef ((pDock->container.iWidth)/2, h/2, 0.);
640
 
                        else
641
 
                                glTranslatef ((pDock->container.iWidth)/2, pDock->container.iHeight - h/2, 0.);
642
 
                }
643
 
                else
644
 
                {
645
 
                        if (!pDock->container.bDirectionUp)
646
 
                                glTranslatef (h/2, (pDock->container.iWidth)/2, 0.);
647
 
                        else
648
 
                                glTranslatef (pDock->container.iHeight - h/2, (pDock->container.iWidth)/2, 0.);
649
 
                }
650
 
                
651
 
                if (! pDock->container.bIsHorizontal)
652
 
                        glRotatef (90., 0, 0, 1);
653
 
                if (! pDock->container.bDirectionUp && myBackground.bReverseVisibleImage)
654
 
                        glScalef (1., -1., 1.);
655
 
                
656
 
                _cairo_dock_apply_texture_at_size (g_pVisibleZoneBuffer.iTexture, w, h);
657
 
                
658
 
                _cairo_dock_disable_texture ();
659
 
        }
660
 
        
661
 
        //\_____________________ on dessine les icones demandant l'attention.
662
 
        //if (myTaskBar.cAnimationOnDemandsAttention)
663
 
        {
664
 
                GList *pFirstDrawnElement = cairo_dock_get_first_drawn_element_linear (pDock->icons);
665
 
                if (pFirstDrawnElement == NULL)
666
 
                        return;
667
 
                double fDockMagnitude = cairo_dock_calculate_magnitude (pDock->iMagnitudeIndex);
668
 
                
669
 
                double y;
670
 
                Icon *icon;
671
 
                GList *ic = pFirstDrawnElement;
672
 
                do
673
 
                {
674
 
                        icon = ic->data;
675
 
                        if (icon->bIsDemandingAttention)
676
 
                        {
677
 
                                //g_print ("%s : %d (%d)\n", icon->cName, icon->bIsDemandingAttention, icon->Xid);
678
 
                                y = icon->fDrawY;
679
 
                                icon->fDrawY = (pDock->container.bDirectionUp ? pDock->container.iHeight - icon->fHeight * icon->fScale : 0.);
680
 
                                glPushMatrix ();
681
 
                                cairo_dock_render_one_icon_opengl (icon, pDock, fDockMagnitude, TRUE);
682
 
                                glPopMatrix ();
683
 
                                icon->fDrawY = y;
684
 
                        }
685
 
                        ic = cairo_dock_get_next_element (ic, pDock->icons);
686
 
                } while (ic != pFirstDrawnElement);
687
 
        }
688
 
}
689
 
 
690
 
 
691
 
 
692
 
GLuint cairo_dock_create_texture_from_surface (cairo_surface_t *pImageSurface)
693
 
{
694
 
        if (! g_bUseOpenGL || pImageSurface == NULL)
695
 
                return 0;
696
 
        GLuint iTexture = 0;
697
 
        int w = cairo_image_surface_get_width (pImageSurface);
698
 
        int h = cairo_image_surface_get_height (pImageSurface);
699
 
        
700
 
        cairo_surface_t *pPowerOfwoSurface = pImageSurface;
701
 
        
702
 
        int iMaxTextureWidth = 4096, iMaxTextureHeight = 4096;  // il faudrait le recuperer de glInfo ...
703
 
        if (! g_openglConfig.bNonPowerOfTwoAvailable)  // cas des vieilles cartes comme la GeForce5.
704
 
        {
705
 
                double log2_w = log (w) / log (2);
706
 
                double log2_h = log (h) / log (2);
707
 
                int w_ = MIN (iMaxTextureWidth, pow (2, ceil (log2_w)));
708
 
                int h_ = MIN (iMaxTextureHeight, pow (2, ceil (log2_h)));
709
 
                cd_debug ("%dx%d --> %dx%d", w, h, w_, h_);
710
 
                
711
 
                if (w != w_ || h != h_)
712
 
                {
713
 
                        pPowerOfwoSurface = _cairo_dock_create_blank_surface (NULL, w_, h_);
714
 
                        cairo_t *pCairoContext = cairo_create (pPowerOfwoSurface);
715
 
                        cairo_scale (pCairoContext, (double) w_ / w, (double) h_ / h);
716
 
                        cairo_set_source_surface (pCairoContext, pImageSurface, 0., 0.);
717
 
                        cairo_paint (pCairoContext);
718
 
                        cairo_destroy (pCairoContext);
719
 
                        w = w_;
720
 
                        h = h_;
721
 
                }
722
 
        }
723
 
        
724
 
        glEnable(GL_TEXTURE_2D);
725
 
        glGenTextures (1, &iTexture);
726
 
        cd_debug ("+ texture %d generee (%x, %dx%d)", iTexture, cairo_image_surface_get_data (pImageSurface), w, h);
727
 
        glBindTexture (GL_TEXTURE_2D, iTexture);
728
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
729
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
730
 
        /*if (g_bEasterEggs)
731
 
                gluBuild2DMipmaps (GL_TEXTURE_2D,
732
 
                        4,
733
 
                        w,
734
 
                        h,
735
 
                        GL_BGRA,
736
 
                        GL_UNSIGNED_BYTE,
737
 
                        cairo_image_surface_get_data (pPowerOfwoSurface));
738
 
        else*/
739
 
                glTexImage2D (GL_TEXTURE_2D,
740
 
                        0,
741
 
                        4,  // GL_ALPHA / GL_BGRA
742
 
                        w,
743
 
                        h,
744
 
                        0,
745
 
                        GL_BGRA,  // GL_ALPHA / GL_BGRA
746
 
                        GL_UNSIGNED_BYTE,
747
 
                        cairo_image_surface_get_data (pPowerOfwoSurface));
748
 
        if (pPowerOfwoSurface != pImageSurface)
749
 
                cairo_surface_destroy (pPowerOfwoSurface);
750
 
        glDisable(GL_TEXTURE_2D);
751
 
        return iTexture;
752
 
}
753
 
 
754
 
GLuint cairo_dock_load_texture_from_raw_data (const guchar *pTextureRaw, int iWidth, int iHeight)
755
 
{
756
 
        /*g_print ("%dx%d\n", iWidth, iHeight);
757
 
        int i;
758
 
        guint pixel, alpha, red, green, blue;
759
 
        float fAlphaFactor;
760
 
        guint *pPixelBuffer = (guint *) pTextureRaw;
761
 
        guint *pPixelBuffer2 = g_new (guint, iHeight * iWidth);
762
 
        for (i = 0; i < iHeight * iWidth; i ++)
763
 
        {
764
 
                pixel = (gint) pPixelBuffer[i];
765
 
                alpha = (pixel & 0xFF000000) >> 24;
766
 
                red = (pixel & 0x00FF0000) >> 16;
767
 
                green = (pixel & 0x0000FF00) >> 8;
768
 
                blue  = (pixel & 0x000000FF);
769
 
                fAlphaFactor = (float) alpha / 255.;
770
 
                red *= fAlphaFactor;
771
 
                green *= fAlphaFactor;
772
 
                blue *= fAlphaFactor;
773
 
                pPixelBuffer2[i] = (pixel & 0xFF000000) + (red << 16) + (green << 8) + (blue << 0);
774
 
                g_print ("\\%o\\%o\\%o\\%o", red, green, blue, alpha);
775
 
        }
776
 
        pTextureRaw = pPixelBuffer2;*/
777
 
        GLuint iTexture = 0;
778
 
        
779
 
        glEnable (GL_TEXTURE_2D);
780
 
        glGenTextures(1, &iTexture);
781
 
        glBindTexture(GL_TEXTURE_2D, iTexture);
782
 
        
783
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
784
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
785
 
        
786
 
        glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, iWidth, iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTextureRaw);
787
 
        glBindTexture (GL_TEXTURE_2D, 0);
788
 
        glDisable(GL_TEXTURE_2D);
789
 
        return iTexture;
790
 
}
791
 
 
792
 
GLuint cairo_dock_create_texture_from_image_full (const gchar *cImageFile, double *fImageWidth, double *fImageHeight)
793
 
{
794
 
        g_return_val_if_fail (GTK_WIDGET_REALIZED (g_pMainDock->container.pWidget), 0);
795
 
        double fWidth=0, fHeight=0;
796
 
        if (cImageFile == NULL)
797
 
                return 0;
798
 
        gchar *cImagePath;
799
 
        if (*cImageFile == '/')
800
 
                cImagePath = (gchar *)cImageFile;
801
 
        else
802
 
                cImagePath = cairo_dock_generate_file_path (cImageFile);
803
 
        
804
 
        cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (g_pMainDock));
805
 
        cairo_surface_t *pSurface = cairo_dock_create_surface_from_image (cImagePath,
806
 
                pCairoContext,
807
 
                1.,
808
 
                0., 0.,
809
 
                CAIRO_DOCK_KEEP_RATIO,
810
 
                &fWidth,
811
 
                &fHeight,
812
 
                NULL, NULL);
813
 
        //cd_debug ("texture genere (%x, %.2fx%.2f)", pSurface, fWidth, fHeight);
814
 
        cairo_destroy (pCairoContext);
815
 
        
816
 
        if (fImageWidth != NULL)
817
 
                *fImageWidth = fWidth;
818
 
        if (fImageHeight != NULL)
819
 
                *fImageHeight = fHeight;
820
 
        GLuint iTexture = cairo_dock_create_texture_from_surface (pSurface);
821
 
        cairo_surface_destroy (pSurface);
822
 
        if (cImagePath != cImageFile)
823
 
                g_free (cImagePath);
824
 
        return iTexture;
825
 
}
826
 
 
827
 
 
828
 
void cairo_dock_update_icon_texture (Icon *pIcon)
829
 
{
830
 
        if (pIcon != NULL && pIcon->pIconBuffer != NULL)
831
 
        {
832
 
                glEnable (GL_TEXTURE_2D);
833
 
                if (pIcon->iIconTexture == 0)
834
 
                        glGenTextures (1, &pIcon->iIconTexture);
835
 
                int w = cairo_image_surface_get_width (pIcon->pIconBuffer);
836
 
                int h = cairo_image_surface_get_height (pIcon->pIconBuffer);
837
 
                glBindTexture (GL_TEXTURE_2D, pIcon->iIconTexture);
838
 
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
839
 
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
840
 
                
841
 
                glTexImage2D (GL_TEXTURE_2D,
842
 
                        0,
843
 
                        4,  // GL_ALPHA / GL_BGRA
844
 
                        w,
845
 
                        h,
846
 
                        0,
847
 
                        GL_BGRA,  // GL_ALPHA / GL_BGRA
848
 
                        GL_UNSIGNED_BYTE,
849
 
                        cairo_image_surface_get_data (pIcon->pIconBuffer));
850
 
                glDisable (GL_TEXTURE_2D);
851
 
        }
852
 
}
853
 
 
854
 
void cairo_dock_update_label_texture (Icon *pIcon)
855
 
{
856
 
        if (pIcon->iLabelTexture != 0)
857
 
        {
858
 
                _cairo_dock_delete_texture (pIcon->iLabelTexture);
859
 
                pIcon->iLabelTexture = 0;
860
 
        }
861
 
        if (pIcon != NULL && pIcon->pTextBuffer != NULL)
862
 
        {
863
 
                glEnable (GL_TEXTURE_2D);
864
 
                glGenTextures (1, &pIcon->iLabelTexture);
865
 
                int w = cairo_image_surface_get_width (pIcon->pTextBuffer);
866
 
                int h = cairo_image_surface_get_height (pIcon->pTextBuffer);
867
 
                glBindTexture (GL_TEXTURE_2D, pIcon->iLabelTexture);
868
 
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
869
 
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
870
 
                glTexImage2D (GL_TEXTURE_2D,
871
 
                        0,
872
 
                        4,  // GL_ALPHA / GL_BGRA
873
 
                        w,
874
 
                        h,
875
 
                        0,
876
 
                        GL_BGRA,  // GL_ALPHA / GL_BGRA
877
 
                        GL_UNSIGNED_BYTE,
878
 
                        cairo_image_surface_get_data (pIcon->pTextBuffer));
879
 
                glDisable (GL_TEXTURE_2D);
880
 
        }
881
 
}
882
 
 
883
 
void cairo_dock_update_quick_info_texture (Icon *pIcon)
884
 
{
885
 
        if (pIcon->iQuickInfoTexture != 0)
886
 
        {
887
 
                _cairo_dock_delete_texture (pIcon->iQuickInfoTexture);
888
 
                pIcon->iQuickInfoTexture = 0;
889
 
        }
890
 
        if (pIcon != NULL && pIcon->pQuickInfoBuffer != NULL)
891
 
        {
892
 
                glEnable (GL_TEXTURE_2D);
893
 
                glGenTextures (1, &pIcon->iQuickInfoTexture);
894
 
                int w = cairo_image_surface_get_width (pIcon->pQuickInfoBuffer);
895
 
                int h = cairo_image_surface_get_height (pIcon->pQuickInfoBuffer);
896
 
                glBindTexture (GL_TEXTURE_2D, pIcon->iQuickInfoTexture);
897
 
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
898
 
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
899
 
                glTexImage2D (GL_TEXTURE_2D,
900
 
                        0,
901
 
                        4,  // GL_ALPHA / GL_BGRA
902
 
                        w,
903
 
                        h,
904
 
                        0,
905
 
                        GL_BGRA,  // GL_ALPHA / GL_BGRA
906
 
                        GL_UNSIGNED_BYTE,
907
 
                        cairo_image_surface_get_data (pIcon->pQuickInfoBuffer));
908
 
                glDisable (GL_TEXTURE_2D);
909
 
        }
910
 
}
911
 
 
912
 
 
913
 
 
914
 
void cairo_dock_draw_texture_with_alpha (GLuint iTexture, int iWidth, int iHeight, double fAlpha)
915
 
{
916
 
        _cairo_dock_enable_texture ();
917
 
        if (fAlpha == 1)
918
 
                _cairo_dock_set_blend_over ();
919
 
        else
920
 
                _cairo_dock_set_blend_alpha ();
921
 
                //_cairo_dock_set_blend_alpha ();
922
 
        
923
 
        _cairo_dock_apply_texture_at_size_with_alpha (iTexture, iWidth, iHeight, fAlpha);
924
 
        
925
 
        _cairo_dock_disable_texture ();
926
 
}
927
 
 
928
 
void cairo_dock_draw_texture (GLuint iTexture, int iWidth, int iHeight)
929
 
{
930
 
        cairo_dock_draw_texture_with_alpha (iTexture, iWidth, iHeight, 1.);
931
 
}
932
 
 
933
 
void cairo_dock_apply_icon_texture_at_current_size (Icon *pIcon, CairoContainer *pContainer)
934
 
{
935
 
        double fSizeX, fSizeY;
936
 
        cairo_dock_get_current_icon_size (pIcon, pContainer, &fSizeX, &fSizeY);
937
 
        
938
 
        _cairo_dock_apply_texture_at_size (pIcon->iIconTexture, fSizeX, fSizeY);
939
 
}
940
 
 
941
 
void cairo_dock_draw_icon_texture (Icon *pIcon, CairoContainer *pContainer)
942
 
{
943
 
        double fSizeX, fSizeY;
944
 
        cairo_dock_get_current_icon_size (pIcon, pContainer, &fSizeX, &fSizeY);
945
 
        
946
 
        cairo_dock_draw_texture_with_alpha (pIcon->iIconTexture,
947
 
                fSizeX,
948
 
                fSizeY,
949
 
                pIcon->fAlpha);
950
 
}
951
 
 
952
 
static inline void  _draw_icon_bent_backwards (Icon *pIcon, CairoContainer *pContainer, GLuint iOriginalTexture, double f)
953
 
{
954
 
        int iWidth, iHeight;
955
 
        cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
956
 
        cairo_dock_set_perspective_view (iWidth, iHeight);
957
 
        glScalef (1., -1., 1.);
958
 
        glTranslatef (0., -iHeight/2, 0.);  // rotation de 50Ā° sur l'axe des X a la base de l'icone.
959
 
        glRotatef (-50.*f, 1., 0., 0.);
960
 
        glTranslatef (0., iHeight/2, 0.);
961
 
        
962
 
        _cairo_dock_enable_texture ();
963
 
        _cairo_dock_set_blend_source ();
964
 
        glBindTexture (GL_TEXTURE_2D, iOriginalTexture);
965
 
        _cairo_dock_apply_current_texture_at_size_with_offset (iWidth*(1+.1*f),
966
 
                iHeight*(1+.25*f),
967
 
                0.,
968
 
                iHeight*(.25/2*f));  // on elargit un peu la texture, car avec l'effet de profondeur elle parait trop petite.
969
 
        _cairo_dock_disable_texture ();
970
 
        cairo_dock_set_ortho_view (iWidth, iHeight);
971
 
}
972
 
static gboolean _transition_step (Icon *pIcon, gpointer data)
973
 
{
974
 
        CairoDock *pDock = cairo_dock_search_dock_from_name (pIcon->cParentDockName);
975
 
        if (pDock == NULL)
976
 
                return FALSE;
977
 
        
978
 
        GLuint iOriginalTexture = GPOINTER_TO_INT (data);
979
 
        double f = cairo_dock_get_transition_fraction (pIcon);
980
 
        if (!pIcon->bIsHidden)
981
 
                f = 1 - f;
982
 
        
983
 
        _draw_icon_bent_backwards (pIcon, CAIRO_CONTAINER (pDock), iOriginalTexture, f);
984
 
        return TRUE;
985
 
}
986
 
static void _free_transition_data (gpointer data)
987
 
{
988
 
        GLuint iOriginalTexture = GPOINTER_TO_INT (data);
989
 
        _cairo_dock_delete_texture (iOriginalTexture);
990
 
}
991
 
void cairo_dock_draw_hidden_appli_icon (Icon *pIcon, CairoContainer *pContainer, gboolean bStateChanged)
992
 
{
993
 
        if (bStateChanged)
994
 
        {
995
 
                cairo_dock_remove_transition_on_icon (pIcon);
996
 
                
997
 
                int iWidth, iHeight;
998
 
                cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
999
 
                
1000
 
                GLuint iOriginalTexture;
1001
 
                if (pIcon->bIsHidden)
1002
 
                {
1003
 
                        iOriginalTexture = pIcon->iIconTexture;
1004
 
                        pIcon->iIconTexture = cairo_dock_create_texture_from_surface (pIcon->pIconBuffer);
1005
 
                        /// Using FBOs copies the texture data (pixels) within VRAM only:
1006
 
                        /// - setup & bind FBO
1007
 
                        /// - setup destination texture (using glTexImage() w/ pixels = 0)
1008
 
                        /// - add (blank but sized) destination texture as color attachment
1009
 
                        /// - bind source texture to texture target
1010
 
                        /// - draw quad w/ glTexCoors describing src area, projection/modelview matrices & glVertexes describing dst area
1011
 
                }
1012
 
                else
1013
 
                {
1014
 
                        iOriginalTexture = cairo_dock_create_texture_from_surface (pIcon->pIconBuffer);
1015
 
                }
1016
 
                
1017
 
                cairo_dock_set_transition_on_icon (pIcon, pContainer, NULL,
1018
 
                        (CairoDockTransitionRenderFunc) NULL,
1019
 
                        (CairoDockTransitionGLRenderFunc) _transition_step,
1020
 
                        TRUE,  // slow
1021
 
                        500,  // ms
1022
 
                        TRUE,  // remove when finished
1023
 
                        GINT_TO_POINTER (iOriginalTexture),
1024
 
                        _free_transition_data);
1025
 
        }
1026
 
        else if (pIcon->bIsHidden)
1027
 
        {
1028
 
                if (!cairo_dock_begin_draw_icon (pIcon, pContainer))
1029
 
                        return ;
1030
 
                _draw_icon_bent_backwards (pIcon, pContainer, pIcon->iIconTexture, 1.);
1031
 
                cairo_dock_end_draw_icon (pIcon, pContainer);
1032
 
        }
1033
 
}
1034
 
 
1035
 
 
1036
 
/// PATH ///
1037
 
 
1038
 
const GLfloat *cairo_dock_generate_rectangle_path (double fDockWidth, double fFrameHeight, double fRadius, gboolean bRoundedBottomCorner, int *iNbPoints)
1039
 
{
1040
 
        //static GLfloat pVertexTab[((90/DELTA_ROUND_DEGREE+1)*4+1)*_CAIRO_DOCK_PATH_DIM];
1041
 
        _cairo_dock_define_static_vertex_tab ((90/DELTA_ROUND_DEGREE+1)*4+1);
1042
 
        
1043
 
        double fTotalWidth = fDockWidth + 2 * fRadius;
1044
 
        double w = fDockWidth / fTotalWidth / 2;
1045
 
        double h = MAX (0, fFrameHeight - 2 * fRadius) / fFrameHeight / 2;
1046
 
        double rw = fRadius / fTotalWidth;
1047
 
        double rh = fRadius / fFrameHeight;
1048
 
        int i=0, t;
1049
 
        int iPrecision = DELTA_ROUND_DEGREE;
1050
 
        for (t = 0;t <= 90;t += iPrecision, i++) // cote haut droit.
1051
 
        {
1052
 
                _cairo_dock_set_vertex_xy (i,
1053
 
                        w + rw * cos (t*RADIAN),
1054
 
                        h + rh * sin (t*RADIAN));
1055
 
                //vx(i) = w + rw * cos (t*RADIAN);
1056
 
                //vy(i) = h + rh * sin (t*RADIAN);
1057
 
        }
1058
 
        for (t = 90;t <= 180;t += iPrecision, i++) // haut gauche.
1059
 
        {
1060
 
                _cairo_dock_set_vertex_xy (i,
1061
 
                        -w + rw * cos (t*RADIAN),
1062
 
                        h + rh * sin (t*RADIAN));
1063
 
                //vx(i) = -w + rw * cos (t*RADIAN);
1064
 
                //vy(i) = h + rh * sin (t*RADIAN);
1065
 
        }
1066
 
        if (bRoundedBottomCorner)
1067
 
        {
1068
 
                for (t = 180;t <= 270;t += iPrecision, i++) // bas gauche.
1069
 
                {
1070
 
                        _cairo_dock_set_vertex_xy (i,
1071
 
                                -w + rw * cos (t*RADIAN),
1072
 
                                -h + rh * sin (t*RADIAN));
1073
 
                        //vx(i) = -w + rw * cos (t*RADIAN);
1074
 
                        //vy(i) = -h + rh * sin (t*RADIAN);
1075
 
                }
1076
 
                for (t = 270;t <= 360;t += iPrecision, i++) // bas droit.
1077
 
                {
1078
 
                        _cairo_dock_set_vertex_xy (i,
1079
 
                                w + rw * cos (t*RADIAN),
1080
 
                                -h + rh * sin (t*RADIAN));
1081
 
                        //vx(i) = w + rw * cos (t*RADIAN);
1082
 
                        //vy(i) = -h + rh * sin (t*RADIAN);
1083
 
                }
1084
 
        }
1085
 
        else
1086
 
        {
1087
 
                _cairo_dock_set_vertex_xy (i,
1088
 
                        -w - rw,
1089
 
                        -h - rh);  // bas gauche.
1090
 
                //vx(i) = -w - rw; // bas gauche.
1091
 
                //vy(i) = -h - rh;
1092
 
                i ++;
1093
 
                _cairo_dock_set_vertex_xy (i,
1094
 
                        w + rw,
1095
 
                        -h - rh);  // bas droit.
1096
 
                //vx(i) = w + rw; // bas droit.
1097
 
                //vy(i) = -h - rh;
1098
 
                i ++;
1099
 
        }
1100
 
        _cairo_dock_close_path (i);  // on boucle.
1101
 
        //vx(i) = w + rw;  // on boucle.
1102
 
        //vy(i) = h;
1103
 
        
1104
 
        *iNbPoints = i+1;
1105
 
        _cairo_dock_return_vertex_tab ();
1106
 
}
1107
 
 
1108
 
#define P(t,p,q,s) ((1-t) * (1-t) * p + 2 * t * (1-t) * q + t * t * s)
1109
 
void cairo_dock_add_simple_curved_subpath_opengl (GLfloat *pVertexTab, int iNbPts, double x0, double y0, double x1, double y1, double x2, double y2)
1110
 
{
1111
 
        double t;
1112
 
        int i;
1113
 
        for (i = 0; i < iNbPts; i ++)
1114
 
        {
1115
 
                t = 1.*i/iNbPts;  // [0;1[
1116
 
                _cairo_dock_set_vertex_xy (i,
1117
 
                        P(t, x0, x1, x2),
1118
 
                        P(t, y0, y1, y2));
1119
 
                //vx(i) = P(t, x0, x1, x2);
1120
 
                //vy(i) = P(t, y0, y1, y2);
1121
 
        }
1122
 
}
1123
 
#define NB_PTS_SIMPLE_CURVE 20
1124
 
GLfloat *cairo_dock_generate_trapeze_path (double fDockWidth, double fFrameHeight, double fRadius, gboolean bRoundedBottomCorner, double fInclination, double *fExtraWidth, int *iNbPoints)
1125
 
{
1126
 
        //static GLfloat pVertexTab[((90/DELTA_ROUND_DEGREE+1+20+1)*2+1)*_CAIRO_DOCK_PATH_DIM];
1127
 
        _cairo_dock_define_static_vertex_tab ((90/DELTA_ROUND_DEGREE+1+NB_PTS_SIMPLE_CURVE+1)*2+1);
1128
 
        
1129
 
        double a = atan (fInclination)/G_PI*180.;
1130
 
        double cosa = 1. / sqrt (1 + fInclination * fInclination);
1131
 
        double sina = cosa * fInclination;
1132
 
        
1133
 
        *fExtraWidth = fInclination * (fFrameHeight - (bRoundedBottomCorner ? 2 : 1-cosa) * fRadius) + fRadius * (bRoundedBottomCorner ? 1 : sina);
1134
 
        double fTotalWidth = fDockWidth + 2*(*fExtraWidth);
1135
 
        double dw = (bRoundedBottomCorner ? fInclination * (fFrameHeight - 2 * fRadius) : *fExtraWidth) / fTotalWidth;
1136
 
        double w = fDockWidth / fTotalWidth / 2;
1137
 
        double h = MAX (0, fFrameHeight - 2 * fRadius) / fFrameHeight / 2;
1138
 
        double rw = fRadius / fTotalWidth;
1139
 
        double rh = fRadius / fFrameHeight;
1140
 
        double w_ = w + dw + (bRoundedBottomCorner ? 0 : 0*rw * cosa);
1141
 
        
1142
 
        int i=0, t;
1143
 
        int iPrecision = DELTA_ROUND_DEGREE;
1144
 
        for (t = a;t <= 90;t += iPrecision, i++) // cote haut droit.
1145
 
        {
1146
 
                _cairo_dock_set_vertex_xy (i,
1147
 
                        w + rw * cos (t*RADIAN),
1148
 
                        h + rh * sin (t*RADIAN));
1149
 
                //vx(i) = w + rw * cos (t*RADIAN);
1150
 
                //vy(i) = h + rh * sin (t*RADIAN);
1151
 
        }
1152
 
        for (t = 90;t <= 180-a;t += iPrecision, i++) // haut gauche.
1153
 
        {
1154
 
                _cairo_dock_set_vertex_xy (i,
1155
 
                        -w + rw * cos (t*RADIAN),
1156
 
                        h + rh * sin (t*RADIAN));
1157
 
                //vx(i) = -w + rw * cos (t*RADIAN);
1158
 
                //vy(i) = h + rh * sin (t*RADIAN);
1159
 
        }
1160
 
        if (bRoundedBottomCorner)
1161
 
        {
1162
 
                // OM(t) = sum ([k=0..n] Bn,k(t)*OAk)
1163
 
                // Bn,k(x) = Cn,k*x^k*(1-x)^(n-k)
1164
 
                double t = 180-a;
1165
 
                double x0 = -w_ + rw * cos (t*RADIAN);
1166
 
                double y0 = -h + rh * sin (t*RADIAN);
1167
 
                double x1 = x0 - fInclination * rw * (1+sina);
1168
 
                double y1 = -h - rh;
1169
 
                double x2 = -w_;
1170
 
                double y2 = y1;
1171
 
                for (t=0; t<=1; t+=.05, i++) // bas gauche.
1172
 
                {
1173
 
                        _cairo_dock_set_vertex_xy (i,
1174
 
                                P(t, x0, x1, x2),
1175
 
                                P(t, y0, y1, y2));
1176
 
                        //vx(i) = P(t, x0, x1, x2);
1177
 
                        //vy(i) = P(t, y0, y1, y2);
1178
 
                }
1179
 
                
1180
 
                double x3 = x0, y3 = y0;
1181
 
                x0 = - x2;
1182
 
                y0 = y2;
1183
 
                x1 = - x1;
1184
 
                x2 = - x3;
1185
 
                y2 = y3;
1186
 
                for (t=0; t<=1; t+=.05, i++) // bas gauche.
1187
 
                {
1188
 
                        _cairo_dock_set_vertex_xy (i,
1189
 
                                P(t, x0, x1, x2),
1190
 
                                P(t, y0, y1, y2));
1191
 
                        //vx(i) = P(t, x0, x1, x2);
1192
 
                        //vy(i) = P(t, y0, y1, y2);
1193
 
                }
1194
 
        }
1195
 
        else
1196
 
        {
1197
 
                _cairo_dock_set_vertex_xy (i,
1198
 
                        -w_,
1199
 
                        -h - rh);  // bas gauche.
1200
 
                //vx(i) = -w_; // bas gauche.
1201
 
                //vy(i) = -h - rh;
1202
 
                i ++;
1203
 
                _cairo_dock_set_vertex_xy (i,
1204
 
                        w_,
1205
 
                        -h - rh);  // bas droit.
1206
 
                //vx(i) = w_; // bas droit.
1207
 
                //vy(i) = -h - rh;
1208
 
                i ++;
1209
 
        }
1210
 
        _cairo_dock_close_path (i);  // on boucle.
1211
 
        //vx(i) = vx(0);  // on boucle.
1212
 
        //vy(i) = vy(0);
1213
 
        
1214
 
        *iNbPoints = i+1;
1215
 
        _cairo_dock_return_vertex_tab ();
1216
 
}
1217
 
 
1218
 
// OM(t) = sum ([k=0..n] Bn,k(t)*OAk)
1219
 
// Bn,k(x) = Cn,k*x^k*(1-x)^(n-k)
1220
 
#define B0(t) (1-t)*(1-t)*(1-t)
1221
 
#define B1(t) 3*t*(1-t)*(1-t)
1222
 
#define B2(t) 3*t*t*(1-t)
1223
 
#define B3(t) t*t*t
1224
 
#define Bezier(x0,x1,x2,x3,t) (B0(t)*x0 + B1(t)*x1 + B2(t)*x2 + B3(t)*x3)
1225
 
 
1226
 
#define _get_icon_center_x(icon) (icon->fDrawX + icon->fWidth * icon->fScale/2)
1227
 
#define _get_icon_center_y(icon) (icon->fDrawY + (bForceConstantSeparator && CAIRO_DOCK_IS_SEPARATOR (icon) ? icon->fHeight * (icon->fScale - .5) : icon->fHeight * icon->fScale/2))
1228
 
#define _get_icon_center(icon,x,y) do {\
1229
 
        if (pDock->container.bIsHorizontal) {\
1230
 
                x = _get_icon_center_x (icon);\
1231
 
                y = pDock->container.iHeight - _get_icon_center_y (icon); }\
1232
 
        else {\
1233
 
                 y = _get_icon_center_x (icon);\
1234
 
                 x = pDock->container.iWidth - _get_icon_center_y (icon); } } while (0)
1235
 
#define _calculate_slope(x0,y0,x1,y1,dx,dy) do {\
1236
 
        dx = x1 - x0;\
1237
 
        dy = y1 - y0;\
1238
 
        norme = sqrt (dx*dx + dy*dy);\
1239
 
        dx /= norme;\
1240
 
        dy /= norme; } while (0)
1241
 
#define NB_VERTEX_PER_ICON_PAIR 10
1242
 
GLfloat *cairo_dock_generate_string_path_opengl (CairoDock *pDock, gboolean bIsLoop, gboolean bForceConstantSeparator, int *iNbPoints)
1243
 
{
1244
 
        //static GLfloat pVertexTab[100*NB_VERTEX_PER_ICON_PAIR*3];
1245
 
        _cairo_dock_define_static_vertex_tab (100*NB_VERTEX_PER_ICON_PAIR);
1246
 
        
1247
 
        bForceConstantSeparator = bForceConstantSeparator || myIcons.bConstantSeparatorSize;
1248
 
        GList *ic, *next_ic, *next2_ic, *pFirstDrawnElement = (pDock->pFirstDrawnElement != NULL ? pDock->pFirstDrawnElement : pDock->icons);
1249
 
        Icon *pIcon, *pNextIcon, *pNext2Icon;
1250
 
        double x0,y0, x1,y1, x2,y2;  // centres des icones P0, P1, P2, en coordonnees opengl.
1251
 
        double norme;  // pour normaliser les pentes.
1252
 
        double dx, dy;  // direction au niveau de l'icone courante P0.
1253
 
        double dx_, dy_;  // direction au niveau de l'icone suivante P1.
1254
 
        double x0_,y0_, x1_,y1_;  // points de controle entre P0 et P1.
1255
 
        if (pFirstDrawnElement == NULL)
1256
 
        {
1257
 
                *iNbPoints = 0;
1258
 
                _cairo_dock_return_vertex_tab ();
1259
 
        }
1260
 
        
1261
 
        // direction initiale.
1262
 
        ic = pFirstDrawnElement;
1263
 
        pIcon = ic->data;
1264
 
        _get_icon_center (pIcon,x0,y0);
1265
 
        next_ic = cairo_dock_get_next_element (ic, pDock->icons);
1266
 
        pNextIcon = next_ic->data;
1267
 
        _get_icon_center (pNextIcon,x1,y1);
1268
 
        if (! bIsLoop)
1269
 
        {
1270
 
                _calculate_slope (x0,y0, x1,y1, dx,dy);
1271
 
        }
1272
 
        else
1273
 
        {
1274
 
                next2_ic = cairo_dock_get_previous_element (ic, pDock->icons);  // icone precedente dans la boucle.
1275
 
                pNext2Icon = next2_ic->data;
1276
 
                _get_icon_center (pNext2Icon,x2,y2);
1277
 
                _calculate_slope (x2,y2, x0,y0, dx,dy);
1278
 
        }
1279
 
        // point suivant.
1280
 
        next2_ic = cairo_dock_get_next_element (next_ic, pDock->icons);
1281
 
        pNext2Icon = next2_ic->data;
1282
 
        _get_icon_center (pNext2Icon,x2,y2);
1283
 
        
1284
 
        // on parcourt les icones.
1285
 
        double t;
1286
 
        int i, n=0;
1287
 
        do
1288
 
        {
1289
 
                // l'icone courante, la suivante, et celle d'apres.
1290
 
                pIcon = ic->data;
1291
 
                pNextIcon = next_ic->data;
1292
 
                pNext2Icon = next2_ic->data;
1293
 
                
1294
 
                // on va tracer de (x0,y0) a (x1,y1)
1295
 
                _get_icon_center (pIcon,x0,y0);
1296
 
                _get_icon_center (pNextIcon,x1,y1);
1297
 
                _get_icon_center (pNext2Icon,x2,y2);
1298
 
                
1299
 
                // la pente au point (x1,y1)
1300
 
                _calculate_slope (x0,y0, x2,y2, dx_,dy_);
1301
 
                
1302
 
                // points de controle.
1303
 
                norme = sqrt ((x1-x0) * (x1-x0) + (y1-y0) * (y1-y0))/2;  // distance de prolongation suivant la pente.
1304
 
                x0_ = x0 + dx * norme;
1305
 
                y0_ = y0 + dy * norme;
1306
 
                x1_ = x1 - dx_ * norme;
1307
 
                y1_ = y1 - dy_ * norme;
1308
 
                
1309
 
                for (i = 0; i < NB_VERTEX_PER_ICON_PAIR; i ++, n++)
1310
 
                {
1311
 
                        t = 1.*i/NB_VERTEX_PER_ICON_PAIR;  // [0;1[
1312
 
                        _cairo_dock_set_vertex_xy (n,
1313
 
                                Bezier (x0,x0_,x1_,x1,t),
1314
 
                                Bezier (y0,y0_,y1_,y1,t));
1315
 
                        //vx(n) = Bezier (x0,x0_,x1_,x1,t);
1316
 
                        //vy(n) = Bezier (y0,y0_,y1_,y1,t);
1317
 
                }
1318
 
                
1319
 
                // on decale tout d'un cran.
1320
 
                ic = next_ic;
1321
 
                next_ic = next2_ic;
1322
 
                next2_ic = cairo_dock_get_next_element (next_ic, pDock->icons);
1323
 
                dx = dx_;
1324
 
                dy = dy_;
1325
 
                if (next_ic == pFirstDrawnElement && ! bIsLoop)
1326
 
                        break ;
1327
 
        }
1328
 
        while (ic != pFirstDrawnElement && n < 100*NB_VERTEX_PER_ICON_PAIR);
1329
 
        
1330
 
        *iNbPoints = n;
1331
 
        _cairo_dock_return_vertex_tab ();
1332
 
}
1333
 
 
1334
 
 
1335
 
void cairo_dock_draw_frame_background_opengl (GLuint iBackgroundTexture, double fDockWidth, double fFrameHeight, double fDockOffsetX, double fDockOffsetY, const GLfloat *pVertexTab, int iNbVertex, CairoDockTypeHorizontality bHorizontal, gboolean bDirectionUp, double fDecorationsOffsetX)
1336
 
{
1337
 
        //\__________________ On mappe la texture dans le cadre.
1338
 
        glEnable(GL_BLEND); // On active le blend
1339
 
        
1340
 
        glPolygonMode(GL_FRONT, GL_FILL);
1341
 
        
1342
 
        if (iBackgroundTexture != 0)
1343
 
        {
1344
 
                glColor4f(1., 1., 1., 1.); // Couleur a fond
1345
 
                glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1346
 
                glEnable(GL_TEXTURE_2D); // Je veux de la texture
1347
 
                glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1348
 
                glBindTexture(GL_TEXTURE_2D, iBackgroundTexture); // allez on bind la texture
1349
 
                glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); // ok la on selectionne le type de generation des coordonnees de la texture
1350
 
                glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
1351
 
                glEnable(GL_TEXTURE_GEN_S); // oui je veux une generation en S
1352
 
                glEnable(GL_TEXTURE_GEN_T); // Et en T aussi
1353
 
                glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1354
 
                glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1355
 
                
1356
 
                //\__________________ bidouille de la texture.
1357
 
                glMatrixMode(GL_TEXTURE); // On selectionne la matrice des textures
1358
 
                glPushMatrix ();
1359
 
                glLoadIdentity(); // On la reset
1360
 
                glTranslatef(0.5f - fDecorationsOffsetX * myBackground.fDecorationSpeed / (fDockWidth), 0.5f, 0.);
1361
 
                glScalef (1., -1., 1.);
1362
 
                glMatrixMode(GL_MODELVIEW);
1363
 
        }
1364
 
        else
1365
 
                glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1366
 
        //\__________________ On place le cadre.
1367
 
        ///glLoadIdentity();
1368
 
        if (bHorizontal)
1369
 
        {
1370
 
                glTranslatef ((int) (fDockOffsetX + fDockWidth/2), (int) (fDockOffsetY - fFrameHeight/2), -100);  // (int) -pDock->iMaxIconHeight * (1 + myIcons.fAmplitude) + 1
1371
 
                glScalef (fDockWidth, fFrameHeight, 1.);
1372
 
        }
1373
 
        else
1374
 
        {
1375
 
                glTranslatef ((int) (fDockOffsetY - fFrameHeight/2), (int) (fDockOffsetX - fDockWidth/2), -100);
1376
 
                glScalef (fFrameHeight, fDockWidth, 1.);
1377
 
        }
1378
 
        
1379
 
        if (! bHorizontal)
1380
 
                glRotatef (bDirectionUp ? 90 : -90, 0., 0., 1.);
1381
 
        
1382
 
        if (bHorizontal)
1383
 
        {
1384
 
                if (! bDirectionUp)
1385
 
                        glScalef (1., -1., 1.);
1386
 
        }
1387
 
        else
1388
 
        {
1389
 
                if (bDirectionUp)
1390
 
                        glScalef (-1., 1., 1.);
1391
 
        }
1392
 
        
1393
 
        //\__________________ On dessine le cadre.
1394
 
        glEnableClientState(GL_VERTEX_ARRAY);
1395
 
        _cairo_dock_set_vertex_pointer (pVertexTab);
1396
 
        glDrawArrays(GL_POLYGON, 0, iNbVertex);  // GL_TRIANGLE_FAN
1397
 
        glDisableClientState(GL_VERTEX_ARRAY);
1398
 
        
1399
 
        //\__________________ fini la texture.
1400
 
        if (iBackgroundTexture != 0)
1401
 
        {
1402
 
                glDisable(GL_BLEND);
1403
 
                glDisable(GL_TEXTURE_GEN_S);
1404
 
                glDisable(GL_TEXTURE_GEN_T);
1405
 
                glDisable(GL_TEXTURE_2D); // Plus de texture merci 
1406
 
                
1407
 
                glMatrixMode(GL_TEXTURE); // On selectionne la matrice des textures
1408
 
                glPopMatrix ();
1409
 
                glMatrixMode(GL_MODELVIEW);
1410
 
        }
1411
 
}
1412
 
 
1413
 
void cairo_dock_draw_current_path_opengl (double fLineWidth, double *fLineColor, /*const GLfloat *pVertexTab, */int iNbVertex)
1414
 
{
1415
 
        glPolygonMode(GL_FRONT, GL_LINE);
1416
 
        glEnable (GL_LINE_SMOOTH);
1417
 
        glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
1418
 
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1419
 
        glEnable(GL_BLEND);
1420
 
        
1421
 
        glLineWidth(fLineWidth); // Ici on choisit l'epaisseur du contour du polygone 
1422
 
        if (fLineColor != NULL)
1423
 
                glColor4f (fLineColor[0], fLineColor[1], fLineColor[2], fLineColor[3]); // Et sa couleur.
1424
 
        
1425
 
        glEnableClientState(GL_VERTEX_ARRAY);
1426
 
        ///glVertexPointer(3, GL_FLOAT, 0, pVertexTab);
1427
 
        glDrawArrays(GL_LINE_STRIP, 0, iNbVertex);
1428
 
        glDisableClientState(GL_VERTEX_ARRAY);
1429
 
        
1430
 
        glDisable(GL_LINE_SMOOTH);
1431
 
        glDisable(GL_BLEND);
1432
 
}
1433
 
 
1434
 
 
1435
 
void cairo_dock_draw_string_opengl (CairoDock *pDock, double fStringLineWidth, gboolean bIsLoop, gboolean bForceConstantSeparator)
1436
 
{
1437
 
        int iNbVertex;
1438
 
        GLfloat *pVertexTab = cairo_dock_generate_string_path_opengl (pDock, bIsLoop, bForceConstantSeparator, &iNbVertex);
1439
 
        if (iNbVertex == 0)
1440
 
                return;
1441
 
        //glVertexPointer(_CAIRO_DOCK_PATH_DIM, GL_FLOAT, 0, pVertexTab);
1442
 
        _cairo_dock_set_vertex_pointer (pVertexTab);
1443
 
        cairo_dock_draw_current_path_opengl (fStringLineWidth, myIcons.fStringColor, iNbVertex);
1444
 
}
1445
 
 
1446
 
void cairo_dock_draw_rounded_rectangle_opengl (double fRadius, double fLineWidth, double fFrameWidth, double fFrameHeight, double fOffsetX, double fOffsetY, double *fLineColor)
1447
 
{
1448
 
        int iNbVertex = 0;
1449
 
        const GLfloat *pVertexTab = cairo_dock_generate_rectangle_path (fFrameWidth, fFrameHeight, fRadius, TRUE, &iNbVertex);
1450
 
        
1451
 
        if (fLineWidth == 0)
1452
 
        {
1453
 
                if (fLineColor != NULL)
1454
 
                        glColor4f (fLineColor[0], fLineColor[1], fLineColor[2], fLineColor[3]);
1455
 
                cairo_dock_draw_frame_background_opengl (0, fFrameWidth+2*fRadius, fFrameHeight, fOffsetX, fOffsetY, pVertexTab, iNbVertex, CAIRO_DOCK_HORIZONTAL, TRUE, 0.);
1456
 
        }
1457
 
        else
1458
 
        {
1459
 
                _cairo_dock_set_vertex_pointer (pVertexTab);
1460
 
                glTranslatef ((int) (fOffsetX + fFrameWidth/2), (int) (fOffsetY - fFrameHeight/2), -1);
1461
 
                glScalef (fFrameHeight, fFrameWidth, 1.);
1462
 
                cairo_dock_draw_current_path_opengl (fLineWidth, fLineColor, iNbVertex);
1463
 
        }
1464
 
}
1465
 
 
1466
 
 
1467
 
// A utiliser un jour.
1468
 
 
1469
 
typedef struct _CairoAnimatedImage {
1470
 
        cairo_surface_t *pSurface;
1471
 
        GLuint iTexture;
1472
 
        gint iFrameWidth, iFrameHeight;
1473
 
        gint iNbFrames;
1474
 
        gint iCurrentFrame;
1475
 
        } CairoAnimatedImage;
1476
 
 
1477
 
void cairo_dock_load_animated_image (const gchar *cImageFile, int iNbFrames, int iFrameWidth, int iFrameHeight, cairo_t *pSourceContext, CairoAnimatedImage *pAnimatedImage)
1478
 
{
1479
 
        pAnimatedImage->iNbFrames = iNbFrames;
1480
 
        pAnimatedImage->iCurrentFrame = 0;
1481
 
        
1482
 
        pAnimatedImage->iFrameWidth = iFrameWidth * iNbFrames;
1483
 
        pAnimatedImage->iFrameHeight = iFrameHeight;
1484
 
        pAnimatedImage->pSurface = cairo_dock_create_surface_from_image_simple (cImageFile,
1485
 
                        pSourceContext,
1486
 
                        pAnimatedImage->iFrameWidth,
1487
 
                        pAnimatedImage->iFrameHeight);
1488
 
        
1489
 
        if (g_bUseOpenGL && pAnimatedImage->pSurface != NULL)
1490
 
        {
1491
 
                pAnimatedImage->iTexture = cairo_dock_create_texture_from_surface (pAnimatedImage->pSurface);
1492
 
        }
1493
 
}
1494
 
 
1495
 
CairoAnimatedImage *cairo_dock_create_animated_image (const gchar *cImageFile, int iNbFrames, int iFrameWidth, int iFrameHeight, cairo_t *pSourceContext)
1496
 
{
1497
 
        CairoAnimatedImage *pAnimatedImage = g_new0 (CairoAnimatedImage, 1);
1498
 
        
1499
 
        cairo_dock_load_animated_image (cImageFile, iNbFrames, iFrameWidth, iFrameHeight, pSourceContext, pAnimatedImage);
1500
 
        
1501
 
        return pAnimatedImage;
1502
 
}
1503
 
 
1504
 
#define cairo_dock_update_animated_image_state(pAnimatedImage) do {\
1505
 
        (pAnimatedImage)->iCurrentFrame ++;\
1506
 
        if ((pAnimatedImage)->iCurrentFrame == (pAnimatedImage)->iNbFrames)\
1507
 
                (pAnimatedImage)->iCurrentFrame = 0; } while (0)
1508
 
 
1509
 
void cairo_dock_update_animated_image_cairo (CairoAnimatedImage *pAnimatedImage, cairo_t *pCairoContext)
1510
 
{
1511
 
        cairo_dock_update_animated_image_state (pAnimatedImage);
1512
 
        cairo_save (pCairoContext);
1513
 
        cairo_rectangle (pCairoContext, 0., 0., pAnimatedImage->iFrameWidth, pAnimatedImage->iFrameHeight);
1514
 
        cairo_clip (pCairoContext);
1515
 
        cairo_set_source_surface (pCairoContext,
1516
 
                pAnimatedImage->pSurface,
1517
 
                - pAnimatedImage->iFrameWidth * pAnimatedImage->iCurrentFrame,
1518
 
                0.);
1519
 
        cairo_restore (pCairoContext);
1520
 
}
1521
 
 
1522
 
void cairo_dock_update_animated_image_opengl (CairoAnimatedImage *pAnimatedImage)
1523
 
{
1524
 
        cairo_dock_update_animated_image_state (pAnimatedImage);
1525
 
        _cairo_dock_apply_current_texture_portion_at_size_with_offset (1.*pAnimatedImage->iCurrentFrame/pAnimatedImage->iNbFrames, 0.,
1526
 
                1. / pAnimatedImage->iNbFrames, 1.,
1527
 
                pAnimatedImage->iFrameWidth, pAnimatedImage->iFrameHeight,
1528
 
                0., 0.);
1529
 
}
1530
 
 
1531
 
 
1532
 
 
1533
 
 
1534
 
 
1535
 
 
1536
 
 
1537
 
typedef struct _CairoDockOpenglPath {
1538
 
        gint iNbVertices;
1539
 
        GLfloat *pVertexTab;
1540
 
        GLfloat *pColorTab;
1541
 
        gint iCurrentIndex;
1542
 
        gint iWidthExtent, iHeightExtent;
1543
 
        } CairoDockOpenglPath;
1544
 
 
1545
 
#define _cairo_dock_ith_vertex_x(pVertexPath, i) (pVertexPath)->pVertexTab[i*_CAIRO_DOCK_PATH_DIM]
1546
 
#define _cairo_dock_ith_vertex_y(pVertexPath, i) (pVertexPath)->pVertexTab[i*_CAIRO_DOCK_PATH_DIM+1]
1547
 
#define _cairo_dock_set_ith_vertex_x(pVertexPath, i, x) _cairo_dock_ith_vertex_x(pVertexPath, i) = x
1548
 
#define _cairo_dock_set_ith_vertex_y(pVertexPath, i, y) _cairo_dock_ith_vertex_y(pVertexPath, i) = y
1549
 
#define cairo_dock_get_current_vertex_x(pVertexPath) _cairo_dock_ith_vertex_x(pVertexPath, pVertexPath->iCurrentIndex-1)
1550
 
#define cairo_dock_get_current_vertex_y(pVertexPath) _cairo_dock_ith_vertex_y(pVertexPath, pVertexPath->iCurrentIndex-1)
1551
 
#define cairo_dock_add_vertex(pVertexPath, x, y) do {\
1552
 
        _cairo_dock_set_ith_vertex_x (pVertexPath, (pVertexPath)->iCurrentIndex, x);\
1553
 
        _cairo_dock_set_ith_vertex_y (pVertexPath, (pVertexPath)->iCurrentIndex, y);\
1554
 
        (pVertexPath)->iCurrentIndex ++; } while (0)
1555
 
 
1556
 
void cairo_dock_add_curved_subpath_opengl (CairoDockOpenglPath *pVertexPath, int iNbPts, double x1, double y1, double x2, double y2, double x3, double y3)
1557
 
{
1558
 
        double x0 = cairo_dock_get_current_vertex_x (pVertexPath);  // doit avoir ete initialise.
1559
 
        double y0 = cairo_dock_get_current_vertex_y (pVertexPath);
1560
 
        double t;
1561
 
        int i;
1562
 
        for (i = 1; i < iNbPts+1; i ++)
1563
 
        {
1564
 
                t = 1.*i/iNbPts;  // ]0;1]
1565
 
                cairo_dock_add_vertex(pVertexPath,
1566
 
                        Bezier (x0,x1,x2,x3,t),
1567
 
                        Bezier (y0,y1,y2,y3,t));
1568
 
                //vx(i) = Bezier (x0,x1,x2,x3,t);
1569
 
                //vy(i) = Bezier (y0,y1,y2,y3,t);
1570
 
        }
1571
 
}
1572
 
 
1573
 
 
1574
 
 
1575
 
GLuint cairo_dock_create_texture_from_text_simple (const gchar *cText, const gchar *cFontDescription, cairo_t* pSourceContext, int *iWidth, int *iHeight)
1576
 
{
1577
 
        g_return_val_if_fail (cText != NULL && cFontDescription != NULL, 0);
1578
 
        
1579
 
        //\_________________ On ecrit le texte dans un calque Pango.
1580
 
        PangoLayout *pLayout = pango_cairo_create_layout (pSourceContext);
1581
 
        
1582
 
        PangoFontDescription *fd = pango_font_description_from_string (cFontDescription);
1583
 
        pango_layout_set_font_description (pLayout, fd);
1584
 
        pango_font_description_free (fd);
1585
 
        
1586
 
        pango_layout_set_text (pLayout, cText, -1);
1587
 
        
1588
 
        //\_________________ On cree une surface aux dimensions du texte.
1589
 
        PangoRectangle ink, log;
1590
 
        pango_layout_get_pixel_extents (pLayout, &ink, &log);
1591
 
        cairo_surface_t* pNewSurface = _cairo_dock_create_blank_surface (pSourceContext,
1592
 
                log.width,
1593
 
                log.height);
1594
 
        *iWidth = log.width;
1595
 
        *iHeight = log.height;
1596
 
        
1597
 
        //\_________________ On dessine le texte.
1598
 
        cairo_t* pCairoContext = cairo_create (pNewSurface);
1599
 
        cairo_translate (pCairoContext, -log.x, -log.y);
1600
 
        cairo_set_source_rgb (pCairoContext, 1., 1., 1.);
1601
 
        cairo_move_to (pCairoContext, 0, 0);
1602
 
        pango_cairo_show_layout (pCairoContext, pLayout);
1603
 
        cairo_destroy (pCairoContext);
1604
 
        
1605
 
        g_object_unref (pLayout);
1606
 
        
1607
 
        //\_________________ On cree la texture.
1608
 
        GLuint iTexture = cairo_dock_create_texture_from_surface (pNewSurface);
1609
 
        cairo_surface_destroy (pNewSurface);
1610
 
        return iTexture;
1611
 
}
1612
 
 
1613
 
 
1614
 
CairoDockGLFont *cairo_dock_load_bitmap_font (const gchar *cFontDescription, int first, int count)
1615
 
{
1616
 
        g_return_val_if_fail (cFontDescription != NULL && count > 0, NULL);
1617
 
        
1618
 
        GLuint iListBase = glGenLists (count);
1619
 
        g_return_val_if_fail (iListBase != 0, NULL);
1620
 
        
1621
 
        CairoDockGLFont *pFont = g_new0 (CairoDockGLFont, 1);
1622
 
        pFont->iListBase = iListBase;
1623
 
        pFont->iNbChars = count;
1624
 
        pFont->iCharBase = first;
1625
 
        
1626
 
        PangoFontDescription *fd = pango_font_description_from_string (cFontDescription);
1627
 
        PangoFont *font = gdk_gl_font_use_pango_font (fd,
1628
 
                first,
1629
 
                count,
1630
 
                iListBase);
1631
 
        g_return_val_if_fail (font != NULL, NULL);
1632
 
        
1633
 
        PangoFontMetrics* metrics = pango_font_get_metrics (font, NULL);
1634
 
        pFont->iCharWidth = pango_font_metrics_get_approximate_char_width (metrics) / PANGO_SCALE;
1635
 
        pFont->iCharHeight = (pango_font_metrics_get_ascent (metrics) + pango_font_metrics_get_descent (metrics)) / PANGO_SCALE;
1636
 
        pango_font_metrics_unref(metrics);
1637
 
        
1638
 
        pango_font_description_free (fd);
1639
 
        return pFont;
1640
 
}
1641
 
 
1642
 
CairoDockGLFont *cairo_dock_load_textured_font (const gchar *cFontDescription, int first, int count)
1643
 
{
1644
 
        g_return_val_if_fail (g_pMainDock != NULL && count > 0, NULL);
1645
 
        if (first < 32)  // 32 = ' '
1646
 
        {
1647
 
                count -= (32 - first);
1648
 
                first = 32;
1649
 
        }
1650
 
        gchar *cPool = g_new0 (gchar, 4*count + 1);
1651
 
        int i, j=0;
1652
 
        guchar c;
1653
 
        for (i = 0; i < count; i ++)
1654
 
        {
1655
 
                c = first + i;
1656
 
                if (c > 254)
1657
 
                {
1658
 
                        count=i;
1659
 
                        break;
1660
 
                }
1661
 
                if ((c > 126 && c < 126 + 37) || (c == 173))  // le 173 est un caractere bizarre (sa taille est nulle).
1662
 
                {
1663
 
                        cPool[j++] = ' ';
1664
 
                }
1665
 
                else
1666
 
                {
1667
 
                        j += MAX (0, sprintf (cPool+j, "%lc", c));  // les caracteres ASCII >128 doivent etre convertis en multi-octets.
1668
 
                }
1669
 
        }
1670
 
        cd_debug ("%s (%d + %d -> '%s')", __func__, first, count, cPool);
1671
 
        /*iconv_t cd = iconv_open("UTF-8", "ISO-8859-1");
1672
 
        gchar *outbuf = g_new0 (gchar, count*4+1);
1673
 
        gchar *outbuf0 = outbuf, *inbuf0 = cPool;
1674
 
        size_t inbytesleft = count;
1675
 
        size_t outbytesleft = count*4;
1676
 
        size_t size = iconv (cd,
1677
 
                &cPool, &inbytesleft,
1678
 
                &outbuf, &outbytesleft);
1679
 
        g_print ("%d bytes left, %d bytes written => '%s'\n", inbytesleft, outbytesleft, outbuf0);
1680
 
        g_free (inbuf0);
1681
 
        cPool = outbuf0;
1682
 
        iconv_close (cd);*/
1683
 
        
1684
 
        int iWidth, iHeight;
1685
 
        cairo_t *pCairoContext = cairo_dock_create_drawing_context_generic (CAIRO_CONTAINER (g_pMainDock));
1686
 
        GLuint iTexture = cairo_dock_create_texture_from_text_simple (cPool, cFontDescription, pCairoContext, &iWidth, &iHeight);
1687
 
        cairo_destroy (pCairoContext);
1688
 
        g_free (cPool);
1689
 
        
1690
 
        CairoDockGLFont *pFont = g_new0 (CairoDockGLFont, 1);
1691
 
        pFont->iTexture = iTexture;
1692
 
        pFont->iNbChars = count;
1693
 
        pFont->iCharBase = first;
1694
 
        pFont->iNbRows = 1;
1695
 
        pFont->iNbColumns = count;
1696
 
        pFont->iCharWidth = (double)iWidth / count;
1697
 
        pFont->iCharHeight = iHeight;
1698
 
        
1699
 
        cd_debug ("%d char / %d pixels => %.3f", count, iWidth, (double)iWidth / count);
1700
 
        return pFont;
1701
 
}
1702
 
 
1703
 
CairoDockGLFont *cairo_dock_load_textured_font_from_image (const gchar *cImagePath)
1704
 
{
1705
 
        double fImageWidth, fImageHeight;
1706
 
        GLuint iTexture = cairo_dock_create_texture_from_image_full (cImagePath, &fImageWidth, &fImageHeight);
1707
 
        g_return_val_if_fail (iTexture != 0, NULL);
1708
 
        
1709
 
        CairoDockGLFont *pFont = g_new0 (CairoDockGLFont, 1);
1710
 
        pFont->iTexture = iTexture;
1711
 
        pFont->iNbChars = 256;
1712
 
        pFont->iCharBase = 0;
1713
 
        pFont->iNbRows = 16;
1714
 
        pFont->iNbColumns = 16;
1715
 
        pFont->iCharWidth = fImageWidth / pFont->iNbColumns;
1716
 
        pFont->iCharHeight = fImageHeight / pFont->iNbRows;
1717
 
        return pFont;
1718
 
}
1719
 
 
1720
 
void cairo_dock_free_gl_font (CairoDockGLFont *pFont)
1721
 
{
1722
 
        if (pFont == NULL)
1723
 
                return ;
1724
 
        if (pFont->iListBase != 0)
1725
 
                glDeleteLists (pFont->iListBase, pFont->iNbChars);
1726
 
        if (pFont->iTexture != 0)
1727
 
                _cairo_dock_delete_texture (pFont->iTexture);
1728
 
        g_free (pFont);
1729
 
}
1730
 
 
1731
 
 
1732
 
void cairo_dock_get_gl_text_extent (const gchar *cText, CairoDockGLFont *pFont, int *iWidth, int *iHeight)
1733
 
{
1734
 
        if (pFont == NULL || cText == NULL)
1735
 
        {
1736
 
                *iWidth = 0;
1737
 
                *iHeight = 0;
1738
 
                return ;
1739
 
        }
1740
 
        int i, w=0, wmax=0, h=pFont->iCharHeight;
1741
 
        for (i = 0; cText[i] != '\0'; i ++)
1742
 
        {
1743
 
                if (cText[i] == '\n')
1744
 
                {
1745
 
                        h += pFont->iCharHeight + 1;
1746
 
                        wmax = MAX (wmax, w);
1747
 
                        w = 0;
1748
 
                }
1749
 
                else
1750
 
                        w += pFont->iCharWidth;
1751
 
        }
1752
 
        
1753
 
        *iWidth = MAX (wmax, w);
1754
 
        *iHeight = h;
1755
 
}
1756
 
 
1757
 
 
1758
 
void cairo_dock_draw_gl_text (const guchar *cText, CairoDockGLFont *pFont)
1759
 
{
1760
 
        int n = strlen (cText);
1761
 
        if (pFont->iListBase != 0)
1762
 
        {
1763
 
                if (pFont->iCharBase == 0 && strchr (cText, '\n') == NULL)  // version optimisee ou on a charge tous les caracteres.
1764
 
                {
1765
 
                        glDisable (GL_TEXTURE_2D);
1766
 
                        glListBase (pFont->iListBase);
1767
 
                        glCallLists (n, GL_UNSIGNED_BYTE, (unsigned char *)cText);
1768
 
                        glListBase (0);
1769
 
                }
1770
 
                else
1771
 
                {
1772
 
                        int i, j;
1773
 
                        for (i = 0; i < n; i ++)
1774
 
                        {
1775
 
                                if (cText[i] == '\n')
1776
 
                                {
1777
 
                                        GLfloat rpos[4];
1778
 
                                        glGetFloatv (GL_CURRENT_RASTER_POSITION, rpos);
1779
 
                                        glRasterPos2f (rpos[0], rpos[1] + pFont->iCharHeight + 1);
1780
 
                                        continue;
1781
 
                                }
1782
 
                                if (cText[i] < pFont->iCharBase || cText[i] >= pFont->iCharBase + pFont->iNbChars)
1783
 
                                        continue;
1784
 
                                j = cText[i] - pFont->iCharBase;
1785
 
                                glCallList (pFont->iListBase + j);
1786
 
                        }
1787
 
                }
1788
 
        }
1789
 
        else if (pFont->iTexture != 0)
1790
 
        {
1791
 
                _cairo_dock_enable_texture ();
1792
 
                glBindTexture (GL_TEXTURE_2D, pFont->iTexture);
1793
 
                double u, v, du=1./pFont->iNbColumns, dv=1./pFont->iNbRows, w=pFont->iCharWidth, h=pFont->iCharHeight, x=.5*w, y=.5*h;
1794
 
                int i, j;
1795
 
                for (i = 0; i < n; i ++)
1796
 
                {
1797
 
                        if (cText[i] == '\n')
1798
 
                        {
1799
 
                                x = .5*pFont->iCharWidth;
1800
 
                                y += pFont->iCharHeight + 1;
1801
 
                                continue;
1802
 
                        }
1803
 
                        if (cText[i] < pFont->iCharBase || cText[i] >= pFont->iCharBase + pFont->iNbChars)
1804
 
                                continue;
1805
 
                        
1806
 
                        j = cText[i] - pFont->iCharBase;
1807
 
                        u = (double) (j%pFont->iNbColumns) / pFont->iNbColumns;
1808
 
                        v = (double) (j/pFont->iNbColumns) / pFont->iNbRows;
1809
 
                        _cairo_dock_apply_current_texture_portion_at_size_with_offset (u, v, du, dv, w, h, x, y);
1810
 
                        x += pFont->iCharWidth;
1811
 
                }
1812
 
                _cairo_dock_disable_texture ();
1813
 
        }
1814
 
}
1815
 
 
1816
 
void cairo_dock_draw_gl_text_in_area (const guchar *cText, CairoDockGLFont *pFont, int iWidth, int iHeight, gboolean bCentered)
1817
 
{
1818
 
        g_return_if_fail (pFont != NULL && cText != NULL);
1819
 
        if (pFont->iListBase != 0)  // marche po sur du raster.
1820
 
        {
1821
 
                cd_warning ("can't resize raster ! use a textured font inside.");
1822
 
        }
1823
 
        else
1824
 
        {
1825
 
                int n = strlen (cText);
1826
 
                int w, h;
1827
 
                cairo_dock_get_gl_text_extent (cText, pFont, &w, &h);
1828
 
                
1829
 
                double zx, zy;
1830
 
                if (fabs ((double)iWidth/w) < fabs ((double)iHeight/h))  // on autorise les dimensions negatives pour pouvoir retourner le texte.
1831
 
                {
1832
 
                        zx = (double)iWidth/w;
1833
 
                        zy = (iWidth*iHeight > 0 ? zx : -zx);
1834
 
                }
1835
 
                else
1836
 
                {
1837
 
                        zy = (double)iHeight/h;
1838
 
                        zx = (iWidth*iHeight > 0 ? zy : -zy);
1839
 
                }
1840
 
                
1841
 
                glScalef (zx, zy, 1.);
1842
 
                if (bCentered)
1843
 
                        glTranslatef (-w/2, -h/2, 0.);
1844
 
                cairo_dock_draw_gl_text (cText, pFont);
1845
 
        }
1846
 
}
1847
 
 
1848
 
void cairo_dock_draw_gl_text_at_position (const guchar *cText, CairoDockGLFont *pFont, int x, int y)
1849
 
{
1850
 
        g_return_if_fail (pFont != NULL && cText != NULL);
1851
 
        if (pFont->iListBase != 0)
1852
 
        {
1853
 
                glRasterPos2f (x, y);
1854
 
        }
1855
 
        else
1856
 
        {
1857
 
                glTranslatef (x, y, 0);
1858
 
        }
1859
 
        cairo_dock_draw_gl_text (cText, pFont);
1860
 
}
1861
 
 
1862
 
void cairo_dock_draw_gl_text_at_position_in_area (const guchar *cText, CairoDockGLFont *pFont, int x, int y, int iWidth, int iHeight, gboolean bCentered)
1863
 
{
1864
 
        g_return_if_fail (pFont != NULL && cText != NULL);
1865
 
        if (pFont->iListBase != 0)  // marche po sur du raster.
1866
 
        {
1867
 
                cd_warning ("can't resize raster ! use a textured font inside.");
1868
 
        }
1869
 
        else
1870
 
        {
1871
 
                glTranslatef (x, y, 0);
1872
 
                cairo_dock_draw_gl_text_in_area (cText, pFont, iWidth, iHeight, bCentered);
1873
 
        }
1874
 
}
1875
 
 
1876
 
 
1877
 
 
1878
 
typedef void (*GLXBindTexImageProc) (Display *display, GLXDrawable drawable, int buffer, int *attribList);
1879
 
typedef void (*GLXReleaseTexImageProc) (Display *display, GLXDrawable drawable, int buffer);
1880
 
 
1881
 
// Bind redirected window to texture:
1882
 
GLuint cairo_dock_texture_from_pixmap (Window Xid, Pixmap iBackingPixmap)
1883
 
{
1884
 
        return 0;  /// ca ne marche pas. :-(
1885
 
        
1886
 
        if (! g_openglConfig.bTextureFromPixmapAvailable)
1887
 
                return 0;
1888
 
        
1889
 
        Display *display = gdk_x11_get_default_xdisplay ();
1890
 
        XWindowAttributes attrib;
1891
 
        XGetWindowAttributes (display, Xid, &attrib);
1892
 
        
1893
 
        VisualID visualid = XVisualIDFromVisual (attrib.visual);
1894
 
        
1895
 
        int nfbconfigs;
1896
 
        int screen = 0;
1897
 
        GLXFBConfig *fbconfigs = glXGetFBConfigs (display, screen, &nfbconfigs);
1898
 
        
1899
 
        GLfloat top=0., bottom=0.;
1900
 
        XVisualInfo *visinfo;
1901
 
        int value;
1902
 
        int i;
1903
 
        for (i = 0; i < nfbconfigs; i++)
1904
 
        {
1905
 
                visinfo = glXGetVisualFromFBConfig (display, fbconfigs[i]);
1906
 
                if (!visinfo || visinfo->visualid != visualid)
1907
 
                        continue;
1908
 
        
1909
 
                glXGetFBConfigAttrib (display, fbconfigs[i], GLX_DRAWABLE_TYPE, &value);
1910
 
                if (!(value & GLX_PIXMAP_BIT))
1911
 
                        continue;
1912
 
        
1913
 
                glXGetFBConfigAttrib (display, fbconfigs[i],
1914
 
                        GLX_BIND_TO_TEXTURE_TARGETS_EXT,
1915
 
                        &value);
1916
 
                if (!(value & GLX_TEXTURE_2D_BIT_EXT))
1917
 
                        continue;
1918
 
                
1919
 
                glXGetFBConfigAttrib (display, fbconfigs[i],
1920
 
                        GLX_BIND_TO_TEXTURE_RGBA_EXT,
1921
 
                        &value);
1922
 
                if (value == FALSE)
1923
 
                {
1924
 
                        glXGetFBConfigAttrib (display, fbconfigs[i],
1925
 
                                GLX_BIND_TO_TEXTURE_RGB_EXT,
1926
 
                                &value);
1927
 
                        if (value == FALSE)
1928
 
                                continue;
1929
 
                }
1930
 
                
1931
 
                glXGetFBConfigAttrib (display, fbconfigs[i],
1932
 
                        GLX_Y_INVERTED_EXT,
1933
 
                        &value);
1934
 
                if (value == TRUE)
1935
 
                {
1936
 
                        top = 0.0f;
1937
 
                        bottom = 1.0f;
1938
 
                }
1939
 
                else
1940
 
                {
1941
 
                        top = 1.0f;
1942
 
                        bottom = 0.0f;
1943
 
                }
1944
 
                
1945
 
                break;
1946
 
        }
1947
 
        
1948
 
        if (i == nfbconfigs)
1949
 
        {
1950
 
                cd_warning ("No FB Config found");
1951
 
                return 0;
1952
 
        }
1953
 
        
1954
 
        int pixmapAttribs[5] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
1955
 
                GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
1956
 
                None };
1957
 
        GLXPixmap glxpixmap = glXCreatePixmap (display, fbconfigs[i], iBackingPixmap, pixmapAttribs);
1958
 
        g_return_val_if_fail (glxpixmap != 0, 0);
1959
 
        
1960
 
        GLuint texture;
1961
 
        glEnable (GL_TEXTURE_2D);
1962
 
        glGenTextures (1, &texture);
1963
 
        glBindTexture (GL_TEXTURE_2D, texture);
1964
 
        
1965
 
        g_openglConfig.bindTexImage (display, glxpixmap, GLX_FRONT_LEFT_EXT, NULL);
1966
 
        
1967
 
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1968
 
        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1969
 
        
1970
 
        // draw using iBackingPixmap as texture
1971
 
        glBegin (GL_QUADS);
1972
 
        
1973
 
        glTexCoord2d (0.0f, bottom);
1974
 
        glVertex2d (0.0f, 0.0f);
1975
 
        
1976
 
        glTexCoord2d (0.0f, top);
1977
 
        glVertex2d (0.0f, 1.0f);
1978
 
        
1979
 
        glTexCoord2d (1.0f, top);
1980
 
        glVertex2d (1.0f, 1.0f);
1981
 
        
1982
 
        glTexCoord2d (1.0f, bottom);
1983
 
        glVertex2d (1.0f, 0.0f);
1984
 
        
1985
 
        glEnd ();
1986
 
        glDisable (GL_TEXTURE_2D);
1987
 
        
1988
 
        g_openglConfig.releaseTexImage (display, glxpixmap, GLX_FRONT_LEFT_EXT);
1989
 
        glXDestroyGLXPixmap (display, glxpixmap);
1990
 
        return texture;
1991
 
}