Merge lp:~mc-return/compiz/compiz0.9.9.merge-plugin-freewins into lp:compiz/0.9.9

Proposed by Sam Spilsbury
Status: Merged
Approved by: Sam Spilsbury
Approved revision: 3329
Merged at revision: 3632
Proposed branch: lp:~mc-return/compiz/compiz0.9.9.merge-plugin-freewins
Merge into: lp:compiz/0.9.9
Diff against target: 4761 lines (+4683/-0)
13 files modified
debian/compiz-plugins.install (+1/-0)
plugins/CMakeLists.txt (+1/-0)
plugins/freewins/AUTHORS (+8/-0)
plugins/freewins/CMakeLists.txt (+8/-0)
plugins/freewins/COPYING (+340/-0)
plugins/freewins/freewins.xml.in (+398/-0)
plugins/freewins/src/action.cpp (+763/-0)
plugins/freewins/src/events.cpp (+854/-0)
plugins/freewins/src/freewins.cpp (+271/-0)
plugins/freewins/src/freewins.h (+589/-0)
plugins/freewins/src/input.cpp (+397/-0)
plugins/freewins/src/paint.cpp (+527/-0)
plugins/freewins/src/util.cpp (+526/-0)
To merge this branch: bzr merge lp:~mc-return/compiz/compiz0.9.9.merge-plugin-freewins
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Sam Spilsbury Approve
Review via email: mp+150960@code.launchpad.net

This proposal supersedes a proposal from 2013-02-03.

Commit message

Added the plug-in "Freely Transformable Windows" aka freewins converted from git to bzr (including full history) to lp:compiz.

(LP: #1012194)

Description of the change

This MP adds the spectacular plugin freewins to lp:compiz.

It is fully working and after a few fixes fully stable.

The only problem left is, that the user cannot re-grab a
already transformed window, while multiple transformations
and grabs of a single window during time of animation works.

Selecting transformed windows (via Switcher for example) works
though and resetting the applied transformations via shortcut
is also possible, so the user will never end up with a transformed
window that cannot be reverted.

The grab logic has yet to be revisited though to make this plugin
work perfectly...

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

This is fine. The reason why users can't re-grab windows is because the input-prevention code has been commented out. Its a pretty easy fix though if we re-enable it, have a chat on IRC about it.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Stephen M. Webb (bregma) wrote : Posted in a previous version of this proposal

Looks like this MP is missing required changes to the inline packaging.

Revision history for this message
Francis Ginther (fginther) wrote : Posted in a previous version of this proposal

The armhf build was terminated before completion to allow another branch to be processed. However, the amd64 and i386 jobs already failed due to the following packaging error:

dh_install: usr/share/compiz/freewins.xml exists in debian/tmp but is not installed to anywhere
dh_install: usr/lib/compiz/libfreewins.so exists in debian/tmp but is not installed to anywhere

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Ah missed that. You'll need to fix that @MCR1

On Fri, Feb 22, 2013 at 11:07 AM, Stephen M. Webb
<email address hidden> wrote:
> Looks like this MP is missing required changes to the inline packaging.
> --
> https://code.launchpad.net/~mc-return/compiz/compiz0.9.9.merge-plugin-freewins/+merge/146291
> You are reviewing the proposed merge of lp:~mc-return/compiz/compiz0.9.9.merge-plugin-freewins into lp:compiz.

--
Sam Spilsbury

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

bregma, fginther, smspillaz: Yeah, sorry - I missed that :)
I will fix it ASAP.

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal

Ok, should be fixed now. :)

Revision history for this message
MC Return (mc-return) wrote : Posted in a previous version of this proposal
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Dunno why compiz-ci hasn't re-run this one yet.

review: Needs Resubmitting
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

It'll do for now.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/compiz-plugins.install'
2--- debian/compiz-plugins.install 2013-02-17 07:28:12 +0000
3+++ debian/compiz-plugins.install 2013-02-28 06:12:23 +0000
4@@ -11,6 +11,7 @@
5 debian/tmp/usr/*/compiz/*extrawm.*
6 debian/tmp/usr/*/compiz/*fadedesktop.*
7 debian/tmp/usr/*/compiz/*firepaint.*
8+debian/tmp/usr/*/compiz/*freewins.*
9 debian/tmp/usr/*/compiz/*gears.*
10 debian/tmp/usr/*/compiz/*imgjpeg.*
11 debian/tmp/usr/*/compiz/*imgsvg.*
12
13=== modified file 'plugins/CMakeLists.txt'
14--- plugins/CMakeLists.txt 2013-02-13 04:30:07 +0000
15+++ plugins/CMakeLists.txt 2013-02-28 06:12:23 +0000
16@@ -23,6 +23,7 @@
17 # disable plugins which won't work on ES2 builds
18 if (BUILD_GLES)
19
20+ set (COMPIZ_DISABLE_PLUGIN_FREEWINS ON)
21 set (COMPIZ_DISABLE_PLUGIN_GEARS ON)
22 set (COMPIZ_DISABLE_PLUGIN_TD ON)
23 set (COMPIZ_DISABLE_PLUGIN_COLORFILTER ON)
24
25=== added directory 'plugins/freewins'
26=== added file 'plugins/freewins/AUTHORS'
27--- plugins/freewins/AUTHORS 1970-01-01 00:00:00 +0000
28+++ plugins/freewins/AUTHORS 2013-02-28 06:12:23 +0000
29@@ -0,0 +1,8 @@
30+The freewins plugin was written by:
31+
32+Rodolfo D. Granata (warlock_mza) <warlock.cc@gmail.com>
33+Sam Spilsbury (smspillaz) <smspillaz@gmail.com>
34+
35+Modifications by
36+
37+enigma_0Z <enigma.0ZA@gmail.com>
38
39=== added file 'plugins/freewins/CMakeLists.txt'
40--- plugins/freewins/CMakeLists.txt 1970-01-01 00:00:00 +0000
41+++ plugins/freewins/CMakeLists.txt 2013-02-28 06:12:23 +0000
42@@ -0,0 +1,8 @@
43+find_package (Compiz REQUIRED)
44+
45+include (CompizPlugin)
46+include (FindOpenGL)
47+
48+if (OPENGL_GLU_FOUND)
49+compiz_plugin (freewins PLUGINDEPS composite opengl PKGDEPS cairo-xlib cairo LIBRARIES ${OPENGL_glu_LIBRARY} INCDIRS ${OPENGL_INCLUDE_DIR} LDFLAGSADD)
50+endif (OPENGL_GLU_FOUND)
51
52=== added file 'plugins/freewins/COPYING'
53--- plugins/freewins/COPYING 1970-01-01 00:00:00 +0000
54+++ plugins/freewins/COPYING 2013-02-28 06:12:23 +0000
55@@ -0,0 +1,340 @@
56+ GNU GENERAL PUBLIC LICENSE
57+ Version 2, June 1991
58+
59+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
60+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
61+ Everyone is permitted to copy and distribute verbatim copies
62+ of this license document, but changing it is not allowed.
63+
64+ Preamble
65+
66+ The licenses for most software are designed to take away your
67+freedom to share and change it. By contrast, the GNU General Public
68+License is intended to guarantee your freedom to share and change free
69+software--to make sure the software is free for all its users. This
70+General Public License applies to most of the Free Software
71+Foundation's software and to any other program whose authors commit to
72+using it. (Some other Free Software Foundation software is covered by
73+the GNU Library General Public License instead.) You can apply it to
74+your programs, too.
75+
76+ When we speak of free software, we are referring to freedom, not
77+price. Our General Public Licenses are designed to make sure that you
78+have the freedom to distribute copies of free software (and charge for
79+this service if you wish), that you receive source code or can get it
80+if you want it, that you can change the software or use pieces of it
81+in new free programs; and that you know you can do these things.
82+
83+ To protect your rights, we need to make restrictions that forbid
84+anyone to deny you these rights or to ask you to surrender the rights.
85+These restrictions translate to certain responsibilities for you if you
86+distribute copies of the software, or if you modify it.
87+
88+ For example, if you distribute copies of such a program, whether
89+gratis or for a fee, you must give the recipients all the rights that
90+you have. You must make sure that they, too, receive or can get the
91+source code. And you must show them these terms so they know their
92+rights.
93+
94+ We protect your rights with two steps: (1) copyright the software, and
95+(2) offer you this license which gives you legal permission to copy,
96+distribute and/or modify the software.
97+
98+ Also, for each author's protection and ours, we want to make certain
99+that everyone understands that there is no warranty for this free
100+software. If the software is modified by someone else and passed on, we
101+want its recipients to know that what they have is not the original, so
102+that any problems introduced by others will not reflect on the original
103+authors' reputations.
104+
105+ Finally, any free program is threatened constantly by software
106+patents. We wish to avoid the danger that redistributors of a free
107+program will individually obtain patent licenses, in effect making the
108+program proprietary. To prevent this, we have made it clear that any
109+patent must be licensed for everyone's free use or not licensed at all.
110+
111+ The precise terms and conditions for copying, distribution and
112+modification follow.
113+
114+ GNU GENERAL PUBLIC LICENSE
115+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
116+
117+ 0. This License applies to any program or other work which contains
118+a notice placed by the copyright holder saying it may be distributed
119+under the terms of this General Public License. The "Program", below,
120+refers to any such program or work, and a "work based on the Program"
121+means either the Program or any derivative work under copyright law:
122+that is to say, a work containing the Program or a portion of it,
123+either verbatim or with modifications and/or translated into another
124+language. (Hereinafter, translation is included without limitation in
125+the term "modification".) Each licensee is addressed as "you".
126+
127+Activities other than copying, distribution and modification are not
128+covered by this License; they are outside its scope. The act of
129+running the Program is not restricted, and the output from the Program
130+is covered only if its contents constitute a work based on the
131+Program (independent of having been made by running the Program).
132+Whether that is true depends on what the Program does.
133+
134+ 1. You may copy and distribute verbatim copies of the Program's
135+source code as you receive it, in any medium, provided that you
136+conspicuously and appropriately publish on each copy an appropriate
137+copyright notice and disclaimer of warranty; keep intact all the
138+notices that refer to this License and to the absence of any warranty;
139+and give any other recipients of the Program a copy of this License
140+along with the Program.
141+
142+You may charge a fee for the physical act of transferring a copy, and
143+you may at your option offer warranty protection in exchange for a fee.
144+
145+ 2. You may modify your copy or copies of the Program or any portion
146+of it, thus forming a work based on the Program, and copy and
147+distribute such modifications or work under the terms of Section 1
148+above, provided that you also meet all of these conditions:
149+
150+ a) You must cause the modified files to carry prominent notices
151+ stating that you changed the files and the date of any change.
152+
153+ b) You must cause any work that you distribute or publish, that in
154+ whole or in part contains or is derived from the Program or any
155+ part thereof, to be licensed as a whole at no charge to all third
156+ parties under the terms of this License.
157+
158+ c) If the modified program normally reads commands interactively
159+ when run, you must cause it, when started running for such
160+ interactive use in the most ordinary way, to print or display an
161+ announcement including an appropriate copyright notice and a
162+ notice that there is no warranty (or else, saying that you provide
163+ a warranty) and that users may redistribute the program under
164+ these conditions, and telling the user how to view a copy of this
165+ License. (Exception: if the Program itself is interactive but
166+ does not normally print such an announcement, your work based on
167+ the Program is not required to print an announcement.)
168+
169
170+These requirements apply to the modified work as a whole. If
171+identifiable sections of that work are not derived from the Program,
172+and can be reasonably considered independent and separate works in
173+themselves, then this License, and its terms, do not apply to those
174+sections when you distribute them as separate works. But when you
175+distribute the same sections as part of a whole which is a work based
176+on the Program, the distribution of the whole must be on the terms of
177+this License, whose permissions for other licensees extend to the
178+entire whole, and thus to each and every part regardless of who wrote it.
179+
180+Thus, it is not the intent of this section to claim rights or contest
181+your rights to work written entirely by you; rather, the intent is to
182+exercise the right to control the distribution of derivative or
183+collective works based on the Program.
184+
185+In addition, mere aggregation of another work not based on the Program
186+with the Program (or with a work based on the Program) on a volume of
187+a storage or distribution medium does not bring the other work under
188+the scope of this License.
189+
190+ 3. You may copy and distribute the Program (or a work based on it,
191+under Section 2) in object code or executable form under the terms of
192+Sections 1 and 2 above provided that you also do one of the following:
193+
194+ a) Accompany it with the complete corresponding machine-readable
195+ source code, which must be distributed under the terms of Sections
196+ 1 and 2 above on a medium customarily used for software interchange; or,
197+
198+ b) Accompany it with a written offer, valid for at least three
199+ years, to give any third party, for a charge no more than your
200+ cost of physically performing source distribution, a complete
201+ machine-readable copy of the corresponding source code, to be
202+ distributed under the terms of Sections 1 and 2 above on a medium
203+ customarily used for software interchange; or,
204+
205+ c) Accompany it with the information you received as to the offer
206+ to distribute corresponding source code. (This alternative is
207+ allowed only for noncommercial distribution and only if you
208+ received the program in object code or executable form with such
209+ an offer, in accord with Subsection b above.)
210+
211+The source code for a work means the preferred form of the work for
212+making modifications to it. For an executable work, complete source
213+code means all the source code for all modules it contains, plus any
214+associated interface definition files, plus the scripts used to
215+control compilation and installation of the executable. However, as a
216+special exception, the source code distributed need not include
217+anything that is normally distributed (in either source or binary
218+form) with the major components (compiler, kernel, and so on) of the
219+operating system on which the executable runs, unless that component
220+itself accompanies the executable.
221+
222+If distribution of executable or object code is made by offering
223+access to copy from a designated place, then offering equivalent
224+access to copy the source code from the same place counts as
225+distribution of the source code, even though third parties are not
226+compelled to copy the source along with the object code.
227+
228
229+ 4. You may not copy, modify, sublicense, or distribute the Program
230+except as expressly provided under this License. Any attempt
231+otherwise to copy, modify, sublicense or distribute the Program is
232+void, and will automatically terminate your rights under this License.
233+However, parties who have received copies, or rights, from you under
234+this License will not have their licenses terminated so long as such
235+parties remain in full compliance.
236+
237+ 5. You are not required to accept this License, since you have not
238+signed it. However, nothing else grants you permission to modify or
239+distribute the Program or its derivative works. These actions are
240+prohibited by law if you do not accept this License. Therefore, by
241+modifying or distributing the Program (or any work based on the
242+Program), you indicate your acceptance of this License to do so, and
243+all its terms and conditions for copying, distributing or modifying
244+the Program or works based on it.
245+
246+ 6. Each time you redistribute the Program (or any work based on the
247+Program), the recipient automatically receives a license from the
248+original licensor to copy, distribute or modify the Program subject to
249+these terms and conditions. You may not impose any further
250+restrictions on the recipients' exercise of the rights granted herein.
251+You are not responsible for enforcing compliance by third parties to
252+this License.
253+
254+ 7. If, as a consequence of a court judgment or allegation of patent
255+infringement or for any other reason (not limited to patent issues),
256+conditions are imposed on you (whether by court order, agreement or
257+otherwise) that contradict the conditions of this License, they do not
258+excuse you from the conditions of this License. If you cannot
259+distribute so as to satisfy simultaneously your obligations under this
260+License and any other pertinent obligations, then as a consequence you
261+may not distribute the Program at all. For example, if a patent
262+license would not permit royalty-free redistribution of the Program by
263+all those who receive copies directly or indirectly through you, then
264+the only way you could satisfy both it and this License would be to
265+refrain entirely from distribution of the Program.
266+
267+If any portion of this section is held invalid or unenforceable under
268+any particular circumstance, the balance of the section is intended to
269+apply and the section as a whole is intended to apply in other
270+circumstances.
271+
272+It is not the purpose of this section to induce you to infringe any
273+patents or other property right claims or to contest validity of any
274+such claims; this section has the sole purpose of protecting the
275+integrity of the free software distribution system, which is
276+implemented by public license practices. Many people have made
277+generous contributions to the wide range of software distributed
278+through that system in reliance on consistent application of that
279+system; it is up to the author/donor to decide if he or she is willing
280+to distribute software through any other system and a licensee cannot
281+impose that choice.
282+
283+This section is intended to make thoroughly clear what is believed to
284+be a consequence of the rest of this License.
285+
286
287+ 8. If the distribution and/or use of the Program is restricted in
288+certain countries either by patents or by copyrighted interfaces, the
289+original copyright holder who places the Program under this License
290+may add an explicit geographical distribution limitation excluding
291+those countries, so that distribution is permitted only in or among
292+countries not thus excluded. In such case, this License incorporates
293+the limitation as if written in the body of this License.
294+
295+ 9. The Free Software Foundation may publish revised and/or new versions
296+of the General Public License from time to time. Such new versions will
297+be similar in spirit to the present version, but may differ in detail to
298+address new problems or concerns.
299+
300+Each version is given a distinguishing version number. If the Program
301+specifies a version number of this License which applies to it and "any
302+later version", you have the option of following the terms and conditions
303+either of that version or of any later version published by the Free
304+Software Foundation. If the Program does not specify a version number of
305+this License, you may choose any version ever published by the Free Software
306+Foundation.
307+
308+ 10. If you wish to incorporate parts of the Program into other free
309+programs whose distribution conditions are different, write to the author
310+to ask for permission. For software which is copyrighted by the Free
311+Software Foundation, write to the Free Software Foundation; we sometimes
312+make exceptions for this. Our decision will be guided by the two goals
313+of preserving the free status of all derivatives of our free software and
314+of promoting the sharing and reuse of software generally.
315+
316+ NO WARRANTY
317+
318+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
319+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
320+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
321+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
322+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
323+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
324+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
325+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
326+REPAIR OR CORRECTION.
327+
328+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
329+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
330+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
331+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
332+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
333+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
334+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
335+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
336+POSSIBILITY OF SUCH DAMAGES.
337+
338+ END OF TERMS AND CONDITIONS
339+
340
341+ How to Apply These Terms to Your New Programs
342+
343+ If you develop a new program, and you want it to be of the greatest
344+possible use to the public, the best way to achieve this is to make it
345+free software which everyone can redistribute and change under these terms.
346+
347+ To do so, attach the following notices to the program. It is safest
348+to attach them to the start of each source file to most effectively
349+convey the exclusion of warranty; and each file should have at least
350+the "copyright" line and a pointer to where the full notice is found.
351+
352+ <one line to give the program's name and a brief idea of what it does.>
353+ Copyright (C) <year> <name of author>
354+
355+ This program is free software; you can redistribute it and/or modify
356+ it under the terms of the GNU General Public License as published by
357+ the Free Software Foundation; either version 2 of the License, or
358+ (at your option) any later version.
359+
360+ This program is distributed in the hope that it will be useful,
361+ but WITHOUT ANY WARRANTY; without even the implied warranty of
362+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
363+ GNU General Public License for more details.
364+
365+ You should have received a copy of the GNU General Public License
366+ along with this program; if not, write to the Free Software
367+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
368+
369+
370+Also add information on how to contact you by electronic and paper mail.
371+
372+If the program is interactive, make it output a short notice like this
373+when it starts in an interactive mode:
374+
375+ Gnomovision version 69, Copyright (C) year name of author
376+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
377+ This is free software, and you are welcome to redistribute it
378+ under certain conditions; type `show c' for details.
379+
380+The hypothetical commands `show w' and `show c' should show the appropriate
381+parts of the General Public License. Of course, the commands you use may
382+be called something other than `show w' and `show c'; they could even be
383+mouse-clicks or menu items--whatever suits your program.
384+
385+You should also get your employer (if you work as a programmer) or your
386+school, if any, to sign a "copyright disclaimer" for the program, if
387+necessary. Here is a sample; alter the names:
388+
389+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
390+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
391+
392+ <signature of Ty Coon>, 1 April 1989
393+ Ty Coon, President of Vice
394+
395+This General Public License does not permit incorporating your program into
396+proprietary programs. If your program is a subroutine library, you may
397+consider it more useful to permit linking proprietary applications with the
398+library. If this is what you want to do, use the GNU Library General
399+Public License instead of this License.
400
401=== added file 'plugins/freewins/freewins.xml.in'
402--- plugins/freewins/freewins.xml.in 1970-01-01 00:00:00 +0000
403+++ plugins/freewins/freewins.xml.in 2013-02-28 06:12:23 +0000
404@@ -0,0 +1,398 @@
405+<?xml version="1.0" encoding="UTF-8"?>
406+<compiz>
407+ <plugin name="freewins" useBcop="true">
408+ <_short>Freely Transformable Windows</_short>
409+ <_long>Freely transform windows</_long>
410+ <category>Effects</category>
411+ <deps>
412+ <requirement>
413+ <plugin>opengl</plugin>
414+ </requirement>
415+ <relation type="after">
416+ <plugin>opengl</plugin>
417+ <plugin>scale</plugin>
418+ <plugin>ring</plugin>
419+ <plugin>shift</plugin>
420+ <plugin>shelf</plugin>
421+ <plugin>group</plugin>
422+ <plugin>wobbly</plugin>
423+ <plugin>animation</plugin>
424+ <plugin>water</plugin>
425+ <plugin>cubeaddon</plugin>
426+ <plugin>3d</plugin>
427+ </relation>
428+ </deps>
429+ <options>
430+ <option name='rotate' type='action'/>
431+ <option name='increment_rotate' type='action'/>
432+ <option name='scale' type='action'/>
433+ <group>
434+ <_short>Free Transformation</_short>
435+ <option type="button" name="initiate_rotation_button">
436+ <_short>Initiate Rotation Button</_short>
437+ <_long>Mouse button to start free rotation.</_long>
438+ <default>&lt;Control&gt;&lt;Shift&gt;Button1</default>
439+ </option>
440+ <option type="button" name="initiate_scale_button">
441+ <_short>Initiate Scaling Button</_short>
442+ <_long>Mouse button to start free scaling.</_long>
443+ <default>&lt;Control&gt;&lt;Shift&gt;Button3</default>
444+ </option>
445+ <option type="button" name="reset_button">
446+ <_short>Reset Transformation Button</_short>
447+ <_long>Mouse button to reset the transformation.</_long>
448+ <default>&lt;Control&gt;&lt;Shift&gt;Button2</default>
449+ </option>
450+ <option type="key" name="reset_key">
451+ <_short>Reset Transformation Key</_short>
452+ <_long>Keyboard shortcut to reset the transformation.</_long>
453+ <default>&lt;Control&gt;&lt;Shift&gt;r</default>
454+ </option>
455+ <option type="key" name="toggle_axis_key">
456+ <_short>Axis Help Toggle</_short>
457+ <_long>Keyboard shortcut to toggle the visibility of the axis selection helper.</_long>
458+ <default>&lt;Control&gt;&lt;Shift&gt;h</default>
459+ </option>
460+ <subgroup>
461+ <_short>Transformation Behaviour</_short>
462+ <option name="snap_mods" type="list">
463+ <_short>Snap Modifier</_short>
464+ <_long>Use these bindings to enable/disable snapping.</_long>
465+ <type>int</type>
466+ <min>0</min>
467+ <max>3</max>
468+ <desc>
469+ <value>0</value>
470+ <_name>Shift</_name>
471+ </desc>
472+ <desc>
473+ <value>1</value>
474+ <_name>Alt</_name>
475+ </desc>
476+ <desc>
477+ <value>2</value>
478+ <_name>Control</_name>
479+ </desc>
480+ <desc>
481+ <value>3</value>
482+ <_name>Meta</_name>
483+ </desc>
484+ </option>
485+ </subgroup>
486+ <subgroup>
487+ <_short>Rotation</_short>
488+ <option name="invert_mods" type="list">
489+ <_short>Invert Modifier</_short>
490+ <_long>Use these bindings to invert the rotation mode.</_long>
491+ <type>int</type>
492+ <min>0</min>
493+ <max>3</max>
494+ <desc>
495+ <value>0</value>
496+ <_name>Shift</_name>
497+ </desc>
498+ <desc>
499+ <value>1</value>
500+ <_name>Alt</_name>
501+ </desc>
502+ <desc>
503+ <value>2</value>
504+ <_name>Control</_name>
505+ </desc>
506+ <desc>
507+ <value>3</value>
508+ <_name>Meta</_name>
509+ </desc>
510+ </option>
511+ </subgroup>
512+ </group>
513+ <group>
514+ <_short>Manual Transformation</_short>
515+ <subgroup>
516+ <_short>Scaling</_short>
517+ <option type="button" name="scale_up_button">
518+ <_short>Scale Up Button</_short>
519+ <_long>Mouse button to scale the window up by one increment.</_long>
520+ <default>&lt;Control&gt;&lt;Shift&gt;Button4</default>
521+ </option>
522+ <option type="button" name="scale_down_button">
523+ <_short>Scale Down Button</_short>
524+ <_long>Mouse button to scale the window down by one increment.</_long>
525+ <default>&lt;Control&gt;&lt;Shift&gt;Button5</default>
526+ </option>
527+ <_short>Scaling</_short>
528+ <option type="key" name="scale_up_key">
529+ <_short>Scale Up Key</_short>
530+ <_long>Keyboard shortcut to scale the window up by one increment.</_long>
531+ <default>&lt;Control&gt;&lt;Shift&gt;Page_Up</default>
532+ </option>
533+ <option type="key" name="scale_down_key">
534+ <_short>Scale Down Key</_short>
535+ <_long>Keyboard shortcut to scale the window down by one increment.</_long>
536+ <default>&lt;Control&gt;&lt;Shift&gt;Page_Down</default>
537+ </option>
538+ </subgroup>
539+ <subgroup>
540+ <_short>Rotation</_short>
541+ <option type="key" name="rotate_up_key">
542+ <_short>Rotate Up Key</_short>
543+ <_long>Keyboard shortcut to rotate the window up by one increment.</_long>
544+ <default>&lt;Control&gt;&lt;Shift&gt;w</default>
545+ </option>
546+ <option type="key" name="rotate_down_key">
547+ <_short>Rotate Down Key</_short>
548+ <_long>Keyboard shortcut to rotate the window down by one increment.</_long>
549+ <default>&lt;Control&gt;&lt;Shift&gt;s</default>
550+ </option>
551+ <option type="key" name="rotate_left_key">
552+ <_short>Rotate Left Key</_short>
553+ <_long>Keyboard shortcut to rotate the window left by one increment.</_long>
554+ <default>&lt;Control&gt;&lt;Shift&gt;d</default>
555+ </option>
556+ <option type="key" name="rotate_right_key">
557+ <_short>Rotate Right Key</_short>
558+ <_long>Keyboard shortcut to rotate the window right by one increment.</_long>
559+ <default>&lt;Control&gt;&lt;Shift&gt;a</default>
560+ </option>
561+ <option type="key" name="rotate_c_key">
562+ <_short>Rotate Clockwise Key</_short>
563+ <_long>Keyboard shortcut to rotate the window clockwise by one increment.</_long>
564+ <default>&lt;Control&gt;&lt;Shift&gt;e</default>
565+ </option>
566+ <option type="key" name="rotate_cc_key">
567+ <_short>Rotate Counter-Clockwise Key</_short>
568+ <_long>Keyboard shortcut to rotate the window counter-clockwise by one increment.</_long>
569+ <default>&lt;Control&gt;&lt;Shift&gt;q</default>
570+ </option>
571+ </subgroup>
572+ </group>
573+ <group>
574+ <_short>Free Transformation</_short>
575+ <subgroup>
576+ <_short>Transformation Behaviour</_short>
577+ <option type="bool" name="snap">
578+ <_short>Snap By Default</_short>
579+ <_long>Snap to common points by default.</_long>
580+ <default>False</default>
581+ </option>
582+ <option type="int" name="snap_threshold">
583+ <_short>Snap Threshold</_short>
584+ <_long>Snap to every one of these angles.</_long>
585+ <min>1</min>
586+ <max>100</max>
587+ </option>
588+ <option type="float" name="mouse_sensitivity">
589+ <_short>Mouse Sensitivity</_short>
590+ <_long>Adjust how sensitive the mouse movement should be.</_long>
591+ <default>1.0</default>
592+ <min>0.1</min>
593+ <max>10.0</max>
594+ </option>
595+ </subgroup>
596+ <subgroup>
597+ <_short>Scaling</_short>
598+ <option type="int" name="scale_mode">
599+ <_short>Scale Mode</_short>
600+ <_long>Select the method to scale windows.</_long>
601+ <desc>
602+ <value>0</value><name>To Centre</name>
603+ </desc>
604+ <desc>
605+ <value>1</value><name>To Opposite Corner</name>
606+ </desc>
607+ <min>0</min>
608+ <max>0</max>
609+ <default>0</default>
610+ </option>
611+ <option type="bool" name="allow_negative">
612+ <_short>Allow Negative</_short>
613+ <_long>Allow negative scaling</_long>
614+ <default>True</default>
615+ </option>
616+ <option type="bool" name="scale_uniform">
617+ <_short>Maintain Aspect Ratio</_short>
618+ <_long>Keep the aspect ratio of the window constant when scaling.</_long>
619+ <default>True</default>
620+ </option>
621+ <option type="float" name="min_scale">
622+ <_short>Minimum scale</_short>
623+ <_long>How small the scale is allowed to be when 'Allow Negative' is not activated.</_long>
624+ <default>0.1</default>
625+ <min>0.01</min>
626+ <max>1.0</max>
627+ </option>
628+ </subgroup>
629+ <subgroup>
630+ <_short>Rotation</_short>
631+ <option type="int" name="z_axis_rotation">
632+ <_short>Rotation Type</_short>
633+ <_long>Choose the type of the rotation.</_long>
634+ <desc>
635+ <value>0</value><name>Always 2D</name>
636+ </desc>
637+ <desc>
638+ <value>1</value><name>Always 3D</name>
639+ </desc>
640+ <desc>
641+ <value>2</value><name>Determine On Click</name>
642+ </desc>
643+ <desc>
644+ <value>3</value><name>Interchangeable</name>
645+ </desc>
646+ <desc>
647+ <value>4</value><name>Switch</name>
648+ </desc>
649+ <desc>
650+ <value>5</value><name>Trackball</name>
651+ </desc>
652+ <default>2</default>
653+ <min>0</min><max>3</max>
654+ </option>
655+ <option type="int" name="rotation_axis">
656+ <_short>Rotation Axis</_short>
657+ <_long>How Freely Transformable Windows should determine the rotation axis.</_long>
658+ <desc>
659+ <value>0</value><name>Always Centre</name>
660+ </desc>
661+ <desc>
662+ <value>1</value><name>Click Point</name>
663+ </desc>
664+ <desc>
665+ <value>2</value><name>Opposite to Click</name>
666+ </desc>
667+ <desc>
668+ <value>3</value><name>Nearest Corner</name>
669+ </desc>
670+ <min>0</min>
671+ <max>2</max>
672+ <default>0</default>
673+ </option>
674+ <option type="float" name="TD_percent">
675+ <_short>3D Rotation Percentage</_short>
676+ <_long>The percentage of the window area used for 3D rotation.</_long>
677+ <default>35.0</default>
678+ <min>10.0</min>
679+ <max>90.0</max>
680+ </option>
681+ <option type="bool" name="auto_zoom">
682+ <_short>Auto-Zoom</_short>
683+ <_long>Auto-Zoom when rotating so that windows do not get too large.</_long>
684+ <default>False</default>
685+ </option>
686+ <option type="bool" name="disable_on_transformed_screen">
687+ <_short>Disable On Transformed Screen</_short>
688+ <_long>Disable the rotation on a transformed screen. This prevents ugly looking clipped windows when the screen is transformed.</_long>
689+ <default>False</default>
690+ </option>
691+ </subgroup>
692+ <subgroup>
693+ <_short>Transformation Behaviour</_short>
694+ <option type="float" name="speed">
695+ <_short>Window Rotation Speed</_short>
696+ <_long>How fast the window should rotate.</_long>
697+ <default>5.0</default>
698+ <min>0.1</min>
699+ <max>15.0</max>
700+ </option>
701+ </subgroup>
702+ </group>
703+ <group>
704+ <_short>Manual Transformation</_short>
705+ <subgroup>
706+ <_short>Rotation</_short>
707+ <option type="float" name="rotate_increment_amount">
708+ <_short>Rotate Increment Amount</_short>
709+ <_long>How far to rotate a window when rotating by an 'increment'.</_long>
710+ <default>10.0</default>
711+ <min>1.0</min>
712+ <max>100.0</max>
713+ </option>
714+ </subgroup>
715+ <subgroup>
716+ <_short>Scaling</_short>
717+ <option type="float" name="scale_increment_amount">
718+ <_short>Scale Increment Amount</_short>
719+ <_long>How much to scale a window by when scaling by an 'increment'.</_long>
720+ <default>0.3</default>
721+ <min>0.01</min>
722+ <max>0.5</max>
723+ </option>
724+ </subgroup>
725+ </group>
726+ <group>
727+ <_short>Misc</_short>
728+ <subgroup>
729+ <_short>Input Prevention</_short>
730+ <option name="shape_window_types" type="match">
731+ <_short>Prevented Input Window Types</_short>
732+ <_long>Window types that should be shaped. Disable problematic windows here.</_long>
733+ <default>(Toolbar | Utility | Dialog | ModalDialog | Normal)</default>
734+ </option>
735+ <option type="bool" name="do_shape_input">
736+ <_short>Prevent Input</_short>
737+ <_long>Prevent input for transformed windows.</_long>
738+ <default>True</default>
739+ </option>
740+ <option type="bool" name="immediate_moves">
741+ <_short>Immediate Moves</_short>
742+ <_long>Don't allow plugins like wobbly to manipulate the transformed window while it's being moved.</_long>
743+ <default>True</default>
744+ </option>
745+ </subgroup>
746+ <subgroup>
747+ <_short>Helper Options</_short>
748+ <option type="color" name="circle_color" >
749+ <_short>Helper Circle Color</_short>
750+ <_long>Color and opacity of the circle.</_long>
751+ <default>
752+ <red>0x5400</red>
753+ <green>0xBE00</green>
754+ <blue>0xFB00</blue>
755+ <alpha>0x8000</alpha>
756+ </default>
757+ </option>
758+ <option type="color" name="line_color" >
759+ <_short>Helper Line Color</_short>
760+ <_long>Color and opacity of the helper line around the circle.</_long>
761+ <default>
762+ <red>0x1800</red>
763+ <green>0x0000</green>
764+ <blue>0xFF00</blue>
765+ <alpha>0xFFFF</alpha>
766+ </default>
767+ </option>
768+ <option type="color" name="cross_line_color" >
769+ <_short>Helper Cross Line Color</_short>
770+ <_long>Color and opacity of the cross lines.</_long>
771+ <default>
772+ <red>0x1800</red>
773+ <green>0x0000</green>
774+ <blue>0xFF00</blue>
775+ <alpha>0xFFFF</alpha>
776+ </default>
777+ </option>
778+ <option type="bool" name="show_circle">
779+ <_short>Show 3D Rotation Circle</_short>
780+ <_long>Show the click area for 3D rotation.</_long>
781+ <default>True</default>
782+ </option>
783+ <option type="bool" name="show_gizmo">
784+ <_short>Show Rotation Gizmo</_short>
785+ <_long>Show the rotation axis info.</_long>
786+ <default>True</default>
787+ </option>
788+ <option type="bool" name="show_cross">
789+ <_short>Show Crosshair</_short>
790+ <_long>Show the crosshair for scaling click regions.</_long>
791+ <default>True</default>
792+ </option>
793+ <option type="bool" name="show_region">
794+ <_short>Show Input Regions</_short>
795+ <_long>Show the input region rectangle.</_long>
796+ <default>True</default>
797+ </option>
798+ </subgroup>
799+ </group>
800+ </options>
801+ </plugin>
802+</compiz>
803
804=== added directory 'plugins/freewins/src'
805=== added file 'plugins/freewins/src/action.cpp'
806--- plugins/freewins/src/action.cpp 1970-01-01 00:00:00 +0000
807+++ plugins/freewins/src/action.cpp 2013-02-28 06:12:23 +0000
808@@ -0,0 +1,763 @@
809+/**
810+ * Compiz Fusion Freewins plugin
811+ *
812+ * action.cpp
813+ *
814+ * Copyright (C) 2007 Rodolfo Granata <warlock.cc@gmail.com>
815+ *
816+ * This program is free software; you can redistribute it and/or
817+ * modify it under the terms of the GNU General Public License
818+ * as published by the Free Software Foundation; either version 2
819+ * of the License, or (at your option) any later version.
820+ *
821+ * This program is distributed in the hope that it will be useful,
822+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
823+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
824+ * GNU General Public License for more details.
825+ *
826+ * Author(s):
827+ * Rodolfo Granata <warlock.cc@gmail.com>
828+ * Sam Spilsbury <smspillaz@gmail.com>
829+ *
830+ * Button binding support and Reset added by:
831+ * enigma_0Z <enigma.0ZA@gmail.com>
832+ *
833+ * Most of the input handling here is based on
834+ * the shelf plugin by
835+ * : Kristian Lyngstøl <kristian@bohemians.org>
836+ * : Danny Baumann <maniac@opencompositing.org>
837+ *
838+ * Description:
839+ *
840+ * This plugin allows you to freely transform the texture of a window,
841+ * whether that be rotation or scaling to make better use of screen space
842+ * or just as a toy.
843+ *
844+ * Todo:
845+ * - Fully implement an input redirection system by
846+ * finding an inverse matrix, multiplying by it,
847+ * translating to the actual window co-ords and
848+ * XSendEvent() the co-ords to the actual window.
849+ * - Code could be cleaner
850+ * - Add timestep and speed options to animation
851+ * - Add window hover-over info via paintOutput : i.e
852+ * - Resize borders
853+ * - 'Reset' Button
854+ * - 'Scale' Button
855+ * - 'Rotate' Button
856+ */
857+
858+/* TODO: Finish porting stuff to actions */
859+
860+#include "freewins.h"
861+
862+
863+/* ------ Actions -------------------------------------------------------*/
864+
865+/* Initiate Mouse Rotation */
866+bool
867+FWScreen::initiateFWRotate (CompAction *action,
868+ CompAction::State state,
869+ CompOption::Vector options)
870+{
871+ CompWindow* w;
872+ CompWindow *useW;
873+ Window xid;
874+
875+ xid = CompOption::getIntOptionNamed (options, "window", 0);
876+
877+ w = screen->findWindow (xid);
878+ useW = screen->findWindow (xid);
879+
880+ if (w)
881+ {
882+
883+ foreach (FWWindowInputInfo *info, mTransformedWindows)
884+ {
885+ if (info->ipw)
886+ if (w->id () == info->ipw)
887+ /* The window we just grabbed was actually
888+ * an IPW, get the real window instead
889+ */
890+ useW = getRealWindow (w);
891+ }
892+
893+ mRotateCursor = XCreateFontCursor (screen->dpy (), XC_fleur);
894+
895+ if (!screen->otherGrabExist ("freewins", 0))
896+ if (!mGrabIndex)
897+ {
898+ mGrabIndex = screen->pushGrab (0, "freewins");
899+ }
900+ }
901+
902+ if (useW)
903+ {
904+ if (true || optionGetShapeWindowTypes ().evaluate (useW))
905+ {
906+ FREEWINS_WINDOW (useW);
907+
908+ int x = CompOption::getIntOptionNamed (options, "x",
909+ useW->x () + (useW->width () / 2));
910+ int y = CompOption::getIntOptionNamed (options, "y",
911+ useW->y () + (useW->height () / 2));
912+
913+ int mods = CompOption::getIntOptionNamed (options, "modifiers", 0);
914+
915+ mGrabWindow = useW;
916+
917+ fww->mGrab = grabRotate;
918+
919+ /* Save current scales and angles */
920+
921+ fww->mAnimate.oldAngX = fww->mTransform.angX;
922+ fww->mAnimate.oldAngY = fww->mTransform.angY;
923+ fww->mAnimate.oldAngZ = fww->mTransform.angZ;
924+ fww->mAnimate.oldScaleX = fww->mTransform.scaleX;
925+ fww->mAnimate.oldScaleY = fww->mTransform.scaleY;
926+
927+ if (pointerY > fww->mIMidY)
928+ {
929+ if (pointerX > fww->mIMidX)
930+ fww->mCorner = CornerBottomRight;
931+ else if (pointerX < fww->mIMidX)
932+ fww->mCorner = CornerBottomLeft;
933+ }
934+ else if (pointerY < fww->mIMidY)
935+ {
936+ if (pointerX > fww->mIMidX)
937+ fww->mCorner = CornerTopRight;
938+ else if (pointerX < fww->mIMidX)
939+ fww->mCorner = CornerTopLeft;
940+ }
941+
942+ switch (optionGetZAxisRotation ())
943+ {
944+ case ZAxisRotationAlways3d:
945+ fww->mCan3D = TRUE;
946+ fww->mCan2D = FALSE;
947+ break;
948+
949+ case ZAxisRotationAlways2d:
950+ fww->mCan3D = FALSE;
951+ fww->mCan2D = TRUE;
952+ break;
953+
954+ case ZAxisRotationDetermineOnClick:
955+ case ZAxisRotationSwitch:
956+ fww->determineZAxisClick (pointerX, pointerY, FALSE);
957+ break;
958+
959+ case ZAxisRotationInterchangeable:
960+ fww->mCan3D = TRUE;
961+ fww->mCan2D = TRUE;
962+ break;
963+
964+ default:
965+ break;
966+ }
967+
968+ /* Set the rotation axis */
969+
970+ switch (optionGetRotationAxis ())
971+ {
972+ case RotationAxisAlwaysCentre:
973+ default:
974+ fww->calculateInputOrigin (WIN_REAL_X (mGrabWindow) +
975+ WIN_REAL_W (mGrabWindow) / 2.0f,
976+ WIN_REAL_Y (mGrabWindow) +
977+ WIN_REAL_H (mGrabWindow) / 2.0f);
978+ fww->calculateOutputOrigin (WIN_OUTPUT_X (mGrabWindow) +
979+ WIN_OUTPUT_W (mGrabWindow) / 2.0f,
980+ WIN_OUTPUT_Y (mGrabWindow) +
981+ WIN_OUTPUT_H (mGrabWindow) / 2.0f);
982+ break;
983+
984+ case RotationAxisClickPoint:
985+ fww->calculateInputOrigin (mClick_root_x, mClick_root_y);
986+ fww->calculateOutputOrigin (mClick_root_x, mClick_root_y);
987+ break;
988+
989+ case RotationAxisOppositeToClick:
990+ fww->calculateInputOrigin (useW->x () + useW->width () - mClick_root_x,
991+ useW->y () + useW->height () - mClick_root_y);
992+ fww->calculateOutputOrigin (useW->x () + useW->width () - mClick_root_x,
993+ useW->y () + useW->height () - mClick_root_y);
994+ break;
995+ }
996+
997+ /* Announce that we grabbed the window */
998+ useW->grabNotify (x, y, mods, CompWindowGrabMoveMask |
999+ CompWindowGrabButtonMask);
1000+
1001+ /* Shape the window beforehand and avoid a stale grab */
1002+ if (fww->canShape ())
1003+ if (fww->handleWindowInputInfo ())
1004+ fww->adjustIPW ();
1005+
1006+ cScreen->damageScreen ();
1007+
1008+ if (state & CompAction::StateInitButton)
1009+ action->setState (action->state () | CompAction::StateTermButton);
1010+
1011+ }
1012+ }
1013+ return true;
1014+}
1015+
1016+bool
1017+FWScreen::terminateFWRotate (CompAction *action,
1018+ CompAction::State state,
1019+ CompOption::Vector options)
1020+{
1021+ if (mGrabWindow && mGrabIndex)
1022+ {
1023+ FREEWINS_WINDOW (mGrabWindow);
1024+ if (fww->mGrab == grabRotate)
1025+ {
1026+ int distX, distY;
1027+
1028+ fww->window->ungrabNotify ();
1029+
1030+ switch (optionGetRotationAxis ())
1031+ {
1032+ case RotationAxisClickPoint:
1033+ case RotationAxisOppositeToClick:
1034+
1035+ distX = (fww->mOutputRect.x1 () +
1036+ (fww->mOutputRect.width ()) / 2.0f) -
1037+ (WIN_REAL_X (mGrabWindow) +
1038+ WIN_REAL_W (mGrabWindow) / 2.0f);
1039+ distY = (fww->mOutputRect.y1 () +
1040+ (fww->mOutputRect.height ()) / 2.0f) -
1041+ (WIN_REAL_Y (mGrabWindow) +
1042+ WIN_REAL_H (mGrabWindow) / 2.0f);
1043+
1044+ mGrabWindow->move (distX, distY, true);
1045+ mGrabWindow->syncPosition ();
1046+
1047+ fww->calculateInputOrigin (WIN_REAL_X (mGrabWindow) +
1048+ WIN_REAL_W (mGrabWindow) / 2.0f,
1049+ WIN_REAL_Y (mGrabWindow) +
1050+ WIN_REAL_H (mGrabWindow) / 2.0f);
1051+ fww->calculateOutputOrigin (WIN_OUTPUT_X (mGrabWindow) +
1052+ WIN_OUTPUT_W (mGrabWindow) / 2.0f,
1053+ WIN_OUTPUT_Y (mGrabWindow) +
1054+ WIN_OUTPUT_H (mGrabWindow) / 2.0f);
1055+
1056+ break;
1057+ default:
1058+ break;
1059+ }
1060+
1061+ if (fww->canShape ())
1062+ if (fww->handleWindowInputInfo ())
1063+ fww->adjustIPW ();
1064+
1065+ screen->removeGrab (mGrabIndex, 0);
1066+ mGrabIndex = 0;
1067+ mGrabWindow = NULL;
1068+ fww->mGrab = grabNone;
1069+ }
1070+ }
1071+
1072+ action->setState (action->state () & ~(CompAction::StateTermKey |
1073+ CompAction::StateTermButton));
1074+
1075+ return false;
1076+}
1077+
1078+/*static void FWMoveWindowToCorrectPosition (CompWindow *w, float distX, float distY)
1079+{
1080+
1081+ FREEWINS_WINDOW (w); action->setState (action->state () & ~(CompAction::StateTermKey |
1082+ CompAction::StateTermButton));
1083+
1084+ fprintf(stderr, "distX is %f distY is %f midX and midY are %f %f\n", distX, distY, fww->mIMidX, fww->mIMidY);
1085+
1086+ moveWindow (w, distX * (1 + (1 - fww->mTransform.scaleX)), distY * (1 + (1 - fww->mTransform.scaleY)), TRUE, FALSE);
1087+
1088+ syncWindowPosition (w);
1089+}*/
1090+
1091+/* Initiate Scaling */
1092+bool
1093+FWScreen::initiateFWScale (CompAction *action,
1094+ CompAction::State state,
1095+ CompOption::Vector options)
1096+{
1097+ CompWindow* w;
1098+ CompWindow *useW;
1099+ Window xid;
1100+
1101+ xid = CompOption::getIntOptionNamed (options, "window", 0);
1102+ w = screen->findWindow (xid);
1103+ useW = screen->findWindow (xid);
1104+
1105+ if (w)
1106+ {
1107+ foreach (FWWindowInputInfo *info, mTransformedWindows)
1108+ {
1109+ if (info->ipw)
1110+ if (w->id () == info->ipw)
1111+ /* The window we just grabbed was actually
1112+ * an IPW, get the real window instead
1113+ */
1114+ useW = getRealWindow (w);
1115+ }
1116+
1117+ mRotateCursor = XCreateFontCursor (screen->dpy (), XC_fleur);
1118+
1119+ if (!screen->otherGrabExist ("freewins", 0))
1120+ if (!mGrabIndex)
1121+ mGrabIndex = screen->pushGrab (mRotateCursor, "freewins");
1122+ }
1123+
1124+ if (useW)
1125+ {
1126+ if (optionGetShapeWindowTypes ().evaluate (useW))
1127+ {
1128+ FREEWINS_WINDOW (useW);
1129+
1130+ int x = CompOption::getIntOptionNamed (options, "x",
1131+ useW->x () + (useW->width () / 2));
1132+ int y = CompOption::getIntOptionNamed (options, "y",
1133+ useW->y () + (useW->height () / 2));
1134+
1135+ int mods = CompOption::getIntOptionNamed (options, "modifiers", 0);
1136+
1137+ mGrabWindow = useW;
1138+
1139+ /* Find out the corner we clicked in */
1140+
1141+ float MidX = fww->mInputRect.centerX ();
1142+ float MidY = fww->mInputRect.centerY ();
1143+
1144+ /* Check for Y axis clicking (Top / Bottom) */
1145+ if (pointerY > MidY)
1146+ {
1147+ /* Check for X axis clicking (Left / Right) */
1148+ if (pointerX > MidX)
1149+ fww->mCorner = CornerBottomRight;
1150+ else if (pointerX < MidX)
1151+ fww->mCorner = CornerBottomLeft;
1152+ }
1153+ else if (pointerY < MidY)
1154+ {
1155+ /* Check for X axis clicking (Left / Right) */
1156+ if (pointerX > MidX)
1157+ fww->mCorner = CornerTopRight;
1158+ else if (pointerX < MidX)
1159+ fww->mCorner = CornerTopLeft;
1160+ }
1161+
1162+ switch (optionGetScaleMode ())
1163+ {
1164+ case ScaleModeToCentre:
1165+ fww->calculateInputOrigin(WIN_REAL_X (useW) + WIN_REAL_W (useW) / 2.0f,
1166+ WIN_REAL_Y (useW) + WIN_REAL_H (useW) / 2.0f);
1167+ fww->calculateOutputOrigin(WIN_OUTPUT_X (useW) + WIN_OUTPUT_W (useW) / 2.0f,
1168+ WIN_OUTPUT_Y (useW) + WIN_OUTPUT_H (useW) / 2.0f);
1169+ break;
1170+ /*
1171+ *Experimental scale to corners mode
1172+ */
1173+ case ScaleModeToOppositeCorner:
1174+ switch (fww->mCorner)
1175+ {
1176+ case CornerBottomRight:
1177+ /* Translate origin to the top left of the window */
1178+ //FWMoveWindowToCorrectPosition (w, fww->inputRect.x1 - WIN_REAL_X (useW), fww->inputRect.y1 - WIN_REAL_Y (useW));
1179+ fww->calculateInputOrigin (WIN_REAL_X (useW), WIN_REAL_Y (useW));
1180+ break;
1181+
1182+ case CornerBottomLeft:
1183+ /* Translate origin to the top right of the window */
1184+ //FWMoveWindowToCorrectPosition (w, fww->inputRect.x2 - (WIN_REAL_X (useW) + WIN_REAL_W (useW)), fww->inputRect.y1 - WIN_REAL_Y (useW));
1185+ fww->calculateInputOrigin (WIN_REAL_X (useW) + (WIN_REAL_W (useW)), WIN_REAL_Y (useW));
1186+ break;
1187+
1188+ case CornerTopRight:
1189+ /* Translate origin to the bottom left of the window */
1190+ //FWMoveWindowToCorrectPosition (w, fww->inputRect.x1 - WIN_REAL_X (useW) , fww->inputRect.y1 - (WIN_REAL_Y (useW) + WIN_REAL_H (useW)));
1191+ fww->calculateInputOrigin (WIN_REAL_X (useW), WIN_REAL_Y (useW) + (WIN_REAL_H (useW)));
1192+ break;
1193+
1194+ case CornerTopLeft:
1195+ /* Translate origin to the bottom right of the window */
1196+ //FWMoveWindowToCorrectPosition (w, fww->inputRect.x1 -(WIN_REAL_X (useW) + WIN_REAL_W (useW)) , fww->inputRect.y1 - (WIN_REAL_Y (useW) + WIN_REAL_H (useW)));
1197+ fww->calculateInputOrigin (WIN_REAL_X (useW) + (WIN_REAL_W (useW)), WIN_REAL_Y (useW) + (WIN_REAL_H (useW)));
1198+ break;
1199+ }
1200+ break;
1201+ }
1202+
1203+ fww->mGrab = grabScale;
1204+
1205+ /* Announce that we grabbed the window */
1206+ useW->grabNotify (x, y, mods, CompWindowGrabMoveMask |
1207+ CompWindowGrabButtonMask);
1208+
1209+ cScreen->damageScreen ();
1210+
1211+ /* Shape the window beforehand and avoid a stale grab */
1212+ if (fww->canShape ())
1213+ if (fww->handleWindowInputInfo ())
1214+ fww->adjustIPW ();
1215+
1216+
1217+ if (state & CompAction::StateInitButton)
1218+ action->setState (action->state () | CompAction::StateTermButton);
1219+ }
1220+ }
1221+
1222+ return TRUE;
1223+}
1224+
1225+bool
1226+FWScreen::terminateFWScale (CompAction *action,
1227+ CompAction::State state,
1228+ CompOption::Vector options)
1229+{
1230+ if (mGrabWindow && mGrabIndex)
1231+ {
1232+ FREEWINS_WINDOW (mGrabWindow);
1233+ if (fww->mGrab == grabScale)
1234+ {
1235+ fww->window->ungrabNotify ();
1236+
1237+ switch (optionGetScaleMode ())
1238+ {
1239+ int distX, distY;
1240+
1241+ case ScaleModeToOppositeCorner:
1242+ distX = (fww->mOutputRect.x1 () + (fww->mOutputRect.width () / 2.0f) - (WIN_REAL_X (mGrabWindow) + WIN_REAL_W (mGrabWindow) / 2.0f));
1243+ distY = (fww->mOutputRect.y1 () + (fww->mOutputRect.width () / 2.0f) - (WIN_REAL_Y (mGrabWindow) + WIN_REAL_H (mGrabWindow) / 2.0f));
1244+
1245+ mGrabWindow->move (distX, distY, true);
1246+ mGrabWindow->syncPosition ();
1247+
1248+ fww->calculateInputOrigin (WIN_REAL_X (mGrabWindow) +
1249+ WIN_REAL_W (mGrabWindow) / 2.0f,
1250+ WIN_REAL_Y (mGrabWindow) +
1251+ WIN_REAL_H (mGrabWindow) / 2.0f);
1252+ fww->calculateOutputOrigin (WIN_OUTPUT_X (mGrabWindow) +
1253+ WIN_OUTPUT_W (mGrabWindow) / 2.0f,
1254+ WIN_OUTPUT_Y (mGrabWindow) +
1255+ WIN_OUTPUT_H (mGrabWindow) / 2.0f);
1256+
1257+ break;
1258+
1259+ default:
1260+ break;
1261+
1262+ }
1263+
1264+ screen->removeGrab (mGrabIndex, 0);
1265+ mGrabIndex = 0;
1266+ mGrabWindow = NULL;
1267+ fww->mGrab = grabNone;
1268+ }
1269+ }
1270+
1271+ action->setState (action->state () & ~(CompAction::StateTermKey |
1272+ CompAction::StateTermButton));
1273+
1274+ return FALSE;
1275+}
1276+
1277+/* Repetitive Stuff */
1278+
1279+void
1280+FWWindow::setPrepareRotation (float dx,
1281+ float dy,
1282+ float dz,
1283+ float dsu,
1284+ float dsd)
1285+{
1286+ if (FWScreen::get (screen)->optionGetShapeWindowTypes ().evaluate (window))
1287+ {
1288+ calculateInputOrigin (WIN_REAL_X (window) +
1289+ WIN_REAL_W (window) / 2.0f,
1290+ WIN_REAL_Y (window) +
1291+ WIN_REAL_H (window) / 2.0f);
1292+ calculateOutputOrigin (WIN_OUTPUT_X (window) +
1293+ WIN_OUTPUT_W (window) / 2.0f,
1294+ WIN_OUTPUT_Y (window) +
1295+ WIN_OUTPUT_H (window) / 2.0f);
1296+
1297+ mTransform.unsnapAngX += dy;
1298+ mTransform.unsnapAngY -= dx;
1299+ mTransform.unsnapAngZ += dz;
1300+
1301+ mTransform.unsnapScaleX += dsu;
1302+ mTransform.unsnapScaleY += dsd;
1303+
1304+ mAnimate.oldAngX = mTransform.angX;
1305+ mAnimate.oldAngY = mTransform.angY;
1306+ mAnimate.oldAngZ = mTransform.angZ;
1307+
1308+ mAnimate.oldScaleX = mTransform.scaleX;
1309+ mAnimate.oldScaleY = mTransform.scaleY;
1310+
1311+ mAnimate.destAngX = mTransform.angX + dy;
1312+ mAnimate.destAngY = mTransform.angY - dx;
1313+ mAnimate.destAngZ = mTransform.angZ + dz;
1314+
1315+ mAnimate.destScaleX = mTransform.scaleX + dsu;
1316+ mAnimate.destScaleY = mTransform.scaleY + dsd;
1317+
1318+ }
1319+}
1320+
1321+#define ROTATE_INC freewinsGetRotateIncrementAmount (w->screen)
1322+#define NEG_ROTATE_INC freewinsGetRotateIncrementAmount (w->screen) *-1
1323+
1324+#define SCALE_INC freewinsGetScaleIncrementAmount (w->screen)
1325+#define NEG_SCALE_INC freewinsGetScaleIncrementAmount (w->screen) *-1
1326+
1327+bool
1328+FWScreen::rotate (CompAction *action,
1329+ CompAction::State state,
1330+ CompOption::Vector options, int dx, int dy, int dz)
1331+{
1332+ CompWindow *w = screen->findWindow (CompOption::getIntOptionNamed (options,
1333+ "window",
1334+ 0));
1335+ foreach (FWWindowInputInfo *info, mTransformedWindows)
1336+ {
1337+ if (info->ipw == w->id ())
1338+ {
1339+ w = getRealWindow (w);
1340+ }
1341+ }
1342+
1343+ FREEWINS_WINDOW (w);
1344+
1345+ fww->setPrepareRotation (dx, dy, dz, 0, 0);
1346+
1347+ if (fww->canShape ())
1348+ if (fww->handleWindowInputInfo ())
1349+ fww->adjustIPW ();
1350+
1351+ return true;
1352+}
1353+
1354+bool
1355+FWScreen::scale (CompAction *action,
1356+ CompAction::State state,
1357+ CompOption::Vector options,
1358+ int scale)
1359+{
1360+ CompWindow *w = screen->findWindow (CompOption::getIntOptionNamed (options,
1361+ "window",
1362+ 0));
1363+ foreach (FWWindowInputInfo *info, mTransformedWindows)
1364+ {
1365+ if (info->ipw == w->id ())
1366+ {
1367+ w = getRealWindow (w);
1368+ }
1369+ }
1370+
1371+ FREEWINS_WINDOW (w);
1372+
1373+ fww->setPrepareRotation (0, 0, 0, scale, scale);
1374+ fww->cWindow->addDamage ();
1375+
1376+ if (fww->canShape ())
1377+ if (fww->handleWindowInputInfo ())
1378+ fww->adjustIPW ();
1379+
1380+ if (!optionGetAllowNegative ())
1381+ {
1382+ float minScale = optionGetMinScale ();
1383+
1384+ if (fww->mAnimate.destScaleX < minScale)
1385+ fww->mAnimate.destScaleX = minScale;
1386+
1387+ if (fww->mAnimate.destScaleY < minScale)
1388+ fww->mAnimate.destScaleY = minScale;
1389+ }
1390+
1391+ return true;
1392+}
1393+
1394+/* Reset the Rotation and Scale to 0 and 1 */
1395+bool
1396+FWScreen::resetFWTransform (CompAction *action,
1397+ CompAction::State state,
1398+ CompOption::Vector options)
1399+{
1400+ CompWindow *w = screen->findWindow (CompOption::getIntOptionNamed (options,
1401+ "window",
1402+ 0));
1403+ foreach (FWWindowInputInfo *info, mTransformedWindows)
1404+ {
1405+ if (info->ipw == w->id ())
1406+ {
1407+ w = getRealWindow (w);
1408+ }
1409+ }
1410+
1411+ if (w)
1412+ {
1413+ FREEWINS_WINDOW (w);
1414+ fww->setPrepareRotation (fww->mTransform.angY,
1415+ -fww->mTransform.angX,
1416+ -fww->mTransform.angZ,
1417+ (1 - fww->mTransform.scaleX),
1418+ (1 - fww->mTransform.scaleY));
1419+ fww->cWindow->addDamage ();
1420+
1421+ fww->mTransformed = FALSE;
1422+
1423+ if (fww->canShape ())
1424+ if (fww->handleWindowInputInfo ())
1425+ fww->adjustIPW ();
1426+
1427+ fww->mResetting = TRUE;
1428+ }
1429+
1430+ return TRUE;
1431+}
1432+
1433+/* Callable action to rotate a window to the angle provided
1434+ * x: Set angle to x degrees
1435+ * y: Set angle to y degrees
1436+ * z: Set angle to z degrees
1437+ * window: The window to apply the transformation to
1438+ */
1439+bool
1440+FWScreen::rotateAction (CompAction *action,
1441+ CompAction::State state,
1442+ CompOption::Vector options)
1443+{
1444+ CompWindow *w;
1445+
1446+ w = screen->findWindow (CompOption::getIntOptionNamed (options, "window", 0));
1447+
1448+ if (w)
1449+ {
1450+ FREEWINS_WINDOW (w);
1451+
1452+ float x = CompOption::getFloatOptionNamed(options, "x", 0.0f);
1453+ float y = CompOption::getFloatOptionNamed(options, "y", 0.0f);
1454+ float z = CompOption::getFloatOptionNamed(options, "z", 0.0f);
1455+
1456+ fww->setPrepareRotation (x - fww->mAnimate.destAngX,
1457+ y - fww->mAnimate.destAngY,
1458+ z - fww->mAnimate.destAngZ, 0, 0);
1459+ fww->cWindow->addDamage ();
1460+
1461+ }
1462+ else
1463+ {
1464+ return false;
1465+ }
1466+
1467+ return true;
1468+}
1469+
1470+/* Callable action to increment window rotation by the angles provided
1471+ * x: Increment angle by x degrees
1472+ * y: Increment angle by y degrees
1473+ * z: Increment angle by z degrees
1474+ * window: The window to apply the transformation to
1475+ */
1476+bool
1477+FWScreen::incrementRotateAction (CompAction *action,
1478+ CompAction::State state,
1479+ CompOption::Vector options)
1480+{
1481+ CompWindow *w;
1482+
1483+ w = screen->findWindow (CompOption::getIntOptionNamed (options, "window", 0));
1484+
1485+ if (w)
1486+ {
1487+ FREEWINS_WINDOW (w);
1488+
1489+ float x = CompOption::getFloatOptionNamed(options, "x", 0.0f);
1490+ float y = CompOption::getFloatOptionNamed(options, "y", 0.0f);
1491+ float z = CompOption::getFloatOptionNamed(options, "z", 0.0f);
1492+
1493+ fww->setPrepareRotation (x,
1494+ y,
1495+ z, 0, 0);
1496+ fww->cWindow->addDamage ();
1497+
1498+ }
1499+ else
1500+ {
1501+ return false;
1502+ }
1503+
1504+ return true;
1505+}
1506+
1507+/* Callable action to scale a window to the scale provided
1508+ * x: Set scale to x factor
1509+ * y: Set scale to y factor
1510+ * window: The window to apply the transformation to
1511+ */
1512+bool
1513+FWScreen::scaleAction (CompAction *action,
1514+ CompAction::State state,
1515+ CompOption::Vector options)
1516+{
1517+ CompWindow *w;
1518+
1519+ w = screen->findWindow (CompOption::getIntOptionNamed (options, "window", 0));
1520+
1521+ if (w)
1522+ {
1523+ FREEWINS_WINDOW (w);
1524+
1525+ float x = CompOption::getFloatOptionNamed (options, "x", 0.0f);
1526+ float y = CompOption::getFloatOptionNamed (options, "y", 0.0f);
1527+
1528+ fww->setPrepareRotation (0, 0, 0,
1529+ x - fww->mAnimate.destScaleX,
1530+ y - fww->mAnimate.destScaleY);
1531+ if (fww->canShape ())
1532+ if (fww->handleWindowInputInfo ())
1533+ fww->adjustIPW ();
1534+
1535+ /* Stop scale at threshold specified */
1536+ if (!optionGetAllowNegative ())
1537+ {
1538+ float minScale = optionGetMinScale ();
1539+ if (fww->mAnimate.destScaleX < minScale)
1540+ fww->mAnimate.destScaleX = minScale;
1541+
1542+ if (fww->mAnimate.destScaleY < minScale)
1543+ fww->mAnimate.destScaleY = minScale;
1544+ }
1545+
1546+ fww->cWindow->addDamage ();
1547+
1548+ if (fww->canShape ())
1549+ fww->handleWindowInputInfo ();
1550+
1551+ }
1552+ else
1553+ {
1554+ return false;
1555+ }
1556+
1557+ return true;
1558+}
1559+
1560+/* Toggle Axis-Help Display */
1561+bool
1562+FWScreen::toggleFWAxis (CompAction *action,
1563+ CompAction::State state,
1564+ CompOption::Vector options)
1565+{
1566+ mAxisHelp = !mAxisHelp;
1567+
1568+ cScreen->damageScreen ();
1569+
1570+ return TRUE;
1571+}
1572
1573=== added file 'plugins/freewins/src/events.cpp'
1574--- plugins/freewins/src/events.cpp 1970-01-01 00:00:00 +0000
1575+++ plugins/freewins/src/events.cpp 2013-02-28 06:12:23 +0000
1576@@ -0,0 +1,854 @@
1577+/**
1578+ * Compiz Fusion Freewins plugin
1579+ *
1580+ * events.cpp
1581+ *
1582+ * Copyright (C) 2007 Rodolfo Granata <warlock.cc@gmail.com>
1583+ *
1584+ * This program is free software; you can redistribute it and/or
1585+ * modify it under the terms of the GNU General Public License
1586+ * as published by the Free Software Foundation; either version 2
1587+ * of the License, or (at your option) any later version.
1588+ *
1589+ * This program is distributed in the hope that it will be useful,
1590+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1591+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1592+ * GNU General Public License for more details.
1593+ *
1594+ * Author(s):
1595+ * Rodolfo Granata <warlock.cc@gmail.com>
1596+ * Sam Spilsbury <smspillaz@gmail.com>
1597+ *
1598+ * Button binding support and Reset added by:
1599+ * enigma_0Z <enigma.0ZA@gmail.com>
1600+ *
1601+ * Most of the input handling here is based on
1602+ * the shelf plugin by
1603+ * : Kristian Lyngstøl <kristian@bohemians.org>
1604+ * : Danny Baumann <maniac@opencompositing.org>
1605+ *
1606+ * Description:
1607+ *
1608+ * This plugin allows you to freely transform the texture of a window,
1609+ * whether that be rotation or scaling to make better use of screen space
1610+ * or just as a toy.
1611+ *
1612+ * Todo:
1613+ * - Fully implement an input redirection system by
1614+ * finding an inverse matrix, multiplying by it,
1615+ * translating to the actual window co-ords and
1616+ * XSendEvent() the co-ords to the actual window.
1617+ * - X Input Redirection
1618+ * - Code could be cleaner
1619+ * - Add timestep and speed options to animation
1620+ * - Add window hover-over info via paintOutput : i.e
1621+ * - Resize borders
1622+ * - 'Reset' Button
1623+ * - 'Scale' Button
1624+ * - 'Rotate' Button
1625+ */
1626+
1627+#include "freewins.h"
1628+
1629+
1630+/* ------ Event Handlers ------------------------------------------------*/
1631+
1632+void
1633+FWWindow::handleIPWResizeInitiate ()
1634+{
1635+ FREEWINS_SCREEN (screen);
1636+
1637+ window->activate ();
1638+ mGrab = grabResize;
1639+ fws->mRotateCursor = XCreateFontCursor (screen->dpy (), XC_plus);
1640+ if(!screen->otherGrabExist ("freewins", "resize", 0))
1641+ if(!fws->mGrabIndex)
1642+ {
1643+ unsigned int mods = 0;
1644+ mods &= CompNoMask;
1645+ fws->mGrabIndex = screen->pushGrab (fws->mRotateCursor, "resize");
1646+ window->grabNotify (window->x () + (window->width () / 2),
1647+ window->y () + (window->height () / 2), mods,
1648+ CompWindowGrabMoveMask | CompWindowGrabButtonMask);
1649+ fws->mGrabWindow = window;
1650+ }
1651+}
1652+
1653+void
1654+FWWindow::handleIPWMoveInitiate ()
1655+{
1656+ FREEWINS_SCREEN (screen);
1657+
1658+ window->activate ();
1659+ mGrab = grabMove;
1660+ fws->mRotateCursor = XCreateFontCursor (screen->dpy (), XC_fleur);
1661+ if(!screen->otherGrabExist ("freewins", "resize", 0))
1662+ if(!fws->mGrabIndex)
1663+ {
1664+ unsigned int mods = 0;
1665+ mods &= CompNoMask;
1666+ fws->mGrabIndex = screen->pushGrab (fws->mRotateCursor, "resize");
1667+ window->grabNotify (window->x () + (window->width () / 2),
1668+ window->y () + (window->height () / 2), mods,
1669+ CompWindowGrabResizeMask | CompWindowGrabButtonMask);
1670+ fws->mGrabWindow = window;
1671+ }
1672+}
1673+
1674+void
1675+FWWindow::handleIPWMoveMotionEvent (unsigned int x,
1676+ unsigned int y)
1677+{
1678+ FREEWINS_SCREEN (screen);
1679+
1680+ int dx = x - lastPointerX;
1681+ int dy = y - lastPointerY;
1682+
1683+ if (!fws->mGrabIndex)
1684+ return;
1685+
1686+ window->move (dx, dy, fws->optionGetImmediateMoves ());
1687+ window->syncPosition ();
1688+
1689+}
1690+
1691+void
1692+FWWindow::handleIPWResizeMotionEvent (unsigned int x,
1693+ unsigned int y)
1694+{
1695+ int dx = (x - lastPointerX) * 10;
1696+ int dy = (y - lastPointerY) * 10;
1697+
1698+ mWinH += dy;
1699+ mWinW += dx;
1700+
1701+ /* In order to prevent a window redraw on resize
1702+ * on every motion event we have a threshold
1703+ */
1704+
1705+ /* FIXME: cf-love: Instead of actually resizing the window, scale it up, then resize it */
1706+
1707+ if (mWinH - 10 > window->height () || mWinW - 10 > window->width ())
1708+ {
1709+ XWindowChanges xwc;
1710+ unsigned int mask = CWX | CWY | CWWidth | CWHeight;
1711+
1712+ xwc.x = window->serverX ();
1713+ xwc.y = window->serverY ();
1714+ xwc.width = mWinW;
1715+ xwc.height = mWinH;
1716+
1717+ if (xwc.width == window->serverWidth ())
1718+ mask &= ~CWWidth;
1719+
1720+ if (xwc.height == window->serverHeight ())
1721+ mask &= ~CWHeight;
1722+
1723+ if (window->mapNum () && (mask & (CWWidth | CWHeight)))
1724+ window->sendSyncRequest ();
1725+
1726+ window->configureXWindow (mask, &xwc);
1727+ }
1728+}
1729+
1730+/* Handle Rotation */
1731+void
1732+FWWindow::handleRotateMotionEvent (float dx,
1733+ float dy,
1734+ int x,
1735+ int y)
1736+{
1737+ FREEWINS_SCREEN (screen);
1738+
1739+ x -= 100;
1740+ y -= 100;
1741+
1742+ int oldX = lastPointerX - 100;
1743+ int oldY = lastPointerY - 100;
1744+
1745+ float midX = WIN_REAL_X (window) + WIN_REAL_W (window)/2.0;
1746+ float midY = WIN_REAL_Y (window) + WIN_REAL_H (window)/2.0;
1747+
1748+ float angX;
1749+ float angY;
1750+ float angZ;
1751+
1752+ /* Save the current angles so we can work with them */
1753+ if (fws->optionGetSnap () || fws->mSnap)
1754+ {
1755+ angX = mTransform.unsnapAngX;
1756+ angY = mTransform.unsnapAngY;
1757+ angZ = mTransform.unsnapAngZ;
1758+ }
1759+ else
1760+ {
1761+ angX = mAnimate.destAngX;
1762+ angY = mAnimate.destAngY;
1763+ angZ = mAnimate.destAngZ;
1764+ }
1765+
1766+ /* Check for Y axis clicking (Top / Bottom) */
1767+ if (pointerY > midY)
1768+ {
1769+ /* Check for X axis clicking (Left / Right) */
1770+ if (pointerX > midX)
1771+ mCorner = CornerBottomRight;
1772+ else if (pointerX < midX)
1773+ mCorner = CornerBottomLeft;
1774+ }
1775+ else if (pointerY < midY)
1776+ {
1777+ /* Check for X axis clicking (Left / Right) */
1778+ if (pointerX > midX)
1779+ mCorner = CornerTopRight;
1780+ else if (pointerX < midX)
1781+ mCorner = CornerTopLeft;
1782+ }
1783+
1784+ float percentFromXAxis = 0.0, percentFromYAxis = 0.0;
1785+
1786+ if (fws->optionGetZAxisRotation () == FreewinsOptions::ZAxisRotationInterchangeable)
1787+ {
1788+
1789+ /* Trackball rotation was too hard to implement. If anyone can implement it,
1790+ * please come forward so I can replace this hacky solution to the problem.
1791+ * Anyways, what happens here, is that we determine how far away we are from
1792+ * each axis (y and x). The further we are away from the y axis, the more
1793+ * up / down movements become Z axis movements and the further we are away from
1794+ * the x-axis, the more left / right movements become z rotations. */
1795+
1796+ /* We determine this by taking a percentage of how far away the cursor is from
1797+ * each axis. We divide the 3D rotation by this percentage ( and divide by the
1798+ * percentage squared in order to ensure that rotation is not too violent when we
1799+ * are quite close to the origin. We multiply the 2D rotation by this percentage also
1800+ * so we are essentially rotating in 3D and 2D all the time, but this is only really
1801+ * noticeable when you move the cursor over to the extremes of a window. In every case
1802+ * percentage can be defined as decimal-percentage (i.e 0.036 == 3.6%). Like I mentioned
1803+ * earlier, if you can replace this with trackball rotation, please come forward! */
1804+
1805+ float halfWidth = WIN_REAL_W (window) / 2.0f;
1806+ float halfHeight = WIN_REAL_H (window) / 2.0f;
1807+
1808+ float distFromXAxis = fabs (mIMidX - pointerX);
1809+ float distFromYAxis = fabs (mIMidY - pointerY);
1810+
1811+ percentFromXAxis = distFromXAxis / halfWidth;
1812+ percentFromYAxis = distFromYAxis / halfHeight;
1813+
1814+ }
1815+ else if (fws->optionGetZAxisRotation () == FreewinsOptions::ZAxisRotationSwitch)
1816+ determineZAxisClick (pointerX, pointerY, TRUE);
1817+
1818+ dx *= 360;
1819+ dy *= 360;
1820+
1821+ /* Handle inversion */
1822+
1823+ bool can2D = mCan2D, can3D = mCan3D;
1824+
1825+ if (fws->mInvert && fws->optionGetZAxisRotation () != FreewinsOptions::ZAxisRotationInterchangeable)
1826+ {
1827+ can2D = !mCan2D;
1828+ can3D = !mCan3D;
1829+ }
1830+
1831+ if(can2D)
1832+ {
1833+
1834+ float zX = 1.0f;
1835+ float zY = 1.0f;
1836+
1837+ if (fws->optionGetZAxisRotation () == FreewinsOptions::ZAxisRotationInterchangeable)
1838+ {
1839+ zX = percentFromXAxis;
1840+ zY = percentFromYAxis;
1841+ }
1842+
1843+ zX = zX > 1.0f ? 1.0f : zX;
1844+ zY = zY > 1.0f ? 1.0f : zY;
1845+
1846+ switch (mCorner)
1847+ {
1848+ case CornerTopRight:
1849+
1850+ if (x < oldX)
1851+ angZ -= dx * zX;
1852+ else if (x > oldX)
1853+ angZ += dx * zX;
1854+
1855+ if (y < oldY)
1856+ angZ -= dy * zY;
1857+ else if (y > oldY)
1858+ angZ += dy * zY;
1859+
1860+ break;
1861+
1862+ case CornerTopLeft:
1863+
1864+ if (x < oldX)
1865+ angZ -= dx * zX;
1866+ else if (x > oldX)
1867+ angZ += dx * zX;
1868+
1869+ if (y < oldY)
1870+ angZ += dy * zY;
1871+ else if (y > oldY)
1872+ angZ -= dy * zY;
1873+
1874+ break;
1875+
1876+ case CornerBottomLeft:
1877+
1878+ if (x < oldX)
1879+ angZ += dx * zX;
1880+ else if (x > oldX)
1881+ angZ -= dx * zX;
1882+
1883+ if (y < oldY)
1884+ angZ += dy * zY;
1885+ else if (y > oldY)
1886+ angZ -= dy * zY;
1887+
1888+ break;
1889+
1890+ case CornerBottomRight:
1891+
1892+ if (x < oldX)
1893+ angZ += dx * zX;
1894+ else if (x > oldX)
1895+ angZ -= dx * zX;
1896+
1897+ if (y < oldY)
1898+ angZ -= dy * zY;
1899+ else if (y > oldY)
1900+ angZ += dy * zY;
1901+
1902+ break;
1903+ }
1904+ }
1905+
1906+ if (can3D)
1907+ {
1908+ if (fws->optionGetZAxisRotation () != FreewinsOptions::ZAxisRotationInterchangeable)
1909+ {
1910+ percentFromXAxis = 0.0f;
1911+ percentFromYAxis = 0.0f;
1912+ }
1913+
1914+ angX -= dy * (1 - percentFromXAxis);
1915+ angY += dx * (1 - percentFromYAxis);
1916+ }
1917+
1918+ /* Restore angles */
1919+
1920+ if (fws->optionGetSnap () || fws->mSnap)
1921+ {
1922+ mTransform.unsnapAngX = angX;
1923+ mTransform.unsnapAngY = angY;
1924+ mTransform.unsnapAngZ = angZ;
1925+ }
1926+ else
1927+ {
1928+ mAnimate.destAngX = angX;
1929+ mAnimate.destAngY = angY;
1930+ mAnimate.destAngZ = angZ;
1931+ }
1932+
1933+ handleSnap ();
1934+}
1935+
1936+/* Handle Scaling */
1937+void
1938+FWWindow::handleScaleMotionEvent (float dx,
1939+ float dy,
1940+ int x,
1941+ int y)
1942+{
1943+ FREEWINS_SCREEN (screen);
1944+
1945+ x -= 100.0;
1946+ y -= 100.0;
1947+
1948+ int oldX = lastPointerX - 100;
1949+ int oldY = lastPointerY - 100;
1950+
1951+ float scaleX, scaleY;
1952+
1953+ if (fws->optionGetSnap () || fws->mSnap)
1954+ {
1955+ scaleX = mTransform.unsnapScaleX;
1956+ scaleY = mTransform.unsnapScaleY;
1957+ }
1958+ else
1959+ {
1960+ scaleX = mAnimate.destScaleX;
1961+ scaleY = mAnimate.destScaleY;
1962+ }
1963+
1964+ calculateInputRect ();
1965+
1966+ switch (mCorner)
1967+ {
1968+ case CornerTopLeft:
1969+
1970+ // Check X Direction
1971+ if (x < oldX)
1972+ scaleX -= dx;
1973+ else if (x > oldX)
1974+ scaleX -= dx;
1975+
1976+ // Check Y Direction
1977+ if (y < oldY)
1978+ scaleY -= dy;
1979+ else if (y > oldY)
1980+ scaleY -= dy;
1981+
1982+ break;
1983+
1984+ case CornerTopRight:
1985+
1986+ // Check X Direction
1987+ if (x < oldX)
1988+ scaleX += dx;
1989+ else if (x > oldX)
1990+ scaleX += dx;
1991+
1992+ // Check Y Direction
1993+ if (y < oldY)
1994+ scaleY -= dy;
1995+ else if (y > oldY)
1996+ scaleY -= dy;
1997+
1998+ break;
1999+
2000+ case CornerBottomLeft:
2001+
2002+ // Check X Direction
2003+ if (x < oldX)
2004+ scaleX -= dx;
2005+ else if (y > oldX)
2006+ scaleX -= dx;
2007+
2008+ // Check Y Direction
2009+ if (y < oldY)
2010+ scaleY += dy;
2011+ else if (y > oldY)
2012+ scaleY += dy;
2013+
2014+ break;
2015+
2016+ case CornerBottomRight:
2017+
2018+ // Check X Direction
2019+ if (x < oldX)
2020+ scaleX += dx;
2021+ else if (x > oldX)
2022+ scaleX += dx;
2023+
2024+ // Check Y Direction
2025+ if (y < oldY)
2026+ scaleY += dy;
2027+ else if (y > oldY)
2028+ scaleY += dy;
2029+
2030+ break;
2031+ }
2032+
2033+ if (fws->optionGetSnap () || fws->mSnap)
2034+ {
2035+ mTransform.unsnapScaleX = scaleX;
2036+ mTransform.unsnapScaleY = scaleY;
2037+ }
2038+ else
2039+ {
2040+ mAnimate.destScaleX = scaleX;
2041+ mAnimate.destScaleY = scaleY;
2042+ }
2043+
2044+ /* Stop scale at threshold specified */
2045+ if (!fws->optionGetAllowNegative ())
2046+ {
2047+ float minScale = fws->optionGetMinScale ();
2048+ if (mAnimate.destScaleX < minScale)
2049+ mAnimate.destScaleX = minScale;
2050+
2051+ if (mAnimate.destScaleY < minScale)
2052+ mAnimate.destScaleY = minScale;
2053+ }
2054+
2055+ /* Change scales for maintaining aspect ratio */
2056+ if (fws->optionGetScaleUniform ())
2057+ {
2058+ float tempscaleX = mAnimate.destScaleX;
2059+ float tempscaleY = mAnimate.destScaleY;
2060+ mAnimate.destScaleX = (tempscaleX + tempscaleY) / 2;
2061+ mAnimate.destScaleY = (tempscaleX + tempscaleY) / 2;
2062+ mTransform.unsnapScaleX = (tempscaleX + tempscaleY) / 2;
2063+ mTransform.unsnapScaleY = (tempscaleX + tempscaleY) / 2;
2064+ }
2065+
2066+ handleSnap ();
2067+}
2068+
2069+void
2070+FWWindow::handleButtonReleaseEvent ()
2071+{
2072+ FREEWINS_SCREEN (screen);
2073+
2074+ if (mGrab == grabMove || mGrab == grabResize)
2075+ {
2076+ screen->removeGrab (fws->mGrabIndex, NULL);
2077+ window->ungrabNotify ();
2078+ window->moveInputFocusTo ();
2079+ adjustIPW ();
2080+ fws->mGrabIndex = 0;
2081+ fws->mGrabWindow = NULL;
2082+ mGrab = grabNone;
2083+ }
2084+}
2085+
2086+void
2087+FWWindow::handleEnterNotify (XEvent *xev)
2088+{
2089+ XEvent EnterNotifyEvent;
2090+
2091+ memcpy (&EnterNotifyEvent.xcrossing, &xev->xcrossing,
2092+ sizeof (XCrossingEvent));
2093+/*
2094+ if (window)
2095+ {
2096+ EnterNotifyEvent.xcrossing.window = window->id ();
2097+ XSendEvent (screen->dpy (), window->id (),
2098+ FALSE, EnterWindowMask, &EnterNotifyEvent);
2099+ }
2100+*/
2101+}
2102+
2103+void
2104+FWWindow::handleLeaveNotify (XEvent *xev)
2105+{
2106+ XEvent LeaveNotifyEvent;
2107+
2108+ memcpy (&LeaveNotifyEvent.xcrossing, &xev->xcrossing,
2109+ sizeof (XCrossingEvent));
2110+ LeaveNotifyEvent.xcrossing.window = window->id ();
2111+
2112+ //XSendEvent (screen->dpy (), window->id (), FALSE,
2113+ // LeaveWindowMask, &LeaveNotifyEvent);
2114+}
2115+
2116+/* X Event Handler */
2117+void
2118+FWScreen::handleEvent (XEvent *ev)
2119+{
2120+ float dx, dy;
2121+ CompWindow *oldPrev, *oldNext, *w;
2122+
2123+ /* Check our modifiers first */
2124+
2125+ if (ev->type == screen->xkbEvent ())
2126+ {
2127+ XkbAnyEvent *xkbEvent = (XkbAnyEvent *) ev;
2128+
2129+ if (xkbEvent->xkb_type == XkbStateNotify)
2130+ {
2131+ XkbStateNotifyEvent *stateEvent = (XkbStateNotifyEvent *) ev;
2132+ unsigned int snapMods = 0xffffffff;
2133+ unsigned int invertMods = 0xffffffff;
2134+
2135+ if (mSnapMask)
2136+ snapMods = mSnapMask;
2137+
2138+ if ((stateEvent->mods & snapMods) == snapMods)
2139+ mSnap = TRUE;
2140+ else
2141+ mSnap = FALSE;
2142+
2143+ if (mInvertMask)
2144+ invertMods = mInvertMask;
2145+
2146+ if ((stateEvent->mods & invertMods) == invertMods)
2147+ mInvert = TRUE;
2148+ else
2149+ mInvert = FALSE;
2150+
2151+ }
2152+ }
2153+
2154+ switch(ev->type)
2155+ {
2156+ case EnterNotify:
2157+ {
2158+ CompWindow *btnW;
2159+ btnW = screen->findWindow (ev->xbutton.subwindow);
2160+
2161+ /* It wasn't the subwindow, try the window */
2162+ if (!btnW)
2163+ btnW = screen->findWindow (ev->xbutton.window);
2164+
2165+ /* We have established the CompWindow we clicked
2166+ * on. Get the real window */
2167+ if (btnW)
2168+ {
2169+ FREEWINS_WINDOW (btnW);
2170+ if (fww->canShape () && !mGrabWindow && !screen->otherGrabExist (0))
2171+ mHoverWindow = btnW;
2172+ btnW = getRealWindow (btnW);
2173+ }
2174+
2175+ if (btnW)
2176+ {
2177+ FREEWINS_WINDOW (btnW);
2178+ if (fww->canShape () && !mGrabWindow && !screen->otherGrabExist (0))
2179+ mHoverWindow = btnW;
2180+ fww->handleEnterNotify (ev);
2181+ }
2182+ }
2183+ break;
2184+
2185+ case LeaveNotify:
2186+ {
2187+ CompWindow *btnW;
2188+ btnW = screen->findWindow (ev->xbutton.subwindow);
2189+
2190+ /* It wasn't the subwindow, try the window */
2191+ if (!btnW)
2192+ btnW = screen->findWindow (ev->xbutton.window);
2193+
2194+ /* We have established the CompWindow we clicked
2195+ * on. Get the real window */
2196+ if (btnW)
2197+ btnW = getRealWindow (btnW);
2198+
2199+ if (btnW)
2200+ FWWindow::get (btnW)->handleLeaveNotify (ev);
2201+ }
2202+ break;
2203+
2204+ case MotionNotify:
2205+ {
2206+ if (mGrabWindow)
2207+ {
2208+ FREEWINS_WINDOW (mGrabWindow);
2209+
2210+ dx = ((float)(pointerX - lastPointerX) / screen->width ()) * \
2211+ optionGetMouseSensitivity ();
2212+ dy = ((float)(pointerY - lastPointerY) / screen->height ()) * \
2213+ optionGetMouseSensitivity ();
2214+
2215+ if (optionGetShapeWindowTypes ().evaluate (mGrabWindow))
2216+ {
2217+ if (fww->mGrab == grabMove || fww->mGrab == grabResize)
2218+ {
2219+ FWWindowInputInfo *info;
2220+// CompWindow *w = mGrabWindow;
2221+ foreach (info, mTransformedWindows)
2222+ {
2223+ if (mGrabWindow->id () == info->ipw)
2224+ /* The window we just grabbed was actually
2225+ * an IPW, get the real window instead
2226+ */
2227+ w = getRealWindow (mGrabWindow);
2228+ }
2229+ }
2230+ switch (fww->mGrab)
2231+ {
2232+ case grabMove:
2233+ fww->handleIPWMoveMotionEvent (pointerX, pointerY); break;
2234+ case grabResize:
2235+ fww->handleIPWResizeMotionEvent (pointerX, pointerY); break;
2236+ default:
2237+ break;
2238+ }
2239+ }
2240+
2241+ if (fww->mGrab == grabRotate)
2242+ {
2243+ fww->handleRotateMotionEvent(dx, dy, ev->xmotion.x, ev->xmotion.y);
2244+ }
2245+
2246+ if (fww->mGrab == grabScale)
2247+ {
2248+ fww->handleScaleMotionEvent(dx * 3, dy * 3, ev->xmotion.x, ev->xmotion.y);
2249+ }
2250+
2251+ //if(dx != 0.0 || dy != 0.0)
2252+ // fww->damageArea ();
2253+ }
2254+ }
2255+ break;
2256+
2257+ /* Button Press and Release */
2258+ case ButtonPress:
2259+ {
2260+ CompWindow *btnW;
2261+ btnW = screen->findWindow (ev->xbutton.subwindow);
2262+
2263+ /* It wasn't the subwindow, try the window */
2264+ if (!btnW)
2265+ btnW = screen->findWindow (ev->xbutton.window);
2266+
2267+ /* We have established the CompWindow we clicked
2268+ * on. Get the real window
2269+ * FIXME: Free btnW and use another CompWindow * such as realW
2270+ */
2271+ if (btnW)
2272+ btnW = getRealWindow (btnW);
2273+
2274+ if (btnW)
2275+ {
2276+ FREEWINS_WINDOW (btnW);
2277+
2278+ if (optionGetShapeWindowTypes ().evaluate (btnW))
2279+ switch (ev->xbutton.button)
2280+ {
2281+ case Button1:
2282+ fww->handleIPWMoveInitiate ();
2283+ break;
2284+
2285+ case Button3:
2286+ fww->handleIPWResizeInitiate ();
2287+ break;
2288+
2289+ default:
2290+ break;
2291+ }
2292+ }
2293+
2294+ mClick_root_x = ev->xbutton.x_root;
2295+ mClick_root_y = ev->xbutton.y_root;
2296+ }
2297+ break;
2298+
2299+ case ButtonRelease:
2300+ {
2301+ if (mGrabWindow)
2302+ {
2303+ FREEWINS_WINDOW (mGrabWindow);
2304+
2305+ if (optionGetShapeWindowTypes ().evaluate (mGrabWindow))
2306+ if (fww->mGrab == grabMove || fww->mGrab == grabResize)
2307+ {
2308+ fww->handleButtonReleaseEvent ();
2309+ mGrabWindow = 0;
2310+ }
2311+ }
2312+ }
2313+ break;
2314+
2315+ case ConfigureNotify:
2316+ {
2317+ w = screen->findWindow (ev->xconfigure.window);
2318+ if (w)
2319+ {
2320+ oldPrev = w->prev;
2321+ oldNext = w->next;
2322+
2323+ FREEWINS_WINDOW (w);
2324+
2325+ fww->mWinH = WIN_REAL_H (w);
2326+ fww->mWinW = WIN_REAL_W (w);
2327+ }
2328+ }
2329+ break;
2330+
2331+#if 0
2332+ case ClientMessage:
2333+ {
2334+ if (ev->xclient.message_type == Atoms::desktopViewport)
2335+ {
2336+ /* Viewport change occurred, or something like that - adjust the IPW's */
2337+ CompWindow *adjW, *actualW;
2338+
2339+ foreach (adjW, screen->windows ())
2340+ {
2341+ int vX = 0, vY = 0, dX, dY;
2342+
2343+ actualW = getRealWindow (adjW);
2344+
2345+ if (!actualW)
2346+ actualW = adjW;
2347+
2348+ if (actualW)
2349+ {
2350+ CompWindow *ipw;
2351+
2352+ FREEWINS_WINDOW (actualW);
2353+
2354+ if (!fww->mInput || fww->mInput->ipw)
2355+ break;
2356+
2357+ ipw = screen->findWindow (fww->mInput->ipw);
2358+
2359+ if (ipw)
2360+ {
2361+ dX = screen->vp ().x () - vX;
2362+ dY = screen->vp ().y () - vY;
2363+
2364+ CompPoint p = actualW->defaultViewport ();
2365+
2366+ vX = p.x ();
2367+ vY = p.y ();
2368+
2369+ ipw->moveToViewportPosition (ipw->x () - dX * screen->width (),
2370+ ipw->y () - dY * screen->height (),
2371+ true); // ???
2372+ }
2373+ }
2374+ }
2375+ }
2376+ }
2377+ break;
2378+#endif
2379+ default:
2380+ break;
2381+#if 0
2382+ if (ev->type == screen->shapeEvent () + ShapeNotify)
2383+ {
2384+ XShapeEvent *se = (XShapeEvent *) ev;
2385+ if (se->kind == ShapeInput)
2386+ {
2387+ CompWindow *w;
2388+ w = screen->findWindow (se->window);
2389+ if (w)
2390+ {
2391+ FREEWINS_WINDOW (w);
2392+
2393+ if (fww->canShape () && (fww->mTransform.scaleX != 1.0f || fww->mTransform.scaleY != 1.0f))
2394+ {
2395+ // Reset the window back to normal
2396+ fww->mTransform.scaleX = 1.0f;
2397+ fww->mTransform.scaleY = 1.0f;
2398+ fww->mTransform.angX = 0.0f;
2399+ fww->mTransform.angY = 0.0f;
2400+ fww->mTransform.angZ = 0.0f;
2401+ /*FWShapeInput (w); - Disabled due to problems it causes*/
2402+ }
2403+ }
2404+ }
2405+ }
2406+#endif
2407+ }
2408+
2409+ screen->handleEvent (ev);
2410+
2411+ /* Now we can find out if a restacking occurred while we were handing events */
2412+ switch (ev->type)
2413+ {
2414+ case ConfigureNotify:
2415+ {
2416+ w = screen->findWindow (ev->xconfigure.window);
2417+ if (w)
2418+ {
2419+ oldPrev = w->prev;
2420+ oldNext = w->next;
2421+ if (w->prev != oldPrev || w->next != oldNext)
2422+ {
2423+ /* restacking occured, ensure ipw stacking */
2424+ adjustIPWStacking ();
2425+ }
2426+ }
2427+ }
2428+ break;
2429+ }
2430+}
2431
2432=== added file 'plugins/freewins/src/freewins.cpp'
2433--- plugins/freewins/src/freewins.cpp 1970-01-01 00:00:00 +0000
2434+++ plugins/freewins/src/freewins.cpp 2013-02-28 06:12:23 +0000
2435@@ -0,0 +1,271 @@
2436+/**
2437+ * Compiz Fusion Freewins plugin
2438+ *
2439+ * freewins.cpp
2440+ *
2441+ * Copyright (C) 2007 Rodolfo Granata <warlock.cc@gmail.com>
2442+ *
2443+ * This program is free software; you can redistribute it and/or
2444+ * modify it under the terms of the GNU General Public License
2445+ * as published by the Free Software Foundation; either version 2
2446+ * of the License, or (at your option) any later version.
2447+ *
2448+ * This program is distributed in the hope that it will be useful,
2449+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2450+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2451+ * GNU General Public License for more details.
2452+ *
2453+ * Author(s):
2454+ * Rodolfo Granata <warlock.cc@gmail.com>
2455+ * Sam Spilsbury <smspillaz@gmail.com>
2456+ *
2457+ * Button binding support and Reset added by:
2458+ * enigma_0Z <enigma.0ZA@gmail.com>
2459+ *
2460+ * Most of the input handling here is based on
2461+ * the shelf plugin by
2462+ * : Kristian Lyngstøl <kristian@bohemians.org>
2463+ * : Danny Baumann <maniac@opencompositing.org>
2464+ *
2465+ * Description:
2466+ *
2467+ * This plugin allows you to freely transform the texture of a window,
2468+ * whether that be rotation or scaling to make better use of screen space
2469+ * or just as a toy.
2470+ *
2471+ * Todo:
2472+ * - Modifier key to rotate on the Z Axis
2473+ * - Fully implement an input redirection system by
2474+ * finding an inverse matrix, multiplying by it,
2475+ * translating to the actual window co-ords and
2476+ * XSendEvent() the co-ords to the actual window.
2477+ * - Code could be cleaner
2478+ * - Add timestep and speed options to animation
2479+ * - Add window hover-over info via paintOutput : i.e
2480+ * - Resize borders
2481+ * - 'Reset' Button
2482+ * - 'Scale' Button
2483+ * - 'Rotate' Button
2484+ */
2485+
2486+#include "freewins.h"
2487+
2488+COMPIZ_PLUGIN_20090315 (freewins, FWPluginVTable);
2489+
2490+/* Information on window resize */
2491+void
2492+FWWindow::resizeNotify (int dx,
2493+ int dy,
2494+ int dw,
2495+ int dh)
2496+{
2497+ calculateInputRect ();
2498+
2499+ int x = WIN_REAL_X(window) + WIN_REAL_W(window)/2.0;
2500+ int y = WIN_REAL_Y(window) + WIN_REAL_H(window)/2.0;
2501+
2502+ mRadius = sqrt(pow((x - WIN_REAL_X (window)), 2) + pow((y - WIN_REAL_Y (window)), 2));
2503+
2504+ window->resizeNotify (dx, dy, dw, dh);
2505+}
2506+
2507+void
2508+FWWindow::moveNotify (int dx,
2509+ int dy,
2510+ bool immediate)
2511+{
2512+ FREEWINS_SCREEN (screen);
2513+
2514+ /* Did we move and IPW and not the actual window? */
2515+ CompWindow *useWindow = fws->getRealWindow (window);
2516+
2517+ if (useWindow)
2518+ useWindow->move (dx, dy, fws->optionGetImmediateMoves ());
2519+ else if (window != fws->mGrabWindow)
2520+ adjustIPW ();
2521+
2522+ if (!useWindow)
2523+ useWindow = window;
2524+
2525+ int x = WIN_REAL_X (useWindow) + WIN_REAL_W (useWindow) /2.0;
2526+ int y = WIN_REAL_Y (useWindow) + WIN_REAL_H (useWindow) /2.0;
2527+
2528+
2529+ mRadius = sqrt (pow((x - WIN_REAL_X (useWindow)), 2) + pow ((y - WIN_REAL_Y (useWindow)), 2));
2530+
2531+ useWindow->moveNotify (dx, dy, immediate);
2532+}
2533+
2534+void
2535+FWScreen::reloadSnapKeys ()
2536+{
2537+ unsigned int imask = optionGetInvertModsMask ();
2538+ mInvertMask = 0;
2539+
2540+ if (imask & InvertModsShiftMask)
2541+ mInvertMask |= ShiftMask;
2542+ if (imask & InvertModsAltMask)
2543+ mInvertMask |= CompAltMask;
2544+ if (imask & InvertModsControlMask)
2545+ mInvertMask |= ControlMask;
2546+ if (imask & InvertModsMetaMask)
2547+ mInvertMask |= CompMetaMask;
2548+
2549+ unsigned int smask = optionGetSnapModsMask ();
2550+ mSnapMask = 0;
2551+ if (smask & SnapModsShiftMask)
2552+ mSnapMask |= ShiftMask;
2553+ if (smask & SnapModsAltMask)
2554+ mSnapMask |= CompAltMask;
2555+ if (smask & SnapModsControlMask)
2556+ mSnapMask |= ControlMask;
2557+ if (smask & SnapModsMetaMask)
2558+ mSnapMask |= CompMetaMask;
2559+}
2560+
2561+void
2562+FWScreen::optionChanged (CompOption *option,
2563+ FreewinsOptions::Options num)
2564+{
2565+ switch (num)
2566+ {
2567+ case FreewinsOptions::SnapMods:
2568+ case FreewinsOptions::InvertMods:
2569+ reloadSnapKeys ();
2570+ break;
2571+ default:
2572+ break;
2573+ }
2574+}
2575+
2576+/* ------ Plugin Initialisation ---------------------------------------*/
2577+
2578+/* Window initialisation / cleaning */
2579+
2580+FWWindow::FWWindow (CompWindow *w) :
2581+ PluginClassHandler <FWWindow, CompWindow> (w),
2582+ window (w),
2583+ cWindow (CompositeWindow::get (w)),
2584+ gWindow (GLWindow::get (w)),
2585+ mIMidX (WIN_REAL_W (w) / 2.0),
2586+ mIMidY (WIN_REAL_H (w) / 2.0),
2587+ mOMidX (0.0f),
2588+ mOMidY (0.0f),
2589+ mAdjustX (0.0f),
2590+ mAdjustY (0.0f),
2591+ mOldWinX (0),
2592+ mOldWinY (0),
2593+ mWinH (0),
2594+ mWinW (0),
2595+ mDirection (UpDown),
2596+ mCorner (CornerTopLeft),
2597+ mInput (NULL),
2598+ mOutputRect (w->outputRect ()),
2599+ mInputRect (w->borderRect ()),
2600+ mResetting (false),
2601+ mIsAnimating (false),
2602+ mCan2D (false),
2603+ mCan3D (false),
2604+ mTransformed (false),
2605+ mGrab (grabNone)
2606+{
2607+ WindowInterface::setHandler (window);
2608+ CompositeWindowInterface::setHandler (cWindow);
2609+ GLWindowInterface::setHandler (gWindow);
2610+
2611+ int x = WIN_REAL_X (w) + WIN_REAL_W (w) /2.0;
2612+ int y = WIN_REAL_Y (w) + WIN_REAL_H (w) /2.0;
2613+
2614+ mRadius = sqrt (pow ((x - WIN_REAL_X (w)), 2) + pow ((y - WIN_REAL_Y (w)), 2));
2615+}
2616+
2617+FWWindow::~FWWindow ()
2618+{
2619+ if (canShape ())
2620+ handleWindowInputInfo ();
2621+
2622+ FREEWINS_SCREEN (screen);
2623+
2624+ if (fws->mGrabWindow == window)
2625+ fws->mGrabWindow = NULL;
2626+}
2627+
2628+#define ROTATE_INC optionGetRotateIncrementAmount ()
2629+#define NEG_ROTATE_INC optionGetRotateIncrementAmount () *-1
2630+
2631+#define SCALE_INC optionGetScaleIncrementAmount ()
2632+#define NEG_SCALE_INC optionGetScaleIncrementAmount () *-1
2633+
2634+FWScreen::FWScreen (CompScreen *screen) :
2635+ PluginClassHandler <FWScreen, CompScreen> (screen),
2636+ cScreen (CompositeScreen::get (screen)),
2637+ gScreen (GLScreen::get (screen)),
2638+ mClick_root_x (0),
2639+ mClick_root_y (0),
2640+ mGrabWindow (NULL),
2641+ mHoverWindow (NULL),
2642+ mLastGrabWindow (NULL),
2643+ mAxisHelp (false),
2644+ mSnap (false),
2645+ mInvert (false),
2646+ mSnapMask (0),
2647+ mInvertMask (0),
2648+ mGrabIndex (0)
2649+{
2650+ ScreenInterface::setHandler (screen);
2651+ CompositeScreenInterface::setHandler (cScreen);
2652+ GLScreenInterface::setHandler (gScreen);
2653+
2654+ /* TODO: warning about shape! */
2655+
2656+ /* BCOP Action initiation */
2657+ optionSetInitiateRotationButtonInitiate (boost::bind (&FWScreen::initiateFWRotate, this, _1, _2, _3));
2658+ optionSetInitiateRotationButtonTerminate (boost::bind (&FWScreen::terminateFWRotate, this, _1, _2, _3));
2659+ optionSetInitiateScaleButtonInitiate (boost::bind (&FWScreen::initiateFWScale, this, _1, _2, _3));
2660+ optionSetInitiateScaleButtonTerminate (boost::bind (&FWScreen::terminateFWScale, this, _1, _2, _3));
2661+ optionSetResetButtonInitiate (boost::bind (&FWScreen::resetFWTransform, this, _1, _2, _3));
2662+ optionSetResetKeyInitiate (boost::bind (&FWScreen::resetFWTransform, this, _1, _2, _3));
2663+ optionSetToggleAxisKeyInitiate (boost::bind (&FWScreen::toggleFWAxis, this, _1, _2, _3));
2664+
2665+ // Rotate / Scale Up Down Left Right TODO: rebind these actions on option change
2666+
2667+ optionSetScaleUpButtonInitiate (boost::bind (&FWScreen::scale, this, _1, _2, _3, SCALE_INC));
2668+ optionSetScaleDownButtonInitiate (boost::bind (&FWScreen::scale, this, _1, _2, _3, NEG_SCALE_INC));
2669+ optionSetScaleUpKeyInitiate (boost::bind (&FWScreen::scale, this, _1, _2, _3, SCALE_INC));
2670+ optionSetScaleDownKeyInitiate (boost::bind (&FWScreen::scale, this, _1, _2, _3, NEG_SCALE_INC));
2671+
2672+ optionSetRotateUpKeyInitiate (boost::bind (&FWScreen::rotate, this, _1, _2, _3, 0, ROTATE_INC, 0));
2673+ optionSetRotateDownKeyInitiate (boost::bind (&FWScreen::rotate, this, _1, _2, _3, 0, NEG_ROTATE_INC, 0));
2674+ optionSetRotateLeftKeyInitiate (boost::bind (&FWScreen::rotate, this, _1, _2, _3, ROTATE_INC, 0, 0));
2675+ optionSetRotateRightKeyInitiate (boost::bind (&FWScreen::rotate, this, _1, _2, _3, NEG_ROTATE_INC, 0, 0));
2676+ optionSetRotateCKeyInitiate (boost::bind (&FWScreen::rotate, this, _1, _2, _3, 0, 0, ROTATE_INC));
2677+ optionSetRotateCcKeyInitiate (boost::bind (&FWScreen::rotate, this, _1, _2, _3, 0, 0, NEG_ROTATE_INC));
2678+
2679+ optionSetRotateInitiate (boost::bind (&FWScreen::rotateAction, this, _1, _2, _3));
2680+ optionSetIncrementRotateInitiate (boost::bind (&FWScreen::incrementRotateAction, this, _1, _2, _3));
2681+ optionSetScaleInitiate (boost::bind (&FWScreen::scaleAction, this, _1, _2, _3));
2682+
2683+ optionSetSnapModsNotify (boost::bind (&FWScreen::optionChanged, this, _1, _2));
2684+ optionSetInvertModsNotify (boost::bind (&FWScreen::optionChanged, this, _1, _2));
2685+
2686+ reloadSnapKeys ();
2687+}
2688+
2689+bool
2690+FWPluginVTable::init ()
2691+{
2692+ if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
2693+ return false;
2694+ if (!CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI))
2695+ return false;
2696+ if (!CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
2697+ return false;
2698+
2699+ if (!screen->XShape ())
2700+ {
2701+ compLogMessage ("shelf", CompLogLevelError,
2702+ "No Shape extension found. IPW Usage not enabled \n");
2703+ }
2704+
2705+ return true;
2706+}
2707
2708=== added file 'plugins/freewins/src/freewins.h'
2709--- plugins/freewins/src/freewins.h 1970-01-01 00:00:00 +0000
2710+++ plugins/freewins/src/freewins.h 2013-02-28 06:12:23 +0000
2711@@ -0,0 +1,589 @@
2712+/**
2713+ * Compiz Fusion Freewins plugin
2714+ *
2715+ * freewins.h
2716+ *
2717+ * Copyright (C) 2007 Rodolfo Granata <warlock.cc@gmail.com>
2718+ *
2719+ * This program is free software; you can redistribute it and/or
2720+ * modify it under the terms of the GNU General Public License
2721+ * as published by the Free Software Foundation; either version 2
2722+ * of the License, or (at your option) any later version.
2723+ *
2724+ * This program is distributed in the hope that it will be useful,
2725+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2726+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2727+ * GNU General Public License for more details.
2728+ *
2729+ * Author(s):
2730+ * Rodolfo Granata <warlock.cc@gmail.com>
2731+ *
2732+ * Button binding support and Reset added by:
2733+ * enigma_0Z <enigma.0ZA@gmail.com>
2734+ *
2735+ * Scaling, Animation, Input-Shaping, Snapping
2736+ * and Key-Based Transformation added by:
2737+ * Sam Spilsbury <smspillaz@gmail.com>
2738+ *
2739+ * Most of the input handling here is based on
2740+ * the shelf plugin by
2741+ * : Kristian Lyngstøl <kristian@bohemians.org>
2742+ * : Danny Baumann <maniac@opencompositing.org>
2743+ *
2744+ * Description:
2745+ *
2746+ * This plugin allows you to freely transform the texture of a window,
2747+ * whether that be rotation or scaling to make better use of screen space
2748+ * or just as a toy.
2749+ *
2750+ * Todo:
2751+ * - Fully implement an input redirection system by
2752+ * finding an inverse matrix, multiplying by it,
2753+ * translating to the actual window co-ords and
2754+ * XSendEvent() the co-ords to the actual window.
2755+ * - Code could be cleaner
2756+ * - Add timestep and speed options to animation
2757+ * - Add window hover-over info via paintOutput : i.e
2758+ * - Resize borders
2759+ * - 'Reset' Button
2760+ * - 'Scale' Button
2761+ * - 'Rotate' Button
2762+ */
2763+
2764+#include <core/core.h>
2765+#include <core/pluginclasshandler.h>
2766+#include <composite/composite.h>
2767+#include <opengl/opengl.h>
2768+#include <core/atoms.h>
2769+
2770+#include <cmath>
2771+#include <cstdio>
2772+#include <cstring>
2773+
2774+#include <X11/cursorfont.h>
2775+#include <X11/extensions/shape.h>
2776+
2777+#include <GL/glu.h>
2778+#include <GL/gl.h>
2779+
2780+#include "freewins_options.h"
2781+
2782+/* #define ABS(x) ((x)>0?(x):-(x)) */
2783+#define D2R(x) ((x) * (M_PI / 180.0))
2784+#define R2D(x) ((x) * (180 / M_PI))
2785+
2786+/* ------ Macros ---------------------------------------------------------*/
2787+
2788+#define WIN_OUTPUT_X(w) (w->x () - w->output ().left)
2789+#define WIN_OUTPUT_Y(w) (w->y () - w->output ().top)
2790+
2791+#define WIN_OUTPUT_W(w) (w->width () + w->output ().left + w->output ().right)
2792+#define WIN_OUTPUT_H(w) (w->height () + w->output ().top + w->output ().bottom)
2793+
2794+#define WIN_REAL_X(w) (w->x () - w->border ().left)
2795+#define WIN_REAL_Y(w) (w->y () - w->border ().top)
2796+
2797+#define WIN_REAL_W(w) (w->width () + w->border ().left + w->border ().right)
2798+#define WIN_REAL_H(w) (w->height () + w->border ().top + w->border ().bottom)
2799+
2800+#define WIN_CORNER1(w) GLVector ic1 = GLVector (WIN_REAL_X (w), WIN_REAL_Y (w), 0.0f, 1.0f);
2801+#define WIN_CORNER2(w) GLVector ic2 = GLVector (WIN_REAL_X (w) + WIN_REAL_W (w), WIN_REAL_Y (w), 0.0f, 1.0f);
2802+#define WIN_CORNER3(w) GLVector ic3 = GLVector (WIN_REAL_X (w), WIN_REAL_Y (w) + WIN_REAL_H (w), 0.0f, 1.0f);
2803+#define WIN_CORNER4(w) GLVector ic4 = GLVector (WIN_REAL_X (w) + WIN_REAL_W (w), WIN_REAL_Y (w) + WIN_REAL_H (w), 0.0f, 1.0f);
2804+
2805+#define WIN_OCORNER1(w) GLVector oc1 = GLVector (WIN_OUTPUT_X (w), WIN_OUTPUT_Y (w), 0.0f, 1.0f);
2806+#define WIN_OCORNER2(w) GLVector oc2 = GLVector (WIN_OUTPUT_X (w) + WIN_OUTPUT_W (w), WIN_OUTPUT_Y (w), 0.0f, 1.0f);
2807+#define WIN_OCORNER3(w) GLVector oc3 = GLVector (WIN_OUTPUT_X (w), WIN_OUTPUT_Y (w) + WIN_OUTPUT_H (w), 0.0f, 1.0f);
2808+#define WIN_OCORNER4(w) GLVector oc4 = GLVector ( WIN_OUTPUT_X (w) + WIN_OUTPUT_W (w), WIN_OUTPUT_Y (w) + WIN_OUTPUT_H (w), 0.0f, 1.0f);
2809+
2810+/* ------ Structures and Enums ------------------------------------------*/
2811+
2812+/* Enums */
2813+typedef enum _StartCorner
2814+{
2815+ CornerTopLeft = 0,
2816+ CornerTopRight = 1,
2817+ CornerBottomLeft = 2,
2818+ CornerBottomRight = 3
2819+} StartCorner;
2820+
2821+typedef enum _FWGrabType
2822+{
2823+ grabNone = 0,
2824+ grabRotate,
2825+ grabScale,
2826+ grabMove,
2827+ grabResize
2828+} FWGrabType;
2829+
2830+typedef enum _Direction
2831+{
2832+ UpDown = 0,
2833+ LeftRight = 1
2834+} Direction;
2835+
2836+typedef enum _FWAxisType
2837+{
2838+ axisX = 0,
2839+ axisY,
2840+ axisZ,
2841+ axisXY,
2842+ axisXZ,
2843+} FWAxisType;
2844+
2845+/* Shape info / restoration */
2846+class FWWindowInputInfo
2847+{
2848+ public:
2849+
2850+ FWWindowInputInfo (CompWindow *);
2851+ ~FWWindowInputInfo ();
2852+
2853+ public:
2854+ CompWindow *w;
2855+
2856+ Window ipw;
2857+
2858+ XRectangle *inputRects;
2859+ int nInputRects;
2860+ int inputRectOrdering;
2861+
2862+ XRectangle *frameInputRects;
2863+ int frameNInputRects;
2864+ int frameInputRectOrdering;
2865+};
2866+
2867+class FWWindowOutputInfo
2868+{
2869+ public:
2870+ float shapex1;
2871+ float shapex2;
2872+ float shapex3;
2873+ float shapex4;
2874+ float shapey1;
2875+ float shapey2;
2876+ float shapey3;
2877+ float shapey4;
2878+};
2879+
2880+/* Trackball */
2881+
2882+/*typedef struct _FWTrackball
2883+{
2884+ CompVector mouseX;
2885+ CompVector mouse0;
2886+ CompVector tr_axis;
2887+ float tr_ang;
2888+ float tr_radius;
2889+
2890+} FWTrackball;*/
2891+
2892+/* Transformation info */
2893+class FWTransformedWindowInfo
2894+{
2895+ public:
2896+ FWTransformedWindowInfo () :
2897+ angX (0),
2898+ angY (0),
2899+ angZ (0),
2900+ scaleX (1.0f),
2901+ scaleY (1.0f),
2902+ unsnapAngX (0),
2903+ unsnapAngY (0),
2904+ unsnapAngZ (0),
2905+ unsnapScaleX (0),
2906+ unsnapScaleY (0) {}
2907+
2908+ //FWTrackball trackball;
2909+
2910+ float angX;
2911+ float angY;
2912+ float angZ;
2913+
2914+ float scaleX;
2915+ float scaleY;
2916+
2917+ // Window transformation
2918+
2919+ /* Used for snapping */
2920+
2921+ float unsnapAngX;
2922+ float unsnapAngY;
2923+ float unsnapAngZ;
2924+
2925+ float unsnapScaleX;
2926+ float unsnapScaleY;
2927+};
2928+
2929+class FWAnimationInfo
2930+{
2931+ public:
2932+
2933+ FWAnimationInfo () :
2934+ oldAngX (0),
2935+ oldAngY (0),
2936+ oldAngZ (0),
2937+ oldScaleX (1.0f),
2938+ oldScaleY (1.0f),
2939+ destAngX (0),
2940+ destAngY (0),
2941+ destAngZ (0),
2942+ destScaleX (1.0f),
2943+ destScaleY (1.0f),
2944+ steps (0) {}
2945+
2946+ // Old values to animate from
2947+ float oldAngX;
2948+ float oldAngY;
2949+ float oldAngZ;
2950+
2951+ float oldScaleX;
2952+ float oldScaleY;
2953+
2954+ // New values to animate to
2955+ float destAngX;
2956+ float destAngY;
2957+ float destAngZ;
2958+
2959+ float destScaleX;
2960+ float destScaleY;
2961+
2962+ // For animation
2963+ float steps;
2964+};
2965+
2966+class FWScreen :
2967+ public PluginClassHandler <FWScreen, CompScreen>,
2968+ public ScreenInterface,
2969+ public CompositeScreenInterface,
2970+ public GLScreenInterface,
2971+ public FreewinsOptions
2972+{
2973+ public:
2974+
2975+ FWScreen (CompScreen *screen);
2976+
2977+ CompositeScreen *cScreen;
2978+ GLScreen *gScreen;
2979+
2980+ std::list <FWWindowInputInfo *> mTransformedWindows;
2981+
2982+ int mClick_root_x;
2983+ int mClick_root_y;
2984+
2985+ CompWindow *mGrabWindow;
2986+ CompWindow *mHoverWindow;
2987+ CompWindow *mLastGrabWindow;
2988+
2989+ bool mAxisHelp;
2990+ bool mSnap;
2991+ bool mInvert;
2992+ int mSnapMask;
2993+ int mInvertMask;
2994+
2995+ Cursor mRotateCursor;
2996+
2997+ CompScreen::GrabHandle mGrabIndex;
2998+
2999+ void preparePaint (int);
3000+ bool glPaintOutput (const GLScreenPaintAttrib &,
3001+ const GLMatrix &,
3002+ const CompRegion &,
3003+ CompOutput *,
3004+ unsigned int );
3005+ void donePaint ();
3006+
3007+ void handleEvent (XEvent *);
3008+
3009+ void
3010+ optionChanged (CompOption *option,
3011+ FreewinsOptions::Options num);
3012+
3013+ void
3014+ reloadSnapKeys ();
3015+
3016+ bool
3017+ initiateFWRotate (CompAction *action,
3018+ CompAction::State state,
3019+ CompOption::Vector options);
3020+
3021+ bool
3022+ terminateFWRotate (CompAction *action,
3023+ CompAction::State state,
3024+ CompOption::Vector options);
3025+
3026+ bool
3027+ initiateFWScale (CompAction *action,
3028+ CompAction::State state,
3029+ CompOption::Vector options);
3030+
3031+ bool
3032+ terminateFWScale (CompAction *action,
3033+ CompAction::State state,
3034+ CompOption::Vector options);
3035+
3036+ bool
3037+ rotate (CompAction *action,
3038+ CompAction::State state,
3039+ CompOption::Vector options, int dx, int dy, int dz);
3040+
3041+ bool
3042+ scale (CompAction *action,
3043+ CompAction::State state,
3044+ CompOption::Vector options,
3045+ int scale);
3046+ bool
3047+ resetFWTransform (CompAction *action,
3048+ CompAction::State state,
3049+ CompOption::Vector options);
3050+
3051+ bool
3052+ rotateAction (CompAction *action,
3053+ CompAction::State state,
3054+ CompOption::Vector options);
3055+
3056+ bool
3057+ incrementRotateAction (CompAction *action,
3058+ CompAction::State state,
3059+ CompOption::Vector options);
3060+
3061+ bool
3062+ scaleAction (CompAction *action,
3063+ CompAction::State state,
3064+ CompOption::Vector options);
3065+
3066+ bool
3067+ toggleFWAxis (CompAction *action,
3068+ CompAction::State state,
3069+ CompOption::Vector options);
3070+
3071+ void
3072+ addWindowToList (FWWindowInputInfo *info);
3073+
3074+ void
3075+ removeWindowFromList (FWWindowInputInfo *info);
3076+
3077+ void
3078+ adjustIPWStacking ();
3079+
3080+ void
3081+ rotateProjectVector (GLVector &vector,
3082+ GLMatrix &transform,
3083+ GLdouble *resultX,
3084+ GLdouble *resultY,
3085+ GLdouble *resultZ);
3086+
3087+ void
3088+ perspectiveDistortAndResetZ (GLMatrix &transform);
3089+
3090+ void
3091+ modifyMatrix (GLMatrix &transform,
3092+ float angX, float angY, float angZ,
3093+ float tX, float tY, float tZ,
3094+ float scX, float scY, float scZ,
3095+ float adjustX, float adjustY, bool paint);
3096+
3097+ CompRect
3098+ createSizedRect (float xScreen1,
3099+ float xScreen2,
3100+ float xScreen3,
3101+ float xScreen4,
3102+ float yScreen1,
3103+ float yScreen2,
3104+ float yScreen3,
3105+ float yScreen4);
3106+
3107+ CompWindow *
3108+ getRealWindow (CompWindow *w);
3109+};
3110+
3111+/* Freewins Window Structure */
3112+class FWWindow :
3113+ public PluginClassHandler <FWWindow, CompWindow>,
3114+ public WindowInterface,
3115+ public CompositeWindowInterface,
3116+ public GLWindowInterface
3117+{
3118+ public:
3119+
3120+ FWWindow (CompWindow *w);
3121+ ~FWWindow ();
3122+
3123+ CompWindow *window;
3124+ CompositeWindow *cWindow;
3125+ GLWindow *gWindow;
3126+
3127+ bool glPaint (const GLWindowPaintAttrib &,
3128+ const GLMatrix &,
3129+ const CompRegion &,
3130+ unsigned int );
3131+
3132+ bool damageRect (bool initial,
3133+ const CompRect &);
3134+
3135+ void moveNotify (int, int, bool);
3136+ void resizeNotify (int, int, int, int);
3137+
3138+ float mIMidX;
3139+ float mIMidY;
3140+
3141+ float mOMidX; /* These will be removed */
3142+ float mOMidY;
3143+
3144+ float mAdjustX;
3145+ float mAdjustY;
3146+
3147+ float mRadius;
3148+
3149+ // Used for determining window movement
3150+
3151+ int mOldWinX;
3152+ int mOldWinY;
3153+
3154+ // Used for resize
3155+
3156+ int mWinH;
3157+ int mWinW;
3158+
3159+ Direction mDirection;
3160+
3161+ // Used to determine starting point
3162+ StartCorner mCorner;
3163+
3164+ // Transformation info
3165+ FWTransformedWindowInfo mTransform;
3166+
3167+ // Animation Info
3168+ FWAnimationInfo mAnimate;
3169+
3170+ // Input Info
3171+ FWWindowInputInfo *mInput;
3172+
3173+ //Output Info
3174+ FWWindowOutputInfo mOutput;
3175+
3176+ CompRect mOutputRect;
3177+ CompRect mInputRect;
3178+
3179+ // Used to determine whether to animate the window
3180+ bool mResetting;
3181+ bool mIsAnimating;
3182+
3183+ // Used to determine whether rotating on X and Y axis, or just on Z
3184+ bool mCan2D; // These need to be removed
3185+ bool mCan3D;
3186+
3187+ bool mTransformed; // So does this in favor of FWWindowInputInfo
3188+
3189+ FWGrabType mGrab;
3190+
3191+ void
3192+ shapeIPW ();
3193+
3194+ void
3195+ saveInputShape (XRectangle **retRects,
3196+ int *retCount,
3197+ int *retOrdering);
3198+
3199+ void
3200+ adjustIPW ();
3201+
3202+ void
3203+ createIPW ();
3204+
3205+ bool
3206+ handleWindowInputInfo ();
3207+
3208+ void
3209+ shapeInput ();
3210+
3211+ void
3212+ unshapeInput ();
3213+
3214+ void
3215+ handleIPWResizeInitiate ();
3216+
3217+ void
3218+ handleIPWMoveInitiate ();
3219+
3220+ void
3221+ handleIPWMoveMotionEvent (unsigned int x,
3222+ unsigned int y);
3223+
3224+ void
3225+ handleIPWResizeMotionEvent (unsigned int x,
3226+ unsigned int y);
3227+
3228+ void
3229+ handleRotateMotionEvent (float dx,
3230+ float dy,
3231+ int x,
3232+ int y);
3233+
3234+ void
3235+ handleScaleMotionEvent (float dx,
3236+ float dy,
3237+ int x,
3238+ int y);
3239+
3240+ void
3241+ handleButtonReleaseEvent ();
3242+
3243+ void
3244+ handleEnterNotify (XEvent *xev);
3245+
3246+ void
3247+ handleLeaveNotify (XEvent *xev);
3248+
3249+ void
3250+ damageArea ();
3251+
3252+ void
3253+ setPrepareRotation (float dx,
3254+ float dy,
3255+ float dz,
3256+ float dsu,
3257+ float dsd);
3258+
3259+ void
3260+ calculateInputOrigin (float x, float y);
3261+
3262+ void
3263+ calculateOutputOrigin (float x, float y);
3264+
3265+ void
3266+ calculateOutputRect ();
3267+
3268+ void
3269+ calculateInputRect ();
3270+
3271+ CompRect
3272+ calculateWindowRect (GLVector c1,
3273+ GLVector c2,
3274+ GLVector c3,
3275+ GLVector c4);
3276+
3277+ void
3278+ determineZAxisClick (int px,
3279+ int py,
3280+ bool motion);
3281+ bool
3282+ canShape ();
3283+
3284+ void
3285+ handleSnap ();
3286+};
3287+
3288+#define FREEWINS_SCREEN(screen) \
3289+ FWScreen *fws = FWScreen::get (screen);
3290+
3291+#define FREEWINS_WINDOW(window) \
3292+ FWWindow *fww = FWWindow::get (window);
3293+
3294+class FWPluginVTable :
3295+ public CompPlugin::VTableForScreenAndWindow <FWScreen, FWWindow>
3296+{
3297+ public:
3298+
3299+ bool init ();
3300+};
3301
3302=== added file 'plugins/freewins/src/input.cpp'
3303--- plugins/freewins/src/input.cpp 1970-01-01 00:00:00 +0000
3304+++ plugins/freewins/src/input.cpp 2013-02-28 06:12:23 +0000
3305@@ -0,0 +1,397 @@
3306+/**
3307+ * Compiz Fusion Freewins plugin
3308+ *
3309+ * input.cpp
3310+ *
3311+ * Copyright (C) 2007 Rodolfo Granata <warlock.cc@gmail.com>
3312+ *
3313+ * This program is free software; you can redistribute it and/or
3314+ * modify it under the terms of the GNU General Public License
3315+ * as published by the Free Software Foundation; either version 2
3316+ * of the License, or (at your option) any later version.
3317+ *
3318+ * This program is distributed in the hope that it will be useful,
3319+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3320+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3321+ * GNU General Public License for more details.
3322+ *
3323+ * Author(s):
3324+ * Rodolfo Granata <warlock.cc@gmail.com>
3325+ * Sam Spilsbury <smspillaz@gmail.com>
3326+ *
3327+ * Button binding support and Reset added by:
3328+ * enigma_0Z <enigma.0ZA@gmail.com>
3329+ *
3330+ * Most of the input handling here is based on
3331+ * the shelf plugin by
3332+ * : Kristian Lyngstøl <kristian@bohemians.org>
3333+ * : Danny Baumann <maniac@opencompositing.org>
3334+ *
3335+ * Description:
3336+ *
3337+ * This plugin allows you to freely transform the texture of a window,
3338+ * whether that be rotation or scaling to make better use of screen space
3339+ * or just as a toy.
3340+ *
3341+ * Todo:
3342+ * - Fully implement an input redirection system by
3343+ * finding an inverse matrix, multiplying by it,
3344+ * translating to the actual window co-ords and
3345+ * XSendEvent() the co-ords to the actual window.
3346+ * - Code could be cleaner
3347+ * - Add timestep and speed options to animation
3348+ * - Add window hover-over info via paintOutput : i.e
3349+ * - Resize borders
3350+ * - 'Reset' Button
3351+ * - 'Scale' Button
3352+ * - 'Rotate' Button
3353+ */
3354+
3355+#include "freewins.h"
3356+#include <cairo/cairo-xlib.h>
3357+
3358+
3359+/* ------ Input Prevention -------------------------------------------*/
3360+
3361+/* Shape the IPW
3362+ * Thanks to Joel Bosveld (b0le)
3363+ * for helping me with this section
3364+ */
3365+void
3366+FWWindow::shapeIPW ()
3367+{
3368+ if (mInput)
3369+ {
3370+ Window xipw = mInput->ipw;
3371+ CompWindow *ipw = screen->findWindow (xipw);
3372+
3373+ if (ipw)
3374+ {
3375+ cairo_t *cr;
3376+ int width, height;
3377+
3378+ width = mInputRect.width ();
3379+ height = mInputRect.height ();
3380+
3381+ Pixmap b = XCreatePixmap (screen->dpy (), xipw, width, height, 1);
3382+
3383+ cairo_surface_t *bitmap =
3384+ cairo_xlib_surface_create_for_bitmap (screen->dpy (),
3385+ b,
3386+ DefaultScreenOfDisplay (screen->dpy ()),
3387+ width, height);
3388+
3389+ cr = cairo_create (bitmap);
3390+
3391+ cairo_save (cr);
3392+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
3393+ cairo_paint (cr);
3394+ cairo_restore (cr);
3395+
3396+ /* Move to our first corner (TopLeft) */
3397+
3398+ cairo_move_to (cr,
3399+ mOutput.shapex1 - MIN(mInputRect.x1 (), mInputRect.x2 ()),
3400+ mOutput.shapey1 - MIN(mInputRect.y1 (), mInputRect.y2 ()));
3401+
3402+ /* Line to TopRight */
3403+
3404+ cairo_line_to (cr,
3405+ mOutput.shapex2 - MIN(mInputRect.x1 (), mInputRect.x2 ()),
3406+ mOutput.shapey2 - MIN(mInputRect.y1 (), mInputRect.y2 ()));
3407+
3408+ /* Line to BottomRight */
3409+
3410+ cairo_line_to (cr,
3411+ mOutput.shapex4 - MIN(mInputRect.x1 (), mInputRect.x2 ()),
3412+ mOutput.shapey4 - MIN(mInputRect.y1 (), mInputRect.y2 ()));
3413+
3414+ /* Line to BottomLeft */
3415+
3416+ cairo_line_to (cr,
3417+ mOutput.shapex3 - MIN(mInputRect.x1 (), mInputRect.x2 ()),
3418+ mOutput.shapey3 - MIN(mInputRect.y1 (), mInputRect.y2 ()));
3419+
3420+ /* Line to TopLeft */
3421+
3422+ cairo_line_to (cr,
3423+ mOutput.shapex1 - MIN(mInputRect.x1 (), mInputRect.x2 ()),
3424+ mOutput.shapey1 - MIN(mInputRect.y1 (), mInputRect.y2 ()));
3425+
3426+ /* Ensure it's all closed up */
3427+
3428+ cairo_close_path (cr);
3429+
3430+ /* Fill in the box */
3431+
3432+ cairo_set_source_rgb (cr, 1.0f, 1.0f, 1.0f);
3433+ cairo_fill (cr);
3434+
3435+ /* This takes the bitmap we just drew with cairo
3436+ * and scans out the white bits (You can see these)
3437+ * if you uncomment the following line after this
3438+ * comment. Then, all the bits we drew on are clickable,
3439+ * leaving us with a nice and neat window shape. Yummy.
3440+ */
3441+
3442+ /* XWriteBitmapFile (ipw->screen->display->display,
3443+ "/path/to/your/image.bmp",
3444+ b,
3445+ ipw->width,
3446+ ipw->height,
3447+ -1, -1); */
3448+
3449+ XShapeCombineMask (screen->dpy (), xipw,
3450+ ShapeBounding,
3451+ 0,
3452+ 0,
3453+ b,
3454+ ShapeSet);
3455+
3456+ XFreePixmap (screen->dpy (), b);
3457+ cairo_surface_destroy (bitmap);
3458+ cairo_destroy (cr);
3459+ }
3460+ }
3461+}
3462+
3463+void
3464+FWWindow::saveInputShape (XRectangle **retRects,
3465+ int *retCount,
3466+ int *retOrdering)
3467+{
3468+ XRectangle *rects;
3469+ int count = 0, ordering;
3470+ Display *dpy = screen->dpy ();
3471+
3472+ rects = XShapeGetRectangles (dpy, window->id (), ShapeInput, &count, &ordering);
3473+
3474+ /* check if the returned shape exactly matches the window shape -
3475+ if that is true, the window currently has no set input shape */
3476+ if ((count == 1) &&
3477+ (rects[0].x == -window->geometry ().border ()) &&
3478+ (rects[0].y == -window->geometry ().border ()) &&
3479+ (rects[0].width == (window->serverWidth () +
3480+ window->serverGeometry ().border ())) &&
3481+ (rects[0].height == (window->serverHeight () +
3482+ window->serverGeometry (). border ())))
3483+ {
3484+ count = 0;
3485+ }
3486+
3487+ *retRects = rects;
3488+ *retCount = count;
3489+ *retOrdering = ordering;
3490+}
3491+
3492+void
3493+FWScreen::addWindowToList (FWWindowInputInfo *info)
3494+{
3495+ mTransformedWindows.push_back (info);
3496+}
3497+
3498+void
3499+FWScreen::removeWindowFromList (FWWindowInputInfo *info)
3500+{
3501+ mTransformedWindows.remove (info);
3502+}
3503+
3504+/* Adjust size and location of the input prevention window */
3505+void
3506+FWWindow::adjustIPW ()
3507+{
3508+ XWindowChanges xwc;
3509+ Display *dpy = screen->dpy ();
3510+ float f_width, f_height;
3511+
3512+ if (!mInput || !mInput->ipw)
3513+ return;
3514+
3515+ f_width = mInputRect.width ();
3516+ f_height = mInputRect.height ();
3517+
3518+ xwc.x = mInputRect.x ();
3519+ xwc.y = mInputRect.y ();
3520+ xwc.width = (int) f_width;
3521+ xwc.height = (int) f_height;
3522+ xwc.stack_mode = Below;
3523+ /* XXX: This causes XConfigureWindow to break */
3524+ //xwc.sibling = window->id ();
3525+
3526+ XMapWindow (dpy, mInput->ipw);
3527+
3528+ XConfigureWindow (dpy, mInput->ipw,
3529+ CWStackMode | CWX | CWY | CWWidth | CWHeight,
3530+ &xwc);
3531+
3532+ shapeIPW ();
3533+}
3534+
3535+void
3536+FWScreen::adjustIPWStacking ()
3537+{
3538+
3539+ foreach (FWWindowInputInfo *run, mTransformedWindows)
3540+ {
3541+ if (!run->w->prev || run->w->prev->id () != run->ipw)
3542+ FWWindow::get (run->w)->adjustIPW ();
3543+ }
3544+}
3545+
3546+/* Create an input prevention window */
3547+void
3548+FWWindow::createIPW ()
3549+{
3550+ Window ipw;
3551+ XSetWindowAttributes attrib;
3552+ XWindowChanges xwc;
3553+
3554+ if (!mInput || mInput->ipw)
3555+ return;
3556+
3557+ attrib.override_redirect = true;
3558+ //attrib.event_mask = 0;
3559+
3560+ xwc.x = mInputRect.x ();
3561+ xwc.y = mInputRect.y ();
3562+ xwc.width = mInputRect.width ();
3563+ xwc.height = mInputRect.height ();
3564+
3565+ ipw = XCreateWindow (screen->dpy (),
3566+ screen->root (),
3567+ xwc.x, xwc.y, xwc.width, xwc.height, 0, CopyFromParent, InputOnly,
3568+ CopyFromParent, CWOverrideRedirect, &attrib);
3569+
3570+ XMapWindow (screen->dpy (), ipw);
3571+
3572+ //XConfigureWindow (screen->dpy (), ipw, CWStackMode | CWX | CWY | CWWidth | CWHeight, &xwc);
3573+
3574+ mInput->ipw = ipw;
3575+
3576+ //shapeIPW ();
3577+}
3578+
3579+FWWindowInputInfo::FWWindowInputInfo (CompWindow *window) :
3580+ w (window),
3581+ ipw (None),
3582+ inputRects (NULL),
3583+ nInputRects (0),
3584+ inputRectOrdering (0),
3585+ frameInputRects (NULL),
3586+ frameNInputRects (0),
3587+ frameInputRectOrdering (0)
3588+{
3589+}
3590+
3591+FWWindowInputInfo::~FWWindowInputInfo ()
3592+{
3593+}
3594+
3595+bool
3596+FWWindow::handleWindowInputInfo ()
3597+{
3598+ FREEWINS_SCREEN (screen);
3599+
3600+ if (!mTransformed && mInput)
3601+ {
3602+ if (mInput->ipw)
3603+ XDestroyWindow (screen->dpy (), mInput->ipw);
3604+
3605+ unshapeInput ();
3606+ fws->removeWindowFromList (mInput);
3607+
3608+ delete mInput;
3609+ mInput = NULL;
3610+
3611+ return false;
3612+ }
3613+ else if (mTransformed && !mInput)
3614+ {
3615+ mInput = new FWWindowInputInfo (window);
3616+ if (!mInput)
3617+ return false;
3618+
3619+ shapeInput ();
3620+ createIPW ();
3621+ fws->addWindowToList (mInput);
3622+ }
3623+
3624+ return true;
3625+}
3626+
3627+/* Shape the input of the window when scaled.
3628+ * Since the IPW will be dealing with the input, removing input
3629+ * from the window entirely is a perfectly good solution. */
3630+void
3631+FWWindow::shapeInput ()
3632+{
3633+ Window frame;
3634+ Display *dpy = screen->dpy();
3635+
3636+ saveInputShape (&mInput->inputRects,
3637+ &mInput->nInputRects,
3638+ &mInput->inputRectOrdering);
3639+
3640+ frame = window->frame();
3641+ if (frame)
3642+ {
3643+ saveInputShape (&mInput->frameInputRects, &mInput->frameNInputRects,
3644+ &mInput->frameInputRectOrdering);
3645+ }
3646+ else
3647+ {
3648+ mInput->frameInputRects = NULL;
3649+ mInput->frameNInputRects = -1;
3650+ mInput->frameInputRectOrdering = 0;
3651+ }
3652+
3653+ /* clear shape */
3654+ XShapeSelectInput (dpy, window->id(), NoEventMask);
3655+ XShapeCombineRectangles (dpy, window->id(), ShapeInput, 0, 0,
3656+ NULL, 0, ShapeSet, 0);
3657+
3658+ if (frame)
3659+ XShapeCombineRectangles (dpy, window->frame(), ShapeInput, 0, 0,
3660+ NULL, 0, ShapeSet, 0);
3661+
3662+ XShapeSelectInput (dpy, window->id(), ShapeNotify);
3663+}
3664+
3665+/* Restores the shape of the window:
3666+ * If the window had a custom shape defined by inputRects then we restore
3667+ * that in order with XShapeCombineRectangles.
3668+ * Most windows have no specific defined shape so we can restore it with
3669+ * setting the shape to a 0x0 mask
3670+ */
3671+void
3672+FWWindow::unshapeInput ()
3673+{
3674+ Display *dpy = screen->dpy ();
3675+
3676+ if (mInput->nInputRects)
3677+ {
3678+ XShapeCombineRectangles (dpy, window->id(), ShapeInput, 0, 0,
3679+ mInput->inputRects, mInput->nInputRects,
3680+ ShapeSet, mInput->inputRectOrdering);
3681+ }
3682+ else
3683+ {
3684+ XShapeCombineMask (dpy, window->id(), ShapeInput, 0, 0, None, ShapeSet);
3685+ }
3686+
3687+ if (mInput->frameNInputRects >= 0)
3688+ {
3689+ if (mInput->frameNInputRects)
3690+ {
3691+ XShapeCombineRectangles (dpy, window->frame(), ShapeInput, 0, 0,
3692+ mInput->frameInputRects,
3693+ mInput->frameNInputRects,
3694+ ShapeSet,
3695+ mInput->frameInputRectOrdering);
3696+ }
3697+ else
3698+ {
3699+ XShapeCombineMask (dpy, window->frame(), ShapeInput, 0, 0, None, ShapeSet);
3700+ }
3701+ }
3702+}
3703
3704=== added file 'plugins/freewins/src/paint.cpp'
3705--- plugins/freewins/src/paint.cpp 1970-01-01 00:00:00 +0000
3706+++ plugins/freewins/src/paint.cpp 2013-02-28 06:12:23 +0000
3707@@ -0,0 +1,527 @@
3708+/**
3709+ * Compiz Fusion Freewins plugin
3710+ *
3711+ * paint.cpp
3712+ *
3713+ * Copyright (C) 2007 Rodolfo Granata <warlock.cc@gmail.com>
3714+ *
3715+ * This program is free software; you can redistribute it and/or
3716+ * modify it under the terms of the GNU General Public License
3717+ * as published by the Free Software Foundation; either version 2
3718+ * of the License, or (at your option) any later version.
3719+ *
3720+ * This program is distributed in the hope that it will be useful,
3721+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3722+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3723+ * GNU General Public License for more details.
3724+ *
3725+ * Author(s):
3726+ * Rodolfo Granata <warlock.cc@gmail.com>
3727+ * Sam Spilsbury <smspillaz@gmail.com>
3728+ *
3729+ * Button binding support and Reset added by:
3730+ * enigma_0Z <enigma.0ZA@gmail.com>
3731+ *
3732+ * Most of the input handling here is based on
3733+ * the shelf plugin by
3734+ * : Kristian Lyngstøl <kristian@bohemians.org>
3735+ * : Danny Baumann <maniac@opencompositing.org>
3736+ *
3737+ * Description:
3738+ *
3739+ * This plugin allows you to freely transform the texture of a window,
3740+ * whether that be rotation or scaling to make better use of screen space
3741+ * or just as a toy.
3742+ *
3743+ * Todo:
3744+ * - Fully implement an input redirection system by
3745+ * finding an inverse matrix, multiplying by it,
3746+ * translating to the actual window co-ords and
3747+ * XSendEvent() the co-ords to the actual window.
3748+ * - Code could be cleaner
3749+ * - Add timestep and speed options to animation
3750+ * - Add window hover-over info via paintOutput : i.e
3751+ * - Resize borders
3752+ * - 'Reset' Button
3753+ * - 'Scale' Button
3754+ * - 'Rotate' Button
3755+ */
3756+
3757+#include "freewins.h"
3758+
3759+
3760+/* ------ Window and Output Painting ------------------------------------*/
3761+
3762+/* Damage util function */
3763+
3764+void
3765+FWWindow::damageArea ()
3766+{
3767+ CompositeScreen::get (screen)->damageRegion (mOutputRect);
3768+}
3769+
3770+/* Animation Prep */
3771+void
3772+FWScreen::preparePaint (int ms)
3773+{
3774+ /* FIXME: should only loop over all windows if at least one animation is running */
3775+ foreach (CompWindow *w, screen->windows ())
3776+ {
3777+ FREEWINS_WINDOW (w);
3778+ float speed = optionGetSpeed ();
3779+ fww->mAnimate.steps = ((float) ms / ((20.1 - speed) * 100));
3780+
3781+ if (fww->mAnimate.steps < 0.005)
3782+ fww->mAnimate.steps = 0.005;
3783+
3784+ /* Animation. We calculate how much increment
3785+ * a window must rotate / scale per paint by
3786+ * using the set destination attributes minus
3787+ * the old attributes divided by the time
3788+ * remaining.
3789+ */
3790+
3791+ /* Don't animate if the window is saved */
3792+ fww->mTransform.angX += (float) fww->mAnimate.steps * (fww->mAnimate.destAngX - fww->mTransform.angX) * speed;
3793+ fww->mTransform.angY += (float) fww->mAnimate.steps * (fww->mAnimate.destAngY - fww->mTransform.angY) * speed;
3794+ fww->mTransform.angZ += (float) fww->mAnimate.steps * (fww->mAnimate.destAngZ - fww->mTransform.angZ) * speed;
3795+
3796+ fww->mTransform.scaleX += (float) fww->mAnimate.steps * (fww->mAnimate.destScaleX - fww->mTransform.scaleX) * speed;
3797+ fww->mTransform.scaleY += (float) fww->mAnimate.steps * (fww->mAnimate.destScaleY - fww->mTransform.scaleY) * speed;
3798+
3799+ if (((fww->mTransform.angX >= fww->mAnimate.destAngX - 0.05 &&
3800+ fww->mTransform.angX <= fww->mAnimate.destAngX + 0.05 ) &&
3801+ (fww->mTransform.angY >= fww->mAnimate.destAngY - 0.05 &&
3802+ fww->mTransform.angY <= fww->mAnimate.destAngY + 0.05 ) &&
3803+ (fww->mTransform.angZ >= fww->mAnimate.destAngZ - 0.05 &&
3804+ fww->mTransform.angZ <= fww->mAnimate.destAngZ + 0.05 ) &&
3805+ (fww->mTransform.scaleX >= fww->mAnimate.destScaleX - 0.00005 &&
3806+ fww->mTransform.scaleX <= fww->mAnimate.destScaleX + 0.00005 ) &&
3807+ (fww->mTransform.scaleY >= fww->mAnimate.destScaleY - 0.00005 &&
3808+ fww->mTransform.scaleY <= fww->mAnimate.destScaleY + 0.00005 )))
3809+ {
3810+ fww->mResetting = FALSE;
3811+
3812+ fww->mTransform.angX = fww->mAnimate.destAngX;
3813+ fww->mTransform.angY = fww->mAnimate.destAngY;
3814+ fww->mTransform.angZ = fww->mAnimate.destAngZ;
3815+ fww->mTransform.scaleX = fww->mAnimate.destScaleX;
3816+ fww->mTransform.scaleY = fww->mAnimate.destScaleY;
3817+
3818+ fww->mTransform.unsnapAngX = fww->mAnimate.destAngX;
3819+ fww->mTransform.unsnapAngY = fww->mAnimate.destAngY;
3820+ fww->mTransform.unsnapAngZ = fww->mAnimate.destAngZ;
3821+ fww->mTransform.unsnapScaleX = fww->mAnimate.destScaleX;
3822+ fww->mTransform.unsnapScaleY = fww->mAnimate.destScaleX;
3823+ }
3824+ //else
3825+ // fww->damageArea ();
3826+ }
3827+
3828+ cScreen->preparePaint (ms);
3829+}
3830+
3831+/* Paint the window rotated or scaled */
3832+bool
3833+FWWindow::glPaint (const GLWindowPaintAttrib &attrib,
3834+ const GLMatrix &transform,
3835+ const CompRegion &region,
3836+ unsigned int mask)
3837+{
3838+
3839+ GLMatrix wTransform (transform);
3840+ int currentCull, invertCull;
3841+ glGetIntegerv (GL_CULL_FACE_MODE, &currentCull);
3842+ invertCull = (currentCull == GL_BACK) ? GL_FRONT : GL_BACK;
3843+
3844+ bool status;
3845+
3846+ FREEWINS_SCREEN (screen);
3847+
3848+ /* Has something happened? */
3849+
3850+ /* Check to see if we are painting on a transformed screen */
3851+ /* Enable this code when we can animate between the two states */
3852+
3853+ if ((mTransform.angX != 0.0 ||
3854+ mTransform.angY != 0.0 ||
3855+ mTransform.angZ != 0.0 ||
3856+ mTransform.scaleX != 1.0 ||
3857+ mTransform.scaleY != 1.0 ||
3858+ mOldWinX != WIN_REAL_X (window) ||
3859+ mOldWinY != WIN_REAL_Y (window)) && fws->optionGetShapeWindowTypes ().evaluate (window))
3860+ {
3861+ mOldWinX = WIN_REAL_X (window);
3862+ mOldWinY = WIN_REAL_Y (window);
3863+
3864+ /* Figure out where our 'origin' is, don't allow the origin to
3865+ * be where we clicked if the window is not grabbed, etc
3866+ */
3867+
3868+ /* Here we duplicate some of the work the openGL does
3869+ * but for different reasons. We have access to the
3870+ * window's transformation matrix, so we will create
3871+ * our own matrix and apply the same transformations
3872+ * to it. From there, we create vectors for each point
3873+ * that we wish to track and multiply them by this
3874+ * matrix to give us the rotated / scaled co-ordinates.
3875+ * From there, we project these co-ordinates onto the flat
3876+ * screen that we have using the OGL viewport, projection
3877+ * matrix and model matrix. Projection gives us three
3878+ * co-ordinates, but we ignore Z and just use X and Y
3879+ * to store in a surrounding rectangle. We can use this
3880+ * surrounding rectangle to make things like shaping and
3881+ * damage a lot more accurate than they used to be.
3882+ */
3883+
3884+ calculateOutputRect ();
3885+
3886+ /* Prepare for transformation by
3887+ * doing any necessary adjustments */
3888+ float autoScaleX = 1.0f;
3889+ float autoScaleY = 1.0f;
3890+
3891+ if (fws->optionGetAutoZoom ())
3892+ {
3893+ float apparantWidth = mOutputRect.width ();
3894+ float apparantHeight = mOutputRect.height ();
3895+
3896+ autoScaleX = (float) WIN_OUTPUT_W (window) / (float) apparantWidth;
3897+ autoScaleY = (float) WIN_OUTPUT_H (window) / (float) apparantHeight;
3898+
3899+ if (autoScaleX >= 1.0f)
3900+ autoScaleX = 1.0f;
3901+ if (autoScaleY >= 1.0f)
3902+ autoScaleY = 1.0f;
3903+
3904+ autoScaleX = autoScaleY = (autoScaleX + autoScaleY) / 2;
3905+
3906+ /* Because we modified the scale after calculating
3907+ * the output rect, we need to recalculate again */
3908+ calculateOutputRect ();
3909+
3910+ }
3911+ /*
3912+ float scaleX = autoScaleX - (1 - mTransform.scaleX);
3913+ float scaleY = autoScaleY - (1 - mTransform.scaleY);
3914+ */
3915+
3916+ /* Actually Transform the window */
3917+ mask |= PAINT_WINDOW_TRANSFORMED_MASK;
3918+
3919+ /* Adjust the window in the matrix to prepare for transformation */
3920+ if (mGrab != grabRotate && mGrab != grabScale)
3921+ {
3922+
3923+ calculateInputOrigin (WIN_REAL_X (window) + WIN_REAL_W (window) / 2.0f,
3924+ WIN_REAL_Y (window) + WIN_REAL_H (window) / 2.0f);
3925+ calculateOutputOrigin (WIN_OUTPUT_X (window) + WIN_OUTPUT_W (window) / 2.0f,
3926+ WIN_OUTPUT_Y (window) + WIN_OUTPUT_H (window) / 2.0f);
3927+ }
3928+
3929+ float adjustX = 0.0f;
3930+ float adjustY = 0.0f;
3931+ fws->modifyMatrix (wTransform,
3932+ mTransform.angX,
3933+ mTransform.angY,
3934+ mTransform.angZ,
3935+ mIMidX, mIMidY , 0.0f,
3936+ mTransform.scaleX,
3937+ mTransform.scaleY,
3938+ 1.0f, adjustX, adjustY, TRUE);
3939+
3940+ /* Create rects for input after we've dealt with output */
3941+ calculateInputRect ();
3942+
3943+ /* Determine if the window is inverted */
3944+ Bool xInvert = FALSE;
3945+ Bool yInvert = FALSE;
3946+
3947+ Bool needsInvert = FALSE;
3948+ float renX = fabs (fmodf (mTransform.angX, 360.0f));
3949+ float renY = fabs (fmodf (mTransform.angY, 360.0f));
3950+
3951+ if (90 < renX && renX < 270)
3952+ xInvert = TRUE;
3953+
3954+ if (90 < renY && renY < 270)
3955+ yInvert = TRUE;
3956+
3957+ if ((xInvert || yInvert) && !(xInvert && yInvert))
3958+ needsInvert = TRUE;
3959+
3960+ if (needsInvert)
3961+ glCullFace (invertCull);
3962+
3963+ status = gWindow->glPaint (attrib, wTransform, region, mask);
3964+
3965+ if (needsInvert)
3966+ glCullFace (currentCull);
3967+
3968+ }
3969+ else
3970+ {
3971+ status = gWindow->glPaint (attrib, wTransform, region, mask);
3972+ }
3973+
3974+ // Check if there are rotated windows
3975+ if (!((mTransform.angX >= 0.0f - 0.05 &&
3976+ mTransform.angX <= 0.0f + 0.05 ) &&
3977+ (mTransform.angY >= 0.0f - 0.05 &&
3978+ mTransform.angY <= 0.0f + 0.05 ) &&
3979+ (mTransform.angZ >= 0.0f - 0.05 &&
3980+ mTransform.angZ <= 0.0f + 0.05 ) &&
3981+ (mTransform.scaleX >= 1.0f - 0.00005 &&
3982+ mTransform.scaleX <= 1.0f + 0.00005 ) &&
3983+ (mTransform.scaleY >= 1.0f - 0.00005 &&
3984+ mTransform.scaleY <= 1.0f + 0.00005 )) && !mTransformed)
3985+ mTransformed = TRUE;
3986+ else if (mTransformed)
3987+ mTransformed = FALSE;
3988+
3989+ /* There is still animation to be done */
3990+ if (!(((mTransform.angX >= mAnimate.destAngX - 0.05 &&
3991+ mTransform.angX <= mAnimate.destAngX + 0.05 ) &&
3992+ (mTransform.angY >= mAnimate.destAngY - 0.05 &&
3993+ mTransform.angY <= mAnimate.destAngY + 0.05 ) &&
3994+ (mTransform.angZ >= mAnimate.destAngZ - 0.05 &&
3995+ mTransform.angZ <= mAnimate.destAngZ + 0.05 ) &&
3996+ (mTransform.scaleX >= mAnimate.destScaleX - 0.00005 &&
3997+ mTransform.scaleX <= mAnimate.destScaleX + 0.00005 ) &&
3998+ (mTransform.scaleY >= mAnimate.destScaleY - 0.00005 &&
3999+ mTransform.scaleY <= mAnimate.destScaleY + 0.00005 ))))
4000+ {
4001+ damageArea ();
4002+ mIsAnimating = TRUE;
4003+ }
4004+ else if (mIsAnimating) /* We're done animating now, and we were animating */
4005+ {
4006+ if (handleWindowInputInfo ())
4007+ adjustIPW ();
4008+ mIsAnimating = FALSE;
4009+ }
4010+
4011+ return status;
4012+}
4013+
4014+/* Paint the window axis help onto the screen */
4015+bool
4016+FWScreen::glPaintOutput (const GLScreenPaintAttrib &attrib,
4017+ const GLMatrix &transform,
4018+ const CompRegion &region,
4019+ CompOutput *output,
4020+ unsigned int mask)
4021+{
4022+ GLMatrix zTransform (transform);
4023+
4024+ if (!mTransformedWindows.empty ())
4025+ mask |= PAINT_SCREEN_WITH_TRANSFORMED_WINDOWS_MASK;
4026+
4027+ bool status = gScreen->glPaintOutput (attrib, transform, region, output, mask);
4028+
4029+ if (mAxisHelp && mHoverWindow)
4030+ {
4031+ int j;
4032+ float x = WIN_REAL_X(mHoverWindow) + WIN_REAL_W(mHoverWindow)/2.0;
4033+ float y = WIN_REAL_Y(mHoverWindow) + WIN_REAL_H(mHoverWindow)/2.0;
4034+
4035+ FREEWINS_WINDOW (mHoverWindow);
4036+
4037+ float zRad = fww->mRadius * (optionGetTdPercent () / 100);
4038+
4039+ bool wasCulled = glIsEnabled (GL_CULL_FACE);
4040+
4041+ zTransform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
4042+
4043+ glPushMatrix ();
4044+ glLoadMatrixf (zTransform.getMatrix ());
4045+
4046+ if (wasCulled)
4047+ glDisable (GL_CULL_FACE);
4048+
4049+ if (optionGetShowCircle () && optionGetRotationAxis () == RotationAxisAlwaysCentre)
4050+ {
4051+ glColor4usv (optionGetCircleColor ());
4052+ glEnable (GL_BLEND);
4053+
4054+ glBegin (GL_POLYGON);
4055+ for (j = 0; j < 360; j += 10)
4056+ glVertex3f ( x + zRad * cos(D2R(j)), y + zRad * sin(D2R(j)), 0.0 );
4057+ glEnd ();
4058+
4059+ glDisable (GL_BLEND);
4060+ glColor4usv (optionGetLineColor ());
4061+ glLineWidth (3.0);
4062+
4063+ glBegin (GL_LINE_LOOP);
4064+ for (j = 360; j >= 0; j -= 10)
4065+ glVertex3f ( x + zRad * cos(D2R(j)), y + zRad * sin(D2R(j)), 0.0 );
4066+ glEnd ();
4067+
4068+ glBegin (GL_LINE_LOOP);
4069+ for (j = 360; j >= 0; j -= 10)
4070+ glVertex3f( x + fww->mRadius * cos(D2R(j)), y + fww->mRadius * sin(D2R(j)), 0.0 );
4071+ glEnd ();
4072+
4073+ }
4074+
4075+ /* Draw the 'gizmo' */
4076+ if (optionGetShowGizmo ())
4077+ {
4078+ glPushMatrix ();
4079+
4080+ glTranslatef (x, y, 0.0);
4081+
4082+ glScalef (zRad, zRad, zRad / (float)screen->width ());
4083+
4084+ glRotatef (fww->mTransform.angX, 1.0f, 0.0f, 0.0f);
4085+ glRotatef (fww->mTransform.angY, 0.0f, 1.0f, 0.0f);
4086+ glRotatef (fww->mTransform.angZ, 0.0f, 0.0f, 1.0f);
4087+
4088+ glLineWidth (4.0f);
4089+
4090+ for (int i = 0; i < 3; i++)
4091+ {
4092+ glPushMatrix ();
4093+ glColor4f (1.0 * (i==0), 1.0 * (i==1), 1.0 * (i==2), 1.0);
4094+ glRotatef (90.0, 1.0 * (i==0), 1.0 * (i==1), 1.0 * (i==2));
4095+
4096+ glBegin (GL_LINE_LOOP);
4097+ for (j=360; j>=0; j -= 10)
4098+ glVertex3f ( cos (D2R (j)), sin (D2R (j)), 0.0 );
4099+ glEnd ();
4100+ glPopMatrix ();
4101+ }
4102+
4103+ glPopMatrix ();
4104+ glColor4usv (defaultColor);
4105+ }
4106+
4107+ /* Draw the bounding box */
4108+ if (optionGetShowRegion ())
4109+ {
4110+ glDisableClientState (GL_TEXTURE_COORD_ARRAY);
4111+ glEnable (GL_BLEND);
4112+ glColor4us (0x2fff, 0x2fff, 0x4fff, 0x4fff);
4113+ glRecti (fww->mInputRect.x1 (), fww->mInputRect.y1 (), fww->mInputRect.x2 (), fww->mInputRect.y2 ());
4114+ glColor4us (0x2fff, 0x2fff, 0x4fff, 0x9fff);
4115+ glBegin (GL_LINE_LOOP);
4116+ glVertex2i (fww->mInputRect.x1 (), fww->mInputRect.y1 ());
4117+ glVertex2i (fww->mInputRect.x2 (), fww->mInputRect.y1 ());
4118+ glVertex2i (fww->mInputRect.x1 (), fww->mInputRect.y2 ());
4119+ glVertex2i (fww->mInputRect.x2 (), fww->mInputRect.y2 ());
4120+ glEnd ();
4121+ glColor4usv (defaultColor);
4122+ glDisable (GL_BLEND);
4123+ glEnableClientState (GL_TEXTURE_COORD_ARRAY);
4124+ }
4125+
4126+ if (optionGetShowCross ())
4127+ {
4128+
4129+ glColor4usv (optionGetCrossLineColor ());
4130+ glBegin(GL_LINES);
4131+ glVertex3f(x, y - (WIN_REAL_H (mHoverWindow) / 2), 0.0f);
4132+ glVertex3f(x, y + (WIN_REAL_H (mHoverWindow) / 2), 0.0f);
4133+ glEnd ();
4134+
4135+ glBegin(GL_LINES);
4136+ glVertex3f(x - (WIN_REAL_W (mHoverWindow) / 2), y, 0.0f);
4137+ glVertex3f(x + (WIN_REAL_W (mHoverWindow) / 2), y, 0.0f);
4138+ glEnd ();
4139+
4140+ /* Move to our first corner (TopLeft) */
4141+ if (fww->mInput)
4142+ {
4143+ glBegin(GL_LINES);
4144+ glVertex3f(fww->mOutput.shapex1, fww->mOutput.shapey1, 0.0f);
4145+ glVertex3f(fww->mOutput.shapex2, fww->mOutput.shapey2, 0.0f);
4146+ glEnd ();
4147+
4148+ glBegin(GL_LINES);
4149+ glVertex3f(fww->mOutput.shapex2, fww->mOutput.shapey2, 0.0f);
4150+ glVertex3f(fww->mOutput.shapex4, fww->mOutput.shapey4, 0.0f);
4151+ glEnd ();
4152+
4153+ glBegin(GL_LINES);
4154+ glVertex3f(fww->mOutput.shapex4, fww->mOutput.shapey4, 0.0f);
4155+ glVertex3f(fww->mOutput.shapex3, fww->mOutput.shapey3, 0.0f);
4156+ glEnd ();
4157+
4158+ glBegin(GL_LINES);
4159+ glVertex3f(fww->mOutput.shapex3, fww->mOutput.shapey3, 0.0f);
4160+ glVertex3f(fww->mOutput.shapex1, fww->mOutput.shapey1, 0.0f);
4161+ glEnd ();
4162+ }
4163+ }
4164+ if (wasCulled)
4165+ glEnable(GL_CULL_FACE);
4166+
4167+ glColor4usv(defaultColor);
4168+ glPopMatrix ();
4169+ }
4170+
4171+ return status;
4172+}
4173+
4174+void
4175+FWScreen::donePaint ()
4176+{
4177+
4178+ if (mAxisHelp && mHoverWindow)
4179+ {
4180+ FREEWINS_WINDOW (mHoverWindow);
4181+
4182+ REGION region;
4183+
4184+ region.rects = &region.extents;
4185+ region.numRects = region.size = 1;
4186+
4187+ region.extents.x1 = MIN (WIN_REAL_X (mHoverWindow),
4188+ WIN_REAL_X (mHoverWindow)
4189+ + WIN_REAL_W (mHoverWindow)
4190+ / 2.0f - fww->mRadius);
4191+ region.extents.x2 = MAX (WIN_REAL_X (mHoverWindow),
4192+ WIN_REAL_X (mHoverWindow)
4193+ + WIN_REAL_W (mHoverWindow)
4194+ / 2.0f + fww->mRadius);
4195+
4196+ region.extents.y1 = MIN (WIN_REAL_Y (mHoverWindow),
4197+ WIN_REAL_Y (mHoverWindow)
4198+ + WIN_REAL_H (mHoverWindow)
4199+ / 2.0f - fww->mRadius);
4200+ region.extents.y2 = MAX (WIN_REAL_Y (mHoverWindow),
4201+ WIN_REAL_Y (mHoverWindow)
4202+ + WIN_REAL_H (mHoverWindow)
4203+ / 2.0f + fww->mRadius);
4204+
4205+ CompRegion damageRegion (region.extents.x1, region.extents.y1, region.extents.x2 - region.extents.x1, region.extents.y2 - region.extents.y1);
4206+
4207+ cScreen->damageRegion (damageRegion);
4208+ }
4209+
4210+ cScreen->donePaint ();
4211+}
4212+
4213+/* Damage the Window Rect */
4214+bool
4215+FWWindow::damageRect (bool initial,
4216+ const CompRect &rect)
4217+{
4218+ FREEWINS_SCREEN(screen);
4219+
4220+ if (mTransformed)
4221+ damageArea ();
4222+
4223+ /**
4224+ * Special situations where we must damage the screen
4225+ * i.e when we are playing with windows and wobbly is
4226+ * enabled
4227+ */
4228+
4229+ if ((mGrab == grabMove && !fws->optionGetImmediateMoves ())
4230+ || (mIsAnimating || window->grabbed ()))
4231+ fws->cScreen->damageScreen ();
4232+
4233+ return cWindow->damageRect (initial, rect);
4234+}
4235
4236=== added file 'plugins/freewins/src/util.cpp'
4237--- plugins/freewins/src/util.cpp 1970-01-01 00:00:00 +0000
4238+++ plugins/freewins/src/util.cpp 2013-02-28 06:12:23 +0000
4239@@ -0,0 +1,526 @@
4240+/**
4241+ * Compiz Fusion Freewins plugin
4242+ *
4243+ * util.cpp
4244+ *
4245+ * Copyright (C) 2007 Rodolfo Granata <warlock.cc@gmail.com>
4246+ *
4247+ * This program is free software; you can redistribute it and/or
4248+ * modify it under the terms of the GNU General Public License
4249+ * as published by the Free Software Foundation; either version 2
4250+ * of the License, or (at your option) any later version.
4251+ *
4252+ * This program is distributed in the hope that it will be useful,
4253+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4254+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4255+ * GNU General Public License for more details.
4256+ *
4257+ * Author(s):
4258+ * Rodolfo Granata <warlock.cc@gmail.com>
4259+ * Sam Spilsbury <smspillaz@gmail.com>
4260+ *
4261+ * Button binding support and Reset added by:
4262+ * enigma_0Z <enigma.0ZA@gmail.com>
4263+ *
4264+ * Most of the input handling here is based on
4265+ * the shelf plugin by
4266+ * : Kristian Lyngstøl <kristian@bohemians.org>
4267+ * : Danny Baumann <maniac@opencompositing.org>
4268+ *
4269+ * Description:
4270+ *
4271+ * This plugin allows you to freely transform the texture of a window,
4272+ * whether that be rotation or scaling to make better use of screen space
4273+ * or just as a toy.
4274+ *
4275+ * Todo:
4276+ * - Fully implement an input redirection system by
4277+ * finding an inverse matrix, multiplying by it,
4278+ * translating to the actual window co-ords and
4279+ * XSendEvent() the co-ords to the actual window.
4280+ * - Code could be cleaner
4281+ * - Add timestep and speed options to animation
4282+ * - Add window hover-over info via paintOutput : i.e
4283+ * - Resize borders
4284+ * - 'Reset' Button
4285+ * - 'Scale' Button
4286+ * - 'Rotate' Button
4287+ */
4288+
4289+#include "freewins.h"
4290+
4291+
4292+/* ------ Utility Functions ---------------------------------------------*/
4293+
4294+/* Rotate and project individual vectors */
4295+void
4296+FWScreen::rotateProjectVector (GLVector &vector,
4297+ GLMatrix &transform,
4298+ GLdouble *resultX,
4299+ GLdouble *resultY,
4300+ GLdouble *resultZ)
4301+{
4302+ vector = transform * vector;
4303+
4304+ GLint viewport[4]; // Viewport
4305+ GLdouble modelview[16]; // Modelview Matrix
4306+ GLdouble projection[16]; // Projection Matrix
4307+
4308+ glGetIntegerv (GL_VIEWPORT, viewport);
4309+ glGetDoublev (GL_MODELVIEW_MATRIX, modelview);
4310+ glGetDoublev (GL_PROJECTION_MATRIX, projection);
4311+
4312+ gluProject (vector[GLVector::x], vector[GLVector::y], vector[GLVector::z],
4313+ modelview, projection, viewport,
4314+ resultX, resultY, resultZ);
4315+
4316+ /* Y must be negated */
4317+ *resultY = screen->height () - *resultY;
4318+}
4319+
4320+/* Scales z by 0 and does perspective distortion so that it
4321+ * looks the same wherever on the screen
4322+ *
4323+ * This code taken from animation.c,
4324+ * Copyright (c) 2006 Erkin Bahceci
4325+ */
4326+void
4327+FWScreen::perspectiveDistortAndResetZ (GLMatrix &transform)
4328+{
4329+ float v = -1.0 / ::screen->width ();
4330+ /*
4331+ This does
4332+ transform = M * transform, where M is
4333+ 1, 0, 0, 0,
4334+ 0, 1, 0, 0,
4335+ 0, 0, 0, v,
4336+ 0, 0, 0, 1
4337+ */
4338+
4339+ transform[8] = v * transform[12];
4340+ transform[9] = v * transform[13];
4341+ transform[10] = v * transform[14];
4342+ transform[11] = v * transform[15];
4343+}
4344+
4345+void
4346+FWScreen::modifyMatrix (GLMatrix &transform,
4347+ float angX, float angY, float angZ,
4348+ float tX, float tY, float tZ,
4349+ float scX, float scY, float scZ,
4350+ float adjustX, float adjustY, bool paint)
4351+{
4352+ /* Create our transformation Matrix */
4353+ transform.translate (tX, tY, 0.0);
4354+ if (paint)
4355+ perspectiveDistortAndResetZ (transform);
4356+ else
4357+ transform.scale (1.0f, 1.0f, 1.0f / screen->width ());
4358+ transform.rotate (angX, 1.0f, 0.0f, 0.0f);
4359+ transform.rotate (angY, 0.0f, 1.0f, 0.0f);
4360+ transform.rotate (angZ, 0.0f, 0.0f, 1.0f);
4361+ transform.scale (scX, 1.0f, 0.0f);
4362+ transform.scale (1.0f, scY, 0.0f);
4363+ transform.translate (-(tX), -(tY), 0.0f);
4364+}
4365+
4366+/*
4367+static float det3(float m00, float m01, float m02,
4368+ float m10, float m11, float m12,
4369+ float m20, float m21, float m22)
4370+{
4371+ float ret = 0.0;
4372+
4373+ ret += m00 * m11 * m22 - m21 * m12 * m00;
4374+ ret += m01 * m12 * m20 - m22 * m10 * m01;
4375+ ret += m02 * m10 * m21 - m20 * m11 * m02;
4376+
4377+ return ret;
4378+}
4379+
4380+static void FWFindInverseMatrix(CompTransform *m, CompTransform *r)
4381+{
4382+ float *mm = m->m;
4383+ float d, c[16];
4384+
4385+ d = mm[0] * det3(mm[5], mm[6], mm[7],
4386+ mm[9], mm[10], mm[11],
4387+ mm[13], mm[14], mm[15]) -
4388+
4389+ mm[1] * det3(mm[4], mm[6], mm[7],
4390+ mm[8], mm[10], mm[11],
4391+ mm[12], mm[14], mm[15]) +
4392+
4393+ mm[2] * det3(mm[4], mm[5], mm[7],
4394+ mm[8], mm[9], mm[11],
4395+ mm[12], mm[13], mm[15]) -
4396+
4397+ mm[3] * det3(mm[4], mm[5], mm[6],
4398+ mm[8], mm[9], mm[10],
4399+ mm[12], mm[13], mm[14]);
4400+
4401+ c[0] = det3(mm[5], mm[6], mm[7],
4402+ mm[9], mm[10], mm[11],
4403+ mm[13], mm[14], mm[15]);
4404+ c[1] = -det3(mm[4], mm[6], mm[7],
4405+ mm[8], mm[10], mm[11],
4406+ mm[12], mm[14], mm[15]);
4407+ c[2] = det3(mm[4], mm[5], mm[7],
4408+ mm[8], mm[9], mm[11],
4409+ mm[12], mm[13], mm[15]);
4410+ c[3] = -det3(mm[4], mm[5], mm[6],
4411+ mm[8], mm[9], mm[10],
4412+ mm[12], mm[13], mm[14]);
4413+
4414+ c[4] = -det3(mm[1], mm[2], mm[3],
4415+ mm[9], mm[10], mm[11],
4416+ mm[13], mm[14], mm[15]);
4417+ c[5] = det3(mm[0], mm[2], mm[3],
4418+ mm[8], mm[10], mm[11],
4419+ mm[12], mm[14], mm[15]);
4420+ c[6] = -det3(mm[0], mm[1], mm[3],
4421+ mm[8], mm[9], mm[11],
4422+ mm[12], mm[13], mm[15]);
4423+ c[7] = det3(mm[0], mm[1], mm[2],
4424+ mm[8], mm[9], mm[10],
4425+ mm[12], mm[13], mm[14]);
4426+
4427+ c[8] = det3(mm[1], mm[2], mm[3],
4428+ mm[5], mm[6], mm[7],
4429+ mm[13], mm[14], mm[15]);
4430+ c[9] = -det3(mm[0], mm[2], mm[3],
4431+ mm[4], mm[6], mm[7],
4432+ mm[12], mm[14], mm[15]);
4433+ c[10] = det3(mm[0], mm[1], mm[3],
4434+ mm[4], mm[5], mm[7],
4435+ mm[12], mm[13], mm[15]);
4436+ c[11] = -det3(mm[0], mm[1], mm[2],
4437+ mm[4], mm[5], mm[6],
4438+ mm[12], mm[13], mm[14]);
4439+
4440+ c[12] = -det3(mm[1], mm[2], mm[3],
4441+ mm[5], mm[6], mm[7],
4442+ mm[9], mm[10], mm[11]);
4443+ c[13] = det3(mm[0], mm[2], mm[3],
4444+ mm[4], mm[6], mm[7],
4445+ mm[8], mm[10], mm[11]);
4446+ c[14] = -det3(mm[0], mm[1], mm[3],
4447+ mm[4], mm[5], mm[7],
4448+ mm[8], mm[9], mm[11]);
4449+ c[15] = det3(mm[0], mm[1], mm[2],
4450+ mm[4], mm[5], mm[6],
4451+ mm[8], mm[9], mm[10]);
4452+
4453+ r->m[0] = c[0] / d;
4454+ r->m[1] = c[4] / d;
4455+ r->m[2] = c[8] / d;
4456+ r->m[3] = c[12] / d;
4457+
4458+ r->m[4] = c[1] / d;
4459+ r->m[5] = c[5] / d;
4460+ r->m[6] = c[9] / d;
4461+ r->m[7] = c[13] / d;
4462+
4463+ r->m[8] = c[2] / d;
4464+ r->m[9] = c[6] / d;
4465+ r->m[10] = c[10] / d;
4466+ r->m[11] = c[14] / d;
4467+
4468+ r->m[12] = c[3] / d;
4469+ r->m[13] = c[7] / d;
4470+ r->m[14] = c[11] / d;
4471+ r->m[15] = c[15] / d;
4472+
4473+ return;
4474+}
4475+*/
4476+
4477+/* Create a rect from 4 screen points */
4478+CompRect
4479+FWScreen::createSizedRect (float xScreen1,
4480+ float xScreen2,
4481+ float xScreen3,
4482+ float xScreen4,
4483+ float yScreen1,
4484+ float yScreen2,
4485+ float yScreen3,
4486+ float yScreen4)
4487+{
4488+ /* Left most point */
4489+ float leftmost = xScreen1;
4490+
4491+ if (xScreen2 <= leftmost)
4492+ leftmost = xScreen2;
4493+
4494+ if (xScreen3 <= leftmost)
4495+ leftmost = xScreen3;
4496+
4497+ if (xScreen4 <= leftmost)
4498+ leftmost = xScreen4;
4499+
4500+ /* Right most point */
4501+ float rightmost = xScreen1;
4502+
4503+ if (xScreen2 >= rightmost)
4504+ rightmost = xScreen2;
4505+
4506+ if (xScreen3 >= rightmost)
4507+ rightmost = xScreen3;
4508+
4509+ if (xScreen4 >= rightmost)
4510+ rightmost = xScreen4;
4511+
4512+ /* Top most point */
4513+ float topmost = yScreen1;
4514+
4515+ if (yScreen2 <= topmost)
4516+ topmost = yScreen2;
4517+
4518+ if (yScreen3 <= topmost)
4519+ topmost = yScreen3;
4520+
4521+ if (yScreen4 <= topmost)
4522+ topmost = yScreen4;
4523+
4524+ /* Bottom most point */
4525+ float bottommost = yScreen1;
4526+
4527+ if (yScreen2 >= bottommost)
4528+ bottommost = yScreen2;
4529+
4530+ if (yScreen3 >= bottommost)
4531+ bottommost = yScreen3;
4532+
4533+ if (yScreen4 >= bottommost)
4534+ bottommost = yScreen4;
4535+/*
4536+ Box rect;
4537+ rect.x1 = leftmost;
4538+ rect.x2 = rightmost;
4539+ rect.y1 = topmost;
4540+ rect.y2 = bottommost;
4541+*/
4542+ return CompRect (leftmost, topmost, rightmost - leftmost, bottommost - topmost);
4543+}
4544+
4545+CompRect
4546+FWWindow::calculateWindowRect (GLVector c1,
4547+ GLVector c2,
4548+ GLVector c3,
4549+ GLVector c4)
4550+{
4551+ FREEWINS_SCREEN (screen);
4552+
4553+ GLMatrix transform;
4554+ GLdouble xScreen1 = 0.0f, yScreen1 = 0.0f, zScreen1 = 0.0f;
4555+ GLdouble xScreen2 = 0.0f, yScreen2 = 0.0f, zScreen2 = 0.0f;
4556+ GLdouble xScreen3 = 0.0f, yScreen3 = 0.0f, zScreen3 = 0.0f;
4557+ GLdouble xScreen4 = 0.0f, yScreen4 = 0.0f, zScreen4 = 0.0f;
4558+
4559+ transform.reset ();
4560+ fws->modifyMatrix (transform,
4561+ mTransform.angX,
4562+ mTransform.angY,
4563+ mTransform.angZ,
4564+ mIMidX, mIMidY, 0.0f,
4565+ mTransform.scaleX,
4566+ mTransform.scaleY, 0.0f, 0.0f, 0.0f, false);
4567+
4568+ fws->rotateProjectVector(c1, transform, &xScreen1, &yScreen1, &zScreen1);
4569+ fws->rotateProjectVector(c2, transform, &xScreen2, &yScreen2, &zScreen2);
4570+ fws->rotateProjectVector(c3, transform, &xScreen3, &yScreen3, &zScreen3);
4571+ fws->rotateProjectVector(c4, transform, &xScreen4, &yScreen4, &zScreen4);
4572+
4573+ /* Save the non-rectangular points so that we can shape the rectangular IPW */
4574+
4575+ mOutput.shapex1 = xScreen1;
4576+ mOutput.shapex2 = xScreen2;
4577+ mOutput.shapex3 = xScreen3;
4578+ mOutput.shapex4 = xScreen4;
4579+ mOutput.shapey1 = yScreen1;
4580+ mOutput.shapey2 = yScreen2;
4581+ mOutput.shapey3 = yScreen3;
4582+ mOutput.shapey4 = yScreen4;
4583+
4584+
4585+ return fws->createSizedRect(xScreen1, xScreen2, xScreen3, xScreen4,
4586+ yScreen1, yScreen2, yScreen3, yScreen4);
4587+}
4588+
4589+void
4590+FWWindow::calculateOutputRect ()
4591+{
4592+ GLVector corner1 = GLVector (WIN_OUTPUT_X (window), WIN_OUTPUT_Y (window), 1.0f, 1.0f);
4593+ GLVector corner2 = GLVector (WIN_OUTPUT_X (window) + WIN_OUTPUT_W (window), WIN_OUTPUT_Y (window), 1.0f, 1.0f);
4594+ GLVector corner3 = GLVector (WIN_OUTPUT_X (window), WIN_OUTPUT_Y (window) + WIN_OUTPUT_H (window), 1.0f, 1.0f);
4595+ GLVector corner4 = GLVector (WIN_OUTPUT_X (window) + WIN_OUTPUT_W (window), WIN_OUTPUT_Y (window) + WIN_OUTPUT_H (window), 1.0f, 1.0f);
4596+
4597+ mOutputRect = calculateWindowRect (corner1, corner2, corner3, corner4);
4598+}
4599+
4600+void
4601+FWWindow::calculateInputRect ()
4602+{
4603+ GLVector corner1 = GLVector (WIN_REAL_X (window), WIN_REAL_Y (window), 1.0f, 1.0f);
4604+ GLVector corner2 = GLVector (WIN_REAL_X (window) + WIN_REAL_W (window), WIN_REAL_Y (window), 1.0f, 1.0f);
4605+ GLVector corner3 = GLVector (WIN_REAL_X (window), WIN_REAL_Y (window) + WIN_REAL_H (window), 1.0f, 1.0f);
4606+ GLVector corner4 = GLVector (WIN_REAL_X (window) + WIN_REAL_W (window), WIN_REAL_Y (window) + WIN_REAL_H (window), 1.0f, 1.0f);
4607+
4608+ mInputRect = calculateWindowRect (corner1, corner2, corner3, corner4);
4609+}
4610+
4611+void
4612+FWWindow::calculateInputOrigin (float x, float y)
4613+{
4614+ mIMidX = x;
4615+ mIMidY = y;
4616+}
4617+
4618+void
4619+FWWindow::calculateOutputOrigin (float x, float y)
4620+{
4621+ float dx, dy;
4622+
4623+ dx = x - WIN_OUTPUT_X (window);
4624+ dy = y - WIN_OUTPUT_Y (window);
4625+
4626+ mOMidX = WIN_OUTPUT_X (window) + dx * mTransform.scaleX;
4627+ mOMidY = WIN_OUTPUT_Y (window) + dy * mTransform.scaleY;
4628+}
4629+
4630+/* Change angles more than 360 into angles out of 360 */
4631+/*static int FWMakeIntoOutOfThreeSixty (int value)
4632+{
4633+ while (value > 0)
4634+ {
4635+ value -= 360;
4636+ }
4637+
4638+ if (value < 0)
4639+ value += 360;
4640+
4641+ return value;
4642+}*/
4643+
4644+/* Determine if we clicked in the z-axis region */
4645+void
4646+FWWindow::determineZAxisClick (int px,
4647+ int py,
4648+ bool motion)
4649+{
4650+ bool directionChange = FALSE;
4651+
4652+ if (!mCan2D && motion)
4653+ {
4654+
4655+ static int steps;
4656+
4657+ /* Check if we are going in a particular 3D direction
4658+ * because if we are going left/right and we suddenly
4659+ * change to 2D mode this would not be expected behaviour.
4660+ * It is only if we have a change in direction that we want
4661+ * to change to 2D rotation.
4662+ */
4663+
4664+ Direction direction, oldDirection = LeftRight;
4665+
4666+ static int ddx, ddy;
4667+
4668+ unsigned int dx = pointerX - lastPointerX;
4669+ unsigned int dy = pointerY - lastPointerY;
4670+
4671+ ddx += dx;
4672+ ddy += dy;
4673+
4674+ if (steps >= 10)
4675+ {
4676+ if (ddx > ddy)
4677+ direction = LeftRight;
4678+ else
4679+ direction = UpDown;
4680+
4681+ if (direction != oldDirection)
4682+ directionChange = TRUE;
4683+
4684+ direction = oldDirection;
4685+ }
4686+
4687+ steps++;
4688+
4689+ }
4690+ else
4691+ directionChange = TRUE;
4692+
4693+ if (directionChange)
4694+ {
4695+ float clickRadiusFromCenter;
4696+
4697+ int x = (WIN_REAL_X(window) + WIN_REAL_W(window)/2.0);
4698+ int y = (WIN_REAL_Y(window) + WIN_REAL_H(window)/2.0);
4699+
4700+ clickRadiusFromCenter = sqrt(pow((x - px), 2) + pow((y - py), 2));
4701+
4702+ if (clickRadiusFromCenter > mRadius * (FWScreen::get (screen)->optionGetTdPercent () / 100))
4703+ {
4704+ mCan2D = TRUE;
4705+ mCan3D = FALSE;
4706+ }
4707+ else
4708+ {
4709+ mCan2D = FALSE;
4710+ mCan3D = TRUE;
4711+ }
4712+ }
4713+}
4714+
4715+/* Check to see if we can shape a window */
4716+bool
4717+FWWindow::canShape ()
4718+{
4719+ FREEWINS_SCREEN (screen);
4720+
4721+ if (!fws->optionGetDoShapeInput ())
4722+ return FALSE;
4723+
4724+ if (!screen->XShape ())
4725+ return FALSE;
4726+
4727+ if (!fws->optionGetShapeWindowTypes ().evaluate (window))
4728+ return FALSE;
4729+
4730+ return TRUE;
4731+}
4732+
4733+/* Checks if w is a ipw and returns the real window */
4734+CompWindow *
4735+FWScreen::getRealWindow (CompWindow *w)
4736+{
4737+ FWWindowInputInfo *info;
4738+
4739+ foreach (info, mTransformedWindows)
4740+ {
4741+ if (w->id () == info->ipw)
4742+ return info->w;
4743+ }
4744+
4745+ return NULL;
4746+}
4747+
4748+void
4749+FWWindow::handleSnap ()
4750+{
4751+ FREEWINS_SCREEN (screen);
4752+
4753+ /* Handle Snapping */
4754+ if (fws->optionGetSnap () || fws->mSnap)
4755+ {
4756+ int snapFactor = fws->optionGetSnapThreshold ();
4757+ mAnimate.destAngX = ((int) (mTransform.unsnapAngX) / snapFactor) * snapFactor;
4758+ mAnimate.destAngY = ((int) (mTransform.unsnapAngY) / snapFactor) * snapFactor;
4759+ mAnimate.destAngZ = ((int) (mTransform.unsnapAngZ) / snapFactor) * snapFactor;
4760+ mTransform.scaleX =
4761+ ((float) ( (int) (mTransform.unsnapScaleX * (21 - snapFactor) + 0.5))) / (21 - snapFactor);
4762+ mTransform.scaleY =
4763+ ((float) ( (int) (mTransform.unsnapScaleY * (21 - snapFactor) + 0.5))) / (21 - snapFactor);
4764+ }
4765+}

Subscribers

People subscribed via source and target branches