1 /*
2 * Compiz cube reflection and cylinder deformation plugin
3 *
4 * cubeaddon.c
5 *
6 * Copyright : (C) 2008 by Dennis Kasprzyk
7 * E-mail : onestone@opencompositing.org
8 *
9 * includes code from cubecaps.c
10 *
11 * Copyright : (C) 2007 Guillaume Seguin
12 * E-mail : guillaume@segu.in
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 */
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <signal.h>
30 #include <unistd.h>
31 #include <math.h>
32
33 #include <compiz-core.h>
34 #include <compiz-cube.h>
35
36 #include "cubeaddon_options.h"
37
38 static int CubeaddonDisplayPrivateIndex;
39 static int cubeDisplayPrivateIndex;
40
41 #define CUBEADDON_GRID_SIZE 100
42 #define CAP_ELEMENTS 15
43 #define CAP_NVERTEX (((CAP_ELEMENTS * (CAP_ELEMENTS + 1)) + 2) * 3)
44 #define CAP_NIDX (CAP_ELEMENTS * (CAP_ELEMENTS - 1) * 4)
45
46 #define CAP_NIMGVERTEX (((CAP_ELEMENTS + 1) * (CAP_ELEMENTS + 1)) * 5)
47 #define CAP_NIMGIDX (CAP_ELEMENTS * CAP_ELEMENTS * 4)
48
49 typedef struct _CubeaddonDisplay
50 {
51 int screenPrivateIndex;
52 } CubeaddonDisplay;
53
54 typedef struct _CubeCap
55 {
56 int current;
57 CompListValue *files;
58
59 Bool loaded;
60
61 CompTexture texture;
62 CompTransform texMat;
63 } CubeCap;
64
65 typedef struct _CubeaddonScreen
66 {
67 DonePaintScreenProc donePaintScreen;
68 PaintOutputProc paintOutput;
69 PaintTransformedOutputProc paintTransformedOutput;
70 AddWindowGeometryProc addWindowGeometry;
71 DrawWindowProc drawWindow;
72 DrawWindowTextureProc drawWindowTexture;
73
74 CubeClearTargetOutputProc clearTargetOutput;
75 CubeGetRotationProc getRotation;
76 CubeCheckOrientationProc checkOrientation;
77 CubeShouldPaintViewportProc shouldPaintViewport;
78 CubePaintTopProc paintTop;
79 CubePaintBottomProc paintBottom;
80
81 Bool reflection;
82 Bool first;
83
84 CompOutput *last;
85
86 float yTrans;
87 float zTrans;
88
89 float backVRotate;
90 float vRot;
91
92 float deform;
93 Bool wasDeformed;
94
95 Region tmpRegion;
96 BoxPtr tmpBox;
97 int nTmpBox;
98
99 GLfloat *winNormals;
100 unsigned int winNormSize;
101
102 GLfloat capFill[CAP_NVERTEX];
103 GLfloat capFillNorm[CAP_NVERTEX];
104 GLushort capFillIdx[CAP_NIDX];
105 float capDeform;
106 float capDistance;
107 int capDeformType;
108
109 CubeCap topCap;
110 CubeCap bottomCap;
111 } CubeaddonScreen;
112
113 #define CUBEADDON_DISPLAY(d) PLUGIN_DISPLAY(d, Cubeaddon, ca)
114 #define CUBEADDON_SCREEN(s) PLUGIN_SCREEN(s, Cubeaddon, ca)
115
116 /*
117 * Initiate a CubeCap
118 */
119 static void
cubeaddonInitCap(CompScreen * s,CubeCap * cap)120 cubeaddonInitCap (CompScreen *s, CubeCap *cap)
121 {
122 initTexture (s, &cap->texture);
123
124 cap->current = 0;
125 cap->files = NULL;
126 cap->loaded = FALSE;
127 }
128
129 /*
130 * Attempt to load current cap image (if any)
131 */
132 static void
cubeaddonLoadCap(CompScreen * s,CubeCap * cap,Bool scale,Bool aspect,Bool clamp)133 cubeaddonLoadCap (CompScreen *s,
134 CubeCap *cap,
135 Bool scale,
136 Bool aspect,
137 Bool clamp)
138 {
139 unsigned int width, height;
140 float xScale, yScale;
141
142 CUBE_SCREEN (s);
143
144 finiTexture (s, &cap->texture);
145 initTexture (s, &cap->texture);
146
147 cap->loaded = FALSE;
148
149 if (!cap->files || !cap->files->nValue)
150 return;
151
152 cap->current = cap->current % cap->files->nValue;
153
154 if (!readImageToTexture (s, &cap->texture,
155 cap->files->value[cap->current].s,
156 &width, &height))
157 {
158 compLogMessage ("cubeaddon", CompLogLevelWarn,
159 "Failed to load image: %s",
160 cap->files->value[cap->current].s);
161
162 finiTexture (s, &cap->texture);
163 initTexture (s, &cap->texture);
164
165 return;
166 }
167
168 cap->loaded = TRUE;
169 matrixGetIdentity (&cap->texMat);
170
171 cap->texMat.m[0] = cap->texture.matrix.xx;
172 cap->texMat.m[1] = cap->texture.matrix.yx;
173 cap->texMat.m[4] = cap->texture.matrix.xy;
174 cap->texMat.m[5] = cap->texture.matrix.yy;
175 cap->texMat.m[12] = cap->texture.matrix.x0;
176 cap->texMat.m[13] = cap->texture.matrix.y0;
177
178 if (aspect)
179 {
180 if (scale)
181 xScale = yScale = MIN (width, height);
182 else
183 xScale = yScale = MAX (width, height);
184 }
185 else
186 {
187 xScale = width;
188 yScale = height;
189 }
190
191 matrixTranslate (&cap->texMat, width / 2, height / 2.0, 0.0);
192 matrixScale (&cap->texMat, xScale / 2.0, yScale / 2.0, 1.0);
193
194 if (scale)
195 xScale = 1.0 / sqrtf (((cs->distance * cs->distance) + 0.25));
196 else
197 xScale = 1.0 / sqrtf (((cs->distance * cs->distance) + 0.25) * 0.5);
198
199 matrixScale (&cap->texMat, xScale, xScale, 1.0);
200
201 enableTexture (s, &cap->texture, COMP_TEXTURE_FILTER_GOOD);
202 if (clamp)
203 {
204 if (s->textureBorderClamp)
205 {
206 glTexParameteri (cap->texture.target, GL_TEXTURE_WRAP_S,
207 GL_CLAMP_TO_BORDER);
208 glTexParameteri (cap->texture.target, GL_TEXTURE_WRAP_T,
209 GL_CLAMP_TO_BORDER);
210 }
211 else
212 {
213 glTexParameteri (cap->texture.target, GL_TEXTURE_WRAP_S,
214 GL_CLAMP_TO_EDGE);
215 glTexParameteri (cap->texture.target, GL_TEXTURE_WRAP_T,
216 GL_CLAMP_TO_EDGE);
217 }
218 }
219 else
220 {
221 glTexParameteri (cap->texture.target, GL_TEXTURE_WRAP_S, GL_REPEAT);
222 glTexParameteri (cap->texture.target, GL_TEXTURE_WRAP_T, GL_REPEAT);
223 }
224 disableTexture (s, &cap->texture);
225 }
226
227 /* Settings handling -------------------------------------------------------- */
228
229 /*
230 * Switch cap, load it and damage screen if possible
231 */
232 static void
cubeaddonChangeCap(CompScreen * s,Bool top,int change)233 cubeaddonChangeCap (CompScreen *s,
234 Bool top,
235 int change)
236 {
237 CUBEADDON_SCREEN (s);
238 CubeCap *cap = (top)? &cas->topCap : &cas->bottomCap;
239 if (cap->files && cap->files->nValue)
240 {
241 int count = cap->files->nValue;
242 cap->current = (cap->current + change + count) % count;
243 if (top)
244 {
245 cubeaddonLoadCap (s, cap, cubeaddonGetTopScale (s),
246 cubeaddonGetTopAspect (s),
247 cubeaddonGetTopClamp (s));
248 }
249 else
250 {
251 cubeaddonLoadCap (s, cap, cubeaddonGetBottomScale (s),
252 cubeaddonGetBottomAspect (s),
253 cubeaddonGetBottomClamp (s));
254 matrixScale (&cap->texMat, 1.0, -1.0, 1.0);
255 }
256 damageScreen (s);
257 }
258 }
259
260 /*
261 * Top images list changed, reload top cap if any
262 */
263 static void
cubeaddonTopImagesChanged(CompScreen * s,CompOption * opt,CubeaddonScreenOptions num)264 cubeaddonTopImagesChanged (CompScreen *s,
265 CompOption *opt,
266 CubeaddonScreenOptions num)
267 {
268 CUBEADDON_SCREEN (s);
269
270 cas->topCap.files = cubeaddonGetTopImages (s);
271 cas->topCap.current = 0;
272 cubeaddonChangeCap (s, TRUE, 0);
273 }
274
275 /*
276 * Bottom images list changed, reload bottom cap if any
277 */
278 static void
cubeaddonBottomImagesChanged(CompScreen * s,CompOption * opt,CubeaddonScreenOptions num)279 cubeaddonBottomImagesChanged (CompScreen *s,
280 CompOption *opt,
281 CubeaddonScreenOptions num)
282 {
283 CUBEADDON_SCREEN (s);
284
285 cas->bottomCap.files = cubeaddonGetBottomImages (s);
286 cas->bottomCap.current = 0;
287 cubeaddonChangeCap (s, FALSE, 0);
288 }
289
290 /*
291 * Top image attribute changed
292 */
293 static void
cubeaddonTopImageChanged(CompScreen * s,CompOption * opt,CubeaddonScreenOptions num)294 cubeaddonTopImageChanged (CompScreen *s,
295 CompOption *opt,
296 CubeaddonScreenOptions num)
297 {
298 cubeaddonChangeCap (s, TRUE, 0);
299 }
300
301 /*
302 * Bottom images attribute changed
303 */
304 static void
cubeaddonBottomImageChanged(CompScreen * s,CompOption * opt,CubeaddonScreenOptions num)305 cubeaddonBottomImageChanged (CompScreen *s,
306 CompOption *opt,
307 CubeaddonScreenOptions num)
308 {
309 cubeaddonChangeCap (s, FALSE, 0);
310 }
311
312 /* Actions handling --------------------------------------------------------- */
313
314 /*
315 * Switch to next top image
316 */
317 static Bool
cubeaddonTopNext(CompDisplay * d,CompAction * action,CompActionState state,CompOption * option,int nOption)318 cubeaddonTopNext (CompDisplay *d,
319 CompAction *action,
320 CompActionState state,
321 CompOption *option,
322 int nOption)
323 {
324 CompScreen *s;
325 Window xid;
326
327 xid = getIntOptionNamed (option, nOption, "root", 0);
328
329 s = findScreenAtDisplay (d, xid);
330
331 if (s)
332 cubeaddonChangeCap (s, TRUE, 1);
333
334 return FALSE;
335 }
336
337 /*
338 * Switch to previous top image
339 */
340 static Bool
cubeaddonTopPrev(CompDisplay * d,CompAction * action,CompActionState state,CompOption * option,int nOption)341 cubeaddonTopPrev (CompDisplay *d,
342 CompAction *action,
343 CompActionState state,
344 CompOption *option,
345 int nOption)
346 {
347 CompScreen *s;
348 Window xid;
349
350 xid = getIntOptionNamed (option, nOption, "root", 0);
351
352 s = findScreenAtDisplay (d, xid);
353 if (s)
354 cubeaddonChangeCap (s, TRUE, -1);
355
356 return FALSE;
357 }
358
359 /*
360 * Switch to next bottom image
361 */
362 static Bool
cubeaddonBottomNext(CompDisplay * d,CompAction * action,CompActionState state,CompOption * option,int nOption)363 cubeaddonBottomNext (CompDisplay *d,
364 CompAction *action,
365 CompActionState state,
366 CompOption *option,
367 int nOption)
368 {
369 CompScreen *s;
370 Window xid;
371
372 xid = getIntOptionNamed (option, nOption, "root", 0);
373
374 s = findScreenAtDisplay (d, xid);
375
376 if (s)
377 cubeaddonChangeCap (s, FALSE, 1);
378
379 return FALSE;
380 }
381
382 /*
383 * Switch to previous bottom image
384 */
385 static Bool
cubeaddonBottomPrev(CompDisplay * d,CompAction * action,CompActionState state,CompOption * option,int nOption)386 cubeaddonBottomPrev (CompDisplay *d,
387 CompAction *action,
388 CompActionState state,
389 CompOption *option,
390 int nOption)
391 {
392 CompScreen *s;
393 Window xid;
394
395 xid = getIntOptionNamed (option, nOption, "root", 0);
396
397 s = findScreenAtDisplay (d, xid);
398 if (s)
399 cubeaddonChangeCap (s, FALSE, -1);
400
401 return FALSE;
402 }
403
404 static void
drawBasicGround(CompScreen * s)405 drawBasicGround (CompScreen *s)
406 {
407 float i;
408
409 glPushMatrix ();
410
411 glEnable (GL_BLEND);
412 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
413
414 glLoadIdentity ();
415 glTranslatef (0.0, 0.0, -DEFAULT_Z_CAMERA);
416
417 i = cubeaddonGetIntensity (s) * 2;
418
419 glBegin (GL_QUADS);
420 glColor4f (0.0, 0.0, 0.0, MAX (0.0, 1.0 - i) );
421 glVertex2f (0.5, 0.0);
422 glVertex2f (-0.5, 0.0);
423 glColor4f (0.0, 0.0, 0.0, MIN (1.0, 1.0 - (i - 1.0) ) );
424 glVertex2f (-0.5, -0.5);
425 glVertex2f (0.5, -0.5);
426 glEnd ();
427
428 if (cubeaddonGetGroundSize (s) > 0.0)
429 {
430 glBegin (GL_QUADS);
431 glColor4usv (cubeaddonGetGroundColor1 (s) );
432 glVertex2f (-0.5, -0.5);
433 glVertex2f (0.5, -0.5);
434 glColor4usv (cubeaddonGetGroundColor2 (s) );
435 glVertex2f (0.5, -0.5 + cubeaddonGetGroundSize (s) );
436 glVertex2f (-0.5, -0.5 + cubeaddonGetGroundSize (s) );
437 glEnd ();
438 }
439
440 glColor4usv (defaultColor);
441
442 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
443 glDisable (GL_BLEND);
444 glPopMatrix ();
445 }
446
447 static Bool
cubeaddonCheckOrientation(CompScreen * s,const ScreenPaintAttrib * sAttrib,const CompTransform * transform,CompOutput * outputPtr,CompVector * points)448 cubeaddonCheckOrientation (CompScreen *s,
449 const ScreenPaintAttrib *sAttrib,
450 const CompTransform *transform,
451 CompOutput *outputPtr,
452 CompVector *points)
453 {
454 Bool status;
455
456 CUBEADDON_SCREEN (s);
457 CUBE_SCREEN (s);
458
459 UNWRAP (cas, cs, checkOrientation);
460 status = (*cs->checkOrientation) (s, sAttrib, transform,
461 outputPtr, points);
462 WRAP (cas, cs, checkOrientation, cubeaddonCheckOrientation);
463
464 if (cas->reflection)
465 return !status;
466
467 return status;
468 }
469
470 static void
cubeaddonGetRotation(CompScreen * s,float * x,float * v,float * progress)471 cubeaddonGetRotation (CompScreen *s,
472 float *x,
473 float *v,
474 float *progress)
475 {
476 CUBE_SCREEN (s);
477 CUBEADDON_SCREEN (s);
478
479 UNWRAP (cas, cs, getRotation);
480 (*cs->getRotation) (s, x, v, progress);
481 WRAP (cas, cs, getRotation, cubeaddonGetRotation);
482
483 if (cubeaddonGetMode (s) == ModeAbove && *v > 0.0 && cas->reflection)
484 {
485 cas->vRot = *v;
486 *v = 0.0;
487 }
488 else
489 cas->vRot = 0.0;
490 }
491
492 static void
cubeaddonClearTargetOutput(CompScreen * s,float xRotate,float vRotate)493 cubeaddonClearTargetOutput (CompScreen *s,
494 float xRotate,
495 float vRotate)
496 {
497 CUBEADDON_SCREEN (s);
498 CUBE_SCREEN (s);
499
500 if (cas->reflection)
501 glCullFace (GL_BACK);
502
503 UNWRAP (cas, cs, clearTargetOutput);
504 (*cs->clearTargetOutput) (s, xRotate, cas->backVRotate);
505 WRAP (cas, cs, clearTargetOutput, cubeaddonClearTargetOutput);
506
507 if (cas->reflection)
508 glCullFace (GL_FRONT);
509 }
510
511 static Bool
cubeaddonShouldPaintViewport(CompScreen * s,const ScreenPaintAttrib * sAttrib,const CompTransform * transform,CompOutput * outputPtr,PaintOrder order)512 cubeaddonShouldPaintViewport (CompScreen *s,
513 const ScreenPaintAttrib *sAttrib,
514 const CompTransform *transform,
515 CompOutput *outputPtr,
516 PaintOrder order)
517 {
518 Bool rv = FALSE;
519
520 CUBEADDON_SCREEN (s);
521 CUBE_SCREEN (s);
522
523 UNWRAP (cas, cs, shouldPaintViewport);
524 rv = (*cs->shouldPaintViewport) (s, sAttrib, transform,
525 outputPtr, order);
526 WRAP (cas, cs, shouldPaintViewport, cubeaddonShouldPaintViewport);
527
528 if (rv || cs->unfolded)
529 return rv;
530
531 if (cas->deform > 0.0 && cubeaddonGetDeformation (s) == DeformationCylinder)
532 {
533 float z[3];
534 Bool ftb1, ftb2, ftb3;
535
536 z[0] = cs->invert * cs->distance;
537 z[1] = z[0] + (0.25 / cs->distance);
538 z[2] = cs->invert * sqrtf (0.25 + (cs->distance * cs->distance));
539
540 CompVector vPoints[3][3] = { { {.v = { -0.5, 0.0, z[0], 1.0 } },
541 {.v = { 0.0, 0.5, z[1], 1.0 } },
542 {.v = { 0.0, 0.0, z[1], 1.0 } } },
543 { {.v = { 0.5, 0.0, z[0], 1.0 } },
544 {.v = { 0.0, -0.5, z[1], 1.0 } },
545 {.v = { 0.0, 0.0, z[1], 1.0 } } },
546 { {.v = { -0.5, 0.0, z[2], 1.0 } },
547 {.v = { 0.0, 0.5, z[2], 1.0 } },
548 {.v = { 0.0, 0.0, z[2], 1.0 } } } };
549
550 ftb1 = (*cs->checkOrientation) (s, sAttrib, transform,
551 outputPtr, vPoints[0]);
552 ftb2 = (*cs->checkOrientation) (s, sAttrib, transform,
553 outputPtr, vPoints[1]);
554 ftb3 = (*cs->checkOrientation) (s, sAttrib, transform,
555 outputPtr, vPoints[2]);
556
557 rv = (order == FTB && (ftb1 || ftb2 || ftb3)) ||
558 (order == BTF && (!ftb1 || !ftb2 || !ftb3));
559 }
560 else if (cas->deform > 0.0 &&
561 cubeaddonGetDeformation (s) == DeformationSphere)
562 {
563 float z[4];
564 Bool ftb1, ftb2, ftb3, ftb4;
565
566 z[0] = sqrtf (0.5 + (cs->distance * cs->distance));
567 z[1] = z[0] + (0.25 / cs->distance);
568 z[2] = sqrtf (0.25 + (cs->distance * cs->distance));
569 z[3] = z[2] + 0.5;
570
571 CompVector vPoints[4][3] = { { {.v = { 0.0, 0.0, z[3], 1.0 } },
572 {.v = { -0.5, 0.5, z[2], 1.0 } },
573 {.v = { 0.0, 0.5, z[2], 1.0 } } },
574 { {.v = { 0.0, 0.0, z[3], 1.0 } },
575 {.v = { 0.5, -0.5, z[2], 1.0 } },
576 {.v = { 0.0, -0.5, z[2], 1.0 } } },
577 { {.v = { 0.0, 0.0, z[1], 1.0 } },
578 {.v = { -0.5, -0.5, z[0], 1.0 } },
579 {.v = { -0.5, 0.0, z[0], 1.0 } } },
580 { {.v = { 0.0, 0.0, z[1], 1.0 } },
581 {.v = { 0.5, 0.5, z[0], 1.0 } },
582 {.v = { 0.5, 0.0, z[0], 1.0 } } } };
583
584 ftb1 = (*cs->checkOrientation) (s, sAttrib, transform,
585 outputPtr, vPoints[0]);
586 ftb2 = (*cs->checkOrientation) (s, sAttrib, transform,
587 outputPtr, vPoints[1]);
588 ftb3 = (*cs->checkOrientation) (s, sAttrib, transform,
589 outputPtr, vPoints[2]);
590 ftb4 = (*cs->checkOrientation) (s, sAttrib, transform,
591 outputPtr, vPoints[3]);
592
593 rv = (order == FTB && (ftb1 || ftb2 || ftb3 || ftb4)) ||
594 (order == BTF && (!ftb1 || !ftb2 || !ftb3 || !ftb4));
595 }
596
597 return rv;
598 }
599
600 static void
cubeaddonPaintCap(CompScreen * s,const ScreenPaintAttrib * sAttrib,const CompTransform * transform,CompOutput * output,int size,Bool top,Bool adjust,unsigned short * color)601 cubeaddonPaintCap (CompScreen *s,
602 const ScreenPaintAttrib *sAttrib,
603 const CompTransform *transform,
604 CompOutput *output,
605 int size,
606 Bool top,
607 Bool adjust,
608 unsigned short *color)
609 {
610 ScreenPaintAttrib sa;
611 CompTransform sTransform;
612 int i, l, opacity;
613 int cullNorm, cullInv;
614 Bool wasCulled = glIsEnabled (GL_CULL_FACE);
615 float cInv = (top) ? 1.0: -1.0;
616 CubeCap *cap;
617 Bool cScale, cAspect;
618
619 CUBE_SCREEN (s);
620 CUBEADDON_SCREEN (s);
621
622 glGetIntegerv (GL_CULL_FACE_MODE, &cullNorm);
623 cullInv = (cullNorm == GL_BACK)? GL_FRONT : GL_BACK;
624
625 opacity = cs->desktopOpacity * color[3] / 0xffff;
626
627 glPushMatrix ();
628 glEnable (GL_BLEND);
629
630 if (top)
631 {
632 cap = &cas->topCap;
633 cScale = cubeaddonGetTopScale (s);
634 cAspect = cubeaddonGetTopAspect (s);
635 }
636 else
637 {
638 cap = &cas->bottomCap;
639 cScale = cubeaddonGetBottomScale (s);
640 cAspect = cubeaddonGetBottomAspect (s);
641 }
642
643
644 glDisableClientState (GL_TEXTURE_COORD_ARRAY);
645
646 if (cubeaddonGetDeformation (s) == DeformationSphere &&
647 cubeaddonGetDeformCaps (s))
648 glEnableClientState (GL_NORMAL_ARRAY);
649
650 glVertexPointer (3, GL_FLOAT, 0, cas->capFill);
651
652 glEnable(GL_CULL_FACE);
653
654 for (l = 0; l < ((cs->invert == 1) ? 2 : 1); l++)
655 {
656 if (cubeaddonGetDeformation (s) == DeformationSphere &&
657 cubeaddonGetDeformCaps (s))
658 {
659 glNormalPointer (GL_FLOAT, 0, (l == 0) ? cas->capFill : cas->capFillNorm);
660 }
661 else
662 glNormal3f (0.0, (l == 0) ? 1.0 : -1.0, 0.0);
663
664 glCullFace(((l == 1) ^ top) ? cullInv : cullNorm);
665
666 for (i = 0; i < size; i++)
667 {
668 sa = *sAttrib;
669 sTransform = *transform;
670 if (cs->invert == 1)
671 {
672 sa.yRotate += (360.0f / size) * cs->xRotations;
673 if (!adjust)
674 sa.yRotate -= (360.0f / size) * s->x;
675 }
676 else
677 {
678 sa.yRotate += 180.0f;
679 sa.yRotate -= (360.0f / size) * cs->xRotations;
680 if (!adjust)
681 sa.yRotate += (360.0f / size) * s->x;
682 }
683 sa.yRotate += (360.0f / size) * i;
684
685 (*s->applyScreenTransform) (s, &sa, output, &sTransform);
686
687 glLoadMatrixf (sTransform.m);
688 glTranslatef (cs->outputXOffset, -cs->outputYOffset, 0.0f);
689 glScalef (cs->outputXScale, cs->outputYScale, 1.0f);
690
691 glScalef (1.0, cInv, 1.0);
692
693 glColor4us (color[0] * opacity / 0xffff,
694 color[1] * opacity / 0xffff,
695 color[2] * opacity / 0xffff,
696 opacity);
697
698 glDrawArrays (GL_TRIANGLE_FAN, 0, CAP_ELEMENTS + 2);
699 if (cubeaddonGetDeformation (s) == DeformationSphere &&
700 cubeaddonGetDeformCaps (s))
701 glDrawElements (GL_QUADS, CAP_NIDX, GL_UNSIGNED_SHORT,
702 cas->capFillIdx);
703
704 if (cap->loaded)
705 {
706 float s_gen[4], t_gen[4];
707 CompTransform texMat = cap->texMat;
708
709 if (cs->invert != 1)
710 matrixScale (&texMat, -1.0, 1.0, 1.0);
711
712 glColor4us (cs->desktopOpacity, cs->desktopOpacity,
713 cs->desktopOpacity, cs->desktopOpacity);
714 enableTexture (s, &cap->texture, COMP_TEXTURE_FILTER_GOOD);
715
716 if (cAspect)
717 {
718 float scale, xScale = 1.0, yScale = 1.0;
719 scale = (float)output->width / (float)output->height;
720
721 if (output->width > output->height)
722 {
723 xScale = 1.0;
724 yScale = 1.0 / scale;
725 }
726 else
727 {
728 xScale = scale;
729 yScale = 1.0;
730 }
731
732 if (cubeaddonGetTopScale(s))
733 {
734 scale = xScale;
735 xScale = 1.0 / yScale;
736 yScale = 1.0 / scale;
737 }
738
739 matrixScale (&texMat, xScale, yScale, 1.0);
740 }
741
742 matrixRotate (&texMat, -(360.0f / size) * i, 0.0, 0.0, 1.0);
743
744 s_gen[0] = texMat.m[0];
745 s_gen[1] = texMat.m[8];
746 s_gen[2] = texMat.m[4];
747 s_gen[3] = texMat.m[12];
748 t_gen[0] = texMat.m[1];
749 t_gen[1] = texMat.m[9];
750 t_gen[2] = texMat.m[5];
751 t_gen[3] = texMat.m[13];
752
753 glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen);
754 glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen);
755
756 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
757 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
758
759 glEnable(GL_TEXTURE_GEN_S);
760 glEnable(GL_TEXTURE_GEN_T);
761
762 glDrawArrays (GL_TRIANGLE_FAN, 0, CAP_ELEMENTS + 2);
763 if (cubeaddonGetDeformation (s) == DeformationSphere &&
764 cubeaddonGetDeformCaps (s))
765 glDrawElements (GL_QUADS, CAP_NIDX, GL_UNSIGNED_SHORT,
766 cas->capFillIdx);
767
768 glDisable(GL_TEXTURE_GEN_S);
769 glDisable(GL_TEXTURE_GEN_T);
770 disableTexture (s, &cas->topCap.texture);
771 }
772 }
773 }
774
775 glEnableClientState (GL_TEXTURE_COORD_ARRAY);
776 glDisableClientState (GL_NORMAL_ARRAY);
777 glDisable (GL_BLEND);
778 glNormal3f (0.0, -1.0, 0.0);
779
780 glCullFace (cullNorm);
781 if (!wasCulled)
782 glDisable (GL_CULL_FACE);
783
784 glPopMatrix ();
785
786 glColor4usv (defaultColor);
787 }
788
789 static void
cubeaddonPaintTop(CompScreen * s,const ScreenPaintAttrib * sAttrib,const CompTransform * transform,CompOutput * output,int size)790 cubeaddonPaintTop (CompScreen *s,
791 const ScreenPaintAttrib *sAttrib,
792 const CompTransform *transform,
793 CompOutput *output,
794 int size)
795 {
796 CUBE_SCREEN (s);
797 CUBEADDON_SCREEN (s);
798
799 if ((!cubeaddonGetDrawBottom (s) && cs->invert == -1) ||
800 (!cubeaddonGetDrawTop (s) && cs->invert == 1))
801 {
802 UNWRAP (cas, cs, paintTop);
803 (*cs->paintTop) (s, sAttrib, transform, output, size);
804 WRAP (cas, cs, paintTop, cubeaddonPaintTop);
805 }
806
807 if (!cubeaddonGetDrawTop (s))
808 return;
809
810 cubeaddonPaintCap (s, sAttrib, transform, output, size, TRUE,
811 cubeaddonGetAdjustTop (s),
812 cubeaddonGetTopColor(s));
813 }
814
815 /*
816 * Paint bottom cube face
817 */
818 static void
cubeaddonPaintBottom(CompScreen * s,const ScreenPaintAttrib * sAttrib,const CompTransform * transform,CompOutput * output,int size)819 cubeaddonPaintBottom (CompScreen *s,
820 const ScreenPaintAttrib *sAttrib,
821 const CompTransform *transform,
822 CompOutput *output,
823 int size)
824 {
825 CUBE_SCREEN (s);
826 CUBEADDON_SCREEN (s);
827
828 if ((!cubeaddonGetDrawBottom (s) && cs->invert == 1) ||
829 (!cubeaddonGetDrawTop (s) && cs->invert == -1))
830 {
831 UNWRAP (cas, cs, paintBottom);
832 (*cs->paintBottom) (s, sAttrib, transform, output, size);
833 WRAP (cas, cs, paintBottom, cubeaddonPaintBottom);
834 }
835
836 if (!cubeaddonGetDrawBottom (s))
837 return;
838
839 cubeaddonPaintCap (s, sAttrib, transform, output, size, FALSE,
840 cubeaddonGetAdjustBottom (s),
841 cubeaddonGetBottomColor(s));
842 }
843
844 static void
cubeaddonAddWindowGeometry(CompWindow * w,CompMatrix * matrix,int nMatrix,Region region,Region clip)845 cubeaddonAddWindowGeometry (CompWindow *w,
846 CompMatrix *matrix,
847 int nMatrix,
848 Region region,
849 Region clip)
850 {
851 CompScreen *s = w->screen;
852
853 CUBEADDON_SCREEN (s);
854 CUBE_SCREEN (s);
855
856 if (cas->deform > 0.0)
857 {
858 int x1, x2, y1, y2, yi, i, j, oldVCount = w->vCount;
859 REGION reg;
860 GLfloat *v;
861 int offX = 0, offY = 0;
862 int sx1, sx2, sw, sy1, sy2, sh, nBox, currBox, cLast;
863 float lastX, lastZ = 0.0, radSquare, last[2][4];
864 Bool found;
865 float inv = (cs->invert == 1) ? 1.0 : -1.0;
866
867 float a1, a2, ang;
868
869 if (cubeaddonGetDeformation (s) == DeformationCylinder || cs->unfolded)
870 {
871 yi = region->extents.y2 - region->extents.y1;
872 radSquare = (cs->distance * cs->distance) + 0.25;
873 }
874 else
875 {
876 yi = CUBEADDON_GRID_SIZE;
877 radSquare = (cs->distance * cs->distance) + 0.5;
878 }
879
880 nBox = (((region->extents.y2 - region->extents.y1) / yi) + 1) *
881 (((region->extents.x2 - region->extents.x1) /
882 CUBEADDON_GRID_SIZE) + 1);
883
884 reg.numRects = 1;
885 reg.rects = ®.extents;
886
887 y1 = region->extents.y1;
888 y2 = MIN (y1 + yi, region->extents.y2);
889
890 UNWRAP (cas, s, addWindowGeometry);
891
892 if (region->numRects > 1)
893 {
894 while (y1 < region->extents.y2)
895 {
896 reg.extents.y1 = y1;
897 reg.extents.y2 = y2;
898
899 x1 = region->extents.x1;
900 x2 = MIN (x1 + CUBEADDON_GRID_SIZE, region->extents.x2);
901
902 while (x1 < region->extents.x2)
903 {
904 reg.extents.x1 = x1;
905 reg.extents.x2 = x2;
906
907 XIntersectRegion (region, ®, cas->tmpRegion);
908
909 if (!XEmptyRegion (cas->tmpRegion))
910 {
911 (*w->screen->addWindowGeometry) (w, matrix, nMatrix,
912 cas->tmpRegion, clip);
913 }
914
915 x1 = x2;
916 x2 = MIN (x2 + CUBEADDON_GRID_SIZE, region->extents.x2);
917 }
918 y1 = y2;
919 y2 = MIN (y2 + yi, region->extents.y2);
920 }
921 }
922 else
923 {
924 if (cas->nTmpBox < nBox)
925 {
926 cas->tmpBox = realloc (cas->tmpBox, nBox * sizeof (BOX));
927 if (!cas->tmpBox)
928 return;
929 cas->nTmpBox = nBox;
930 }
931
932 reg.extents = region->extents;
933 reg.rects = cas->tmpBox;
934
935 currBox = 0;
936 while (y1 < region->extents.y2)
937 {
938 x1 = region->extents.x1;
939 x2 = MIN (x1 + CUBEADDON_GRID_SIZE, region->extents.x2);
940
941 while (x1 < region->extents.x2)
942 {
943 reg.rects[currBox].y1 = y1;
944 reg.rects[currBox].y2 = y2;
945 reg.rects[currBox].x1 = x1;
946 reg.rects[currBox].x2 = x2;
947
948 currBox++;
949
950 x1 = x2;
951 x2 = MIN (x2 + CUBEADDON_GRID_SIZE, region->extents.x2);
952 }
953 y1 = y2;
954 y2 = MIN (y2 + yi, region->extents.y2);
955 }
956 reg.numRects = currBox;
957 (*w->screen->addWindowGeometry) (w, matrix, nMatrix, ®, clip);
958 }
959 WRAP (cas, s, addWindowGeometry, cubeaddonAddWindowGeometry);
960
961 v = w->vertices + (w->vertexStride - 3);
962 v += w->vertexStride * oldVCount;
963
964 if (!windowOnAllViewports (w))
965 {
966 getWindowMovementForOffset (w, s->windowOffsetX,
967 s->windowOffsetY, &offX, &offY);
968 }
969
970 if (cs->moMode == CUBE_MOMODE_ONE)
971 {
972 sx1 = 0;
973 sx2 = s->width;
974 sw = s->width;
975 sy1 = 0;
976 sy2 = s->height;
977 sh = s->height;
978 }
979 else if (cs->moMode == CUBE_MOMODE_MULTI)
980 {
981 sx1 = cas->last->region.extents.x1;
982 sx2 = cas->last->region.extents.x2;
983 sw = sx2 - sx1;
984 sy1 = cas->last->region.extents.y1;
985 sy2 = cas->last->region.extents.y2;
986 sh = sy2 - sy1;
987 }
988 else
989 {
990 if (cs->nOutput != s->nOutputDev)
991 {
992 sx1 = 0;
993 sx2 = s->width;
994 sw = s->width;
995 sy1 = 0;
996 sy2 = s->height;
997 sh = s->height;
998 }
999 else
1000 {
1001 sx1 = s->outputDev[cs->srcOutput].region.extents.x1;
1002 sx2 = s->outputDev[cs->srcOutput].region.extents.x2;
1003 sw = sx2 - sx1;
1004 sy1 = s->outputDev[cs->srcOutput].region.extents.y1;
1005 sy2 = s->outputDev[cs->srcOutput].region.extents.y2;
1006 sh = sy2 - sy1;
1007 }
1008 }
1009
1010 if (cubeaddonGetDeformation (s) == DeformationCylinder || cs->unfolded)
1011 {
1012 lastX = -1000000000.0;
1013
1014 for (i = oldVCount; i < w->vCount; i++)
1015 {
1016 if (v[0] == lastX)
1017 {
1018 v[2] = lastZ;
1019 }
1020 else if (v[0] + offX >= sx1 - CUBEADDON_GRID_SIZE &&
1021 v[0] + offX < sx2 + CUBEADDON_GRID_SIZE)
1022 {
1023 ang = (((v[0] + offX - sx1) / (float)sw) - 0.5);
1024 ang *= ang;
1025 if (ang < radSquare)
1026 {
1027 v[2] = sqrtf (radSquare - ang) - cs->distance;
1028 v[2] *= cas->deform * inv;
1029 }
1030 }
1031
1032 lastX = v[0];
1033 lastZ = v[2];
1034
1035 v += w->vertexStride;
1036 }
1037 }
1038 else
1039 {
1040
1041 last[0][0] = -1000000000.0;
1042 last[1][0] = -1000000000.0;
1043
1044 cLast = 0;
1045 for (i = oldVCount; i < w->vCount; i++)
1046 {
1047 found = FALSE;
1048
1049 for (j = 0; j < 2 && !found; j++)
1050 if (last[j][0] == v[0] && last[j][1] == v[1])
1051 {
1052 v[0] = last[j][2];
1053 v[2] = last[j][3];
1054 found = TRUE;
1055 }
1056
1057 if (!found && v[0] + offX >= sx1 - CUBEADDON_GRID_SIZE &&
1058 v[0] + offX < sx2 + CUBEADDON_GRID_SIZE &&
1059 v[1] + offY >= sy1 - CUBEADDON_GRID_SIZE &&
1060 v[1] + offY < sy2 + CUBEADDON_GRID_SIZE)
1061 {
1062 last[cLast][0] = v[0];
1063 last[cLast][1] = v[1];
1064 a1 = (((v[0] + offX - sx1) / (float)sw) - 0.5);
1065 a2 = (((v[1] + offY - sy1) / (float)sh) - 0.5);
1066 a2 *= a2;
1067
1068 ang = atanf (a1 / cs->distance);
1069 a2 = sqrtf (radSquare - a2);
1070
1071 v[2] += ((cosf (ang) * a2) - cs->distance) *
1072 cas->deform * inv;
1073 v[0] += ((sinf (ang) * a2) - a1) * sw * cas->deform;
1074 last[cLast][2] = v[0];
1075 last[cLast][3] = v[2];
1076 cLast = (cLast + 1) & 1;
1077 }
1078 v += w->vertexStride;
1079 }
1080 }
1081 }
1082 else
1083 {
1084 UNWRAP (cas, s, addWindowGeometry);
1085 (*w->screen->addWindowGeometry) (w, matrix, nMatrix, region, clip);
1086 WRAP (cas, s, addWindowGeometry, cubeaddonAddWindowGeometry);
1087 }
1088 }
1089
1090 static Bool
cubeaddonDrawWindow(CompWindow * w,const CompTransform * transform,const FragmentAttrib * attrib,Region region,unsigned int mask)1091 cubeaddonDrawWindow (CompWindow *w,
1092 const CompTransform *transform,
1093 const FragmentAttrib *attrib,
1094 Region region,
1095 unsigned int mask)
1096 {
1097 CompScreen *s = w->screen;
1098 Bool status;
1099
1100 CUBEADDON_SCREEN (s);
1101
1102 if (!(mask & PAINT_WINDOW_TRANSFORMED_MASK) && cas->deform)
1103 {
1104 int offX = 0, offY = 0;
1105 int x1, x2;
1106
1107 if (!windowOnAllViewports (w))
1108 {
1109 getWindowMovementForOffset (w, s->windowOffsetX,
1110 s->windowOffsetY, &offX, &offY);
1111 }
1112
1113 x1 = w->attrib.x - w->output.left + offX;
1114 x2 = w->attrib.x + w->width + w->output.right + offX;
1115 if (x1 < 0 && x2 < 0)
1116 return FALSE;
1117 if (x1 > s->width && x2 > s->width)
1118 return FALSE;
1119 }
1120
1121 UNWRAP (cas, s, drawWindow);
1122 status = (*s->drawWindow) (w, transform, attrib, region, mask);
1123 WRAP (cas, s, drawWindow, cubeaddonDrawWindow);
1124
1125 return status;
1126 }
1127
1128 static void
cubeaddonDrawWindowTexture(CompWindow * w,CompTexture * texture,const FragmentAttrib * attrib,unsigned int mask)1129 cubeaddonDrawWindowTexture (CompWindow *w,
1130 CompTexture *texture,
1131 const FragmentAttrib *attrib,
1132 unsigned int mask)
1133 {
1134 CompScreen *s = w->screen;
1135
1136 CUBEADDON_SCREEN (s);
1137
1138 if (cas->deform > 0.0 && s->lighting)
1139 {
1140 int i;
1141 int sx1, sx2, sw, sy1, sy2, sh;
1142 int offX = 0, offY = 0;
1143 float x, y, ym;
1144 GLfloat *v;
1145 float inv;
1146
1147 CUBE_SCREEN (s);
1148
1149 inv = (cs->invert == 1) ? 1.0: -1.0;
1150 ym = (cubeaddonGetDeformation (s) == DeformationCylinder) ? 0.0 : 1.0;
1151
1152 if (cas->winNormSize < w->vCount * 3)
1153 {
1154 cas->winNormals = realloc (cas->winNormals,
1155 w->vCount * 3 * sizeof (GLfloat));
1156 if (!cas->winNormals)
1157 {
1158 cas->winNormSize = 0;
1159 return;
1160 }
1161 cas->winNormSize = w->vCount * 3;
1162 }
1163
1164 if (!windowOnAllViewports (w))
1165 {
1166 getWindowMovementForOffset (w, s->windowOffsetX,
1167 s->windowOffsetY, &offX, &offY);
1168 }
1169
1170 if (cs->moMode == CUBE_MOMODE_ONE)
1171 {
1172 sx1 = 0;
1173 sx2 = s->width;
1174 sw = s->width;
1175 sy1 = 0;
1176 sy2 = s->height;
1177 sh = s->height;
1178 }
1179 else if (cs->moMode == CUBE_MOMODE_MULTI)
1180 {
1181 sx1 = cas->last->region.extents.x1;
1182 sx2 = cas->last->region.extents.x2;
1183 sw = sx2 - sx1;
1184 sy1 = cas->last->region.extents.y1;
1185 sy2 = cas->last->region.extents.y2;
1186 sh = sy2 - sy1;
1187 }
1188 else
1189 {
1190 if (cs->nOutput != s->nOutputDev)
1191 {
1192 sx1 = 0;
1193 sx2 = s->width;
1194 sw = s->width;
1195 sy1 = 0;
1196 sy2 = s->height;
1197 sh = s->height;
1198 }
1199 else
1200 {
1201 sx1 = s->outputDev[cs->srcOutput].region.extents.x1;
1202 sx2 = s->outputDev[cs->srcOutput].region.extents.x2;
1203 sw = sx2 - sx1;
1204 sy1 = s->outputDev[cs->srcOutput].region.extents.y1;
1205 sy2 = s->outputDev[cs->srcOutput].region.extents.y2;
1206 sh = sy2 - sy1;
1207 }
1208 }
1209
1210 v = w->vertices + (w->vertexStride - 3);
1211
1212 for (i = 0; i < w->vCount; i++)
1213 {
1214 x = (((v[0] + offX - sx1) / (float)sw) - 0.5);
1215 y = (((v[1] + offY - sy1) / (float)sh) - 0.5);
1216
1217 if (cs->paintOrder == FTB)
1218 {
1219 cas->winNormals[i * 3] = x / sw * cas->deform;
1220 cas->winNormals[(i * 3) + 1] = y / sh * cas->deform * ym;
1221 cas->winNormals[(i * 3) + 2] = v[2] + cs->distance;
1222 }
1223 else
1224 {
1225 cas->winNormals[i * 3] = -x / sw * cas->deform * inv;
1226 cas->winNormals[(i * 3) + 1] = -y / sh * cas->deform * ym * inv;
1227 cas->winNormals[(i * 3) + 2] = -(v[2] + cs->distance);
1228 }
1229
1230 v += w->vertexStride;
1231 }
1232
1233 glEnable (GL_NORMALIZE);
1234 glNormalPointer (GL_FLOAT,0, cas->winNormals);
1235
1236 glEnableClientState (GL_NORMAL_ARRAY);
1237
1238 UNWRAP (cas, s, drawWindowTexture);
1239 (*s->drawWindowTexture) (w, texture, attrib, mask);
1240 WRAP (cas, s, drawWindowTexture, cubeaddonDrawWindowTexture);
1241
1242 glDisable (GL_NORMALIZE);
1243 glDisableClientState (GL_NORMAL_ARRAY);
1244 glNormal3f (0.0, 0.0, -1.0);
1245 return;
1246 }
1247
1248 UNWRAP (cas, s, drawWindowTexture);
1249 (*s->drawWindowTexture) (w, texture, attrib, mask);
1250 WRAP (cas, s, drawWindowTexture, cubeaddonDrawWindowTexture);
1251 }
1252
1253 static void
cubeaddonPaintTransformedOutput(CompScreen * s,const ScreenPaintAttrib * sAttrib,const CompTransform * transform,Region region,CompOutput * output,unsigned int mask)1254 cubeaddonPaintTransformedOutput (CompScreen *s,
1255 const ScreenPaintAttrib *sAttrib,
1256 const CompTransform *transform,
1257 Region region,
1258 CompOutput *output,
1259 unsigned int mask)
1260 {
1261 static GLfloat light0Position[] = { -0.5f, 0.5f, -9.0f, 1.0f };
1262 CompTransform sTransform = *transform;
1263
1264 CUBEADDON_SCREEN (s);
1265 CUBE_SCREEN (s);
1266
1267 if (cubeaddonGetDeformation (s) != DeformationNone
1268 && s->hsize * cs->nOutput > 2 && s->desktopWindowCount &&
1269 (cs->rotationState == RotationManual ||
1270 (cs->rotationState == RotationChange &&
1271 !cubeaddonGetCylinderManualOnly (s)) || cas->wasDeformed) &&
1272 (!cs->unfolded || cubeaddonGetUnfoldDeformation (s)))
1273 {
1274 float x, progress;
1275
1276 (*cs->getRotation) (s, &x, &x, &progress);
1277 cas->deform = progress;
1278
1279 if (cubeaddonGetSphereAspect (s) > 0.0 && cs->invert == 1 &&
1280 cubeaddonGetDeformation (s) == DeformationSphere)
1281 {
1282 float scale, val = cubeaddonGetSphereAspect (s) * cas->deform;
1283
1284 if (output->width > output->height)
1285 {
1286 scale = (float)output->height / (float)output->width;
1287 scale = (scale * val) + 1.0 - val;
1288 matrixScale (&sTransform, scale, 1.0, 1.0);
1289 }
1290 else
1291 {
1292 scale = (float)output->width / (float)output->height;
1293 scale = (scale * val) + 1.0 - val;
1294 matrixScale (&sTransform, 1.0, scale, 1.0);
1295 }
1296 }
1297 }
1298 else
1299 {
1300 cas->deform = 0.0;
1301 }
1302
1303 cs->paintAllViewports |= !cubeaddonGetDrawTop (s) ||
1304 !cubeaddonGetDrawBottom (s) ||
1305 (cubeaddonGetTopColorAlpha (s) != OPAQUE) ||
1306 (cubeaddonGetBottomColorAlpha (s) != OPAQUE) ||
1307 (cas->deform > 0.0);
1308
1309 if (cas->capDistance != cs->distance)
1310 {
1311 cubeaddonChangeCap (s, TRUE, 0);
1312 cubeaddonChangeCap (s, FALSE, 0);
1313 }
1314
1315 if (cas->deform != cas->capDeform || cas->capDistance != cs->distance ||
1316 cas->capDeformType != cubeaddonGetDeformation (s))
1317 {
1318 float *quad;
1319 int i, j;
1320 float rS, r, x, y, z, w;
1321 if (cubeaddonGetDeformation (s) != DeformationSphere ||
1322 !cubeaddonGetDeformCaps (s))
1323 {
1324 rS = (cs->distance * cs->distance) + 0.5;
1325
1326 cas->capFill[0] = 0.0;
1327 cas->capFill[1] = 0.5;
1328 cas->capFill[2] = 0.0;
1329 cas->capFillNorm[0] = 0.0;
1330 cas->capFillNorm[1] = -1.0;
1331 cas->capFillNorm[2] = 0.0;
1332
1333 z = cs->distance;
1334 r = 0.25 + (cs->distance * cs->distance);
1335
1336 for (j = 0; j <= CAP_ELEMENTS; j++)
1337 {
1338 x = -0.5 + ((float)j / (float)CAP_ELEMENTS);
1339 z = ((sqrtf(r - (x * x)) - cs->distance) * cas->deform) +
1340 cs->distance;
1341 y = 0.5;
1342
1343 quad = &cas->capFill[(1 + j) * 3];
1344
1345 quad[0] = x;
1346 quad[1] = y;
1347 quad[2] = z;
1348
1349 quad = &cas->capFillNorm[(1 + j) * 3];
1350
1351 quad[0] = -x;
1352 quad[1] = -y;
1353 quad[2] = -z;
1354 }
1355 }
1356 else
1357 {
1358 rS = (cs->distance * cs->distance) + 0.5;
1359
1360 cas->capFill[0] = 0.0;
1361 cas->capFill[1] = ((sqrtf (rS) - 0.5) * cas->deform) + 0.5;
1362 cas->capFill[2] = 0.0;
1363 cas->capFillNorm[0] = 0.0;
1364 cas->capFillNorm[1] = -1.0;
1365 cas->capFillNorm[2] = 0.0;
1366
1367 for (i = 0; i < CAP_ELEMENTS; i++)
1368 {
1369 w = (float)(i + 1) / (float)CAP_ELEMENTS;
1370
1371 r = (((w / 2.0) * (w / 2.0)) +
1372 (cs->distance * cs->distance * w * w));
1373
1374 for (j = 0; j <= CAP_ELEMENTS; j++)
1375 {
1376 x = - (w / 2.0) + ((float)j * w / (float)CAP_ELEMENTS);
1377 z = ((sqrtf(r - (x * x)) - (cs->distance * w)) *
1378 cas->deform) + (cs->distance * w);
1379 y = ((sqrtf(rS - (x * x) - (r - (x * x))) - 0.5) *
1380 cas->deform) + 0.5;
1381
1382 quad = &cas->capFill[(1 + (i * (CAP_ELEMENTS + 1)) +
1383 j) * 3];
1384
1385 quad[0] = x;
1386 quad[1] = y;
1387 quad[2] = z;
1388
1389 quad = &cas->capFillNorm[(1 + (i * (CAP_ELEMENTS + 1)) +
1390 j) * 3];
1391
1392 quad[0] = -x;
1393 quad[1] = -y;
1394 quad[2] = -z;
1395 }
1396 }
1397 }
1398
1399 cas->capDeform = cas->deform;
1400 cas->capDistance = cs->distance;
1401 cas->capDeformType = cubeaddonGetDeformation (s);
1402 }
1403
1404 if (cs->invert == 1 && cas->first && cubeaddonGetReflection (s))
1405 {
1406 cas->first = FALSE;
1407 cas->reflection = TRUE;
1408
1409 if (cs->grabIndex)
1410 {
1411 CompTransform rTransform = sTransform;
1412
1413 matrixTranslate (&rTransform, 0.0, -1.0, 0.0);
1414 matrixScale (&rTransform, 1.0, -1.0, 1.0);
1415 glCullFace (GL_FRONT);
1416
1417 UNWRAP (cas, s, paintTransformedOutput);
1418 (*s->paintTransformedOutput) (s, sAttrib, &rTransform,
1419 region, output, mask);
1420 WRAP (cas, s, paintTransformedOutput,
1421 cubeaddonPaintTransformedOutput);
1422
1423 glCullFace (GL_BACK);
1424 drawBasicGround (s);
1425 }
1426 else
1427 {
1428 CompTransform rTransform = sTransform;
1429 CompTransform pTransform;
1430 float angle = 360.0 / ((float) s->hsize * cs->nOutput);
1431 float xRot, vRot, xRotate, xRotate2, vRotate, p;
1432 float rYTrans;
1433 CompVector point = { .v = { -0.5, -0.5, cs->distance, 1.0 } };
1434 CompVector point2 = { .v = { -0.5, 0.5, cs->distance, 1.0 } };
1435 float deform;
1436
1437 (*cs->getRotation) (s, &xRot, &vRot, &p);
1438
1439 cas->backVRotate = 0.0;
1440
1441 xRotate = xRot;
1442 xRotate2 = xRot;
1443 vRotate = vRot;
1444
1445 if (vRotate < 0.0)
1446 xRotate += 180;
1447
1448 vRotate = fmod (fabs (vRotate), 180.0);
1449 xRotate = fmod (fabs (xRotate), angle);
1450 xRotate2 = fmod (fabs (xRotate2), angle);
1451
1452 if (vRotate >= 90.0)
1453 vRotate = 180.0 - vRotate;
1454
1455 if (xRotate >= angle / 2.0)
1456 xRotate = angle - xRotate;
1457
1458 if (xRotate2 >= angle / 2.0)
1459 xRotate2 = angle - xRotate2;
1460
1461 xRotate = (cas->deform * angle * 0.5) +
1462 ((1.0 - cas->deform) * xRotate);
1463 xRotate2 = (cas->deform * angle * 0.5) +
1464 ((1.0 - cas->deform) * xRotate2);
1465
1466 matrixGetIdentity (&pTransform);
1467 matrixRotate (&pTransform, xRotate, 0.0f, 1.0f, 0.0f);
1468 matrixRotate (&pTransform,
1469 vRotate, cosf (xRotate * DEG2RAD),
1470 0.0f, sinf (xRotate * DEG2RAD));
1471
1472 matrixMultiplyVector (&point, &point, &pTransform);
1473
1474 matrixGetIdentity (&pTransform);
1475 matrixRotate (&pTransform, xRotate2, 0.0f, 1.0f, 0.0f);
1476 matrixRotate (&pTransform,
1477 vRotate, cosf (xRotate2 * DEG2RAD),
1478 0.0f, sinf (xRotate2 * DEG2RAD));
1479
1480 matrixMultiplyVector (&point2, &point2, &pTransform);
1481
1482 switch (cubeaddonGetMode (s)) {
1483 case ModeJumpyReflection:
1484 cas->yTrans = 0.0;
1485 if (cubeaddonGetDeformation (s) == DeformationSphere &&
1486 cubeaddonGetDeformCaps (s) && cubeaddonGetDrawBottom (s))
1487 {
1488 rYTrans = sqrt (0.5 + (cs->distance * cs->distance)) *
1489 -2.0;
1490 }
1491 else
1492 {
1493 rYTrans = point.y * 2.0;
1494 }
1495
1496 break;
1497 case ModeDistance:
1498 cas->yTrans = 0.0;
1499 rYTrans = sqrt (0.5 + (cs->distance * cs->distance)) * -2.0;
1500 break;
1501 default:
1502
1503 if (cubeaddonGetDeformation (s) == DeformationSphere &&
1504 cubeaddonGetDeformCaps (s) && cubeaddonGetDrawBottom (s))
1505 {
1506 cas->yTrans = cas->capFill[1] - 0.5;
1507 rYTrans = -cas->capFill[1] - 0.5;
1508 }
1509 else if (cubeaddonGetDeformation (s) == DeformationSphere &&
1510 vRotate > atan (cs->distance * 2) / DEG2RAD)
1511 {
1512 cas->yTrans = sqrt (0.5 + (cs->distance * cs->distance)) - 0.5;
1513 rYTrans = -sqrt (0.5 + (cs->distance * cs->distance)) - 0.5;
1514 }
1515 else
1516 {
1517 cas->yTrans = -point.y - 0.5;
1518 rYTrans = point.y - 0.5;
1519 }
1520 break;
1521 }
1522
1523 if (!cubeaddonGetAutoZoom (s) ||
1524 ((cs->rotationState != RotationManual) &&
1525 cubeaddonGetZoomManualOnly (s)))
1526 {
1527 cas->zTrans = 0.0;
1528 }
1529 else
1530 cas->zTrans = -point2.z + cs->distance;
1531
1532 if (cubeaddonGetMode (s) == ModeAbove)
1533 cas->zTrans = 0.0;
1534
1535 if (cubeaddonGetDeformation (s) == DeformationCylinder)
1536 deform = (sqrt (0.25 + (cs->distance * cs->distance)) -
1537 cs->distance) * -cas->deform;
1538 else if (cubeaddonGetDeformation (s) == DeformationSphere)
1539 deform = (sqrt (0.5 + (cs->distance * cs->distance)) -
1540 cs->distance) * -cas->deform;
1541
1542 if (cas->deform > 0.0)
1543 cas->zTrans = deform;
1544
1545 if (cubeaddonGetMode (s) == ModeAbove && cas->vRot > 0.0)
1546 {
1547 cas->backVRotate = cas->vRot;
1548 if (cubeaddonGetDeformation (s) == DeformationSphere &&
1549 cubeaddonGetDeformCaps (s) && cubeaddonGetDrawBottom (s))
1550 {
1551 cas->yTrans = cas->capFill[1] - 0.5;
1552 rYTrans = -cas->capFill[1] - 0.5;
1553 }
1554 else
1555 {
1556 cas->yTrans = 0.0;
1557 rYTrans = -1.0;
1558 }
1559
1560 matrixGetIdentity (&pTransform);
1561 applyScreenTransform (s, sAttrib, output, &pTransform);
1562 point.x = point.y = 0.0;
1563 point.z = -cs->distance;
1564 point.z += deform;
1565 point.w = 1.0;
1566 matrixMultiplyVector (&point, &point, &pTransform);
1567
1568 matrixTranslate (&rTransform, 0.0, 0.0, point.z);
1569 matrixRotate (&rTransform, cas->vRot, 1.0, 0.0, 0.0);
1570 matrixScale (&rTransform, 1.0, -1.0, 1.0);
1571 matrixTranslate (&rTransform, 0.0, -rYTrans,
1572 -point.z + cas->zTrans);
1573 }
1574 else
1575 {
1576 matrixTranslate (&rTransform, 0.0, rYTrans, cas->zTrans);
1577 matrixScale (&rTransform, 1.0, -1.0, 1.0);
1578 }
1579
1580 glPushMatrix ();
1581 glLoadIdentity ();
1582 glScalef (1.0, -1.0, 1.0);
1583 glLightfv (GL_LIGHT0, GL_POSITION, light0Position);
1584 glPopMatrix ();
1585 glCullFace (GL_FRONT);
1586
1587 UNWRAP (cas, s, paintTransformedOutput);
1588 (*s->paintTransformedOutput) (s, sAttrib, &rTransform,
1589 region, output, mask);
1590 WRAP (cas, s, paintTransformedOutput,
1591 cubeaddonPaintTransformedOutput);
1592
1593 glCullFace (GL_BACK);
1594 glPushMatrix ();
1595 glLoadIdentity ();
1596 glLightfv (GL_LIGHT0, GL_POSITION, light0Position);
1597 glPopMatrix ();
1598
1599 if (cubeaddonGetMode (s) == ModeAbove && cas->vRot > 0.0)
1600 {
1601 int j;
1602 float i, c;
1603 float v = MIN (1.0, cas->vRot / 30.0);
1604 float col1[4], col2[4];
1605
1606 glPushMatrix ();
1607
1608 glEnable (GL_BLEND);
1609 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1610
1611 glLoadIdentity ();
1612 glTranslatef (0.0, 0.0, -DEFAULT_Z_CAMERA);
1613
1614 i = cubeaddonGetIntensity (s) * 2;
1615 c = cubeaddonGetIntensity (s);
1616
1617 glBegin (GL_QUADS);
1618 glColor4f (0.0, 0.0, 0.0,
1619 ((1 - v) * MAX (0.0, 1.0 - i)) + (v * c));
1620 glVertex2f (0.5, v / 2.0);
1621 glVertex2f (-0.5, v / 2.0);
1622 glColor4f (0.0, 0.0, 0.0,
1623 ((1 - v) * MIN (1.0, 1.0 - (i - 1.0))) + (v * c));
1624 glVertex2f (-0.5, -0.5);
1625 glVertex2f (0.5, -0.5);
1626 glEnd ();
1627
1628 for (j = 0; j < 4; j++)
1629 {
1630 col1[j] = (1.0 - v) * cubeaddonGetGroundColor1 (s) [j] +
1631 (v * (cubeaddonGetGroundColor1 (s) [j] +
1632 cubeaddonGetGroundColor2 (s) [j]) * 0.5);
1633 col1[j] /= 0xffff;
1634 col2[j] = (1.0 - v) * cubeaddonGetGroundColor2 (s) [j] +
1635 (v * (cubeaddonGetGroundColor1 (s) [j] +
1636 cubeaddonGetGroundColor2 (s) [j]) * 0.5);
1637 col2[j] /= 0xffff;
1638 }
1639
1640 if (cubeaddonGetGroundSize (s) > 0.0)
1641 {
1642 glBegin (GL_QUADS);
1643 glColor4fv (col1);
1644 glVertex2f (-0.5, -0.5);
1645 glVertex2f (0.5, -0.5);
1646 glColor4fv (col2);
1647 glVertex2f (0.5, -0.5 +
1648 ((1 - v) * cubeaddonGetGroundSize (s)) + v);
1649 glVertex2f (-0.5, -0.5 +
1650 ((1 - v) * cubeaddonGetGroundSize (s)) + v);
1651 glEnd ();
1652 }
1653
1654 glColor4usv (defaultColor);
1655
1656 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1657 glDisable (GL_BLEND);
1658 glPopMatrix ();
1659 }
1660 else
1661 drawBasicGround (s);
1662 }
1663
1664 memset (cs->capsPainted, 0, sizeof (Bool) * s->nOutputDev);
1665 cas->reflection = FALSE;
1666 }
1667
1668 if (!cubeaddonGetReflection (s))
1669 {
1670 cas->yTrans = 0.0;
1671 cas->zTrans = (sqrt (0.25 + (cs->distance * cs->distance)) -
1672 cs->distance) * -cas->deform;
1673 }
1674
1675 matrixTranslate (&sTransform, 0.0, cas->yTrans, cas->zTrans);
1676
1677 UNWRAP (cas, s, paintTransformedOutput);
1678 (*s->paintTransformedOutput) (s, sAttrib, &sTransform,
1679 region, output, mask);
1680 WRAP (cas, s, paintTransformedOutput, cubeaddonPaintTransformedOutput);
1681 }
1682
1683 static Bool
cubeaddonPaintOutput(CompScreen * s,const ScreenPaintAttrib * sAttrib,const CompTransform * transform,Region region,CompOutput * output,unsigned int mask)1684 cubeaddonPaintOutput (CompScreen *s,
1685 const ScreenPaintAttrib *sAttrib,
1686 const CompTransform *transform,
1687 Region region,
1688 CompOutput *output,
1689 unsigned int mask)
1690 {
1691 Bool status;
1692
1693 CUBEADDON_SCREEN (s);
1694
1695 if (cas->last != output)
1696 cas->first = TRUE;
1697
1698 cas->last = output;
1699
1700 UNWRAP (cas, s, paintOutput);
1701 status = (*s->paintOutput) (s, sAttrib, transform, region, output, mask);
1702 WRAP (cas, s, paintOutput, cubeaddonPaintOutput);
1703
1704 return status;
1705 }
1706
1707 static void
cubeaddonDonePaintScreen(CompScreen * s)1708 cubeaddonDonePaintScreen (CompScreen * s)
1709 {
1710 CUBEADDON_SCREEN (s);
1711
1712 cas->first = TRUE;
1713 cas->yTrans = 0.0;
1714 cas->zTrans = 0.0;
1715
1716 cas->wasDeformed = (cas->deform > 0.0);
1717
1718 if (cas->deform > 0.0 && cas->deform < 1.0)
1719 {
1720 damageScreen (s);
1721 cas->deform = 0.0;
1722 }
1723
1724 UNWRAP (cas, s, donePaintScreen);
1725 (*s->donePaintScreen) (s);
1726 WRAP (cas, s, donePaintScreen, cubeaddonDonePaintScreen);
1727 }
1728
1729
1730 static Bool
cubeaddonInitDisplay(CompPlugin * p,CompDisplay * d)1731 cubeaddonInitDisplay (CompPlugin *p,
1732 CompDisplay *d)
1733 {
1734 CubeaddonDisplay *cad;
1735
1736 if (!checkPluginABI ("core", CORE_ABIVERSION) ||
1737 !checkPluginABI ("cube", CUBE_ABIVERSION))
1738 return FALSE;
1739
1740 if (!getPluginDisplayIndex (d, "cube", &cubeDisplayPrivateIndex))
1741 return FALSE;
1742
1743 cad = malloc (sizeof (CubeaddonDisplay));
1744
1745 if (!cad)
1746 return FALSE;
1747
1748 cad->screenPrivateIndex = allocateScreenPrivateIndex (d);
1749
1750 if (cad->screenPrivateIndex < 0)
1751 {
1752 free (cad);
1753 return FALSE;
1754 }
1755
1756 d->base.privates[CubeaddonDisplayPrivateIndex].ptr = cad;
1757
1758 cubeaddonSetTopNextKeyInitiate (d, cubeaddonTopNext);
1759 cubeaddonSetTopPrevKeyInitiate (d, cubeaddonTopPrev);
1760 cubeaddonSetBottomNextKeyInitiate (d, cubeaddonBottomNext);
1761 cubeaddonSetBottomPrevKeyInitiate (d, cubeaddonBottomPrev);
1762
1763 cubeaddonSetTopNextButtonInitiate (d, cubeaddonTopNext);
1764 cubeaddonSetTopPrevButtonInitiate (d, cubeaddonTopPrev);
1765 cubeaddonSetBottomNextButtonInitiate (d, cubeaddonBottomNext);
1766 cubeaddonSetBottomPrevButtonInitiate (d, cubeaddonBottomPrev);
1767
1768 return TRUE;
1769 }
1770
1771 static void
cubeaddonFiniDisplay(CompPlugin * p,CompDisplay * d)1772 cubeaddonFiniDisplay (CompPlugin *p,
1773 CompDisplay *d)
1774 {
1775 CUBEADDON_DISPLAY (d);
1776
1777 freeScreenPrivateIndex (d, cad->screenPrivateIndex);
1778 free (cad);
1779 }
1780
1781 static Bool
cubeaddonInitScreen(CompPlugin * p,CompScreen * s)1782 cubeaddonInitScreen (CompPlugin *p,
1783 CompScreen *s)
1784 {
1785 CubeaddonScreen *cas;
1786 GLushort *idx;
1787 int i, j;
1788
1789 CUBEADDON_DISPLAY (s->display);
1790 CUBE_SCREEN (s);
1791
1792 cas = malloc (sizeof (CubeaddonScreen));
1793
1794 if (!cas)
1795 return FALSE;
1796
1797 s->base.privates[cad->screenPrivateIndex].ptr = cas;
1798
1799 cas->reflection = FALSE;
1800 cas->first = TRUE;
1801 cas->last = NULL;
1802 cas->yTrans = 0.0;
1803 cas->zTrans = 0.0;
1804 cas->tmpRegion = XCreateRegion ();
1805 cas->deform = 0.0;
1806 cas->capDeform = -1.0;
1807 cas->capDistance = cs->distance;
1808
1809 cas->winNormals = NULL;
1810 cas->winNormSize = 0;
1811
1812 cas->tmpBox = NULL;
1813 cas->nTmpBox = 0;
1814
1815 idx = cas->capFillIdx;
1816 for (i = 0; i < CAP_ELEMENTS - 1; i++)
1817 {
1818 for (j = 0; j < CAP_ELEMENTS; j++)
1819 {
1820 idx[0] = 1 + (i * (CAP_ELEMENTS + 1)) + j;
1821 idx[1] = 1 + ((i + 1) * (CAP_ELEMENTS + 1)) + j;
1822 idx[2] = 2 + ((i + 1) * (CAP_ELEMENTS + 1)) + j;
1823 idx[3] = 2 + (i * (CAP_ELEMENTS + 1)) + j;
1824 idx += 4;
1825 }
1826 }
1827
1828 cubeaddonInitCap (s, &cas->topCap);
1829 cubeaddonInitCap (s, &cas->bottomCap);
1830
1831 cas->topCap.files = cubeaddonGetTopImages (s);
1832 cas->bottomCap.files = cubeaddonGetBottomImages (s);
1833
1834 cubeaddonSetTopImagesNotify (s, cubeaddonTopImagesChanged);
1835 cubeaddonSetBottomImagesNotify (s, cubeaddonBottomImagesChanged);
1836
1837 cubeaddonSetTopScaleNotify (s, cubeaddonTopImageChanged);
1838 cubeaddonSetTopAspectNotify (s, cubeaddonTopImageChanged);
1839 cubeaddonSetTopClampNotify (s, cubeaddonTopImageChanged);
1840 cubeaddonSetBottomScaleNotify (s, cubeaddonBottomImageChanged);
1841 cubeaddonSetBottomAspectNotify (s, cubeaddonBottomImageChanged);
1842 cubeaddonSetBottomClampNotify (s, cubeaddonTopImageChanged);
1843
1844 cubeaddonChangeCap (s, TRUE, 0);
1845 cubeaddonChangeCap (s, FALSE, 0);
1846
1847 WRAP (cas, s, paintTransformedOutput, cubeaddonPaintTransformedOutput);
1848 WRAP (cas, s, paintOutput, cubeaddonPaintOutput);
1849 WRAP (cas, s, donePaintScreen, cubeaddonDonePaintScreen);
1850 WRAP (cas, s, addWindowGeometry, cubeaddonAddWindowGeometry);
1851 WRAP (cas, s, drawWindow, cubeaddonDrawWindow);
1852 WRAP (cas, s, drawWindowTexture, cubeaddonDrawWindowTexture);
1853
1854
1855 WRAP (cas, cs, clearTargetOutput, cubeaddonClearTargetOutput);
1856 WRAP (cas, cs, getRotation, cubeaddonGetRotation);
1857 WRAP (cas, cs, checkOrientation, cubeaddonCheckOrientation);
1858 WRAP (cas, cs, shouldPaintViewport, cubeaddonShouldPaintViewport);
1859 WRAP (cas, cs, paintTop, cubeaddonPaintTop);
1860 WRAP (cas, cs, paintBottom, cubeaddonPaintBottom);
1861
1862 return TRUE;
1863 }
1864
1865 static void
cubeaddonFiniScreen(CompPlugin * p,CompScreen * s)1866 cubeaddonFiniScreen (CompPlugin *p,
1867 CompScreen *s)
1868 {
1869 CUBEADDON_SCREEN (s);
1870 CUBE_SCREEN (s);
1871
1872 if (cas->winNormals)
1873 free (cas->winNormals);
1874
1875 if (cas->tmpBox)
1876 free (cas->tmpBox);
1877
1878 XDestroyRegion (cas->tmpRegion);
1879
1880 UNWRAP (cas, s, paintTransformedOutput);
1881 UNWRAP (cas, s, paintOutput);
1882 UNWRAP (cas, s, donePaintScreen);
1883 UNWRAP (cas, s, addWindowGeometry);
1884 UNWRAP (cas, s, drawWindow);
1885 UNWRAP (cas, s, drawWindowTexture);
1886
1887 UNWRAP (cas, cs, clearTargetOutput);
1888 UNWRAP (cas, cs, getRotation);
1889 UNWRAP (cas, cs, checkOrientation);
1890 UNWRAP (cas, cs, shouldPaintViewport);
1891 UNWRAP (cas, cs, paintTop);
1892 UNWRAP (cas, cs, paintBottom);
1893
1894 free (cas);
1895 }
1896
1897 static Bool
cubeaddonInit(CompPlugin * p)1898 cubeaddonInit (CompPlugin *p)
1899 {
1900 CubeaddonDisplayPrivateIndex = allocateDisplayPrivateIndex ();
1901
1902 if (CubeaddonDisplayPrivateIndex < 0)
1903 return FALSE;
1904
1905 return TRUE;
1906 }
1907
1908 static void
cubeaddonFini(CompPlugin * p)1909 cubeaddonFini (CompPlugin *p)
1910 {
1911 freeDisplayPrivateIndex (CubeaddonDisplayPrivateIndex);
1912 }
1913
1914 static CompBool
cubeaddonInitObject(CompPlugin * p,CompObject * o)1915 cubeaddonInitObject (CompPlugin *p,
1916 CompObject *o)
1917 {
1918 static InitPluginObjectProc dispTab[] = {
1919 (InitPluginObjectProc) 0, /* InitCore */
1920 (InitPluginObjectProc) cubeaddonInitDisplay,
1921 (InitPluginObjectProc) cubeaddonInitScreen
1922 };
1923
1924 RETURN_DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), TRUE, (p, o));
1925 }
1926
1927 static void
cubeaddonFiniObject(CompPlugin * p,CompObject * o)1928 cubeaddonFiniObject (CompPlugin *p,
1929 CompObject *o)
1930 {
1931 static FiniPluginObjectProc dispTab[] = {
1932 (FiniPluginObjectProc) 0, /* FiniCore */
1933 (FiniPluginObjectProc) cubeaddonFiniDisplay,
1934 (FiniPluginObjectProc) cubeaddonFiniScreen
1935 };
1936
1937 DISPATCH (o, dispTab, ARRAY_SIZE (dispTab), (p, o));
1938 }
1939
1940 CompPluginVTable cubeaddonVTable = {
1941 "cubeaddon",
1942 0,
1943 cubeaddonInit,
1944 cubeaddonFini,
1945 cubeaddonInitObject,
1946 cubeaddonFiniObject,
1947 0,
1948 0
1949 };
1950
1951 CompPluginVTable *
getCompPluginInfo(void)1952 getCompPluginInfo (void)
1953 {
1954 return &cubeaddonVTable;
1955 }
1956