Merge lp:~mniess/ubuntu/precise/compiz-plugins-main/lp953278 into lp:ubuntu/precise/compiz-plugins-main

Proposed by Matthias Niess
Status: Merged
Merge reported by: Didier Roche-Tolomelli
Merged at revision: not available
Proposed branch: lp:~mniess/ubuntu/precise/compiz-plugins-main/lp953278
Merge into: lp:ubuntu/precise/compiz-plugins-main
Diff against target: 17565 lines (+318/-16206)
47 files modified
.pc/applied-patches (+0/-10)
.pc/expo.patch/expo/CMakeLists.txt (+0/-7)
.pc/expo.patch/expo/expo.xml.in (+0/-257)
.pc/expo.patch/expo/src/expo.cpp (+0/-1382)
.pc/expo.patch/expo/src/expo.h (+0/-163)
.pc/expo_api_931927.patch/expo/src/expo.cpp (+0/-1692)
.pc/fix_930192.patch/animation/src/animation.cpp (+0/-2962)
.pc/fix_broken_build.patch/wall/src/wall.h (+0/-208)
.pc/fix_clipping_issues_in_expo.patch/expo/src/expo.cpp (+0/-1667)
.pc/shift_954079.patch/shift/shift.xml.in (+0/-393)
.pc/ubuntu_config.patch/animation/animation.xml.in (+0/-757)
.pc/ubuntu_config.patch/ezoom/ezoom.xml.in (+0/-288)
.pc/ubuntu_config.patch/grid/grid.xml.in (+0/-565)
.pc/ubuntu_config.patch/staticswitcher/staticswitcher.xml.in (+0/-298)
.pc/ubuntu_config.patch/vpswitch/vpswitch.xml.in (+0/-126)
.pc/ubuntu_config.patch/wall/wall.xml.in (+0/-361)
.pc/vpswitch_953834.patch/vpswitch/src/vpswitch.cpp (+0/-369)
.pc/workarounds_923087.patch/workarounds/src/workarounds.cpp (+0/-1178)
.pc/workarounds_931473.patch/workarounds/src/workarounds.cpp (+0/-1152)
.pc/workarounds_931473.patch/workarounds/src/workarounds.h (+0/-215)
.pc/workarounds_931473.patch/workarounds/workarounds.xml.in (+0/-106)
animation/animation.xml.in (+23/-23)
animation/src/animation.cpp (+0/-5)
debian/changelog (+9/-0)
debian/patches/fix-lp953278.patch (+16/-0)
debian/patches/series (+1/-0)
expo/CMakeLists.txt (+1/-1)
expo/expo.xml.in (+11/-33)
expo/src/expo.cpp (+167/-477)
expo/src/expo.h (+2/-57)
expo/src/glow.cpp (+0/-428)
expo/src/glow.h (+0/-66)
expo/src/group_glow.h (+0/-197)
ezoom/ezoom.xml.in (+3/-0)
glow.cpp (+0/-428)
glow.h (+0/-66)
grid/grid.xml.in (+4/-2)
group_glow.h (+0/-197)
shift/shift.xml.in (+5/-0)
staticswitcher/staticswitcher.xml.in (+9/-8)
vpswitch/src/vpswitch.cpp (+1/-1)
vpswitch/vpswitch.xml.in (+2/-0)
wall/src/wall.h (+1/-1)
wall/wall.xml.in (+31/-31)
workarounds/src/workarounds.cpp (+32/-20)
workarounds/src/workarounds.h (+0/-4)
workarounds/workarounds.xml.in (+0/-5)
To merge this branch: bzr merge lp:~mniess/ubuntu/precise/compiz-plugins-main/lp953278
Reviewer Review Type Date Requested Status
Didier Roche-Tolomelli Approve
Ubuntu branches Pending
Review via email: mp+99407@code.launchpad.net

Description of the change

Disabled super+r as bad default for fit_to_window_key (LP: #953278)

To post a comment you must log in.
31. By Matthias Niess

* debian/patches/fix-lp953278.patch:
  - disable bad default of Super+r causing zoom to current window in
    ezoom plugin (LP: #953278)

Revision history for this message
Matthias Niess (mniess) wrote :

Changed the branch to not do the change directly in the file but put a patch in debian/patches.

Revision history for this message
Didier Roche-Tolomelli (didrocks) wrote :

Hey Matthias.

Thanks a lot for your patch!
However, I can't see it in the below diff (looked for a fix-lp953278.patch file).
The idea of the change is good, so I committed it under your name in the correct branch: http://bazaar.launchpad.net/~compiz/compcomm-plugins-main/ubuntu
(look at the Vcs-Bzr tag in debian/control, the command "debcheckout <package_name>" should bzr branch from the right branch).

Also, you will notice I merged your change to debian/patches/ubuntu_config.patch as it's really where this change should be.

Thanks again for your contribution :)
I'm marking this branch as merged then.

review: Approve
Revision history for this message
Matthias Niess (mniess) wrote :

Hi Didier. I'll do better next time! ;) I already know where things went wrong (i.e. I followed the Fixing Ubuntu bugs guide to the letter and edit-patch changed behavior). Thanks for the tips.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== removed file '.pc/applied-patches'
--- .pc/applied-patches 2012-03-21 11:46:41 +0000
+++ .pc/applied-patches 1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
1expo.patch
2fix_clipping_issues_in_expo.patch
3ubuntu_config.patch
4expo_api_931927.patch
5workarounds_923087.patch
6workarounds_931473.patch
7shift_954079.patch
8fix_broken_build.patch
9vpswitch_953834.patch
10fix_930192.patch
110
=== removed directory '.pc/expo.patch'
=== removed directory '.pc/expo.patch/expo'
=== removed file '.pc/expo.patch/expo/CMakeLists.txt'
--- .pc/expo.patch/expo/CMakeLists.txt 2012-02-13 15:30:29 +0000
+++ .pc/expo.patch/expo/CMakeLists.txt 1970-01-01 00:00:00 +0000
@@ -1,7 +0,0 @@
1find_package (Compiz REQUIRED)
2include (FindOpenGL)
3include (CompizPlugin)
4
5if (OPENGL_GLU_FOUND)
6 compiz_plugin (expo PLUGINDEPS composite opengl LIBRARIES ${OPENGL_glu_LIBRARY} INCDIRS ${OPENGL_INCLUDE_DIR})
7endif (OPENGL_GLU_FOUND)
80
=== removed file '.pc/expo.patch/expo/expo.xml.in'
--- .pc/expo.patch/expo/expo.xml.in 2012-02-13 15:30:29 +0000
+++ .pc/expo.patch/expo/expo.xml.in 1970-01-01 00:00:00 +0000
@@ -1,257 +0,0 @@
1<?xml version="1.0"?>
2<compiz>
3 <plugin name="expo" useBcop="true">
4 <_short>Expo</_short>
5 <_long>Expo Plugin</_long>
6 <category>Desktop</category>
7 <deps>
8 <requirement>
9 <plugin>opengl</plugin>
10 </requirement>
11 <relation type="after">
12 <plugin>composite</plugin>
13 <plugin>opengl</plugin>
14 <plugin>decor</plugin>
15 <plugin>cube</plugin>
16 <plugin>cubeaddon</plugin>
17 <plugin>wobbly</plugin>
18 <plugin>animation</plugin>
19 <plugin>wallpaper</plugin>
20 </relation>
21 </deps>
22 <options>
23 <group>
24 <_short>Bindings</_short>
25 <option name="expo_key" type="key">
26 <_short>Expo key</_short>
27 <_long>Engage wall expo mode key binding</_long>
28 <default>&lt;Super&gt;e</default>
29 </option>
30 <option name="expo_button" type="button">
31 <_short>Expo button</_short>
32 <_long>Engage wall expo mode button binding</_long>
33 <default></default>
34 </option>
35 <option name="expo_edge" type="edge">
36 <_short>Expo edge</_short>
37 <_long>Engage wall expo mode edge binding</_long>
38 <default>
39 <edge name="TopLeft"/>
40 </default>
41 </option>
42 <option name="double_click_time" type="int">
43 <_short>Double click time</_short>
44 <_long>Timeframe to execute a double click</_long>
45 <default>500</default>
46 <min>50</min>
47 <max>2000</max>
48 </option>
49 <option name="dnd_button" type="button">
50 <_short>Drag&amp;drop</_short>
51 <_long>Button binding for drag &amp; drop of windows</_long>
52 <default>Button1</default>
53 <passive_grab>false</passive_grab>
54 <internal/>
55 </option>
56 <option name="exit_button" type="button">
57 <_short>Exit expo</_short>
58 <_long>Button binding to exit expo</_long>
59 <default>Button3</default>
60 <passive_grab>false</passive_grab>
61 <internal/>
62 </option>
63 <option name="next_vp_button" type="button">
64 <_short>Next viewport</_short>
65 <_long>Button binding to switch to next viewport in expo</_long>
66 <default>Button5</default>
67 <passive_grab>false</passive_grab>
68 <internal/>
69 </option>
70 <option name="prev_vp_button" type="button">
71 <_short>Previous viewport</_short>
72 <_long>Button binding to switch to next viewport in expo</_long>
73 <default>Button4</default>
74 <passive_grab>false</passive_grab>
75 <internal/>
76 </option>
77 </group>
78 <group>
79 <_short>Behaviour</_short>
80 <option name="zoom_time" type="float">
81 <_short>Zoom time</_short>
82 <_long>Duration of the zoomout animation</_long>
83 <default>0.5</default>
84 <min>0.1</min>
85 <max>5.0</max>
86 <precision>0.1</precision>
87 </option>
88 <option name="expo_immediate_move" type="bool">
89 <_short>Immediate moves</_short>
90 <_long>Selects if windows movements in expo mode should be immediate - this among other things disables wobbliness</_long>
91 <default>false</default>
92 </option>
93 <option name="expo_animation" type="int">
94 <_short>Expo Animation</_short>
95 <_long>Animation used when switching to expo mode</_long>
96 <default>0</default>
97 <min>0</min>
98 <max>2</max>
99 <desc>
100 <value>0</value>
101 <_name>Zoom</_name>
102 </desc>
103 <desc>
104 <value>1</value>
105 <_name>Fade + Zoom</_name>
106 </desc>
107 <desc>
108 <value>2</value>
109 <_name>Vortex</_name>
110 </desc>
111 </option>
112 </group>
113 <group>
114 <_short>Appearance</_short>
115 <option name="deform" type="int">
116 <_short>Deformation</_short>
117 <_long>Deformation of the expo wall</_long>
118 <default>0</default>
119 <min>0</min>
120 <max>2</max>
121 <desc>
122 <value>0</value>
123 <_name>None</_name>
124 </desc>
125 <desc>
126 <value>1</value>
127 <_name>Tilt</_name>
128 </desc>
129 <desc>
130 <value>2</value>
131 <_name>Curve</_name>
132 </desc>
133 </option>
134 <option name="distance" type="float">
135 <_short>Distance</_short>
136 <_long>Distance of the expo wall</_long>
137 <default>0.0</default>
138 <min>0.0</min>
139 <max>1.0</max>
140 <precision>0.01</precision>
141 </option>
142 <option name="vp_distance" type="float">
143 <_short>Viewport distance</_short>
144 <_long>Distance between viewports</_long>
145 <default>0.10</default>
146 <min>0.0</min>
147 <max>1.0</max>
148 <precision>0.01</precision>
149 </option>
150 <option name="aspect_ratio" type="float">
151 <_short>Aspect Ratio</_short>
152 <_long>Expo mode aspect ratio</_long>
153 <default>1.0</default>
154 <min>0.0</min>
155 <max>1.0</max>
156 <precision>0.1</precision>
157 </option>
158 <option name="curve" type="float">
159 <_short>Curve strength</_short>
160 <_long>Strength of the deformation in curve mode</_long>
161 <default>0.50</default>
162 <min>0.0</min>
163 <max>1.0</max>
164 <precision>0.01</precision>
165 </option>
166 <option name="hide_docks" type="bool">
167 <_short>Hide panels/docks in expo</_short>
168 <_long>Hide panels/docks in expo.</_long>
169 <default>false</default>
170 </option>
171 <option name="mipmaps" type="bool">
172 <_short>Mipmaps</_short>
173 <_long>Generate mipmaps in expo mode</_long>
174 <default>false</default>
175 </option>
176 <option name="multioutput_mode" type="int">
177 <_short>Multi Output Mode</_short>
178 <_long>Selects how the expo wall is displayed if multiple output devices are used.</_long>
179 <min>0</min>
180 <max>1</max>
181 <default>0</default>
182 <desc>
183 <value>0</value>
184 <_name>One big wall</_name>
185 </desc>
186 <desc>
187 <value>1</value>
188 <_name>One wall per output</_name>
189 </desc>
190 </option>
191 <subgroup>
192 <short>Inactive viewports</short>
193 <option name="vp_brightness" type="float">
194 <_short>Brightness</_short>
195 <_long>Inactive viewport brightness.</_long>
196 <default>75.0</default>
197 <min>0.0</min>
198 <max>100.0</max>
199 <precision>0.1</precision>
200 </option>
201 <option name="vp_saturation" type="float">
202 <_short>Saturation</_short>
203 <_long>Inactive viewport saturation.</_long>
204 <default>100.0</default>
205 <min>0.0</min>
206 <max>100.0</max>
207 <precision>0.1</precision>
208 </option>
209 </subgroup>
210 <subgroup>
211 <short>Reflection</short>
212 <option name="reflection" type="bool">
213 <_short>Reflection</_short>
214 <_long>Show a reflection of the viewports on the ground</_long>
215 <default>true</default>
216 </option>
217 <option name="ground_color1" type="color">
218 <_short>Ground color(near)</_short>
219 <_long>Color of the ground (near).</_long>
220 <default>
221 <red>0xb333</red>
222 <green>0xb333</green>
223 <blue>0xb333</blue>
224 <alpha>0xcccc</alpha>
225 </default>
226 </option>
227 <option name="ground_color2" type="color">
228 <_short>Ground color(far)</_short>
229 <_long>Color of the ground (far).</_long>
230 <default>
231 <red>0xb333</red>
232 <green>0xb333</green>
233 <blue>0xb333</blue>
234 <alpha>0x0000</alpha>
235 </default>
236 </option>
237 <option name="ground_size" type="float">
238 <_short>Reflection ground size</_short>
239 <_long>Reflection ground size.</_long>
240 <default>0.5</default>
241 <min>0.0</min>
242 <max>1.0</max>
243 <precision>0.01</precision>
244 </option>
245 <option name="scale_factor" type="float">
246 <_short>Reflection Scale</_short>
247 <_long>Scale factor of the expo wall reflection</_long>
248 <default>0.75</default>
249 <min>0.0</min>
250 <max>2.0</max>
251 <precision>0.01</precision>
252 </option>
253 </subgroup>
254 </group>
255 </options>
256 </plugin>
257</compiz>
2580
=== removed directory '.pc/expo.patch/expo/src'
=== removed file '.pc/expo.patch/expo/src/expo.cpp'
--- .pc/expo.patch/expo/src/expo.cpp 2012-02-13 15:30:29 +0000
+++ .pc/expo.patch/expo/src/expo.cpp 1970-01-01 00:00:00 +0000
@@ -1,1382 +0,0 @@
1/**
2 *
3 * Compiz expo plugin
4 *
5 * expo.c
6 *
7 * Copyright (c) 2008 Dennis Kasprzyk <racarr@opencompositing.org>
8 * Copyright (c) 2006 Robert Carr <racarr@beryl-project.org>
9 *
10 * Authors:
11 * Robert Carr <racarr@beryl-project.org>
12 * Dennis Kasprzyk <onestone@opencompositing.org>
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 **/
25
26#include "expo.h"
27#include <math.h>
28#include <GL/glu.h>
29
30COMPIZ_PLUGIN_20090315 (expo, ExpoPluginVTable);
31
32#define sigmoid(x) (1.0f / (1.0f + exp (-5.5f * 2 * ((x) - 0.5))))
33#define sigmoidProgress(x) ((sigmoid (x) - sigmoid (0)) / \
34 (sigmoid (1) - sigmoid (0)))
35
36#define interpolate(a, b, val) (((val) * (a)) + ((1 - (val)) * (b)))
37
38bool
39ExpoScreen::dndInit (CompAction *action,
40 CompAction::State state,
41 CompOption::Vector& options)
42{
43 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
44 if (xid != screen->root ())
45 return false;
46
47 if (expoMode)
48 {
49 dndState = DnDStart;
50 action->setState (action->state () | CompAction::StateTermButton);
51 cScreen->damageScreen ();
52
53 return true;
54 }
55
56 return false;
57}
58
59bool
60ExpoScreen::dndFini (CompAction *action,
61 CompAction::State state,
62 CompOption::Vector& options)
63{
64 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
65 if (xid != screen->root ())
66 return false;
67
68 if (dndState == DnDDuring || dndState == DnDStart)
69 {
70 if (dndWindow)
71 finishWindowMovement ();
72
73 dndState = DnDNone;
74 dndWindow = NULL;
75
76 action->setState (action->state () & CompAction::StateInitButton);
77 cScreen->damageScreen ();
78
79 return true;
80 }
81
82 return false;
83}
84
85bool
86ExpoScreen::doExpo (CompAction *action,
87 CompAction::State state,
88 CompOption::Vector& options)
89{
90 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
91 if (xid != screen->root ())
92 return false;
93
94 if (screen->otherGrabExist ("expo", NULL))
95 return false;
96
97 if (!expoMode)
98 {
99 if (!grabIndex)
100 grabIndex = screen->pushGrab (None, "expo");
101
102 updateWraps (true);
103
104 expoMode = true;
105 anyClick = false;
106 doubleClick = false;
107 clickTime = 0;
108
109 dndState = DnDNone;
110 dndWindow = NULL;
111
112 selectedVp = screen->vp ();
113 lastSelectedVp = screen->vp ();
114 origVp = screen->vp ();
115
116 screen->addAction (&optionGetDndButton ());
117 screen->addAction (&optionGetExitButton ());
118 screen->addAction (&optionGetNextVpButton ());
119 screen->addAction (&optionGetPrevVpButton ());
120
121 cScreen->damageScreen ();
122 }
123 else
124 {
125 termExpo (action, state, options);
126 }
127
128 return true;
129}
130
131bool
132ExpoScreen::termExpo (CompAction *action,
133 CompAction::State state,
134 CompOption::Vector& options)
135{
136 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
137 if (xid && xid != screen->root ())
138 return false;
139
140 if (!expoMode)
141 return true;
142
143 expoMode = false;
144
145 if (dndState != DnDNone)
146 dndFini (action, state, options);
147
148 if (state & CompAction::StateCancel)
149 vpUpdateMode = VPUpdatePrevious;
150 else
151 vpUpdateMode = VPUpdateMouseOver;
152
153 dndState = DnDNone;
154 dndWindow = NULL;
155
156 screen->removeAction (&optionGetDndButton ());
157 screen->removeAction (&optionGetExitButton ());
158 screen->removeAction (&optionGetNextVpButton ());
159 screen->removeAction (&optionGetPrevVpButton ());
160
161 cScreen->damageScreen ();
162 screen->focusDefaultWindow ();
163
164 return true;
165}
166
167bool
168ExpoScreen::exitExpo (CompAction *action,
169 CompAction::State state,
170 CompOption::Vector& options)
171{
172 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
173 if (xid != screen->root ())
174 return false;
175
176 if (!expoMode)
177 return false;
178
179 termExpo (action, 0, noOptions);
180 anyClick = true;
181 cScreen->damageScreen ();
182
183 return true;
184}
185
186bool
187ExpoScreen::nextVp (CompAction *action,
188 CompAction::State state,
189 CompOption::Vector& options)
190{
191 unsigned int newX, newY;
192 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
193 if (xid != screen->root ())
194 return false;
195
196 if (!expoMode)
197 return false;
198
199 newX = selectedVp.x () + 1;
200 newY = selectedVp.y ();
201
202 if (newX >= (unsigned int) screen->vpSize ().width ())
203 {
204 newX = 0;
205 newY = newY + 1;
206 if (newY >= (unsigned int) screen->vpSize ().height ())
207 newY = 0;
208 }
209
210 moveFocusViewport (newX - selectedVp.x (),
211 newY - selectedVp.y ());
212 cScreen->damageScreen ();
213
214 return true;
215}
216
217bool
218ExpoScreen::prevVp (CompAction *action,
219 CompAction::State state,
220 CompOption::Vector& options)
221{
222 unsigned int newX, newY;
223 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
224 if (xid != screen->root ())
225 return false;
226
227 if (!expoMode)
228 return false;
229
230 newX = selectedVp.x () - 1;
231 newY = selectedVp.y ();
232
233 if (newX < 0)
234 {
235 newX = screen->vpSize ().width () - 1;
236 newY = newY - 1;
237 if (newY < 0)
238 newY = screen->vpSize ().height () - 1;
239 }
240
241 moveFocusViewport (newX - selectedVp.x (),
242 newY - selectedVp.y ());
243 cScreen->damageScreen ();
244
245 return true;
246}
247
248void
249ExpoScreen::moveFocusViewport (int dx,
250 int dy)
251{
252 int newX, newY;
253
254 lastSelectedVp = selectedVp;
255
256 newX = selectedVp.x () + dx;
257 newY = selectedVp.y () + dy;
258
259 newX = MAX (0, MIN ((int) screen->vpSize ().width () - 1, newX));
260 newY = MAX (0, MIN ((int) screen->vpSize ().height () - 1, newY));
261
262 selectedVp.set (newX, newY);
263 cScreen->damageScreen ();
264}
265
266void
267ExpoScreen::finishWindowMovement ()
268{
269 dndWindow->syncPosition ();
270 dndWindow->ungrabNotify ();
271
272 screen->moveViewport (screen->vp ().x () - selectedVp.x (),
273 screen->vp ().y () - selectedVp.y (), true);
274
275 /* update saved window attributes in case we moved the
276 window to a new viewport */
277 if (dndWindow->saveMask () & CWX)
278 {
279 dndWindow->saveWc ().x = dndWindow->saveWc ().x % screen->width ();
280 if (dndWindow->saveWc ().x < 0)
281 dndWindow->saveWc ().x += screen->width ();
282 }
283 if (dndWindow->saveMask () & CWY)
284 {
285 dndWindow->saveWc ().y = dndWindow->saveWc ().y % screen->height ();
286 if (dndWindow->saveWc ().y < 0)
287 dndWindow->saveWc ().y += screen->height ();
288 }
289
290 /* update window attibutes to make sure a moved maximized window
291 is properly snapped to the work area */
292 if (dndWindow->state () & MAXIMIZE_STATE)
293 dndWindow->updateAttributes (CompStackingUpdateModeNone);
294
295#if 0 /* FIXME: obsolete in the meantime? */
296 {
297 int lastOutput;
298 int centerX, centerY;
299
300 /* make sure we snap to the correct output */
301 lastOutput = s->currentOutputDev;
302 centerX = (WIN_X (w) + WIN_W (w) / 2) % s->width;
303 if (centerX < 0)
304 centerX += s->width;
305 centerY = (WIN_Y (w) + WIN_H (w) / 2) % s->height;
306 if (centerY < 0)
307 centerY += s->height;
308
309 s->currentOutputDev = outputDeviceForPoint (s, centerX, centerY);
310
311 updateWindowAttributes (w, CompStackingUpdateModeNone);
312
313 s->currentOutputDev = lastOutput;
314 }
315#endif
316}
317
318void
319ExpoScreen::handleEvent (XEvent *event)
320{
321 switch (event->type) {
322 case KeyPress:
323 if (expoMode && event->xkey.root == screen->root ())
324 {
325 if (event->xkey.keycode == leftKey)
326 moveFocusViewport (-1, 0);
327 else if (event->xkey.keycode == rightKey)
328 moveFocusViewport (1, 0);
329 else if (event->xkey.keycode == upKey)
330 moveFocusViewport (0, -1);
331 else if (event->xkey.keycode == downKey)
332 moveFocusViewport (0, 1);
333 }
334 break;
335
336 case ButtonPress:
337 if (expoMode && event->xbutton.button == Button1 &&
338 event->xbutton.root == screen->root ())
339 {
340 anyClick = true;
341 if (clickTime == 0)
342 {
343 clickTime = event->xbutton.time;
344 }
345 else if (event->xbutton.time - clickTime <=
346 (unsigned int) optionGetDoubleClickTime () && lastSelectedVp == selectedVp)
347 {
348 doubleClick = true;
349 }
350 else
351 {
352 clickTime = event->xbutton.time;
353 doubleClick = false;
354 }
355 cScreen->damageScreen ();
356 }
357 break;
358
359 case ButtonRelease:
360 if (expoMode && event->xbutton.button == Button1 &&
361 event->xbutton.root == screen->root ())
362 {
363 if (event->xbutton.time - clickTime >
364 (unsigned int) optionGetDoubleClickTime ())
365 {
366 clickTime = 0;
367 doubleClick = false;
368 }
369 else if (doubleClick)
370 {
371 CompAction& action = optionGetExpoKey ();
372
373 clickTime = 0;
374 doubleClick = false;
375
376 termExpo (&action, 0, noOptions);
377 anyClick = true;
378 }
379 }
380 break;
381 }
382
383 screen->handleEvent (event);
384}
385
386void
387ExpoScreen::preparePaint (int msSinceLastPaint)
388{
389 float val = ((float) msSinceLastPaint / 1000.0) / optionGetZoomTime ();
390
391 if (expoMode)
392 expoCam = MIN (1.0, expoCam + val);
393 else
394 expoCam = MAX (0.0, expoCam - val);
395
396 if (expoCam)
397 {
398 unsigned int i, j, vp;
399 unsigned int vpCount = screen->vpSize ().width () *
400 screen->vpSize ().height ();
401
402 if (vpActivity.size () < vpCount)
403 {
404 vpActivity.resize (vpCount);
405 foreach (float& activity, vpActivity)
406 activity = 1.0f;
407 }
408
409 for (i = 0; i < (unsigned int) screen->vpSize ().width (); i++)
410 {
411 for (j = 0; j < (unsigned int) screen->vpSize ().height (); j++)
412 {
413 vp = (j * screen->vpSize ().width ()) + i;
414
415 if (CompPoint (i, j) == selectedVp)
416 vpActivity[vp] = MIN (1.0, vpActivity[vp] + val);
417 else
418 vpActivity[vp] = MAX (0.0, vpActivity[vp] - val);
419 }
420 }
421
422 for (i = 0; i < 360; i++)
423 {
424 float fi = (float) i;
425
426 vpNormals[i * 3] = (-sin (fi * (M_PI / 180.0f)) / screen->width ()) *
427 expoCam;
428 vpNormals[(i * 3) + 1] = 0.0;
429 vpNormals[(i * 3) + 2] = (-cos (fi * (M_PI / 180.0f)) * expoCam) -
430 (1 - expoCam);
431 }
432 }
433
434 cScreen->preparePaint (msSinceLastPaint);
435}
436
437void
438ExpoScreen::updateWraps (bool enable)
439{
440 screen->handleEventSetEnabled (this, enable);
441 cScreen->preparePaintSetEnabled (this, enable);
442 cScreen->paintSetEnabled (this, enable);
443 cScreen->donePaintSetEnabled (this, enable);
444 gScreen->glPaintOutputSetEnabled (this, enable);
445 gScreen->glPaintTransformedOutputSetEnabled (this, enable);
446
447 foreach (CompWindow *w, screen->windows ())
448 {
449 ExpoWindow *ew = ExpoWindow::get (w);
450
451 ew->cWindow->damageRectSetEnabled (ew, enable);
452 ew->gWindow->glPaintSetEnabled (ew, enable);
453 ew->gWindow->glDrawSetEnabled (ew, enable);
454 ew->gWindow->glAddGeometrySetEnabled (ew, enable);
455 ew->gWindow->glDrawTextureSetEnabled (ew, enable);
456 }
457}
458
459void
460ExpoScreen::paint (CompOutput::ptrList& outputs,
461 unsigned int mask)
462{
463 int width = outputs.front ()->width ();
464 int height = outputs.front ()->height ();
465 bool sizeDiff = false;
466
467 /* "One big wall" does not make sense where outputs are different
468 * sizes, so force multiple walls in this case
469 *
470 * TODO: Is it possible to re-create "one big wall" using
471 * independent output painting in this case? */
472
473 foreach (CompOutput *o, outputs)
474 {
475 if (o->width () != width || o->height () != height)
476 {
477 sizeDiff = true;
478 break;
479 }
480 }
481
482 if (expoCam > 0.0 && outputs.size () > 1 &&
483 optionGetMultioutputMode () == MultioutputModeOneBigWall &&
484 !sizeDiff)
485 {
486 outputs.clear ();
487 outputs.push_back (&screen->fullscreenOutput ());
488 }
489
490 cScreen->paint (outputs, mask);
491}
492
493void
494ExpoScreen::donePaint ()
495{
496 switch (vpUpdateMode) {
497 case VPUpdateMouseOver:
498 screen->moveViewport (screen->vp ().x () - selectedVp.x (),
499 screen->vp ().y () - selectedVp.y (), true);
500 screen->focusDefaultWindow ();
501 vpUpdateMode = VPUpdateNone;
502 break;
503 case VPUpdatePrevious:
504 screen->moveViewport (screen->vp ().x () - origVp.x (),
505 screen->vp ().y () - origVp.y (), true);
506 lastSelectedVp = selectedVp;
507 selectedVp = origVp;
508 screen->focusDefaultWindow ();
509 vpUpdateMode = VPUpdateNone;
510 break;
511 default:
512 break;
513 }
514
515 if ((expoCam > 0.0f && expoCam < 1.0f) || dndState != DnDNone)
516 cScreen->damageScreen ();
517
518 if (expoCam == 1.0f)
519 {
520 foreach (float& vp, vpActivity)
521 if (vp != 0.0 && vp != 1.0)
522 cScreen->damageScreen ();
523 }
524
525 if (grabIndex && expoCam <= 0.0f && !expoMode)
526 {
527 screen->removeGrab (grabIndex, NULL);
528 grabIndex = 0;
529 updateWraps (false);
530 }
531
532 cScreen->donePaint ();
533
534 switch (dndState) {
535 case DnDDuring:
536 {
537 if (dndWindow)
538 dndWindow->move (newCursor.x () - prevCursor.x (),
539 newCursor.y () - prevCursor.y (),
540 optionGetExpoImmediateMove ());
541
542 prevCursor = newCursor;
543 cScreen->damageScreen ();
544 }
545 break;
546
547 case DnDStart:
548 {
549 int xOffset, yOffset;
550 CompWindowList::reverse_iterator iter;
551
552 xOffset = screen->vpSize ().width () * screen->width ();
553 yOffset = screen->vpSize ().height () * screen->height ();
554
555 dndState = DnDNone;
556
557 for (iter = screen->windows ().rbegin ();
558 iter != screen->windows ().rend (); ++iter)
559 {
560 CompWindow *w = *iter;
561 CompRect input (w->inputRect ());
562 bool inWindow;
563 int nx, ny;
564
565 if (w->destroyed ())
566 continue;
567
568 if (!w->shaded () && !w->isViewable ())
569 continue;
570
571 if (w->onAllViewports ())
572 {
573 nx = (newCursor.x () + xOffset) % screen->width ();
574 ny = (newCursor.y () + yOffset) % screen->height ();
575 }
576 else
577 {
578 nx = newCursor.x () -
579 (screen->vp ().x () * screen->width ());
580 ny = newCursor.y () -
581 (screen->vp ().y () * screen->height ());
582 }
583
584 inWindow = (nx >= input.left () && nx <= input.right ()) ||
585 (nx >= (input.left () + xOffset) &&
586 nx <= (input.right () + xOffset));
587
588 inWindow &= (ny >= input.top () && ny <= input.bottom ()) ||
589 (ny >= (input.top () + yOffset) &&
590 ny <= (input.bottom () + yOffset));
591
592 if (!inWindow)
593 continue;
594
595 /* make sure we never move windows we're not allowed to move */
596 if (!w->managed ())
597 break;
598 else if (!(w->actions () & CompWindowActionMoveMask))
599 break;
600 else if (w->type () & (CompWindowTypeDockMask |
601 CompWindowTypeDesktopMask))
602 break;
603
604 dndState = DnDDuring;
605 dndWindow = w;
606
607 w->grabNotify (nx, ny, 0,
608 CompWindowGrabMoveMask |
609 CompWindowGrabButtonMask);
610
611 w->raise ();
612 w->moveInputFocusTo ();
613 break;
614 }
615
616 prevCursor = newCursor;
617 }
618 break;
619 default:
620 break;
621 }
622}
623
624void
625ExpoScreen::invertTransformedVertex (const GLScreenPaintAttrib& attrib,
626 const GLMatrix& transform,
627 CompOutput *output,
628 int vertex[2])
629{
630 GLMatrix sTransform (transform);
631 GLdouble p1[3], p2[3], v[3], alpha;
632 GLdouble mvm[16], pm[16];
633 GLint viewport[4];
634 int i;
635
636 gScreen->glApplyTransform (attrib, output, &sTransform);
637 sTransform.toScreenSpace (output, -attrib.zTranslate);
638
639 glGetIntegerv (GL_VIEWPORT, viewport);
640 for (i = 0; i < 16; i++)
641 {
642 mvm[i] = sTransform[i];
643 pm[i] = gScreen->projectionMatrix ()[i];
644 }
645
646 gluUnProject (vertex[0], screen->height () - vertex[1], 0, mvm, pm,
647 viewport, &p1[0], &p1[1], &p1[2]);
648 gluUnProject (vertex[0], screen->height () - vertex[1], -1.0, mvm, pm,
649 viewport, &p2[0], &p2[1], &p2[2]);
650
651 for (i = 0; i < 3; i++)
652 v[i] = p1[i] - p2[i];
653
654 alpha = -p1[2] / v[2];
655
656 if (optionGetDeform () == DeformCurve && screen->desktopWindowCount ())
657 {
658 const float sws = screen->width () * screen->width ();
659 const float rs = (curveDistance * curveDistance) + 0.25;
660 const float p = ((2.0 * sws * (p1[2] - curveDistance) * v[2]) +
661 (2.0 * p1[0] * v[0]) -
662 (v[0] * (float) screen->width ())) /
663 ((v[2] * v[2] * sws) + (v[0] * v[0]));
664 const float q = (-(sws * rs) + (sws * (p1[2] - curveDistance) *
665 (p1[2] - curveDistance)) +
666 (0.25 * sws) + (p1[0] * p1[0]) -
667 (p1[0] * (float) screen->width ())) /
668 ((v[2] * v[2] * sws) + (v[0] * v[0]));
669
670 const float rq = (0.25 * p * p) - q;
671 const float ph = -p * 0.5;
672
673 if (rq < 0.0)
674 {
675 vertex[0] = -1000;
676 vertex[1] = -1000;
677 return;
678 }
679 else
680 {
681 alpha = ph + sqrt(rq);
682 if (p1[2] + (alpha * v[2]) > 0.0)
683 {
684 vertex[0] = -1000;
685 vertex[1] = -1000;
686 return;
687 }
688 }
689 }
690
691 vertex[0] = ceil (p1[0] + (alpha * v[0]));
692 vertex[1] = ceil (p1[1] + (alpha * v[1]));
693}
694
695void
696ExpoScreen::paintWall (const GLScreenPaintAttrib& attrib,
697 const GLMatrix& transform,
698 const CompRegion& region,
699 CompOutput *output,
700 unsigned int mask,
701 bool reflection)
702{
703 GLMatrix sTransformW, sTransform (transform);
704 int i, j, vp;
705 GLenum oldFilter = gScreen->textureFilter ();
706
707 float sx = (float) screen->width () / output->width ();
708 float sy = (float) screen->height () / output->height ();
709 float biasZ;
710 float oScale, rotation = 0.0f, progress, vpp;
711 float aspectX = 1.0f, aspectY = 1.0f;
712 GLVector cam;
713 CompPoint vpSize (screen->vpSize ().width (), screen->vpSize ().height ());
714
715 /* amount of gap between viewports */
716 const float gapY = optionGetVpDistance () * 0.1f * expoCam;
717 const float gapX = optionGetVpDistance () * 0.1f * screen->height () /
718 screen->width () * expoCam;
719
720 int glPaintTransformedOutputIndex =
721 gScreen->glPaintTransformedOutputGetCurrentIndex ();
722
723 // Make sure that the base glPaintTransformedOutput function is called
724 gScreen->glPaintTransformedOutputSetCurrentIndex (MAXSHORT);
725
726 /* Zoom animation stuff */
727 /* camera position for the selected viewport */
728 GLVector vpCamPos (0, 0, 0, 0);
729
730 /* camera position during expo mode */
731 GLVector expoCamPos (0, 0, 0, 0);
732
733 if (optionGetDeform () == DeformCurve)
734 {
735 vpCamPos[GLVector::x] = -sx * (0.5 - (((float) output->x () +
736 (output->width () / 2.0)) /
737 (float) screen->width ()));
738 }
739 else
740 {
741 vpCamPos[GLVector::x] = (screen->vp ().x () * sx) + 0.5 +
742 (output->x () / output->width ()) -
743 (vpSize.x () * 0.5 * sx) +
744 gapX * screen->vp ().x ();
745 }
746 vpCamPos[GLVector::y] = -((screen->vp ().y () * sy) + 0.5 +
747 (output->y () / output->height ())) +
748 (vpSize.y () * 0.5 * sy) -
749 gapY * screen->vp ().y ();
750
751 biasZ = MAX (vpSize.x () * sx, vpSize.y () * sy);
752 if (optionGetDeform () == DeformTilt || optionGetReflection ())
753 biasZ *= (0.15 + optionGetDistance ());
754 else
755 biasZ *= optionGetDistance ();
756
757 progress = sigmoidProgress (expoCam);
758
759 if (optionGetDeform () != DeformCurve)
760 expoCamPos[GLVector::x] = gapX * (vpSize.x () - 1) * 0.5;
761
762 expoCamPos[GLVector::y] = -gapY * (vpSize.y () - 1) * 0.5;
763 expoCamPos[GLVector::z] = -DEFAULT_Z_CAMERA + DEFAULT_Z_CAMERA *
764 (MAX (vpSize.x () + (vpSize.x () - 1) * gapX,
765 vpSize.y () + (vpSize.y () - 1) * gapY) +
766 biasZ);
767
768 /* interpolate between vpCamPos and expoCamPos */
769 cam[GLVector::x] = vpCamPos[GLVector::x] * (1 - progress) +
770 expoCamPos[GLVector::x] * progress;
771 cam[GLVector::y] = vpCamPos[GLVector::y] * (1 - progress) +
772 expoCamPos[GLVector::y] * progress;
773 cam[GLVector::z] = vpCamPos[GLVector::z] * (1 - progress) +
774 expoCamPos[GLVector::z] * progress;
775
776 if (vpSize.x () > vpSize.y ())
777 {
778 aspectY = (float) vpSize.x () / (float) vpSize.y ();
779 aspectY -= 1.0;
780 aspectY *= -optionGetAspectRatio () + 1.0;
781 aspectY *= progress;
782 aspectY += 1.0;
783 }
784 else
785 {
786 aspectX = (float) vpSize.y () / (float) vpSize.x ();
787 aspectX -= 1.0;
788 aspectX *= -optionGetAspectRatio () + 1.0;
789 aspectX *= progress;
790 aspectX += 1.0;
791 }
792
793 /* End of Zoom animation stuff */
794
795 if (optionGetDeform () == DeformTilt)
796 {
797 if (optionGetExpoAnimation () == ExpoAnimationZoom)
798 rotation = 10.0 * sigmoidProgress (expoCam);
799 else
800 rotation = 10.0 * expoCam;
801 }
802
803 if (optionGetMipmaps ())
804 gScreen->setTextureFilter (GL_LINEAR_MIPMAP_LINEAR);
805
806 /* ALL TRANSFORMATION ARE EXECUTED FROM BOTTOM TO TOP */
807
808 oScale = 1 / (1 + ((MAX (sx, sy) - 1) * progress));
809
810 sTransform.scale (oScale, oScale, 1.0);
811
812 /* zoom out */
813 oScale = DEFAULT_Z_CAMERA / (cam[GLVector::z] + DEFAULT_Z_CAMERA);
814 sTransform.scale (oScale, oScale, oScale);
815 glNormal3f (0.0, 0.0, -oScale);
816 sTransform.translate (-cam[GLVector::x], -cam[GLVector::y],
817 -cam[GLVector::z] - DEFAULT_Z_CAMERA);
818
819 if (reflection)
820 {
821 float scaleFactor = optionGetScaleFactor ();
822
823 sTransform.translate (0.0,
824 (vpSize.y () + ((vpSize.y () - 1) * gapY * 2)) *
825 -sy * aspectY,
826 0.0);
827 sTransform.scale (1.0, -1.0, 1.0);
828 sTransform.translate (0.0,
829 - (1 - scaleFactor) / 2 * sy * aspectY *
830 (vpSize.y () + ((vpSize.y () - 1) * gapY * 2)),
831 0.0);
832 sTransform.scale (1.0, scaleFactor, 1.0);
833 glCullFace (GL_FRONT);
834 }
835
836 /* rotate */
837 sTransform.rotate (rotation, 0.0f, 1.0f, 0.0f);
838 sTransform.scale (aspectX, aspectY, 1.0);
839
840 /* translate expo to center */
841 sTransform.translate (vpSize.x () * sx * -0.5,
842 vpSize.y () * sy * 0.5, 0.0f);
843
844 if (optionGetDeform () == DeformCurve)
845 sTransform.translate ((vpSize.x () - 1) * sx * 0.5, 0.0, 0.0);
846
847 sTransformW = sTransform;
848
849 /* revert prepareXCoords region shift. Now all screens display the same */
850 sTransform.translate (0.5f, -0.5f, DEFAULT_Z_CAMERA);
851
852 if (vpSize.x () > 2)
853 /* we can't have 90 degree for the left/right most viewport */
854 curveAngle = interpolate (359 / ((vpSize.x () - 1) * 2), 1,
855 optionGetCurve ());
856 else
857 curveAngle = interpolate (180 / vpSize.x (), 1, optionGetCurve ());
858
859 curveDistance = ((0.5f * sx) + (gapX / 2.0)) /
860 tanf ((M_PI / 180.0f) * curveAngle / 2.0);
861 curveRadius = ((0.5f * sx) + (gapX / 2.0)) /
862 sinf ((M_PI / 180.0f) * curveAngle / 2.0);
863
864 expoActive = true;
865
866 for (j = 0; j < vpSize.y (); j++)
867 {
868 GLMatrix sTransform2 (sTransform), sTransform3;
869
870 for (i = 0; i < vpSize.x (); i++)
871 {
872 if (optionGetExpoAnimation () == ExpoAnimationVortex)
873 sTransform2.rotate (360 * expoCam,
874 0.0f, 1.0f, 2.0f * expoCam);
875
876 sTransform3 = sTransform2;
877
878 sTransform3.translate (output->x () / output->width (),
879 -output->y () / output->height (), 0.0);
880
881 cScreen->setWindowPaintOffset ((screen->vp ().x () - i) *
882 screen->width (),
883 (screen->vp ().y () - j) *
884 screen->height ());
885
886 vp = (j * vpSize.x ()) + i;
887
888 vpp = (expoCam * vpActivity[vp]) + (1 - expoCam);
889 vpp = sigmoidProgress (vpp);
890
891 vpBrightness = vpp + ((1.0 - vpp) *
892 optionGetVpBrightness () / 100.0);
893 vpSaturation = vpp + ((1.0 - vpp) *
894 optionGetVpSaturation () / 100.0);
895
896 paintingVp.set (i, j);
897
898 if (optionGetDeform () == DeformCurve)
899 {
900 float rotateX;
901
902 sTransform3.translate (-vpCamPos[GLVector::x], 0.0f,
903 curveDistance - DEFAULT_Z_CAMERA);
904
905 rotateX = -i + interpolate (((float) vpSize.x () / 2.0) - 0.5,
906 screen->vp ().x (), progress);
907
908 sTransform3.rotate (curveAngle * rotateX, 0.0, 1.0, 0.0);
909
910 sTransform3.translate (vpCamPos[GLVector::x], 0.0f,
911 DEFAULT_Z_CAMERA - curveDistance);
912 }
913
914 gScreen->glPaintTransformedOutput (attrib, sTransform3,
915 screen->region (), output,
916 mask);
917
918 if (!reflection)
919 {
920 int cursor[2] = { pointerX, pointerY };
921
922 invertTransformedVertex (attrib, sTransform3,
923 output, cursor);
924
925 if ((cursor[0] > 0) && (cursor[0] < (int) screen->width ()) &&
926 (cursor[1] > 0) && (cursor[1] < (int) screen->height ()))
927 {
928 newCursor.setX (i * screen->width () + cursor[0]);
929 newCursor.setY (j * screen->height () + cursor[1]);
930
931 if (anyClick || dndState != DnDNone)
932 {
933 /* Used to save last viewport interaction was in */
934 lastSelectedVp = selectedVp;
935 selectedVp.set (i, j);
936 anyClick = false;
937 }
938 }
939 }
940
941 /* not sure this will work with different resolutions */
942 if (optionGetDeform () != DeformCurve)
943 sTransform2.translate (sx + gapX, 0.0f, 0.0);
944 }
945
946 /* not sure this will work with different resolutions */
947 sTransform.translate (0.0, -(sy + gapY), 0.0f);
948 }
949
950 glNormal3f (0.0, 0.0, -1.0);
951
952 if (reflection)
953 {
954 glEnable (GL_BLEND);
955 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
956
957 glPushMatrix ();
958
959 if (optionGetDeform () != DeformCurve)
960 {
961 glLoadMatrixf (sTransformW.getMatrix ());
962
963 glBegin (GL_QUADS);
964 glColor4f (0.0, 0.0, 0.0, 1.0);
965 glVertex2f (0.0, 0.0);
966 glColor4f (0.0, 0.0, 0.0, 0.5);
967 glVertex2f (0.0, -vpSize.y () * (sy + gapY));
968 glVertex2f (vpSize.x () * sx * (1.0 + gapX),
969 -vpSize.y () * sy * (1.0 + gapY));
970 glColor4f (0.0, 0.0, 0.0, 1.0);
971 glVertex2f (vpSize.x () * sx * (1.0 + gapX), 0.0);
972 glEnd ();
973 }
974 else
975 {
976 glCullFace (GL_BACK);
977 glLoadIdentity ();
978 glTranslatef (0.0, 0.0, -DEFAULT_Z_CAMERA);
979
980 glBegin (GL_QUADS);
981 glColor4f (0.0, 0.0, 0.0, 1.0 * expoCam);
982 glVertex2f (-0.5, -0.5);
983 glVertex2f (0.5, -0.5);
984 glColor4f (0.0, 0.0, 0.0, 0.5 * expoCam);
985 glVertex2f (0.5, 0.0);
986 glVertex2f (-0.5, 0.0);
987 glColor4f (0.0, 0.0, 0.0, 0.5 * expoCam);
988 glVertex2f (-0.5, 0.0);
989 glVertex2f (0.5, 0.0);
990 glColor4f (0.0, 0.0, 0.0, 0.0);
991 glVertex2f (0.5, 0.5);
992 glVertex2f (-0.5, 0.5);
993 glEnd ();
994 }
995 glCullFace (GL_BACK);
996
997 glLoadIdentity ();
998 glTranslatef (0.0, 0.0, -DEFAULT_Z_CAMERA);
999
1000 if (optionGetGroundSize () > 0.0)
1001 {
1002 glBegin (GL_QUADS);
1003 glColor4usv (optionGetGroundColor1 ());
1004 glVertex2f (-0.5, -0.5);
1005 glVertex2f (0.5, -0.5);
1006 glColor4usv (optionGetGroundColor2 ());
1007 glVertex2f (0.5, -0.5 + optionGetGroundSize ());
1008 glVertex2f (-0.5, -0.5 + optionGetGroundSize ());
1009 glEnd ();
1010 }
1011
1012 glColor4usv (defaultColor);
1013
1014 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1015 glDisable (GL_BLEND);
1016 glPopMatrix ();
1017 }
1018
1019 expoActive = false;
1020
1021 cScreen->setWindowPaintOffset (0, 0);
1022
1023 gScreen->glPaintTransformedOutputSetCurrentIndex (glPaintTransformedOutputIndex);
1024 gScreen->setTextureFilter (oldFilter);
1025}
1026
1027bool
1028ExpoScreen::glPaintOutput (const GLScreenPaintAttrib& attrib,
1029 const GLMatrix& transform,
1030 const CompRegion& region,
1031 CompOutput *output,
1032 unsigned int mask)
1033{
1034 if (expoCam > 0.0)
1035 mask |= PAINT_SCREEN_TRANSFORMED_MASK | PAINT_SCREEN_CLEAR_MASK;
1036
1037 return gScreen->glPaintOutput (attrib, transform, region, output, mask);
1038}
1039
1040void
1041ExpoScreen::glPaintTransformedOutput (const GLScreenPaintAttrib& attrib,
1042 const GLMatrix& transform,
1043 const CompRegion& region,
1044 CompOutput *output,
1045 unsigned int mask)
1046{
1047 expoActive = false;
1048
1049 if (expoCam > 0)
1050 mask |= PAINT_SCREEN_CLEAR_MASK;
1051
1052 if (expoCam <= 0 || (expoCam > 0.0 && expoCam < 1.0 &&
1053 optionGetExpoAnimation () != ExpoAnimationZoom))
1054 {
1055 gScreen->glPaintTransformedOutput (attrib, transform, region,
1056 output, mask);
1057 }
1058 else
1059 {
1060 gScreen->clearOutput (output, GL_COLOR_BUFFER_BIT);
1061 }
1062
1063 mask &= ~PAINT_SCREEN_CLEAR_MASK;
1064
1065 if (expoCam > 0.0)
1066 {
1067 if (optionGetReflection ())
1068 paintWall (attrib, transform, region, output, mask, true);
1069
1070 paintWall (attrib, transform, region, output, mask, false);
1071 anyClick = false;
1072 }
1073}
1074
1075bool
1076ExpoWindow::glDraw (const GLMatrix& transform,
1077 GLFragment::Attrib& fragment,
1078 const CompRegion& region,
1079 unsigned int mask)
1080{
1081 if (eScreen->expoCam == 0.0f)
1082 return gWindow->glDraw (transform, fragment, region, mask);
1083
1084 GLFragment::Attrib fA (fragment);
1085 int expoAnimation;
1086
1087 expoAnimation = eScreen->optionGetExpoAnimation ();
1088
1089 if (eScreen->expoActive)
1090 {
1091 if (expoAnimation != ExpoScreen::ExpoAnimationZoom)
1092 fA.setOpacity (fragment.getOpacity () * eScreen->expoCam);
1093
1094 if (window->wmType () & CompWindowTypeDockMask &&
1095 eScreen->optionGetHideDocks ())
1096 {
1097 if (expoAnimation == ExpoScreen::ExpoAnimationZoom &&
1098 eScreen->paintingVp == eScreen->selectedVp)
1099 {
1100 fA.setOpacity (fragment.getOpacity () *
1101 (1 - sigmoidProgress (eScreen->expoCam)));
1102 }
1103 else
1104 {
1105 fA.setOpacity (0);
1106 }
1107 }
1108
1109 fA.setBrightness (fragment.getBrightness () * eScreen->vpBrightness);
1110 fA.setSaturation (fragment.getSaturation () * eScreen->vpSaturation);
1111 }
1112 else
1113 {
1114 if (expoAnimation == ExpoScreen::ExpoAnimationZoom)
1115 fA.setBrightness (0);
1116 else
1117 fA.setBrightness (fragment.getBrightness () *
1118 (1 - sigmoidProgress (eScreen->expoCam)));
1119 }
1120
1121 return gWindow->glDraw (transform, fA, region, mask);
1122}
1123
1124#define EXPO_GRID_SIZE 100
1125
1126void
1127ExpoWindow::glAddGeometry (const GLTexture::MatrixList& matrices,
1128 const CompRegion& region,
1129 const CompRegion& clip,
1130 unsigned int maxGridWidth,
1131 unsigned int maxGridHeight)
1132{
1133 if (eScreen->expoCam > 0.0 &&
1134 screen->desktopWindowCount () &&
1135 eScreen->optionGetDeform () == ExpoScreen::DeformCurve)
1136 {
1137 int i, oldVCount = gWindow->geometry ().vCount;
1138 GLfloat *v;
1139 CompPoint offset;
1140 float lastX, lastZ = 0.0;
1141 const float radSquare = pow (eScreen->curveDistance, 2) + 0.25;
1142 float ang;
1143
1144 gWindow->glAddGeometry (matrices, region, clip,
1145 MIN(maxGridWidth , EXPO_GRID_SIZE),
1146 maxGridHeight);
1147
1148 v = gWindow->geometry ().vertices;
1149 v += gWindow->geometry ().vertexStride - 3;
1150 v += gWindow->geometry ().vertexStride * oldVCount;
1151
1152 if (!window->onAllViewports ())
1153 {
1154 offset = eScreen->cScreen->windowPaintOffset ();
1155 offset = window->getMovementForOffset (offset);
1156 }
1157
1158 lastX = -1000000000.0;
1159
1160 for (i = oldVCount; i < gWindow->geometry ().vCount; i++)
1161 {
1162 if (v[0] == lastX)
1163 {
1164 v[2] = lastZ;
1165 }
1166 else if (v[0] + offset.x () >= -EXPO_GRID_SIZE &&
1167 v[0] + offset.x () < screen->width () + EXPO_GRID_SIZE)
1168 {
1169 ang = (((v[0] + offset.x ()) / (float) screen->width ()) - 0.5);
1170 ang *= ang;
1171 if (ang < radSquare)
1172 {
1173 v[2] = eScreen->curveDistance - sqrt (radSquare - ang);
1174 v[2] *= sigmoidProgress (eScreen->expoCam);
1175 }
1176 }
1177
1178 lastX = v[0];
1179 lastZ = v[2];
1180
1181 v += gWindow->geometry ().vertexStride;
1182 }
1183 }
1184 else
1185 {
1186 gWindow->glAddGeometry (matrices, region, clip, maxGridWidth, maxGridHeight);
1187 }
1188}
1189
1190void
1191ExpoWindow::glDrawTexture (GLTexture *texture,
1192 GLFragment::Attrib& attrib,
1193 unsigned int mask)
1194{
1195 if (eScreen->expoCam > 0.0 &&
1196 eScreen->optionGetDeform () == ExpoScreen::DeformCurve &&
1197 eScreen->gScreen->lighting () &&
1198 screen->desktopWindowCount ())
1199 {
1200 unsigned int i, idx, vCount;
1201 CompPoint offset;
1202 float x;
1203 GLfloat *v;
1204
1205 vCount = gWindow->geometry ().vCount;
1206
1207 if (eScreen->winNormals.size () < vCount * 3)
1208 eScreen->winNormals.resize (vCount * 3);
1209
1210 if (!window->onAllViewports ())
1211 {
1212 offset = eScreen->cScreen->windowPaintOffset ();
1213 offset = window->getMovementForOffset (offset);
1214 }
1215
1216 v = gWindow->geometry ().vertices +
1217 (gWindow->geometry ().vertexStride - 3);
1218
1219 for (i = 0; i < vCount; i++)
1220 {
1221 x = (float) (v[0] + offset.x () - screen->width () / 2) *
1222 eScreen->curveAngle / screen->width ();
1223
1224 while (x < 0)
1225 x += 360.0;
1226
1227 idx = floor (x);
1228
1229 eScreen->winNormals[i * 3] = -eScreen->vpNormals[idx * 3];
1230 eScreen->winNormals[(i * 3) + 1] =
1231 eScreen->vpNormals[(idx * 3) + 1];
1232 eScreen->winNormals[(i * 3) + 2] =
1233 eScreen->vpNormals[(idx * 3) + 2];
1234
1235 v += gWindow->geometry ().vertexStride;
1236 }
1237
1238 glEnable (GL_NORMALIZE);
1239 glNormalPointer (GL_FLOAT,0, &eScreen->winNormals.at (0));
1240
1241 glEnableClientState (GL_NORMAL_ARRAY);
1242
1243 gWindow->glDrawTexture (texture, attrib, mask);
1244
1245 glDisable (GL_NORMALIZE);
1246 glDisableClientState (GL_NORMAL_ARRAY);
1247 glNormal3f (0.0, 0.0, -1.0);
1248 }
1249 else
1250 {
1251 glEnable (GL_NORMALIZE);
1252 gWindow->glDrawTexture (texture, attrib, mask);
1253 glDisable (GL_NORMALIZE);
1254 }
1255}
1256
1257bool
1258ExpoWindow::glPaint (const GLWindowPaintAttrib& attrib,
1259 const GLMatrix& transform,
1260 const CompRegion& region,
1261 unsigned int mask)
1262{
1263 if (eScreen->expoActive)
1264 {
1265 float opacity = 1.0;
1266 bool hide;
1267 bool zoomAnim;
1268
1269 zoomAnim = eScreen->optionGetExpoAnimation () ==
1270 ExpoScreen::ExpoAnimationZoom;
1271 hide = eScreen->optionGetHideDocks () &&
1272 (window->wmType () & CompWindowTypeDockMask);
1273
1274 if (eScreen->expoCam > 0.0)
1275 {
1276 if (eScreen->expoCam < 1.0 && !zoomAnim)
1277 mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
1278 else if (hide)
1279 mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
1280 }
1281
1282 if (!zoomAnim)
1283 opacity = attrib.opacity * eScreen->expoCam;
1284
1285 if (hide)
1286 {
1287 if (zoomAnim && eScreen->paintingVp == eScreen->selectedVp)
1288 opacity = attrib.opacity *
1289 (1 - sigmoidProgress (eScreen->expoCam));
1290 else
1291 opacity = 0;
1292 }
1293
1294 if (opacity <= 0)
1295 mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
1296 }
1297
1298 return gWindow->glPaint (attrib, transform, region, mask);
1299}
1300
1301bool
1302ExpoWindow::damageRect (bool initial,
1303 const CompRect& rect)
1304{
1305 if (eScreen->expoCam > 0.0f)
1306 eScreen->cScreen->damageScreen ();
1307
1308 return cWindow->damageRect (initial, rect);
1309}
1310
1311#define EXPOINITBIND(opt, func) \
1312 optionSet##opt##Initiate (boost::bind (&ExpoScreen::func, \
1313 this, _1, _2, _3));
1314#define EXPOTERMBIND(opt, func) \
1315 optionSet##opt##Terminate (boost::bind (&ExpoScreen::func, \
1316 this, _1, _2, _3));
1317
1318ExpoScreen::ExpoScreen (CompScreen *s) :
1319 PluginClassHandler<ExpoScreen, CompScreen> (s),
1320 ExpoOptions (),
1321 cScreen (CompositeScreen::get (s)),
1322 gScreen (GLScreen::get (s)),
1323 expoCam (0.0f),
1324 expoActive (false),
1325 expoMode (false),
1326 dndState (DnDNone),
1327 dndWindow (NULL),
1328 origVp (s->vp ()),
1329 selectedVp (s->vp ()),
1330 lastSelectedVp (s->vp ()),
1331 vpUpdateMode (VPUpdateNone),
1332 clickTime (0),
1333 doubleClick (false),
1334 vpNormals (360 * 3),
1335 grabIndex (0)
1336{
1337 leftKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Left"));
1338 rightKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Right"));
1339 upKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Up"));
1340 downKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Down"));
1341
1342 EXPOINITBIND (ExpoKey, doExpo);
1343 EXPOTERMBIND (ExpoKey, termExpo);
1344 EXPOINITBIND (ExpoButton, doExpo);
1345 EXPOTERMBIND (ExpoButton, termExpo);
1346 EXPOINITBIND (ExpoEdge, doExpo);
1347 EXPOTERMBIND (ExpoButton, termExpo);
1348
1349 EXPOINITBIND (DndButton, dndInit);
1350 EXPOTERMBIND (DndButton, dndFini);
1351 EXPOINITBIND (ExitButton, exitExpo);
1352 EXPOINITBIND (NextVpButton, nextVp);
1353 EXPOINITBIND (PrevVpButton, prevVp);
1354
1355 ScreenInterface::setHandler (screen, false);
1356 CompositeScreenInterface::setHandler (cScreen, false);
1357 GLScreenInterface::setHandler (gScreen, false);
1358}
1359
1360ExpoWindow::ExpoWindow (CompWindow *w) :
1361 PluginClassHandler<ExpoWindow, CompWindow> (w),
1362 window (w),
1363 cWindow (CompositeWindow::get (w)),
1364 gWindow (GLWindow::get (w)),
1365 eScreen (ExpoScreen::get (screen))
1366{
1367 CompositeWindowInterface::setHandler (cWindow, false);
1368 GLWindowInterface::setHandler (gWindow, false);
1369}
1370
1371bool
1372ExpoPluginVTable::init ()
1373{
1374 if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
1375 !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
1376 !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
1377 return false;
1378
1379 return true;
1380}
1381
1382
13830
=== removed file '.pc/expo.patch/expo/src/expo.h'
--- .pc/expo.patch/expo/src/expo.h 2012-02-13 15:30:29 +0000
+++ .pc/expo.patch/expo/src/expo.h 1970-01-01 00:00:00 +0000
@@ -1,163 +0,0 @@
1/**
2 *
3 * Compiz expo plugin
4 *
5 * expo.c
6 *
7 * Copyright (c) 2008 Dennis Kasprzyk <racarr@opencompositing.org>
8 * Copyright (c) 2006 Robert Carr <racarr@beryl-project.org>
9 *
10 * Authors:
11 * Robert Carr <racarr@beryl-project.org>
12 * Dennis Kasprzyk <onestone@opencompositing.org>
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 **/
25
26#include <core/core.h>
27#include <core/pluginclasshandler.h>
28
29#include <composite/composite.h>
30#include <opengl/opengl.h>
31
32#include "expo_options.h"
33
34class ExpoScreen :
35 public ScreenInterface,
36 public CompositeScreenInterface,
37 public GLScreenInterface,
38 public PluginClassHandler<ExpoScreen, CompScreen>,
39 public ExpoOptions
40{
41 public:
42 ExpoScreen (CompScreen *);
43
44 void handleEvent (XEvent *);
45
46 void preparePaint (int);
47 void paint (CompOutput::ptrList&, unsigned int);
48 void donePaint ();
49
50 bool glPaintOutput (const GLScreenPaintAttrib&, const GLMatrix&,
51 const CompRegion&, CompOutput *, unsigned int);
52 void glPaintTransformedOutput (const GLScreenPaintAttrib&,
53 const GLMatrix&, const CompRegion&,
54 CompOutput *, unsigned int);
55
56 bool dndInit (CompAction *, CompAction::State, CompOption::Vector&);
57 bool dndFini (CompAction *, CompAction::State, CompOption::Vector&);
58 bool doExpo (CompAction *, CompAction::State, CompOption::Vector&);
59 bool exitExpo (CompAction *, CompAction::State, CompOption::Vector&);
60 bool termExpo (CompAction *, CompAction::State, CompOption::Vector&);
61 bool nextVp (CompAction *, CompAction::State, CompOption::Vector&);
62 bool prevVp (CompAction *, CompAction::State, CompOption::Vector&);
63
64 typedef enum {
65 DnDNone,
66 DnDDuring,
67 DnDStart
68 } DnDState;
69
70 typedef enum {
71 VPUpdateNone,
72 VPUpdateMouseOver,
73 VPUpdatePrevious
74 } VPUpdateMode;
75
76 CompositeScreen *cScreen;
77 GLScreen *gScreen;
78
79 float expoCam;
80 bool expoActive;
81 bool expoMode;
82
83 DnDState dndState;
84 CompWindow *dndWindow;
85
86 CompPoint prevCursor;
87 CompPoint newCursor;
88
89 CompPoint origVp;
90 CompPoint selectedVp;
91 CompPoint lastSelectedVp;
92 CompPoint paintingVp;
93
94 std::vector<float> vpActivity;
95 float vpBrightness;
96 float vpSaturation;
97
98 VPUpdateMode vpUpdateMode;
99
100 bool anyClick;
101 unsigned int clickTime;
102 bool doubleClick;
103
104 CompRegion tmpRegion;
105
106 float curveAngle;
107 float curveDistance;
108 float curveRadius;
109
110 std::vector<GLfloat> vpNormals;
111 std::vector<GLfloat> winNormals;
112
113 CompScreen::GrabHandle grabIndex;
114
115 private:
116 void moveFocusViewport (int, int);
117 void finishWindowMovement ();
118 void updateWraps (bool);
119
120 void invertTransformedVertex (const GLScreenPaintAttrib&,
121 const GLMatrix&, CompOutput *, int[2]);
122 void paintWall (const GLScreenPaintAttrib&, const GLMatrix&,
123 const CompRegion&, CompOutput *, unsigned int, bool);
124
125 KeyCode leftKey;
126 KeyCode rightKey;
127 KeyCode upKey;
128 KeyCode downKey;
129};
130
131class ExpoWindow :
132 public CompositeWindowInterface,
133 public GLWindowInterface,
134 public PluginClassHandler<ExpoWindow, CompWindow>
135{
136 public:
137 ExpoWindow (CompWindow *);
138
139 bool damageRect (bool, const CompRect&);
140
141 bool glDraw (const GLMatrix&, GLFragment::Attrib&,
142 const CompRegion&, unsigned int);
143 bool glPaint (const GLWindowPaintAttrib&, const GLMatrix&,
144 const CompRegion&, unsigned int);
145 void glAddGeometry (const GLTexture::MatrixList&,
146 const CompRegion&, const CompRegion&,
147 unsigned int, unsigned int);
148 void glDrawTexture (GLTexture *, GLFragment::Attrib& attrib,
149 unsigned int);
150
151 CompWindow *window;
152 CompositeWindow *cWindow;
153 GLWindow *gWindow;
154 ExpoScreen *eScreen;
155};
156
157class ExpoPluginVTable :
158 public CompPlugin::VTableForScreenAndWindow<ExpoScreen, ExpoWindow>
159{
160 public:
161 bool init ();
162};
163
1640
=== removed file '.pc/expo.patch/expo/src/glow.cpp'
=== removed file '.pc/expo.patch/expo/src/glow.h'
=== removed file '.pc/expo.patch/expo/src/group_glow.h'
=== removed file '.pc/expo.patch/glow.cpp'
=== removed file '.pc/expo.patch/glow.h'
=== removed file '.pc/expo.patch/group_glow.h'
=== removed directory '.pc/expo_api_931927.patch'
=== removed directory '.pc/expo_api_931927.patch/expo'
=== removed directory '.pc/expo_api_931927.patch/expo/src'
=== removed file '.pc/expo_api_931927.patch/expo/src/expo.cpp'
--- .pc/expo_api_931927.patch/expo/src/expo.cpp 2012-02-16 15:14:05 +0000
+++ .pc/expo_api_931927.patch/expo/src/expo.cpp 1970-01-01 00:00:00 +0000
@@ -1,1692 +0,0 @@
1/**
2 *
3 * Compiz expo plugin
4 *
5 * expo.c
6 *
7 * Copyright (c) 2008 Dennis Kasprzyk <racarr@opencompositing.org>
8 * Copyright (c) 2006 Robert Carr <racarr@beryl-project.org>
9 *
10 * Authors:
11 * Robert Carr <racarr@beryl-project.org>
12 * Dennis Kasprzyk <onestone@opencompositing.org>
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 **/
25
26#include "expo.h"
27#include <math.h>
28#include <GL/glu.h>
29#include <X11/cursorfont.h>
30
31COMPIZ_PLUGIN_20090315 (expo, ExpoPluginVTable);
32
33#define sigmoid(x) (1.0f / (1.0f + exp (-5.5f * 2 * ((x) - 0.5))))
34#define sigmoidProgress(x) ((sigmoid (x) - sigmoid (0)) / \
35 (sigmoid (1) - sigmoid (0)))
36
37#define interpolate(a, b, val) (((val) * (a)) + ((1 - (val)) * (b)))
38
39bool
40ExpoScreen::dndInit (CompAction *action,
41 CompAction::State state,
42 CompOption::Vector& options)
43{
44 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
45 if (xid != screen->root ())
46 return false;
47
48 if (expoMode)
49 {
50 dndState = DnDStart;
51 action->setState (action->state () | CompAction::StateTermButton);
52 cScreen->damageScreen ();
53
54 return true;
55 }
56
57 return false;
58}
59
60bool
61ExpoScreen::dndFini (CompAction *action,
62 CompAction::State state,
63 CompOption::Vector& options)
64{
65 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
66 if (xid != screen->root ())
67 return false;
68
69 if (dndState == DnDDuring || dndState == DnDStart)
70 {
71 if (dndWindows.size ())
72 finishWindowMovement ();
73
74 dndState = DnDNone;
75
76 action->setState (action->state () & CompAction::StateInitButton);
77 cScreen->damageScreen ();
78
79 return true;
80 }
81
82 return false;
83}
84
85bool
86ExpoScreen::doExpo (CompAction *action,
87 CompAction::State state,
88 CompOption::Vector& options)
89{
90 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
91 if (xid != screen->root ())
92 return false;
93
94 if (screen->otherGrabExist ("expo", NULL))
95 return false;
96
97 if (!expoMode)
98 {
99 if (!grabIndex)
100 grabIndex = screen->pushGrab (None, "expo");
101
102 updateWraps (true);
103
104 expoMode = true;
105 anyClick = false;
106 doubleClick = false;
107 clickTime = 0;
108
109 dndState = DnDNone;
110
111 selectedVp = screen->vp ();
112 origVp = screen->vp ();
113
114 screen->addAction (&optionGetDndButton ());
115 screen->addAction (&optionGetExitButton ());
116 screen->addAction (&optionGetNextVpButton ());
117 screen->addAction (&optionGetPrevVpButton ());
118
119 cScreen->damageScreen ();
120 }
121 else
122 {
123 termExpo (action, state, options);
124 }
125
126 return true;
127}
128
129bool
130ExpoScreen::termExpo (CompAction *action,
131 CompAction::State state,
132 CompOption::Vector& options)
133{
134 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
135 if (xid && xid != screen->root ())
136 return false;
137
138 if (!expoMode)
139 return true;
140
141 expoMode = false;
142
143 if (dndState != DnDNone)
144 dndFini (action, state, options);
145
146 if (state & CompAction::StateCancel)
147 vpUpdateMode = VPUpdatePrevious;
148 else
149 vpUpdateMode = VPUpdateMouseOver;
150
151 screen->removeAction (&optionGetDndButton ());
152 screen->removeAction (&optionGetExitButton ());
153 screen->removeAction (&optionGetNextVpButton ());
154 screen->removeAction (&optionGetPrevVpButton ());
155
156 cScreen->damageScreen ();
157 screen->focusDefaultWindow ();
158
159 return true;
160}
161
162bool
163ExpoScreen::exitExpo (CompAction *action,
164 CompAction::State state,
165 CompOption::Vector& options)
166{
167 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
168 if (xid != screen->root ())
169 return false;
170
171 if (!expoMode)
172 return false;
173
174 termExpo (action, 0, noOptions);
175 anyClick = true;
176 cScreen->damageScreen ();
177
178 return true;
179}
180
181bool
182ExpoScreen::nextVp (CompAction *action,
183 CompAction::State state,
184 CompOption::Vector& options)
185{
186 unsigned int newX, newY;
187 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
188 if (xid != screen->root ())
189 return false;
190
191 if (!expoMode)
192 return false;
193
194 newX = selectedVp.x () + 1;
195 newY = selectedVp.y ();
196
197 if (newX >= (unsigned int) screen->vpSize ().width ())
198 {
199 newX = 0;
200 newY = newY + 1;
201 if (newY >= (unsigned int) screen->vpSize ().height ())
202 newY = 0;
203 }
204
205 moveFocusViewport (newX - selectedVp.x (),
206 newY - selectedVp.y ());
207 cScreen->damageScreen ();
208
209 return true;
210}
211
212bool
213ExpoScreen::prevVp (CompAction *action,
214 CompAction::State state,
215 CompOption::Vector& options)
216{
217 unsigned int newX, newY;
218 Window xid = CompOption::getIntOptionNamed (options, "root", 0);
219 if (xid != screen->root ())
220 return false;
221
222 if (!expoMode)
223 return false;
224
225 newX = selectedVp.x () - 1;
226 newY = selectedVp.y ();
227
228 if (newX < 0)
229 {
230 newX = screen->vpSize ().width () - 1;
231 newY = newY - 1;
232 if (newY < 0)
233 newY = screen->vpSize ().height () - 1;
234 }
235
236 moveFocusViewport (newX - selectedVp.x (),
237 newY - selectedVp.y ());
238 cScreen->damageScreen ();
239
240 return true;
241}
242
243void
244ExpoScreen::moveFocusViewport (int dx,
245 int dy)
246{
247 int newX, newY;
248
249 newX = selectedVp.x () + dx;
250 newY = selectedVp.y () + dy;
251
252 newX = MAX (0, MIN ((int) screen->vpSize ().width () - 1, newX));
253 newY = MAX (0, MIN ((int) screen->vpSize ().height () - 1, newY));
254
255 selectedVp.set (newX, newY);
256 cScreen->damageScreen ();
257}
258
259void
260ExpoScreen::finishWindowMovement ()
261{
262 foreach (CompWindow *dndWindow, dndWindows)
263 {
264 if (dndWindow->grabbed ())
265 {
266 dndWindow->syncPosition ();
267 dndWindow->ungrabNotify ();
268
269 screen->updateGrab (grabIndex, None);
270
271 screen->moveViewport (screen->vp ().x () - selectedVp.x (),
272 screen->vp ().y () - selectedVp.y (), true);
273
274 /* update saved window attributes in case we moved the
275 window to a new viewport */
276 if (dndWindow->saveMask () & CWX)
277 {
278 dndWindow->saveWc ().x = dndWindow->saveWc ().x % screen->width ();
279 if (dndWindow->saveWc ().x < 0)
280 dndWindow->saveWc ().x += screen->width ();
281 }
282 if (dndWindow->saveMask () & CWY)
283 {
284 dndWindow->saveWc ().y = dndWindow->saveWc ().y % screen->height ();
285 if (dndWindow->saveWc ().y < 0)
286 dndWindow->saveWc ().y += screen->height ();
287 }
288
289 /* update window attibutes to make sure a moved maximized window
290 is properly snapped to the work area */
291 if (dndWindow->state () & MAXIMIZE_STATE)
292 dndWindow->updateAttributes (CompStackingUpdateModeNone);
293 }
294 }
295}
296
297void
298ExpoScreen::handleEvent (XEvent *event)
299{
300 switch (event->type) {
301 case KeyPress:
302 if (expoMode && event->xkey.root == screen->root ())
303 {
304 if (event->xkey.keycode == leftKey)
305 moveFocusViewport (-1, 0);
306 else if (event->xkey.keycode == rightKey)
307 moveFocusViewport (1, 0);
308 else if (event->xkey.keycode == upKey)
309 moveFocusViewport (0, -1);
310 else if (event->xkey.keycode == downKey)
311 moveFocusViewport (0, 1);
312 }
313 break;
314
315 case ButtonPress:
316 if (expoMode && event->xbutton.button == Button1 &&
317 event->xbutton.root == screen->root ())
318 {
319 anyClick = true;
320 if (clickTime == 0)
321 {
322 clickTime = event->xbutton.time;
323 }
324 else if (event->xbutton.time - clickTime <=
325 (unsigned int) optionGetDoubleClickTime ())
326 {
327 doubleClick = true;
328 }
329 else
330 {
331 clickTime = event->xbutton.time;
332 doubleClick = false;
333 }
334 cScreen->damageScreen ();
335 }
336 break;
337
338 case ButtonRelease:
339 if (expoMode && event->xbutton.button == Button1 &&
340 event->xbutton.root == screen->root ())
341 {
342 if (event->xbutton.time - clickTime >
343 (unsigned int) optionGetDoubleClickTime ())
344 {
345 clickTime = 0;
346 doubleClick = false;
347 }
348 else if (doubleClick)
349 {
350 CompAction& action = optionGetExpoKey ();
351
352 clickTime = 0;
353 doubleClick = false;
354
355 termExpo (&action, 0, noOptions);
356 anyClick = true;
357 }
358 }
359 break;
360 }
361
362 screen->handleEvent (event);
363}
364
365bool
366ExpoScreen::windowsOnVp (CompPoint &p)
367{
368 foreach (CompWindow *w, screen->clientList (true))
369 {
370 CompPoint viewport;
371
372 screen->viewportForGeometry (w->geometry (), viewport);
373
374 if (viewport == p&&
375 w->type () != CompWindowTypeDesktopMask &&
376 w->type () != CompWindowTypeDockMask)
377 {
378 return true;
379 }
380 }
381
382 return false;
383}
384
385void
386ExpoScreen::preparePaint (int msSinceLastPaint)
387{
388 float val = ((float) msSinceLastPaint / 1000.0) / optionGetZoomTime ();
389
390 if (expoMode)
391 expoCam = MIN (1.0, expoCam + val);
392 else
393 expoCam = MAX (0.0, expoCam - val);
394
395 if (dndState == DnDDuring)
396 {
397 foreach (CompWindow *w, dndWindows)
398 ExpoWindow::get (w)->dndOpacity = MIN (1.0, ExpoWindow::get (w)->dndOpacity + val);
399 }
400 else if (dndState == DnDNone)
401 {
402 CompWindowList::iterator it = dndWindows.begin ();
403
404 while (it != dndWindows.end ())
405 {
406 ExpoWindow::get ((*it))->dndOpacity = MAX (0.0, ExpoWindow::get ((*it))->dndOpacity - val);
407
408 if (ExpoWindow::get ((*it))->dndOpacity <= 0.0f)
409 {
410 dndWindows.erase (it);
411 it = dndWindows.begin ();
412 }
413 else
414 it++;
415 }
416 }
417
418 if (expoCam)
419 {
420 unsigned int i, j, vp;
421 unsigned int vpCount = screen->vpSize ().width () *
422 screen->vpSize ().height ();
423
424 if (vpActivity.size () < vpCount)
425 {
426 vpActivity.resize (vpCount);
427 foreach (float& activity, vpActivity)
428 activity = 1.0f;
429 }
430
431 for (i = 0; i < (unsigned int) screen->vpSize ().width (); i++)
432 {
433 for (j = 0; j < (unsigned int) screen->vpSize ().height (); j++)
434 {
435 vp = (j * screen->vpSize ().width ()) + i;
436 CompPoint vpPos = CompPoint (i, j);
437
438 if (windowsOnVp (vpPos))
439 vpActivity[vp] = MIN (1.0, vpActivity[vp] + val);
440 else
441 vpActivity[vp] = MAX (0.0, vpActivity[vp] - val);
442 }
443 }
444
445 for (i = 0; i < 360; i++)
446 {
447 float fi = (float) i;
448
449 vpNormals[i * 3] = (-sin (fi * (M_PI / 180.0f)) / screen->width ()) *
450 expoCam;
451 vpNormals[(i * 3) + 1] = 0.0;
452 vpNormals[(i * 3) + 2] = (-cos (fi * (M_PI / 180.0f)) * expoCam) -
453 (1 - expoCam);
454 }
455 }
456
457 cScreen->preparePaint (msSinceLastPaint);
458}
459
460void
461ExpoScreen::updateWraps (bool enable)
462{
463 screen->handleEventSetEnabled (this, enable);
464 cScreen->preparePaintSetEnabled (this, enable);
465 cScreen->paintSetEnabled (this, enable);
466 cScreen->donePaintSetEnabled (this, enable);
467 gScreen->glPaintOutputSetEnabled (this, enable);
468 gScreen->glPaintTransformedOutputSetEnabled (this, enable);
469
470 foreach (CompWindow *w, screen->windows ())
471 {
472 ExpoWindow *ew = ExpoWindow::get (w);
473
474 ew->cWindow->damageRectSetEnabled (ew, enable);
475 ew->gWindow->glPaintSetEnabled (ew, enable);
476 ew->gWindow->glDrawSetEnabled (ew, enable);
477 ew->gWindow->glAddGeometrySetEnabled (ew, enable);
478 ew->gWindow->glDrawTextureSetEnabled (ew, enable);
479 }
480}
481
482void
483ExpoScreen::paint (CompOutput::ptrList& outputs,
484 unsigned int mask)
485{
486 int width = outputs.front ()->width ();
487 int height = outputs.front ()->height ();
488 bool sizeDiff = false;
489
490 /* "One big wall" does not make sense where outputs are different
491 * sizes, so force multiple walls in this case
492 *
493 * TODO: Is it possible to re-create "one big wall" using
494 * independent output painting in this case? */
495
496 foreach (CompOutput *o, outputs)
497 {
498 if (o->width () != width || o->height () != height)
499 {
500 sizeDiff = true;
501 break;
502 }
503 }
504
505 if (expoCam > 0.0 && outputs.size () > 1 &&
506 optionGetMultioutputMode () == MultioutputModeOneBigWall &&
507 !sizeDiff)
508 {
509 outputs.clear ();
510 outputs.push_back (&screen->fullscreenOutput ());
511 }
512
513 cScreen->paint (outputs, mask);
514}
515
516void
517ExpoScreen::donePaint ()
518{
519 switch (vpUpdateMode) {
520 case VPUpdateMouseOver:
521 screen->moveViewport (screen->vp ().x () - selectedVp.x (),
522 screen->vp ().y () - selectedVp.y (), true);
523 screen->focusDefaultWindow ();
524 vpUpdateMode = VPUpdateNone;
525 break;
526 case VPUpdatePrevious:
527 screen->moveViewport (screen->vp ().x () - origVp.x (),
528 screen->vp ().y () - origVp.y (), true);
529 selectedVp = origVp;
530 screen->focusDefaultWindow ();
531 vpUpdateMode = VPUpdateNone;
532 break;
533 default:
534 break;
535 }
536
537 if ((expoCam > 0.0f && expoCam < 1.0f) || dndState != DnDNone)
538 cScreen->damageScreen ();
539
540 if (expoCam == 1.0f)
541 {
542 foreach (float& vp, vpActivity)
543 if (vp != 0.0 && vp != 1.0)
544 cScreen->damageScreen ();
545
546 foreach (CompWindow *w, dndWindows)
547 if (ExpoWindow::get (w)->dndOpacity != 0.0f &&
548 ExpoWindow::get (w)->dndOpacity != 1.0f)
549 cScreen->damageScreen ();
550 }
551
552 if (grabIndex && expoCam <= 0.0f && !expoMode)
553 {
554 screen->removeGrab (grabIndex, NULL);
555 grabIndex = 0;
556 updateWraps (false);
557 }
558
559 cScreen->donePaint ();
560
561 switch (dndState) {
562 case DnDDuring:
563 {
564 if (dndWindows.size ())
565 {
566 foreach (CompWindow *dndWindow, dndWindows)
567 {
568 if (dndWindow->grabbed ())
569 {
570 dndWindow->move (newCursor.x () - prevCursor.x (),
571 newCursor.y () - prevCursor.y (),
572 optionGetExpoImmediateMove ());
573 }
574 }
575 }
576
577 prevCursor = newCursor;
578 cScreen->damageScreen ();
579 }
580 break;
581
582 case DnDStart:
583 {
584 int xOffset, yOffset;
585 CompWindowList::reverse_iterator iter;
586
587 xOffset = screen->vpSize ().width () * screen->width ();
588 yOffset = screen->vpSize ().height () * screen->height ();
589
590 dndState = DnDNone;
591
592 for (iter = screen->windows ().rbegin ();
593 iter != screen->windows ().rend (); ++iter)
594 {
595 CompWindow *w = *iter;
596 CompRect input (w->inputRect ());
597 bool inWindow;
598 int nx, ny;
599
600 if (w->destroyed ())
601 continue;
602
603 if (!w->shaded () && !w->isViewable ())
604 continue;
605
606 if (w->onAllViewports ())
607 {
608 nx = (newCursor.x () + xOffset) % screen->width ();
609 ny = (newCursor.y () + yOffset) % screen->height ();
610 }
611 else
612 {
613 nx = newCursor.x () -
614 (screen->vp ().x () * screen->width ());
615 ny = newCursor.y () -
616 (screen->vp ().y () * screen->height ());
617 }
618
619 inWindow = (nx >= input.left () && nx <= input.right ()) ||
620 (nx >= (input.left () + xOffset) &&
621 nx <= (input.right () + xOffset));
622
623 inWindow &= (ny >= input.top () && ny <= input.bottom ()) ||
624 (ny >= (input.top () + yOffset) &&
625 ny <= (input.bottom () + yOffset));
626
627 if (!inWindow)
628 continue;
629
630 /* make sure we never move windows we're not allowed to move */
631 if (!w->managed ())
632 break;
633 else if (!(w->actions () & CompWindowActionMoveMask))
634 break;
635 else if (w->type () & (CompWindowTypeDockMask |
636 CompWindowTypeDesktopMask))
637 break;
638
639 dndState = DnDDuring;
640 dndWindows.push_back (w);
641
642 w->grabNotify (nx, ny, 0,
643 CompWindowGrabMoveMask |
644 CompWindowGrabButtonMask);
645
646 screen->updateGrab (grabIndex, mMoveCursor);
647
648 w->raise ();
649 w->moveInputFocusTo ();
650 break;
651 }
652
653 prevCursor = newCursor;
654 }
655 break;
656 default:
657 break;
658 }
659}
660
661void
662ExpoScreen::invertTransformedVertex (const GLScreenPaintAttrib& attrib,
663 const GLMatrix& transform,
664 CompOutput *output,
665 int vertex[2])
666{
667 GLMatrix sTransform (transform);
668 GLdouble p1[3], p2[3], v[3], alpha;
669 GLdouble mvm[16], pm[16];
670 GLint viewport[4];
671 int i;
672
673 gScreen->glApplyTransform (attrib, output, &sTransform);
674 sTransform.toScreenSpace (output, -attrib.zTranslate);
675
676 glGetIntegerv (GL_VIEWPORT, viewport);
677 for (i = 0; i < 16; i++)
678 {
679 mvm[i] = sTransform[i];
680 pm[i] = gScreen->projectionMatrix ()[i];
681 }
682
683 gluUnProject (vertex[0], screen->height () - vertex[1], 0, mvm, pm,
684 viewport, &p1[0], &p1[1], &p1[2]);
685 gluUnProject (vertex[0], screen->height () - vertex[1], -1.0, mvm, pm,
686 viewport, &p2[0], &p2[1], &p2[2]);
687
688 for (i = 0; i < 3; i++)
689 v[i] = p1[i] - p2[i];
690
691 alpha = -p1[2] / v[2];
692
693 if (optionGetDeform () == DeformCurve && screen->desktopWindowCount ())
694 {
695 const float sws = screen->width () * screen->width ();
696 const float rs = (curveDistance * curveDistance) + 0.25;
697 const float p = ((2.0 * sws * (p1[2] - curveDistance) * v[2]) +
698 (2.0 * p1[0] * v[0]) -
699 (v[0] * (float) screen->width ())) /
700 ((v[2] * v[2] * sws) + (v[0] * v[0]));
701 const float q = (-(sws * rs) + (sws * (p1[2] - curveDistance) *
702 (p1[2] - curveDistance)) +
703 (0.25 * sws) + (p1[0] * p1[0]) -
704 (p1[0] * (float) screen->width ())) /
705 ((v[2] * v[2] * sws) + (v[0] * v[0]));
706
707 const float rq = (0.25 * p * p) - q;
708 const float ph = -p * 0.5;
709
710 if (rq < 0.0)
711 {
712 vertex[0] = -1000;
713 vertex[1] = -1000;
714 return;
715 }
716 else
717 {
718 alpha = ph + sqrt(rq);
719 if (p1[2] + (alpha * v[2]) > 0.0)
720 {
721 vertex[0] = -1000;
722 vertex[1] = -1000;
723 return;
724 }
725 }
726 }
727
728 vertex[0] = ceil (p1[0] + (alpha * v[0]));
729 vertex[1] = ceil (p1[1] + (alpha * v[1]));
730}
731
732void
733ExpoScreen::paintViewport (const GLScreenPaintAttrib& attrib,
734 const GLMatrix& transform,
735 const CompRegion& region,
736 CompOutput *output,
737 unsigned int mask,
738 CompPoint vpPos,
739 GLVector &vpCamPos,
740 bool reflection)
741{
742 GLMatrix sTransform (transform);
743 GLMatrix sTransform2, sTransform3;
744 float sx = (float) screen->width () / output->width ();
745 float sy = (float) screen->height () / output->height ();
746 float vpp;
747 float progress = sigmoidProgress (expoCam);
748 unsigned int vp;
749 CompPoint vpSize (screen->vpSize ().width (), screen->vpSize ().height ());
750
751 const float gapY = optionGetVpDistance () * 0.1f * expoCam;
752 const float gapX = optionGetVpDistance () * 0.1f * screen->height () /
753 screen->width () * expoCam;
754
755 /* not sure this will work with different resolutions */
756 sTransform.translate (0.0, MAX (0, vpPos.y ()) * -(sy + gapY), 0.0f);
757
758 sTransform2 = sTransform;
759
760 /* not sure this will work with different resolutions */
761 if (optionGetDeform () != DeformCurve)
762 sTransform2.translate (MAX (0, vpPos.x ()) * (sx + gapX), 0.0f, 0.0);
763
764
765 if (optionGetExpoAnimation () == ExpoAnimationVortex)
766 sTransform2.rotate (360 * expoCam,
767 0.0f, 1.0f, 2.0f * expoCam);
768
769 sTransform3 = sTransform2;
770
771 sTransform3.translate (output->x () / output->width (),
772 -output->y () / output->height (), 0.0);
773
774 cScreen->setWindowPaintOffset ((screen->vp ().x () - vpPos.x ()) *
775 screen->width (),
776 (screen->vp ().y () - vpPos.y ()) *
777 screen->height ());
778
779 vp = (vpPos.y () * vpSize.x ()) + vpPos.x ();
780
781 vpp = (expoCam * vpActivity[vp]) + (1 - expoCam);
782 vpp = sigmoidProgress (vpp);
783
784 vpBrightness = vpp + ((1.0 - vpp) *
785 optionGetVpBrightness () / 100.0);
786 vpSaturation = vpp + ((1.0 - vpp) *
787 optionGetVpSaturation () / 100.0);
788
789 paintingVp = vpPos;
790
791 if (optionGetDeform () == DeformCurve)
792 {
793 float rotateX;
794
795 sTransform3.translate (-vpCamPos[GLVector::x], 0.0f,
796 curveDistance - DEFAULT_Z_CAMERA);
797
798 rotateX = -vpPos.x () + interpolate (((float) vpSize.x () / 2.0) - 0.5,
799 screen->vp ().x (), progress);
800
801 sTransform3.rotate (curveAngle * rotateX, 0.0, 1.0, 0.0);
802
803 sTransform3.translate (vpCamPos[GLVector::x], 0.0f,
804 DEFAULT_Z_CAMERA - curveDistance);
805 }
806
807 if (paintingDndWindow)
808 cScreen->getWindowPaintListSetEnabled (this, true);
809 gScreen->glPaintTransformedOutput (attrib, sTransform3,
810 screen->region (), output,
811 mask);
812
813 if (paintingDndWindow)
814 cScreen->getWindowPaintListSetEnabled (this, false);
815
816 if (!reflection && !paintingDndWindow)
817 {
818 int cursor[2] = { pointerX, pointerY };
819
820 invertTransformedVertex (attrib, sTransform3,
821 output, cursor);
822
823 if ((cursor[0] > 0) && (cursor[0] < (int) screen->width ()) &&
824 (cursor[1] > 0) && (cursor[1] < (int) screen->height ()))
825 {
826 newCursor.setX (vpPos.x () * screen->width () + cursor[0]);
827 newCursor.setY (vpPos.y () * screen->height () + cursor[1]);
828
829 if (anyClick || dndState != DnDNone)
830 {
831 /* Used to save last viewport interaction was in */
832 selectedVp = vpPos;
833 anyClick = false;
834 }
835 }
836 }
837
838 /* Calculate the current viewport size */
839 int tl[2] = { 0, 0 };
840 int br[2] = { screen->width (), screen->height () };
841
842 invertTransformedVertex (attrib, sTransform3, output, tl);
843 invertTransformedVertex (attrib, sTransform3, output, br);
844
845 viewport_size = CompSize (br[0] - tl[0], br[1] - tl[1]);
846
847 cScreen->setWindowPaintOffset (0, 0);
848}
849
850void
851ExpoScreen::paintWall (const GLScreenPaintAttrib& attrib,
852 const GLMatrix& transform,
853 const CompRegion& region,
854 CompOutput *output,
855 unsigned int mask,
856 bool reflection)
857{
858 GLMatrix sTransformW, sTransform (transform);
859 GLenum oldFilter = gScreen->textureFilter ();
860 float sx = (float) screen->width () / output->width ();
861 float sy = (float) screen->height () / output->height ();
862 float biasZ;
863 float oScale, rotation = 0.0f, progress;
864 float aspectX = 1.0f, aspectY = 1.0f;
865 GLVector cam;
866 CompPoint vpSize (screen->vpSize ().width (), screen->vpSize ().height ());
867
868 /* amount of gap between viewports */
869 const float gapY = optionGetVpDistance () * 0.1f * expoCam;
870 const float gapX = optionGetVpDistance () * 0.1f * screen->height () /
871 screen->width () * expoCam;
872
873 int glPaintTransformedOutputIndex =
874 gScreen->glPaintTransformedOutputGetCurrentIndex ();
875
876 // Make sure that the base glPaintTransformedOutput function is called
877 gScreen->glPaintTransformedOutputSetCurrentIndex (MAXSHORT);
878
879 /* Zoom animation stuff */
880 /* camera position for the selected viewport */
881 GLVector vpCamPos (0, 0, 0, 0);
882
883 /* camera position during expo mode */
884 GLVector expoCamPos (0, 0, 0, 0);
885
886 if (optionGetDeform () == DeformCurve)
887 {
888 vpCamPos[GLVector::x] = -sx * (0.5 - (((float) output->x () +
889 (output->width () / 2.0)) /
890 (float) screen->width ()));
891 }
892 else
893 {
894 vpCamPos[GLVector::x] = (screen->vp ().x () * sx) + 0.5 +
895 (output->x () / output->width ()) -
896 (vpSize.x () * 0.5 * sx) +
897 gapX * screen->vp ().x ();
898 }
899 vpCamPos[GLVector::y] = -((screen->vp ().y () * sy) + 0.5 +
900 (output->y () / output->height ())) +
901 (vpSize.y () * 0.5 * sy) -
902 gapY * screen->vp ().y ();
903
904 biasZ = MAX (vpSize.x () * sx, vpSize.y () * sy);
905 if (optionGetDeform () == DeformTilt || optionGetReflection ())
906 biasZ *= (0.15 + optionGetDistance ());
907 else
908 biasZ *= optionGetDistance ();
909
910 progress = sigmoidProgress (expoCam);
911
912 if (optionGetDeform () != DeformCurve)
913 expoCamPos[GLVector::x] = gapX * (vpSize.x () - 1) * 0.5;
914
915 expoCamPos[GLVector::y] = -gapY * (vpSize.y () - 1) * 0.5;
916 expoCamPos[GLVector::z] = -DEFAULT_Z_CAMERA + DEFAULT_Z_CAMERA *
917 (MAX (vpSize.x () + (vpSize.x () - 1) * gapX,
918 vpSize.y () + (vpSize.y () - 1) * gapY) +
919 biasZ);
920
921 /* interpolate between vpCamPos and expoCamPos */
922 cam[GLVector::x] = vpCamPos[GLVector::x] * (1 - progress) +
923 expoCamPos[GLVector::x] * progress;
924 cam[GLVector::y] = vpCamPos[GLVector::y] * (1 - progress) +
925 expoCamPos[GLVector::y] * progress;
926 cam[GLVector::z] = vpCamPos[GLVector::z] * (1 - progress) +
927 expoCamPos[GLVector::z] * progress;
928
929 if (vpSize.x () > vpSize.y ())
930 {
931 aspectY = (float) vpSize.x () / (float) vpSize.y ();
932 aspectY -= 1.0;
933 aspectY *= -optionGetAspectRatio () + 1.0;
934 aspectY *= progress;
935 aspectY += 1.0;
936 }
937 else
938 {
939 aspectX = (float) vpSize.y () / (float) vpSize.x ();
940 aspectX -= 1.0;
941 aspectX *= -optionGetAspectRatio () + 1.0;
942 aspectX *= progress;
943 aspectX += 1.0;
944 }
945
946 /* End of Zoom animation stuff */
947
948 if (optionGetDeform () == DeformTilt)
949 {
950 if (optionGetExpoAnimation () == ExpoAnimationZoom)
951 rotation = 10.0 * sigmoidProgress (expoCam);
952 else
953 rotation = 10.0 * expoCam;
954 }
955
956 if (optionGetMipmaps ())
957 gScreen->setTextureFilter (GL_LINEAR_MIPMAP_LINEAR);
958
959 /* ALL TRANSFORMATION ARE EXECUTED FROM BOTTOM TO TOP */
960
961 oScale = 1 / (1 + ((MAX (sx, sy) - 1) * progress));
962
963 sTransform.scale (oScale, oScale, 1.0);
964
965 /* zoom out */
966 oScale = DEFAULT_Z_CAMERA / (cam[GLVector::z] + DEFAULT_Z_CAMERA);
967 sTransform.scale (oScale, oScale, oScale);
968 glNormal3f (0.0, 0.0, -oScale);
969 sTransform.translate (-cam[GLVector::x], -cam[GLVector::y],
970 -cam[GLVector::z] - DEFAULT_Z_CAMERA);
971
972 if (reflection)
973 {
974 float scaleFactor = optionGetScaleFactor ();
975
976 sTransform.translate (0.0,
977 (vpSize.y () + ((vpSize.y () - 1) * gapY * 2)) *
978 -sy * aspectY,
979 0.0);
980 sTransform.scale (1.0, -1.0, 1.0);
981 sTransform.translate (0.0,
982 - (1 - scaleFactor) / 2 * sy * aspectY *
983 (vpSize.y () + ((vpSize.y () - 1) * gapY * 2)),
984 0.0);
985 sTransform.scale (1.0, scaleFactor, 1.0);
986 glCullFace (GL_FRONT);
987 }
988
989 /* rotate */
990 sTransform.rotate (rotation, 0.0f, 1.0f, 0.0f);
991 sTransform.scale (aspectX, aspectY, 1.0);
992
993 float xoffset = 0.0;
994 float yoffset = 0.0;
995 float xadjs = 1.0f;
996 float yadjs = 1.0f;
997
998 if (output->left () == 0)
999 {
1000 xoffset = ((vpSize.x () * sx) / ((float) output->width ()) * (optionGetXOffset ()) * sigmoidProgress (expoCam));
1001 xadjs = 1.0f - ((float) (optionGetXOffset ()) / (float) (output->width ())) * sigmoidProgress (expoCam);
1002 }
1003
1004 if (output->top () == 0)
1005 {
1006 yoffset = ((vpSize.y () * sy) / ((float) output->height ()) * (optionGetYOffset ()) * sigmoidProgress (expoCam));
1007
1008 yadjs = 1.0f - ((float) (optionGetYOffset ()) / (float) output->height ()) * sigmoidProgress (expoCam);
1009 }
1010
1011 /* translate expo to center */
1012 sTransform.translate (vpSize.x () * sx * -0.5 + xoffset,
1013 vpSize.y () * sy * 0.5 - yoffset, 0.0f);
1014 sTransform.scale (xadjs, yadjs, 1.0f);
1015
1016 if (optionGetDeform () == DeformCurve)
1017 sTransform.translate ((vpSize.x () - 1) * sx * 0.5, 0.0, 0.0);
1018
1019 sTransformW = sTransform;
1020
1021 /* revert prepareXCoords region shift. Now all screens display the same */
1022 sTransform.translate (0.5f, -0.5f, DEFAULT_Z_CAMERA);
1023
1024 if (vpSize.x () > 2)
1025 /* we can't have 90 degree for the left/right most viewport */
1026 curveAngle = interpolate (359 / ((vpSize.x () - 1) * 2), 1,
1027 optionGetCurve ());
1028 else
1029 curveAngle = interpolate (180 / vpSize.x (), 1, optionGetCurve ());
1030
1031 curveDistance = ((0.5f * sx) + (gapX / 2.0)) /
1032 tanf ((M_PI / 180.0f) * curveAngle / 2.0);
1033 curveRadius = ((0.5f * sx) + (gapX / 2.0)) /
1034 sinf ((M_PI / 180.0f) * curveAngle / 2.0);
1035
1036 expoActive = true;
1037
1038 for (int j = 0; j < screen->vpSize ().height (); j++)
1039 for (int i = 0; i < screen->vpSize().width (); i++)
1040 paintViewport (attrib, sTransform, region, output, mask, CompPoint (i, j), vpCamPos, reflection);
1041
1042 paintingDndWindow = true;
1043
1044 foreach (CompWindow *dndWindow, dndWindows)
1045 {
1046 CompPoint vp;
1047
1048 screen->viewportForGeometry (dndWindow->geometry (), vp);
1049
1050 while (vp.x () < 0)
1051 vp.setX (screen->vpSize ().width () + vp.x ());
1052
1053 while (vp.y () < 0)
1054 vp.setY (screen->vpSize ().height () + vp.y ());
1055
1056 paintViewport (attrib, sTransform, infiniteRegion, output, mask, vp, vpCamPos, reflection);
1057 }
1058
1059 paintingDndWindow = false;
1060
1061 glNormal3f (0.0, 0.0, -1.0);
1062
1063 if (reflection)
1064 {
1065 glEnable (GL_BLEND);
1066 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1067
1068 glPushMatrix ();
1069
1070 if (optionGetDeform () != DeformCurve)
1071 {
1072 glLoadMatrixf (sTransformW.getMatrix ());
1073
1074 glBegin (GL_QUADS);
1075 glColor4f (0.0, 0.0, 0.0, 1.0);
1076 glVertex2f (0.0, 0.0);
1077 glColor4f (0.0, 0.0, 0.0, 0.5);
1078 glVertex2f (0.0, -vpSize.y () * (sy + gapY));
1079 glVertex2f (vpSize.x () * sx * (1.0 + gapX),
1080 -vpSize.y () * sy * (1.0 + gapY));
1081 glColor4f (0.0, 0.0, 0.0, 1.0);
1082 glVertex2f (vpSize.x () * sx * (1.0 + gapX), 0.0);
1083 glEnd ();
1084 }
1085 else
1086 {
1087 glCullFace (GL_BACK);
1088 glLoadIdentity ();
1089 glTranslatef (0.0, 0.0, -DEFAULT_Z_CAMERA);
1090
1091 glBegin (GL_QUADS);
1092 glColor4f (0.0, 0.0, 0.0, 1.0 * expoCam);
1093 glVertex2f (-0.5, -0.5);
1094 glVertex2f (0.5, -0.5);
1095 glColor4f (0.0, 0.0, 0.0, 0.5 * expoCam);
1096 glVertex2f (0.5, 0.0);
1097 glVertex2f (-0.5, 0.0);
1098 glColor4f (0.0, 0.0, 0.0, 0.5 * expoCam);
1099 glVertex2f (-0.5, 0.0);
1100 glVertex2f (0.5, 0.0);
1101 glColor4f (0.0, 0.0, 0.0, 0.0);
1102 glVertex2f (0.5, 0.5);
1103 glVertex2f (-0.5, 0.5);
1104 glEnd ();
1105 }
1106 glCullFace (GL_BACK);
1107
1108 glLoadIdentity ();
1109 glTranslatef (0.0, 0.0, -DEFAULT_Z_CAMERA);
1110
1111 if (optionGetGroundSize () > 0.0)
1112 {
1113 glBegin (GL_QUADS);
1114 glColor4usv (optionGetGroundColor1 ());
1115 glVertex2f (-0.5, -0.5);
1116 glVertex2f (0.5, -0.5);
1117 glColor4usv (optionGetGroundColor2 ());
1118 glVertex2f (0.5, -0.5 + optionGetGroundSize ());
1119 glVertex2f (-0.5, -0.5 + optionGetGroundSize ());
1120 glEnd ();
1121 }
1122
1123 glColor4usv (defaultColor);
1124
1125 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1126 glDisable (GL_BLEND);
1127 glPopMatrix ();
1128 }
1129
1130 expoActive = false;
1131
1132 gScreen->glPaintTransformedOutputSetCurrentIndex (glPaintTransformedOutputIndex);
1133 gScreen->setTextureFilter (oldFilter);
1134}
1135
1136const CompWindowList &
1137ExpoScreen::getWindowPaintList ()
1138{
1139 return dndWindows;
1140}
1141
1142bool
1143ExpoScreen::glPaintOutput (const GLScreenPaintAttrib& attrib,
1144 const GLMatrix& transform,
1145 const CompRegion& region,
1146 CompOutput *output,
1147 unsigned int mask)
1148{
1149 if (expoCam > 0.0)
1150 mask |= PAINT_SCREEN_TRANSFORMED_MASK | PAINT_SCREEN_CLEAR_MASK;
1151
1152 return gScreen->glPaintOutput (attrib, transform, region, output, mask);
1153}
1154
1155void
1156ExpoScreen::glPaintTransformedOutput (const GLScreenPaintAttrib& attrib,
1157 const GLMatrix& transform,
1158 const CompRegion& region,
1159 CompOutput *output,
1160 unsigned int mask)
1161{
1162 expoActive = false;
1163
1164 if (expoCam > 0)
1165 mask |= PAINT_SCREEN_CLEAR_MASK;
1166
1167 if (expoCam <= 0 || (expoCam > 0.0 && expoCam < 1.0 &&
1168 optionGetExpoAnimation () != ExpoAnimationZoom))
1169 {
1170 gScreen->glPaintTransformedOutput (attrib, transform, region,
1171 output, mask);
1172 }
1173 else
1174 {
1175 gScreen->clearOutput (output, GL_COLOR_BUFFER_BIT);
1176 }
1177
1178 mask &= ~PAINT_SCREEN_CLEAR_MASK;
1179
1180 if (expoCam > 0.0)
1181 {
1182 if (optionGetReflection ())
1183 paintWall (attrib, transform, region, output, mask, true);
1184
1185 paintWall (attrib, transform, region, output, mask, false);
1186 anyClick = false;
1187 }
1188}
1189
1190bool
1191ExpoWindow::glDraw (const GLMatrix& transform,
1192 GLFragment::Attrib& fragment,
1193 const CompRegion& region,
1194 unsigned int mask)
1195{
1196 GLMatrix wTransform (transform);
1197 CompPoint vp;
1198
1199 screen->viewportForGeometry (window->geometry (), vp);
1200
1201 if (eScreen->expoCam == 0.0f)
1202 return gWindow->glDraw (transform, fragment, region, mask);
1203
1204 GLFragment::Attrib fA (fragment);
1205 int expoAnimation;
1206
1207 expoAnimation = eScreen->optionGetExpoAnimation ();
1208
1209 if (eScreen->expoActive)
1210 {
1211 if (expoAnimation != ExpoScreen::ExpoAnimationZoom)
1212 fA.setOpacity (fragment.getOpacity () * eScreen->expoCam);
1213
1214 if (window->wmType () & CompWindowTypeDockMask &&
1215 eScreen->optionGetHideDocks ())
1216 {
1217 if (expoAnimation == ExpoScreen::ExpoAnimationZoom &&
1218 eScreen->paintingVp == eScreen->selectedVp)
1219 {
1220 fA.setOpacity (fragment.getOpacity () *
1221 (1 - sigmoidProgress (eScreen->expoCam)));
1222 }
1223 else
1224 {
1225 fA.setOpacity (0);
1226 }
1227 }
1228
1229 if (vp == eScreen->paintingVp || window->onAllViewports ())
1230 {
1231 fA.setBrightness (fragment.getBrightness () * eScreen->vpBrightness);
1232 fA.setSaturation (fragment.getSaturation () * eScreen->vpSaturation);
1233 }
1234 }
1235 else
1236 {
1237 if (expoAnimation == ExpoScreen::ExpoAnimationZoom)
1238 fA.setBrightness (0);
1239 else
1240 fA.setBrightness (fragment.getBrightness () *
1241 (1 - sigmoidProgress (eScreen->expoCam)));
1242 }
1243
1244 bool status = gWindow->glDraw (wTransform, fA, region, mask);
1245
1246 if (window->type () & CompWindowTypeDesktopMask)
1247 {
1248 /* We want to set the geometry of the polka dots to the window
1249 * region */
1250 CompRegion reg = CompRegion (0, 0, window->width (), window->height ());
1251
1252 foreach(GLTexture * tex, eScreen->polkadots_texture)
1253 {
1254 GLTexture::MatrixList matl;
1255 GLTexture::Matrix mat = tex->matrix();
1256 CompRegion paintRegion(region);
1257
1258 /* We can reset the window geometry since it will be
1259 * re-added later */
1260 gWindow->geometry().reset();
1261
1262 float xScale = screen->width () / (float) eScreen->viewport_size.width ();
1263 float yScale = screen->height () / (float) eScreen->viewport_size.height ();
1264
1265 mat.xx *= xScale;
1266 mat.yy *= yScale;
1267
1268 /* Not sure what this does, but it is necessary
1269 * (adjusts for scale?) */
1270 mat.x0 -= mat.xx * reg.boundingRect().x1();
1271 mat.y0 -= mat.yy * reg.boundingRect().y1();
1272
1273 matl.push_back(mat);
1274
1275 if (mask & PAINT_WINDOW_TRANSFORMED_MASK)
1276 paintRegion = infiniteRegion;
1277
1278 /* Now allow plugins to mess with the geometry of our
1279 * dim (so we get a nice render for things like
1280 * wobbly etc etc */
1281 gWindow->glAddGeometry(matl, reg, paintRegion);
1282
1283 /* Did it succeed? */
1284 if (gWindow->geometry().vertices)
1285 {
1286 unsigned int glDrawTextureIndex = gWindow->glDrawTextureGetCurrentIndex();
1287 fA.setOpacity (fragment.getOpacity () * (((1.0 - eScreen->vpBrightness) + (1.0 - eScreen->vpSaturation) / 2.0)));
1288 /* Texture rendering set-up */
1289 eScreen->gScreen->setTexEnvMode(GL_MODULATE);
1290 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1291 /* Draw the dim texture with all of it's modified
1292 * geometry glory */
1293 gWindow->glDrawTextureSetCurrentIndex(MAXSHORT);
1294 gWindow->glDrawTexture(tex, fA, mask | PAINT_WINDOW_BLEND_MASK
1295 | PAINT_WINDOW_TRANSLUCENT_MASK |
1296 PAINT_WINDOW_TRANSFORMED_MASK);
1297 gWindow->glDrawTextureSetCurrentIndex(glDrawTextureIndex);
1298 /* Texture rendering tear-down */
1299 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1300 eScreen->gScreen->setTexEnvMode(GL_REPLACE);
1301 }
1302 }
1303
1304 /* Paint the outline */
1305 if (mGlowQuads && eScreen->paintingVp == eScreen->selectedVp)
1306 {
1307 if (region.numRects ())
1308 {
1309 /* reset geometry and paint */
1310 gWindow->geometry ().reset ();
1311
1312 paintGlow (fragment, infiniteRegion, mask);
1313 }
1314 }
1315
1316 }
1317
1318 return status;
1319
1320}
1321
1322#define EXPO_GRID_SIZE 100
1323
1324void
1325ExpoWindow::glAddGeometry (const GLTexture::MatrixList& matrices,
1326 const CompRegion& region,
1327 const CompRegion& clip,
1328 unsigned int maxGridWidth,
1329 unsigned int maxGridHeight)
1330{
1331 if (eScreen->expoCam > 0.0 &&
1332 screen->desktopWindowCount () &&
1333 eScreen->optionGetDeform () == ExpoScreen::DeformCurve)
1334 {
1335 int i, oldVCount = gWindow->geometry ().vCount;
1336 GLfloat *v;
1337 CompPoint offset;
1338 float lastX, lastZ = 0.0;
1339 const float radSquare = pow (eScreen->curveDistance, 2) + 0.25;
1340 float ang;
1341
1342 gWindow->glAddGeometry (matrices, region, clip,
1343 MIN(maxGridWidth , EXPO_GRID_SIZE),
1344 maxGridHeight);
1345
1346 v = gWindow->geometry ().vertices;
1347 v += gWindow->geometry ().vertexStride - 3;
1348 v += gWindow->geometry ().vertexStride * oldVCount;
1349
1350 if (!window->onAllViewports ())
1351 {
1352 offset = eScreen->cScreen->windowPaintOffset ();
1353 offset = window->getMovementForOffset (offset);
1354 }
1355
1356 lastX = -1000000000.0;
1357
1358 for (i = oldVCount; i < gWindow->geometry ().vCount; i++)
1359 {
1360 if (v[0] == lastX)
1361 {
1362 v[2] = lastZ;
1363 }
1364 else if (v[0] + offset.x () >= -EXPO_GRID_SIZE &&
1365 v[0] + offset.x () < screen->width () + EXPO_GRID_SIZE)
1366 {
1367 ang = (((v[0] + offset.x ()) / (float) screen->width ()) - 0.5);
1368 ang *= ang;
1369 if (ang < radSquare)
1370 {
1371 v[2] = eScreen->curveDistance - sqrt (radSquare - ang);
1372 v[2] *= sigmoidProgress (eScreen->expoCam);
1373 }
1374 }
1375
1376 lastX = v[0];
1377 lastZ = v[2];
1378
1379 v += gWindow->geometry ().vertexStride;
1380 }
1381 }
1382 else
1383 {
1384 gWindow->glAddGeometry (matrices, region, clip, maxGridWidth, maxGridHeight);
1385 }
1386}
1387
1388void
1389ExpoWindow::glDrawTexture (GLTexture *texture,
1390 GLFragment::Attrib& attrib,
1391 unsigned int mask)
1392{
1393 if (eScreen->expoCam > 0.0 &&
1394 eScreen->optionGetDeform () == ExpoScreen::DeformCurve &&
1395 eScreen->gScreen->lighting () &&
1396 screen->desktopWindowCount ())
1397 {
1398 unsigned int i, idx, vCount;
1399 CompPoint offset;
1400 float x;
1401 GLfloat *v;
1402
1403 vCount = gWindow->geometry ().vCount;
1404
1405 if (eScreen->winNormals.size () < vCount * 3)
1406 eScreen->winNormals.resize (vCount * 3);
1407
1408 if (!window->onAllViewports ())
1409 {
1410 offset = eScreen->cScreen->windowPaintOffset ();
1411 offset = window->getMovementForOffset (offset);
1412 }
1413
1414 v = gWindow->geometry ().vertices +
1415 (gWindow->geometry ().vertexStride - 3);
1416
1417 for (i = 0; i < vCount; i++)
1418 {
1419 x = (float) (v[0] + offset.x () - screen->width () / 2) *
1420 eScreen->curveAngle / screen->width ();
1421
1422 while (x < 0)
1423 x += 360.0;
1424
1425 idx = floor (x);
1426
1427 eScreen->winNormals[i * 3] = -eScreen->vpNormals[idx * 3];
1428 eScreen->winNormals[(i * 3) + 1] =
1429 eScreen->vpNormals[(idx * 3) + 1];
1430 eScreen->winNormals[(i * 3) + 2] =
1431 eScreen->vpNormals[(idx * 3) + 2];
1432
1433 v += gWindow->geometry ().vertexStride;
1434 }
1435
1436 glEnable (GL_NORMALIZE);
1437 glNormalPointer (GL_FLOAT,0, &eScreen->winNormals.at (0));
1438
1439 glEnableClientState (GL_NORMAL_ARRAY);
1440
1441 gWindow->glDrawTexture (texture, attrib, mask);
1442
1443 glDisable (GL_NORMALIZE);
1444 glDisableClientState (GL_NORMAL_ARRAY);
1445 glNormal3f (0.0, 0.0, -1.0);
1446 }
1447 else
1448 {
1449 glEnable (GL_NORMALIZE);
1450 gWindow->glDrawTexture (texture, attrib, mask);
1451 glDisable (GL_NORMALIZE);
1452 }
1453}
1454
1455bool
1456ExpoWindow::glPaint (const GLWindowPaintAttrib& attrib,
1457 const GLMatrix& transform,
1458 const CompRegion& region,
1459 unsigned int mask)
1460{
1461 GLMatrix wTransform (transform);
1462 GLWindowPaintAttrib wAttrib (attrib);
1463 CompRegion clip (region);
1464
1465 if (eScreen->expoActive)
1466 {
1467 float opacity = 1.0;
1468 bool hide;
1469 bool zoomAnim;
1470 CompPoint vp;
1471 screen->viewportForGeometry (window->geometry (), vp);
1472
1473 zoomAnim = eScreen->optionGetExpoAnimation () ==
1474 ExpoScreen::ExpoAnimationZoom;
1475 hide = eScreen->optionGetHideDocks () &&
1476 (window->wmType () & CompWindowTypeDockMask);
1477
1478 if (eScreen->expoCam > 0.0)
1479 {
1480 if (eScreen->expoCam < 1.0 && !zoomAnim)
1481 mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
1482 else if (hide)
1483 mask |= PAINT_WINDOW_TRANSLUCENT_MASK;
1484 }
1485
1486 if (!zoomAnim)
1487 opacity = attrib.opacity * eScreen->expoCam;
1488
1489 if (hide)
1490 {
1491 if (zoomAnim && eScreen->paintingVp == eScreen->selectedVp)
1492 opacity = attrib.opacity *
1493 (1 - sigmoidProgress (eScreen->expoCam));
1494 else
1495 opacity = 0;
1496 }
1497
1498 if (opacity <= 0)
1499 mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
1500 else
1501 wAttrib.opacity = wAttrib.opacity * opacity;
1502
1503 /* Stretch maximized windows a little so that you don't
1504 * have an awkward gap */
1505
1506 if (window->state () & MAXIMIZE_STATE &&
1507 !window->border ().top)
1508 {
1509 CompOutput *o = &screen->outputDevs ()[screen->outputDeviceForGeometry(window->geometry())];
1510 float yS = 1.0 + ((o->height () / (float) window->height ()) - 1.0f) * sigmoidProgress (eScreen->expoCam);
1511 wTransform.translate (window->x () + window->width () / 2,
1512 window->y () + window->height (),
1513 0.0f);
1514 wTransform.scale (1.0f, yS, 1.0f);
1515 wTransform.translate (-(window->x () + window->width () / 2),
1516 -(window->y () + window->height ()),
1517 0.0f);
1518
1519 if (eScreen->paintingVp != vp)
1520 mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
1521
1522 mask |= PAINT_WINDOW_TRANSFORMED_MASK;
1523 }
1524
1525 if (std::find (eScreen->dndWindows.begin(), eScreen->dndWindows.end (), window) != eScreen->dndWindows.end ())
1526 {
1527 if (!eScreen->paintingDndWindow)
1528 {
1529 mask |= PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
1530 }
1531 else
1532 {
1533 mask |= PAINT_WINDOW_TRANSFORMED_MASK;
1534 clip = infiniteRegion;
1535 }
1536 }
1537 }
1538
1539 bool status = gWindow->glPaint (wAttrib, wTransform, clip, mask);
1540
1541 return status;
1542}
1543
1544bool
1545ExpoWindow::damageRect (bool initial,
1546 const CompRect& rect)
1547{
1548 if (eScreen->expoCam > 0.0f)
1549 eScreen->cScreen->damageScreen ();
1550
1551 return cWindow->damageRect (initial, rect);
1552}
1553
1554#define EXPOINITBIND(opt, func) \
1555 optionSet##opt##Initiate (boost::bind (&ExpoScreen::func, \
1556 this, _1, _2, _3));
1557#define EXPOTERMBIND(opt, func) \
1558 optionSet##opt##Terminate (boost::bind (&ExpoScreen::func, \
1559 this, _1, _2, _3));
1560
1561ExpoScreen::ExpoScreen (CompScreen *s) :
1562 PluginClassHandler<ExpoScreen, CompScreen> (s),
1563 ExpoOptions (),
1564 cScreen (CompositeScreen::get (s)),
1565 gScreen (GLScreen::get (s)),
1566 expoCam (0.0f),
1567 expoActive (false),
1568 expoMode (false),
1569 dndState (DnDNone),
1570 dndWindows (0),
1571 origVp (s->vp ()),
1572 selectedVp (s->vp ()),
1573 vpUpdateMode (VPUpdateNone),
1574 clickTime (0),
1575 doubleClick (false),
1576 vpNormals (360 * 3),
1577 grabIndex (0),
1578 paintingDndWindow (false),
1579 mGlowTextureProperties (&glowTextureProperties)
1580{
1581 CompString fname;
1582 CompString pname = "expo";
1583 CompSize size;
1584
1585
1586 leftKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Left"));
1587 rightKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Right"));
1588 upKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Up"));
1589 downKey = XKeysymToKeycode (s->dpy (), XStringToKeysym ("Down"));
1590
1591 mMoveCursor = XCreateFontCursor (screen->dpy (), XC_fleur);
1592
1593 EXPOINITBIND (ExpoKey, doExpo);
1594 EXPOTERMBIND (ExpoKey, termExpo);
1595 EXPOINITBIND (ExpoButton, doExpo);
1596 EXPOTERMBIND (ExpoButton, termExpo);
1597 EXPOINITBIND (ExpoEdge, doExpo);
1598 EXPOTERMBIND (ExpoButton, termExpo);
1599
1600 EXPOINITBIND (DndButton, dndInit);
1601 EXPOTERMBIND (DndButton, dndFini);
1602 EXPOINITBIND (ExitButton, exitExpo);
1603 EXPOINITBIND (NextVpButton, nextVp);
1604 EXPOINITBIND (PrevVpButton, prevVp);
1605
1606 ScreenInterface::setHandler (screen, false);
1607 CompositeScreenInterface::setHandler (cScreen, false);
1608 GLScreenInterface::setHandler (gScreen, false);
1609
1610 outline_texture = GLTexture::imageDataToTexture (mGlowTextureProperties->textureData,
1611 CompSize (mGlowTextureProperties->textureSize,
1612 mGlowTextureProperties->textureSize),
1613 GL_RGBA, GL_UNSIGNED_BYTE);
1614 fname = "texture_tile.png";
1615 polkadots_texture = GLTexture::readImageToTexture (fname, pname, polkadots_texture_size);
1616
1617 if (polkadots_texture.empty ())
1618 compLogMessage ("expo", CompLogLevelWarn, "failed to bind image to texture");
1619 else
1620 {
1621 foreach (GLTexture *tex, polkadots_texture)
1622 {
1623 tex->enable (GLTexture::Good);
1624 glTexParameteri (tex->target (), GL_TEXTURE_WRAP_S, GL_REPEAT);
1625 glTexParameteri (tex->target (), GL_TEXTURE_WRAP_T, GL_REPEAT);
1626 tex->disable ();
1627 }
1628 }
1629}
1630
1631ExpoScreen::~ExpoScreen ()
1632{
1633 if (mMoveCursor)
1634 XFreeCursor (screen->dpy (), mMoveCursor);
1635}
1636
1637void
1638ExpoWindow::resizeNotify(int dx, int dy, int dw, int dh)
1639{
1640 window->resizeNotify (dx, dy, dw, dh);
1641
1642 /* mGlowQuads contains positional info, so we need to recalc that */
1643 if (mGlowQuads)
1644 {
1645 /* FIXME: we need to find a more multitexture friendly way
1646 * of doing this */
1647 GLTexture::Matrix tMat = eScreen->outline_texture.at (0)->matrix ();
1648 computeGlowQuads (&tMat);
1649 }
1650}
1651
1652ExpoWindow::ExpoWindow (CompWindow *w) :
1653 PluginClassHandler<ExpoWindow, CompWindow> (w),
1654 window (w),
1655 cWindow (CompositeWindow::get (w)),
1656 gWindow (GLWindow::get (w)),
1657 eScreen (ExpoScreen::get (screen)),
1658 dndOpacity (0.0f),
1659 mGlowQuads (NULL)
1660{
1661 CompositeWindowInterface::setHandler (cWindow, false);
1662 GLWindowInterface::setHandler (gWindow, false);
1663 WindowInterface::setHandler (window, true);
1664
1665 if (window->type () & CompWindowTypeDesktopMask)
1666 {
1667 foreach (GLTexture *tex, eScreen->outline_texture)
1668 {
1669 GLTexture::Matrix mat = tex->matrix ();
1670 computeGlowQuads (&mat);
1671 }
1672 }
1673}
1674
1675ExpoWindow::~ExpoWindow ()
1676{
1677 eScreen->dndWindows.remove (window);
1678 computeGlowQuads (NULL);
1679}
1680
1681bool
1682ExpoPluginVTable::init ()
1683{
1684 if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) ||
1685 !CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) ||
1686 !CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
1687 return false;
1688
1689 return true;
1690}
1691
1692
16930
=== removed directory '.pc/fix_930192.patch'
=== removed directory '.pc/fix_930192.patch/animation'
=== removed directory '.pc/fix_930192.patch/animation/src'
=== removed file '.pc/fix_930192.patch/animation/src/animation.cpp'
--- .pc/fix_930192.patch/animation/src/animation.cpp 2012-03-21 11:46:41 +0000
+++ .pc/fix_930192.patch/animation/src/animation.cpp 1970-01-01 00:00:00 +0000
@@ -1,2962 +0,0 @@
1/**
2 * Animation plugin for compiz/beryl
3 *
4 * animation.c
5 *
6 * Copyright : (C) 2006 Erkin Bahceci
7 * E-mail : erkinbah@gmail.com
8 *
9 * Based on Wobbly and Minimize plugins by
10 * : David Reveman
11 * E-mail : davidr@novell.com>
12 *
13 * Airplane added by : Carlo Palma
14 * E-mail : carlopalma@salug.it
15 * Based on code originally written by Mark J. Kilgard
16 *
17 * Beam-Up added by : Florencio Guimaraes
18 * E-mail : florencio@nexcorp.com.br
19 *
20 * Fold and Skewer added by : Tomasz Kolodziejski
21 * E-mail : tkolodziejski@gmail.com
22 *
23 * Hexagon tessellator added by : Mike Slegeir
24 * E-mail : mikeslegeir@mail.utexas.edu>
25 *
26 * Particle system added by : (C) 2006 Dennis Kasprzyk
27 * E-mail : onestone@beryl-project.org
28 *
29 * This program is free software; you can redistribute it and/or
30 * modify it under the terms of the GNU General Public License
31 * as published by the Free Software Foundation; either version 2
32 * of the License, or (at your option) any later version.
33 *
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
38 *
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
42 **/
43
44/*
45 * TODO:
46 *
47 * - Custom bounding box update function for Airplane
48 *
49 * - Auto direction option: Close in opposite direction of opening
50 * - Proper side surface normals for lighting
51 * - decoration shadows
52 * - shadow quad generation
53 * - shadow texture coords (from clip tex. matrices)
54 * - draw shadows
55 * - fade in shadows
56 *
57 * - Voronoi tessellation
58 * - Brick tessellation
59 * - Triangle tessellation
60 * - Hexagonal tessellation
61 *
62 * Effects:
63 * - Circular action for tornado type fx
64 * - Tornado 3D (especially for minimize)
65 * - Helix 3D (hor. strips descend while they rotate and fade in)
66 * - Glass breaking 3D
67 * - Gaussian distr. points (for gradually increasing polygon size
68 * starting from center or near mouse pointer)
69 * - Drawing cracks
70 * - Gradual cracking
71 *
72 * - fix slowness during transparent cube with <100 opacity
73 * - fix occasional wrong side color in some windows
74 * - fix on top windows and panels
75 * (These two only matter for viewing during Rotate Cube.
76 * All windows should be painted with depth test on
77 * like 3d-plugin does)
78 * - play better with rotate (fix cube face drawn on top of polygons
79 * after 45 deg. rotation)
80 *
81 */
82
83#include <GL/glu.h>
84#include <core/atoms.h>
85#include <sys/time.h>
86#include <assert.h>
87#include "private.h"
88
89using namespace compiz::core;
90
91class AnimPluginVTable :
92 public CompPlugin::VTableForScreenAndWindow<AnimScreen, AnimWindow>
93{
94public:
95 bool init ();
96 void fini ();
97};
98
99COMPIZ_PLUGIN_20090315 (animation, AnimPluginVTable);
100
101#define FAKE_ICON_SIZE 4
102
103const char *eventNames[AnimEventNum] =
104{"Open", "Close", "Minimize", "Shade", "Focus"};
105
106int chosenEffectOptionIds[AnimEventNum] =
107{
108 AnimationOptions::OpenEffects,
109 AnimationOptions::CloseEffects,
110 AnimationOptions::MinimizeEffects,
111 AnimationOptions::ShadeEffects,
112 AnimationOptions::FocusEffects
113};
114
115int randomEffectOptionIds[AnimEventNum] =
116{
117 AnimationOptions::OpenRandomEffects,
118 AnimationOptions::CloseRandomEffects,
119 AnimationOptions::MinimizeRandomEffects,
120 AnimationOptions::ShadeRandomEffects,
121 -1
122};
123
124int customOptionOptionIds[AnimEventNum] =
125{
126 AnimationOptions::OpenOptions,
127 AnimationOptions::CloseOptions,
128 AnimationOptions::MinimizeOptions,
129 AnimationOptions::ShadeOptions,
130 AnimationOptions::FocusOptions
131};
132
133int matchOptionIds[AnimEventNum] =
134{
135 AnimationOptions::OpenMatches,
136 AnimationOptions::CloseMatches,
137 AnimationOptions::MinimizeMatches,
138 AnimationOptions::ShadeMatches,
139 AnimationOptions::FocusMatches
140};
141
142int durationOptionIds[AnimEventNum] =
143{
144 AnimationOptions::OpenDurations,
145 AnimationOptions::CloseDurations,
146 AnimationOptions::MinimizeDurations,
147 AnimationOptions::ShadeDurations,
148 AnimationOptions::FocusDurations
149};
150
151// Bind each effect in the list of chosen effects for every event, to the
152// corresponding animation effect (i.e. effect with that name) if it is
153// provided by a plugin, otherwise set it to None.
154void
155PrivateAnimScreen::updateEventEffects (AnimEvent e,
156 bool forRandom,
157 bool callPost)
158{
159 CompOption::Value::Vector *listVal;
160 EffectSet *effectSet;
161 if (forRandom)
162 {
163 listVal = &getOptions ()[(unsigned)randomEffectOptionIds[e]].value ().
164 list ();
165 effectSet = &mRandomEffects[e];
166 }
167 else
168 {
169 listVal = &getOptions ()[(unsigned)chosenEffectOptionIds[e]].value ().
170 list ();
171 effectSet = &mEventEffects[e];
172 }
173 unsigned int n = listVal->size ();
174
175 effectSet->effects.clear ();
176 effectSet->effects.reserve (n);
177
178 AnimEffectVector &eventEffectsAllowed = mEventEffectsAllowed[e];
179
180 for (unsigned int r = 0; r < n; r++) // for each row
181 {
182 const CompString &animName = (*listVal)[r].s ();
183
184 // Find the animation effect with matching name
185 AnimEffectVector::iterator it =
186 find_if (eventEffectsAllowed.begin (),
187 eventEffectsAllowed.end (),
188 boost::bind (&AnimEffectInfo::matchesEffectName,
189 _1, animName));
190
191 effectSet->effects.push_back (it == eventEffectsAllowed.end () ?
192 AnimEffectNone : *it);
193 }
194
195 if (callPost)
196 {
197 foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
198 extPlugin->postUpdateEventEffects (e, forRandom);
199 }
200}
201
202void
203PrivateAnimScreen::updateAllEventEffects ()
204{
205 // for each anim event
206 for (int e = 0; e < AnimEventNum; e++)
207 updateEventEffects ((AnimEvent)e, false);
208
209 // for each anim event except focus
210 for (int e = 0; e < AnimEventNum - 1; e++)
211 updateEventEffects ((AnimEvent)e, true);
212}
213
214bool
215PrivateAnimScreen::isAnimEffectInList (AnimEffect theEffect,
216 EffectSet &effectList)
217{
218 for (unsigned int i = 0; i < effectList.effects.size (); i++)
219 if (effectList.effects[i] == theEffect)
220 return true;
221 return false;
222}
223
224bool
225PrivateAnimScreen::isAnimEffectPossibleForEvent (AnimEffect theEffect,
226 AnimEvent event)
227{
228 // Check all rows to see if the effect is chosen there
229 unsigned int nRows = mEventEffects[event].effects.size ();
230 for (unsigned int i = 0; i < nRows; i++)
231 {
232 AnimEffect chosenEffect = mEventEffects[event].effects[i];
233 // if chosen directly
234 if (chosenEffect == theEffect)
235 return true;
236 // if chosen in random pool
237 if (mRandomEffects[event].effects.size () &&
238 chosenEffect == AnimEffectRandom &&
239 isAnimEffectInList (theEffect, mRandomEffects[event]))
240 return true;
241 }
242 return false;
243}
244
245bool
246PrivateAnimScreen::isAnimEffectPossible (AnimEffect theEffect)
247{
248 for (int e = 0; e < AnimEventNum; e++)
249 if (isAnimEffectPossibleForEvent (theEffect, (AnimEvent)e))
250 return true;
251 return false;
252}
253
254bool
255PrivateAnimScreen::isRestackAnimPossible ()
256{
257 // Check all rows to see if the chosen effect is a restack animation
258 unsigned int nRows = mEventEffects[AnimEventFocus].effects.size ();
259
260 for (unsigned int i = 0; i < nRows; i++)
261 {
262 AnimEffect chosenEffect = mEventEffects[(unsigned)AnimEventFocus].
263 effects[i];
264 if (chosenEffect->isRestackAnim)
265 return true;
266 }
267 return false;
268}
269
270bool
271AnimScreen::isRestackAnimPossible ()
272{
273 return priv->isRestackAnimPossible ();
274}
275
276// Extension functions
277
278void
279AnimScreen::addExtension (ExtensionPluginInfo *extensionPluginInfo)
280{
281 priv->addExtension (extensionPluginInfo, true);
282}
283
284void
285PrivateAnimScreen::addExtension (ExtensionPluginInfo *extensionPluginInfo,
286 bool shouldInitPersistentData)
287{
288 mExtensionPlugins.push_back (extensionPluginInfo);
289
290 unsigned int nPluginEffects = extensionPluginInfo->nEffects;
291
292 bool eventEffectsNeedUpdate[AnimEventNum] =
293 {false, false, false, false, false};
294
295 // Put this plugin's effects into mEventEffects and
296 // mEventEffectsAllowed
297 for (unsigned int j = 0; j < nPluginEffects; j++)
298 {
299 const AnimEffect effect = extensionPluginInfo->effects[j];
300
301 // Update allowed effects for each event
302 for (int e = 0; e < AnimEventNum; e++)
303 {
304 if (effect->usedForEvents[e])
305 {
306 mEventEffectsAllowed[e].push_back (effect);
307 eventEffectsNeedUpdate[e] = true;
308 }
309 }
310 }
311
312 for (int e = 0; e < AnimEventNum; e++)
313 if (eventEffectsNeedUpdate[e])
314 {
315 updateEventEffects ((AnimEvent)e, false, false);
316 if (e != AnimEventFocus)
317 updateEventEffects ((AnimEvent)e, true, false);
318 }
319
320 if (shouldInitPersistentData)
321 {
322 const CompWindowList &pl = pushLockedPaintList ();
323 // Initialize persistent window data for the extension plugin
324 foreach (CompWindow *w, pl)
325 {
326 AnimWindow *aw = AnimWindow::get (w);
327 extensionPluginInfo->initPersistentData (aw);
328 }
329
330 popLockedPaintList ();
331 }
332}
333
334void
335AnimScreen::removeExtension (ExtensionPluginInfo *extensionPluginInfo)
336{
337 priv->removeExtension (extensionPluginInfo);
338}
339
340void
341PrivateAnimScreen::removeExtension (ExtensionPluginInfo *extensionPluginInfo)
342{
343 // Stop all ongoing animations
344 const CompWindowList &pl = pushLockedPaintList ();
345
346 foreach (CompWindow *w, pl)
347 {
348 PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
349 if (aw->curAnimation ())
350 aw->postAnimationCleanUp ();
351 }
352
353 popLockedPaintList ();
354
355 // Find the matching plugin and delete it
356
357 ExtensionPluginVector::iterator it = find (mExtensionPlugins.begin (),
358 mExtensionPlugins.end (),
359 extensionPluginInfo);
360
361 if (it == mExtensionPlugins.end ())
362 return; // couldn't find that extension plugin
363
364 mExtensionPlugins.erase (it);
365
366 if (extensionPluginInfo->nEffects == 0)
367 return; // no animation effects -> we're done here
368
369
370 // Also delete the "allowed effect" entries for that plugin
371
372 for (int e = 0; e < AnimEventNum; e++)
373 {
374 AnimEffectVector &eventEffectsAllowed = mEventEffectsAllowed[e];
375
376 // Find the first animation effect with matching name
377 AnimEffectVector::iterator itBeginEffect =
378 find_if (eventEffectsAllowed.begin (),
379 eventEffectsAllowed.end (),
380 boost::bind (&AnimEffectInfo::matchesPluginName,
381 _1, extensionPluginInfo->name));
382
383 if (itBeginEffect == eventEffectsAllowed.end ())
384 continue; // plugin didn't provide any effects for this event
385
386 // Find the first animation effect with non-matching name,
387 // starting with itBeginEffect
388 AnimEffectVector::iterator itEndEffect =
389 find_if (itBeginEffect,
390 eventEffectsAllowed.end (),
391 boost::bind (&AnimEffectInfo::matchesPluginName,
392 _1, extensionPluginInfo->name) == false);
393
394 eventEffectsAllowed.erase (itBeginEffect, itEndEffect);
395
396 // Update event effects to complete removal
397 updateEventEffects ((AnimEvent)e, false);
398 if (e != AnimEventFocus)
399 updateEventEffects ((AnimEvent)e, true);
400 }
401
402 const CompWindowList &cpl = pushLockedPaintList ();
403
404 // Destroy persistent window data for the extension plugin
405 foreach (CompWindow *w, cpl)
406 {
407 AnimWindow *aw = AnimWindow::get (w);
408 extensionPluginInfo->destroyPersistentData (aw);
409 }
410
411 popLockedPaintList ();
412}
413
414ExtensionPluginInfo::ExtensionPluginInfo (const CompString &name,
415 unsigned int nEffects,
416 AnimEffect *effects,
417 CompOption::Vector *effectOptions,
418 unsigned int firstEffectOptionIndex) :
419 name (name),
420 nEffects (nEffects),
421 effects (effects),
422 effectOptions (effectOptions),
423 firstEffectOptionIndex (firstEffectOptionIndex)
424{
425}
426
427// End of extension functions
428
429Animation::Animation (CompWindow *w,
430 WindowEvent curWindowEvent,
431 float duration,
432 const AnimEffect info,
433 const CompRect &icon) :
434 mWindow (w),
435 mAWindow (AnimWindow::get (w)),
436 mTotalTime (duration),
437 mRemainingTime (duration),
438 mTimeElapsedWithinTimeStep (0),
439 mOverrideProgressDir (0),
440 mCurPaintAttrib (GLWindow::defaultPaintAttrib),
441 mStoredOpacity (CompositeWindow::get (w)->opacity ()),
442 mCurWindowEvent (curWindowEvent),
443 mInitialized (false), // store window opacity
444 mInfo (info),
445 mIcon (icon)
446{
447 if (curWindowEvent == WindowEventShade ||
448 curWindowEvent == WindowEventUnshade)
449 {
450 mDecorTopHeight = w->output ().top;
451 mDecorBottomHeight = w->output ().bottom;
452 }
453
454 texturesCache = new GLTexture::List (GLWindow::get (w)->textures ());
455 PrivateAnimScreen *as = mAWindow->priv->paScreen ();
456
457 mTimestep = as->optionGetTimeStep ();
458}
459
460Animation::~Animation ()
461{
462 delete texturesCache;
463}
464
465CompOption::Value &
466Animation::optVal (unsigned int optionId)
467{
468 return mAWindow->pluginOptVal (getExtensionPluginInfo (), optionId, this);
469}
470
471/// Play the animation effect backwards from where it left off.
472void
473Animation::reverse ()
474{
475 mRemainingTime = mTotalTime - mRemainingTime;
476
477 // avoid window remains
478 if (mRemainingTime <= 0)
479 mRemainingTime = 1;
480
481 switch (mCurWindowEvent) // the old event
482 {
483 case WindowEventOpen:
484 mCurWindowEvent = WindowEventClose;
485 break;
486 case WindowEventClose:
487 mCurWindowEvent = WindowEventOpen;
488 break;
489 case WindowEventMinimize:
490 mCurWindowEvent = WindowEventUnminimize;
491 break;
492 case WindowEventUnminimize:
493 mCurWindowEvent = WindowEventMinimize;
494 break;
495 case WindowEventShade:
496 mCurWindowEvent = WindowEventUnshade;
497 break;
498 case WindowEventUnshade:
499 mCurWindowEvent = WindowEventShade;
500 break;
501 default:
502 break;
503 }
504
505 // 1: forward, 2: backward (3 - progressDir is opposite direction)
506 int progressDir = 1;
507
508 switch (mCurWindowEvent) // the new event
509 {
510 case WindowEventClose:
511 case WindowEventMinimize:
512 case WindowEventShade:
513 progressDir = 2;
514 break;
515 default:
516 break;
517 }
518
519 if (mOverrideProgressDir == 0)
520 mOverrideProgressDir = progressDir;
521 else if (mOverrideProgressDir == 3 - progressDir)
522 mOverrideProgressDir = 0; // disable override
523}
524
525PartialWindowAnim::PartialWindowAnim (CompWindow *w,
526 WindowEvent curWindowEvent,
527 float duration,
528 const AnimEffect info,
529 const CompRect &icon) :
530 Animation::Animation (w, curWindowEvent, duration, info, icon),
531 mUseDrawRegion (false),
532 mDrawRegion ()
533{
534}
535
536void
537PrivateAnimWindow::updateSelectionRow (unsigned int r)
538{
539 mPrevAnimSelectionRow = mCurAnimSelectionRow;
540 mCurAnimSelectionRow = (int)r;
541}
542
543// Assumes events in the metadata are in
544// [Open, Close, Minimize, Focus, Shade] order
545// and effects among those are in alphabetical order
546// but with "(Event) None" first and "(Event) Random" last.
547AnimEffect
548PrivateAnimScreen::getMatchingAnimSelection (CompWindow *w,
549 AnimEvent e,
550 int *duration)
551{
552 PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
553
554 EffectSet *eventEffects = &mEventEffects[e];
555 CompOption::Value &valMatch =
556 getOptions ()[(unsigned)matchOptionIds[e]].value ();
557 CompOption::Value &valDuration =
558 getOptions ()[(unsigned)durationOptionIds[e]].value ();
559 CompOption::Value &valCustomOptions =
560 getOptions ()[(unsigned)customOptionOptionIds[e]].value ();
561
562 unsigned int nRows = valMatch.list ().size ();
563 if (nRows != eventEffects->effects.size () ||
564 nRows != valDuration.list ().size () ||
565 nRows != valCustomOptions.list ().size ())
566 {
567 compLogMessage ("animation", CompLogLevelError,
568 "Animation settings mismatch in \"Animation "
569 "Selection\" list for %s event.", eventNames[e]);
570 return AnimEffectNone;
571 }
572
573 // Find the first row that matches this window for this event
574 for (unsigned int i = 0; i < nRows; i++)
575 {
576 if (!valMatch.list ()[i].match ().evaluate (w))
577 continue;
578
579 aw->updateSelectionRow (i);
580
581 if (duration)
582 *duration = valDuration.list ()[i].i ();
583
584 AnimEffect effect = eventEffects->effects[i];
585
586 return (effect ? effect : AnimEffectNone);
587 }
588
589 return AnimEffectNone;
590}
591
592AnimEffect
593PrivateAnimScreen::getActualEffect (AnimEffect effect,
594 AnimEvent animEvent)
595{
596 bool allRandom = optionGetAllRandom ();
597 AnimEffectVector *randomEffects = &mRandomEffects[animEvent].effects;
598 unsigned int nRandomEffects = randomEffects->size ();
599 unsigned int nFirstRandomEffect = 0;
600
601 if ((effect == AnimEffectRandom) || allRandom)
602 {
603 if (nRandomEffects == 0) // no random animation selected, assume "all"
604 {
605 randomEffects = &mEventEffectsAllowed[animEvent];
606
607 // exclude None and Random
608 nFirstRandomEffect = 2;
609 nRandomEffects = randomEffects->size () - 2;
610 }
611 unsigned int index = nFirstRandomEffect +
612 (unsigned int)(nRandomEffects * (double)rand () / RAND_MAX);
613 return (*randomEffects)[index];
614 }
615 else
616 return effect;
617}
618
619/// Converts animation direction (up, down, left, right, random, auto)
620/// to an actual direction (up, down, left, or right).
621AnimDirection
622Animation::getActualAnimDirection (AnimDirection dir,
623 bool openDir)
624{
625 if (dir == AnimDirectionRandom)
626 {
627 dir = (AnimDirection)(rand () % 4);
628 }
629 else if (dir == AnimDirectionAuto)
630 {
631 CompRect outRect (mAWindow->savedRectsValid () ?
632 mAWindow->savedOutRect () :
633 mWindow->outputRect ());
634
635 // away from icon
636 int centerX = outRect.x () + outRect.width () / 2 ;
637 int centerY = outRect.y () + outRect.height () / 2 ;
638 float relDiffX = ((float)centerX - mIcon.x ()) / outRect.width ();
639 float relDiffY = ((float)centerY - mIcon.y ()) / outRect.height ();
640
641 if (openDir)
642 {
643 if (mCurWindowEvent == WindowEventMinimize ||
644 mCurWindowEvent == WindowEventUnminimize)
645 // min/unmin. should always result in +/- y direction
646 dir = (mIcon.y () < (int)::screen->height () - mIcon.y ()) ?
647 AnimDirectionDown : AnimDirectionUp;
648 else if (fabs (relDiffY) > fabs (relDiffX))
649 dir = relDiffY > 0 ? AnimDirectionDown : AnimDirectionUp;
650 else
651 dir = relDiffX > 0 ? AnimDirectionRight : AnimDirectionLeft;
652 }
653 else
654 {
655 if (mCurWindowEvent == WindowEventMinimize ||
656 mCurWindowEvent == WindowEventUnminimize)
657 // min/unmin. should always result in +/- y direction
658 dir = (mIcon.y () < (int)::screen->height () - mIcon.y ()) ?
659 AnimDirectionUp : AnimDirectionDown;
660 else if (fabs (relDiffY) > fabs (relDiffX))
661 dir = relDiffY > 0 ? AnimDirectionUp : AnimDirectionDown;
662 else
663 dir = relDiffX > 0 ? AnimDirectionLeft : AnimDirectionRight;
664 }
665 }
666 return dir;
667}
668
669float
670Animation::progressLinear ()
671{
672 float forwardProgress =
673 1 - mRemainingTime / (mTotalTime - mTimestep);
674 forwardProgress = MIN (forwardProgress, 1);
675 forwardProgress = MAX (forwardProgress, 0);
676
677 if (mCurWindowEvent == WindowEventOpen ||
678 mCurWindowEvent == WindowEventUnminimize ||
679 mCurWindowEvent == WindowEventUnshade ||
680 mCurWindowEvent == WindowEventFocus)
681 forwardProgress = 1 - forwardProgress;
682
683 return forwardProgress;
684}
685
686float
687Animation::progressEaseInEaseOut ()
688{
689 float forwardProgress =
690 1 - mRemainingTime / (mTotalTime - mTimestep);
691 forwardProgress = MIN (forwardProgress, 1);
692 forwardProgress = MAX (forwardProgress, 0);
693
694 // Apply sigmoid and normalize
695 forwardProgress =
696 (sigmoid (forwardProgress) - sigmoid (0)) /
697 (sigmoid (1) - sigmoid (0));
698
699 if (mCurWindowEvent == WindowEventOpen ||
700 mCurWindowEvent == WindowEventUnminimize ||
701 mCurWindowEvent == WindowEventUnshade ||
702 mCurWindowEvent == WindowEventFocus)
703 forwardProgress = 1 - forwardProgress;
704
705 return forwardProgress;
706}
707
708/// Gives some acceleration (when closing a window)
709/// or deceleration (when opening a window).
710/// Applies a sigmoid with slope s,
711/// where minx and maxx are the
712/// starting and ending points on the sigmoid.
713float
714Animation::progressDecelerateCustom (float progress, float minx, float maxx)
715{
716 float x = 1 - progress;
717 float s = 8;
718
719 return
720 1 - ((sigmoid2 (minx + (x * (maxx - minx)), s) - sigmoid2 (minx, s)) /
721 (sigmoid2 (maxx, s) - sigmoid2 (minx, s)));
722}
723
724float
725Animation::progressDecelerate (float progress)
726{
727 return progressDecelerateCustom (progress, 0.5, 0.75);
728}
729
730BoxPtr
731AnimWindow::BB ()
732{
733 return &priv->mBB;
734}
735
736CompRegion &
737AnimWindow::stepRegion ()
738{
739 return priv->mStepRegion;
740}
741
742void
743PrivateAnimWindow::copyResetStepRegion ()
744{
745 mLastStepRegion = mStepRegion;
746
747 // Reset bounding box for current step
748 mBB.x1 = mBB.y1 = MAXSHORT;
749 mBB.x2 = mBB.y2 = MINSHORT;
750}
751
752void
753AnimWindow::expandBBWithBox (Box &source)
754{
755 Box &target = priv->BB ();
756
757 if (source.x1 < target.x1)
758 target.x1 = source.x1;
759 if (source.x2 > target.x2)
760 target.x2 = source.x2;
761 if (source.y1 < target.y1)
762 target.y1 = source.y1;
763 if (source.y2 > target.y2)
764 target.y2 = source.y2;
765}
766
767void
768AnimWindow::expandBBWithPoint (float fx, float fy)
769{
770 Box &target = priv->BB ();
771
772 short x = MAX (MIN (fx, MAXSHORT - 1), MINSHORT);
773 short y = MAX (MIN (fy, MAXSHORT - 1), MINSHORT);
774
775 if (target.x1 == MAXSHORT)
776 {
777 target.x1 = x;
778 target.y1 = y;
779 target.x2 = x + 1;
780 target.y2 = y + 1;
781 return;
782 }
783 if (x < target.x1)
784 target.x1 = x;
785 else if (x > target.x2)
786 target.x2 = x;
787
788 if (y < target.y1)
789 target.y1 = y;
790 else if (y > target.y2)
791 target.y2 = y;
792}
793
794/// This will work for zoom-like 2D transforms,
795/// but not for glide-like 3D transforms.
796void
797AnimWindow::expandBBWithPoint2DTransform (GLVector &coords,
798 GLMatrix &transformMat)
799{
800 GLVector coordsTransformed = transformMat * coords;
801 expandBBWithPoint (coordsTransformed[GLVector::x],
802 coordsTransformed[GLVector::y]);
803}
804
805/// Either points or objects should be non-0.
806bool
807AnimWindow::expandBBWithPoints3DTransform (CompOutput &output,
808 GLMatrix &transform,
809 const float *points,
810 GridAnim::GridModel::GridObject *objects,
811 unsigned int nPoints)
812{
813 GLdouble dModel[16];
814 GLdouble dProjection[16];
815 GLdouble x, y, z;
816 for (unsigned int i = 0; i < 16; i++)
817 {
818 dModel[i] = transform[i];
819 dProjection[i] = GLScreen::get (::screen)->projectionMatrix ()[i];
820 }
821 GLint viewport[4] =
822 {output.region ()->extents.x1,
823 output.region ()->extents.y1,
824 output.width (),
825 output.height ()};
826
827 if (points) // use points
828 {
829 for (; nPoints; nPoints--, points += 3)
830 {
831 if (!gluProject (points[0], points[1], points[2],
832 dModel, dProjection, viewport,
833 &x, &y, &z))
834 return false;
835
836 expandBBWithPoint (x + 0.5, (::screen->height () - y) + 0.5);
837 }
838 }
839 else // use grid model objects
840 {
841 GridAnim::GridModel::GridObject *object = objects;
842 for (; nPoints; nPoints--, object++)
843 {
844 if (!gluProject (object->position ().x (),
845 object->position ().y (),
846 object->position ().z (),
847 dModel, dProjection, viewport,
848 &x, &y, &z))
849 return false;
850
851 expandBBWithPoint (x + 0.5, (::screen->height () - y) + 0.5);
852 }
853 }
854 return true;
855}
856
857void
858AnimWindow::expandBBWithWindow ()
859{
860 CompRect outRect (savedRectsValid () ?
861 savedOutRect () :
862 mWindow->outputRect ());
863 Box windowBox = {
864 outRect.x (), outRect.x () + outRect.width (),
865 outRect.y (), outRect.y () + outRect.height ()
866 };
867 expandBBWithBox (windowBox);
868}
869
870void
871AnimWindow::expandBBWithScreen ()
872{
873 Box screenBox = {0, ::screen->width (),
874 0, ::screen->height ()};
875 expandBBWithBox (screenBox);
876}
877
878void
879Animation::prepareTransform (CompOutput &output,
880 GLMatrix &resultTransform,
881 GLMatrix &transform)
882{
883 GLMatrix sTransform;
884 sTransform.toScreenSpace (&output, -DEFAULT_Z_CAMERA);
885 resultTransform = sTransform * transform;
886}
887
888void
889AnimWindow::resetStepRegionWithBB ()
890{
891 // Have a 1 pixel margin to prevent occasional 1 pixel line artifact
892 CompRegion region (priv->mBB.x1 - 1,
893 priv->mBB.y1 - 1,
894 priv->mBB.x2 - priv->mBB.x1 + 2,
895 priv->mBB.y2 - priv->mBB.y1 + 2);
896 priv->mStepRegion = region;
897}
898
899/// Damage the union of window's bounding box
900/// before and after animStepFunc does its job.
901void
902PrivateAnimWindow::damageThisAndLastStepRegion ()
903{
904 // Find union of the regions for this step and last step
905 CompRegion totalRegionToDamage (mStepRegion + mLastStepRegion);
906
907 mPAScreen->cScreen->damageRegion (totalRegionToDamage);
908}
909
910CompOutput &
911AnimScreen::output ()
912{
913 return priv->output ();
914}
915
916bool
917AnimScreen::getMousePointerXY (short *x, short *y)
918{
919 Window w1, w2;
920 int xp, yp, xj, yj;
921 unsigned int m;
922
923 if (XQueryPointer
924 (::screen->dpy (), ::screen->root (), &w1, &w2, &xj, &yj, &xp, &yp, &m))
925 {
926 *x = xp;
927 *y = yp;
928 return true;
929 }
930 return false;
931}
932
933unsigned int
934PrivateAnimWindow::getState ()
935{
936 Atom actual;
937 int result, format;
938 unsigned long n, left;
939 unsigned char *data;
940 unsigned int retval = WithdrawnState;
941
942 result = XGetWindowProperty (::screen->dpy (), mWindow->id (),
943 Atoms::wmState, 0L,
944 1L, false,
945 Atoms::wmState,
946 &actual, &format, &n, &left, &data);
947
948 if (result == Success && data)
949 {
950 if (n)
951 memcpy (&retval, data, sizeof (int));
952
953 XFree ((void *)data);
954 }
955
956 return retval;
957}
958
959CompOption::Vector &
960AnimScreen::getOptions ()
961{
962 return priv->getOptions ();
963}
964
965bool
966AnimScreen::setOption (const CompString &name,
967 CompOption::Value &value)
968{
969 return priv->setOption (name, value);
970}
971
972void
973PrivateAnimScreen::eventMatchesChanged (CompOption *opt,
974 AnimationOptions::Options num)
975{
976 if (mExtensionPlugins.size () == 0)
977 initAnimationList ();
978 foreach (CompOption::Value &val, opt->value ().list ())
979 val.match ().update ();
980}
981
982void
983PrivateAnimScreen::eventOptionsChanged (CompOption *opt,
984 AnimationOptions::Options num)
985{
986 if (mExtensionPlugins.size () == 0)
987 initAnimationList ();
988 updateOptionSets (getCorrespondingAnimEvent (num));
989}
990
991void
992PrivateAnimScreen::eventEffectsChanged (CompOption *opt,
993 AnimationOptions::Options num)
994{
995 if (mExtensionPlugins.size () == 0)
996 initAnimationList ();
997 updateEventEffects (getCorrespondingAnimEvent (num), false);
998}
999
1000void
1001PrivateAnimScreen::eventRandomEffectsChanged (CompOption *opt,
1002 AnimationOptions::Options num)
1003{
1004 if (mExtensionPlugins.size () == 0)
1005 initAnimationList ();
1006 updateEventEffects (getCorrespondingAnimEvent (num), true);
1007}
1008
1009void
1010PrivateAnimWindow::postAnimationCleanUpCustom (bool closing,
1011 bool destructing,
1012 bool clearMatchingRow)
1013{
1014 bool shouldDamageWindow = false;
1015
1016 notifyAnimation (false);
1017
1018 if (mCurAnimation)
1019 {
1020 if (mCurAnimation->shouldDamageWindowOnEnd ())
1021 shouldDamageWindow = true;
1022 }
1023 enablePainting (false);
1024
1025 if (shouldDamageWindow)
1026 mAWindow->expandBBWithWindow ();
1027
1028 if (shouldDamageWindow ||
1029 (mCurAnimation &&
1030 !mCurAnimation->stepRegionUsed () &&
1031 mAWindow->BB ()->x1 != MAXSHORT)) // BB intialized
1032 mAWindow->resetStepRegionWithBB ();
1033
1034 damageThisAndLastStepRegion ();
1035
1036 if (mCurAnimation)
1037 {
1038 mCurAnimation->cleanUp (closing, destructing);
1039 delete mCurAnimation;
1040 mCurAnimation = 0;
1041 }
1042
1043 mBB.x1 = mBB.y1 = MAXSHORT;
1044 mBB.x2 = mBB.y2 = MINSHORT;
1045
1046 mState = mNewState;
1047
1048 if (clearMatchingRow)
1049 mCurAnimSelectionRow = -1;
1050
1051 mFinishingAnim = true;
1052 if (!destructing)
1053 {
1054 mIgnoreDamage = true;
1055 while (mUnmapCnt > 0)
1056 {
1057 mWindow->unmap ();
1058 mUnmapCnt--;
1059 }
1060 if (mUnmapCnt < 0)
1061 mUnmapCnt = 0;
1062 mIgnoreDamage = false;
1063 }
1064
1065 while (mDestroyCnt)
1066 {
1067 mWindow->destroy ();
1068 mDestroyCnt--;
1069 }
1070 mFinishingAnim = false;
1071
1072 foreach (ExtensionPluginInfo *extPlugin, mPAScreen->mExtensionPlugins)
1073 extPlugin->cleanUpAnimation (closing, destructing);
1074}
1075
1076void
1077AnimWindow::postAnimationCleanUp ()
1078{
1079 priv->postAnimationCleanUp ();
1080}
1081
1082void
1083PrivateAnimWindow::postAnimationCleanUp ()
1084{
1085 if (mCurAnimation->curWindowEvent () == WindowEventClose)
1086 postAnimationCleanUpCustom (true, false, true);
1087 else
1088 postAnimationCleanUpCustom (false, false, true);
1089}
1090
1091void
1092PrivateAnimWindow::postAnimationCleanUpPrev (bool closing,
1093 bool clearMatchingRow)
1094{
1095 int curAnimSelectionRow = mCurAnimSelectionRow;
1096 // Use previous event's anim selection row
1097 mCurAnimSelectionRow = mPrevAnimSelectionRow;
1098
1099 postAnimationCleanUpCustom (closing, false, clearMatchingRow);
1100
1101 // Restore current event's anim selection row
1102 mCurAnimSelectionRow = curAnimSelectionRow;
1103}
1104
1105void
1106PrivateAnimScreen::activateEvent (bool activating)
1107{
1108 if (activating)
1109 {
1110 if (mAnimInProgress)
1111 return;
1112 }
1113 else
1114 {
1115 // Animations have finished for all windows
1116 // (Keep preparePaint enabled)
1117
1118 aScreen->enableCustomPaintList (false);
1119 }
1120 cScreen->donePaintSetEnabled (this, activating);
1121 gScreen->glPaintOutputSetEnabled (this, activating);
1122
1123 mAnimInProgress = activating;
1124
1125 CompOption::Vector o (0);
1126
1127 o.push_back (CompOption ("root", CompOption::TypeInt));
1128 o.push_back (CompOption ("active", CompOption::TypeBool));
1129
1130 o[0].value ().set ((int) ::screen->root ());
1131 o[1].value ().set (activating);
1132
1133 ::screen->handleCompizEvent ("animation", "activate", o);
1134}
1135
1136void
1137PrivateAnimWindow::notifyAnimation (bool activation)
1138{
1139 CompOption::Vector o (0);
1140
1141 if (!mCurAnimation)
1142 return;
1143
1144 o.push_back (CompOption ("root", CompOption::TypeInt));
1145 o.push_back (CompOption ("window", CompOption::TypeInt));
1146 o.push_back (CompOption ("type", CompOption::TypeString));
1147 o.push_back (CompOption ("active", CompOption::TypeBool));
1148
1149 o[0].value ().set ((int) ::screen->root ());
1150 o[1].value ().set ((int) mWindow->id ());
1151
1152 switch (mCurAnimation->curWindowEvent ())
1153 {
1154 case WindowEventOpen:
1155 o[2].value ().set ("open");
1156 break;
1157 case WindowEventClose:
1158 o[2].value ().set ("close");
1159 break;
1160 case WindowEventMinimize:
1161 o[2].value ().set ("minimize");
1162 break;
1163 case WindowEventUnminimize:
1164 o[2].value ().set ("unminimize");
1165 break;
1166 case WindowEventShade:
1167 o[2].value ().set ("shade");
1168 break;
1169 case WindowEventUnshade:
1170 o[2].value ().set ("unshade");
1171 break;
1172 case WindowEventFocus:
1173 o[2].value ().set ("focus");
1174 break;
1175 case WindowEventNum:
1176 case WindowEventNone:
1177 default:
1178 o[2].value ().set ("none");
1179 break;
1180 }
1181
1182 o[3].value ().set (activation);
1183
1184 screen->handleCompizEvent ("animation", "window_animation", o);
1185}
1186
1187bool
1188PrivateAnimScreen::otherPluginsActive ()
1189{
1190 for (int i = 0; i < WatchedScreenPluginNum; i++)
1191 if (mPluginActive[i])
1192 return true;
1193 return false;
1194}
1195
1196bool
1197Animation::shouldSkipFrame (int msSinceLastPaintActual)
1198{
1199 mTimeElapsedWithinTimeStep += msSinceLastPaintActual;
1200 if (mTimeElapsedWithinTimeStep < mTimestep) // if timestep not yet completed
1201 return true;
1202
1203 mTimeElapsedWithinTimeStep = fmod (mTimeElapsedWithinTimeStep, mTimestep);
1204 return false;
1205}
1206
1207bool
1208Animation::advanceTime (int msSinceLastPaint)
1209{
1210 mRemainingTime -= msSinceLastPaint;
1211 mRemainingTime = MAX (mRemainingTime, 0); // avoid sub-zero values
1212
1213 mTimeSinceLastPaint = msSinceLastPaint;
1214
1215 return (mRemainingTime > 0);
1216}
1217
1218void
1219PrivateAnimScreen::preparePaint (int msSinceLastPaint)
1220{
1221 // Check and update "switcher post wait" counter
1222 if (mSwitcherPostWait > 0)
1223 {
1224 mSwitcherPostWait++;
1225 if (mSwitcherPostWait > 5) // wait over
1226 {
1227 mSwitcherPostWait = 0;
1228
1229 // Reset stacking related info since it will
1230 // cause problems because of the restacking
1231 // just done by Switcher.
1232 ExtensionPluginAnimation *extPlugin =
1233 static_cast<ExtensionPluginAnimation *> (mExtensionPlugins[0]);
1234 extPlugin->resetStackingInfo ();
1235 }
1236 }
1237
1238 foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1239 extPlugin->prePreparePaintGeneral ();
1240
1241 if (mAnimInProgress)
1242 {
1243 int msSinceLastPaintActual;
1244 const CompWindowList &pl = pushLockedPaintList ();
1245 CompWindowList windowsFinishedAnimations;
1246
1247 struct timeval curTime;
1248 gettimeofday (&curTime, 0);
1249
1250 if (mLastRedrawTimeFresh)
1251 {
1252 msSinceLastPaintActual = timer::timeval_diff (&curTime, &mLastRedrawTime);
1253 // handle clock rollback
1254 if (msSinceLastPaintActual < 0)
1255 msSinceLastPaintActual = 0;
1256 }
1257 else
1258 msSinceLastPaintActual = 20; // assume 20 ms passed
1259
1260 mLastRedrawTime = curTime; // Store current time for next time
1261 mLastRedrawTimeFresh = true;
1262
1263 bool animStillInProgress = false;
1264
1265 /* Paint list includes destroyed windows */
1266 for (CompWindowList::const_reverse_iterator rit = pl.rbegin ();
1267 rit != pl.rend (); rit++)
1268 {
1269 CompWindow *w = (*rit);
1270 AnimWindow *animWin = AnimWindow::get (w);
1271 PrivateAnimWindow *aw = animWin->priv;
1272 Animation *curAnim = aw->curAnimation ();
1273
1274 if (curAnim)
1275 {
1276 if (!curAnim->initialized ())
1277 curAnim->init ();
1278
1279 if (curAnim->prePreparePaint (msSinceLastPaint))
1280 animStillInProgress = true;
1281
1282 /* TODO optimize grid model by reusing one GridModel
1283 if (aw->com.mModel &&
1284 (aw->com.mModel->winWidth != outRect.width () ||
1285 aw->com.mModel->winHeight != outRect.height ()))
1286 {
1287 // mModel needs update
1288 // re-create mModel
1289 if (!animEnsureModel (w))
1290 {
1291 // Abort this window's animation
1292 postAnimationCleanUp (w);
1293 continue;
1294 }
1295 }*/
1296
1297 bool animShouldSkipFrame =
1298 (curAnim->shouldSkipFrame (msSinceLastPaintActual) &&
1299 // Skip only if we're not on the first animation frame
1300 curAnim->initialized ());
1301
1302 // Skip only if we're not on the last animation frame
1303 animShouldSkipFrame &=
1304 curAnim->advanceTime (msSinceLastPaint);
1305
1306 if (!animShouldSkipFrame)
1307 {
1308 if (curAnim->updateBBUsed ())
1309 {
1310 aw->copyResetStepRegion ();
1311
1312 if (!curAnim->initialized () &&
1313 curAnim->shouldDamageWindowOnStart ())
1314 aw->aWindow ()->expandBBWithWindow ();
1315 }
1316
1317 if (!curAnim->initialized ())
1318 curAnim->setInitialized ();
1319
1320 curAnim->step ();
1321
1322 if (curAnim->updateBBUsed ())
1323 {
1324 foreach (CompOutput &output, ::screen->outputDevs ())
1325 curAnim->updateBB (output);
1326
1327 if (!curAnim->stepRegionUsed () &&
1328 aw->BB ().x1 != MAXSHORT) // BB initialized
1329 {
1330 // BB is used instead of step region,
1331 // so reset step region here with BB.
1332 animWin->resetStepRegionWithBB ();
1333 }
1334 if (!(cScreen->damageMask () &
1335 COMPOSITE_SCREEN_DAMAGE_ALL_MASK))
1336 aw->damageThisAndLastStepRegion ();
1337 }
1338 }
1339
1340 bool finished = (curAnim->remainingTime () <= 0);
1341 if (finished) // Animation is done
1342 windowsFinishedAnimations.push_back (w);
1343 else
1344 animStillInProgress = true;
1345 }
1346 }
1347
1348 foreach (CompWindow *w, pl)
1349 {
1350 PrivateAnimWindow *aw = AnimWindow::get (w)->priv;
1351 if (aw->curAnimation ())
1352 aw->curAnimation ()->postPreparePaint ();
1353 }
1354
1355 popLockedPaintList ();
1356 }
1357
1358 foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1359 extPlugin->postPreparePaintGeneral ();
1360
1361 cScreen->preparePaint (msSinceLastPaint);
1362
1363 if (mStartCountdown)
1364 {
1365 mStartCountdown--;
1366 if (!mStartCountdown)
1367 {
1368 foreach (ExtensionPluginInfo *extPlugin, mExtensionPlugins)
1369 extPlugin->postStartupCountdown ();
1370 }
1371 }
1372}
1373
1374void
1375PrivateAnimScreen::donePaint ()
1376{
1377 assert (mAnimInProgress);
1378
1379 const CompWindowList &pl = pushLockedPaintList ();
1380 CompWindowList windowsFinishedAnimations;
1381
1382 bool animStillInProgress = false;
1383
1384 /* Paint list includes destroyed windows */
1385 for (CompWindowList::const_reverse_iterator rit = pl.rbegin ();
1386 rit != pl.rend (); rit++)
1387 {
1388 CompWindow *w = (*rit);
1389 AnimWindow *animWin = AnimWindow::get (w);
1390 PrivateAnimWindow *aw = animWin->priv;
1391 Animation *curAnim = aw->curAnimation ();
1392
1393 if (curAnim)
1394 {
1395 bool finished = (curAnim->remainingTime () <= 0);
1396 if (finished) // Animation is done
1397 windowsFinishedAnimations.push_back (w);
1398 else
1399 animStillInProgress = true;
1400 }
1401 }
1402
1403 popLockedPaintList ();
1404
1405 foreach (CompWindow *w, windowsFinishedAnimations)
1406 {
1407 AnimWindow *aw = AnimWindow::get (w);
1408 aw->priv->notifyAnimation (false);
1409 aw->priv->postAnimationCleanUp ();
1410 }
1411
1412 if (!animStillInProgress)
1413 {
1414 activateEvent (false);
1415 mLastRedrawTimeFresh = false;
1416
1417 // Reset stacking related info after all animations are done.
1418 ExtensionPluginAnimation *extPlugin =
1419 static_cast<ExtensionPluginAnimation *> (mExtensionPlugins[0]);
1420 extPlugin->resetStackingInfo ();
1421 }
1422
1423 cScreen->damagePending ();
1424
1425 cScreen->donePaint ();
1426}
1427
1428void
1429PrivateAnimWindow::enablePainting (bool enabling)
1430{
1431 gWindow->glPaintSetEnabled (this, enabling);
1432 gWindow->glAddGeometrySetEnabled (this, enabling);
1433 gWindow->glDrawGeometrySetEnabled (this, enabling);
1434 gWindow->glDrawTextureSetEnabled (this, enabling);
1435}
1436
1437void
1438PrivateAnimWindow::glAddGeometry (const GLTexture::MatrixList &matrix,
1439 const CompRegion &region,
1440 const CompRegion &clip,
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches