Merge lp:~compiz-team/compiz-expo-plugin/oneiric.fix_868121 into lp:compiz-expo-plugin

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~compiz-team/compiz-expo-plugin/oneiric.fix_868121
Merge into: lp:compiz-expo-plugin
Diff against target: 1716 lines (+1232/-89) (has conflicts)
6 files modified
expo.xml.in (+33/-11)
src/expo.cpp (+452/-77)
src/expo.h (+56/-1)
src/glow.cpp (+428/-0)
src/glow.h (+66/-0)
src/group_glow.h (+197/-0)
Text conflict in src/expo.cpp
To merge this branch: bzr merge lp:~compiz-team/compiz-expo-plugin/oneiric.fix_868121
Reviewer Review Type Date Requested Status
Sam Spilsbury Pending
Review via email: mp+78210@code.launchpad.net

This proposal supersedes a proposal from 2011-10-05.

Description of the change

Fix bug 868121

Ensure that windows are always painted at least once, make sure state is set and unset at the right points.

To post a comment you must log in.

Unmerged revisions

157. By Sam Spilsbury

Fix rendering glitches. Ensure that we always paint windows during a cycle
(eg, don't just set NO_CORE_INSTANCE_MASK when expo isn't active) and
make sure that state is correclty set and unset at the right points

156. By Sam Spilsbury

Don't scale up windows with titlebars, Fixes LP #864963

155. By Sam Spilsbury

Merge lp:~compiz-team/compiz-expo-plugin/oneiric.fix_clipping_issues

154. By Sam Spilsbury

Added expo plugin polish

153. By Sam Spilsbury

Revert all that

152. By Sam Spilsbury

Added glow

151. By Sam Spilsbury

Do the polka dots wrapping properly using OpenGL

150. By Sam Spilsbury

Perfect the fade animation

149. By Sam Spilsbury

Use the new texture tile, paint maximized windows to take up the space where
the panel was and paint dnd windows on top of all workspaces

148. By Sam Spilsbury

Add a small hack so that maximized windows will be stretched to fill the entire viewport so that there's no awkward gap at the top

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'expo.xml.in'
2--- expo.xml.in 2010-09-28 22:30:37 +0000
3+++ expo.xml.in 2011-10-05 08:01:34 +0000
4@@ -17,6 +17,7 @@
5 <plugin>wobbly</plugin>
6 <plugin>animation</plugin>
7 <plugin>wallpaper</plugin>
8+ <plugin>imgpng</plugin>
9 </relation>
10 </deps>
11 <options>
12@@ -25,7 +26,7 @@
13 <option name="expo_key" type="key">
14 <_short>Expo key</_short>
15 <_long>Engage wall expo mode key binding</_long>
16- <default>&lt;Super&gt;e</default>
17+ <default>&lt;Super&gt;s</default>
18 </option>
19 <option name="expo_button" type="button">
20 <_short>Expo button</_short>
21@@ -35,9 +36,6 @@
22 <option name="expo_edge" type="edge">
23 <_short>Expo edge</_short>
24 <_long>Engage wall expo mode edge binding</_long>
25- <default>
26- <edge name="TopLeft"/>
27- </default>
28 </option>
29 <option name="double_click_time" type="int">
30 <_short>Double click time</_short>
31@@ -80,7 +78,7 @@
32 <option name="zoom_time" type="float">
33 <_short>Zoom time</_short>
34 <_long>Duration of the zoomout animation</_long>
35- <default>0.5</default>
36+ <default>0.3</default>
37 <min>0.1</min>
38 <max>5.0</max>
39 <precision>0.1</precision>
40@@ -131,10 +129,24 @@
41 <_name>Curve</_name>
42 </desc>
43 </option>
44+ <option name="x_offset" type="int">
45+ <_short>X Space</_short>
46+ <_long> Left Side screen space of expo in pixels</_long>
47+ <min>-1680</min>
48+ <max>1680</max>
49+ <default>64</default>
50+ </option>
51+ <option name="y_offset" type="int">
52+ <_short>Y Space</_short>
53+ <_long> Top Side screen space of expo in pixels</_long>
54+ <min>-100</min>
55+ <max>100</max>
56+ <default>24</default>
57+ </option>
58 <option name="distance" type="float">
59 <_short>Distance</_short>
60 <_long>Distance of the expo wall</_long>
61- <default>0.0</default>
62+ <default>0.005</default>
63 <min>0.0</min>
64 <max>1.0</max>
65 <precision>0.01</precision>
66@@ -142,7 +154,7 @@
67 <option name="vp_distance" type="float">
68 <_short>Viewport distance</_short>
69 <_long>Distance between viewports</_long>
70- <default>0.10</default>
71+ <default>0.2</default>
72 <min>0.0</min>
73 <max>1.0</max>
74 <precision>0.01</precision>
75@@ -193,7 +205,7 @@
76 <option name="vp_brightness" type="float">
77 <_short>Brightness</_short>
78 <_long>Inactive viewport brightness.</_long>
79- <default>75.0</default>
80+ <default>40.0</default>
81 <min>0.0</min>
82 <max>100.0</max>
83 <precision>0.1</precision>
84@@ -201,18 +213,28 @@
85 <option name="vp_saturation" type="float">
86 <_short>Saturation</_short>
87 <_long>Inactive viewport saturation.</_long>
88- <default>100.0</default>
89+ <default>40.0</default>
90 <min>0.0</min>
91 <max>100.0</max>
92 <precision>0.1</precision>
93 </option>
94+ <option name="selected_color" type="color">
95+ <_short>Selected Color</_short>
96+ <_long>Color to use when highlighting the selected viewport</_long>
97+ <default>
98+ <red>0xfbfb</red>
99+ <green>0x8b8b</green>
100+ <blue>0x0</blue>
101+ <alpha>0xffff</alpha>
102+ </default>
103+ </option>
104 </subgroup>
105 <subgroup>
106 <short>Reflection</short>
107 <option name="reflection" type="bool">
108 <_short>Reflection</_short>
109 <_long>Show a reflection of the viewports on the ground</_long>
110- <default>true</default>
111+ <default>false</default>
112 </option>
113 <option name="ground_color1" type="color">
114 <_short>Ground color(near)</_short>
115@@ -245,7 +267,7 @@
116 <option name="scale_factor" type="float">
117 <_short>Reflection Scale</_short>
118 <_long>Scale factor of the expo wall reflection</_long>
119- <default>0.75</default>
120+ <default>1.0</default>
121 <min>0.0</min>
122 <max>2.0</max>
123 <precision>0.01</precision>
124
125=== added directory 'images'
126=== added file 'images/glow_outline.png'
127Binary files images/glow_outline.png 1970-01-01 00:00:00 +0000 and images/glow_outline.png 2011-10-05 08:01:34 +0000 differ
128=== added file 'images/texture_tile.png'
129Binary files images/texture_tile.png 1970-01-01 00:00:00 +0000 and images/texture_tile.png 2011-10-05 08:01:34 +0000 differ
130=== modified file 'src/expo.cpp'
131--- src/expo.cpp 2011-09-20 14:38:27 +0000
132+++ src/expo.cpp 2011-10-05 08:01:34 +0000
133@@ -26,6 +26,7 @@
134 #include "expo.h"
135 #include <math.h>
136 #include <GL/glu.h>
137+#include <X11/cursorfont.h>
138
139 COMPIZ_PLUGIN_20090315 (expo, ExpoPluginVTable);
140
141@@ -67,11 +68,10 @@
142
143 if (dndState == DnDDuring || dndState == DnDStart)
144 {
145- if (dndWindow)
146+ if (dndWindows.size ())
147 finishWindowMovement ();
148
149 dndState = DnDNone;
150- dndWindow = NULL;
151
152 action->setState (action->state () & CompAction::StateInitButton);
153 cScreen->damageScreen ();
154@@ -107,7 +107,6 @@
155 clickTime = 0;
156
157 dndState = DnDNone;
158- dndWindow = NULL;
159
160 selectedVp = screen->vp ();
161 lastSelectedVp = screen->vp ();
162@@ -151,7 +150,6 @@
163 vpUpdateMode = VPUpdateMouseOver;
164
165 dndState = DnDNone;
166- dndWindow = NULL;
167
168 screen->removeAction (&optionGetDndButton ());
169 screen->removeAction (&optionGetExitButton ());
170@@ -266,53 +264,41 @@
171 void
172 ExpoScreen::finishWindowMovement ()
173 {
174- dndWindow->syncPosition ();
175- dndWindow->ungrabNotify ();
176-
177- screen->moveViewport (screen->vp ().x () - selectedVp.x (),
178- screen->vp ().y () - selectedVp.y (), true);
179-
180- /* update saved window attributes in case we moved the
181- window to a new viewport */
182- if (dndWindow->saveMask () & CWX)
183- {
184- dndWindow->saveWc ().x = dndWindow->saveWc ().x % screen->width ();
185- if (dndWindow->saveWc ().x < 0)
186- dndWindow->saveWc ().x += screen->width ();
187- }
188- if (dndWindow->saveMask () & CWY)
189- {
190- dndWindow->saveWc ().y = dndWindow->saveWc ().y % screen->height ();
191- if (dndWindow->saveWc ().y < 0)
192- dndWindow->saveWc ().y += screen->height ();
193- }
194-
195- /* update window attibutes to make sure a moved maximized window
196- is properly snapped to the work area */
197- if (dndWindow->state () & MAXIMIZE_STATE)
198- dndWindow->updateAttributes (CompStackingUpdateModeNone);
199-
200-#if 0 /* FIXME: obsolete in the meantime? */
201- {
202- int lastOutput;
203- int centerX, centerY;
204-
205- /* make sure we snap to the correct output */
206- lastOutput = s->currentOutputDev;
207- centerX = (WIN_X (w) + WIN_W (w) / 2) % s->width;
208- if (centerX < 0)
209- centerX += s->width;
210- centerY = (WIN_Y (w) + WIN_H (w) / 2) % s->height;
211- if (centerY < 0)
212- centerY += s->height;
213-
214- s->currentOutputDev = outputDeviceForPoint (s, centerX, centerY);
215-
216- updateWindowAttributes (w, CompStackingUpdateModeNone);
217-
218- s->currentOutputDev = lastOutput;
219- }
220-#endif
221+ foreach (CompWindow *dndWindow, dndWindows)
222+ {
223+ if (dndWindow->grabbed ())
224+ {
225+ dndWindow->syncPosition ();
226+ dndWindow->ungrabNotify ();
227+
228+ screen->updateGrab (grabIndex, None);
229+
230+ screen->moveViewport (screen->vp ().x () - selectedVp.x (),
231+ screen->vp ().y () - selectedVp.y (), true);
232+
233+ /* update saved window attributes in case we moved the
234+ window to a new viewport */
235+ if (dndWindow->saveMask () & CWX)
236+ {
237+ dndWindow->saveWc ().x = dndWindow->saveWc ().x % screen->width ();
238+ if (dndWindow->saveWc ().x < 0)
239+ dndWindow->saveWc ().x += screen->width ();
240+ }
241+ if (dndWindow->saveMask () & CWY)
242+ {
243+ dndWindow->saveWc ().y = dndWindow->saveWc ().y % screen->height ();
244+ if (dndWindow->saveWc ().y < 0)
245+ dndWindow->saveWc ().y += screen->height ();
246+ }
247+
248+ /* update window attibutes to make sure a moved maximized window
249+ is properly snapped to the work area */
250+ if (dndWindow->state () & MAXIMIZE_STATE)
251+ dndWindow->updateAttributes (CompStackingUpdateModeNone);
252+ }
253+ }
254+
255+ dndWindows.clear ();
256 }
257
258 void
259@@ -383,6 +369,26 @@
260 screen->handleEvent (event);
261 }
262
263+bool
264+ExpoScreen::windowsOnVp (CompPoint &p)
265+{
266+ foreach (CompWindow *w, screen->clientList (true))
267+ {
268+ CompPoint viewport;
269+
270+ screen->viewportForGeometry (w->geometry (), viewport);
271+
272+ if (viewport == p&&
273+ w->type () != CompWindowTypeDesktopMask &&
274+ w->type () != CompWindowTypeDockMask)
275+ {
276+ return true;
277+ }
278+ }
279+
280+ return false;
281+}
282+
283 void
284 ExpoScreen::preparePaint (int msSinceLastPaint)
285 {
286@@ -411,8 +417,9 @@
287 for (j = 0; j < (unsigned int) screen->vpSize ().height (); j++)
288 {
289 vp = (j * screen->vpSize ().width ()) + i;
290+ CompPoint vpPos = CompPoint (i, j);
291
292- if (CompPoint (i, j) == selectedVp)
293+ if (windowsOnVp (vpPos))
294 vpActivity[vp] = MIN (1.0, vpActivity[vp] + val);
295 else
296 vpActivity[vp] = MAX (0.0, vpActivity[vp] - val);
297@@ -527,6 +534,7 @@
298 screen->removeGrab (grabIndex, NULL);
299 grabIndex = 0;
300 updateWraps (false);
301+ cScreen->damageScreen ();
302 }
303
304 cScreen->donePaint ();
305@@ -534,10 +542,18 @@
306 switch (dndState) {
307 case DnDDuring:
308 {
309- if (dndWindow)
310- dndWindow->move (newCursor.x () - prevCursor.x (),
311- newCursor.y () - prevCursor.y (),
312- optionGetExpoImmediateMove ());
313+ if (dndWindows.size ())
314+ {
315+ foreach (CompWindow *dndWindow, dndWindows)
316+ {
317+ if (dndWindow->grabbed ())
318+ {
319+ dndWindow->move (newCursor.x () - prevCursor.x (),
320+ newCursor.y () - prevCursor.y (),
321+ optionGetExpoImmediateMove ());
322+ }
323+ }
324+ }
325
326 prevCursor = newCursor;
327 cScreen->damageScreen ();
328@@ -602,12 +618,16 @@
329 break;
330
331 dndState = DnDDuring;
332- dndWindow = w;
333+
334+ if (std::find (dndWindows.begin (), dndWindows.end (), w) == dndWindows.end ())
335+ dndWindows.push_back (w);
336
337 w->grabNotify (nx, ny, 0,
338 CompWindowGrabMoveMask |
339 CompWindowGrabButtonMask);
340
341+ screen->updateGrab (grabIndex, mMoveCursor);
342+
343 w->raise ();
344 w->moveInputFocusTo ();
345 break;
346@@ -693,6 +713,124 @@
347 }
348
349 void
350+ExpoScreen::paintViewport (const GLScreenPaintAttrib& attrib,
351+ const GLMatrix& transform,
352+ const CompRegion& region,
353+ CompOutput *output,
354+ unsigned int mask,
355+ CompPoint vpPos,
356+ GLVector &vpCamPos,
357+ bool reflection)
358+{
359+ GLMatrix sTransform (transform);
360+ GLMatrix sTransform2, sTransform3;
361+ float sx = (float) screen->width () / output->width ();
362+ float sy = (float) screen->height () / output->height ();
363+ float vpp;
364+ float progress = sigmoidProgress (expoCam);
365+ unsigned int vp;
366+ CompPoint vpSize (screen->vpSize ().width (), screen->vpSize ().height ());
367+
368+ const float gapY = optionGetVpDistance () * 0.1f * expoCam;
369+ const float gapX = optionGetVpDistance () * 0.1f * screen->height () /
370+ screen->width () * expoCam;
371+
372+ /* not sure this will work with different resolutions */
373+ sTransform.translate (0.0, MAX (0, vpPos.y ()) * -(sy + gapY), 0.0f);
374+
375+ sTransform2 = sTransform;
376+
377+ /* not sure this will work with different resolutions */
378+ if (optionGetDeform () != DeformCurve)
379+ sTransform2.translate (MAX (0, vpPos.x ()) * (sx + gapX), 0.0f, 0.0);
380+
381+
382+ if (optionGetExpoAnimation () == ExpoAnimationVortex)
383+ sTransform2.rotate (360 * expoCam,
384+ 0.0f, 1.0f, 2.0f * expoCam);
385+
386+ sTransform3 = sTransform2;
387+
388+ sTransform3.translate (output->x () / output->width (),
389+ -output->y () / output->height (), 0.0);
390+
391+ cScreen->setWindowPaintOffset ((screen->vp ().x () - vpPos.x ()) *
392+ screen->width (),
393+ (screen->vp ().y () - vpPos.y ()) *
394+ screen->height ());
395+
396+ vp = (vpPos.y () * vpSize.x ()) + vpPos.x ();
397+
398+ vpp = (expoCam * vpActivity[vp]) + (1 - expoCam);
399+ vpp = sigmoidProgress (vpp);
400+
401+ vpBrightness = vpp + ((1.0 - vpp) *
402+ optionGetVpBrightness () / 100.0);
403+ vpSaturation = vpp + ((1.0 - vpp) *
404+ optionGetVpSaturation () / 100.0);
405+
406+ paintingVp = vpPos;
407+
408+ if (optionGetDeform () == DeformCurve)
409+ {
410+ float rotateX;
411+
412+ sTransform3.translate (-vpCamPos[GLVector::x], 0.0f,
413+ curveDistance - DEFAULT_Z_CAMERA);
414+
415+ rotateX = -vpPos.x () + interpolate (((float) vpSize.x () / 2.0) - 0.5,
416+ screen->vp ().x (), progress);
417+
418+ sTransform3.rotate (curveAngle * rotateX, 0.0, 1.0, 0.0);
419+
420+ sTransform3.translate (vpCamPos[GLVector::x], 0.0f,
421+ DEFAULT_Z_CAMERA - curveDistance);
422+ }
423+
424+ if (paintingDndWindow)
425+ cScreen->getWindowPaintListSetEnabled (this, true);
426+ gScreen->glPaintTransformedOutput (attrib, sTransform3,
427+ screen->region (), output,
428+ mask);
429+
430+ if (paintingDndWindow)
431+ cScreen->getWindowPaintListSetEnabled (this, false);
432+
433+ if (!reflection && !paintingDndWindow)
434+ {
435+ int cursor[2] = { pointerX, pointerY };
436+
437+ invertTransformedVertex (attrib, sTransform3,
438+ output, cursor);
439+
440+ if ((cursor[0] > 0) && (cursor[0] < (int) screen->width ()) &&
441+ (cursor[1] > 0) && (cursor[1] < (int) screen->height ()))
442+ {
443+ newCursor.setX (vpPos.x () * screen->width () + cursor[0]);
444+ newCursor.setY (vpPos.y () * screen->height () + cursor[1]);
445+
446+ if (anyClick || dndState != DnDNone)
447+ {
448+ /* Used to save last viewport interaction was in */
449+ selectedVp = vpPos;
450+ anyClick = false;
451+ }
452+ }
453+ }
454+
455+ /* Calculate the current viewport size */
456+ int tl[2] = { 0, 0 };
457+ int br[2] = { screen->width (), screen->height () };
458+
459+ invertTransformedVertex (attrib, sTransform3, output, tl);
460+ invertTransformedVertex (attrib, sTransform3, output, br);
461+
462+ viewport_size = CompSize (br[0] - tl[0], br[1] - tl[1]);
463+
464+ cScreen->setWindowPaintOffset (0, 0);
465+}
466+
467+void
468 ExpoScreen::paintWall (const GLScreenPaintAttrib& attrib,
469 const GLMatrix& transform,
470 const CompRegion& region,
471@@ -701,13 +839,11 @@
472 bool reflection)
473 {
474 GLMatrix sTransformW, sTransform (transform);
475- int i, j, vp;
476 GLenum oldFilter = gScreen->textureFilter ();
477-
478- float sx = (float) screen->width () / output->width ();
479- float sy = (float) screen->height () / output->height ();
480+ float sx = (float) screen->width () / output->width ();
481+ float sy = (float) screen->height () / output->height ();
482 float biasZ;
483- float oScale, rotation = 0.0f, progress, vpp;
484+ float oScale, rotation = 0.0f, progress;
485 float aspectX = 1.0f, aspectY = 1.0f;
486 GLVector cam;
487 CompPoint vpSize (screen->vpSize ().width (), screen->vpSize ().height ());
488@@ -837,9 +973,28 @@
489 sTransform.rotate (rotation, 0.0f, 1.0f, 0.0f);
490 sTransform.scale (aspectX, aspectY, 1.0);
491
492+ float xoffset = 0.0;
493+ float yoffset = 0.0;
494+ float xadjs = 1.0f;
495+ float yadjs = 1.0f;
496+
497+ if (output->left () == 0)
498+ {
499+ xoffset = ((vpSize.x () * sx) / ((float) output->width ()) * (optionGetXOffset ()) * sigmoidProgress (expoCam));
500+ xadjs = 1.0f - ((float) (optionGetXOffset ()) / (float) (output->width ())) * sigmoidProgress (expoCam);
501+ }
502+
503+ if (output->top () == 0)
504+ {
505+ yoffset = ((vpSize.y () * sy) / ((float) output->height ()) * (optionGetYOffset ()) * sigmoidProgress (expoCam));
506+
507+ yadjs = 1.0f - ((float) (optionGetYOffset ()) / (float) output->height ()) * sigmoidProgress (expoCam);
508+ }
509+
510 /* translate expo to center */
511- sTransform.translate (vpSize.x () * sx * -0.5,
512- vpSize.y () * sy * 0.5, 0.0f);
513+ sTransform.translate (vpSize.x () * sx * -0.5 + xoffset,
514+ vpSize.y () * sy * 0.5 - yoffset, 0.0f);
515+ sTransform.scale (xadjs, yadjs, 1.0f);
516
517 if (optionGetDeform () == DeformCurve)
518 sTransform.translate ((vpSize.x () - 1) * sx * 0.5, 0.0, 0.0);
519@@ -863,8 +1018,15 @@
520
521 expoActive = true;
522
523- for (j = 0; j < vpSize.y (); j++)
524+ for (int j = 0; j < screen->vpSize ().height (); j++)
525+ for (int i = 0; i < screen->vpSize().width (); i++)
526+ paintViewport (attrib, sTransform, region, output, mask, CompPoint (i, j), vpCamPos, reflection);
527+
528+ paintingDndWindow = true;
529+
530+ foreach (CompWindow *dndWindow, dndWindows)
531 {
532+<<<<<<< TREE
533 GLMatrix sTransform2 (sTransform), sTransform3;
534
535 for (i = 0; i < vpSize.x (); i++)
536@@ -945,8 +1107,23 @@
537
538 /* not sure this will work with different resolutions */
539 sTransform.translate (0.0, -(sy + gapY), 0.0f);
540+=======
541+ CompPoint vp;
542+
543+ screen->viewportForGeometry (dndWindow->geometry (), vp);
544+
545+ while (vp.x () < 0)
546+ vp.setX (screen->vpSize ().width () + vp.x ());
547+
548+ while (vp.y () < 0)
549+ vp.setY (screen->vpSize ().height () + vp.y ());
550+
551+ paintViewport (attrib, sTransform, region, output, mask, vp, vpCamPos, reflection);
552+>>>>>>> MERGE-SOURCE
553 }
554
555+ paintingDndWindow = false;
556+
557 glNormal3f (0.0, 0.0, -1.0);
558
559 if (reflection)
560@@ -1018,12 +1195,16 @@
561
562 expoActive = false;
563
564- cScreen->setWindowPaintOffset (0, 0);
565-
566 gScreen->glPaintTransformedOutputSetCurrentIndex (glPaintTransformedOutputIndex);
567 gScreen->setTextureFilter (oldFilter);
568 }
569
570+const CompWindowList &
571+ExpoScreen::getWindowPaintList ()
572+{
573+ return dndWindows;
574+}
575+
576 bool
577 ExpoScreen::glPaintOutput (const GLScreenPaintAttrib& attrib,
578 const GLMatrix& transform,
579@@ -1078,6 +1259,11 @@
580 const CompRegion& region,
581 unsigned int mask)
582 {
583+ GLMatrix wTransform (transform);
584+ CompPoint vp;
585+
586+ screen->viewportForGeometry (window->geometry (), vp);
587+
588 if (eScreen->expoCam == 0.0f)
589 return gWindow->glDraw (transform, fragment, region, mask);
590
591@@ -1106,8 +1292,11 @@
592 }
593 }
594
595- fA.setBrightness (fragment.getBrightness () * eScreen->vpBrightness);
596- fA.setSaturation (fragment.getSaturation () * eScreen->vpSaturation);
597+ if ((vp == eScreen->paintingVp || window->onAllViewports ()) && !eScreen->paintingDndWindow)
598+ {
599+ fA.setBrightness (fragment.getBrightness () * eScreen->vpBrightness);
600+ fA.setSaturation (fragment.getSaturation () * eScreen->vpSaturation);
601+ }
602 }
603 else
604 {
605@@ -1118,7 +1307,81 @@
606 (1 - sigmoidProgress (eScreen->expoCam)));
607 }
608
609- return gWindow->glDraw (transform, fA, region, mask);
610+ bool status = gWindow->glDraw (wTransform, fA, region, mask);
611+
612+ if (window->type () & CompWindowTypeDesktopMask)
613+ {
614+ /* We want to set the geometry of the polka dots to the window
615+ * region */
616+ CompRegion reg = CompRegion (0, 0, window->width (), window->height ());
617+
618+ foreach(GLTexture * tex, eScreen->polkadots_texture)
619+ {
620+ GLTexture::MatrixList matl;
621+ GLTexture::Matrix mat = tex->matrix();
622+ CompRegion paintRegion(region);
623+
624+ /* We can reset the window geometry since it will be
625+ * re-added later */
626+ gWindow->geometry().reset();
627+
628+ float xScale = screen->width () / (float) eScreen->viewport_size.width ();
629+ float yScale = screen->height () / (float) eScreen->viewport_size.height ();
630+
631+ mat.xx *= xScale;
632+ mat.yy *= yScale;
633+
634+ /* Not sure what this does, but it is necessary
635+ * (adjusts for scale?) */
636+ mat.x0 -= mat.xx * reg.boundingRect().x1();
637+ mat.y0 -= mat.yy * reg.boundingRect().y1();
638+
639+ matl.push_back(mat);
640+
641+ if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
642+ paintRegion = infiniteRegion;
643+
644+ /* Now allow plugins to mess with the geometry of our
645+ * dim (so we get a nice render for things like
646+ * wobbly etc etc */
647+ gWindow->glAddGeometry(matl, reg, paintRegion);
648+
649+ /* Did it succeed? */
650+ if (gWindow->geometry().vertices)
651+ {
652+ unsigned int glDrawTextureIndex = gWindow->glDrawTextureGetCurrentIndex();
653+ fA.setOpacity (fragment.getOpacity () * (((1.0 - eScreen->vpBrightness) + (1.0 - eScreen->vpSaturation) / 2.0)));
654+ /* Texture rendering set-up */
655+ eScreen->gScreen->setTexEnvMode(GL_MODULATE);
656+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
657+ /* Draw the dim texture with all of it's modified
658+ * geometry glory */
659+ gWindow->glDrawTextureSetCurrentIndex(MAXSHORT);
660+ gWindow->glDrawTexture(tex, fA, mask | PAINT_WINDOW_BLEND_MASK
661+ | PAINT_WINDOW_TRANSLUCENT_MASK |
662+ PAINT_WINDOW_TRANSFORMED_MASK);
663+ gWindow->glDrawTextureSetCurrentIndex(glDrawTextureIndex);
664+ /* Texture rendering tear-down */
665+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
666+ eScreen->gScreen->setTexEnvMode(GL_REPLACE);
667+ }
668+ }
669+
670+ /* Paint the outline */
671+ if (mGlowQuads && eScreen->paintingVp == eScreen->selectedVp)
672+ {
673+ if (region.numRects ())
674+ {
675+ /* reset geometry and paint */
676+ gWindow->geometry ().reset ();
677+
678+ paintGlow (fragment, infiniteRegion, mask);
679+ }
680+ }
681+
682+ }
683+ return status;
684+
685 }
686
687 #define EXPO_GRID_SIZE 100
688@@ -1260,11 +1523,17 @@
689 const CompRegion& region,
690 unsigned int mask)
691 {
692+ GLMatrix wTransform (transform);
693+ GLWindowPaintAttrib wAttrib (attrib);
694+ CompRegion clip (region);
695+
696 if (eScreen->expoActive)
697 {
698- float opacity = 1.0;
699- bool hide;
700- bool zoomAnim;
701+ float opacity = 1.0;
702+ bool hide;
703+ bool zoomAnim;
704+ CompPoint vp;
705+ screen->viewportForGeometry (window->geometry (), vp);
706
707 zoomAnim = eScreen->optionGetExpoAnimation () ==
708 ExpoScreen::ExpoAnimationZoom;
709@@ -1293,9 +1562,48 @@
710
711 if (opacity <= 0)
712 mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
713+ else
714+ wAttrib.opacity = wAttrib.opacity * opacity;
715+
716+ /* Stretch maximized windows a little so that you don't
717+ * have an awkward gap */
718+
719+ if (window->state () & MAXIMIZE_STATE &&
720+ !window->border ().top)
721+ {
722+ CompOutput *o = &screen->outputDevs ()[screen->outputDeviceForGeometry(window->geometry())];
723+ float yS = 1.0 + ((o->height () / (float) window->height ()) - 1.0f) * sigmoidProgress (eScreen->expoCam);
724+ wTransform.translate (window->x () + window->width () / 2,
725+ window->y () + window->height (),
726+ 0.0f);
727+ wTransform.scale (1.0f, yS, 1.0f);
728+ wTransform.translate (-(window->x () + window->width () / 2),
729+ -(window->y () + window->height ()),
730+ 0.0f);
731+
732+ if (eScreen->paintingVp != vp)
733+ mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
734+
735+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
736+ }
737+
738+ if (std::find (eScreen->dndWindows.begin(), eScreen->dndWindows.end (), window) != eScreen->dndWindows.end ())
739+ {
740+ if (!eScreen->paintingDndWindow)
741+ {
742+ mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
743+ }
744+ else
745+ {
746+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
747+ clip = infiniteRegion;
748+ }
749+ }
750 }
751
752- return gWindow->glPaint (attrib, transform, region, mask);
753+ bool status = gWindow->glPaint (wAttrib, wTransform, clip, mask);
754+
755+ return status;
756 }
757
758 bool
759@@ -1324,7 +1632,7 @@
760 expoActive (false),
761 expoMode (false),
762 dndState (DnDNone),
763- dndWindow (NULL),
764+ dndWindows (0),
765 origVp (s->vp ()),
766 selectedVp (s->vp ()),
767 lastSelectedVp (s->vp ()),
768@@ -1332,13 +1640,22 @@
769 clickTime (0),
770 doubleClick (false),
771 vpNormals (360 * 3),
772- grabIndex (0)
773+ grabIndex (0),
774+ paintingDndWindow (false),
775+ mGlowTextureProperties (&glowTextureProperties)
776 {
777+ CompString fname;
778+ CompString pname = "expo";
779+ CompSize size;
780+
781+
782 leftKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Left"));
783 rightKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Right"));
784 upKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Up"));
785 downKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Down"));
786
787+ mMoveCursor = XCreateFontCursor (screen->dpy (), XC_fleur);
788+
789 EXPOINITBIND (ExpoKey, doExpo);
790 EXPOTERMBIND (ExpoKey, termExpo);
791 EXPOINITBIND (ExpoButton, doExpo);
792@@ -1355,6 +1672,47 @@
793 ScreenInterface::setHandler (screen, false);
794 CompositeScreenInterface::setHandler (cScreen, false);
795 GLScreenInterface::setHandler (gScreen, false);
796+
797+ outline_texture = GLTexture::imageDataToTexture (mGlowTextureProperties->textureData,
798+ CompSize (mGlowTextureProperties->textureSize,
799+ mGlowTextureProperties->textureSize),
800+ GL_RGBA, GL_UNSIGNED_BYTE);
801+ fname = "texture_tile.png";
802+ polkadots_texture = GLTexture::readImageToTexture (fname, pname, polkadots_texture_size);
803+
804+ if (polkadots_texture.empty ())
805+ compLogMessage ("expo", CompLogLevelWarn, "failed to bind image to texture");
806+ else
807+ {
808+ foreach (GLTexture *tex, polkadots_texture)
809+ {
810+ tex->enable (GLTexture::Good);
811+ glTexParameteri (tex->target (), GL_TEXTURE_WRAP_S, GL_REPEAT);
812+ glTexParameteri (tex->target (), GL_TEXTURE_WRAP_T, GL_REPEAT);
813+ tex->disable ();
814+ }
815+ }
816+}
817+
818+ExpoScreen::~ExpoScreen ()
819+{
820+ if (mMoveCursor)
821+ XFreeCursor (screen->dpy (), mMoveCursor);
822+}
823+
824+void
825+ExpoWindow::resizeNotify(int dx, int dy, int dw, int dh)
826+{
827+ window->resizeNotify (dx, dy, dw, dh);
828+
829+ /* mGlowQuads contains positional info, so we need to recalc that */
830+ if (mGlowQuads)
831+ {
832+ /* FIXME: we need to find a more multitexture friendly way
833+ * of doing this */
834+ GLTexture::Matrix tMat = eScreen->outline_texture.at (0)->matrix ();
835+ computeGlowQuads (&tMat);
836+ }
837 }
838
839 ExpoWindow::ExpoWindow (CompWindow *w) :
840@@ -1362,10 +1720,27 @@
841 window (w),
842 cWindow (CompositeWindow::get (w)),
843 gWindow (GLWindow::get (w)),
844- eScreen (ExpoScreen::get (screen))
845+ eScreen (ExpoScreen::get (screen)),
846+ mGlowQuads (NULL)
847 {
848 CompositeWindowInterface::setHandler (cWindow, false);
849 GLWindowInterface::setHandler (gWindow, false);
850+ WindowInterface::setHandler (window, true);
851+
852+ if (window->type () & CompWindowTypeDesktopMask)
853+ {
854+ foreach (GLTexture *tex, eScreen->outline_texture)
855+ {
856+ GLTexture::Matrix mat = tex->matrix ();
857+ computeGlowQuads (&mat);
858+ }
859+ }
860+}
861+
862+ExpoWindow::~ExpoWindow ()
863+{
864+ eScreen->dndWindows.remove (window);
865+ computeGlowQuads (NULL);
866 }
867
868 bool
869
870=== modified file 'src/expo.h'
871--- src/expo.h 2011-09-20 14:38:27 +0000
872+++ src/expo.h 2011-10-05 08:01:34 +0000
873@@ -25,11 +25,21 @@
874
875 #include <core/core.h>
876 #include <core/pluginclasshandler.h>
877+#include <cairo.h>
878+#include <cairo-xlib-xrender.h>
879
880 #include <composite/composite.h>
881 #include <opengl/opengl.h>
882
883 #include "expo_options.h"
884+#include "glow.h"
885+
886+#define WIN_REAL_X(w) (w->x () - w->border ().left)
887+#define WIN_REAL_Y(w) (w->y () - w->border ().top)
888+#define WIN_REAL_WIDTH(w) (w->width () + 2 * w->geometry ().border () + \
889+ w->border ().left + w->border ().right)
890+#define WIN_REAL_HEIGHT(w) (w->height () + 2 * w->geometry ().border () + \
891+ w->border ().top + w->border ().bottom)
892
893 class ExpoScreen :
894 public ScreenInterface,
895@@ -40,6 +50,7 @@
896 {
897 public:
898 ExpoScreen (CompScreen *);
899+ ~ExpoScreen ();
900
901 void handleEvent (XEvent *);
902
903@@ -53,6 +64,8 @@
904 const GLMatrix&, const CompRegion&,
905 CompOutput *, unsigned int);
906
907+ const CompWindowList & getWindowPaintList ();
908+
909 bool dndInit (CompAction *, CompAction::State, CompOption::Vector&);
910 bool dndFini (CompAction *, CompAction::State, CompOption::Vector&);
911 bool doExpo (CompAction *, CompAction::State, CompOption::Vector&);
912@@ -61,6 +74,8 @@
913 bool nextVp (CompAction *, CompAction::State, CompOption::Vector&);
914 bool prevVp (CompAction *, CompAction::State, CompOption::Vector&);
915
916+ CompPoint currentViewport ();
917+
918 typedef enum {
919 DnDNone,
920 DnDDuring,
921@@ -81,7 +96,7 @@
922 bool expoMode;
923
924 DnDState dndState;
925- CompWindow *dndWindow;
926+ CompWindowList dndWindows;
927
928 CompPoint prevCursor;
929 CompPoint newCursor;
930@@ -112,6 +127,17 @@
931
932 CompScreen::GrabHandle grabIndex;
933
934+ GLTexture::List polkadots_texture;
935+ CompSize polkadots_texture_size;
936+ CompSize viewport_size;
937+
938+ GLTexture::List outline_texture;
939+ CompSize outline_texture_size;
940+
941+ bool paintingDndWindow;
942+
943+ const GlowTextureProperties *mGlowTextureProperties;
944+
945 private:
946 void moveFocusViewport (int, int);
947 void finishWindowMovement ();
948@@ -122,22 +148,39 @@
949 void paintWall (const GLScreenPaintAttrib&, const GLMatrix&,
950 const CompRegion&, CompOutput *, unsigned int, bool);
951
952+ void paintViewport (const GLScreenPaintAttrib& attrib,
953+ const GLMatrix& transform,
954+ const CompRegion& region,
955+ CompOutput *output,
956+ unsigned int mask,
957+ CompPoint vpPos,
958+ GLVector &vpCamPos,
959+ bool reflection);
960+
961+ bool windowsOnVp (CompPoint &p);
962+
963 KeyCode leftKey;
964 KeyCode rightKey;
965 KeyCode upKey;
966 KeyCode downKey;
967+
968+ Cursor mMoveCursor;
969 };
970
971 class ExpoWindow :
972 public CompositeWindowInterface,
973 public GLWindowInterface,
974+ public WindowInterface,
975 public PluginClassHandler<ExpoWindow, CompWindow>
976 {
977 public:
978 ExpoWindow (CompWindow *);
979+ ~ExpoWindow ();
980
981 bool damageRect (bool, const CompRect&);
982
983+ void resizeNotify (int dx, int dy, int dw, int dh);
984+
985 bool glDraw (const GLMatrix&, GLFragment::Attrib&,
986 const CompRegion&, unsigned int);
987 bool glPaint (const GLWindowPaintAttrib&, const GLMatrix&,
988@@ -148,10 +191,22 @@
989 void glDrawTexture (GLTexture *, GLFragment::Attrib& attrib,
990 unsigned int);
991
992+ void
993+ paintGlow (GLFragment::Attrib &attrib,
994+ const CompRegion &paintRegion,
995+ unsigned int mask);
996+
997+ void
998+ computeGlowQuads (GLTexture::Matrix *matrix);
999+
1000 CompWindow *window;
1001 CompositeWindow *cWindow;
1002 GLWindow *gWindow;
1003 ExpoScreen *eScreen;
1004+
1005+ float dndOpacity;
1006+
1007+ GlowQuad *mGlowQuads;
1008 };
1009
1010 class ExpoPluginVTable :
1011
1012=== added file 'src/glow.cpp'
1013--- src/glow.cpp 1970-01-01 00:00:00 +0000
1014+++ src/glow.cpp 2011-10-05 08:01:34 +0000
1015@@ -0,0 +1,428 @@
1016+/**
1017+ *
1018+ * Compiz group plugin
1019+ *
1020+ * glow.cpp
1021+ *
1022+ * Copyright : (C) 2006-2010 by Patrick Niklaus, Roi Cohen,
1023+ * Danny Baumann, Sam Spilsbury
1024+ * Authors: Patrick Niklaus <patrick.niklaus@googlemail.com>
1025+ * Roi Cohen <roico.beryl@gmail.com>
1026+ * Danny Baumann <maniac@opencompositing.org>
1027+ * Sam Spilsbury <smspillaz@gmail.com>
1028+ *
1029+ *
1030+ * This program is free software; you can redistribute it and/or
1031+ * modify it under the terms of the GNU General Public License
1032+ * as published by the Free Software Foundation; either version 2
1033+ * of the License, or (at your option) any later version.
1034+ *
1035+ * This program is distributed in the hope that it will be useful,
1036+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1037+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1038+ * GNU General Public License for more details.
1039+ *
1040+ **/
1041+
1042+#include "expo.h"
1043+#include "group_glow.h"
1044+
1045+const GlowTextureProperties glowTextureProperties = {
1046+ /* GlowTextureRectangular */
1047+ glowTexRect, 32, 21
1048+};
1049+
1050+/*
1051+ * GroupWindow::paintGlow
1052+ *
1053+ * Takes our glow texture, stretches the appropriate positions in the glow texture,
1054+ * adds those geometries (so plugins like wobby and deform this texture correctly)
1055+ * and then draws the glow texture with this geometry (plugins like wobbly and friends
1056+ * will automatically deform the texture based on our set geometry)
1057+ */
1058+
1059+void
1060+ExpoWindow::paintGlow (GLFragment::Attrib &attrib,
1061+ const CompRegion &paintRegion,
1062+ unsigned int mask)
1063+{
1064+ CompRegion reg;
1065+ int i;
1066+
1067+ /* There are 8 glow parts of the glow texture which we wish to paint
1068+ * separately with different transformations
1069+ */
1070+ for (i = 0; i < NUM_GLOWQUADS; i++)
1071+ {
1072+ /* Using precalculated quads here */
1073+ reg = CompRegion (mGlowQuads[i].mBox);
1074+
1075+ if (reg.boundingRect ().x1 () < reg.boundingRect ().x2 () &&
1076+ reg.boundingRect ().y1 () < reg.boundingRect ().y2 ())
1077+ {
1078+ GLTexture::MatrixList matl;
1079+ reg = CompRegion (reg.boundingRect ().x1 (),
1080+ reg.boundingRect ().y1 (),
1081+ reg.boundingRect ().width (),
1082+ reg.boundingRect ().height ());
1083+
1084+ matl.push_back (mGlowQuads[i].mMatrix);
1085+ gWindow->glAddGeometry (matl, reg, paintRegion);
1086+ }
1087+ }
1088+
1089+ /* If the geometry add succeeded */
1090+ if (gWindow->geometry ().vertices)
1091+ {
1092+ GLFragment::Attrib fAttrib (attrib);
1093+ GLushort average;
1094+ GLushort color[3] = {MAXSHORT,
1095+ MAXSHORT,
1096+ MAXSHORT};
1097+
1098+ float alpha = (float) ExpoScreen::get (screen)->optionGetSelectedColorAlpha () / 65535.0f;
1099+
1100+ GLScreen::get (screen)->setTexEnvMode (GL_MODULATE);
1101+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1102+ glColor4f (((float) ExpoScreen::get (screen)->optionGetSelectedColorRed () / 65535.0f) * alpha,
1103+ ((float) ExpoScreen::get (screen)->optionGetSelectedColorGreen () / 65535.0f) * alpha,
1104+ ((float) ExpoScreen::get (screen)->optionGetSelectedColorBlue () / 65535.0f) * alpha,
1105+ alpha);
1106+
1107+ /* we use PAINT_WINDOW_TRANSFORMED_MASK here to force
1108+ the usage of a good texture filter */
1109+ foreach (GLTexture *tex, ExpoScreen::get (screen)->outline_texture)
1110+ {
1111+ gWindow->glDrawTexture (tex, fAttrib, mask |
1112+ PAINT_WINDOW_BLEND_MASK |
1113+ PAINT_WINDOW_TRANSLUCENT_MASK |
1114+ PAINT_WINDOW_TRANSFORMED_MASK);
1115+ }
1116+
1117+ glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1118+ GLScreen::get (screen)->setTexEnvMode (GL_REPLACE);
1119+ glColor4usv (defaultColor);
1120+ }
1121+}
1122+
1123+/*
1124+ * ExpoWindow::computeGlowQuads
1125+ *
1126+ * This function computures the matrix transformation required for each
1127+ * part of the glow texture which we wish to stretch to some rectangular
1128+ * dimentions
1129+ *
1130+ * There are eight quads different parts of the texture which we wish to
1131+ * paint here, the 4 sides and four corners, eg:
1132+ *
1133+ * ------------------
1134+ * | 1 | 4 | 6 |
1135+ * ------------- ------------------
1136+ * | 1 | 4 | 6 | | | | |
1137+ * ------------- | | | |
1138+ * | 2 | n | 7 | -> | 2 | n | 7 |
1139+ * ------------- | | | |
1140+ * | 3 | 5 | 8 | | | | |
1141+ * ------------- ------------------
1142+ * | 3 | 5 | 8 |
1143+ * ------------------
1144+ *
1145+ * In this example here, 2, 4, 5 and 7 are stretched, and the matrices for
1146+ * each quad rect adjusted accordingly for it's size compared to the original
1147+ * texture size.
1148+ *
1149+ * When we are adjusting the matrices here, the initial size of each corner has
1150+ * a size of of "1.0f", so according to 2x2 matrix rules,
1151+ * the scale factor is the inverse of the size of the glow (which explains
1152+ * while you will see here that matrix->xx is (1 / glowSize)
1153+ * where glowSize is the size the user specifies they want their glow to extend.
1154+ * (likewise, matrix->yy is adjusted similarly for corners and for top/bottom)
1155+ *
1156+ * matrix->x0 and matrix->y0 here are set to be the top left edge of the rect
1157+ * adjusted by the matrix scale factor (matrix->xx and matrix->yy)
1158+ *
1159+ */
1160+void
1161+ExpoWindow::computeGlowQuads (GLTexture::Matrix *matrix)
1162+{
1163+ CompRect *box;
1164+ int x1, x2, y1, y2;
1165+ GLTexture::Matrix *quadMatrix;
1166+ int glowSize, glowOffset;
1167+ CompWindow *w = window;
1168+
1169+ /* Passing NULL to this function frees the glow quads
1170+ * (so the window is not painted with glow) */
1171+
1172+ if (matrix)
1173+ {
1174+ if (!mGlowQuads)
1175+ mGlowQuads = new GlowQuad[NUM_GLOWQUADS];
1176+ if (!mGlowQuads)
1177+ return;
1178+ }
1179+ else
1180+ {
1181+ if (mGlowQuads)
1182+ {
1183+ delete[] mGlowQuads;
1184+ mGlowQuads = NULL;
1185+ }
1186+ return;
1187+ }
1188+
1189+ glowSize = 48;
1190+ glowOffset = (glowSize * ExpoScreen::get (screen)->mGlowTextureProperties->glowOffset /
1191+ ExpoScreen::get (screen)->mGlowTextureProperties->textureSize) + 1;
1192+
1193+ /* Top left corner */
1194+ box = &mGlowQuads[GLOWQUAD_TOPLEFT].mBox;
1195+ mGlowQuads[GLOWQUAD_TOPLEFT].mMatrix = *matrix;
1196+ quadMatrix = &mGlowQuads[GLOWQUAD_TOPLEFT].mMatrix;
1197+
1198+ /* Set the desired rect dimentions
1199+ * for the part of the glow we are painting */
1200+
1201+ x1 = WIN_REAL_X (w) - glowSize + glowOffset;
1202+ y1 = WIN_REAL_Y (w) - glowSize + glowOffset;
1203+
1204+ /* 2x2 Matrix here, adjust both x and y scale factors
1205+ * and the x and y position
1206+ *
1207+ * Scaling both parts of the texture in a positive direction
1208+ * here (left to right top to bottom)
1209+ *
1210+ * The base position (x0 and y0) here requires us to move backwards
1211+ * on the x and y dimentions by the calculated rect dimentions
1212+ * multiplied by the scale factors
1213+ */
1214+
1215+ quadMatrix->xx = 1.0f / glowSize;
1216+ quadMatrix->yy = 1.0f / (glowSize);
1217+ quadMatrix->x0 = -(x1 * quadMatrix->xx);
1218+ quadMatrix->y0 = -(y1 * quadMatrix->yy);
1219+
1220+ x2 = MIN (WIN_REAL_X (w) + glowOffset,
1221+ WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
1222+ y2 = MIN (WIN_REAL_Y (w) + glowOffset,
1223+ WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));
1224+
1225+ *box = CompRect (x1, y1, x2 - x1, y2 - y1);
1226+
1227+ /* Top right corner */
1228+ box = &mGlowQuads[GLOWQUAD_TOPRIGHT].mBox;
1229+ mGlowQuads[GLOWQUAD_TOPRIGHT].mMatrix = *matrix;
1230+ quadMatrix = &mGlowQuads[GLOWQUAD_TOPRIGHT].mMatrix;
1231+
1232+ /* Set the desired rect dimentions
1233+ * for the part of the glow we are painting */
1234+
1235+ x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
1236+ y1 = WIN_REAL_Y (w) - glowSize + glowOffset;
1237+ x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset;
1238+
1239+ /* 2x2 Matrix here, adjust both x and y scale factors
1240+ * and the x and y position
1241+ *
1242+ * Scaling the y part of the texture in a positive direction
1243+ * and the x part in a negative direction here
1244+ * (right to left top to bottom)
1245+ *
1246+ * The base position (x0 and y0) here requires us to move backwards
1247+ * on the y dimention and forwards on x by the calculated rect dimentions
1248+ * multiplied by the scale factors (since we are moving forward on x we
1249+ * need the inverse of that which is 1 - x1 * xx
1250+ */
1251+
1252+ quadMatrix->xx = -1.0f / glowSize;
1253+ quadMatrix->yy = 1.0f / glowSize;
1254+ quadMatrix->x0 = 1.0 - (x1 * quadMatrix->xx);
1255+ quadMatrix->y0 = -(y1 * quadMatrix->yy);
1256+
1257+ x1 = MAX (WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset,
1258+ WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
1259+ y2 = MIN (WIN_REAL_Y (w) + glowOffset,
1260+ WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));
1261+
1262+ *box = CompRect (x1, y1, x2 - x1, y2 - y1);
1263+
1264+ /* Bottom left corner */
1265+ box = &mGlowQuads[GLOWQUAD_BOTTOMLEFT].mBox;
1266+ mGlowQuads[GLOWQUAD_BOTTOMLEFT].mMatrix = *matrix;
1267+ quadMatrix = &mGlowQuads[GLOWQUAD_BOTTOMLEFT].mMatrix;
1268+
1269+ x1 = WIN_REAL_X (w) - glowSize + glowOffset;
1270+ y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
1271+ x2 = WIN_REAL_X (w) + glowOffset;
1272+ y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + glowSize - glowOffset;
1273+
1274+ /* 2x2 Matrix here, adjust both x and y scale factors
1275+ * and the x and y position
1276+ *
1277+ * Scaling the x part of the texture in a positive direction
1278+ * and the y part in a negative direction here
1279+ * (left to right bottom to top)
1280+ *
1281+ * The base position (x0 and y0) here requires us to move backwards
1282+ * on the x dimention and forwards on y by the calculated rect dimentions
1283+ * multiplied by the scale factors (since we are moving forward on x we
1284+ * need the inverse of that which is 1 - y1 * yy
1285+ */
1286+
1287+ quadMatrix->xx = 1.0f / glowSize;
1288+ quadMatrix->yy = -1.0f / glowSize;
1289+ quadMatrix->x0 = -(x1 * quadMatrix->xx);
1290+ quadMatrix->y0 = 1.0f - (y1 * quadMatrix->yy);
1291+
1292+ y1 = MAX (WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset,
1293+ WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));
1294+ x2 = MIN (WIN_REAL_X (w) + glowOffset,
1295+ WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
1296+
1297+ *box = CompRect (x1, y1, x2 - x1, y2 - y1);
1298+
1299+ /* Bottom right corner */
1300+ box = &mGlowQuads[GLOWQUAD_BOTTOMRIGHT].mBox;
1301+ mGlowQuads[GLOWQUAD_BOTTOMRIGHT].mMatrix = *matrix;
1302+ quadMatrix = &mGlowQuads[GLOWQUAD_BOTTOMRIGHT].mMatrix;
1303+
1304+ x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
1305+ y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
1306+ x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset;
1307+ y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + glowSize - glowOffset;
1308+
1309+ /* 2x2 Matrix here, adjust both x and y scale factors
1310+ * and the x and y position
1311+ *
1312+ * Scaling the both parts of the texture in a negative direction
1313+ * (right to left bottom to top)
1314+ *
1315+ * The base position (x0 and y0) here requires us to move forwards
1316+ * on both dimentions by the calculated rect dimentions
1317+ * multiplied by the scale factors
1318+ */
1319+
1320+ quadMatrix->xx = -1.0f / glowSize;
1321+ quadMatrix->yy = -1.0f / glowSize;
1322+ quadMatrix->x0 = 1.0 - (x1 * quadMatrix->xx);
1323+ quadMatrix->y0 = 1.0 - (y1 * quadMatrix->yy);
1324+
1325+ x1 = MAX (WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset,
1326+ WIN_REAL_X (w) + (WIN_REAL_WIDTH (w) / 2));
1327+ y1 = MAX (WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset,
1328+ WIN_REAL_Y (w) + (WIN_REAL_HEIGHT (w) / 2));
1329+
1330+ *box = CompRect (x1, y1, x2 - x1, y2 - y1);
1331+
1332+ /* Top edge */
1333+ box = &mGlowQuads[GLOWQUAD_TOP].mBox;
1334+ mGlowQuads[GLOWQUAD_TOP].mMatrix = *matrix;
1335+ quadMatrix = &mGlowQuads[GLOWQUAD_TOP].mMatrix;
1336+
1337+ x1 = WIN_REAL_X (w) + glowOffset;
1338+ y1 = WIN_REAL_Y (w) - glowSize + glowOffset;
1339+ x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
1340+ y2 = WIN_REAL_Y (w) + glowOffset;
1341+
1342+ /* 2x2 Matrix here, adjust both x and y scale factors
1343+ * and the x and y position
1344+ *
1345+ * No need to scale the x part of the texture here, but we
1346+ * are scaling on the y part in a positive direciton
1347+ *
1348+ * The base position (y0) here requires us to move backwards
1349+ * on the x dimention and forwards on y by the calculated rect dimentions
1350+ * multiplied by the scale factors
1351+ */
1352+
1353+ quadMatrix->xx = 0.0f;
1354+ quadMatrix->yy = 1.0f / glowSize;
1355+ quadMatrix->x0 = 1.0;
1356+ quadMatrix->y0 = -(y1 * quadMatrix->yy);
1357+
1358+ *box = CompRect (x1, y1, x2 - x1, y2 - y1);
1359+
1360+ /* Bottom edge */
1361+ box = &mGlowQuads[GLOWQUAD_BOTTOM].mBox;
1362+ mGlowQuads[GLOWQUAD_BOTTOM].mMatrix = *matrix;
1363+ quadMatrix = &mGlowQuads[GLOWQUAD_BOTTOM].mMatrix;
1364+
1365+ x1 = WIN_REAL_X (w) + glowOffset;
1366+ y1 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
1367+ x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
1368+ y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) + glowSize - glowOffset;
1369+
1370+ /* 2x2 Matrix here, adjust both x and y scale factors
1371+ * and the x and y position
1372+ *
1373+ * No need to scale the x part of the texture here, but we
1374+ * are scaling on the y part in a negative direciton
1375+ *
1376+ * The base position (y0) here requires us to move forwards
1377+ * on y by the calculated rect dimentions
1378+ * multiplied by the scale factors
1379+ */
1380+
1381+ quadMatrix->xx = 0.0f;
1382+ quadMatrix->yy = -1.0f / glowSize;
1383+ quadMatrix->x0 = 1.0;
1384+ quadMatrix->y0 = 1.0 - (y1 * quadMatrix->yy);
1385+
1386+ *box = CompRect (x1, y1, x2 - x1, y2 - y1);
1387+
1388+ /* Left edge */
1389+ box = &mGlowQuads[GLOWQUAD_LEFT].mBox;
1390+ mGlowQuads[GLOWQUAD_LEFT].mMatrix = *matrix;
1391+ quadMatrix = &mGlowQuads[GLOWQUAD_LEFT].mMatrix;
1392+
1393+ x1 = WIN_REAL_X (w) - glowSize + glowOffset;
1394+ y1 = WIN_REAL_Y (w) + glowOffset;
1395+ x2 = WIN_REAL_X (w) + glowOffset;
1396+ y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
1397+
1398+ /* 2x2 Matrix here, adjust both x and y scale factors
1399+ * and the x and y position
1400+ *
1401+ * No need to scale the y part of the texture here, but we
1402+ * are scaling on the x part in a positive direciton
1403+ *
1404+ * The base position (x0) here requires us to move backwards
1405+ * on x by the calculated rect dimentions
1406+ * multiplied by the scale factors
1407+ */
1408+
1409+ quadMatrix->xx = 1.0f / glowSize;
1410+ quadMatrix->yy = 0.0f;
1411+ quadMatrix->x0 = -(x1 * quadMatrix->xx);
1412+ quadMatrix->y0 = 1.0;
1413+
1414+ *box = CompRect (x1, y1, x2 - x1, y2 - y1);
1415+
1416+ /* Right edge */
1417+ box = &mGlowQuads[GLOWQUAD_RIGHT].mBox;
1418+ mGlowQuads[GLOWQUAD_RIGHT].mMatrix = *matrix;
1419+ quadMatrix = &mGlowQuads[GLOWQUAD_RIGHT].mMatrix;
1420+
1421+ x1 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) - glowOffset;
1422+ y1 = WIN_REAL_Y (w) + glowOffset;
1423+ x2 = WIN_REAL_X (w) + WIN_REAL_WIDTH (w) + glowSize - glowOffset;
1424+ y2 = WIN_REAL_Y (w) + WIN_REAL_HEIGHT (w) - glowOffset;
1425+
1426+ /* 2x2 Matrix here, adjust both x and y scale factors
1427+ * and the x and y position
1428+ *
1429+ * No need to scale the y part of the texture here, but we
1430+ * are scaling on the x part in a negative direciton
1431+ *
1432+ * The base position (x0) here requires us to move forwards
1433+ * on x by the calculated rect dimentions
1434+ * multiplied by the scale factors
1435+ */
1436+
1437+ quadMatrix->xx = -1.0f / glowSize;
1438+ quadMatrix->yy = 0.0f;
1439+ quadMatrix->x0 = 1.0 - (x1 * quadMatrix->xx);
1440+ quadMatrix->y0 = 1.0;
1441+
1442+ *box = CompRect (x1, y1, x2 - x1, y2 - y1);
1443+}
1444
1445=== added file 'src/glow.h'
1446--- src/glow.h 1970-01-01 00:00:00 +0000
1447+++ src/glow.h 2011-10-05 08:01:34 +0000
1448@@ -0,0 +1,66 @@
1449+/**
1450+ *
1451+ * Compiz group plugin
1452+ *
1453+ * glow.h
1454+ *
1455+ * Copyright : (C) 2006-2010 by Patrick Niklaus, Roi Cohen,
1456+ * Danny Baumann, Sam Spilsbury
1457+ * Authors: Patrick Niklaus <patrick.niklaus@googlemail.com>
1458+ * Roi Cohen <roico.beryl@gmail.com>
1459+ * Danny Baumann <maniac@opencompositing.org>
1460+ * Sam Spilsbury <smspillaz@gmail.com>
1461+ *
1462+ *
1463+ * This program is free software; you can redistribute it and/or
1464+ * modify it under the terms of the GNU General Public License
1465+ * as published by the Free Software Foundation; either version 2
1466+ * of the License, or (at your option) any later version.
1467+ *
1468+ * This program is distributed in the hope that it will be useful,
1469+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1470+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1471+ * GNU General Public License for more details.
1472+ *
1473+ **/
1474+
1475+#ifndef _EXPO_GLOW_H
1476+#define _EXPO_GLOW_H
1477+
1478+#define GLOWQUAD_TOPLEFT 0
1479+#define GLOWQUAD_TOPRIGHT 1
1480+#define GLOWQUAD_BOTTOMLEFT 2
1481+#define GLOWQUAD_BOTTOMRIGHT 3
1482+#define GLOWQUAD_TOP 4
1483+#define GLOWQUAD_BOTTOM 5
1484+#define GLOWQUAD_LEFT 6
1485+#define GLOWQUAD_RIGHT 7
1486+#define NUM_GLOWQUADS 8
1487+
1488+/* Represents a particular glow texture, so here
1489+ * we have hardcoded in the texture data, the offset
1490+ * and the size of the texture
1491+ */
1492+
1493+typedef struct _GlowTextureProperties {
1494+ char *textureData;
1495+ int textureSize;
1496+ int glowOffset;
1497+} GlowTextureProperties;
1498+
1499+/* Each glow quad contains a 2x2 scale + positional matrix
1500+ * (the 3rd column is not used since that is for matrix skew
1501+ * operations which we do not care about)
1502+ * and also a CompRect which describes the size and position of
1503+ * the quad on the glow
1504+ */
1505+
1506+class GlowQuad {
1507+ public:
1508+ CompRect mBox;
1509+ GLTexture::Matrix mMatrix;
1510+};
1511+
1512+extern const GlowTextureProperties glowTextureProperties;
1513+
1514+#endif
1515
1516=== added file 'src/group_glow.h'
1517--- src/group_glow.h 1970-01-01 00:00:00 +0000
1518+++ src/group_glow.h 2011-10-05 08:01:34 +0000
1519@@ -0,0 +1,197 @@
1520+#ifndef _GROUP_GLOWTEX_H
1521+#define _GROUP_GLOWTEX_H
1522+
1523+/**
1524+ *
1525+ * Compiz group plugin
1526+ *
1527+ * group_glow.h
1528+ *
1529+ * Copyright : (C) 2006-2010 by Patrick Niklaus, Roi Cohen,
1530+ * Danny Baumann, Sam Spilsbury
1531+ * Authors: Patrick Niklaus <patrick.niklaus@googlemail.com>
1532+ * Roi Cohen <roico.beryl@gmail.com>
1533+ * Danny Baumann <maniac@opencompositing.org>
1534+ * Sam Spilsbury <smspillaz@gmail.com>
1535+ *
1536+ *
1537+ * This program is free software; you can redistribute it and/or
1538+ * modify it under the terms of the GNU General Public License
1539+ * as published by the Free Software Foundation; either version 2
1540+ * of the License, or (at your option) any later version.
1541+ *
1542+ * This program is distributed in the hope that it will be useful,
1543+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1544+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1545+ * GNU General Public License for more details.
1546+ *
1547+ **/
1548+
1549+/*
1550+ * glowTex
1551+ */
1552+
1553+static char glowTexRect[4097] = {
1554+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1555+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1556+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377"
1557+ "\377\377\6\377\377\377\6\377\377\377\6\377\377\377\6\377\377\377\6\377\377"
1558+ "\377\6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1559+ "\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\6\377\377\377\6\377\377"
1560+ "\377\6\377\377\377\6\377\377\377\6\377\377\377\6\377\377\377\6\377\377\377"
1561+ "\6\377\377\377\6\377\377\377\6\377\377\377\6\377\377\377\6\377\377\377\6"
1562+ "\377\377\377\14\377\377\377\14\377\377\377\14\377\377\377\14\377\377\377"
1563+ "\14\377\377\377\14\377\377\377\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1564+ "\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\6\377\377\377\6\377\377\377\14"
1565+ "\377\377\377\14\377\377\377\22\377\377\377\22\377\377\377\22\377\377\377"
1566+ "\27\377\377\377\27\377\377\377\27\377\377\377\27\377\377\377\27\377\377\377"
1567+ "\27\377\377\377\27\377\377\377\27\377\377\377\27\377\377\377\27\377\377\377"
1568+ "\35\377\377\377\35\377\377\377\35\377\377\377\35\377\377\377\35\377\377\377"
1569+ "\35\377\377\377\35\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377"
1570+ "\377\6\377\377\377\6\377\377\377\14\377\377\377\22\377\377\377\27\377\377"
1571+ "\377\27\377\377\377\35\377\377\377#\377\377\377'\377\377\377'\377\377\377"
1572+ "+\377\377\377+\377\377\377+\377\377\377+\377\377\377+\377\377\377+\377\377"
1573+ "\377+\377\377\377+\377\377\377+\377\377\3771\377\377\3771\377\377\3771\377"
1574+ "\377\3771\377\377\3771\377\377\3771\377\377\3771\0\0\0\0\0\0\0\0\0\0\0\0"
1575+ "\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377\377\377\22\377\377\377"
1576+ "\27\377\377\377\35\377\377\377#\377\377\377+\377\377\3771\377\377\3776\377"
1577+ "\377\377<\377\377\377>\377\377\377C\377\377\377I\377\377\377I\377\377\377"
1578+ "I\377\377\377I\377\377\377I\377\377\377I\377\377\377I\377\377\377I\377\377"
1579+ "\377L\377\377\377L\377\377\377L\377\377\377L\377\377\377L\377\377\377L\377"
1580+ "\377\377L\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377"
1581+ "\377\377\22\377\377\377\27\377\377\377#\377\377\377+\377\377\3776\377\377"
1582+ "\377C\377\377\377L\377\377\377U\377\377\377]\377\377\377`\377\377\377d\377"
1583+ "\377\377h\377\377\377k\377\377\377k\377\377\377k\377\377\377k\377\377\377"
1584+ "k\377\377\377k\377\377\377k\377\377\377p\377\377\377p\377\377\377p\377\377"
1585+ "\377p\377\377\377p\377\377\377p\377\377\377p\0\0\0\0\0\0\0\0\0\0\0\0\377"
1586+ "\377\377\6\377\377\377\14\377\377\377\22\314\314\314\35\377\377\377'\377"
1587+ "\377\3771\377\377\377>\357\357\357P\377\377\377]\363\363\363k\365\365\365"
1588+ "v\365\365\365|\377\377\377\202\367\367\367\210\367\367\367\214\367\367\367"
1589+ "\216\367\367\367\221\367\367\367\221\367\367\367\221\367\367\367\221\367"
1590+ "\367\367\221\367\367\367\221\367\367\367\224\367\367\367\224\367\367\367"
1591+ "\224\367\367\367\224\367\367\367\224\367\367\367\224\367\367\367\224\0\0"
1592+ "\0\0\0\0\0\0\377\377\377\6\377\377\377\6\377\377\377\22\377\377\377\27\377"
1593+ "\377\377'\377\377\3776\377\377\377I\377\377\377Y\377\377\377k\376\376\376"
1594+ "y\377\377\377\210\377\377\377\224\377\377\377\235\377\377\377\245\377\377"
1595+ "\377\253\377\377\377\255\377\377\377\262\377\377\377\262\377\377\377\263"
1596+ "\377\377\377\263\377\377\377\263\377\377\377\263\377\377\377\263\377\377"
1597+ "\377\266\377\377\377\266\377\377\377\266\377\377\377\266\377\377\377\266"
1598+ "\377\377\377\266\377\377\377\266\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377"
1599+ "\14\377\377\377\27\377\377\377#\377\377\3771\377\377\377I\377\377\377]\377"
1600+ "\377\377r\377\377\377\205\377\377\377\231\377\377\377\247\377\377\377\263"
1601+ "\377\377\377\275\377\377\377\304\377\377\377\310\377\377\377\313\377\377"
1602+ "\377\316\377\377\377\320\377\377\377\320\377\377\377\320\377\377\377\320"
1603+ "\377\377\377\320\377\377\377\320\377\377\377\322\377\377\377\322\377\377"
1604+ "\377\322\377\377\377\322\377\377\377\322\377\377\377\322\377\377\377\322"
1605+ "\0\0\0\0\377\377\377\6\377\377\377\6\377\377\377\22\377\377\377\35\377\377"
1606+ "\377+\377\377\377>\377\377\377Y\377\377\377r\377\377\377\210\376\376\376"
1607+ "\237\377\377\377\262\377\377\377\302\377\377\377\313\377\377\377\324\377"
1608+ "\377\377\332\376\376\376\336\377\377\377\341\377\377\377\342\377\377\377"
1609+ "\344\377\377\377\344\377\377\377\344\377\377\377\344\377\377\377\344\377"
1610+ "\377\377\344\377\377\377\345\377\377\377\345\377\377\377\345\377\377\377"
1611+ "\345\377\377\377\345\377\377\377\345\377\377\377\345\0\0\0\0\377\377\377"
1612+ "\6\377\377\377\14\377\377\377\27\377\377\377#\377\377\3776\377\377\377P\377"
1613+ "\377\377k\377\377\377\205\376\376\376\237\372\372\372\266\377\377\377\307"
1614+ "\373\373\373\325\373\373\373\337\374\374\374\345\374\374\374\352\374\374"
1615+ "\374\355\374\374\374\357\374\374\374\360\374\374\374\361\374\374\374\361"
1616+ "\374\374\374\362\374\374\374\362\374\374\374\362\374\374\374\362\374\374"
1617+ "\374\362\374\374\374\362\374\374\374\362\374\374\374\362\374\374\374\362"
1618+ "\374\374\374\362\374\374\374\362\0\0\0\0\377\377\377\6\377\377\377\14\377"
1619+ "\377\377\35\377\377\377+\377\377\377C\377\377\377]\377\377\377|\377\377\377"
1620+ "\231\377\377\377\263\377\377\377\307\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1621+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1622+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377"
1623+ "\377\377\6\377\377\377\22\324\324\324#\377\377\3771\377\377\377L\363\363"
1624+ "\363k\377\377\377\210\377\377\377\247\377\377\377\302\377\377\377\325\0\0"
1625+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1626+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1627+ "\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377\377\377\22\377\377"
1628+ "\377#\377\377\377<\377\377\377U\377\377\377v\377\377\377\226\377\377\377"
1629+ "\263\377\377\377\315\377\377\377\337\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1630+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1631+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377"
1632+ "\6\377\377\377\14\377\377\377\27\377\377\377'\377\377\377>\377\377\377]\377"
1633+ "\377\377|\370\370\370\237\377\377\377\275\373\373\373\325\377\377\377\345"
1634+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1635+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1636+ "\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377\377\377\27\377"
1637+ "\377\377+\377\377\377C\377\377\377`\377\377\377\202\377\377\377\247\377\377"
1638+ "\377\304\377\377\377\332\377\377\377\352\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1639+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1640+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377"
1641+ "\377\6\377\377\377\14\377\377\377\27\377\377\377+\377\377\377C\377\377\377"
1642+ "d\377\377\377\210\377\377\377\253\377\377\377\310\376\376\376\336\374\374"
1643+ "\374\355\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1644+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1645+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377\377\377"
1646+ "\35\377\377\377+\377\377\377I\377\377\377h\377\377\377\214\377\377\377\260"
1647+ "\377\377\377\313\374\374\374\342\374\374\374\357\0\0\0\0\0\0\0\0\0\0\0\0"
1648+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1649+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1650+ "\377\377\377\6\377\377\377\14\377\377\377\35\342\342\3421\377\377\377I\377"
1651+ "\377\377k\377\377\377\216\377\377\377\262\377\377\377\316\374\374\374\344"
1652+ "\377\377\377\360\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1653+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1654+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377"
1655+ "\377\377\35\377\377\3771\377\377\377L\377\377\377k\377\377\377\221\377\377"
1656+ "\377\263\377\377\377\320\377\377\377\344\377\377\377\361\0\0\0\0\0\0\0\0"
1657+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1658+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1659+ "\0\0\0\0\377\377\377\6\377\377\377\14\377\377\377\35\377\377\3771\377\377"
1660+ "\377L\377\377\377k\377\377\377\221\377\377\377\263\377\377\377\320\377\377"
1661+ "\377\344\374\374\374\362\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1662+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1663+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377"
1664+ "\14\377\377\377\35\377\377\3771\377\377\377L\364\364\364p\377\377\377\221"
1665+ "\372\372\372\266\377\377\377\320\374\374\374\345\377\377\377\362\0\0\0\0"
1666+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1667+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1668+ "\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377\377\377\35\377\377\377"
1669+ "1\377\377\377L\377\377\377p\377\377\377\221\377\377\377\266\373\373\373\322"
1670+ "\377\377\377\345\377\377\377\362\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1671+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1672+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377"
1673+ "\377\377\14\377\377\377\35\377\377\3771\377\377\377L\377\377\377p\377\377"
1674+ "\377\221\377\377\377\266\373\373\373\322\377\377\377\345\377\377\377\362"
1675+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1676+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1677+ "\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377\377\377\35\377"
1678+ "\377\3771\377\377\377L\377\377\377p\377\377\377\221\377\377\377\266\373\373"
1679+ "\373\322\377\377\377\345\377\377\377\362\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1680+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1681+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377"
1682+ "\377\6\377\377\377\14\377\377\377\35\377\377\3771\377\377\377L\377\377\377"
1683+ "p\367\367\367\224\377\377\377\266\377\377\377\322\377\377\377\345\374\374"
1684+ "\374\362\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1685+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1686+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377\377\377"
1687+ "\35\377\377\3771\377\377\377L\377\377\377p\367\367\367\224\377\377\377\266"
1688+ "\377\377\377\322\377\377\377\345\374\374\374\362\0\0\0\0\0\0\0\0\0\0\0\0"
1689+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1690+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1691+ "\377\377\377\6\377\377\377\14\377\377\377\35\377\377\3771\377\377\377L\377"
1692+ "\377\377p\367\367\367\224\377\377\377\266\377\377\377\322\377\377\377\345"
1693+ "\374\374\374\362\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1694+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1695+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377"
1696+ "\377\377\35\377\377\3771\377\377\377L\377\377\377p\367\367\367\224\377\377"
1697+ "\377\266\377\377\377\322\377\377\377\345\374\374\374\362\0\0\0\0\0\0\0\0"
1698+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1699+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1700+ "\0\0\0\0\377\377\377\6\377\377\377\14\377\377\377\35\377\377\3771\377\377"
1701+ "\377L\377\377\377p\367\367\367\224\377\377\377\266\377\377\377\322\377\377"
1702+ "\377\345\374\374\374\362\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1703+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1704+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377"
1705+ "\14\377\377\377\35\377\377\3771\377\377\377L\377\377\377p\367\367\367\224"
1706+ "\377\377\377\266\377\377\377\322\377\377\377\345\374\374\374\362\0\0\0\0"
1707+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1708+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1709+ "\0\0\0\0\0\0\0\0\377\377\377\6\377\377\377\14\377\377\377\35\377\377\377"
1710+ "1\377\377\377L\377\377\377p\367\367\367\224\377\377\377\266\377\377\377\322"
1711+ "\377\377\377\345\374\374\374\362\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1712+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
1713+ "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
1714+};
1715+
1716+#endif

Subscribers

People subscribed via source and target branches