1 #include "3d.h"
  2 
  3 COMPIZ_PLUGIN_20090315 (td, TdPluginVTable);
  4 
  5 const double PI = 3.14159265359f;
  6 
  7 void
  8 setFunctions (bool enabled)
  9 {
 10     TD_SCREEN (screen);
 11 
 12     tds->gScreen->glPaintOutputSetEnabled (tds, enabled);
 13     tds->gScreen->glApplyTransformSetEnabled (tds, enabled);
 14     tds->cScreen->donePaintSetEnabled (tds, enabled);
 15     tds->cubeScreen->cubePaintViewportSetEnabled (tds, enabled);
 16     tds->cubeScreen->cubeShouldPaintViewportSetEnabled (tds, enabled);
 17     tds->cubeScreen->cubeShouldPaintAllViewportsSetEnabled (tds, enabled);
 18 
 19     foreach (CompWindow *w, screen->windows ())
 20     {
 21 	TD_WINDOW (w);
 22 
 23 	tdw->gWindow->glPaintSetEnabled (tdw, enabled);
 24     }
 25 }
 26 
 27 bool
 28 TdWindow::is3D ()
 29 {
 30     if (window->overrideRedirect ())
 31 	return false;
 32 
 33     if (!window->isViewable () || window->shaded ())
 34 	return false;
 35 
 36     if (window->state () & (CompWindowStateSkipPagerMask |
 37 		    CompWindowStateSkipTaskbarMask))
 38 	return false;
 39 
 40     if (!TdScreen::get (screen)->optionGetWindowMatch ().evaluate (window))
 41 	return false;
 42 
 43     return true;
 44 }
 45 
 46 void
 47 TdScreen::preparePaint (int msSinceLastPaint)
 48 {
 49     bool       active;
 50 
 51     CUBE_SCREEN (screen);
 52 
 53     active = (cs->rotationState () != CubeScreen::RotationNone) && screen->vpSize ().width () > 2 &&
 54 	     !(optionGetManualOnly () && (cs->rotationState () != CubeScreen::RotationManual));
 55 
 56     if (active || mBasicScale != 1.0)
 57     {
 58 	float maxDiv = (float) optionGetMaxWindowSpace () / 100;
 59 	float minScale = (float) optionGetMinCubeSize () / 100;
 60 	float x, progress;
 61 
 62 	cs->cubeGetRotation (x, x, progress);
 63 
 64 	mMaxDepth = 0;
 65 	foreach (CompWindow *w, screen->windows ())
 66 	{
 67 	    TD_WINDOW (w);
 68 	    tdw->mIs3D = false;
 69 	    tdw->mDepth = 0;
 70 
 71 	    if (!tdw->is3D ())
 72 		continue;
 73 
 74 	    tdw->mIs3D = true;
 75 	    mMaxDepth++;
 76 	    tdw->mDepth = mMaxDepth;
 77 
 78 	}
 79 
 80 	minScale =  MAX (minScale, 1.0 - (mMaxDepth * maxDiv));
 81 	mBasicScale = 1.0 - ((1.0 - minScale) * progress);
 82 	mDamage = (progress != 0.0 && progress != 1.0);
 83     }
 84     else
 85     {
 86 	mBasicScale = 1.0;
 87     }
 88 
 89     /* comparing float values with != is error prone, so better cache
 90        the comparison and allow a small difference */
 91     mActive       = (fabs (mBasicScale - 1.0f) > 1e-4);
 92     mCurrentScale = mBasicScale;
 93 
 94     cScreen->preparePaint (msSinceLastPaint);
 95 
 96     setFunctions (mActive);
 97 }
 98 
 99 #define DOBEVEL(corner) (tds->optionGetBevel##corner () ? bevel : 0)
100 
101 #define SET_V								       \
102     for (int i = 0; i < 4; i++)						       \
103 	v[i] = tPoint[i];
104 
105 #define ADDQUAD(x1,y1,x2,y2)                                      \
106 	point[GLVector::x] = x1; point[GLVector::y] = y1;                               \
107 	tPoint = transform * point;       \
108 	SET_V \
109 	glVertex4fv (v);                                  \
110 	point[GLVector::x] = x2; point[GLVector::y] = y2;                               \
111 	tPoint = transform * point;        \
112 	SET_V \
113 	glVertex4fv (v);                                   \
114 	tPoint = tds->mBTransform * point; \
115 	SET_V \
116 	glVertex4fv (v);                                \
117 	point[GLVector::x] = x1; point[GLVector::y] = y1;                               \
118 	tPoint = tds->mBTransform * point; \
119 	SET_V \
120 	glVertex4fv (v);                                   \
121 
122 #define ADDBEVELQUAD(x1,y1,x2,y2,m1,m2)             \
123 	point[GLVector::x] = x1; point[GLVector::y] = y1;                 \
124 	tPoint = m1 * point; \
125 	SET_V \
126 	glVertex4fv (v);                     \
127 	tPoint = m2 * point; \
128 	SET_V \
129 	glVertex4fv (v);                     \
130 	point[GLVector::x] = x2; point[GLVector::y] = y2;                 \
131 	tPoint = m2 * point; \
132 	SET_V \
133 	glVertex4fv (v);                     \
134 	tPoint = m1 * point; \
135 	SET_V \
136 	glVertex4fv (v);                     \
137 
138 bool
139 TdWindow::glPaintWithDepth (const GLWindowPaintAttrib &attrib,
140 			    const GLMatrix	      &transform,
141 			    const CompRegion	      &region,
142 			    unsigned int	      mask)
143 {
144     bool status;
145     int            wx, wy, ww, wh;
146     int            bevel, cull, cullInv;
147     GLVector       point, tPoint;
148     unsigned short *c;
149 
150     TD_SCREEN (screen);
151     CUBE_SCREEN (screen);
152 
153     glIsEnabled (GL_CULL_FACE);
154 
155     wx = window->x () - window->input ().left;
156     wy = window->y () - window->input ().top;
157 
158     ww = window->width () + window->input ().left + window->input ().right;
159     wh = window->height () + window->input ().top + window->input ().bottom;
160 
161     bevel = tds->optionGetBevel ();
162 
163     glGetIntegerv (GL_CULL_FACE_MODE, &cull);
164     cullInv = (cull == GL_BACK)? GL_FRONT : GL_BACK;
165 
166     if (ww && wh && !(mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK) &&
167 	((cs->paintOrder () == FTB && mFtb) ||
168 	(cs->paintOrder () == BTF && !mFtb)))
169     {
170         float v[4];
171 	int   temp;
172 
173 	/* Paint window depth. */
174 	glPushMatrix ();
175 	glLoadIdentity ();
176 
177 	if (cs->paintOrder () == BTF)
178 	    glCullFace (cullInv);
179 
180 	glEnable (GL_BLEND);
181 	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
182 
183 	if (window->id () == screen->activeWindow ())
184 	    c = tds->optionGetWidthColor ();
185 	else
186 	    c = tds->optionGetWidthColorInactive ();
187 
188 	temp = c[3] * gWindow->paintAttrib ().opacity;
189 	temp /= 0xffff;
190 	glColor4us (c[0], c[1], c[2], temp);
191 
192 	point[GLVector::z] = 0.0f;
193 	point[GLVector::w] = 1.0f;
194 
195 	glBegin (GL_QUADS);
196 
197 	/* Top */
198 	ADDQUAD (wx + ww - DOBEVEL (Topleft), wy + 0.01,
199 		 wx + DOBEVEL (Topright), wy + 0.01);
200 
201 	/* Bottom */
202 	ADDQUAD (wx + DOBEVEL (Bottomleft), wy + wh - 0.01,
203 		 wx + ww - DOBEVEL (Bottomright), wy + wh - 0.01);
204 
205 	/* Left */
206 	ADDQUAD (wx + 0.01, wy + DOBEVEL (Topleft),
207 		 wx + 0.01, wy + wh - DOBEVEL (Bottomleft));
208 
209 	/* Right */
210 	ADDQUAD (wx + ww - 0.01, wy + wh - DOBEVEL (Topright),
211 		 wx + ww - 0.01, wy + DOBEVEL (Bottomright));
212 
213 	/* Top left bevel */
214 	if (tds->optionGetBevelTopleft ())
215 	{
216 	    ADDBEVELQUAD (wx + bevel / 2.0f,
217 			  wy + bevel - bevel / 1.2f,
218 			  wx, wy + bevel,
219 			  tds->mBTransform, transform);
220 
221 	    ADDBEVELQUAD (wx + bevel / 2.0f,
222 			  wy + bevel - bevel / 1.2f,
223 			  wx + bevel, wy,
224 			  transform, tds->mBTransform);
225 
226 	}
227 
228 	/* Bottom left bevel */
229 	if (tds->optionGetBevelBottomleft ())
230 	{
231 	    ADDBEVELQUAD (wx + bevel / 2.0f,
232 			  wy + wh - bevel + bevel / 1.2f,
233 			  wx, wy + wh - bevel,
234 			  transform, tds->mBTransform);
235 
236 	    ADDBEVELQUAD (wx + bevel / 2.0f,
237 			  wy + wh - bevel + bevel / 1.2f,
238 			  wx + bevel, wy + wh,
239 			  tds->mBTransform, transform);
240 	}
241 
242 	/* Bottom right bevel */
243 	if (tds->optionGetBevelBottomright ())
244 	{
245 	    ADDBEVELQUAD (wx + ww - bevel / 2.0f,
246 			  wy + wh - bevel + bevel / 1.2f,
247 			  wx + ww - bevel, wy + wh,
248 			  transform, tds->mBTransform);
249 
250 	    ADDBEVELQUAD (wx + ww - bevel / 2.0f,
251 			  wy + wh - bevel + bevel / 1.2f,
252 			  wx + ww, wy + wh - bevel,
253 			  tds->mBTransform, transform);
254 
255 
256 	}
257 
258 	/* Top right bevel */
259 	if (tds->optionGetBevelTopright ())
260 	{
261 	    ADDBEVELQUAD (wx + ww - bevel, wy,
262 			  wx + ww - bevel / 2.0f,
263 			  wy + bevel - bevel / 1.2f,
264 			  transform, tds->mBTransform);
265 
266 	    ADDBEVELQUAD (wx + ww, wy + bevel,
267 			  wx + ww - bevel / 2.0f,
268 			  wy + bevel - bevel / 1.2f,
269 			  tds->mBTransform, transform);
270 	}
271 	glEnd ();
272 
273 	glColor4usv (defaultColor);
274 	glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
275 	glPopMatrix ();
276 
277 	if (cs->paintOrder () == BTF)
278 	    glCullFace (cull);
279     }
280 
281     if (cs->paintOrder () == BTF)
282 	status = gWindow->glPaint (attrib, transform, region, mask);
283     else
284 	status = gWindow->glPaint (attrib, tds->mBTransform, region,
285 				   mask | PAINT_WINDOW_TRANSFORMED_MASK);
286 
287     return status;
288 }
289 
290 bool
291 TdWindow::glPaint (const GLWindowPaintAttrib &attrib,
292 		   const GLMatrix	     &transform,
293 		   const CompRegion	     &region,
294 		   unsigned int		     mask)
295 {
296     bool           status;
297 
298     TD_SCREEN (screen);
299 
300     if (mDepth != 0.0f && !tds->mPainting3D && tds->mActive)
301 	mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
302 
303     if (tds->mPainting3D && tds->optionGetWidth () && (mDepth != 0.0f) &&
304 	tds->mWithDepth)
305     {
306 	status = glPaintWithDepth (attrib, transform, region, mask);
307     }
308     else
309     {
310 	status = gWindow->glPaint (attrib, transform, region, mask);
311     }
312 
313     return status;
314 }
315 
316 void
317 TdScreen::glApplyTransform (const GLScreenPaintAttrib &attrib,
318 			    CompOutput *output,
319 			    GLMatrix *transform)
320 {
321 
322     gScreen->glApplyTransform (attrib, output, transform);
323 
324     transform->scale (mCurrentScale, mCurrentScale, mCurrentScale);
325 }
326 
327 
328 void
329 TdScreen::cubePaintViewport (const GLScreenPaintAttrib &attrib,
330 			     const GLMatrix	       &transform,
331 			     const CompRegion	       &region,
332 			     CompOutput		       *output,
333 			     unsigned int	       mask)
334 {
335     CUBE_SCREEN (screen);
336 
337     if (cs->paintOrder () == BTF)
338     {
339         cs->cubePaintViewport (attrib, transform,region, output, mask);
340     }
341 
342     if (mActive)
343     {
344 	GLMatrix      mTransform; // NOT a member variable
345 	GLMatrix      screenSpace;
346 	GLMatrix      screenSpaceOffset;
347 	TdWindow      *tdw;
348 	CompWindowList                   pl;
349 	CompWindowList::iterator it;
350 	float         wDepth = 0.0;
351 	float         pointZ = cs->invert () * cs->distance ();
352 	unsigned int  newMask;
353 
354 	std::vector<GLVector> vPoints;
355 	vPoints.push_back (GLVector (-0.5, 0.0, pointZ, 1.0));
356 	vPoints.push_back (GLVector (0.0, 0.5, pointZ, 1.0));
357 	vPoints.push_back (GLVector (0.0, 0.0, pointZ, 1.0));
358 
359 	if (mWithDepth)
360 	    wDepth = -MIN((optionGetWidth ()) / 30, (1.0 - mBasicScale) /
361 			  mMaxDepth);
362 
363 	if (wDepth != 0.0)
364 	{
365 	    /* all BTF windows in normal order */
366 	    foreach (CompWindow *w, screen->windows ())
367 	    {
368 		tdw = TdWindow::get (w);
369 
370 		if (!tdw->mIs3D)
371 		    continue;
372 
373 		mCurrentScale = mBasicScale +
374 		                    (tdw->mDepth * ((1.0 - mBasicScale) /
375 				    mMaxDepth));
376 
377 		tdw->mFtb = cs->cubeCheckOrientation (attrib, transform, output,
378 						  vPoints);
379 	    }
380 	}
381 
382 	mCurrentScale = mBasicScale;
383 	mPainting3D   = true;
384 
385 	gScreen->setLighting (true);
386 
387 	screenSpace.reset ();
388 	screenSpace.toScreenSpace (output, -attrib.zTranslate);
389 
390 	glPushMatrix ();
391 
392 	pl = cScreen->getWindowPaintList ();
393 
394 	/* paint all windows from bottom to top */
395 	for (it = pl.begin (); it != pl.end (); ++it)
396 	{
397 	    CompWindow *w = (*it);
398 	    tdw = TdWindow::get (w);
399 
400 	    if (w->destroyed ())
401 		continue;
402 
403 	    if (!w->shaded () || !w->isViewable ())
404 	    {
405 		if (!tdw->cWindow->damaged ())
406 		    continue;
407 	    }
408 
409 	    mTransform = transform;
410 	    newMask = PAINT_WINDOW_ON_TRANSFORMED_SCREEN_MASK;
411 
412 	    if (tdw->mDepth != 0.0f)
413 	    {
414 		mCurrentScale = mBasicScale +
415 		                    (tdw->mDepth * ((1.0 - mBasicScale) /
416 						   mMaxDepth));
417 
418 		if (wDepth != 0.0)
419 		{
420 		    mCurrentScale += wDepth;
421 		    mBTransform   = transform;
422 		    gScreen->glApplyTransform (attrib, output, &mBTransform);
423 		    mCurrentScale -= wDepth;
424 		}
425 
426 		gScreen->glApplyTransform (attrib, output, &mTransform);
427 
428 		gScreen->glEnableOutputClipping (mTransform, region, output);
429 
430 		if ((cScreen->windowPaintOffset ().x () != 0 ||
431 		     cScreen->windowPaintOffset ().y () != 0) &&
432 		    !w->onAllViewports ())
433 		{
434 		    CompPoint moveOffset;
435 		    moveOffset = w->getMovementForOffset (
436 		    			cScreen->windowPaintOffset ());
437 
438 		    screenSpaceOffset = screenSpace;
439 		    screenSpaceOffset.translate (moveOffset.x (),
440 		    				 moveOffset.y (), 0);
441 
442 		    if (wDepth != 0.0)
443 		        mBTransform = mBTransform * screenSpaceOffset;
444 		    mTransform = mTransform * screenSpaceOffset;
445 
446 		    newMask |= PAINT_WINDOW_WITH_OFFSET_MASK;
447 		}
448 		else
449 		{
450 		    if (wDepth != 0.0)
451 			mBTransform = mBTransform * screenSpace;
452 		    mTransform = mTransform * screenSpace;
453 		}
454 
455 		glLoadMatrixf (mTransform.getMatrix ());
456 
457 		tdw->gWindow->glPaint (tdw->gWindow->paintAttrib (), mTransform,
458 				  infiniteRegion, newMask);
459 
460 		gScreen->glDisableOutputClipping ();
461 
462 	    }
463 	}
464 
465 	glPopMatrix ();
466 
467 	mPainting3D   = false;
468 	mCurrentScale = mBasicScale;
469 
470     }
471 
472 
473     if (cs->paintOrder () == FTB)
474     {
475         cs->cubePaintViewport (attrib, transform, region, output, mask);
476     }
477 }
478 
479 bool
480 TdScreen::cubeShouldPaintAllViewports ()
481 {
482     return true;
483 }
484 
485 bool
486 TdScreen::cubeShouldPaintViewport (const GLScreenPaintAttrib &attrib,
487 				   const GLMatrix	     &transform,
488 				   CompOutput		     *outputPtr,
489 				   PaintOrder		     order)
490 {
491     bool rv = false;
492 
493     CUBE_SCREEN (screen);
494 
495     rv = cs->cubeShouldPaintViewport (attrib, transform, outputPtr, order);
496 
497     if (mActive)
498     {
499 	float pointZ = cs->invert () * cs->distance ();
500 	bool  ftb1, ftb2;
501 
502 	std::vector<GLVector> vPoints;
503 
504 	vPoints.push_back (GLVector (-0.5, 0.0, pointZ, 1.0));
505 	vPoints.push_back (GLVector (0.0, 0.5, pointZ, 1.0));
506 	vPoints.push_back (GLVector (0.0, 0.0, pointZ, 1.0));
507 
508 	mCurrentScale = 1.0;
509 
510 	ftb1 = cs->cubeCheckOrientation (attrib, transform, outputPtr, vPoints);
511 
512 	mCurrentScale = mBasicScale;
513 
514 	ftb2 = cs->cubeCheckOrientation (attrib, transform, outputPtr, vPoints);
515 
516 	return (order == FTB && (ftb1 || ftb2)) ||
517 	       (order == BTF && (!ftb1 || !ftb2)) || rv;
518     }
519 
520     return true;
521 }
522 
523 bool
524 TdScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
525 			 const GLMatrix		   &transform,
526 			 const CompRegion	   &region,
527 			 CompOutput		   *output,
528 			 unsigned int		   mask)
529 {
530     bool status;
531 
532     if (mActive)
533     {
534 	CompPlugin *p;
535 
536 	mask |= PAINT_SCREEN_TRANSFORMED_MASK |
537 	        PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK |
538 		PAINT_SCREEN_NO_OCCLUSION_DETECTION_MASK;
539 
540 	mWithDepth = true;
541 
542 	p = CompPlugin::find ("cubeaddon");
543 	if (p)
544 	{
545 	    CompOption::Vector &options = p->vTable->getOptions ();
546 	    CompOption option;
547 
548 	    mWithDepth = (CompOption::getIntOptionNamed
549 					      (options, "deformation", 0) == 0);
550 	}
551     }
552 
553 
554     status = gScreen->glPaintOutput (attrib, transform, region, output, mask);
555 
556     return status;
557 }
558 
559 void
560 TdScreen::donePaint ()
561 {
562     if (mActive && mDamage)
563     {
564 	mDamage = false;
565 	cScreen->damageScreen ();
566     }
567 
568     cScreen->donePaint ();
569 }
570 
571 TdScreen::TdScreen (CompScreen *screen) :
572     PluginClassHandler <TdScreen, CompScreen> (screen),
573     cScreen (CompositeScreen::get (screen)),
574     gScreen (GLScreen::get (screen)),
575     cubeScreen (CubeScreen::get (screen)),
576     mActive (false),
577     mPainting3D (false),
578     mCurrentScale (1.0f),
579     mBasicScale (1.0f)
580 {
581     CompositeScreenInterface::setHandler (cScreen, false);
582     GLScreenInterface::setHandler (gScreen, false);
583     CubeScreenInterface::setHandler (cubeScreen, false);
584 
585     cScreen->preparePaintSetEnabled (this, true);
CID 12589 - UNINIT_CTOR
Non-static class member "mMaxDepth" is not initialized in this constructor nor in any functions that it calls.
Non-static class member "mDamage" is not initialized in this constructor nor in any functions that it calls.
Non-static class member "mWithDepth" is not initialized in this constructor nor in any functions that it calls.
586 }
587 
588 TdScreen::~TdScreen ()
589 {
590 }
591 
592 TdWindow::TdWindow (CompWindow *window) :
593     PluginClassHandler <TdWindow, CompWindow> (window),
594     window (window),
595     cWindow (CompositeWindow::get (window)),
596     gWindow (GLWindow::get (window)),
597     mIs3D (false),
598     mFtb (false),
599     mDepth (0.0f)
600 {
601     GLWindowInterface::setHandler (gWindow, false);
602 }
603 
604 TdWindow::~TdWindow ()
605 {
606 }
607 
608 bool
609 TdPluginVTable::init ()
610 {
611     if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
612     	!CompPlugin::checkPluginABI ("cube", COMPIZ_CUBE_ABI) ||
613         !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
614         !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
615         return false;
616 
617     return true;
618 }