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

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 154
Proposed branch: lp:~compiz-team/compiz-expo-plugin/oneiric.actual_polish
Merge into: lp:~compiz-team/compiz-expo-plugin/oneiric
Diff against target: 1748 lines (+1233/-160)
6 files modified
expo.xml.in (+15/-4)
src/expo.cpp (+471/-155)
src/expo.h (+56/-1)
src/glow.cpp (+428/-0)
src/glow.h (+66/-0)
src/group_glow.h (+197/-0)
To merge this branch: bzr merge lp:~compiz-team/compiz-expo-plugin/oneiric.actual_polish
Reviewer Review Type Date Requested Status
Jason Smith (community) Approve
Robert Carr Pending
Review via email: mp+75526@code.launchpad.net

This proposal supersedes a proposal from 2011-09-02.

Description of the change

Center the spread as per design

Bug 837545

To post a comment you must log in.
Revision history for this message
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal

+1. Looks like there might be something wrong with...merging the group plugin though ?!?!

review: Approve
Revision history for this message
Jason Smith (jassmith) wrote :

Looks fine, dupes some code but we dont care since we dont use the group plugin.

review: Approve

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

Subscribers

People subscribed via source and target branches

to all changes: