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

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Matthieu Baerts (matttbe), Matthieu Baerts (matttbe), Didier Roche
  • Date: 2010-03-01 21:24:00 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20100301212400-3a3csog6eonse3in
Tags: 2.1.3-6-0ubuntu1
[ Matthieu Baerts (matttbe) ]
* New Upstream Version. (LP: #521534)
* Updated debian/watch and debian/copyright with LP account.
* Removed debian/patches/02-merge-changelog.patch'
 - data/ChangeLog.txt has to respect a syntax and is used by CD.
* debian/cairo-dock.1:
 - Updated with the latest release.
 - The domain name 'cairo-dock.org' has changed to 'glx-dock.org'
* debian/control:
 - Changed the homepage and other links (glx-dock.org)
 - Updated cairo-dock-dev architecture to 'all' (it no longer contains compiled files)
* debian/cairo-dock-dev.install
 - libcairo-dock.a and libcairo-dock.so no longer exist
* debian/rules
 - removed uneeded changelog file
* Updated debian/patches/01-desktop-file-category.patch

[ Didier Roche ]
* Fix debian/watch
* Fix some issue in versionning
* debian/control: clean the packaging and add right -plugins depends

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 <string.h>
 
21
#include <math.h>
 
22
#include <stdlib.h>
 
23
 
 
24
#include <gdk/gdkx.h>
 
25
#include <gtk/gtkgl.h>
 
26
 
 
27
#include <X11/extensions/Xrender.h>
 
28
#include <GL/glx.h>
 
29
#include <GL/glxext.h>
 
30
#include <GL/glu.h>
 
31
 
 
32
#include "cairo-dock-log.h"
 
33
#include "cairo-dock-dock-factory.h"
 
34
#include "cairo-dock-load.h"
 
35
#include "cairo-dock-internal-icons.h"
 
36
#include "cairo-dock-internal-system.h"
 
37
#include "cairo-dock-draw-opengl.h"
 
38
#include "cairo-dock-opengl.h"
 
39
 
 
40
extern CairoDockGLConfig g_openglConfig;
 
41
extern gboolean g_bUseOpenGL;
 
42
extern CairoDock *g_pMainDock;
 
43
extern CairoDockDesktopBackground *g_pFakeTransparencyDesktopBg;
 
44
extern int g_iXScreenWidth[2];
 
45
extern int g_iXScreenHeight[2];
 
46
extern gboolean g_bEasterEggs;
 
47
 
 
48
static inline gboolean _check_extension (const char *extName, const gchar *cExtensions)
 
49
{
 
50
        g_return_val_if_fail (cExtensions != NULL, FALSE);
 
51
        /*
 
52
        ** Search for extName in the extensions string.  Use of strstr()
 
53
        ** is not sufficient because extension names can be prefixes of
 
54
        ** other extension names.  Could use strtok() but the constant
 
55
        ** string returned by glGetString can be in read-only memory.
 
56
        */
 
57
        char *p = (char *) cExtensions;
 
58
 
 
59
        char *end;
 
60
        int extNameLen;
 
61
 
 
62
        extNameLen = strlen(extName);
 
63
        end = p + strlen(p);
 
64
 
 
65
        while (p < end)
 
66
        {
 
67
                int n = strcspn(p, " ");
 
68
                if ((extNameLen == n) && (strncmp(extName, p, n) == 0))
 
69
                {
 
70
                        return TRUE;
 
71
                }
 
72
                p += (n + 1);
 
73
        }
 
74
        return FALSE;
 
75
}
 
76
static gboolean _check_gl_extension (const char *extName)
 
77
{
 
78
        const gchar *glExtensions = glGetString (GL_EXTENSIONS);
 
79
        return _check_extension (extName, glExtensions);
 
80
}
 
81
static gboolean _check_client_glx_extension (const char *extName)
 
82
{
 
83
        Display *display = gdk_x11_get_default_xdisplay ();
 
84
        int screen = 0;
 
85
        //const gchar *glxExtensions = glXQueryExtensionsString (display, screen);
 
86
        const gchar *glxExtensions = glXGetClientString (display,GLX_EXTENSIONS);
 
87
        return _check_extension (extName, glxExtensions);
 
88
}
 
89
 
 
90
 
 
91
static inline XVisualInfo *_get_visual_from_fbconfigs (GLXFBConfig *pFBConfigs, int iNumOfFBConfigs, Display *XDisplay)
 
92
{
 
93
        XRenderPictFormat *pPictFormat;
 
94
        XVisualInfo *pVisInfo = NULL;
 
95
        int i;
 
96
        for (i = 0; i < iNumOfFBConfigs; i++)
 
97
        {
 
98
                pVisInfo = glXGetVisualFromFBConfig (XDisplay, pFBConfigs[i]);
 
99
                if (!pVisInfo)
 
100
                {
 
101
                        cd_warning ("this FBConfig has no visual.");
 
102
                        continue;
 
103
                }
 
104
                
 
105
                pPictFormat = XRenderFindVisualFormat (XDisplay, pVisInfo->visual);
 
106
                if (!pPictFormat)
 
107
                {
 
108
                        cd_warning ("this visual has an unknown format.");
 
109
                        XFree (pVisInfo);
 
110
                        pVisInfo = NULL;
 
111
                        continue;
 
112
                }
 
113
                
 
114
                if (pPictFormat->direct.alphaMask > 0)
 
115
                {
 
116
                        cd_message ("Strike, found a GLX visual with alpha-support !");
 
117
                        break;
 
118
                }
 
119
 
 
120
                XFree (pVisInfo);
 
121
                pVisInfo = NULL;
 
122
        }
 
123
        return pVisInfo;
 
124
}
 
125
 
 
126
gboolean cairo_dock_initialize_opengl_backend (gboolean bToggleIndirectRendering, gboolean bForceOpenGL)  // taken from a MacSlow's exemple.
 
127
{
 
128
        memset (&g_openglConfig, 0, sizeof (CairoDockGLConfig));
 
129
        g_bUseOpenGL = FALSE;
 
130
        g_openglConfig.bHasBeenForced = bForceOpenGL;
 
131
        gboolean bStencilBufferAvailable, bAlphaAvailable;
 
132
        Display *XDisplay = gdk_x11_get_default_xdisplay ();
 
133
        
 
134
        //\_________________ On cherche un visual qui reponde a tous les criteres.
 
135
        GLXFBConfig *pFBConfigs;
 
136
        XRenderPictFormat *pPictFormat = NULL;
 
137
        int doubleBufferAttributes[] = {
 
138
                GLX_DRAWABLE_TYPE,      GLX_WINDOW_BIT,
 
139
                GLX_RENDER_TYPE,                GLX_RGBA_BIT,
 
140
                GLX_DOUBLEBUFFER,       True,
 
141
                GLX_RED_SIZE,           1,
 
142
                GLX_GREEN_SIZE,                 1,
 
143
                GLX_BLUE_SIZE,          1,
 
144
                GLX_DEPTH_SIZE,                 1,
 
145
                GLX_ALPHA_SIZE,                 1,
 
146
                GLX_STENCIL_SIZE,       1,
 
147
                /// a tester ...
 
148
                (g_bEasterEggs ? GLX_SAMPLE_BUFFERS_ARB : None), 1,
 
149
                GLX_SAMPLES_ARB, 2,
 
150
                /*GL_MULTISAMPLEBUFFERS,        1,
 
151
                GL_MULTISAMPLESAMPLES,  2,*/
 
152
                None};
 
153
        
 
154
        XVisualInfo *pVisInfo = NULL;
 
155
        int iNumOfFBConfigs = 0;
 
156
        pFBConfigs = glXChooseFBConfig (XDisplay,
 
157
                DefaultScreen (XDisplay),
 
158
                doubleBufferAttributes,
 
159
                &iNumOfFBConfigs);
 
160
        cd_debug ("got %d FBConfig(s)", iNumOfFBConfigs);
 
161
        bStencilBufferAvailable = TRUE;
 
162
        bAlphaAvailable = TRUE;
 
163
        
 
164
        pVisInfo = _get_visual_from_fbconfigs (pFBConfigs, iNumOfFBConfigs, XDisplay);
 
165
        if (pFBConfigs)
 
166
                XFree (pFBConfigs);
 
167
        
 
168
        //\_________________ Si pas trouve, on en cherche un moins contraignant.
 
169
        if (pVisInfo == NULL)
 
170
        {
 
171
                cd_warning ("couldn't find an appropriate visual, trying to get one without Stencil buffer\n(it may cause some little deterioration in the rendering) ...");
 
172
                doubleBufferAttributes[16] = None;
 
173
                pFBConfigs = glXChooseFBConfig (XDisplay,
 
174
                        DefaultScreen (XDisplay),
 
175
                        doubleBufferAttributes,
 
176
                        &iNumOfFBConfigs);
 
177
                cd_debug ("this time got %d FBConfig(s)", iNumOfFBConfigs);
 
178
                bStencilBufferAvailable = FALSE;
 
179
                bAlphaAvailable = TRUE;
 
180
                
 
181
                pVisInfo = _get_visual_from_fbconfigs (pFBConfigs, iNumOfFBConfigs, XDisplay);
 
182
                if (pFBConfigs)
 
183
                        XFree (pFBConfigs);
 
184
        }
 
185
        
 
186
        //\_________________ Si toujours rien, on essaye avec la methode de gdkgl.
 
187
        if (pVisInfo == NULL)
 
188
        {
 
189
                cd_warning ("still couldn't find an appropriate visual ourself, trying something else, this may not work with some drivers ...");
 
190
                g_openglConfig.pGlConfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
 
191
                        GDK_GL_MODE_ALPHA |
 
192
                        GDK_GL_MODE_DEPTH |
 
193
                        GDK_GL_MODE_DOUBLE |
 
194
                        GDK_GL_MODE_STENCIL);
 
195
                bStencilBufferAvailable = TRUE;
 
196
                bAlphaAvailable = TRUE;
 
197
                
 
198
                if (g_openglConfig.pGlConfig == NULL)
 
199
                {
 
200
                        cd_warning ("no luck, trying without double-buffer and stencil ...");
 
201
                        g_openglConfig.pGlConfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
 
202
                                GDK_GL_MODE_ALPHA |
 
203
                                GDK_GL_MODE_DEPTH);
 
204
                        bStencilBufferAvailable = FALSE;
 
205
                        bAlphaAvailable = TRUE;
 
206
                }
 
207
        }
 
208
        
 
209
        //\_________________ Si toujours rien et si l'utilisateur n'en demord pas, on en cherche un sans canal alpha.
 
210
        if (pVisInfo == NULL && g_openglConfig.pGlConfig == NULL && bForceOpenGL)
 
211
        {
 
212
                cd_warning ("we could not get an ARGB-visual, trying to get an RGB one (fake transparency will be used in return) ...");
 
213
                g_openglConfig.bAlphaAvailable = FALSE;
 
214
                doubleBufferAttributes[14] = None;
 
215
                int i, iNumOfFBConfigs;
 
216
                pFBConfigs = glXChooseFBConfig (XDisplay,
 
217
                        DefaultScreen (XDisplay),
 
218
                        doubleBufferAttributes,
 
219
                        &iNumOfFBConfigs);
 
220
                bStencilBufferAvailable = FALSE;
 
221
                bAlphaAvailable = FALSE;
 
222
                cd_debug ("got %d FBConfig(s) without alpha channel", iNumOfFBConfigs);
 
223
                for (i = 0; i < iNumOfFBConfigs; i++)
 
224
                {
 
225
                        pVisInfo = glXGetVisualFromFBConfig (XDisplay, pFBConfigs[i]);
 
226
                        if (!pVisInfo)
 
227
                        {
 
228
                                cd_warning ("this FBConfig has no visual.");
 
229
                                XFree (pVisInfo);
 
230
                                pVisInfo = NULL;
 
231
                        }
 
232
                        else
 
233
                                break;
 
234
                }
 
235
                if (pFBConfigs)
 
236
                        XFree (pFBConfigs);
 
237
                
 
238
                if (pVisInfo == NULL)
 
239
                {
 
240
                        cd_warning ("still no visual, this is the last chance");
 
241
                        pVisInfo = glXChooseVisual (XDisplay,
 
242
                                DefaultScreen (XDisplay),
 
243
                                doubleBufferAttributes);
 
244
                }
 
245
        }
 
246
        g_openglConfig.bStencilBufferAvailable = bStencilBufferAvailable;
 
247
        g_openglConfig.bAlphaAvailable = bAlphaAvailable;
 
248
        
 
249
        //\_________________ Si rien de chez rien, on quitte.
 
250
        if (pVisInfo == NULL && g_openglConfig.pGlConfig == NULL)
 
251
        {
 
252
                cd_warning ("couldn't find a suitable GLX Visual, OpenGL can't be used.\n (sorry to say that, but your graphic card and/or its driver is crappy)");
 
253
                return FALSE;
 
254
        }
 
255
        
 
256
        //\_________________ On en deduit une config opengl valide pour les widgets gtk.
 
257
        if (pVisInfo != NULL)
 
258
        {
 
259
                cd_message ("ok, got a visual");
 
260
                g_openglConfig.pGlConfig = gdk_x11_gl_config_new_from_visualid (pVisInfo->visualid);
 
261
                XFree (pVisInfo);
 
262
        }
 
263
        g_return_val_if_fail (g_openglConfig.pGlConfig != NULL, FALSE);
 
264
        g_bUseOpenGL = TRUE;
 
265
        
 
266
        //\_________________ On regarde si le rendu doit etre indirect ou pas.
 
267
        g_openglConfig.bIndirectRendering = bToggleIndirectRendering;
 
268
        if (glXQueryVersion(XDisplay, &g_openglConfig.iGlxMajor, &g_openglConfig.iGlxMinor) == False)
 
269
        {
 
270
                cd_warning ("GLX not available !\nFear the worst !");
 
271
        }
 
272
        else
 
273
        {
 
274
                if (g_openglConfig.iGlxMajor <= 1 && g_openglConfig.iGlxMinor < 3)  // on a besoin de GLX >= 1.3 pour les pbuffers; mais si on a l'extension GLX_SGIX_pbuffer et un version inferieure, ca marche quand meme.
 
275
                {
 
276
                        if (! _check_client_glx_extension ("GLX_SGIX_pbuffer"))
 
277
                        {
 
278
                                cd_warning ("No pbuffer extension in GLX.\n this might affect the drawing of some applets which are inside a dock");
 
279
                        }
 
280
                        else
 
281
                        {
 
282
                                cd_warning ("GLX version too old (%d.%d).\nCairo-Dock needs at least GLX 1.3. Indirect rendering will be toggled on/off as a workaround.", g_openglConfig.iGlxMajor, g_openglConfig.iGlxMinor);
 
283
                                g_openglConfig.bPBufferAvailable = TRUE;
 
284
                                g_openglConfig.bIndirectRendering = ! bToggleIndirectRendering;
 
285
                        }
 
286
                }
 
287
                else
 
288
                {
 
289
                        g_openglConfig.bPBufferAvailable = TRUE;
 
290
                }
 
291
        }
 
292
        
 
293
        //\_________________ on verifier les capacites des textures.
 
294
        g_openglConfig.bTextureFromPixmapAvailable = _check_client_glx_extension ("GLX_EXT_texture_from_pixmap");
 
295
        if (g_openglConfig.bTextureFromPixmapAvailable)
 
296
        {
 
297
                g_openglConfig.bindTexImage = (gpointer)glXGetProcAddress ("glXBindTexImageEXT");
 
298
                g_openglConfig.releaseTexImage = (gpointer)glXGetProcAddress ("glXReleaseTexImageEXT");
 
299
                g_openglConfig.bTextureFromPixmapAvailable = (g_openglConfig.bindTexImage && g_openglConfig.releaseTexImage);
 
300
        }
 
301
        
 
302
        return TRUE;
 
303
}
 
304
 
 
305
 
 
306
 
 
307
static GLXPbuffer _cairo_dock_create_pbuffer (int iWidth, int iHeight, GLXContext *pContext)
 
308
{
 
309
        Display *XDisplay = gdk_x11_get_default_xdisplay ();
 
310
        
 
311
        GLXFBConfig *pFBConfigs;
 
312
        XRenderPictFormat *pPictFormat = NULL;
 
313
        int visAttribs[] = {
 
314
                GLX_DRAWABLE_TYPE,      GLX_PBUFFER_BIT | GLX_WINDOW_BIT,
 
315
                GLX_RENDER_TYPE,                GLX_RGBA_BIT,
 
316
                GLX_RED_SIZE,           1,
 
317
                GLX_GREEN_SIZE,                 1,
 
318
                GLX_BLUE_SIZE,          1,
 
319
                GLX_ALPHA_SIZE,                 1,
 
320
                GLX_DEPTH_SIZE,                 1,
 
321
                None};
 
322
        
 
323
        XVisualInfo *pVisInfo = NULL;
 
324
        int i, iNumOfFBConfigs = 0;
 
325
        pFBConfigs = glXChooseFBConfig (XDisplay,
 
326
                DefaultScreen (XDisplay),
 
327
                visAttribs,
 
328
                &iNumOfFBConfigs);
 
329
        if (iNumOfFBConfigs == 0)
 
330
        {
 
331
                cd_warning ("No suitable visual could be found for pbuffer\n this might affect the drawing of some applets which are inside a dock");
 
332
                *pContext = 0;
 
333
                return 0;
 
334
        }
 
335
        cd_debug (" -> %d FBConfig(s) pour le pbuffer", iNumOfFBConfigs);
 
336
        
 
337
        int pbufAttribs [] = {
 
338
                GLX_PBUFFER_WIDTH, iWidth,
 
339
                GLX_PBUFFER_HEIGHT, iHeight,
 
340
                GLX_LARGEST_PBUFFER, True,
 
341
                None};
 
342
        GLXPbuffer pbuffer = glXCreatePbuffer (XDisplay, pFBConfigs[0], pbufAttribs);
 
343
        
 
344
        pVisInfo = glXGetVisualFromFBConfig (XDisplay, pFBConfigs[0]);
 
345
        
 
346
        GdkGLContext *pGlContext = gtk_widget_get_gl_context (g_pMainDock->container.pWidget);
 
347
        GLXContext mainContext = GDK_GL_CONTEXT_GLXCONTEXT (pGlContext);
 
348
        *pContext = glXCreateContext (XDisplay, pVisInfo, mainContext, ! g_openglConfig.bIndirectRendering);
 
349
        
 
350
        XFree (pVisInfo);
 
351
        XFree (pFBConfigs);
 
352
        
 
353
        return pbuffer;
 
354
}
 
355
 
 
356
void cairo_dock_create_icon_pbuffer (void)
 
357
{
 
358
        if (! g_openglConfig.pGlConfig || ! g_openglConfig.bPBufferAvailable)
 
359
                return ;
 
360
        int iWidth = 0, iHeight = 0;
 
361
        int i;
 
362
        for (i = 0; i < CAIRO_DOCK_NB_TYPES; i += 2)
 
363
        {
 
364
                iWidth = MAX (iWidth, myIcons.tIconAuthorizedWidth[i]);
 
365
                iHeight = MAX (iHeight, myIcons.tIconAuthorizedHeight[i]);
 
366
        }
 
367
        if (iWidth == 0)
 
368
                iWidth = 48;
 
369
        if (iHeight == 0)
 
370
                iHeight = 48;
 
371
        iWidth *= (1 + myIcons.fAmplitude);
 
372
        iHeight *= (1 + myIcons.fAmplitude);
 
373
        
 
374
        cd_debug ("%s (%dx%d)", __func__, iWidth, iHeight);
 
375
        if (g_openglConfig.iIconPbufferWidth != iWidth || g_openglConfig.iIconPbufferHeight != iHeight)
 
376
        {
 
377
                Display *XDisplay = gdk_x11_get_default_xdisplay ();
 
378
                if (g_openglConfig.iconPbuffer != 0)
 
379
                {
 
380
                        glXDestroyPbuffer (XDisplay, g_openglConfig.iconPbuffer);
 
381
                        glXDestroyContext (XDisplay, g_openglConfig.iconContext);
 
382
                        g_openglConfig.iconContext = 0;
 
383
                }
 
384
                g_openglConfig.iconPbuffer = _cairo_dock_create_pbuffer (iWidth, iHeight, &g_openglConfig.iconContext);
 
385
                g_openglConfig.iIconPbufferWidth = iWidth;
 
386
                g_openglConfig.iIconPbufferHeight = iHeight;
 
387
                
 
388
                g_print ("activating pbuffer, usually buggy drivers will crash here ...");
 
389
                if (g_openglConfig.iconPbuffer != 0 && g_openglConfig.iconContext != 0 && glXMakeCurrent (XDisplay, g_openglConfig.iconPbuffer, g_openglConfig.iconContext))
 
390
                {
 
391
                        glMatrixMode(GL_PROJECTION);
 
392
                        glLoadIdentity();
 
393
                        glOrtho(0, iWidth, 0, iHeight, 0.0, 500.0);
 
394
                        glMatrixMode (GL_MODELVIEW);
 
395
                        
 
396
                        glLoadIdentity();
 
397
                        gluLookAt (0., 0., 3.,
 
398
                                0., 0., 0.,
 
399
                                0.0f, 1.0f, 0.0f);
 
400
                        
 
401
                        glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
 
402
                        glClearDepth (1.0f);
 
403
                }
 
404
                g_print (" ok, they are fine enough.\n");
 
405
        }
 
406
}
 
407
 
 
408
void cairo_dock_destroy_icon_pbuffer (void)
 
409
{
 
410
        Display *XDisplay = gdk_x11_get_default_xdisplay ();
 
411
        if (g_openglConfig.iconPbuffer != 0)
 
412
        {
 
413
                glXDestroyPbuffer (XDisplay, g_openglConfig.iconPbuffer);
 
414
                g_openglConfig.iconPbuffer = 0;
 
415
        }
 
416
        if (g_openglConfig.iconContext != 0)
 
417
        {
 
418
                glXDestroyContext (XDisplay, g_openglConfig.iconContext);
 
419
                g_openglConfig.iconContext = 0;
 
420
        }
 
421
        g_openglConfig.iIconPbufferWidth = 0;
 
422
        g_openglConfig.iIconPbufferHeight = 0;
 
423
}
 
424
 
 
425
gboolean cairo_dock_begin_draw_icon (Icon *pIcon, CairoContainer *pContainer)
 
426
{
 
427
        if (CAIRO_DOCK_IS_DESKLET (pContainer))
 
428
        {
 
429
                GdkGLContext *pGlContext = gtk_widget_get_gl_context (pContainer->pWidget);
 
430
                GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (pContainer->pWidget);
 
431
                if (! gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
 
432
                        return FALSE;
 
433
                
 
434
                cairo_dock_set_ortho_view (pContainer->iWidth, pContainer->iHeight);
 
435
        }
 
436
        else if (g_openglConfig.iconContext != 0)
 
437
        {
 
438
                Display *XDisplay = gdk_x11_get_default_xdisplay ();
 
439
                if (! glXMakeCurrent (XDisplay, g_openglConfig.iconPbuffer, g_openglConfig.iconContext))
 
440
                        return FALSE;
 
441
                glLoadIdentity ();
 
442
                glTranslatef (g_openglConfig.iIconPbufferWidth/2, g_openglConfig.iIconPbufferHeight/2, - g_openglConfig.iIconPbufferHeight/2);
 
443
        }
 
444
        else
 
445
                return FALSE;
 
446
        
 
447
        glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
448
        
 
449
        glColor4f(1., 1., 1., 1.);
 
450
        
 
451
        glScalef (1., -1., 1.);
 
452
        
 
453
        return TRUE;
 
454
}
 
455
 
 
456
void cairo_dock_end_draw_icon (Icon *pIcon, CairoContainer *pContainer)
 
457
{
 
458
        g_return_if_fail (pIcon->iIconTexture != 0);
 
459
        // taille de la texture
 
460
        int iWidth, iHeight;
 
461
        cairo_dock_get_icon_extent (pIcon, pContainer, &iWidth, &iHeight);
 
462
        
 
463
        // copie dans notre texture
 
464
        glEnable (GL_TEXTURE_2D);
 
465
        glBindTexture (GL_TEXTURE_2D, pIcon->iIconTexture);
 
466
        glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
467
        glEnable(GL_BLEND);
 
468
        glBlendFunc (GL_ZERO, GL_ONE);
 
469
        glColor4f(1., 1., 1., 1.);
 
470
        
 
471
        int x,y;
 
472
        if (CAIRO_DOCK_IS_DESKLET (pContainer))
 
473
        {
 
474
                x = (pContainer->iWidth - iWidth)/2;
 
475
                y = (pContainer->iHeight - iHeight)/2;
 
476
        }
 
477
        else
 
478
        {
 
479
                x = (g_openglConfig.iIconPbufferWidth - iWidth)/2;
 
480
                y = (g_openglConfig.iIconPbufferHeight - iHeight)/2;
 
481
        }
 
482
        
 
483
        glCopyTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, x, y, iWidth, iHeight, 0);  // target, num mipmap, format, x,y, w,h, border.
 
484
        glDisable (GL_TEXTURE_2D);
 
485
        glDisable (GL_BLEND);
 
486
        
 
487
        //end
 
488
        if (CAIRO_DOCK_IS_DESKLET (pContainer))
 
489
        {
 
490
                cairo_dock_set_perspective_view (pContainer->iWidth, pContainer->iHeight);
 
491
                
 
492
                GdkGLDrawable *pGlDrawable = gtk_widget_get_gl_drawable (pContainer->pWidget);
 
493
                gdk_gl_drawable_gl_end (pGlDrawable);
 
494
        }
 
495
}
 
496
 
 
497
 
 
498
 
 
499
 
 
500
void cairo_dock_set_perspective_view (int iWidth, int iHeight)
 
501
{
 
502
        glMatrixMode(GL_PROJECTION);
 
503
        glLoadIdentity();
 
504
        gluPerspective(60.0, 1.0*(GLfloat)iWidth/(GLfloat)iHeight, 1., 4*iHeight);
 
505
        glMatrixMode (GL_MODELVIEW);
 
506
        
 
507
        glLoadIdentity ();
 
508
        gluLookAt (0., 0., 3.,
 
509
                0., 0., 0.,
 
510
                0.0f, 1.0f, 0.0f);
 
511
        glTranslatef (0., 0., -iHeight*(sqrt(3)/2) - 1);
 
512
}
 
513
 
 
514
void cairo_dock_set_ortho_view (int iWidth, int iHeight)
 
515
{
 
516
        glMatrixMode(GL_PROJECTION);
 
517
        glLoadIdentity();
 
518
        glOrtho(0, iWidth, 0, iHeight, 0.0, 500.0);
 
519
        glMatrixMode (GL_MODELVIEW);
 
520
        
 
521
        glLoadIdentity ();
 
522
        gluLookAt (0/2, 0/2, 3.,
 
523
                0/2, 0/2, 0.,
 
524
                0.0f, 1.0f, 0.0f);
 
525
        glTranslatef (iWidth/2, iHeight/2, - iHeight/2);
 
526
}
 
527
 
 
528
 
 
529
void cairo_dock_apply_desktop_background_opengl (CairoContainer *pContainer)
 
530
{
 
531
        if (! mySystem.bUseFakeTransparency || ! g_pFakeTransparencyDesktopBg || g_pFakeTransparencyDesktopBg->iTexture == 0)
 
532
                return ;
 
533
        
 
534
        _cairo_dock_enable_texture ();
 
535
        _cairo_dock_set_blend_source ();
 
536
        _cairo_dock_set_alpha (1.);
 
537
        glBindTexture (GL_TEXTURE_2D, g_pFakeTransparencyDesktopBg->iTexture);
 
538
        
 
539
        glBegin(GL_QUADS);
 
540
        glTexCoord2f (1.*(pContainer->iWindowPositionX + 0.)/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL],
 
541
        1.*(pContainer->iWindowPositionY + 0.)/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
 
542
        glVertex3f (0., pContainer->iHeight, 0.);  // Top Left.
 
543
        
 
544
        glTexCoord2f (1.*(pContainer->iWindowPositionX + pContainer->iWidth)/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL], 1.*(pContainer->iWindowPositionY + 0.)/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
 
545
        glVertex3f (pContainer->iWidth, pContainer->iHeight, 0.);  // Top Right
 
546
        
 
547
        glTexCoord2f (1.*(pContainer->iWindowPositionX + pContainer->iWidth)/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL], 1.*(pContainer->iWindowPositionY + pContainer->iHeight)/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
 
548
        glVertex3f (pContainer->iWidth, 0., 0.);  // Bottom Right
 
549
        
 
550
        glTexCoord2f (1.*(pContainer->iWindowPositionX + 0.)/g_iXScreenWidth[CAIRO_DOCK_HORIZONTAL], 1.*(pContainer->iWindowPositionY + pContainer->iHeight)/g_iXScreenHeight[CAIRO_DOCK_HORIZONTAL]);
 
551
        glVertex3f (0., 0., 0.);  // Bottom Left
 
552
        glEnd();
 
553
        
 
554
        _cairo_dock_disable_texture ();
 
555
}
 
556
 
 
557
 
 
558
 
 
559
 
 
560
static void _cairo_dock_post_initialize_opengl_backend (GtkWidget* pWidget, gpointer data)  // initialisation necessitant un contexte opengl.
 
561
{
 
562
        static gboolean bChecked=FALSE;
 
563
        if (bChecked)
 
564
                return;
 
565
        GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
 
566
        GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
 
567
        if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
 
568
                return ;
 
569
        
 
570
        bChecked = TRUE;
 
571
        g_openglConfig.bNonPowerOfTwoAvailable = _check_gl_extension ("GL_ARB_texture_non_power_of_two");
 
572
        
 
573
        g_print ("OpenGL config summary :\n - bNonPowerOfTwoAvailable : %d\n - bPBufferAvailable : %d\n - direct rendering : %d\n - bTextureFromPixmapAvailable : %d\n - GLX version : %d.%d\n - OpenGL version: %s\n - OpenGL vendor: %s\n - OpenGL renderer: %s\n\n",
 
574
                g_openglConfig.bNonPowerOfTwoAvailable,
 
575
                g_openglConfig.bPBufferAvailable,
 
576
                !g_openglConfig.bIndirectRendering,
 
577
                g_openglConfig.bTextureFromPixmapAvailable,
 
578
                g_openglConfig.iGlxMajor,
 
579
                g_openglConfig.iGlxMinor,
 
580
                glGetString (GL_VERSION),
 
581
                glGetString (GL_VENDOR),
 
582
                glGetString (GL_RENDERER));
 
583
        
 
584
        gdk_gl_drawable_gl_end (pGlDrawable);
 
585
}
 
586
 
 
587
 
 
588
static void _reset_opengl_context (GtkWidget* pWidget, gpointer data)
 
589
{
 
590
        if (! g_bUseOpenGL)
 
591
                return ;
 
592
        
 
593
        GdkGLContext* pGlContext = gtk_widget_get_gl_context (pWidget);
 
594
        GdkGLDrawable* pGlDrawable = gtk_widget_get_gl_drawable (pWidget);
 
595
        if (!gdk_gl_drawable_gl_begin (pGlDrawable, pGlContext))
 
596
                return ;
 
597
        
 
598
        glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
 
599
        glClearDepth (1.0f);
 
600
        glClearStencil (0);
 
601
        glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
 
602
        
 
603
        /// a tester ...
 
604
        if (g_bEasterEggs)
 
605
                glEnable (GL_MULTISAMPLE_ARB);
 
606
        
 
607
        glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);  // GL_MODULATE / GL_DECAL /  GL_BLEND
 
608
        
 
609
        glTexParameteri (GL_TEXTURE_2D,
 
610
                GL_TEXTURE_MIN_FILTER,
 
611
                GL_LINEAR_MIPMAP_LINEAR);
 
612
        glTexParameteri (GL_TEXTURE_2D,
 
613
                GL_TEXTURE_MAG_FILTER,
 
614
                GL_LINEAR);
 
615
        
 
616
        gdk_gl_drawable_gl_end (pGlDrawable);
 
617
}
 
618
void cairo_dock_set_gl_capabilities (GtkWidget *pWindow)
 
619
{
 
620
        gboolean bFirstContainer = (! g_pMainDock || ! g_pMainDock->container.pWidget);
 
621
        GdkGLContext *pMainGlContext = (bFirstContainer ? NULL : gtk_widget_get_gl_context (g_pMainDock->container.pWidget));  // NULL si on est en train de creer la fenetre du main dock, ce qui nous convient.
 
622
        gtk_widget_set_gl_capability (pWindow,
 
623
                g_openglConfig.pGlConfig,
 
624
                pMainGlContext,  // on partage les ressources entre les contextes.
 
625
                ! g_openglConfig.bIndirectRendering,  // TRUE <=> direct connection to the graphics system.
 
626
                GDK_GL_RGBA_TYPE);
 
627
        if (bFirstContainer)  // c'est donc le 1er container cree, on finit l'initialisation du backend opengl.
 
628
                g_signal_connect (G_OBJECT (pWindow),
 
629
                        "realize",
 
630
                        G_CALLBACK (_cairo_dock_post_initialize_opengl_backend),
 
631
                        NULL);
 
632
        g_signal_connect_after (G_OBJECT (pWindow),
 
633
                "realize",
 
634
                G_CALLBACK (_reset_opengl_context),
 
635
                NULL);
 
636
}