1 /*
2  * Copyright © 2005 Novell, Inc.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software
5  * and its documentation for any purpose is hereby granted without
6  * fee, provided that the above copyright notice appear in all copies
7  * and that both that copyright notice and this permission notice
8  * appear in supporting documentation, and that the name of
9  * Novell, Inc. not be used in advertising or publicity pertaining to
10  * distribution of the software without specific, written prior permission.
11  * Novell, Inc. makes no representations about the suitability of this
12  * software for any purpose. It is provided "as is" without express or
13  * implied warranty.
14  *
15  * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17  * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Author: David Reveman <davidr@novell.com>
24  */
25 
26 #include <stdlib.h>
27 #include <string.h>
28 #include <math.h>
29 
30 #include <compiz-core.h>
31 
32 ScreenPaintAttrib defaultScreenPaintAttrib = {
33     0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -DEFAULT_Z_CAMERA
34 };
35 
36 WindowPaintAttrib defaultWindowPaintAttrib = {
37     OPAQUE, BRIGHT, COLOR, 1.0f, 1.0f, 0.0f, 0.0f
38 };
39 
40 void
preparePaintScreen(CompScreen * screen,int msSinceLastPaint)41 preparePaintScreen (CompScreen *screen,
42 		    int	       msSinceLastPaint)
43 {
44 }
45 
46 void
donePaintScreen(CompScreen * screen)47 donePaintScreen (CompScreen *screen)
48 {
49 }
50 
51 void
applyScreenTransform(CompScreen * screen,const ScreenPaintAttrib * sAttrib,CompOutput * output,CompTransform * transform)52 applyScreenTransform (CompScreen	      *screen,
53 		      const ScreenPaintAttrib *sAttrib,
54 		      CompOutput	      *output,
55 		      CompTransform	      *transform)
56 {
57     matrixTranslate (transform,
58 		     sAttrib->xTranslate,
59 		     sAttrib->yTranslate,
60 		     sAttrib->zTranslate + sAttrib->zCamera);
61     matrixRotate (transform,
62 		  sAttrib->xRotate, 0.0f, 1.0f, 0.0f);
63     matrixRotate (transform,
64 		  sAttrib->vRotate,
65 		  cosf (sAttrib->xRotate * DEG2RAD),
66 		  0.0f,
67 		  sinf (sAttrib->xRotate * DEG2RAD));
68     matrixRotate (transform,
69 		  sAttrib->yRotate, 0.0f, 1.0f, 0.0f);
70 }
71 
72 void
transformToScreenSpace(CompScreen * screen,CompOutput * output,float z,CompTransform * transform)73 transformToScreenSpace (CompScreen    *screen,
74 			CompOutput    *output,
75 			float         z,
76 			CompTransform *transform)
77 {
78     matrixTranslate (transform, -0.5f, -0.5f, z);
79     matrixScale (transform,
80 		 1.0f  / output->width,
81 		 -1.0f / output->height,
82 		 1.0f);
83     matrixTranslate (transform,
84 		     -output->region.extents.x1,
85 		     -output->region.extents.y2,
86 		     0.0f);
87 }
88 
89 void
prepareXCoords(CompScreen * screen,CompOutput * output,float z)90 prepareXCoords (CompScreen *screen,
91 		CompOutput *output,
92 		float      z)
93 {
94     glTranslatef (-0.5f, -0.5f, z);
95     glScalef (1.0f  / output->width,
96 	      -1.0f / output->height,
97 	      1.0f);
98     glTranslatef (-output->region.extents.x1,
99 		  -output->region.extents.y2,
100 		  0.0f);
101 }
102 
103 void
paintCursor(CompCursor * c,const CompTransform * transform,Region region,unsigned int mask)104 paintCursor (CompCursor		 *c,
105 	     const CompTransform *transform,
106 	     Region		 region,
107 	     unsigned int	 mask)
108 {
109     int x1, y1, x2, y2;
110 
111     if (!c->image)
112 	return;
113 
114     x1 = c->x;
115     y1 = c->y;
116     x2 = c->x + c->image->width;
117     y2 = c->y + c->image->height;
118 
119     glDisableClientState (GL_TEXTURE_COORD_ARRAY);
120     glEnable (GL_BLEND);
121 
122     enableTexture (c->screen, &c->image->texture, COMP_TEXTURE_FILTER_FAST);
123 
124     glBegin (GL_QUADS);
125 
126     glTexCoord2f (COMP_TEX_COORD_X (&c->matrix, x1),
127 		  COMP_TEX_COORD_Y (&c->matrix, y2));
128     glVertex2i (x1, y2);
129     glTexCoord2f (COMP_TEX_COORD_X (&c->matrix, x2),
130 		  COMP_TEX_COORD_Y (&c->matrix, y2));
131     glVertex2i (x2, y2);
132     glTexCoord2f (COMP_TEX_COORD_X (&c->matrix, x2),
133 		  COMP_TEX_COORD_Y (&c->matrix, y1));
134     glVertex2i (x2, y1);
135     glTexCoord2f (COMP_TEX_COORD_X (&c->matrix, x1),
136 		  COMP_TEX_COORD_Y (&c->matrix, y1));
137     glVertex2i (x1, y1);
138 
139     glEnd ();
140 
141     disableTexture (c->screen, &c->image->texture);
142 
143     glDisable (GL_BLEND);
144     glEnableClientState (GL_TEXTURE_COORD_ARRAY);
145 }
146 
147 static void
paintBackground(CompScreen * s,Region region,Bool transformed)148 paintBackground (CompScreen   *s,
149 		 Region	      region,
150 		 Bool	      transformed)
151 {
152     CompTexture *bg = &s->backgroundTexture;
153     BoxPtr      pBox = region->rects;
154     int	        n, nBox = region->numRects;
155     GLfloat     *d, *data;
156 
157     if (!nBox)
158 	return;
159 
160     if (s->desktopWindowCount)
161     {
162 	if (bg->name)
163 	{
164 	    finiTexture (s, bg);
165 	    initTexture (s, bg);
166 	}
167 
168 	s->backgroundLoaded = FALSE;
169 
170 	return;
171     }
172     else
173     {
174 	if (!s->backgroundLoaded)
175 	    updateScreenBackground (s, bg);
176 
177 	s->backgroundLoaded = TRUE;
178     }
179 
180     data = malloc (sizeof (GLfloat) * nBox * 16);
181     if (!data)
182 	return;
183 
184     d = data;
185     n = nBox;
186     while (n--)
187     {
188 	*d++ = COMP_TEX_COORD_X (&bg->matrix, pBox->x1);
189 	*d++ = COMP_TEX_COORD_Y (&bg->matrix, pBox->y2);
190 
191 	*d++ = pBox->x1;
192 	*d++ = pBox->y2;
193 
194 	*d++ = COMP_TEX_COORD_X (&bg->matrix, pBox->x2);
195 	*d++ = COMP_TEX_COORD_Y (&bg->matrix, pBox->y2);
196 
197 	*d++ = pBox->x2;
198 	*d++ = pBox->y2;
199 
200 	*d++ = COMP_TEX_COORD_X (&bg->matrix, pBox->x2);
201 	*d++ = COMP_TEX_COORD_Y (&bg->matrix, pBox->y1);
202 
203 	*d++ = pBox->x2;
204 	*d++ = pBox->y1;
205 
206 	*d++ = COMP_TEX_COORD_X (&bg->matrix, pBox->x1);
207 	*d++ = COMP_TEX_COORD_Y (&bg->matrix, pBox->y1);
208 
209 	*d++ = pBox->x1;
210 	*d++ = pBox->y1;
211 
212 	pBox++;
213     }
214 
215     glTexCoordPointer (2, GL_FLOAT, sizeof (GLfloat) * 4, data);
216     glVertexPointer (2, GL_FLOAT, sizeof (GLfloat) * 4, data + 2);
217 
218     if (bg->name)
219     {
220 	if (transformed)
221 	    enableTexture (s, bg, COMP_TEXTURE_FILTER_GOOD);
222 	else
223 	    enableTexture (s, bg, COMP_TEXTURE_FILTER_FAST);
224 
225 	glDrawArrays (GL_QUADS, 0, nBox * 4);
226 
227 	disableTexture (s, bg);
228     }
229     else
230     {
231 	glColor4us (0, 0, 0, 0);
232 	glDrawArrays (GL_QUADS, 0, nBox * 4);
233 	glColor4usv (defaultColor);
234     }
235 
236     free (data);
237 }
238 
239 
240 /* This function currently always performs occlusion detection to
241    minimize paint regions. OpenGL precision requirements are no good
242    enough to guarantee that the results from using occlusion detection
243    is the same as without. It's likely not possible to see any
244    difference with most hardware but occlusion detection in the
245    transformed screen case should be made optional for those who do
246    see a difference. */
247 static void
paintOutputRegion(CompScreen * screen,const CompTransform * transform,Region region,CompOutput * output,unsigned int mask)248 paintOutputRegion (CompScreen	       *screen,
249 		   const CompTransform *transform,
250 		   Region	       region,
251 		   CompOutput	       *output,
252 		   unsigned int	       mask)
253 {
254     static Region tmpRegion = NULL;
255     CompWindow    *w;
256     CompCursor	  *c;
257     int		  count, windowMask, odMask, i;
258     CompWindow	  *fullscreenWindow = NULL;
259     CompWalker    walk;
260     Bool          status;
261     Bool          withOffset = FALSE;
262     CompTransform vTransform;
263     int           offX, offY;
264     Region        clip = region;
265 
266     if (!tmpRegion)
267     {
268 	tmpRegion = XCreateRegion ();
269 	if (!tmpRegion)
270 	    return;
271     }
272 
273     if (mask & PAINT_SCREEN_TRANSFORMED_MASK)
274     {
275 	windowMask     = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
276 	count	       = 1;
277     }
278     else
279     {
280 	windowMask     = 0;
281 	count	       = 0;
282     }
283 
284     XSubtractRegion (region, &emptyRegion, tmpRegion);
285 
286     (*screen->initWindowWalker) (screen, &walk);
287 
288     if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
289     {
290 	/* detect occlusions */
291 	for (w = (*walk.last) (screen); w; w = (*walk.prev) (w))
292 	{
293 	    if (w->destroyed)
294 		continue;
295 
296 	    if (!w->shaded)
297 	    {
298 		if (w->attrib.map_state != IsViewable || !w->damaged)
299 		    continue;
300 	    }
301 
302 	    /* copy region */
303 	    XSubtractRegion (tmpRegion, &emptyRegion, w->clip);
304 
305 	    odMask = PAINT_WINDOW_OCCLUSION_DETECTION_MASK;
306 
307 	    if ((screen->windowOffsetX != 0 || screen->windowOffsetY != 0) &&
308 		!windowOnAllViewports (w))
309 	    {
310 		withOffset = TRUE;
311 
312 		getWindowMovementForOffset (w, screen->windowOffsetX,
313 					    screen->windowOffsetY,
314 					    &offX, &offY);
315 
316 		vTransform = *transform;
317 		matrixTranslate (&vTransform, offX, offY, 0);
318 
319 		XOffsetRegion (w->clip, -offX, -offY);
320 
321 		odMask |= PAINT_WINDOW_WITH_OFFSET_MASK;
322 		status = (*screen->paintWindow) (w, &w->paint, &vTransform,
323 						 tmpRegion, odMask);
324 	    }
325 	    else
326 	    {
327 		withOffset = FALSE;
328 		status = (*screen->paintWindow) (w, &w->paint, transform, tmpRegion,
329 						 odMask);
330 	    }
331 
332 	    if (status)
333 	    {
334 		if (withOffset)
335 		{
336 		    XOffsetRegion (w->region, offX, offY);
337 		    XSubtractRegion (tmpRegion, w->region, tmpRegion);
338 		    XOffsetRegion (w->region, -offX, -offY);
339 		}
340 		else
341 		    XSubtractRegion (tmpRegion, w->region, tmpRegion);
342 
343 		/* unredirect top most fullscreen windows. */
344 		if (count == 0 &&
345 		    screen->opt[COMP_SCREEN_OPTION_UNREDIRECT_FS].value.b)
346 		{
347 		    if (XEqualRegion (w->region, &screen->region) &&
348 			!REGION_NOT_EMPTY (tmpRegion))
349 		    {
350 			fullscreenWindow = w;
351 		    }
352 		    else
353 		    {
354 			for (i = 0; i < screen->nOutputDev; i++)
355 			    if (XEqualRegion (w->region,
356 					      &screen->outputDev[i].region))
357 				fullscreenWindow = w;
358 		    }
359 		}
360 	    }
361 
362 	    if (!w->invisible)
363 		count++;
364 	}
365     }
366 
367     if (fullscreenWindow)
368 	unredirectWindow (fullscreenWindow);
369 
370     if (!(mask & PAINT_SCREEN_NO_BACKGROUND_MASK))
371 	paintBackground (screen, tmpRegion,
372 			 (mask & PAINT_SCREEN_TRANSFORMED_MASK));
373 
374     /* paint all windows from bottom to top */
375     for (w = (*walk.first) (screen); w; w = (*walk.next) (w))
376     {
377 	if (w->destroyed)
378 	    continue;
379 
380 	if (w == fullscreenWindow)
381 	    continue;
382 
383 	if (!w->shaded)
384 	{
385 	    if (w->attrib.map_state != IsViewable || !w->damaged)
386 		continue;
387 	}
388 
389 	if (!(mask & PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK))
390 	    clip = w->clip;
391 
392 	if ((screen->windowOffsetX != 0 || screen->windowOffsetY != 0) &&
393 	    !windowOnAllViewports (w))
394 	{
395 	    getWindowMovementForOffset (w, screen->windowOffsetX,
396 					screen->windowOffsetY, &offX, &offY);
397 
398 	    vTransform = *transform;
399 	    matrixTranslate (&vTransform, offX, offY, 0);
400 	    (*screen->paintWindow) (w, &w->paint, &vTransform, clip,
401 				    windowMask | PAINT_WINDOW_WITH_OFFSET_MASK);
402 	}
403 	else
404 	{
405 	    (*screen->paintWindow) (w, &w->paint, transform, clip,
406 				    windowMask);
407 	}
408     }
409 
410     if (walk.fini)
411 	(*walk.fini) (screen, &walk);
412 
413     /* paint cursors */
414     for (c = screen->cursors; c; c = c->next)
415 	(*screen->paintCursor) (c, transform, tmpRegion, 0);
416 }
417 
418 void
enableOutputClipping(CompScreen * screen,const CompTransform * transform,Region region,CompOutput * output)419 enableOutputClipping (CompScreen	  *screen,
420 		      const CompTransform *transform,
421 		      Region		  region,
422 		      CompOutput	  *output)
423 {
424     GLdouble h = screen->height;
425 
426     GLdouble p1[2] = { region->extents.x1, h - region->extents.y2 };
427     GLdouble p2[2] = { region->extents.x2, h - region->extents.y1 };
428 
429     GLdouble halfW = output->width / 2.0;
430     GLdouble halfH = output->height / 2.0;
431 
432     GLdouble cx = output->region.extents.x1 + halfW;
433     GLdouble cy = (h - output->region.extents.y2) + halfH;
434 
435     GLdouble top[4]    = { 0.0, halfH / (cy - p1[1]), 0.0, 0.5 };
436     GLdouble bottom[4] = { 0.0, halfH / (cy - p2[1]), 0.0, 0.5 };
437     GLdouble left[4]   = { halfW / (cx - p1[0]), 0.0, 0.0, 0.5 };
438     GLdouble right[4]  = { halfW / (cx - p2[0]), 0.0, 0.0, 0.5 };
439 
440     glPushMatrix ();
441     glLoadMatrixf (transform->m);
442 
443     glClipPlane (GL_CLIP_PLANE0, top);
444     glClipPlane (GL_CLIP_PLANE1, bottom);
445     glClipPlane (GL_CLIP_PLANE2, left);
446     glClipPlane (GL_CLIP_PLANE3, right);
447 
448     glEnable (GL_CLIP_PLANE0);
449     glEnable (GL_CLIP_PLANE1);
450     glEnable (GL_CLIP_PLANE2);
451     glEnable (GL_CLIP_PLANE3);
452 
453     glPopMatrix ();
454 }
455 
456 void
disableOutputClipping(CompScreen * screen)457 disableOutputClipping (CompScreen *screen)
458 {
459     glDisable (GL_CLIP_PLANE0);
460     glDisable (GL_CLIP_PLANE1);
461     glDisable (GL_CLIP_PLANE2);
462     glDisable (GL_CLIP_PLANE3);
463 }
464 
465 #define CLIP_PLANE_MASK (PAINT_SCREEN_TRANSFORMED_MASK | \
466 			 PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK)
467 
468 void
paintTransformedOutput(CompScreen * screen,const ScreenPaintAttrib * sAttrib,const CompTransform * transform,Region region,CompOutput * output,unsigned int mask)469 paintTransformedOutput (CompScreen		*screen,
470 			const ScreenPaintAttrib *sAttrib,
471 			const CompTransform	*transform,
472 			Region			region,
473 			CompOutput		*output,
474 			unsigned int		mask)
475 {
476     CompTransform sTransform = *transform;
477 
478     if (mask & PAINT_SCREEN_CLEAR_MASK)
479 	clearTargetOutput (screen->display, GL_COLOR_BUFFER_BIT);
480 
481     screenLighting (screen, TRUE);
482 
483     (*screen->applyScreenTransform) (screen, sAttrib, output, &sTransform);
484 
485     if ((mask & CLIP_PLANE_MASK) == CLIP_PLANE_MASK)
486     {
487 	screen->enableOutputClipping (screen, &sTransform, region, output);
488 
489 	transformToScreenSpace (screen, output, -sAttrib->zTranslate,
490 				&sTransform);
491 
492 	glPushMatrix ();
493 	glLoadMatrixf (sTransform.m);
494 
495 	paintOutputRegion (screen, &sTransform, region, output, mask);
496 
497 	glPopMatrix ();
498 
499 	screen->disableOutputClipping (screen);
500     }
501     else
502     {
503 	transformToScreenSpace (screen, output, -sAttrib->zTranslate,
504 				&sTransform);
505 
506 	glPushMatrix ();
507 	glLoadMatrixf (sTransform.m);
508 
509 	paintOutputRegion (screen, &sTransform, region, output, mask);
510 
511 	glPopMatrix ();
512     }
513 }
514 
515 Bool
paintOutput(CompScreen * screen,const ScreenPaintAttrib * sAttrib,const CompTransform * transform,Region region,CompOutput * output,unsigned int mask)516 paintOutput (CompScreen		     *screen,
517 	     const ScreenPaintAttrib *sAttrib,
518 	     const CompTransform     *transform,
519 	     Region		     region,
520 	     CompOutput		     *output,
521 	     unsigned int	     mask)
522 {
523     CompTransform sTransform = *transform;
524 
525     if (mask & PAINT_SCREEN_REGION_MASK)
526     {
527 	if (mask & PAINT_SCREEN_TRANSFORMED_MASK)
528 	{
529 	    if (mask & PAINT_SCREEN_FULL_MASK)
530 	    {
531 		region = &output->region;
532 
533 		(*screen->paintTransformedOutput) (screen, sAttrib,
534 						   &sTransform, region,
535 						   output, mask);
536 
537 		return TRUE;
538 	    }
539 
540 	    return FALSE;
541 	}
542 
543 	/* fall through and redraw region */
544     }
545     else if (mask & PAINT_SCREEN_FULL_MASK)
546     {
547 	(*screen->paintTransformedOutput) (screen, sAttrib, &sTransform,
548 					   &output->region,
549 					   output, mask);
550 
551 	return TRUE;
552     }
553     else
554 	return FALSE;
555 
556     screenLighting (screen, FALSE);
557 
558     transformToScreenSpace (screen, output, -DEFAULT_Z_CAMERA, &sTransform);
559 
560     glPushMatrix ();
561     glLoadMatrixf (sTransform.m);
562 
563     paintOutputRegion (screen, &sTransform, region, output, mask);
564 
565     glPopMatrix ();
566 
567     return TRUE;
568 }
569 
570 #define ADD_RECT(data, m, n, x1, y1, x2, y2)	   \
571     for (it = 0; it < n; it++)			   \
572     {						   \
573 	*(data)++ = COMP_TEX_COORD_X (&m[it], x1); \
574 	*(data)++ = COMP_TEX_COORD_Y (&m[it], y1); \
575     }						   \
576     *(data)++ = (x1);				   \
577     *(data)++ = (y1);				   \
578     *(data)++ = 0.0;				   \
579     for (it = 0; it < n; it++)			   \
580     {						   \
581 	*(data)++ = COMP_TEX_COORD_X (&m[it], x1); \
582 	*(data)++ = COMP_TEX_COORD_Y (&m[it], y2); \
583     }						   \
584     *(data)++ = (x1);				   \
585     *(data)++ = (y2);				   \
586     *(data)++ = 0.0;				   \
587     for (it = 0; it < n; it++)			   \
588     {						   \
589 	*(data)++ = COMP_TEX_COORD_X (&m[it], x2); \
590 	*(data)++ = COMP_TEX_COORD_Y (&m[it], y2); \
591     }						   \
592     *(data)++ = (x2);				   \
593     *(data)++ = (y2);				   \
594     *(data)++ = 0.0;				   \
595     for (it = 0; it < n; it++)			   \
596     {						   \
597 	*(data)++ = COMP_TEX_COORD_X (&m[it], x2); \
598 	*(data)++ = COMP_TEX_COORD_Y (&m[it], y1); \
599     }						   \
600     *(data)++ = (x2);				   \
601     *(data)++ = (y1);				   \
602     *(data)++ = 0.0
603 
604 #define ADD_QUAD(data, m, n, x1, y1, x2, y2)		\
605     for (it = 0; it < n; it++)				\
606     {							\
607 	*(data)++ = COMP_TEX_COORD_XY (&m[it], x1, y1);	\
608 	*(data)++ = COMP_TEX_COORD_YX (&m[it], x1, y1);	\
609     }							\
610     *(data)++ = (x1);					\
611     *(data)++ = (y1);					\
612     *(data)++ = 0.0;					\
613     for (it = 0; it < n; it++)				\
614     {							\
615 	*(data)++ = COMP_TEX_COORD_XY (&m[it], x1, y2);	\
616 	*(data)++ = COMP_TEX_COORD_YX (&m[it], x1, y2);	\
617     }							\
618     *(data)++ = (x1);					\
619     *(data)++ = (y2);					\
620     *(data)++ = 0.0;					\
621     for (it = 0; it < n; it++)				\
622     {							\
623 	*(data)++ = COMP_TEX_COORD_XY (&m[it], x2, y2);	\
624 	*(data)++ = COMP_TEX_COORD_YX (&m[it], x2, y2);	\
625     }							\
626     *(data)++ = (x2);					\
627     *(data)++ = (y2);					\
628     *(data)++ = 0.0;					\
629     for (it = 0; it < n; it++)				\
630     {							\
631 	*(data)++ = COMP_TEX_COORD_XY (&m[it], x2, y1);	\
632 	*(data)++ = COMP_TEX_COORD_YX (&m[it], x2, y1);	\
633     }							\
634     *(data)++ = (x2);					\
635     *(data)++ = (y1);					\
636     *(data)++ = 0.0;
637 
638 
639 Bool
moreWindowVertices(CompWindow * w,int newSize)640 moreWindowVertices (CompWindow *w,
641 		    int        newSize)
642 {
643     if (newSize > w->vertexSize)
644     {
645 	GLfloat *vertices;
646 
647 	vertices = realloc (w->vertices, sizeof (GLfloat) * newSize);
648 	if (!vertices)
649 	    return FALSE;
650 
651 	w->vertices = vertices;
652 	w->vertexSize = newSize;
653     }
654 
655     return TRUE;
656 }
657 
658 Bool
moreWindowIndices(CompWindow * w,int newSize)659 moreWindowIndices (CompWindow *w,
660 		   int        newSize)
661 {
662     if (newSize > w->indexSize)
663     {
664 	GLushort *indices;
665 
666 	indices = realloc (w->indices, sizeof (GLushort) * newSize);
667 	if (!indices)
668 	    return FALSE;
669 
670 	w->indices = indices;
671 	w->indexSize = newSize;
672     }
673 
674     return TRUE;
675 }
676 
677 static void
drawWindowGeometry(CompWindow * w)678 drawWindowGeometry (CompWindow *w)
679 {
680     int     texUnit = w->texUnits;
681     int     currentTexUnit = 0;
682     int     stride = w->vertexStride;
683     GLfloat *vertices = w->vertices + (stride - 3);
684 
685     stride *= sizeof (GLfloat);
686 
687     glVertexPointer (3, GL_FLOAT, stride, vertices);
688 
689     while (texUnit--)
690     {
691 	if (texUnit != currentTexUnit)
692 	{
693 	    (*w->screen->clientActiveTexture) (GL_TEXTURE0_ARB + texUnit);
694 	    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
695 	    currentTexUnit = texUnit;
696 	}
697 	vertices -= w->texCoordSize;
698 	glTexCoordPointer (w->texCoordSize, GL_FLOAT, stride, vertices);
699     }
700 
701     glDrawArrays (GL_QUADS, 0, w->vCount);
702 
703     /* disable all texture coordinate arrays except 0 */
704     texUnit = w->texUnits;
705     if (texUnit > 1)
706     {
707 	while (--texUnit)
708 	{
709 	    (*w->screen->clientActiveTexture) (GL_TEXTURE0_ARB + texUnit);
710 	    glDisableClientState (GL_TEXTURE_COORD_ARRAY);
711 	}
712 
713 	(*w->screen->clientActiveTexture) (GL_TEXTURE0_ARB);
714     }
715 }
716 
717 void
addWindowGeometry(CompWindow * w,CompMatrix * matrix,int nMatrix,Region region,Region clip)718 addWindowGeometry (CompWindow *w,
719 		   CompMatrix *matrix,
720 		   int	      nMatrix,
721 		   Region     region,
722 		   Region     clip)
723 {
724     BoxRec full;
725 
726     w->texUnits = nMatrix;
727 
728     full = clip->extents;
729     if (region->extents.x1 > full.x1)
730 	full.x1 = region->extents.x1;
731     if (region->extents.y1 > full.y1)
732 	full.y1 = region->extents.y1;
733     if (region->extents.x2 < full.x2)
734 	full.x2 = region->extents.x2;
735     if (region->extents.y2 < full.y2)
736 	full.y2 = region->extents.y2;
737 
738     if (full.x1 < full.x2 && full.y1 < full.y2)
739     {
740 	BoxPtr  pBox;
741 	int     nBox;
742 	BoxPtr  pClip;
743 	int     nClip;
744 	BoxRec  cbox;
745 	int     vSize;
746 	int     n, it, x1, y1, x2, y2;
747 	GLfloat *d;
748 	Bool    rect = TRUE;
749 
750 	for (it = 0; it < nMatrix; it++)
751 	{
752 	    if (matrix[it].xy != 0.0f || matrix[it].yx != 0.0f)
753 	    {
754 		rect = FALSE;
755 		break;
756 	    }
757 	}
758 
759 	pBox = region->rects;
760 	nBox = region->numRects;
761 
762 	vSize = 3 + nMatrix * 2;
763 
764 	n = w->vCount / 4;
765 
766 	if ((n + nBox) * vSize * 4 > w->vertexSize)
767 	{
768 	    if (!moreWindowVertices (w, (n + nBox) * vSize * 4))
769 		return;
770 	}
771 
772 	d = w->vertices + (w->vCount * vSize);
773 
774 	while (nBox--)
775 	{
776 	    x1 = pBox->x1;
777 	    y1 = pBox->y1;
778 	    x2 = pBox->x2;
779 	    y2 = pBox->y2;
780 
781 	    pBox++;
782 
783 	    if (x1 < full.x1)
784 		x1 = full.x1;
785 	    if (y1 < full.y1)
786 		y1 = full.y1;
787 	    if (x2 > full.x2)
788 		x2 = full.x2;
789 	    if (y2 > full.y2)
790 		y2 = full.y2;
791 
792 	    if (x1 < x2 && y1 < y2)
793 	    {
794 		nClip = clip->numRects;
795 
796 		if (nClip == 1)
797 		{
798 		    if (rect)
799 		    {
800 			ADD_RECT (d, matrix, nMatrix, x1, y1, x2, y2);
801 		    }
802 		    else
803 		    {
804 			ADD_QUAD (d, matrix, nMatrix, x1, y1, x2, y2);
805 		    }
806 
807 		    n++;
808 		}
809 		else
810 		{
811 		    pClip = clip->rects;
812 
813 		    if (((n + nClip) * vSize * 4) > w->vertexSize)
814 		    {
815 			if (!moreWindowVertices (w, (n + nClip) * vSize * 4))
816 			    return;
817 
818 			d = w->vertices + (n * vSize * 4);
819 		    }
820 
821 		    while (nClip--)
822 		    {
823 			cbox = *pClip;
824 
825 			pClip++;
826 
827 			if (cbox.x1 < x1)
828 			    cbox.x1 = x1;
829 			if (cbox.y1 < y1)
830 			    cbox.y1 = y1;
831 			if (cbox.x2 > x2)
832 			    cbox.x2 = x2;
833 			if (cbox.y2 > y2)
834 			    cbox.y2 = y2;
835 
836 			if (cbox.x1 < cbox.x2 && cbox.y1 < cbox.y2)
837 			{
838 			    if (rect)
839 			    {
840 				ADD_RECT (d, matrix, nMatrix,
841 					  cbox.x1, cbox.y1, cbox.x2, cbox.y2);
842 			    }
843 			    else
844 			    {
845 				ADD_QUAD (d, matrix, nMatrix,
846 					  cbox.x1, cbox.y1, cbox.x2, cbox.y2);
847 			    }
848 
849 			    n++;
850 			}
851 		    }
852 		}
853 	    }
854 	}
855 
856 	w->vCount	      = n * 4;
857 	w->vertexStride       = vSize;
858 	w->texCoordSize       = 2;
859 	w->drawWindowGeometry = drawWindowGeometry;
860     }
861 }
862 
863 static Bool
enableFragmentProgramAndDrawGeometry(CompWindow * w,CompTexture * texture,const FragmentAttrib * attrib,int filter,unsigned int mask)864 enableFragmentProgramAndDrawGeometry (CompWindow	   *w,
865 				      CompTexture	   *texture,
866 				      const FragmentAttrib *attrib,
867 				      int		   filter,
868 				      unsigned int	   mask)
869 {
870     FragmentAttrib fa = *attrib;
871     CompScreen     *s = w->screen;
872     Bool	   blending;
873 
874     if (s->canDoSaturated && attrib->saturation != COLOR)
875     {
876 	int param, function;
877 
878 	param    = allocFragmentParameters (&fa, 1);
879 	function = getSaturateFragmentFunction (s, texture, param);
880 
881 	addFragmentFunction (&fa, function);
882 
883 	(*s->programEnvParameter4f) (GL_FRAGMENT_PROGRAM_ARB, param,
884 				     RED_SATURATION_WEIGHT,
885 				     GREEN_SATURATION_WEIGHT,
886 				     BLUE_SATURATION_WEIGHT,
887 				     attrib->saturation / 65535.0f);
888     }
889 
890     if (!enableFragmentAttrib (s, &fa, &blending))
891 	return FALSE;
892 
893     enableTexture (s, texture, filter);
894 
895     if (mask & PAINT_WINDOW_BLEND_MASK)
896     {
897 	if (blending)
898 	    glEnable (GL_BLEND);
899 
900 	if (attrib->opacity != OPAQUE || attrib->brightness != BRIGHT)
901 	{
902 	    GLushort color;
903 
904 	    color = (attrib->opacity * attrib->brightness) >> 16;
905 
906 	    screenTexEnvMode (s, GL_MODULATE);
907 	    glColor4us (color, color, color, attrib->opacity);
908 
909 	    (*w->drawWindowGeometry) (w);
910 
911 	    glColor4usv (defaultColor);
912 	    screenTexEnvMode (s, GL_REPLACE);
913 	}
914 	else
915 	{
916 	    (*w->drawWindowGeometry) (w);
917 	}
918 
919 	if (blending)
920 	    glDisable (GL_BLEND);
921     }
922     else if (attrib->brightness != BRIGHT)
923     {
924 	screenTexEnvMode (s, GL_MODULATE);
925 	glColor4us (attrib->brightness, attrib->brightness,
926 		    attrib->brightness, BRIGHT);
927 
928 	(*w->drawWindowGeometry) (w);
929 
930 	glColor4usv (defaultColor);
931 	screenTexEnvMode (s, GL_REPLACE);
932     }
933     else
934     {
935 	(*w->drawWindowGeometry) (w);
936     }
937 
938     disableTexture (w->screen, texture);
939 
940     disableFragmentAttrib (s, &fa);
941 
942     return TRUE;
943 }
944 
945 static void
enableFragmentOperationsAndDrawGeometry(CompWindow * w,CompTexture * texture,const FragmentAttrib * attrib,int filter,unsigned int mask)946 enableFragmentOperationsAndDrawGeometry (CompWindow	      *w,
947 					 CompTexture	      *texture,
948 					 const FragmentAttrib *attrib,
949 					 int		      filter,
950 					 unsigned int	      mask)
951 {
952     CompScreen *s = w->screen;
953 
954     if (s->canDoSaturated && attrib->saturation != COLOR)
955     {
956 	GLfloat constant[4];
957 
958 	if (mask & PAINT_WINDOW_BLEND_MASK)
959 	    glEnable (GL_BLEND);
960 
961 	enableTexture (s, texture, filter);
962 
963 	glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
964 
965 	glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
966 	glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
967 	glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
968 	glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR);
969 	glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
970 	glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
971 	glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
972 
973 	glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
974 	glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
975 	glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
976 
977 	glColor4f (1.0f, 1.0f, 1.0f, 0.5f);
978 
979 	s->activeTexture (GL_TEXTURE1_ARB);
980 
981 	enableTexture (s, texture, filter);
982 
983 	glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
984 
985 	glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB);
986 	glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
987 	glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
988 	glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
989 	glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
990 
991 	if (s->canDoSlightlySaturated && attrib->saturation > 0)
992 	{
993 	    glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
994 	    glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
995 	    glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
996 
997 	    constant[0] = 0.5f + 0.5f * RED_SATURATION_WEIGHT;
998 	    constant[1] = 0.5f + 0.5f * GREEN_SATURATION_WEIGHT;
999 	    constant[2] = 0.5f + 0.5f * BLUE_SATURATION_WEIGHT;
1000 	    constant[3] = 1.0;
1001 
1002 	    glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
1003 
1004 	    s->activeTexture (GL_TEXTURE2_ARB);
1005 
1006 	    enableTexture (s, texture, filter);
1007 
1008 	    glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1009 
1010 	    glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
1011 	    glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
1012 	    glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
1013 	    glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_CONSTANT);
1014 	    glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1015 	    glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
1016 	    glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
1017 
1018 	    glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
1019 	    glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
1020 	    glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1021 
1022 	    constant[3] = attrib->saturation / 65535.0f;
1023 
1024 	    glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
1025 
1026 	    if (attrib->opacity < OPAQUE || attrib->brightness != BRIGHT)
1027 	    {
1028 		s->activeTexture (GL_TEXTURE3_ARB);
1029 
1030 		enableTexture (s, texture, filter);
1031 
1032 		constant[3] = attrib->opacity / 65535.0f;
1033 		constant[0] = constant[1] = constant[2] = constant[3] *
1034 		    attrib->brightness / 65535.0f;
1035 
1036 		glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
1037 
1038 		glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1039 
1040 		glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
1041 		glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS);
1042 		glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT);
1043 		glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1044 		glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
1045 
1046 		glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
1047 		glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
1048 		glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_CONSTANT);
1049 		glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1050 		glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
1051 
1052 		(*w->drawWindowGeometry) (w);
1053 
1054 		disableTexture (s, texture);
1055 
1056 		glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1057 
1058 		s->activeTexture (GL_TEXTURE2_ARB);
1059 	    }
1060 	    else
1061 	    {
1062 		(*w->drawWindowGeometry) (w);
1063 	    }
1064 
1065 	    disableTexture (s, texture);
1066 
1067 	    glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1068 
1069 	    s->activeTexture (GL_TEXTURE1_ARB);
1070 	}
1071 	else
1072 	{
1073 	    glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
1074 	    glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
1075 	    glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_CONSTANT);
1076 	    glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1077 	    glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
1078 
1079 	    constant[3] = attrib->opacity / 65535.0f;
1080 	    constant[0] = constant[1] = constant[2] = constant[3] *
1081 		attrib->brightness / 65535.0f;
1082 
1083 	    constant[0] = 0.5f + 0.5f * RED_SATURATION_WEIGHT   * constant[0];
1084 	    constant[1] = 0.5f + 0.5f * GREEN_SATURATION_WEIGHT * constant[1];
1085 	    constant[2] = 0.5f + 0.5f * BLUE_SATURATION_WEIGHT  * constant[2];
1086 
1087 	    glTexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant);
1088 
1089 	    (*w->drawWindowGeometry) (w);
1090 	}
1091 
1092 	disableTexture (s, texture);
1093 
1094 	glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
1095 
1096 	s->activeTexture (GL_TEXTURE0_ARB);
1097 
1098 	disableTexture (s, texture);
1099 
1100 	glColor4usv (defaultColor);
1101 	screenTexEnvMode (s, GL_REPLACE);
1102 
1103 	if (mask & PAINT_WINDOW_BLEND_MASK)
1104 	    glDisable (GL_BLEND);
1105     }
1106     else
1107     {
1108 	enableTexture (s, texture, filter);
1109 
1110 	if (mask & PAINT_WINDOW_BLEND_MASK)
1111 	{
1112 	    glEnable (GL_BLEND);
1113 	    if (attrib->opacity != OPAQUE || attrib->brightness != BRIGHT)
1114 	    {
1115 		GLushort color;
1116 
1117 		color = (attrib->opacity * attrib->brightness) >> 16;
1118 
1119 		screenTexEnvMode (s, GL_MODULATE);
1120 		glColor4us (color, color, color, attrib->opacity);
1121 
1122 		(*w->drawWindowGeometry) (w);
1123 
1124 		glColor4usv (defaultColor);
1125 		screenTexEnvMode (s, GL_REPLACE);
1126 	    }
1127 	    else
1128 	    {
1129 		(*w->drawWindowGeometry) (w);
1130 	    }
1131 
1132 	    glDisable (GL_BLEND);
1133 	}
1134 	else if (attrib->brightness != BRIGHT)
1135 	{
1136 	    screenTexEnvMode (s, GL_MODULATE);
1137 	    glColor4us (attrib->brightness, attrib->brightness,
1138 			attrib->brightness, BRIGHT);
1139 
1140 	    (*w->drawWindowGeometry) (w);
1141 
1142 	    glColor4usv (defaultColor);
1143 	    screenTexEnvMode (s, GL_REPLACE);
1144 	}
1145 	else
1146 	{
1147 	    (*w->drawWindowGeometry) (w);
1148 	}
1149 
1150 	disableTexture (w->screen, texture);
1151     }
1152 }
1153 
1154 void
drawWindowTexture(CompWindow * w,CompTexture * texture,const FragmentAttrib * attrib,unsigned int mask)1155 drawWindowTexture (CompWindow		*w,
1156 		   CompTexture		*texture,
1157 		   const FragmentAttrib	*attrib,
1158 		   unsigned int		mask)
1159 {
1160     int filter;
1161 
1162     if (mask & (PAINT_WINDOW_TRANSFORMED_MASK |
1163 		PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK))
1164 	filter = w->screen->filter[SCREEN_TRANS_FILTER];
1165     else
1166 	filter = w->screen->filter[NOTHING_TRANS_FILTER];
1167 
1168     if ((!attrib->nFunction && (!w->screen->lighting ||
1169 	 attrib->saturation == COLOR || attrib->saturation == 0)) ||
1170 	!enableFragmentProgramAndDrawGeometry (w,
1171 					       texture,
1172 					       attrib,
1173 					       filter,
1174 					       mask))
1175     {
1176 	enableFragmentOperationsAndDrawGeometry (w,
1177 						 texture,
1178 						 attrib,
1179 						 filter,
1180 						 mask);
1181     }
1182 }
1183 
1184 Bool
drawWindow(CompWindow * w,const CompTransform * transform,const FragmentAttrib * fragment,Region region,unsigned int mask)1185 drawWindow (CompWindow		 *w,
1186 	    const CompTransform  *transform,
1187 	    const FragmentAttrib *fragment,
1188 	    Region		 region,
1189 	    unsigned int	 mask)
1190 {
1191     if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
1192 	region = &infiniteRegion;
1193 
1194     if (!region->numRects)
1195 	return TRUE;
1196 
1197     if (w->attrib.map_state != IsViewable)
1198 	return TRUE;
1199 
1200     if (!w->texture->pixmap && !bindWindow (w))
1201 	return FALSE;
1202 
1203     if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
1204 	mask |= PAINT_WINDOW_BLEND_MASK;
1205 
1206     w->vCount = w->indexCount = 0;
1207     (*w->screen->addWindowGeometry) (w, &w->matrix, 1, w->region, region);
1208     if (w->vCount)
1209 	(*w->screen->drawWindowTexture) (w, w->texture, fragment, mask);
1210 
1211     return TRUE;
1212 }
1213 
1214 Bool
paintWindow(CompWindow * w,const WindowPaintAttrib * attrib,const CompTransform * transform,Region region,unsigned int mask)1215 paintWindow (CompWindow		     *w,
1216 	     const WindowPaintAttrib *attrib,
1217 	     const CompTransform     *transform,
1218 	     Region		     region,
1219 	     unsigned int	     mask)
1220 {
1221     FragmentAttrib fragment;
1222     Bool	   status;
1223 
1224     w->lastPaint = *attrib;
1225 
1226     if (w->alpha || attrib->opacity != OPAQUE)
1227 	mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
1228 
1229     w->lastMask = mask;
1230 
1231     if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
1232     {
1233 	if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
1234 	    return FALSE;
1235 
1236 	if (mask & PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
1237 	    return FALSE;
1238 
1239 	if (mask & PAINT_WINDOW_TRANSLUCENT_MASK)
1240 	    return FALSE;
1241 
1242 	if (w->shaded)
1243 	    return FALSE;
1244 
1245 	return TRUE;
1246     }
1247 
1248     if (mask & PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
1249 	return TRUE;
1250 
1251     initFragmentAttrib (&fragment, attrib);
1252 
1253     if (mask & PAINT_WINDOW_TRANSFORMED_MASK ||
1254         mask & PAINT_WINDOW_WITH_OFFSET_MASK)
1255     {
1256 	glPushMatrix ();
1257 	glLoadMatrixf (transform->m);
1258     }
1259 
1260     status = (*w->screen->drawWindow) (w, transform, &fragment, region, mask);
1261 
1262     if (mask & PAINT_WINDOW_TRANSFORMED_MASK ||
1263         mask & PAINT_WINDOW_WITH_OFFSET_MASK)
1264 	glPopMatrix ();
1265 
1266     return status;
1267 }
1268