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 <stdlib.h>
21 #include <string.h>
22 #include <math.h>
23 
24 #include "applet-struct.h"
25 #include "applet-session.h"
26 #include "applet-draw.h"
27 
28 #define STATIC_ANGLE 20.
29 
30 #define _alpha_prompt(k,n) cos (G_PI/2*fabs ((double) ((k % (2*n)) - n) / n));
31 
32 const int s_iNbPromptAnimationSteps = 40;
33 
_cd_do_get_matching_icons_width(int * iNbIcons)34 static inline int _cd_do_get_matching_icons_width (int *iNbIcons)
35 {
36 	int i = 0, iIconsWidth = 0;
37 	Icon *pIcon;
38 	int iWidth, iHeight;
39 	double fZoom;
40 	GList *ic;
41 	for (ic = myData.pMatchingIcons; ic != NULL; ic = ic->next)
42 	{
43 		pIcon = ic->data;
44 		if (pIcon->image.pSurface == NULL && pIcon->image.iTexture == 0)  // icone pas encore chargee.
45 			continue;
46 		cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
47 		if (iHeight != 0)
48 		{
49 			fZoom = (double) g_pMainDock->container.iHeight/2 / iHeight;
50 			iIconsWidth += iWidth * fZoom;
51 		}
52 		i ++;
53 	}
54 	*iNbIcons = i;
55 	return iIconsWidth;
56 }
57 
_cd_do_get_icon_x(GList * pElement)58 static inline int _cd_do_get_icon_x (GList *pElement)
59 {
60 	int iOffset = 0;
61 	Icon *pIcon;
62 	int iWidth, iHeight;
63 	double fZoom;
64 	GList *ic;
65 	for (ic = myData.pMatchingIcons; ic != NULL && ic != pElement; ic = ic->next)
66 	{
67 		pIcon = ic->data;
68 		if (pIcon->image.pSurface == NULL && pIcon->image.iTexture == 0)  // icone pas encore chargee.
69 			continue;
70 		cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
71 		if (iHeight != 0)
72 		{
73 			fZoom = (double) g_pMainDock->container.iHeight/2 / iHeight;
74 			iOffset += iWidth * fZoom;
75 		}
76 	}
77 	return iOffset;
78 }
79 
cd_do_render_cairo(CairoDock * pMainDock,cairo_t * pCairoContext)80 void cd_do_render_cairo (CairoDock *pMainDock, cairo_t *pCairoContext)
81 {
82 	double fAlpha;
83 	if (myData.iCloseTime != 0) // animation de fin
84 		fAlpha = (double) myData.iCloseTime / myConfig.iCloseDuration;
85 	else
86 		fAlpha = 1.;
87 
88 	if (myData.pCharList == NULL && myData.pListingHistory == NULL)  // aucune lettre de tapee => on montre le prompt.
89 	{
90 		if (myData.pPromptSurface != NULL)
91 		{
92 			double fFrameWidth = myData.iPromptWidth;
93 			double fFrameHeight = myData.iPromptHeight;
94 
95 			double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du prompt.
96 			fDockOffsetX = (pMainDock->container.iWidth - fFrameWidth) / 2;
97 			fDockOffsetY = (pMainDock->container.iHeight - fFrameHeight) / 2;  // centre verticalement.
98 
99 			fAlpha *= _alpha_prompt (myData.iPromptAnimationCount, s_iNbPromptAnimationSteps);
100 
101 			if (fAlpha != 0)
102 			{
103 				cairo_translate (pCairoContext, fDockOffsetX, fDockOffsetY);
104 				cairo_dock_draw_surface (pCairoContext, myData.pPromptSurface, fFrameWidth, fFrameHeight, pMainDock->container.bDirectionUp, pMainDock->container.bIsHorizontal, fAlpha);
105 				//cairo_set_source_surface (pCairoContext, myData.pPromptSurface, 0., 0.);
106 				//cairo_paint_with_alpha (pCairoContext, fAlpha);
107 			}
108 		}
109 	}
110 	else  // si du texte a ete entre, on le dessine, ainsi que eventuellement la liste des icones correspondantes.
111 	{
112 		// dessin des icones correspondantes.
113 		int iIconsWidth = 0, iNbIcons = 0;
114 		if (myData.pMatchingIcons != NULL)
115 		{
116 			// on determine au prealable la largeur des icones pour pouvoir les centrer.
117 			iIconsWidth = _cd_do_get_matching_icons_width (&iNbIcons);
118 
119 			// dessin du fond des icones.
120 			double fFrameWidth = iIconsWidth;
121 			double fFrameHeight = pMainDock->container.iHeight/2;
122 			double fRadius = fFrameHeight / 10;
123 			double fLineWidth = 0.;
124 			double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du cadre.
125 			fDockOffsetX = (pMainDock->container.iWidth - fFrameWidth) / 2;
126 			fDockOffsetY = (!myConfig.bTextOnTop ? 0. : pMainDock->container.iHeight - fFrameHeight);
127 
128 			cairo_save (pCairoContext);
129 			cairo_translate (pCairoContext, fDockOffsetX -fRadius, fDockOffsetY);
130 			cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, fFrameWidth, fFrameHeight);
131 			cairo_set_line_width (pCairoContext, fLineWidth);
132 			cairo_set_source_rgba (pCairoContext, myConfig.pFrameColor[0], myConfig.pFrameColor[1], myConfig.pFrameColor[2], myConfig.pFrameColor[3] * fAlpha);
133 			cairo_fill (pCairoContext);
134 			cairo_restore (pCairoContext);
135 
136 			// on les dessine.
137 			//int iOffsetX = _cd_do_get_icon_x (myData.pCurrentMatchingElement) + myData.iCurrentMatchingOffset * myData.iCurrentMatchingDirection - iIconsWidth/2;  // ecart au centre du debut de l'icone courante.
138 			//iOffsetX = - iOffsetX;
139 			int iOffsetX = myData.iCurrentMatchingOffset + iIconsWidth/2;
140 			while (iOffsetX > iIconsWidth)
141 				iOffsetX -= iIconsWidth;
142 			while (iOffsetX < 0)
143 				iOffsetX += iIconsWidth;
144 
145 			double fIconScale = (iIconsWidth > pMainDock->container.iWidth ? (double) pMainDock->container.iWidth / iIconsWidth : 1.);
146 			double x0 = (pMainDock->container.iWidth - iIconsWidth * fIconScale) / 2;
147 			double x = x0 + iOffsetX * fIconScale;  // abscisse de l'icone courante.
148 			Icon *pIcon;
149 			int iWidth, iHeight;
150 			double fZoom;
151 			GList *ic;
152 			for (ic = myData.pMatchingIcons; ic != NULL; ic = ic->next)
153 			{
154 				pIcon = ic->data;
155 				if (pIcon->image.pSurface == NULL)  // icone pas encore chargee.
156 					continue;
157 				cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
158 				fZoom = fIconScale * pMainDock->container.iHeight/2 / iHeight * (myData.pCurrentMatchingElement == ic ? 1. : 1.);
159 				cairo_save (pCairoContext);
160 
161 				//if (!bRound)
162 				{
163 					if (x < x0)
164 						x += iIconsWidth * fIconScale;
165 					else if (x > x0 + iIconsWidth * fIconScale)
166 						x -= iIconsWidth * fIconScale;
167 				}
168 				if (pMainDock->container.bIsHorizontal)
169 					cairo_translate (pCairoContext,
170 						x - (iNbIcons & 1 ? iWidth * fZoom * fIconScale / 2 : 0.),
171 						(myConfig.bTextOnTop ?
172 							pMainDock->container.iHeight/2 :
173 							0.));
174 				else
175 					cairo_translate (pCairoContext,
176 						(myConfig.bTextOnTop ?
177 							pMainDock->container.iHeight/2 :
178 							0.),
179 						x - (iNbIcons & 1 ? iWidth * fZoom * fIconScale / 2 : 0.));
180 				cairo_scale (pCairoContext,
181 					fZoom,
182 					fZoom);
183 				cairo_set_source_surface (pCairoContext, pIcon->image.pSurface, 0., 0.);
184 				cairo_paint_with_alpha (pCairoContext, (myData.pCurrentMatchingElement == ic ? 1. : .5));
185 
186 				if (myData.pCurrentMatchingElement == ic)
187 				{
188 					fLineWidth = 4.;
189 					cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, iWidth-2*fRadius, iHeight-fLineWidth);
190 					cairo_set_line_width (pCairoContext, fLineWidth);
191 					cairo_set_source_rgba (pCairoContext, myConfig.pFrameColor[0]+.1, myConfig.pFrameColor[1]+.1, myConfig.pFrameColor[2]+.1, 1.);
192 					cairo_stroke (pCairoContext);
193 				}
194 
195 				cairo_restore (pCairoContext);
196 				x += iWidth * fZoom;
197 			}
198 		}
199 
200 		// dessin du fond du texte.
201 		double fFrameWidth = myData.iTextWidth;
202 		double fTextScale = (fFrameWidth > pMainDock->container.iWidth ? (double) pMainDock->container.iWidth / fFrameWidth : 1.);
203 		double fFrameHeight = myData.iTextHeight;
204 		double fRadius = fFrameHeight / 5 * myConfig.fFontSizeRatio;
205 		double fLineWidth = 0.;
206 		double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du cadre.
207 		fDockOffsetX = (pMainDock->container.iWidth - fFrameWidth * fTextScale) / 2;
208 		fDockOffsetY = (myConfig.bTextOnTop ? 0. : pMainDock->container.iHeight - fFrameHeight);
209 
210 		cairo_save (pCairoContext);
211 		cairo_translate (pCairoContext, fDockOffsetX -fRadius, fDockOffsetY);
212 		cairo_dock_draw_rounded_rectangle (pCairoContext, fRadius, fLineWidth, fFrameWidth, fFrameHeight);
213 		cairo_set_line_width (pCairoContext, fLineWidth);
214 		cairo_set_source_rgba (pCairoContext, myConfig.pFrameColor[0], myConfig.pFrameColor[1], myConfig.pFrameColor[2], myConfig.pFrameColor[3] * fAlpha);
215 		cairo_fill (pCairoContext);
216 		cairo_restore (pCairoContext);
217 
218 		// dessin des lettres.
219 		CDChar *pChar;
220 		GList *c;
221 		for (c = myData.pCharList; c != NULL; c = c->next)
222 		{
223 			pChar = c->data;
224 			cairo_save (pCairoContext);
225 
226 			cairo_translate (pCairoContext,
227 				(pChar->iCurrentX * fTextScale + pMainDock->container.iWidth/2),
228 				pChar->iCurrentY + (myConfig.bTextOnTop ?
229 					(myData.iTextHeight - pChar->iHeight) :
230 					pMainDock->container.iHeight - pChar->iHeight));  // aligne en bas.
231 
232 			if (fTextScale != 1)
233 				cairo_scale (pCairoContext, fTextScale, fTextScale);
234 			cairo_set_source_surface (pCairoContext, pChar->pSurface, 0., 0.);
235 			cairo_paint_with_alpha (pCairoContext, fAlpha);
236 
237 			cairo_restore (pCairoContext);
238 		}
239 	}
240 }
241 
242 
cd_do_render_opengl(CairoDock * pMainDock)243 void cd_do_render_opengl (CairoDock *pMainDock)
244 {
245 	double fAlpha;
246 	if (myData.iCloseTime != 0) // animation de fin
247 		fAlpha = (double) myData.iCloseTime / myConfig.iCloseDuration;
248 	else
249 		fAlpha = 1.;
250 
251 	if (myData.pCharList == NULL && myData.pListingHistory == NULL)  // aucune lettre de tapee => on montre le prompt.
252 	{
253 		if (myData.iPromptTexture != 0)
254 		{
255 			double fFrameWidth = myData.iPromptWidth;
256 			double fFrameHeight = myData.iPromptHeight;
257 
258 			/*double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du prompt.
259 			fDockOffsetX = (pMainDock->container.iWidth - fFrameWidth) / 2;
260 			fDockOffsetY = (pMainDock->container.iHeight - fFrameHeight) / 2;*/
261 
262 			fAlpha *= _alpha_prompt (myData.iPromptAnimationCount, s_iNbPromptAnimationSteps);
263 
264 			if (fAlpha != 0)
265 			{
266 				glPushMatrix ();
267 				if (! pMainDock->container.bIsHorizontal)
268 					glRotatef (pMainDock->container.bDirectionUp ? 90. : -90., 0., 0., 1.);
269 				glTranslatef (pMainDock->container.iWidth/2, pMainDock->container.iHeight/2, 0.);
270 
271 				_cairo_dock_enable_texture ();
272 				_cairo_dock_set_blend_alpha ();
273 
274 				_cairo_dock_apply_texture_at_size_with_alpha (myData.iPromptTexture, fFrameWidth, fFrameHeight, fAlpha);
275 
276 				_cairo_dock_disable_texture ();
277 
278 				glPopMatrix();
279 			}
280 		}
281 	}
282 	else  // si du texte a ete entre, on le dessine, ainsi que eventuellement la liste des icones correspondantes.
283 	{
284 		// dessin des icones correspondantes.
285 		int iIconsWidth = 0, iNbIcons = 0;
286 		if (myData.pMatchingIcons != NULL)
287 		{
288 			// on determine au prealable la largeur des icones pour povouir les centrer.
289 			iIconsWidth = _cd_do_get_matching_icons_width (&iNbIcons);
290 
291 			// dessin du fond des icones.
292 			double fFrameWidth = iIconsWidth;
293 			double fFrameHeight = pMainDock->container.iHeight/2;
294 			double fRadius = fFrameHeight / 10;
295 			double fLineWidth = 0.;
296 			double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du cadre.
297 			fDockOffsetX = pMainDock->container.iWidth/2 - fFrameWidth / 2 - fRadius;
298 			fDockOffsetY = (!myConfig.bTextOnTop ? pMainDock->container.iHeight : fFrameHeight);
299 			double fFrameColor[4] = {myConfig.pFrameColor[0], myConfig.pFrameColor[1], myConfig.pFrameColor[2], myConfig.pFrameColor[3] * fAlpha};
300 			glPushMatrix ();
301 			if (! pMainDock->container.bIsHorizontal)
302 				glRotatef (pMainDock->container.bDirectionUp ? 90. : -90., 0., 0., 1.);
303 			glTranslatef (fDockOffsetX, fDockOffsetY, 0.);
304 			cairo_dock_draw_rounded_rectangle_opengl (fFrameWidth, fFrameHeight, fRadius, fLineWidth, fFrameColor);
305 			glPopMatrix ();
306 
307 			// on les dessine.
308 			//int iOffsetX = _cd_do_get_icon_x (myData.pCurrentMatchingElement) + myData.iCurrentMatchingOffset * myData.iCurrentMatchingDirection - iIconsWidth/2;  // ecart au centre du debut de l'icone courante.
309 			//iOffsetX = - iOffsetX;
310 			//g_print ("myData.iCurrentMatchingOffset : %d\n", myData.iCurrentMatchingOffset);
311 			int iOffsetX = myData.iCurrentMatchingOffset + iIconsWidth/2;
312 			while (iOffsetX > iIconsWidth)
313 				iOffsetX -= iIconsWidth;
314 			while (iOffsetX < 0)
315 				iOffsetX += iIconsWidth;
316 
317 			double fIconScale = (iIconsWidth > pMainDock->container.iWidth ? (double) pMainDock->container.iWidth / (iIconsWidth) : 1.);
318 			double x0 = (pMainDock->container.iWidth - iIconsWidth * fIconScale) / 2;
319 			double x = x0 - iOffsetX * fIconScale;  // abscisse de l'icone courante.
320 			Icon *pIcon;
321 			int iWidth, iHeight;
322 			double fZoom;
323 			GList *ic;
324 
325 			_cairo_dock_enable_texture ();
326 			_cairo_dock_set_blend_alpha ();
327 			_cairo_dock_set_alpha (1.);
328 			for (ic = myData.pMatchingIcons; ic != NULL; ic = ic->next)
329 			{
330 				pIcon = ic->data;
331 				if (pIcon->image.iTexture == 0)  // icone pas encore chargee.
332 					continue;
333 				cairo_dock_get_icon_extent (pIcon, &iWidth, &iHeight);
334 				fZoom = (double) pMainDock->container.iHeight/2 / iHeight * (myData.pCurrentMatchingElement == ic ? 1. : 1.);
335 				glPushMatrix ();
336 
337 				//if (!bRound)
338 				{
339 					if (x < x0)
340 						x += iIconsWidth * fIconScale;
341 					else if (x + (iNbIcons & 1 ? 0. : iWidth * fZoom/2 * fIconScale) > x0 + iIconsWidth * fIconScale)
342 						x -= iIconsWidth * fIconScale;
343 				}
344 				if (pMainDock->container.bIsHorizontal)
345 					glTranslatef (x + (iNbIcons & 1 ? 0. : iWidth * fZoom/2 * fIconScale),
346 						(myConfig.bTextOnTop ?
347 							pMainDock->container.iHeight/4 :
348 							pMainDock->container.iHeight - iHeight * fZoom/2),
349 						0.);
350 				else
351 					glTranslatef ((myConfig.bTextOnTop ?
352 							pMainDock->container.iHeight/4 :
353 							pMainDock->container.iHeight - iHeight * fZoom/2),
354 						x + (iNbIcons & 1 ? 0. : iWidth * fZoom/2 * fIconScale),
355 						0.);
356 				_cairo_dock_apply_texture_at_size_with_alpha (pIcon->image.iTexture,
357 					iWidth * fZoom * fIconScale,
358 					pMainDock->container.iHeight/2 * fIconScale,
359 					(myData.pCurrentMatchingElement == ic ? 1. : .5));
360 
361 				if (myData.pCurrentMatchingElement == ic)
362 				{
363 					_cairo_dock_disable_texture ();
364 					fLineWidth = 4.;
365 					double fFrameColor[4] = {myConfig.pFrameColor[0]+.1, myConfig.pFrameColor[1]+.1, myConfig.pFrameColor[2]+.1, 1.};
366 					glTranslatef (iWidth/2 * fZoom * fIconScale + fLineWidth/2, iHeight * fZoom/2 * fIconScale - fLineWidth/2, 0.);
367 					cairo_dock_draw_rounded_rectangle_opengl (iWidth * fZoom * fIconScale - fLineWidth,
368 						iHeight * fZoom * fIconScale - fLineWidth,
369 						fRadius,
370 						fLineWidth,
371 						fFrameColor);
372 					_cairo_dock_enable_texture ();
373 					_cairo_dock_set_blend_alpha ();
374 				}
375 
376 				glPopMatrix ();
377 				x += iWidth * fZoom * fIconScale;
378 			}
379 			_cairo_dock_disable_texture ();
380 		}
381 		_cairo_dock_set_alpha (1.);
382 
383 		// dessin du fond du texte.
384 		double fFrameWidth = myData.iTextWidth;
385 		double fTextScale = (fFrameWidth > pMainDock->container.iWidth ? (double) pMainDock->container.iWidth / fFrameWidth : 1.);
386 		double fFrameHeight = myData.iTextHeight;
387 		double fRadius = myDocksParam.iDockRadius * myConfig.fFontSizeRatio;
388 
389 		double fDockOffsetX, fDockOffsetY;  // Offset du coin haut gauche du cadre.
390 		fDockOffsetX = pMainDock->container.iWidth/2 - fFrameWidth * fTextScale / 2 - fRadius;
391 		fDockOffsetY = (myConfig.bTextOnTop ? pMainDock->container.iHeight : fFrameHeight);
392 
393 		glPushMatrix ();
394 		double fFrameColor[4] = {myConfig.pFrameColor[0], myConfig.pFrameColor[1], myConfig.pFrameColor[2], myConfig.pFrameColor[3] * fAlpha};
395 
396 		if (! pMainDock->container.bIsHorizontal)
397 			glRotatef (pMainDock->container.bDirectionUp ? 90. : -90., 0., 0., 1.);
398 		glTranslatef (fDockOffsetX, fDockOffsetY, 0.);
399 		cairo_dock_draw_rounded_rectangle_opengl (fFrameWidth, fFrameHeight, fRadius, 0, fFrameColor);
400 		glPopMatrix();
401 
402 		// dessin des lettres.
403 		_cairo_dock_enable_texture ();
404 		_cairo_dock_set_blend_alpha ();
405 		_cairo_dock_set_alpha (fAlpha);
406 
407 		gldi_gl_container_set_perspective_view (CAIRO_CONTAINER (pMainDock));
408 		if (pMainDock->container.bIsHorizontal)
409 		{
410 			glTranslatef (-pMainDock->container.iWidth/2, -pMainDock->container.iHeight/2, 0.);
411 		}
412 		else
413 		{
414 			glTranslatef (-pMainDock->container.iHeight/2, -pMainDock->container.iWidth/2, 0.);
415 		}
416 		glEnable (GL_DEPTH_TEST);
417 
418 		CDChar *pChar;
419 		GList *c;
420 		for (c = myData.pCharList; c != NULL; c = c->next)
421 		{
422 			pChar = c->data;
423 			glPushMatrix();
424 
425 			if (pMainDock->container.bIsHorizontal)
426 				glTranslatef (pChar->iCurrentX * fTextScale + pMainDock->container.iWidth/2 + pChar->iWidth/2,
427 					(myConfig.bTextOnTop ?
428 						pMainDock->container.iHeight - (myData.iTextHeight - pChar->iHeight/2) :
429 						pChar->iHeight/2),
430 					0.);  // aligne en bas.
431 			else
432 				glTranslatef ((myConfig.bTextOnTop ?
433 						pMainDock->container.iHeight - (myData.iTextHeight - pChar->iHeight/2) :
434 						pChar->iHeight/2),
435 					pChar->iCurrentX * fTextScale + pMainDock->container.iWidth/2 + pChar->iWidth/2,
436 					0.);  // aligne en bas.
437 
438 			double fRotationAngle = pChar->fRotationAngle;
439 			if (myConfig.iAppearanceDuration != 0)
440 			{
441 				glBindTexture (GL_TEXTURE_2D, pChar->iTexture);
442 
443 				glScalef (pChar->iWidth * fTextScale, pChar->iHeight * fTextScale, 1.);
444 
445 				glRotatef (fRotationAngle, 1., 0., 0.);
446 				glRotatef (MIN (fRotationAngle/3, STATIC_ANGLE), 0., 0., 1.);
447 				glRotatef (MIN (fRotationAngle/3, STATIC_ANGLE), 0., 1., 0.);
448 
449 				glPolygonMode (GL_FRONT, GL_FILL);
450 				double a = .5 / sqrt (2);
451 				glBegin(GL_QUADS);
452 				// Front Face (note that the texture's corners have to match the quad's corners)
453 				glNormal3f(0,0,1);
454 				glTexCoord2f (0., 0.); glVertex3f(-a,  a,  a);  // Bottom Left Of The Texture and Quad
455 				glTexCoord2f (1., 0.); glVertex3f( a,  a,  a);  // Bottom Right Of The Texture and Quad
456 				glTexCoord2f (1., 1.); glVertex3f( a, -a,  a);  // Top Right Of The Texture and Quad
457 				glTexCoord2f (0., 1.); glVertex3f(-a, -a,  a);  // Top Left Of The Texture and Quad
458 				// Back Face
459 				glNormal3f(0,0,-1);
460 				glTexCoord2f (1., 0.); glVertex3f( -a, a, -a);  // Bottom Right Of The Texture and Quad
461 				glTexCoord2f (1., 1.); glVertex3f( -a, -a, -a);  // Top Right Of The Texture and Quad
462 				glTexCoord2f (0., 1.); glVertex3f(a, -a, -a);  // Top Left Of The Texture and Quad
463 				glTexCoord2f (0., 0.); glVertex3f(a, a, -a);  // Bottom Left Of The Texture and Quad
464 				// Top Face
465 				glNormal3f(0,1,0);
466 				glTexCoord2f (0., 1.); glVertex3f(-a,  a,  a);  // Top Left Of The Texture and Quad
467 				glTexCoord2f (0., 0.); glVertex3f(-a,  a, -a);  // Bottom Left Of The Texture and Quad
468 				glTexCoord2f (1., 0.); glVertex3f( a,  a, -a);  // Bottom Right Of The Texture and Quad
469 				glTexCoord2f (1., 1.); glVertex3f( a,  a,  a);  // Top Right Of The Texture and Quad
470 				// Bottom Face
471 				glNormal3f(0,-1,0);
472 				glTexCoord2f (1., 1.); glVertex3f( a, -a, -a);  // Top Right Of The Texture and Quad
473 				glTexCoord2f (0., 1.); glVertex3f(-a, -a, -a);  // Top Left Of The Texture and Quad
474 				glTexCoord2f (0., 0.); glVertex3f(-a, -a,  a);  // Bottom Left Of The Texture and Quad
475 				glTexCoord2f (1., 0.); glVertex3f( a, -a,  a);  // Bottom Right Of The Texture and Quad
476 				// Right face
477 				glNormal3f(1,0,0);
478 				glTexCoord2f (1., 0.);  glVertex3f( a,  a, -a);  // Bottom Right Of The Texture and Quad
479 				glTexCoord2f (1., 1.);  glVertex3f( a, -a, -a);  // Top Right Of The Texture and Quad
480 				glTexCoord2f (0., 1.);  glVertex3f( a, -a,  a);  // Top Left Of The Texture and Quad
481 				glTexCoord2f (0., 0.);  glVertex3f( a,  a,  a);  // Bottom Left Of The Texture and Quad
482 				// Left Face
483 				glNormal3f(-1,0,0);
484 				glTexCoord2f (0., 0.);  glVertex3f(-a,  a, -a);  // Bottom Left Of The Texture and Quad
485 				glTexCoord2f (1., 0.);  glVertex3f(-a,  a,  a);  // Bottom Right Of The Texture and Quad
486 				glTexCoord2f (1., 1.);  glVertex3f(-a, -a,  a);  // Top Right Of The Texture and Quad
487 				glTexCoord2f (0., 1.);  glVertex3f(-a, -a, -a);  // Top Left Of The Texture and Quad
488 				glEnd();
489 			}
490 			else
491 			{
492 				_cairo_dock_apply_texture_at_size (pChar->iTexture, pChar->iWidth, pChar->iHeight);
493 			}
494 
495 			glPopMatrix();
496 		}
497 		gldi_gl_container_set_ortho_view (CAIRO_CONTAINER (pMainDock));
498 		if (pMainDock->container.bIsHorizontal)
499 		{
500 			glTranslatef (-pMainDock->container.iWidth/2, -pMainDock->container.iHeight/2, 0.);
501 		}
502 		else
503 		{
504 			glTranslatef (-pMainDock->container.iHeight/2, -pMainDock->container.iWidth/2, 0.);
505 		}
506 		glDisable (GL_DEPTH_TEST);
507 	}
508 }
509