Compare commits
	
		
			73 Commits
		
	
	
		
			3.6.0
			...
			wip/multit
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					bdfb8609a3 | ||
| 
						 | 
					141a353a52 | ||
| 
						 | 
					15186016c2 | ||
| 
						 | 
					bd77a67ea4 | ||
| 
						 | 
					2a9a499841 | ||
| 
						 | 
					50aa509ee1 | ||
| 
						 | 
					0eefb6b306 | ||
| 
						 | 
					d115c90ed1 | ||
| 
						 | 
					83096642f0 | ||
| 
						 | 
					a65c4e993e | ||
| 
						 | 
					e73a566eeb | ||
| 
						 | 
					46ef055da5 | ||
| 
						 | 
					45450c2fa3 | ||
| 
						 | 
					afa4c643a8 | ||
| 
						 | 
					5d1c302b18 | ||
| 
						 | 
					53b289ce25 | ||
| 
						 | 
					776628fde2 | ||
| 
						 | 
					b9f5185c90 | ||
| 
						 | 
					7555b092eb | ||
| 
						 | 
					f46ef5f6e0 | ||
| 
						 | 
					0e182c7c3d | ||
| 
						 | 
					84b9d5c9f9 | ||
| 
						 | 
					8e3b9be79c | ||
| 
						 | 
					74520ab20b | ||
| 
						 | 
					40c2b0c5bb | ||
| 
						 | 
					40ec37eed0 | ||
| 
						 | 
					4e6e40de87 | ||
| 
						 | 
					319208f859 | ||
| 
						 | 
					f670a4f348 | ||
| 
						 | 
					57dff10ab5 | ||
| 
						 | 
					53bd0c70c9 | ||
| 
						 | 
					2507d20bb7 | ||
| 
						 | 
					7d5e7ec3e6 | ||
| 
						 | 
					0b8848057b | ||
| 
						 | 
					0b841f8940 | ||
| 
						 | 
					61b120d08c | ||
| 
						 | 
					2aa39eb4fd | ||
| 
						 | 
					dc5b813608 | ||
| 
						 | 
					df044a0035 | ||
| 
						 | 
					154730a3d9 | ||
| 
						 | 
					557ed7ac0b | ||
| 
						 | 
					bce2bc0568 | ||
| 
						 | 
					7c86cb85ba | ||
| 
						 | 
					ab58d87142 | ||
| 
						 | 
					e62076f055 | ||
| 
						 | 
					1e8f10826a | ||
| 
						 | 
					cca79a77da | ||
| 
						 | 
					67018d2d04 | ||
| 
						 | 
					199395a395 | ||
| 
						 | 
					ad911d6cce | ||
| 
						 | 
					daeaf44e02 | ||
| 
						 | 
					ec587190e8 | ||
| 
						 | 
					22a44bf007 | ||
| 
						 | 
					e1679cb35b | ||
| 
						 | 
					5da2ff0f4e | ||
| 
						 | 
					a547596be4 | ||
| 
						 | 
					bb7d549136 | ||
| 
						 | 
					e800da2bca | ||
| 
						 | 
					3def650a93 | ||
| 
						 | 
					48f59d88fa | ||
| 
						 | 
					01e77bae9d | ||
| 
						 | 
					66e9720cb7 | ||
| 
						 | 
					3a8837f8ab | ||
| 
						 | 
					cc4f66bc8a | ||
| 
						 | 
					90287cb3f6 | ||
| 
						 | 
					0c317e8ced | ||
| 
						 | 
					33c829ee39 | ||
| 
						 | 
					e92757ac8b | ||
| 
						 | 
					08f06ba012 | ||
| 
						 | 
					e49cbb3614 | ||
| 
						 | 
					98e95ed5e8 | ||
| 
						 | 
					5338134b49 | ||
| 
						 | 
					f5aab9398b | 
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -19,7 +19,6 @@ libtool
 | 
			
		||||
ltmain.sh
 | 
			
		||||
missing
 | 
			
		||||
.deps
 | 
			
		||||
src/50-mutter-windows.xml
 | 
			
		||||
src/mutter-wm.desktop
 | 
			
		||||
src/mutter.desktop
 | 
			
		||||
*.o
 | 
			
		||||
@@ -49,8 +48,7 @@ libmutter.pc
 | 
			
		||||
mutter
 | 
			
		||||
mutter-theme-viewer
 | 
			
		||||
mutter.desktop
 | 
			
		||||
org.gnome.mutter.gschema.valid
 | 
			
		||||
org.gnome.mutter.gschema.xml
 | 
			
		||||
mutter.schemas
 | 
			
		||||
testasyncgetprop
 | 
			
		||||
testboxes
 | 
			
		||||
testgradient
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								HACKING
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								HACKING
									
									
									
									
									
								
							@@ -42,10 +42,10 @@ Minimal Building/Testing Environment
 | 
			
		||||
  build a development version of Metacity -- odds are, you may be able
 | 
			
		||||
  to build metacity from CVS without building any other modules.
 | 
			
		||||
 | 
			
		||||
  As long as you have gtk+ >= 3.0 and GIO >= 2.25.10 with your distro
 | 
			
		||||
  (gtk+ >= 2.6 if you manually revert the change from bug 348633), you
 | 
			
		||||
  should be able to install your distro's development packages
 | 
			
		||||
  (e.g. gtk2-devel, glib-devel, startup-notification-devel on
 | 
			
		||||
  As long as you have gtk+ >= 2.10 and GConf with your distro (gtk+ >=
 | 
			
		||||
  2.6 if you manually revert the change from bug 348633), you should
 | 
			
		||||
  be able to install your distro's development packages
 | 
			
		||||
  (e.g. gtk2-devel, GConf2-devel, startup-notification-devel on
 | 
			
		||||
  Fedora; also, remember to install the gnome-common package which is
 | 
			
		||||
  needed for building cvs versions of Gnome modules like Metacity) as
 | 
			
		||||
  well as the standard development tools (gcc, autoconf, automake,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										288
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										288
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,291 +1,3 @@
 | 
			
		||||
3.6.0
 | 
			
		||||
=====
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Alexander Shopov [bg], Daniel Korostil [uk], Rajesh Ranjan [hi],
 | 
			
		||||
  Krishnababu Krothapalli [te], Ani Peter [ml], Rūdolfs Mazurs [lv],
 | 
			
		||||
  Sweta Kothari [gu], Ihar Hrachyshka [be], Noriko Mizumoto [ja],
 | 
			
		||||
  Timo Jyrinki [fi], Mattias Põldaru [et]
 | 
			
		||||
 | 
			
		||||
3.5.92
 | 
			
		||||
======
 | 
			
		||||
* screen: Allow NULL out arguments in meta_screen_get_size [Tomeu]
 | 
			
		||||
* display: Add API to set wm_name / wm_keybindings [Florian; #671010]
 | 
			
		||||
* Improve the not responding dialog [Jon, Florian; #684306]
 | 
			
		||||
* Misc. bugfixes [Jasper]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  William Jon McCann, Florian Müllner, Jasper St. Pierre, Tomeu Vizoso
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Gabor Kelemen [hu], Piotr Drąg [pl], Dr.T.Vasudevan [ta], Bruce Cowan [en_GB],
 | 
			
		||||
  Alexandre Franke [fr], Theppitak Karoonboonyanan [th], Gil Forcada [ca],
 | 
			
		||||
  Carles Ferrando [ca@valencia], Tobias Endrigkeit [de], Tom Tryfonidis [el],
 | 
			
		||||
  Nguyễn Thái Ngọc Duy [vi], Changwoo Ryu [ko], Ask H. Larsen [da],
 | 
			
		||||
  Rafael Ferreira [pt_BR], Marek Černocký [cs]
 | 
			
		||||
 | 
			
		||||
3.5.91
 | 
			
		||||
======
 | 
			
		||||
* Do not include markup in app not responding dialog [Alex]
 | 
			
		||||
* Fix subtracting unredirected windows from visible region [Jasper; #677116]
 | 
			
		||||
* Minor improvements and bugfixes [Jasper, Florian; #682648, #682993]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Alexander Larsson, Florian Müllner, Jasper St. Pierre
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Dirgita [id], Piotr Drąg [pl], A S Alam [pa], Yuri Myasoedov [ru],
 | 
			
		||||
  Milo Casagrande [it], Nilamdyuti Goswami [as], Tom Tryfonidis [el],
 | 
			
		||||
  Duarte Loreto [pt], Fran Diéguez [gl], Nguyễn Thái Ngọc Duy [vi],
 | 
			
		||||
  Aurimas Černius [lt], Daniel Nylander [sv]
 | 
			
		||||
 | 
			
		||||
3.5.90
 | 
			
		||||
======
 | 
			
		||||
* Fix logic for handling translations of the windows group [Owen; #681221]
 | 
			
		||||
* Handle painting inside a Clutter clone [Owen; #681953]
 | 
			
		||||
* Update overlay-key on settings changes [Florian; #681906]
 | 
			
		||||
* Add keybinding for overlay-key [Florian; #665547]
 | 
			
		||||
* Minor fixes and improvements [Javier, Florian]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Javier Jardón, Florian Müllner, Owen Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Sweta Kothari [gu], Muhammet Kara [tr], Khaled Hosny [ar],
 | 
			
		||||
  Sandeep Sheshrao Shedmake [mr]
 | 
			
		||||
 | 
			
		||||
3.5.5
 | 
			
		||||
=====
 | 
			
		||||
* Fix flickering around windows when using window group [Tom; #681221]
 | 
			
		||||
 | 
			
		||||
Contributor(s):
 | 
			
		||||
  Tom Beckmann
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Chao-Hsiung Liao [zh_HK, zh_TW], Matej Urbančič [sl], Fran Diéguez [gl],
 | 
			
		||||
  Мирослав Николић [sr, sr@latin], Yaron Shahrabani [he], Kjartan Maraas [nb]
 | 
			
		||||
 | 
			
		||||
3.5.4
 | 
			
		||||
=====
 | 
			
		||||
* Make it possible to reimplement move-to-workspace keybindings from plugins
 | 
			
		||||
  [Giovanni; #674104]
 | 
			
		||||
* Add a preference to ignore hide-titlebar-when-maximized hint [Rico; #678947]
 | 
			
		||||
* window: Also use hide-titlebar-when-maximized when tiled [Florian; #679290]
 | 
			
		||||
* Center modal dialogs on their parent instead [Florian; #674499]
 | 
			
		||||
* Reduce amount of markup in translated messages [Matthias; #679660]
 | 
			
		||||
* Fix focus problem after closing a window with focus-follows-mouse
 | 
			
		||||
  [Jasper; #675982]
 | 
			
		||||
* Handle changes of the attach-modal-dialogs preference [Florian; #679904]
 | 
			
		||||
* Do not restore tiling on unmaximize [Florian; #677565]
 | 
			
		||||
* Misc. fixes and cleanups [Jasper Adriaanse, Jasper, Debarshi, Pavel;
 | 
			
		||||
  #679153, 673824]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Jasper Lievisse Adriaanse, Giovanni Campagna, Matthias Clasen, Florian Müllner,
 | 
			
		||||
 Debarshi Ray, Jasper St. Pierre, Rico Tzschichholz, Pavel Vasin
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 Alexander Shopov [bg], Kjartan Maraas [nb], Yaron Shahrabani [he],
 | 
			
		||||
 Nilamdyuti Goswami [as], Ihar Hrachyshka [be], Daniel Mustieles [es]
 | 
			
		||||
 | 
			
		||||
3.5.3
 | 
			
		||||
=====
 | 
			
		||||
* Simplify plugin system [Jasper; #676855]
 | 
			
		||||
* meta-window-actor: Don't unredirect shaped windows [Jasper; #677657]
 | 
			
		||||
* screen: Add new public meta_screen_get_current_monitor API [Tim; #642591]
 | 
			
		||||
* frames: Increase the size of resize corners [Jasper; #677669]
 | 
			
		||||
* window: Make some window methods public [Jasper; #678126]
 | 
			
		||||
* Fix crash when running mutter stand-alone [Jasper; #678238]
 | 
			
		||||
* meta-window-actor: Fix potential crash in shaping code [Jasper; #677977]
 | 
			
		||||
* Misc. fixes [Jasper, Marc-Antoine, Rico]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Tim L, Marc-Antoine Perennou, Jasper St. Pierre, Rico Tzschichholz
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 | 
			
		||||
 Daniel Mustieles [es], Matej Urbančič [sl], Khaled Hosny [ar],
 | 
			
		||||
 Bruno Brouard [fr], Fran Diéguez [gl]
 | 
			
		||||
 | 
			
		||||
3.5.2
 | 
			
		||||
=====
 | 
			
		||||
* keybindings: Remove 'toggle-recording' binding [Florian; #674376]
 | 
			
		||||
* Switch to gtk-doc syntax [Jasper; #673752]
 | 
			
		||||
* shaped-texture: never slice shape mask texture [Robert; #674731]
 | 
			
		||||
* Make Mutter stop relying on Cogl including a GL header [Neil; #672711]
 | 
			
		||||
* Make support for "XFree86" Xinerama mandatory [Owen; #674727]
 | 
			
		||||
* meta_window_move_frame(): fix crash when frame is NULL [Owen; #675254]
 | 
			
		||||
* Fix memory leaks [Pavel; #672640]
 | 
			
		||||
* Code cleanups [Jasper; #671104 #674876 #676052]
 | 
			
		||||
* Look for themes in XDG user data dir [Jasper; #675316]
 | 
			
		||||
* Remove frame pixel caching [Jasper; #675111]
 | 
			
		||||
* stack: Ignore keep-on-top property on maximized windows [Florian; #673581]
 | 
			
		||||
* Misc. fixes [Javier, Jasper, Owen, Rico]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Robert Bragg, Javier Járdon, Florian Müllner, Neil Roberts, Jasper St. Pierre, 
 | 
			
		||||
 Owen Taylor, Rico Tzschichholz, Pavel Vasin
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 Praveen Illa [te], Luca Ferretti [it], Daniel Mustieles [es]
 | 
			
		||||
 | 
			
		||||
3.4.1
 | 
			
		||||
=====
 | 
			
		||||
* API change: the meta_display_add_keybinding() function added in 3.4
 | 
			
		||||
  wasn't usable from a GNOME Shell extension, so has been changed to take
 | 
			
		||||
  a GSettings object rather than the name of a schema [Jasper; #673014]
 | 
			
		||||
* Don't try to auto-maximize not-maximizable windows; this fixes the problem
 | 
			
		||||
  with the Nautilus desktop window being mis-positioned when enabled
 | 
			
		||||
  [Owen; #673566]
 | 
			
		||||
* Fix a crash in the default plugin (not used in GNOME) [Giovanni; #673809]
 | 
			
		||||
* Make the <Super> key work when set as the mouse button modifier
 | 
			
		||||
  [Florian; #662476]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Giovanni Campagna, Florian Muellner, Jasper St. Pierre, Owen Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 Khaled Hosny [ar], Jordi Serratosa [ca], Carles Ferrando [ca@valencia],
 | 
			
		||||
 Christian Kirbach [de], Kristjan Schmidt [eo], Arash Mousavi [fa],
 | 
			
		||||
 Jiro Matsuzawa [ja], Shankar Prasad [kn], Aurimas Černius [lt],
 | 
			
		||||
 Yinghua Wang [zh_CN]
 | 
			
		||||
 | 
			
		||||
3.4.0
 | 
			
		||||
=====
 | 
			
		||||
* Fix crash when a full-screen window is opened [Jasper; #672797]
 | 
			
		||||
* Fix memory leaks [Pavel; #672640]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Jasper St. Pierre, Pavel Vasin
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 Marek Černocký, Petr Kovar [cz], Bruno Brouard [fr], Sweta Kothari [gu],
 | 
			
		||||
 Yaron Shahrabani [he], Changwoo Ryu [kr], Enrico Nicoletto [pt_BR],
 | 
			
		||||
 Yuri Myasoedov [ru], Muhammet Kara [tr], Nguyễn Thái Ngọc Duy [vi]
 | 
			
		||||
 | 
			
		||||
3.3.92
 | 
			
		||||
======
 | 
			
		||||
* Automaximize large windows on map [Adel; #671677]
 | 
			
		||||
* When unmaximizing windows, make sure the unminimized size
 | 
			
		||||
  is signficantly less than the maximized size [Adel; #671677]
 | 
			
		||||
* Don't offer maximize option for windows larger than the screen
 | 
			
		||||
  [Jasper; #643606]
 | 
			
		||||
* Always focus the window immediately underneath without restacking
 | 
			
		||||
  when closing a window [Jasper; #620744]
 | 
			
		||||
* Avoid drawing shadows when two windows are tiled together [Rui; #643075]
 | 
			
		||||
* Remove tooltips for window decorations [Florian; #645101]
 | 
			
		||||
* Add org.gnome.mutter.dynamic-workspaces GSetting - when this is set
 | 
			
		||||
  to true, workspace counts are never saved to GSettings, avoiding
 | 
			
		||||
  pointless disk traffic for GNOME dynamic workspaces [Florian; #671568]
 | 
			
		||||
* Add ::grab-op-begin, ::grab-op-end signals to MetaDisplay [Jasper; #670658]
 | 
			
		||||
* Add meta_display_get_ignored_modifier_mask() [Florian; #665215]
 | 
			
		||||
* Remove pointless wrapper methods on MetaPlugin [Jasper; #671103]
 | 
			
		||||
* Fix frame drawing with 3.3.x GTK+ releases [Florian; #671796]
 | 
			
		||||
* Build fixes [Jasper, Rico, Rui]
 | 
			
		||||
* Misc bug fixes [Damien, Jasper, Lionel, Marius, Owen, Rui;
 | 
			
		||||
  #661256, #667437, #671601, #671087, #672374]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Stefano Facchini, Adel Gadllah, Lionel Landwerlin, Mariusz Libera,
 | 
			
		||||
 Rui Matos, Florian Müllner, Jasper St. Pierre, Damien Radtke, Owen Taylor,
 | 
			
		||||
 Rico Tzschichholz
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 Nilamdyuti Goswami [as], Ihar Hrachyshka [be], Alexander Shopov [bg],
 | 
			
		||||
 David Planella [ca], Carles Ferrando [ca@valencia], Kenneth Nielsen [dk],
 | 
			
		||||
 Bruce Cowan [en_GB], Daniel Mustieles [es], Mattias Põldaru [et],
 | 
			
		||||
 Inaki Larranaga Murgoitio [eu], Timo Jyrinki [fi], Fran Diéguez [gl],
 | 
			
		||||
 Gabor Kelemen [hu], Changwoo Ryu [ko], Anita Reitere [lv],
 | 
			
		||||
 Kjartan Maraas [nb], Wouter Bolsterlee [nl], A S Alam [pa], Piotr Drąg [pl],
 | 
			
		||||
 Duarte Loreto [pt], Yuri Myasoedov [ru], Daniel Nylander [se],
 | 
			
		||||
 Matej Urbančič [sl], Miroslav Nikolić [sr], Tirumurti Vasudevan [ta],
 | 
			
		||||
 Sasi Bhushan [te], Daniel Korostil [uk], Nguyễn Thái Ngọc Duy [vi],
 | 
			
		||||
 YunQiang Su [zh_CN], Chao-Hsiung Liao [zh_HK, zh_TW]
 | 
			
		||||
 | 
			
		||||
3.3.90
 | 
			
		||||
======
 | 
			
		||||
* Update for Cogl API changes [Robert]
 | 
			
		||||
* Bug fixes [Adel, Jasper;  #659643]
 | 
			
		||||
* Build fixes [Jasper, Owen]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Robert Bragg, Adel Gadllah, Jasper St. Pierre, Owen Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 Ask H. Larsen [dk], Miroslav Nikolić [sr]
 | 
			
		||||
 | 
			
		||||
3.3.5
 | 
			
		||||
=====
 | 
			
		||||
* MetaShapedTexture no longer is a ClutterTexture subclass [Jasper; #660941]
 | 
			
		||||
* Add meta_shaped_texture_get_image() [Jasper; #660941]
 | 
			
		||||
* Cleanups [Rui, Jasper; #657639]
 | 
			
		||||
* Depend on GTK+ 3.3.7 [Rico]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Rui Matos, Jasper St. Pierre, Rico Tzschichholz
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 Kjartan Maraas [nb], Chao-Hsiung Liao [zh_HK, zh_TW]
 | 
			
		||||
 | 
			
		||||
3.3.4
 | 
			
		||||
=====
 | 
			
		||||
* Adapt to changes in GtkStateFlags [Owen]
 | 
			
		||||
* Redo properties for applications menu corresponding to GTK+ changes -
 | 
			
		||||
  they are now _GTK_* not DBUS_*. [Ryan]
 | 
			
		||||
* Fix crash on gnome-shell restart when a modal dialog is open [Owen; #668299]
 | 
			
		||||
* Code cleanup [Florian; #666039]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Ryan Lortie, Florian Müllner, Owen Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 Alexander Shopov [bg], Fran Diéguez [gl]
 | 
			
		||||
 | 
			
		||||
3.3.3
 | 
			
		||||
=====
 | 
			
		||||
* Add keybindings for tiling to left or right [Florian; #648700]
 | 
			
		||||
* Support GTK+'s hide-titlebar-when-maximized hint [Florian; #665617]
 | 
			
		||||
* Load _DBUS_APPLICATION_ID, _DBUS_UNIQUE_NAME, _DBUS_OBJECT_PATH
 | 
			
		||||
  property [Colin, Ryan; #664851]
 | 
			
		||||
* Handle changes to workspaces-only-on-primary GSetting [Florian; #664853]
 | 
			
		||||
* Don't use the Clutter default stage [Jasper; #664028]
 | 
			
		||||
* Fix compilation with --disable-introspection [Lionel; #661871]
 | 
			
		||||
* Fix problem where stage could end up mis-sized on startup with
 | 
			
		||||
  multiple monitors [Lionel]
 | 
			
		||||
* Misc bug fixes [Adel, Lionel, Jasper; #666015]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Adel Gadllah, Lionel Landwerlin, Florian Müllner, Jasper St. Pierre
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 Daniel Mustieles [es], Yaron Shahrabani [he], Kjartan Maraas [nb],
 | 
			
		||||
 Matej Urbančič [sk], Muhammet Kara [tr]
 | 
			
		||||
 | 
			
		||||
3.3.2
 | 
			
		||||
=====
 | 
			
		||||
 | 
			
		||||
* Move from GConf to GSettings for preferences [Florian; #635378]
 | 
			
		||||
* Add meta_display_add_keybinding()/meta_display_remove_keybinding()
 | 
			
		||||
  to allow creating new keybindings at runtime [Florian; #663428]
 | 
			
		||||
* Add suport for new _NET_WM_STATE_FOCUSED atom in _NET_WM_STATE
 | 
			
		||||
  to allow applications to draw unfocused windows differently
 | 
			
		||||
  [Rui; #661427]
 | 
			
		||||
* Add meta_window_move_resize_frame() to allow specifying the
 | 
			
		||||
  size and position of a window via the outside dimensions of the
 | 
			
		||||
  window frame.
 | 
			
		||||
* Don't activate window tiling when moving in snap mode
 | 
			
		||||
  [Rui; #662270]
 | 
			
		||||
* Remove the ability to resize a window from the inner edge of
 | 
			
		||||
  the titlebar [Jasper; #660129]
 | 
			
		||||
* Fix for deprecations in GTK+ [Jasper, Rico; #662574, #662895]
 | 
			
		||||
* Misc bug fixes [Jasper, Rico, Rui; #662895, #642652, #660941, #662225]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
 Tim Cuthbertson, Rui Matos, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
 Jorge González (es), Kjartan Maraas (nb), Krishnababu Krothapalli (te), Nguyễn Thái Ngọc Duy (vi)
 | 
			
		||||
 | 
			
		||||
3.2.1
 | 
			
		||||
=====
 | 
			
		||||
* Allow keyboard window switching (alt-Tab) during drag-and-drop
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								README
									
									
									
									
									
								
							@@ -18,7 +18,8 @@ COMPILING MUTTER
 | 
			
		||||
You need GTK+ 2.2.  For startup notification to work you need
 | 
			
		||||
libstartup-notification at
 | 
			
		||||
http://www.freedesktop.org/software/startup-notification/ or on the
 | 
			
		||||
GNOME ftp site.
 | 
			
		||||
GNOME ftp site. You also need GConf 1.2 (unless building a funky
 | 
			
		||||
extra-small embedded metacity with --disable-gconf, see below).
 | 
			
		||||
You need Clutter 1.0. You need gobject-introspection 0.6.3.
 | 
			
		||||
 | 
			
		||||
REPORTING BUGS AND SUBMITTING PATCHES
 | 
			
		||||
@@ -58,24 +59,25 @@ MUTTER FEATURES
 | 
			
		||||
   and should work with KWin, fvwm2, and other EWMH-compliant WMs.)
 | 
			
		||||
 | 
			
		||||
 - Has a simple theme system and a couple of extra themes come with it.
 | 
			
		||||
   Change themes via gsettings:
 | 
			
		||||
     gsettings set org.gnome.desktop.wm.preferences theme Crux
 | 
			
		||||
     gsettings set org.gnome.desktop.wm.preferences theme Gorilla
 | 
			
		||||
     gsettings set org.gnome.desktop.wm.preferences theme Atlanta
 | 
			
		||||
     gsettings set org.gnome.desktop.wm.preferences theme Bright
 | 
			
		||||
   Change themes via gconf-editor or gconftool or GNOME themes control
 | 
			
		||||
   panel:
 | 
			
		||||
     gconftool-2 --type=string --set /apps/metacity/general/theme Crux
 | 
			
		||||
     gconftool-2 --type=string --set /apps/metacity/general/theme Gorilla
 | 
			
		||||
     gconftool-2 --type=string --set /apps/metacity/general/theme Atlanta
 | 
			
		||||
     gconftool-2 --type=string --set /apps/metacity/general/theme Bright
 | 
			
		||||
 | 
			
		||||
   See theme-format.txt for docs on the theme format. Use 
 | 
			
		||||
   metacity-theme-viewer to preview themes.
 | 
			
		||||
 | 
			
		||||
 - Change number of workspaces via gsettings:
 | 
			
		||||
     gsettings set org.gnome.desktop.wm.preferences num-workspaces 5
 | 
			
		||||
 - Change number of workspaces via gconf-editor or gconftool:
 | 
			
		||||
     gconftool-2 --type=int --set /apps/metacity/general/num_workspaces 5
 | 
			
		||||
 | 
			
		||||
   Can also change workspaces from GNOME 2 pager.
 | 
			
		||||
 | 
			
		||||
 - Change focus mode:
 | 
			
		||||
     gsettings set org.gnome.desktop.wm.preferences focus-mode mouse
 | 
			
		||||
     gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy
 | 
			
		||||
     gsettings set org.gnome.desktop.wm.preferences focus-mode click
 | 
			
		||||
     gconftool-2 --type=string --set /apps/metacity/general/focus_mode mouse
 | 
			
		||||
     gconftool-2 --type=string --set /apps/metacity/general/focus_mode sloppy
 | 
			
		||||
     gconftool-2 --type=string --set /apps/metacity/general/focus_mode click
 | 
			
		||||
 | 
			
		||||
 - Global keybinding defaults include:   
 | 
			
		||||
 | 
			
		||||
@@ -90,9 +92,10 @@ MUTTER FEATURES
 | 
			
		||||
 | 
			
		||||
   Change keybindings for example:
 | 
			
		||||
 | 
			
		||||
     gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 '[<Alt>F1]'
 | 
			
		||||
     unst gconftool-2 --type=string --set /apps/metacity/global_keybindings/switch_to_workspace_1 '<Alt>F1'
 | 
			
		||||
   
 | 
			
		||||
   Also try the GNOME keyboard shortcuts control panel.
 | 
			
		||||
   Also try the GNOME keyboard shortcuts control panel, or
 | 
			
		||||
   gconf-editor.
 | 
			
		||||
 | 
			
		||||
 - Window keybindings:
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										206
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										206
									
								
								configure.in
									
									
									
									
									
								
							@@ -1,8 +1,8 @@
 | 
			
		||||
AC_PREREQ(2.50)
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_major_version], [3])
 | 
			
		||||
m4_define([mutter_minor_version], [6])
 | 
			
		||||
m4_define([mutter_micro_version], [0])
 | 
			
		||||
m4_define([mutter_minor_version], [2])
 | 
			
		||||
m4_define([mutter_micro_version], [1])
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_version],
 | 
			
		||||
          [mutter_major_version.mutter_minor_version.mutter_micro_version])
 | 
			
		||||
@@ -61,23 +61,21 @@ AC_CHECK_SIZEOF(__int64)
 | 
			
		||||
## byte order
 | 
			
		||||
AC_C_BIGENDIAN
 | 
			
		||||
 | 
			
		||||
GTK_MIN_VERSION=2.91.7
 | 
			
		||||
CANBERRA_GTK=libcanberra-gtk3
 | 
			
		||||
CANBERRA_GTK_VERSION=0.26
 | 
			
		||||
 | 
			
		||||
CLUTTER_PACKAGE=clutter-1.0
 | 
			
		||||
MUTTER_PC_MODULES="gtk+-3.0 >= $GTK_MIN_VERSION pango >= 1.2.0 cairo >= 1.10.0"
 | 
			
		||||
 | 
			
		||||
MUTTER_PC_MODULES="
 | 
			
		||||
   gtk+-3.0 >= 3.3.7
 | 
			
		||||
   gio-2.0 >= 2.25.10
 | 
			
		||||
   pango >= 1.2.0
 | 
			
		||||
   cairo >= 1.10.0
 | 
			
		||||
   gsettings-desktop-schemas >= 3.3.0
 | 
			
		||||
   xcomposite >= 0.2 xfixes xrender xdamage
 | 
			
		||||
   $CLUTTER_PACKAGE >= 1.9.10
 | 
			
		||||
   cogl-1.0 >= 1.9.6
 | 
			
		||||
"
 | 
			
		||||
AC_ARG_ENABLE(gconf,
 | 
			
		||||
  AC_HELP_STRING([--disable-gconf],
 | 
			
		||||
                 [disable gconf usage, for embedded/size-sensitive non-GNOME builds]),,
 | 
			
		||||
  enable_gconf=yes)
 | 
			
		||||
 | 
			
		||||
GLIB_GSETTINGS
 | 
			
		||||
if test x$enable_gconf = xyes; then
 | 
			
		||||
    AC_DEFINE(HAVE_GCONF,1,[Build with gconf support])
 | 
			
		||||
    MUTTER_PC_MODULES="$MUTTER_PC_MODULES gconf-2.0 >= 1.2.0"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(verbose-mode,
 | 
			
		||||
  AC_HELP_STRING([--disable-verbose-mode],
 | 
			
		||||
@@ -113,14 +111,17 @@ AC_ARG_ENABLE(shape,
 | 
			
		||||
                 [disable mutter's use of the shaped window extension]),,
 | 
			
		||||
  enable_shape=auto)
 | 
			
		||||
 | 
			
		||||
## try definining HAVE_BACKTRACE
 | 
			
		||||
AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
 | 
			
		||||
 | 
			
		||||
AM_GLIB_GNU_GETTEXT
 | 
			
		||||
 | 
			
		||||
## here we get the flags we'll actually use
 | 
			
		||||
# GRegex requires Glib-2.14.0
 | 
			
		||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
 | 
			
		||||
# gtk_window_set_icon_name requires gtk2+-2.6.0
 | 
			
		||||
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-3.0)
 | 
			
		||||
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-3.0)
 | 
			
		||||
PKG_CHECK_MODULES(MUTTER_MESSAGE, gtk+-3.0 >= $GTK_MIN_VERSION)
 | 
			
		||||
PKG_CHECK_MODULES(MUTTER_WINDOW_DEMO, gtk+-3.0 >= $GTK_MIN_VERSION)
 | 
			
		||||
 | 
			
		||||
# Unconditionally use this dir to avoid a circular dep with gnomecc
 | 
			
		||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
 | 
			
		||||
@@ -170,6 +171,31 @@ else
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
XCOMPOSITE_VERSION=0.2
 | 
			
		||||
 | 
			
		||||
AC_MSG_CHECKING([Xcomposite >= $XCOMPOSITE_VERSION])
 | 
			
		||||
if $PKG_CONFIG --atleast-version $XCOMPOSITE_VERSION xcomposite; then
 | 
			
		||||
  MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcomposite >= $XCOMPOSITE_VERSION xfixes xrender xdamage"
 | 
			
		||||
  AC_DEFINE(HAVE_COMPOSITE_EXTENSIONS, 1, [Building with compositing manager support])
 | 
			
		||||
  echo "Building with compositing manager"
 | 
			
		||||
 | 
			
		||||
  ## force on render also
 | 
			
		||||
  have_xrender=yes
 | 
			
		||||
else
 | 
			
		||||
  AC_MSG_ERROR([no. Mutter requires the Xcomposite extension to build.])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
CLUTTER_VERSION=1.7.5
 | 
			
		||||
CLUTTER_PACKAGE=clutter-1.0
 | 
			
		||||
AC_SUBST(CLUTTER_PACKAGE)
 | 
			
		||||
if $PKG_CONFIG --atleast-version $CLUTTER_VERSION $CLUTTER_PACKAGE ; then
 | 
			
		||||
  MUTTER_PC_MODULES="$MUTTER_PC_MODULES $CLUTTER_PACKAGE "
 | 
			
		||||
  PKG_CHECK_MODULES(CLUTTER, $CLUTTER_PACKAGE)
 | 
			
		||||
  AC_DEFINE(WITH_CLUTTER, , [Building with Clutter compositor])
 | 
			
		||||
else
 | 
			
		||||
  AC_MSG_ERROR([no. Mutter requires Clutter version $CLUTTER_VERSION.])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
INTROSPECTION_VERSION=0.9.5
 | 
			
		||||
GOBJECT_INTROSPECTION_CHECK([$INTROSPECTION_VERSION])
 | 
			
		||||
 | 
			
		||||
@@ -199,41 +225,110 @@ if test x$have_xcursor = xyes; then
 | 
			
		||||
  AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
 | 
			
		||||
XINPUT2_VERSION=1.4.0
 | 
			
		||||
 | 
			
		||||
# This is used for plugins
 | 
			
		||||
AC_SUBST(CLUTTER_PACKAGE)
 | 
			
		||||
PKG_CHECK_MODULES(CLUTTER, $CLUTTER_PACKAGE)
 | 
			
		||||
AC_ARG_ENABLE(xinput2,
 | 
			
		||||
  AC_HELP_STRING([--disable-xinput2],
 | 
			
		||||
                 [disable XInput2 usage]),,
 | 
			
		||||
  enable_xinput2=yes)
 | 
			
		||||
 | 
			
		||||
if test x$enable_xinput2 = xyes; then
 | 
			
		||||
  AC_MSG_CHECKING([XInput2])
 | 
			
		||||
  if $PKG_CONFIG --atleast-version $XINPUT2_VERSION xi; then
 | 
			
		||||
    have_xinput2=yes
 | 
			
		||||
  else
 | 
			
		||||
    have_xinput2=no
 | 
			
		||||
  fi
 | 
			
		||||
  AC_MSG_RESULT($have_xinput2)
 | 
			
		||||
else
 | 
			
		||||
  have_xinput2=no
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test x$have_xinput2 = xyes; then
 | 
			
		||||
  echo "Building with XInput2"
 | 
			
		||||
  MUTTER_PC_MODULES="$MUTTER_PC_MODULES xi"
 | 
			
		||||
  AC_DEFINE(HAVE_XINPUT2, , [Building with XInput2 support])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AM_CONDITIONAL(HAVE_XINPUT2, test "$have_xinput2" = "yes")
 | 
			
		||||
 | 
			
		||||
if test x$have_xinput2 = xyes; then
 | 
			
		||||
  mutter_save_libs="$LIBS"
 | 
			
		||||
  LIBS="-lXi $LIBS"
 | 
			
		||||
 | 
			
		||||
  AC_CHECK_FUNC(XIAllowTouchEvents,
 | 
			
		||||
                have_xtouch=yes,
 | 
			
		||||
                have_xtouch=no)
 | 
			
		||||
 | 
			
		||||
  LIBS="$mutter_save_libs"
 | 
			
		||||
else
 | 
			
		||||
  have_xtouch=no
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test x$have_xtouch = xyes; then
 | 
			
		||||
  AC_DEFINE(HAVE_XTOUCH, , [Building with X touch events])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
 | 
			
		||||
 | 
			
		||||
AC_PATH_XTRA
 | 
			
		||||
 | 
			
		||||
ALL_X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
 | 
			
		||||
 | 
			
		||||
# Check for Xinerama extension - we only support the "XFree86" style,
 | 
			
		||||
# and not the older Solaris-only version; recent Solaris supports the
 | 
			
		||||
# XFree86 style.
 | 
			
		||||
# Check for Xinerama extension (Solaris impl or Xfree impl)
 | 
			
		||||
mutter_save_cppflags="$CPPFLAGS"
 | 
			
		||||
CPPFLAGS="$CPPFLAGS $X_CFLAGS"
 | 
			
		||||
 | 
			
		||||
have_xinerama=yes
 | 
			
		||||
AC_CHECK_LIB(Xinerama, XineramaQueryExtension,
 | 
			
		||||
    [AC_CHECK_HEADER(X11/extensions/Xinerama.h,
 | 
			
		||||
		     [X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS"
 | 
			
		||||
		     if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
 | 
			
		||||
			 X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
 | 
			
		||||
		     fi],
 | 
			
		||||
		     have_xinerama=no,
 | 
			
		||||
		     [#include <X11/Xlib.h>])],
 | 
			
		||||
    have_xinerama=no, -lXext $ALL_X_LIBS)
 | 
			
		||||
AC_MSG_CHECKING(for Xinerama support)
 | 
			
		||||
AC_MSG_RESULT($have_xinerama)
 | 
			
		||||
AC_ARG_ENABLE(xinerama,
 | 
			
		||||
  AC_HELP_STRING([--disable-xinerama],
 | 
			
		||||
                 [disable mutter's use of the Xinerama extension]),
 | 
			
		||||
  try_xinerama=$enable_xinerama,try_xinerama=yes)
 | 
			
		||||
 | 
			
		||||
use_solaris_xinerama=no
 | 
			
		||||
use_xfree_xinerama=no
 | 
			
		||||
if test "${try_xinerama}" != no; then
 | 
			
		||||
    case "$host" in
 | 
			
		||||
        *-*-solaris*)
 | 
			
		||||
            # Check for solaris
 | 
			
		||||
            use_solaris_xinerama=yes
 | 
			
		||||
            AC_CHECK_LIB(Xext, XineramaGetInfo,
 | 
			
		||||
                         use_solaris_xinerama=yes, use_solaris_xinerama=no,
 | 
			
		||||
                         $ALL_X_LIBS)
 | 
			
		||||
            if test "x$use_solaris_xinerama" = "xyes"; then
 | 
			
		||||
                AC_CHECK_HEADER(X11/extensions/xinerama.h,
 | 
			
		||||
                                if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
 | 
			
		||||
                                    X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
 | 
			
		||||
                                fi
 | 
			
		||||
                                AC_DEFINE(HAVE_SOLARIS_XINERAMA, , [Have Solaris-style Xinerama])
 | 
			
		||||
                                AC_DEFINE(HAVE_XINERAMA, , [Have some version of Xinerama]),
 | 
			
		||||
                                use_solaris_xinerama=no,
 | 
			
		||||
                                [#include <X11/Xlib.h>])
 | 
			
		||||
            fi
 | 
			
		||||
            AC_MSG_CHECKING(for Xinerama support on Solaris)
 | 
			
		||||
            AC_MSG_RESULT($use_solaris_xinerama);
 | 
			
		||||
            ;;
 | 
			
		||||
        *)
 | 
			
		||||
            # Check for XFree
 | 
			
		||||
            use_xfree_xinerama=yes
 | 
			
		||||
            AC_CHECK_LIB(Xinerama, XineramaQueryExtension,
 | 
			
		||||
                [AC_CHECK_HEADER(X11/extensions/Xinerama.h,
 | 
			
		||||
                                 X_EXTRA_LIBS="-lXinerama $X_EXTRA_LIBS"
 | 
			
		||||
                                 if test -z "`echo $ALL_X_LIBS | grep "\-lXext" 2> /dev/null`"; then
 | 
			
		||||
                                     X_EXTRA_LIBS="-lXext $X_EXTRA_LIBS"
 | 
			
		||||
                                 fi
 | 
			
		||||
                                 AC_DEFINE(HAVE_XFREE_XINERAMA, , [Have XFree86-style Xinerama])
 | 
			
		||||
                                 AC_DEFINE(HAVE_XINERAMA,, [Have some version of Xinerama]),
 | 
			
		||||
                                 use_xfree_xinerama=no,
 | 
			
		||||
                                 [#include <X11/Xlib.h>])],
 | 
			
		||||
                use_xfree_xinerama=no, -lXext $ALL_X_LIBS)
 | 
			
		||||
            AC_MSG_CHECKING(for Xinerama support on XFree86)
 | 
			
		||||
            AC_MSG_RESULT($use_xfree_xinerama);
 | 
			
		||||
            ;;
 | 
			
		||||
    esac
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
CPPFLAGS="$mutter_save_cppflags"
 | 
			
		||||
 | 
			
		||||
if test x$have_xinerama = xno; then
 | 
			
		||||
   AC_MSG_ERROR([Xinerama extension was not found])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
SHAPE_LIBS=
 | 
			
		||||
found_shape=no
 | 
			
		||||
AC_CHECK_LIB(Xext, XShapeQueryExtension,
 | 
			
		||||
@@ -349,6 +444,18 @@ fi
 | 
			
		||||
 | 
			
		||||
AC_SUBST(GDK_PIXBUF_CSOURCE)
 | 
			
		||||
 | 
			
		||||
if test x$enable_gconf = xyes; then
 | 
			
		||||
   AC_PATH_PROG(GCONFTOOL, gconftool-2, no)
 | 
			
		||||
   if test x"$GCONFTOOL" = xno; then
 | 
			
		||||
     AC_MSG_ERROR([gconftool-2 executable not found in your path - should be installed with GConf])
 | 
			
		||||
   fi
 | 
			
		||||
 | 
			
		||||
   AM_GCONF_SOURCE_2
 | 
			
		||||
else
 | 
			
		||||
  GCONF_SCHEMAS_INSTALL_TRUE='#'
 | 
			
		||||
  GCONF_SCHEMAS_INSTALL_FALSE=
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_PATH_PROG(ZENITY, zenity, no)
 | 
			
		||||
if test x"$ZENITY" = xno; then
 | 
			
		||||
  AC_MSG_ERROR([zenity not found in your path - needed for dialogs])
 | 
			
		||||
@@ -364,6 +471,9 @@ fi
 | 
			
		||||
# For fix-meta-rectangle.py
 | 
			
		||||
AM_PATH_PYTHON([2.5])
 | 
			
		||||
 | 
			
		||||
# Use gnome-doc-utils:
 | 
			
		||||
GNOME_DOC_INIT([0.8.0])
 | 
			
		||||
 | 
			
		||||
#### Warnings (last since -Werror can disturb other tests)
 | 
			
		||||
 | 
			
		||||
# Stay command-line compatible with the gnome-common configure option. Here
 | 
			
		||||
@@ -423,7 +533,7 @@ if test "$enable_compile_warnings" != no ; then
 | 
			
		||||
    if test "$enable_compile_warnings" = error; then
 | 
			
		||||
      case " $CFLAGS " in
 | 
			
		||||
      *[\ \	]-Werror[\ \	]*) ;;
 | 
			
		||||
      *) CFLAGS="$CFLAGS -Werror -Wno-error=deprecated-declarations" ;;
 | 
			
		||||
      *) CFLAGS="$CFLAGS -Werror" ;;
 | 
			
		||||
      esac
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
@@ -445,6 +555,13 @@ po/Makefile.in
 | 
			
		||||
 | 
			
		||||
AC_OUTPUT
 | 
			
		||||
 | 
			
		||||
if test x$enable_gconf = xno; then
 | 
			
		||||
        echo "*** WARNING WARNING WARNING WARNING WARNING"
 | 
			
		||||
        echo "*** Building without GConf.  This means there's no"
 | 
			
		||||
        echo "*** way to change prefs except hacking source code."
 | 
			
		||||
        echo "*** This is intended for embedded systems etc., not for normal use."
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test x$enable_verbose_mode = xno; then
 | 
			
		||||
        echo "*** WARNING WARNING WARNING WARNING WARNING"
 | 
			
		||||
        echo "*** Building without verbose mode"
 | 
			
		||||
@@ -461,6 +578,9 @@ mutter-$VERSION
 | 
			
		||||
	source code location:	  ${srcdir}
 | 
			
		||||
	compiler:		  ${CC}
 | 
			
		||||
 | 
			
		||||
	GConf:                    ${enable_gconf}
 | 
			
		||||
	XFree86 Xinerama:         ${use_xfree_xinerama}
 | 
			
		||||
	Solaris Xinerama:         ${use_solaris_xinerama}
 | 
			
		||||
	Startup notification:     ${have_startup_notification}
 | 
			
		||||
	libcanberra:              ${have_libcanberra}
 | 
			
		||||
	Introspection:            ${found_introspection}
 | 
			
		||||
@@ -468,6 +588,8 @@ mutter-$VERSION
 | 
			
		||||
	Shape extension:          ${found_shape}
 | 
			
		||||
	Xsync:                    ${found_xsync}
 | 
			
		||||
	Xcursor:                  ${have_xcursor}
 | 
			
		||||
	XInput2:                  ${have_xinput2}
 | 
			
		||||
	Touch events:             ${have_xtouch}
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -475,8 +597,8 @@ MUTTER_MINOR_VERSION=mutter_minor_version
 | 
			
		||||
if expr $MUTTER_MINOR_VERSION % 2 > /dev/null ; then
 | 
			
		||||
   stable_version=`expr $MUTTER_MINOR_VERSION - 1`
 | 
			
		||||
   echo "This is the UNSTABLE branch of mutter"
 | 
			
		||||
   echo -n "Use 3.$stable_version.x for stable "
 | 
			
		||||
   echo    "(gnome-3-$stable_version branch in git)"
 | 
			
		||||
   echo -n "Use 2.$stable_version.x for stable "
 | 
			
		||||
   echo    "(gnome-2-$stable_version branch in git)"
 | 
			
		||||
else
 | 
			
		||||
   echo "This is the stable branch of mutter"
 | 
			
		||||
fi
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,8 @@ workspaces.  In these cases, there needs to be a rule consistent with
 | 
			
		||||
the above about the new window to choose.
 | 
			
		||||
 | 
			
		||||
Focus method  Behavior
 | 
			
		||||
    click     Focus the window on top
 | 
			
		||||
    click     Focus the most recently used window (same as the window
 | 
			
		||||
              on top)
 | 
			
		||||
   sloppy     Focus the window containing the pointer if there is such
 | 
			
		||||
              a window, otherwise focus the most recently used window.
 | 
			
		||||
    mouse     Focus the non-DESKTOP window containing the pointer if
 | 
			
		||||
 
 | 
			
		||||
@@ -46,13 +46,13 @@ because the original program does not have a manual page.
 | 
			
		||||
Restart \fBmutter\fP(1) which is running.
 | 
			
		||||
.TP
 | 
			
		||||
.B reload-theme
 | 
			
		||||
Reload a theme which is specified on gsettings database.
 | 
			
		||||
Reload a theme which is specified on gconf database.
 | 
			
		||||
.TP
 | 
			
		||||
.B enable-keybindings
 | 
			
		||||
Enable all of keybindings which is specified on gsettings database.
 | 
			
		||||
Enable all of keybindings which is specified on gconf database.
 | 
			
		||||
.TP
 | 
			
		||||
.B disable-keybindings
 | 
			
		||||
Disable all of keybindings which is specified on gsettings database.
 | 
			
		||||
Disable all of keybindings which is specified on gconf database.
 | 
			
		||||
.SH SEE ALSO
 | 
			
		||||
.BR mutter (1)
 | 
			
		||||
.SH AUTHOR
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,7 @@ Print the version number.
 | 
			
		||||
.B \-?, \-\-help
 | 
			
		||||
Show summary of options.
 | 
			
		||||
.SH CONFIGURATION
 | 
			
		||||
\fBmutter\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gsettings.
 | 
			
		||||
\fBmutter\fP configuration can be found under \fIPreferences\fP->\fIWindows\fP and \fIPreferences\fP->\fIKeyboard Shortcuts\fP on the menu-panel. Advanced configuration can be achieved directly through gconf editing (gconf-editor or gconftool-2).
 | 
			
		||||
.SH SEE ALSO
 | 
			
		||||
.BR mutter-message (1)
 | 
			
		||||
.SH AUTHOR
 | 
			
		||||
 
 | 
			
		||||
@@ -39,11 +39,4 @@ environment.</description>
 | 
			
		||||
      <gnome:userid>otaylor</gnome:userid>
 | 
			
		||||
    </foaf:Person>
 | 
			
		||||
  </maintainer>
 | 
			
		||||
  <maintainer>
 | 
			
		||||
    <foaf:Person>
 | 
			
		||||
      <foaf:name>Florian Müllner</foaf:name>
 | 
			
		||||
      <foaf:mbox rdf:resource="mailto:fmuellner@gnome.org" />
 | 
			
		||||
      <gnome:userid>fmuellner</gnome:userid>
 | 
			
		||||
    </foaf:Person>
 | 
			
		||||
  </maintainer>
 | 
			
		||||
</Project>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
# List of source files containing translatable strings.
 | 
			
		||||
# Please keep this file sorted alphabetically.
 | 
			
		||||
src/50-mutter-windows.xml.in
 | 
			
		||||
src/compositor/compositor.c
 | 
			
		||||
src/core/all-keybindings.h
 | 
			
		||||
src/core/bell.c
 | 
			
		||||
src/core/core.c
 | 
			
		||||
src/core/delete.c
 | 
			
		||||
@@ -19,7 +19,7 @@ src/core/window-props.c
 | 
			
		||||
src/core/xprops.c
 | 
			
		||||
src/mutter.desktop.in
 | 
			
		||||
src/mutter-wm.desktop.in
 | 
			
		||||
src/org.gnome.mutter.gschema.xml.in
 | 
			
		||||
src/mutter.schemas.in
 | 
			
		||||
src/tools/mutter-message.c
 | 
			
		||||
src/ui/frames.c
 | 
			
		||||
src/ui/menu.c
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1233
									
								
								po/ca@valencia.po
									
									
									
									
									
								
							
							
						
						
									
										1233
									
								
								po/ca@valencia.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1185
									
								
								po/en_GB.po
									
									
									
									
									
								
							
							
						
						
									
										1185
									
								
								po/en_GB.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										511
									
								
								po/et.po
									
									
									
									
									
								
							
							
						
						
									
										511
									
								
								po/et.po
									
									
									
									
									
								
							@@ -7,39 +7,253 @@
 | 
			
		||||
#
 | 
			
		||||
# Tõivo Leedjärv <toivo linux ee>, 2004.
 | 
			
		||||
# Ivar Smolin <okul linux ee>, 2005, 2006, 2009–2011.
 | 
			
		||||
# Mattias Põldaru <mahfiaz@gmail.com>, 2008–2011, 2012.
 | 
			
		||||
# Mattias Põldaru <mahfiaz gmail com>, 2008–2011.
 | 
			
		||||
#
 | 
			
		||||
msgid ""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Project-Id-Version: mutter MASTER\n"
 | 
			
		||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
 | 
			
		||||
"product=mutter&keywords=I18N+L10N&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2012-09-22 18:05+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2012-09-23 10:41+0300\n"
 | 
			
		||||
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
 | 
			
		||||
"Language-Team: Estonian <>\n"
 | 
			
		||||
"Language: et\n"
 | 
			
		||||
"product=mutter&component=general\n"
 | 
			
		||||
"POT-Creation-Date: 2011-03-07 23:35+0000\n"
 | 
			
		||||
"PO-Revision-Date: 2011-03-09 06:41+0200\n"
 | 
			
		||||
"Last-Translator: Ivar Smolin <okul@linux.ee>\n"
 | 
			
		||||
"Language-Team: Estonian <gnome-et@linux.ee>\n"
 | 
			
		||||
"MIME-Version: 1.0\n"
 | 
			
		||||
"Content-Type: text/plain; charset=UTF-8\n"
 | 
			
		||||
"Content-Transfer-Encoding: 8bit\n"
 | 
			
		||||
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
 | 
			
		||||
"Language: et\n"
 | 
			
		||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
 | 
			
		||||
 | 
			
		||||
msgid "Windows"
 | 
			
		||||
msgstr "Aknad"
 | 
			
		||||
msgid "Switch to workspace 1"
 | 
			
		||||
msgstr "Lülitumine 1. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "View split on left"
 | 
			
		||||
msgstr "Vaade poolitatakse vasakult"
 | 
			
		||||
msgid "Switch to workspace 2"
 | 
			
		||||
msgstr "Lülitumine 2. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "View split on right"
 | 
			
		||||
msgstr "Vaade poolitatakse paremalt"
 | 
			
		||||
msgid "Switch to workspace 3"
 | 
			
		||||
msgstr "Lülitumine 3. tööalale"
 | 
			
		||||
 | 
			
		||||
#. This probably means that a non-WM compositor like xcompmgr is running;
 | 
			
		||||
#. * we have no way to get it to exit
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Another compositing manager is already running on screen %i on display \"%s"
 | 
			
		||||
"\"."
 | 
			
		||||
msgstr "Teine komposiithaldur juba töötab ekraani %i kuval \"%s\"."
 | 
			
		||||
msgid "Switch to workspace 4"
 | 
			
		||||
msgstr "Lülitumine 4. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace 5"
 | 
			
		||||
msgstr "Lülitumine 5. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace 6"
 | 
			
		||||
msgstr "Lülitumine 6. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace 7"
 | 
			
		||||
msgstr "Lülitumine 7. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace 8"
 | 
			
		||||
msgstr "Lülitumine 8. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace 9"
 | 
			
		||||
msgstr "Lülitumine 9. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace 10"
 | 
			
		||||
msgstr "Lülitumine 10. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace 11"
 | 
			
		||||
msgstr "Lülitumine 11. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace 12"
 | 
			
		||||
msgstr "Lülitumine 12. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace on the left of the current workspace"
 | 
			
		||||
msgstr "Lülitumine sellest tööalast vasakul olevale tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace on the right of the current workspace"
 | 
			
		||||
msgstr "Lülitumine sellest tööalast paremal olevale tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace above the current workspace"
 | 
			
		||||
msgstr "Lülitumine selle tööala kohal olevale tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Switch to workspace below the current workspace"
 | 
			
		||||
msgstr "Lülitumine selle tööala all olevale tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move between windows of an application, using a popup window"
 | 
			
		||||
msgstr "Liigu rakenduse akende vahel, hüpikaknaga"
 | 
			
		||||
 | 
			
		||||
msgid "Move backward between windows of an application, using a popup window"
 | 
			
		||||
msgstr "Liigu rakenduse akende vahel tagasisuunas, hüpikaknaga"
 | 
			
		||||
 | 
			
		||||
msgid "Move between windows, using a popup window"
 | 
			
		||||
msgstr "Liigu akende vahel, hüpikaknaga"
 | 
			
		||||
 | 
			
		||||
msgid "Move backward between windows, using a popup window"
 | 
			
		||||
msgstr "Liigu akende vahel tagasisuunas, hüpikaknaga"
 | 
			
		||||
 | 
			
		||||
msgid "Move between panels and the desktop, using a popup window"
 | 
			
		||||
msgstr "Liigu paneelide ja töölaua vahel, hüpikaknaga"
 | 
			
		||||
 | 
			
		||||
msgid "Move backward between panels and the desktop, using a popup window"
 | 
			
		||||
msgstr "Liigu tagasisuunas paneelide ja töölaua vahel, hüpikaknaga"
 | 
			
		||||
 | 
			
		||||
msgid "Move between windows of an application immediately"
 | 
			
		||||
msgstr "Liigu koheselt rakenduse akende vahel"
 | 
			
		||||
 | 
			
		||||
msgid "Move backward between windows of an application immediately"
 | 
			
		||||
msgstr "Liigu koheselt rakenduse akende vahel tagasisuunas"
 | 
			
		||||
 | 
			
		||||
msgid "Move between windows immediately"
 | 
			
		||||
msgstr "Liigu koheselt akende vahel"
 | 
			
		||||
 | 
			
		||||
msgid "Move backward between windows immediately"
 | 
			
		||||
msgstr "Liigu koheselt akende vahel tagasisuunas"
 | 
			
		||||
 | 
			
		||||
msgid "Move between panels and the desktop immediately"
 | 
			
		||||
msgstr "Liigu koheselt paneeli ja töölaua vahel"
 | 
			
		||||
 | 
			
		||||
msgid "Move backward between panels and the desktop immediately"
 | 
			
		||||
msgstr "Liigu koheselt tagasisuunas paneelide ja töölaua vahel"
 | 
			
		||||
 | 
			
		||||
msgid "Hide all normal windows and set focus to the desktop"
 | 
			
		||||
msgstr "Peida kõik tavalised aknad ja fokuseeri töölaud"
 | 
			
		||||
 | 
			
		||||
msgid "Show the panel's main menu"
 | 
			
		||||
msgstr "Paneeli peamenüü näitamine"
 | 
			
		||||
 | 
			
		||||
msgid "Show the panel's \"Run Application\" dialog box"
 | 
			
		||||
msgstr "Paneeli dialoogi \"Käivita rakendus\" näitamine"
 | 
			
		||||
 | 
			
		||||
msgid "Start or stop recording the session"
 | 
			
		||||
msgstr "Seansi salvestamise käivitamine või seiskamine"
 | 
			
		||||
 | 
			
		||||
msgid "Take a screenshot"
 | 
			
		||||
msgstr "Kuvatõmmise võtmine"
 | 
			
		||||
 | 
			
		||||
msgid "Take a screenshot of a window"
 | 
			
		||||
msgstr "Kuvatõmmise võtmine aknast"
 | 
			
		||||
 | 
			
		||||
msgid "Run a terminal"
 | 
			
		||||
msgstr "Terminali käivitamine"
 | 
			
		||||
 | 
			
		||||
msgid "Activate the window menu"
 | 
			
		||||
msgstr "Aknamenüü aktiveerimine"
 | 
			
		||||
 | 
			
		||||
msgid "Toggle fullscreen mode"
 | 
			
		||||
msgstr "Täisekraanivaate sisse- ja väljalülitamine"
 | 
			
		||||
 | 
			
		||||
msgid "Toggle maximization state"
 | 
			
		||||
msgstr "Maksimeeritud oleku sisse- ja väljalülitamine"
 | 
			
		||||
 | 
			
		||||
msgid "Toggle whether a window will always be visible over other windows"
 | 
			
		||||
msgstr "Lüliti määrab, kas aken on alati teiste akende kohal nähtav"
 | 
			
		||||
 | 
			
		||||
msgid "Maximize window"
 | 
			
		||||
msgstr "Akna maksimeerimine"
 | 
			
		||||
 | 
			
		||||
msgid "Restore window"
 | 
			
		||||
msgstr "Taasta akna suurus"
 | 
			
		||||
 | 
			
		||||
msgid "Toggle shaded state"
 | 
			
		||||
msgstr "Varjatud oleku lüliti"
 | 
			
		||||
 | 
			
		||||
msgid "Minimize window"
 | 
			
		||||
msgstr "Akna minimeerimine"
 | 
			
		||||
 | 
			
		||||
msgid "Close window"
 | 
			
		||||
msgstr "Akna sulgemine"
 | 
			
		||||
 | 
			
		||||
msgid "Move window"
 | 
			
		||||
msgstr "Teisalda aken"
 | 
			
		||||
 | 
			
		||||
msgid "Resize window"
 | 
			
		||||
msgstr "Muuda akna suurust"
 | 
			
		||||
 | 
			
		||||
msgid "Toggle whether window is on all workspaces or just one"
 | 
			
		||||
msgstr "Lüliti määrab, kas aken on kõigil tööaladel või ainult ühel"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 1"
 | 
			
		||||
msgstr "Akna tõstmine 1. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 2"
 | 
			
		||||
msgstr "Akna tõstmine 2. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 3"
 | 
			
		||||
msgstr "Akna tõstmine 3. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 4"
 | 
			
		||||
msgstr "Akna tõstmine 4. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 5"
 | 
			
		||||
msgstr "Akna tõstmine 5. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 6"
 | 
			
		||||
msgstr "Akna tõstmine 6. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 7"
 | 
			
		||||
msgstr "Akna tõstmine 7. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 8"
 | 
			
		||||
msgstr "Akna tõstmine 8. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 9"
 | 
			
		||||
msgstr "Akna tõstmine 9. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 10"
 | 
			
		||||
msgstr "Akna tõstmine 10. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 11"
 | 
			
		||||
msgstr "Akna tõstmine 11. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to workspace 12"
 | 
			
		||||
msgstr "Akna tõstmine 12. tööalale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window one workspace to the left"
 | 
			
		||||
msgstr "Akna tõstmine ühe tööala võrra vasakule"
 | 
			
		||||
 | 
			
		||||
msgid "Move window one workspace to the right"
 | 
			
		||||
msgstr "Akna tõstmine ühe tööala võrra paremale"
 | 
			
		||||
 | 
			
		||||
msgid "Move window one workspace up"
 | 
			
		||||
msgstr "Akna tõstmine ühe tööala võrra ülespoole"
 | 
			
		||||
 | 
			
		||||
msgid "Move window one workspace down"
 | 
			
		||||
msgstr "Akna tõstmine ühe tööala võrra allapoole"
 | 
			
		||||
 | 
			
		||||
msgid "Raise window if it's covered by another window, otherwise lower it"
 | 
			
		||||
msgstr "Tõsta aken, kui seda katab teine aken, muul juhul vii tahapoole"
 | 
			
		||||
 | 
			
		||||
msgid "Raise window above other windows"
 | 
			
		||||
msgstr "Akna tõstmine teiste akende kohale"
 | 
			
		||||
 | 
			
		||||
msgid "Lower window below other windows"
 | 
			
		||||
msgstr "Saada aken teiste taha"
 | 
			
		||||
 | 
			
		||||
msgid "Maximize window vertically"
 | 
			
		||||
msgstr "Maksimeeri aken vertikaalselt"
 | 
			
		||||
 | 
			
		||||
msgid "Maximize window horizontally"
 | 
			
		||||
msgstr "Maksimeeri aken horisontaalselt"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to north-west (top left) corner"
 | 
			
		||||
msgstr "Akna tõstmine ekraani loodepoolsesse (ülemisse vasakusse) nurka"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to north-east (top right) corner"
 | 
			
		||||
msgstr "Akna tõstmine ekraani kirdepoolsesse (ülemisse paremasse) nurka"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to south-west (bottom left) corner"
 | 
			
		||||
msgstr "Akna tõstmine ekraani edelapoolsesse (alumisse vasakusse) nurka"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to south-east (bottom right) corner"
 | 
			
		||||
msgstr "Akna tõstmine ekraani kagupoolsesse (alumisse paremasse) nurka"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to north (top) side of screen"
 | 
			
		||||
msgstr "Akna tõstmine ekraani põhjapoolsesse (ülemisse) serva"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to south (bottom) side of screen"
 | 
			
		||||
msgstr "Akna tõstmine ekraani lõunapoolsesse (alumisse) serva"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to east (right) side of screen"
 | 
			
		||||
msgstr "Akna tõstmine ekraani idapoolsesse (paremasse) serva"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to west (left) side of screen"
 | 
			
		||||
msgstr "Akna tõstmine ekraani läänepoolsesse (vasakusse) serva"
 | 
			
		||||
 | 
			
		||||
msgid "Move window to center of screen"
 | 
			
		||||
msgstr "Akna tõstmine ekraani keskele"
 | 
			
		||||
 | 
			
		||||
msgid "Bell event"
 | 
			
		||||
msgstr "Helina sündmus"
 | 
			
		||||
@@ -48,12 +262,10 @@ msgstr "Helina sündmus"
 | 
			
		||||
msgid "Unknown window information request: %d"
 | 
			
		||||
msgstr "Tundmatu aknateabe päring: %d"
 | 
			
		||||
 | 
			
		||||
#. Translators: %s is a window title
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%s is not responding."
 | 
			
		||||
msgstr "%s ei vasta."
 | 
			
		||||
 | 
			
		||||
msgid "Application is not responding."
 | 
			
		||||
msgstr "Rakendus ei vasta."
 | 
			
		||||
msgid "<tt>%s</tt> is not responding."
 | 
			
		||||
msgstr "<tt>%s</tt> ei vasta."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"You may choose to wait a short while for it to continue or force the "
 | 
			
		||||
@@ -82,6 +294,27 @@ msgstr ""
 | 
			
		||||
"Mõni teine programm juba kasutab klahvi %s koos muuteklahvidega %x "
 | 
			
		||||
"kiirklahvina\n"
 | 
			
		||||
 | 
			
		||||
#. Displayed when a keybinding which is
 | 
			
		||||
#. * supposed to launch a program fails.
 | 
			
		||||
#.
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"There was an error running <tt>%s</tt>:\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"%s"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"<tt>%s</tt> käivitamisel esines viga:\n"
 | 
			
		||||
"\n"
 | 
			
		||||
"%s"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "No command %d has been defined.\n"
 | 
			
		||||
msgstr "Käsku %d pole defineeritud.\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "No terminal command has been defined.\n"
 | 
			
		||||
msgstr "Terminalikäsku pole defineeritud.\n"
 | 
			
		||||
 | 
			
		||||
msgid "Disable connection to session manager"
 | 
			
		||||
msgstr "Seansihalduriga ühendumise keelamine"
 | 
			
		||||
 | 
			
		||||
@@ -128,8 +361,41 @@ msgstr ""
 | 
			
		||||
msgid "Print version"
 | 
			
		||||
msgstr "Versiooni printimine"
 | 
			
		||||
 | 
			
		||||
msgid "Mutter plugin to use"
 | 
			
		||||
msgstr "Millist Mutteri pluginat kasutada"
 | 
			
		||||
msgid "Comma-separated list of compositor plugins"
 | 
			
		||||
msgstr "Komaga eraldatud nimekiri komposiitmontaaži pluginatest"
 | 
			
		||||
 | 
			
		||||
#.
 | 
			
		||||
#. * We found it, but it was invalid.  Complain.
 | 
			
		||||
#. *
 | 
			
		||||
#. * FIXME: This replicates the original behaviour, but in the future
 | 
			
		||||
#. * we might consider reverting invalid keys to their original values.
 | 
			
		||||
#. * (We know the old value, so we can look up a suitable string in
 | 
			
		||||
#. * the symtab.)
 | 
			
		||||
#. *
 | 
			
		||||
#. * (Empty comment follows so the translators don't see this.)
 | 
			
		||||
#.
 | 
			
		||||
#.
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "GConf key '%s' is set to an invalid value\n"
 | 
			
		||||
msgstr "GConf võtme '%s' väärtus on vigane\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "%d stored in GConf key %s is out of range %d to %d\n"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"%d, mis on salvestatud GConf võtmes %s, on väljaspool piirkonda %d - %d\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "GConf key \"%s\" is set to an invalid type\n"
 | 
			
		||||
msgstr "GConf-i võti \"%s\" on määratud vigase tüübiga\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "GConf key %s is already in use and can't be used to override %s\n"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"GConfi võti %s on juba kasutusel ja sellega ei saa tühistada võtit %s\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Can't override GConf key, %s not found\n"
 | 
			
		||||
msgstr "GConfi võtit pole võimalik tühistada, võtit %s ei leitud\n"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Workarounds for broken applications disabled. Some applications may not "
 | 
			
		||||
@@ -139,8 +405,8 @@ msgstr ""
 | 
			
		||||
"ei pruugi õigesti käituda.\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Could not parse font description \"%s\" from GSettings key %s\n"
 | 
			
		||||
msgstr "Fondi kirjeldust \"%s\" GSettings võtmest %s pole võimalik töödelda\n"
 | 
			
		||||
msgid "Could not parse font description \"%s\" from GConf key %s\n"
 | 
			
		||||
msgstr "Fondi kirjeldust \"%s\" GConf võtmest %s ei saa töödelda\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
@@ -150,6 +416,14 @@ msgstr ""
 | 
			
		||||
"Seadistuste andmebaasist leitud \"%s\" ei ole sobiv väärtus hiireklahvi "
 | 
			
		||||
"modifikaatoriks\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Error setting number of workspaces to %d: %s\n"
 | 
			
		||||
msgstr "Viga tööalade arvuks %d määramisel: %s\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Workspace %d"
 | 
			
		||||
msgstr "Tööala %d"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"\"%s\" found in configuration database is not a valid value for keybinding "
 | 
			
		||||
@@ -159,8 +433,16 @@ msgstr ""
 | 
			
		||||
"\"\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Workspace %d"
 | 
			
		||||
msgstr "Tööala %d"
 | 
			
		||||
msgid "Error setting name for workspace %d to \"%s\": %s\n"
 | 
			
		||||
msgstr "Viga tööalale %d nime \"%s\" määramisel: %s\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Error setting live hidden windows status status: %s\n"
 | 
			
		||||
msgstr "Viga varjus elushoitavate akende oleku määramisel: %s\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Error setting no tab popup status: %s\n"
 | 
			
		||||
msgstr ""
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Screen %d on display '%s' is invalid\n"
 | 
			
		||||
@@ -258,6 +540,10 @@ msgstr "Aknahalduri hoiatus: "
 | 
			
		||||
msgid "Window manager error: "
 | 
			
		||||
msgstr "Aknahalduri viga: "
 | 
			
		||||
 | 
			
		||||
#. Translators: This is the title used on dialog boxes
 | 
			
		||||
msgid "Mutter"
 | 
			
		||||
msgstr "Mutter"
 | 
			
		||||
 | 
			
		||||
#. first time through
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
@@ -295,12 +581,6 @@ msgstr "%s (masinas %s)"
 | 
			
		||||
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
 | 
			
		||||
msgstr "Vigane WM_TRANSIENT_FOR aknale 0x%lx määratud %s jaoks.\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"WM_TRANSIENT_FOR aknale 0x%lx määratud %s jaoks tekitaks tsüklilise "
 | 
			
		||||
"korduse.\n"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Window 0x%lx has property %s\n"
 | 
			
		||||
@@ -324,8 +604,18 @@ msgid ""
 | 
			
		||||
"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"
 | 
			
		||||
msgstr "Omadus %s aknal 0x%lx sisaldab vigast UTF-8 %d kirjele nimekirjas\n"
 | 
			
		||||
 | 
			
		||||
msgid "Mutter"
 | 
			
		||||
msgstr "Mutter"
 | 
			
		||||
msgid "Attach modal dialogs"
 | 
			
		||||
msgstr "Modaaldialoogide kinnistamine"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Determines whether hidden windows (i.e., minimized windows and windows on "
 | 
			
		||||
"other workspaces than the current one) should be kept alive."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Määrab, kas varjatud aknaid (nt minimeeritud ja teistel tööaladel aknad) "
 | 
			
		||||
"hoitakse elus."
 | 
			
		||||
 | 
			
		||||
msgid "Live Hidden Windows"
 | 
			
		||||
msgstr "Varjatud akende aktiivsus"
 | 
			
		||||
 | 
			
		||||
msgid "Modifier to use for extended window management operations"
 | 
			
		||||
msgstr "Laiendatud aknaoperatsioonide korral kasutatav muuteklahv"
 | 
			
		||||
@@ -342,9 +632,6 @@ msgstr ""
 | 
			
		||||
"klahv\". Eeldatavasti määratakse selle seose väärtuseks vaikimisi või tühi "
 | 
			
		||||
"sõne."
 | 
			
		||||
 | 
			
		||||
msgid "Attach modal dialogs"
 | 
			
		||||
msgstr "Modaaldialoogide kinnistamine"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"When true, instead of having independent titlebars, modal dialogs appear "
 | 
			
		||||
"attached to the titlebar of the parent window and are moved together with "
 | 
			
		||||
@@ -353,69 +640,43 @@ msgstr ""
 | 
			
		||||
"Kui märgitud, siis eraldi tiitliribade asemel on moodaalsed dialoogid "
 | 
			
		||||
"emaakna tiitliribade küljes ning liiguvad koos emaaknaga."
 | 
			
		||||
 | 
			
		||||
msgid "Enable edge tiling when dropping windows on screen edges"
 | 
			
		||||
msgstr "Akna ümberpaigutamine selle lohistamisel ekraani serva"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"If enabled, dropping windows on vertical screen edges maximizes them "
 | 
			
		||||
"vertically and resizes them horizontally to cover half of the available "
 | 
			
		||||
"area. Dropping windows on the top screen edge maximizes them completely."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Kui märgitud, siis akna lohistamine ekraani külgservale maksimeerib selle "
 | 
			
		||||
"vertikaalselt ja laius katab pool saadaolevast laiusest. Akna lohistamine "
 | 
			
		||||
"ekraani ülaserva maksimeerib akna täielikult."
 | 
			
		||||
 | 
			
		||||
msgid "Workspaces are managed dynamically"
 | 
			
		||||
msgstr "Tööalade dünaamiline haldus"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Determines whether workspaces are managed dynamically or whether there's a "
 | 
			
		||||
"static number of workspaces (determined by the num-workspaces key in org."
 | 
			
		||||
"gnome.desktop.wm.preferences)."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Määrab, kas tööalasid hallatakse dünaamiliselt või on nende arv staatiline "
 | 
			
		||||
"(arvu määrab org.gnome.desktop.wm.preferences all võti num-workspaces)."
 | 
			
		||||
 | 
			
		||||
msgid "Workspaces only on primary"
 | 
			
		||||
msgstr "Tööalad ainult peamisel"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Determines whether workspace switching should happen for windows on all "
 | 
			
		||||
"monitors or only for windows on the primary monitor."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Määrab, kas tööalade vahetamine mõjutab kõiki aknaid kõigil monitoridel või "
 | 
			
		||||
"ainult aknaid peamisel monitoril."
 | 
			
		||||
 | 
			
		||||
msgid "No tab popup"
 | 
			
		||||
msgstr "Tabulaatoril pole hüpikakent"
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"Determines whether the use of popup and highlight frame should be disabled "
 | 
			
		||||
"for window cycling."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Kui märgitud, siis on hüpikaken ja esiletõstmise raam keelatud akende "
 | 
			
		||||
"vahetamisel."
 | 
			
		||||
 | 
			
		||||
msgid "Draggable border width"
 | 
			
		||||
msgstr "Lohistatava äärise laius."
 | 
			
		||||
 | 
			
		||||
msgid ""
 | 
			
		||||
"The amount of total draggable borders. If the theme's visible borders are "
 | 
			
		||||
"not enough, invisible borders will be added to meet this value."
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Lohistatava äärise laius. Kui kujunduse nähtavatest ääristest ei piisa, "
 | 
			
		||||
"lisatakse puuduoleva osa jaoks nähtamatu ääris."
 | 
			
		||||
 | 
			
		||||
msgid "Select window from tab popup"
 | 
			
		||||
msgstr "Akna valimine tabulaatori hüpikaknalt"
 | 
			
		||||
 | 
			
		||||
msgid "Cancel tab popup"
 | 
			
		||||
msgstr "Tabulaatori hüpikakna katkestamine"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid "Usage: %s\n"
 | 
			
		||||
msgstr "Kasutamine: %s\n"
 | 
			
		||||
 | 
			
		||||
msgid "Close Window"
 | 
			
		||||
msgstr "Sulge aken"
 | 
			
		||||
 | 
			
		||||
msgid "Window Menu"
 | 
			
		||||
msgstr "Aknamenüü"
 | 
			
		||||
 | 
			
		||||
msgid "Minimize Window"
 | 
			
		||||
msgstr "Akna minimeerimine"
 | 
			
		||||
 | 
			
		||||
msgid "Maximize Window"
 | 
			
		||||
msgstr "Akna maksimeerimine"
 | 
			
		||||
 | 
			
		||||
msgid "Restore Window"
 | 
			
		||||
msgstr "Akna taastamine"
 | 
			
		||||
 | 
			
		||||
msgid "Roll Up Window"
 | 
			
		||||
msgstr "Akna kokkukerimine"
 | 
			
		||||
 | 
			
		||||
msgid "Unroll Window"
 | 
			
		||||
msgstr "Akna lahtikerimine"
 | 
			
		||||
 | 
			
		||||
msgid "Keep Window On Top"
 | 
			
		||||
msgstr "Akna kõige pealmiseks määramine"
 | 
			
		||||
 | 
			
		||||
msgid "Remove Window From Top"
 | 
			
		||||
msgstr "Eemalda aken kõige pealmise kohalt"
 | 
			
		||||
 | 
			
		||||
msgid "Always On Visible Workspace"
 | 
			
		||||
msgstr "Alati nähtaval tööalal"
 | 
			
		||||
 | 
			
		||||
msgid "Put Window On Only One Workspace"
 | 
			
		||||
msgstr "Tõsta aken ainult ühele tööalale"
 | 
			
		||||
 | 
			
		||||
#. Translators: Translate this string the same way as you do in libwnck!
 | 
			
		||||
msgid "Mi_nimize"
 | 
			
		||||
msgstr "_Minimeeri"
 | 
			
		||||
@@ -616,30 +877,6 @@ msgstr "Raami geomeetria ei määra nuppude suurust"
 | 
			
		||||
msgid "Gradients should have at least two colors"
 | 
			
		||||
msgstr "Värviüleminekus peaks olema vähemalt kaks värvi"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"GTK custom color specification must have color name and fallback in "
 | 
			
		||||
"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
 | 
			
		||||
msgstr ""
 | 
			
		||||
"GTK kohandatud värvi määrang peab sisaldama sulgudes värvi nimetust ning "
 | 
			
		||||
"varuvärvi, nt gtk:custom(foo,bar); väärtust \"%s\" pole võimalik töödelda"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
 | 
			
		||||
"_ are valid"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"gtk:custom color_name parameetris sobimatu märk '%c', lubatud on ainult A-Za-"
 | 
			
		||||
"z0-9-_"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
 | 
			
		||||
"fit the format"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Gtk:custom vorming on \"gtk:custom(värvi_nimi,varuvärv)\", \"%s\" ei sobi "
 | 
			
		||||
"selle vorminguga"
 | 
			
		||||
 | 
			
		||||
#, c-format
 | 
			
		||||
msgid ""
 | 
			
		||||
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
 | 
			
		||||
@@ -1274,3 +1511,25 @@ msgstr "y väärtus oli %d, oodati väärtust %d"
 | 
			
		||||
msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"%d koordinaatide avaldis töödeldi %g sekundiga (keskmine %g sekundit)\n"
 | 
			
		||||
 | 
			
		||||
#~ msgid ""
 | 
			
		||||
#~ "Don't make fullscreen windows that are maximized and have no decorations"
 | 
			
		||||
#~ msgstr "Ei tehta maksimeeritud ilma raamita täisekraanaknaid."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Whether window popup/frame should be shown when cycling windows."
 | 
			
		||||
#~ msgstr "Kas hüpikakent/raami näidatakse akende vahetamisel."
 | 
			
		||||
 | 
			
		||||
#~ msgid "Internal argument for GObject introspection"
 | 
			
		||||
#~ msgstr "GObject enesevaatluse siseargument"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Failed to restart: %s\n"
 | 
			
		||||
#~ msgstr "Tõrge taaskäivitamisel: %s\n"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Error setting clutter plugin list: %s\n"
 | 
			
		||||
#~ msgstr "Viga clutteri pluginate nimekirja määramisel: %s\n"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Clutter Plugins"
 | 
			
		||||
#~ msgstr "Clutteri pluginad"
 | 
			
		||||
 | 
			
		||||
#~ msgid "Plugins to load for the Clutter-based compositing manager."
 | 
			
		||||
#~ msgstr "Clutteril põhineva komposiitmontaažihalduri laadimise pluginad."
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1238
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
							
						
						
									
										1238
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2986
									
								
								po/sr@latin.po
									
									
									
									
									
								
							
							
						
						
									
										2986
									
								
								po/sr@latin.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1100
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
							
						
						
									
										1100
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1292
									
								
								po/zh_HK.po
									
									
									
									
									
								
							
							
						
						
									
										1292
									
								
								po/zh_HK.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1299
									
								
								po/zh_TW.po
									
									
									
									
									
								
							
							
						
						
									
										1299
									
								
								po/zh_TW.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,15 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" ?>
 | 
			
		||||
<KeyListEntries schema="org.gnome.mutter.keybindings"
 | 
			
		||||
                group="system"
 | 
			
		||||
                _name="Windows"
 | 
			
		||||
                wm_name="Mutter"
 | 
			
		||||
                package="mutter">
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="toggle-tiled-left"
 | 
			
		||||
                      _description="View split on left"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="toggle-tiled-right"
 | 
			
		||||
                      _description="View split on right"/>
 | 
			
		||||
 | 
			
		||||
</KeyListEntries>
 | 
			
		||||
 | 
			
		||||
@@ -27,6 +27,8 @@ INCLUDES=								\
 | 
			
		||||
	-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"
 | 
			
		||||
 | 
			
		||||
mutter_built_sources = \
 | 
			
		||||
	mutter-marshal.h \
 | 
			
		||||
	mutter-marshal.c \
 | 
			
		||||
	mutter-enum-types.h \
 | 
			
		||||
	mutter-enum-types.c
 | 
			
		||||
 | 
			
		||||
@@ -52,6 +54,7 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	compositor/meta-shadow-factory.c	\
 | 
			
		||||
	compositor/meta-shadow-factory-private.h	\
 | 
			
		||||
	compositor/meta-shaped-texture.c	\
 | 
			
		||||
	compositor/meta-shaped-texture.h	\
 | 
			
		||||
	compositor/meta-texture-rectangle.c	\
 | 
			
		||||
	compositor/meta-texture-rectangle.h	\
 | 
			
		||||
	compositor/meta-texture-tower.c		\
 | 
			
		||||
@@ -75,6 +78,20 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	core/constraints.h			\
 | 
			
		||||
	core/core.c				\
 | 
			
		||||
	core/delete.c				\
 | 
			
		||||
	core/device.c				\
 | 
			
		||||
	meta/device.h				\
 | 
			
		||||
	core/device-keyboard.c			\
 | 
			
		||||
	core/device-keyboard.h			\
 | 
			
		||||
	core/device-pointer.c			\
 | 
			
		||||
	core/device-pointer.h			\
 | 
			
		||||
	core/device-private.h			\
 | 
			
		||||
	core/device-map.c			\
 | 
			
		||||
	meta/device-map.h			\
 | 
			
		||||
	core/device-map-private.h		\
 | 
			
		||||
	core/device-map-core.c			\
 | 
			
		||||
	core/device-map-core.h			\
 | 
			
		||||
	core/devices-core.c			\
 | 
			
		||||
	core/devices-core.h			\
 | 
			
		||||
	core/display.c				\
 | 
			
		||||
	core/display-private.h			\
 | 
			
		||||
	meta/display.h				\
 | 
			
		||||
@@ -97,6 +114,8 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	meta/group.h				\
 | 
			
		||||
	core/iconcache.c			\
 | 
			
		||||
	core/iconcache.h			\
 | 
			
		||||
	core/input-events.c			\
 | 
			
		||||
	core/input-events.h			\
 | 
			
		||||
	core/keybindings.c			\
 | 
			
		||||
	core/keybindings-private.h		\
 | 
			
		||||
	core/main.c				\
 | 
			
		||||
@@ -130,6 +149,8 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	core/core.h				\
 | 
			
		||||
	ui/ui.h					\
 | 
			
		||||
	inlinepixbufs.h				\
 | 
			
		||||
	ui/fixedtip.c				\
 | 
			
		||||
	ui/fixedtip.h				\
 | 
			
		||||
	ui/frames.c				\
 | 
			
		||||
	ui/frames.h				\
 | 
			
		||||
	ui/menu.c				\
 | 
			
		||||
@@ -147,10 +168,19 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	meta/theme.h				\
 | 
			
		||||
	ui/theme-private.h			\
 | 
			
		||||
	ui/ui.c					\
 | 
			
		||||
	core/all-keybindings.h			\
 | 
			
		||||
	meta/preview-widget.h			\
 | 
			
		||||
	ui/preview-widget.c			\
 | 
			
		||||
	$(mutter_built_sources)
 | 
			
		||||
 | 
			
		||||
if HAVE_XINPUT2
 | 
			
		||||
libmutter_la_SOURCES += 			\
 | 
			
		||||
	core/device-map-xi2.c			\
 | 
			
		||||
	core/device-map-xi2.h			\
 | 
			
		||||
	core/devices-xi2.c			\
 | 
			
		||||
	core/devices-xi2.h
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
libmutter_la_LDFLAGS = -no-undefined
 | 
			
		||||
libmutter_la_LIBADD  = $(MUTTER_LIBS)
 | 
			
		||||
 | 
			
		||||
@@ -161,6 +191,8 @@ libmutterinclude_base_headers =		\
 | 
			
		||||
	meta/common.h				\
 | 
			
		||||
	meta/compositor-mutter.h		\
 | 
			
		||||
	meta/compositor.h			\
 | 
			
		||||
	meta/device.h				\
 | 
			
		||||
	meta/device-map.h			\
 | 
			
		||||
	meta/display.h				\
 | 
			
		||||
	meta/errors.h				\
 | 
			
		||||
	meta/gradient.h				\
 | 
			
		||||
@@ -169,7 +201,6 @@ libmutterinclude_base_headers =		\
 | 
			
		||||
	meta/main.h				\
 | 
			
		||||
	meta/meta-background-actor.h		\
 | 
			
		||||
	meta/meta-plugin.h			\
 | 
			
		||||
	meta/meta-shaped-texture.h		\
 | 
			
		||||
	meta/meta-shadow-factory.h		\
 | 
			
		||||
	meta/meta-window-actor.h		\
 | 
			
		||||
	meta/prefs.h				\
 | 
			
		||||
@@ -221,8 +252,8 @@ typelib_DATA = Meta-$(api_version).typelib
 | 
			
		||||
INTROSPECTION_GIRS = Meta-$(api_version).gir
 | 
			
		||||
 | 
			
		||||
Meta-$(api_version).gir: libmutter.la
 | 
			
		||||
@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0
 | 
			
		||||
@META_GIR@_EXPORT_PACKAGES = libmutter
 | 
			
		||||
@META_GIR@_INCLUDES = GObject-2.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0
 | 
			
		||||
@META_GIR@_PACKAGES = clutter-1.0 gtk+-3.0
 | 
			
		||||
@META_GIR@_CFLAGS = $(INCLUDES)
 | 
			
		||||
@META_GIR@_LIBS = libmutter.la
 | 
			
		||||
@META_GIR@_FILES =				\
 | 
			
		||||
@@ -257,17 +288,20 @@ wmproperties_in_files=mutter-wm.desktop.in
 | 
			
		||||
wmproperties_files=$(wmproperties_in_files:.desktop.in=.desktop)
 | 
			
		||||
wmproperties_DATA = $(wmproperties_files)
 | 
			
		||||
 | 
			
		||||
xmldir       = @GNOME_KEYBINDINGS_KEYSDIR@
 | 
			
		||||
xml_in_files = \
 | 
			
		||||
        50-mutter-windows.xml.in
 | 
			
		||||
xml_DATA     = $(xml_in_files:.xml.in=.xml)
 | 
			
		||||
schemadir   = $(GCONF_SCHEMA_FILE_DIR)
 | 
			
		||||
schema_in_files = mutter.schemas.in
 | 
			
		||||
schema_DATA = $(schema_in_files:.schemas.in=.schemas)
 | 
			
		||||
 | 
			
		||||
gsettings_SCHEMAS = org.gnome.mutter.gschema.xml
 | 
			
		||||
@INTLTOOL_XML_NOMERGE_RULE@
 | 
			
		||||
@GSETTINGS_RULES@
 | 
			
		||||
 | 
			
		||||
convertdir = $(datadir)/GConf/gsettings
 | 
			
		||||
convert_DATA = mutter-schemas.convert
 | 
			
		||||
@INTLTOOL_SCHEMAS_RULE@
 | 
			
		||||
 | 
			
		||||
if GCONF_SCHEMAS_INSTALL
 | 
			
		||||
install-data-local:
 | 
			
		||||
	GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(schema_DATA)
 | 
			
		||||
else
 | 
			
		||||
install-data-local:
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
IMAGES=stock_maximize.png stock_minimize.png stock_delete.png
 | 
			
		||||
VARIABLES=stock_maximize_data $(srcdir)/stock_maximize.png \
 | 
			
		||||
@@ -279,8 +313,7 @@ CLEANFILES =					\
 | 
			
		||||
	inlinepixbufs.h				\
 | 
			
		||||
	mutter.desktop				\
 | 
			
		||||
	mutter-wm.desktop			\
 | 
			
		||||
	org.gnome.mutter.gschema.xml		\
 | 
			
		||||
	$(xml_DATA)				\
 | 
			
		||||
	mutter.schemas				\
 | 
			
		||||
	$(mutter_built_sources)			\
 | 
			
		||||
	$(typelib_DATA)				\
 | 
			
		||||
	$(gir_DATA)
 | 
			
		||||
@@ -297,18 +330,37 @@ EXTRA_DIST=$(desktopfiles_files) 	\
 | 
			
		||||
	$(IMAGES) 			\
 | 
			
		||||
	$(desktopfiles_in_files)	\
 | 
			
		||||
	$(wmproperties_in_files)	\
 | 
			
		||||
	$(xml_in_files)			\
 | 
			
		||||
	org.gnome.mutter.gschema.xml.in \
 | 
			
		||||
	mutter-schemas.convert \
 | 
			
		||||
	$(schema_in_files)		\
 | 
			
		||||
	libmutter.pc.in \
 | 
			
		||||
	mutter-plugins.pc.in  \
 | 
			
		||||
	mutter-enum-types.h.in \
 | 
			
		||||
	mutter-enum-types.c.in
 | 
			
		||||
	mutter-enum-types.c.in \
 | 
			
		||||
	mutter-marshal.list
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES += $(mutter_built_sources)
 | 
			
		||||
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
 | 
			
		||||
MUTTER_STAMP_FILES = stamp-mutter-marshal.h stamp-mutter-enum-types.h
 | 
			
		||||
CLEANFILES += $(MUTTER_STAMP_FILES)
 | 
			
		||||
 | 
			
		||||
mutter-marshal.h: stamp-mutter-marshal.h
 | 
			
		||||
	@true
 | 
			
		||||
stamp-mutter-marshal.h: Makefile mutter-marshal.list
 | 
			
		||||
	$(AM_V_GEN) $(GLIB_GENMARSHAL) \
 | 
			
		||||
		--prefix=_mutter_marshal \
 | 
			
		||||
		--header \
 | 
			
		||||
	$(srcdir)/mutter-marshal.list > xgen-tmh && \
 | 
			
		||||
	(cmp -s xgen-tmh mutter-marshal.h || cp -f xgen-tmh mutter-marshal.h) && \
 | 
			
		||||
	rm -f xgen-tmh && \
 | 
			
		||||
	echo timestamp > $(@F)
 | 
			
		||||
 | 
			
		||||
mutter-marshal.c: Makefile mutter-marshal.list
 | 
			
		||||
	 $(AM_V_GEN) (echo "#include \"mutter-marshal.h\"" ; \
 | 
			
		||||
	 $(GLIB_GENMARSHAL) \
 | 
			
		||||
		--prefix=_mutter_marshal \
 | 
			
		||||
		--body \
 | 
			
		||||
	 $(srcdir)/mutter-marshal.list ) > xgen-tmc && \
 | 
			
		||||
	cp -f xgen-tmc mutter-marshal.c && \
 | 
			
		||||
	rm -f xgen-tmc
 | 
			
		||||
 | 
			
		||||
mutter-enum-types.h: stamp-mutter-enum-types.h Makefile
 | 
			
		||||
	@true
 | 
			
		||||
stamp-mutter-enum-types.h: $(libmutterinclude_base_headers) mutter-enum-types.h.in
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,9 @@ struct _MetaCompScreen
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void meta_switch_workspace_completed (MetaScreen    *screen);
 | 
			
		||||
void meta_set_stage_input_region     (MetaScreen    *screen,
 | 
			
		||||
                                      XserverRegion  region);
 | 
			
		||||
void meta_empty_stage_input_region   (MetaScreen    *screen);
 | 
			
		||||
 | 
			
		||||
gboolean meta_begin_modal_for_plugin (MetaScreen       *screen,
 | 
			
		||||
                                      MetaPlugin       *plugin,
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,8 @@
 | 
			
		||||
#include "meta-background-actor-private.h"
 | 
			
		||||
#include "window-private.h" /* to check window->hidden */
 | 
			
		||||
#include "display-private.h" /* for meta_display_lookup_x_window() */
 | 
			
		||||
#include "core.h" /* for meta_core_select_events() */
 | 
			
		||||
#include "input-events.h"
 | 
			
		||||
#include <X11/extensions/shape.h>
 | 
			
		||||
#include <X11/extensions/Xcomposite.h>
 | 
			
		||||
 | 
			
		||||
@@ -155,7 +157,6 @@ get_output_window (MetaScreen *screen)
 | 
			
		||||
  MetaDisplay *display = meta_screen_get_display (screen);
 | 
			
		||||
  Display     *xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
  Window       output, xroot;
 | 
			
		||||
  XWindowAttributes attr;
 | 
			
		||||
  long         event_mask;
 | 
			
		||||
 | 
			
		||||
  xroot = meta_screen_get_xroot (screen);
 | 
			
		||||
@@ -169,13 +170,7 @@ get_output_window (MetaScreen *screen)
 | 
			
		||||
               KeyPressMask | KeyReleaseMask;
 | 
			
		||||
 | 
			
		||||
  output = XCompositeGetOverlayWindow (xdisplay, xroot);
 | 
			
		||||
 | 
			
		||||
  if (XGetWindowAttributes (xdisplay, output, &attr))
 | 
			
		||||
      {
 | 
			
		||||
        event_mask |= attr.your_event_mask;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  XSelectInput (xdisplay, output, event_mask);
 | 
			
		||||
  meta_core_select_events (xdisplay, output, event_mask, TRUE);
 | 
			
		||||
 | 
			
		||||
  return output;
 | 
			
		||||
}
 | 
			
		||||
@@ -347,26 +342,34 @@ meta_begin_modal_for_plugin (MetaScreen       *screen,
 | 
			
		||||
   * merge the two.
 | 
			
		||||
   */
 | 
			
		||||
  MetaDisplay    *display    = meta_screen_get_display (screen);
 | 
			
		||||
  Display        *xdpy       = meta_display_get_xdisplay (display);
 | 
			
		||||
  MetaCompositor *compositor = display->compositor;
 | 
			
		||||
  gboolean pointer_grabbed = FALSE;
 | 
			
		||||
  gboolean keyboard_grabbed = FALSE;
 | 
			
		||||
  int result;
 | 
			
		||||
  gboolean result;
 | 
			
		||||
  MetaDevice     *device;
 | 
			
		||||
  MetaGrabInfo   *grab_info;
 | 
			
		||||
 | 
			
		||||
  if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE)
 | 
			
		||||
  /* FIXME: need a real device here, and probably
 | 
			
		||||
   * some exclusion mode for other devices */
 | 
			
		||||
  device = meta_device_map_lookup (display->device_map,
 | 
			
		||||
                                   META_CORE_POINTER_ID);
 | 
			
		||||
 | 
			
		||||
  grab_info = meta_display_get_grab_info (display, device);
 | 
			
		||||
 | 
			
		||||
  if (compositor->modal_plugin != NULL || grab_info != NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0)
 | 
			
		||||
    {
 | 
			
		||||
      result = XGrabPointer (xdpy, grab_window,
 | 
			
		||||
                             False, /* owner_events */
 | 
			
		||||
                             (ButtonPressMask | ButtonReleaseMask |
 | 
			
		||||
                              EnterWindowMask | LeaveWindowMask | PointerMotionMask),
 | 
			
		||||
                             GrabModeAsync, GrabModeAsync,
 | 
			
		||||
                             None, /* confine to */
 | 
			
		||||
                             cursor,
 | 
			
		||||
                             timestamp);
 | 
			
		||||
      if (result != Success)
 | 
			
		||||
      result = meta_device_grab (device,
 | 
			
		||||
                                 grab_window,
 | 
			
		||||
                                 (ButtonPressMask | ButtonReleaseMask |
 | 
			
		||||
                                  EnterWindowMask | LeaveWindowMask | PointerMotionMask),
 | 
			
		||||
                                 cursor,
 | 
			
		||||
                                 FALSE,
 | 
			
		||||
                                 FALSE,
 | 
			
		||||
                                 timestamp);
 | 
			
		||||
      if (!result)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
      pointer_grabbed = TRUE;
 | 
			
		||||
@@ -374,22 +377,25 @@ meta_begin_modal_for_plugin (MetaScreen       *screen,
 | 
			
		||||
 | 
			
		||||
  if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0)
 | 
			
		||||
    {
 | 
			
		||||
      result = XGrabKeyboard (xdpy, grab_window,
 | 
			
		||||
                              False, /* owner_events */
 | 
			
		||||
                              GrabModeAsync, GrabModeAsync,
 | 
			
		||||
                              timestamp);
 | 
			
		||||
 | 
			
		||||
      if (result != Success)
 | 
			
		||||
      result = meta_device_grab (meta_device_get_paired_device (device),
 | 
			
		||||
                                 grab_window,
 | 
			
		||||
                                 (KeyPressMask | KeyReleaseMask),
 | 
			
		||||
                                 META_CURSOR_DEFAULT,
 | 
			
		||||
                                 FALSE, FALSE,
 | 
			
		||||
                                 timestamp);
 | 
			
		||||
      if (!result)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
      keyboard_grabbed = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  display->grab_op = META_GRAB_OP_COMPOSITOR;
 | 
			
		||||
  display->grab_window = NULL;
 | 
			
		||||
  display->grab_screen = screen;
 | 
			
		||||
  display->grab_have_pointer = TRUE;
 | 
			
		||||
  display->grab_have_keyboard = TRUE;
 | 
			
		||||
  grab_info = meta_display_create_grab_info (display, device);
 | 
			
		||||
 | 
			
		||||
  grab_info->grab_op = META_GRAB_OP_COMPOSITOR;
 | 
			
		||||
  grab_info->grab_window = NULL;
 | 
			
		||||
  grab_info->grab_screen = screen;
 | 
			
		||||
  grab_info->grab_have_pointer = TRUE;
 | 
			
		||||
  grab_info->grab_have_keyboard = TRUE;
 | 
			
		||||
 | 
			
		||||
  compositor->modal_plugin = plugin;
 | 
			
		||||
 | 
			
		||||
@@ -397,9 +403,9 @@ meta_begin_modal_for_plugin (MetaScreen       *screen,
 | 
			
		||||
 | 
			
		||||
 fail:
 | 
			
		||||
  if (pointer_grabbed)
 | 
			
		||||
    XUngrabPointer (xdpy, timestamp);
 | 
			
		||||
    meta_device_ungrab (device, timestamp);
 | 
			
		||||
  if (keyboard_grabbed)
 | 
			
		||||
    XUngrabKeyboard (xdpy, timestamp);
 | 
			
		||||
    meta_device_ungrab (meta_device_get_paired_device (device), timestamp);
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
@@ -410,20 +416,19 @@ meta_end_modal_for_plugin (MetaScreen     *screen,
 | 
			
		||||
                           guint32         timestamp)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay    *display    = meta_screen_get_display (screen);
 | 
			
		||||
  Display        *xdpy = meta_display_get_xdisplay (display);
 | 
			
		||||
  MetaCompositor *compositor = display->compositor;
 | 
			
		||||
  MetaDevice     *device;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (compositor->modal_plugin == plugin);
 | 
			
		||||
 | 
			
		||||
  XUngrabPointer (xdpy, timestamp);
 | 
			
		||||
  XUngrabKeyboard (xdpy, timestamp);
 | 
			
		||||
  /* FIXME: need a real device here */
 | 
			
		||||
  device = meta_device_map_lookup (display->device_map,
 | 
			
		||||
                                   META_CORE_POINTER_ID);
 | 
			
		||||
 | 
			
		||||
  display->grab_op = META_GRAB_OP_NONE;
 | 
			
		||||
  display->grab_window = NULL;
 | 
			
		||||
  display->grab_screen = NULL;
 | 
			
		||||
  display->grab_have_pointer = FALSE;
 | 
			
		||||
  display->grab_have_keyboard = FALSE;
 | 
			
		||||
  meta_device_ungrab (device, timestamp);
 | 
			
		||||
  meta_device_ungrab (meta_device_get_paired_device (device), timestamp);
 | 
			
		||||
 | 
			
		||||
  meta_display_remove_grab_info (display, device);
 | 
			
		||||
  compositor->modal_plugin = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -456,7 +461,6 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
  Window          xroot         = meta_screen_get_xroot (screen);
 | 
			
		||||
  Window          xwin;
 | 
			
		||||
  gint            width, height;
 | 
			
		||||
  XWindowAttributes attr;
 | 
			
		||||
  long            event_mask;
 | 
			
		||||
  guint           n_retries;
 | 
			
		||||
  guint           max_retries;
 | 
			
		||||
@@ -515,15 +519,13 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
 | 
			
		||||
  meta_screen_set_cm_selection (screen);
 | 
			
		||||
 | 
			
		||||
  info->stage = clutter_stage_new ();
 | 
			
		||||
  info->stage = clutter_stage_get_default ();
 | 
			
		||||
 | 
			
		||||
  meta_screen_get_size (screen, &width, &height);
 | 
			
		||||
  clutter_actor_realize (info->stage);
 | 
			
		||||
  clutter_actor_set_size (info->stage, width, height);
 | 
			
		||||
 | 
			
		||||
  xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
 | 
			
		||||
 | 
			
		||||
  XResizeWindow (xdisplay, xwin, width, height);
 | 
			
		||||
 | 
			
		||||
  event_mask = FocusChangeMask |
 | 
			
		||||
               ExposureMask |
 | 
			
		||||
               EnterWindowMask | LeaveWindowMask |
 | 
			
		||||
@@ -533,12 +535,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
               KeyPressMask | KeyReleaseMask |
 | 
			
		||||
               StructureNotifyMask;
 | 
			
		||||
 | 
			
		||||
  if (XGetWindowAttributes (xdisplay, xwin, &attr))
 | 
			
		||||
      {
 | 
			
		||||
        event_mask |= attr.your_event_mask;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
  XSelectInput (xdisplay, xwin, event_mask);
 | 
			
		||||
  meta_core_select_events (xdisplay, xwin, event_mask, TRUE);
 | 
			
		||||
 | 
			
		||||
  info->window_group = meta_window_group_new (screen);
 | 
			
		||||
  info->background_actor = meta_background_actor_new_for_screen (screen);
 | 
			
		||||
@@ -557,7 +554,9 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
 | 
			
		||||
 | 
			
		||||
  clutter_actor_hide (info->hidden_group);
 | 
			
		||||
 | 
			
		||||
  info->plugin_mgr = meta_plugin_manager_new (screen);
 | 
			
		||||
  info->plugin_mgr =
 | 
			
		||||
    meta_plugin_manager_get (screen);
 | 
			
		||||
  meta_plugin_manager_initialize (info->plugin_mgr);
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Delay the creation of the overlay window as long as we can, to avoid
 | 
			
		||||
@@ -695,9 +694,15 @@ meta_compositor_set_updates (MetaCompositor *compositor,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_grabbed_event (XEvent *event)
 | 
			
		||||
is_grabbed_event (MetaDisplay *display,
 | 
			
		||||
                  XEvent      *event)
 | 
			
		||||
{
 | 
			
		||||
  switch (event->xany.type)
 | 
			
		||||
  guint evtype;
 | 
			
		||||
 | 
			
		||||
  if (!meta_input_event_get_type (display, event, &evtype))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  switch (evtype)
 | 
			
		||||
    {
 | 
			
		||||
    case ButtonPress:
 | 
			
		||||
    case ButtonRelease:
 | 
			
		||||
@@ -730,7 +735,8 @@ meta_compositor_process_event (MetaCompositor *compositor,
 | 
			
		||||
                               XEvent         *event,
 | 
			
		||||
                               MetaWindow     *window)
 | 
			
		||||
{
 | 
			
		||||
  if (compositor->modal_plugin && is_grabbed_event (event))
 | 
			
		||||
  if (compositor->modal_plugin &&
 | 
			
		||||
      is_grabbed_event (compositor->display, event))
 | 
			
		||||
    {
 | 
			
		||||
      MetaPluginClass *klass = META_PLUGIN_GET_CLASS (compositor->modal_plugin);
 | 
			
		||||
 | 
			
		||||
@@ -869,6 +875,29 @@ meta_compositor_unmaximize_window (MetaCompositor    *compositor,
 | 
			
		||||
  meta_window_actor_unmaximize (window_actor, old_rect, new_rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_update_workspace_geometry (MetaCompositor *compositor,
 | 
			
		||||
                                           MetaWorkspace  *workspace)
 | 
			
		||||
{
 | 
			
		||||
#if 0
 | 
			
		||||
  /* FIXME -- should do away with this function in favour of MetaWorkspace
 | 
			
		||||
   * signal.
 | 
			
		||||
   */
 | 
			
		||||
  MetaScreen     *screen = meta_workspace_get_screen (workspace);
 | 
			
		||||
  MetaCompScreen *info;
 | 
			
		||||
  MetaPluginManager *mgr;
 | 
			
		||||
 | 
			
		||||
  DEBUG_TRACE ("meta_compositor_update_workspace_geometry\n");
 | 
			
		||||
  info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
  mgr  = info->plugin_mgr;
 | 
			
		||||
 | 
			
		||||
  if (!mgr || !workspace)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_plugin_manager_update_workspace (mgr, workspace);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_switch_workspace (MetaCompositor     *compositor,
 | 
			
		||||
                                  MetaScreen         *screen,
 | 
			
		||||
@@ -1116,18 +1145,12 @@ meta_compositor_sync_screen_size (MetaCompositor  *compositor,
 | 
			
		||||
				  guint		   width,
 | 
			
		||||
				  guint		   height)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay    *display = meta_screen_get_display (screen);
 | 
			
		||||
  MetaCompScreen *info    = meta_screen_get_compositor_data (screen);
 | 
			
		||||
  Display        *xdisplay;
 | 
			
		||||
  Window          xwin;
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (screen);
 | 
			
		||||
 | 
			
		||||
  DEBUG_TRACE ("meta_compositor_sync_screen_size\n");
 | 
			
		||||
  g_return_if_fail (info);
 | 
			
		||||
 | 
			
		||||
  xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
  xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
 | 
			
		||||
 | 
			
		||||
  XResizeWindow (xdisplay, xwin, width, height);
 | 
			
		||||
  clutter_actor_set_size (info->stage, width, height);
 | 
			
		||||
 | 
			
		||||
  meta_background_actor_screen_size_changed (screen);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,9 +28,6 @@
 | 
			
		||||
#define COGL_ENABLE_EXPERIMENTAL_API
 | 
			
		||||
#include <cogl/cogl-texture-pixmap-x11.h>
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
 | 
			
		||||
#include "cogl-utils.h"
 | 
			
		||||
@@ -255,8 +252,6 @@ meta_background_actor_dispose (GObject *object)
 | 
			
		||||
      cogl_handle_unref (priv->material);
 | 
			
		||||
      priv->material = COGL_INVALID_HANDLE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -542,11 +537,9 @@ meta_background_actor_update (MetaScreen *screen)
 | 
			
		||||
  if (root_pixmap_id != None)
 | 
			
		||||
    {
 | 
			
		||||
      CoglHandle texture;
 | 
			
		||||
      CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
      GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
      meta_error_trap_push (display);
 | 
			
		||||
      texture = cogl_texture_pixmap_x11_new (ctx, root_pixmap_id, FALSE, &error);
 | 
			
		||||
      texture = cogl_texture_pixmap_x11_new (root_pixmap_id, FALSE);
 | 
			
		||||
      meta_error_trap_pop (display);
 | 
			
		||||
 | 
			
		||||
      if (texture != COGL_INVALID_HANDLE)
 | 
			
		||||
@@ -557,12 +550,6 @@ meta_background_actor_update (MetaScreen *screen)
 | 
			
		||||
          background->have_pixmap = True;
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          g_warning ("Failed to create background texture from pixmap: %s",
 | 
			
		||||
                     error->message);
 | 
			
		||||
          g_error_free (error);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  background->have_pixmap = False;
 | 
			
		||||
 
 | 
			
		||||
@@ -35,32 +35,34 @@
 | 
			
		||||
 | 
			
		||||
#include <clutter/x11/clutter-x11.h>
 | 
			
		||||
 | 
			
		||||
static GType plugin_type = G_TYPE_NONE;
 | 
			
		||||
static GSList *plugin_types;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * We have one "default plugin manager" that acts for the first screen,
 | 
			
		||||
 * but also can be used before we open any screens, and additional
 | 
			
		||||
 * plugin managers for each screen. (This is ugly. Probably we should
 | 
			
		||||
 * have one plugin manager and only make the plugins per-screen.)
 | 
			
		||||
 */
 | 
			
		||||
static MetaPluginManager *default_plugin_manager;
 | 
			
		||||
 | 
			
		||||
struct MetaPluginManager
 | 
			
		||||
{
 | 
			
		||||
  MetaScreen *screen;
 | 
			
		||||
  MetaPlugin *plugin;
 | 
			
		||||
  MetaScreen   *screen;
 | 
			
		||||
 | 
			
		||||
  GList /* MetaPlugin */ *plugins;  /* TODO -- maybe use hash table */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_manager_set_plugin_type (GType gtype)
 | 
			
		||||
{
 | 
			
		||||
  if (plugin_type != G_TYPE_NONE)
 | 
			
		||||
    meta_fatal ("Mutter plugin already set: %s", g_type_name (plugin_type));
 | 
			
		||||
 | 
			
		||||
  plugin_type = gtype;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Loads the given plugin.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_manager_load (const gchar       *plugin_name)
 | 
			
		||||
meta_plugin_manager_load (MetaPluginManager *plugin_mgr,
 | 
			
		||||
                          const gchar       *plugin_name)
 | 
			
		||||
{
 | 
			
		||||
  const gchar *dpath = MUTTER_PLUGIN_DIR "/";
 | 
			
		||||
  gchar       *path;
 | 
			
		||||
  MetaModule  *module;
 | 
			
		||||
  GType        plugin_type;
 | 
			
		||||
 | 
			
		||||
  if (g_path_is_absolute (plugin_name))
 | 
			
		||||
    path = g_strdup (plugin_name);
 | 
			
		||||
@@ -79,57 +81,162 @@ meta_plugin_manager_load (const gchar       *plugin_name)
 | 
			
		||||
      exit (1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_plugin_manager_set_plugin_type (meta_module_get_plugin_type (module));
 | 
			
		||||
  plugin_type = meta_module_get_plugin_type (module);
 | 
			
		||||
  meta_plugin_manager_register (plugin_mgr, plugin_type);
 | 
			
		||||
 | 
			
		||||
  g_type_module_unuse (G_TYPE_MODULE (module));
 | 
			
		||||
  g_free (path);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaPluginManager *
 | 
			
		||||
/*
 | 
			
		||||
 * Registers the given plugin type
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_manager_register (MetaPluginManager *plugin_mgr,
 | 
			
		||||
                              GType              plugin_type)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin  *plugin;
 | 
			
		||||
 | 
			
		||||
  plugin_types = g_slist_prepend (plugin_types, GSIZE_TO_POINTER (plugin_type));
 | 
			
		||||
 | 
			
		||||
  plugin = g_object_new (plugin_type, NULL);
 | 
			
		||||
  plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, plugin);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_manager_initialize (MetaPluginManager *plugin_mgr)
 | 
			
		||||
{
 | 
			
		||||
  GList *iter;
 | 
			
		||||
 | 
			
		||||
  if (!plugin_mgr->plugins)
 | 
			
		||||
    {
 | 
			
		||||
      /*
 | 
			
		||||
       * If no plugins are specified, load the default plugin.
 | 
			
		||||
       */
 | 
			
		||||
      meta_plugin_manager_load (plugin_mgr, "default");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  for (iter = plugin_mgr->plugins; iter; iter = iter->next)
 | 
			
		||||
    {
 | 
			
		||||
      MetaPlugin *plugin = (MetaPlugin*) iter->data;
 | 
			
		||||
      MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
 | 
			
		||||
      g_object_set (plugin,
 | 
			
		||||
                    "screen", plugin_mgr->screen,
 | 
			
		||||
                    NULL);
 | 
			
		||||
 | 
			
		||||
      if (klass->start)
 | 
			
		||||
        klass->start (plugin);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaPluginManager *
 | 
			
		||||
meta_plugin_manager_new (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginManager *plugin_mgr;
 | 
			
		||||
  MetaPluginClass *klass;
 | 
			
		||||
  MetaPlugin *plugin;
 | 
			
		||||
 | 
			
		||||
  plugin_mgr = g_new0 (MetaPluginManager, 1);
 | 
			
		||||
  plugin_mgr->screen = screen;
 | 
			
		||||
  plugin_mgr->plugin = plugin = g_object_new (plugin_type, "screen", screen, NULL);
 | 
			
		||||
 | 
			
		||||
  klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
 | 
			
		||||
  if (klass->start)
 | 
			
		||||
    klass->start (plugin);
 | 
			
		||||
  if (screen)
 | 
			
		||||
    g_object_set_data (G_OBJECT (screen), "meta-plugin-manager", plugin_mgr);
 | 
			
		||||
 | 
			
		||||
  return plugin_mgr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaPluginManager *
 | 
			
		||||
meta_plugin_manager_get_default (void)
 | 
			
		||||
{
 | 
			
		||||
  if (!default_plugin_manager)
 | 
			
		||||
    {
 | 
			
		||||
      default_plugin_manager = meta_plugin_manager_new (NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return default_plugin_manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaPluginManager *
 | 
			
		||||
meta_plugin_manager_get (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginManager *plugin_mgr;
 | 
			
		||||
 | 
			
		||||
  plugin_mgr = g_object_get_data (G_OBJECT (screen), "meta-plugin-manager");
 | 
			
		||||
  if (plugin_mgr)
 | 
			
		||||
    return plugin_mgr;
 | 
			
		||||
 | 
			
		||||
  if (!default_plugin_manager)
 | 
			
		||||
    meta_plugin_manager_get_default ();
 | 
			
		||||
 | 
			
		||||
  if (!default_plugin_manager->screen)
 | 
			
		||||
    {
 | 
			
		||||
      /* The default plugin manager is so far unused, we can recycle it */
 | 
			
		||||
      default_plugin_manager->screen = screen;
 | 
			
		||||
      g_object_set_data (G_OBJECT (screen), "meta-plugin-manager", default_plugin_manager);
 | 
			
		||||
 | 
			
		||||
      return default_plugin_manager;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      GSList *iter;
 | 
			
		||||
      GType plugin_type;
 | 
			
		||||
      MetaPlugin *plugin;
 | 
			
		||||
 | 
			
		||||
      plugin_mgr = meta_plugin_manager_new (screen);
 | 
			
		||||
 | 
			
		||||
      for (iter = plugin_types; iter; iter = iter->next)
 | 
			
		||||
        {
 | 
			
		||||
          plugin_type = (GType)GPOINTER_TO_SIZE (iter->data);
 | 
			
		||||
          plugin = g_object_new (plugin_type, "screen", screen,  NULL);
 | 
			
		||||
          plugin_mgr->plugins = g_list_prepend (plugin_mgr->plugins, plugin);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      return plugin_mgr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_plugin_manager_kill_window_effects (MetaPluginManager *plugin_mgr,
 | 
			
		||||
                                         MetaWindowActor   *actor)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin        *plugin = plugin_mgr->plugin;
 | 
			
		||||
  MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
  GList *l = plugin_mgr->plugins;
 | 
			
		||||
 | 
			
		||||
  if (klass->kill_window_effects)
 | 
			
		||||
    klass->kill_window_effects (plugin, actor);
 | 
			
		||||
  while (l)
 | 
			
		||||
    {
 | 
			
		||||
      MetaPlugin        *plugin = l->data;
 | 
			
		||||
      MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
 | 
			
		||||
      if (!meta_plugin_disabled (plugin)
 | 
			
		||||
	  && klass->kill_window_effects)
 | 
			
		||||
        klass->kill_window_effects (plugin, actor);
 | 
			
		||||
 | 
			
		||||
      l = l->next;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_plugin_manager_kill_switch_workspace (MetaPluginManager *plugin_mgr)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin        *plugin = plugin_mgr->plugin;
 | 
			
		||||
  MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
  GList *l = plugin_mgr->plugins;
 | 
			
		||||
 | 
			
		||||
  if (klass->kill_switch_workspace)
 | 
			
		||||
    klass->kill_switch_workspace (plugin);
 | 
			
		||||
  while (l)
 | 
			
		||||
    {
 | 
			
		||||
      MetaPlugin        *plugin = l->data;
 | 
			
		||||
      MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
 | 
			
		||||
      if (!meta_plugin_disabled (plugin)
 | 
			
		||||
          && (meta_plugin_features (plugin) & META_PLUGIN_SWITCH_WORKSPACE)
 | 
			
		||||
	  && klass->kill_switch_workspace)
 | 
			
		||||
        klass->kill_switch_workspace (plugin);
 | 
			
		||||
 | 
			
		||||
      l = l->next;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public method that the compositor hooks into for events that require
 | 
			
		||||
 * no additional parameters.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns TRUE if the plugin handled the event type (i.e.,
 | 
			
		||||
 * Returns TRUE if at least one of the plugins handled the event type (i.e.,
 | 
			
		||||
 * if the return value is FALSE, there will be no subsequent call to the
 | 
			
		||||
 * manager completed() callback, and the compositor must ensure that any
 | 
			
		||||
 * appropriate post-effect cleanup is carried out.
 | 
			
		||||
@@ -139,48 +246,60 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
 | 
			
		||||
                                  MetaWindowActor   *actor,
 | 
			
		||||
                                  unsigned long      event)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin *plugin = plugin_mgr->plugin;
 | 
			
		||||
  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
  MetaDisplay *display  = meta_screen_get_display (plugin_mgr->screen);
 | 
			
		||||
  GList *l = plugin_mgr->plugins;
 | 
			
		||||
  gboolean retval = FALSE;
 | 
			
		||||
  MetaDisplay *display  = meta_screen_get_display (plugin_mgr->screen);
 | 
			
		||||
 | 
			
		||||
  if (display->display_opening)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  switch (event)
 | 
			
		||||
  while (l)
 | 
			
		||||
    {
 | 
			
		||||
    case META_PLUGIN_MINIMIZE:
 | 
			
		||||
      if (klass->minimize)
 | 
			
		||||
        {
 | 
			
		||||
          retval = TRUE;
 | 
			
		||||
          meta_plugin_manager_kill_window_effects (plugin_mgr,
 | 
			
		||||
                                                   actor);
 | 
			
		||||
      MetaPlugin        *plugin = l->data;
 | 
			
		||||
      MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
 | 
			
		||||
          _meta_plugin_effect_started (plugin);
 | 
			
		||||
          klass->minimize (plugin, actor);
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PLUGIN_MAP:
 | 
			
		||||
      if (klass->map)
 | 
			
		||||
      if (!meta_plugin_disabled (plugin) &&
 | 
			
		||||
          (meta_plugin_features (plugin) & event))
 | 
			
		||||
        {
 | 
			
		||||
          retval = TRUE;
 | 
			
		||||
          meta_plugin_manager_kill_window_effects (plugin_mgr,
 | 
			
		||||
                                                   actor);
 | 
			
		||||
 | 
			
		||||
          _meta_plugin_effect_started (plugin);
 | 
			
		||||
          klass->map (plugin, actor);
 | 
			
		||||
          switch (event)
 | 
			
		||||
            {
 | 
			
		||||
            case META_PLUGIN_MINIMIZE:
 | 
			
		||||
              if (klass->minimize)
 | 
			
		||||
                {
 | 
			
		||||
                  meta_plugin_manager_kill_window_effects (
 | 
			
		||||
		      plugin_mgr,
 | 
			
		||||
		      actor);
 | 
			
		||||
 | 
			
		||||
                  _meta_plugin_effect_started (plugin);
 | 
			
		||||
                  klass->minimize (plugin, actor);
 | 
			
		||||
                }
 | 
			
		||||
              break;
 | 
			
		||||
            case META_PLUGIN_MAP:
 | 
			
		||||
              if (klass->map)
 | 
			
		||||
                {
 | 
			
		||||
                  meta_plugin_manager_kill_window_effects (
 | 
			
		||||
		      plugin_mgr,
 | 
			
		||||
		      actor);
 | 
			
		||||
 | 
			
		||||
                  _meta_plugin_effect_started (plugin);
 | 
			
		||||
                  klass->map (plugin, actor);
 | 
			
		||||
                }
 | 
			
		||||
              break;
 | 
			
		||||
            case META_PLUGIN_DESTROY:
 | 
			
		||||
              if (klass->destroy)
 | 
			
		||||
                {
 | 
			
		||||
                  _meta_plugin_effect_started (plugin);
 | 
			
		||||
                  klass->destroy (plugin, actor);
 | 
			
		||||
                }
 | 
			
		||||
              break;
 | 
			
		||||
            default:
 | 
			
		||||
              g_warning ("Incorrect handler called for event %lu", event);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PLUGIN_DESTROY:
 | 
			
		||||
      if (klass->destroy)
 | 
			
		||||
        {
 | 
			
		||||
          retval = TRUE;
 | 
			
		||||
          _meta_plugin_effect_started (plugin);
 | 
			
		||||
          klass->destroy (plugin, actor);
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      g_warning ("Incorrect handler called for event %lu", event);
 | 
			
		||||
 | 
			
		||||
      l = l->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return retval;
 | 
			
		||||
@@ -190,7 +309,7 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
 | 
			
		||||
 * The public method that the compositor hooks into for maximize and unmaximize
 | 
			
		||||
 * events.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns TRUE if the plugin handled the event type (i.e.,
 | 
			
		||||
 * Returns TRUE if at least one of the plugins handled the event type (i.e.,
 | 
			
		||||
 * if the return value is FALSE, there will be no subsequent call to the
 | 
			
		||||
 * manager completed() callback, and the compositor must ensure that any
 | 
			
		||||
 * appropriate post-effect cleanup is carried out.
 | 
			
		||||
@@ -204,44 +323,57 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
 | 
			
		||||
                                    gint               target_width,
 | 
			
		||||
                                    gint               target_height)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin *plugin = plugin_mgr->plugin;
 | 
			
		||||
  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
  MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
 | 
			
		||||
  GList *l = plugin_mgr->plugins;
 | 
			
		||||
  gboolean retval = FALSE;
 | 
			
		||||
  MetaDisplay *display  = meta_screen_get_display (plugin_mgr->screen);
 | 
			
		||||
 | 
			
		||||
  if (display->display_opening)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  switch (event)
 | 
			
		||||
  while (l)
 | 
			
		||||
    {
 | 
			
		||||
    case META_PLUGIN_MAXIMIZE:
 | 
			
		||||
      if (klass->maximize)
 | 
			
		||||
      MetaPlugin        *plugin = l->data;
 | 
			
		||||
      MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
 | 
			
		||||
      if (!meta_plugin_disabled (plugin) &&
 | 
			
		||||
          (meta_plugin_features (plugin) & event))
 | 
			
		||||
        {
 | 
			
		||||
          retval = TRUE;
 | 
			
		||||
          meta_plugin_manager_kill_window_effects (plugin_mgr,
 | 
			
		||||
                                                   actor);
 | 
			
		||||
 | 
			
		||||
          _meta_plugin_effect_started (plugin);
 | 
			
		||||
          klass->maximize (plugin, actor,
 | 
			
		||||
                           target_x, target_y,
 | 
			
		||||
                           target_width, target_height);
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PLUGIN_UNMAXIMIZE:
 | 
			
		||||
      if (klass->unmaximize)
 | 
			
		||||
        {
 | 
			
		||||
          retval = TRUE;
 | 
			
		||||
          meta_plugin_manager_kill_window_effects (plugin_mgr,
 | 
			
		||||
                                                   actor);
 | 
			
		||||
          switch (event)
 | 
			
		||||
            {
 | 
			
		||||
            case META_PLUGIN_MAXIMIZE:
 | 
			
		||||
              if (klass->maximize)
 | 
			
		||||
                {
 | 
			
		||||
                  meta_plugin_manager_kill_window_effects (
 | 
			
		||||
		      plugin_mgr,
 | 
			
		||||
		      actor);
 | 
			
		||||
 | 
			
		||||
          _meta_plugin_effect_started (plugin);
 | 
			
		||||
          klass->unmaximize (plugin, actor,
 | 
			
		||||
                             target_x, target_y,
 | 
			
		||||
                             target_width, target_height);
 | 
			
		||||
                  _meta_plugin_effect_started (plugin);
 | 
			
		||||
                  klass->maximize (plugin, actor,
 | 
			
		||||
                                   target_x, target_y,
 | 
			
		||||
                                   target_width, target_height);
 | 
			
		||||
                }
 | 
			
		||||
              break;
 | 
			
		||||
            case META_PLUGIN_UNMAXIMIZE:
 | 
			
		||||
              if (klass->unmaximize)
 | 
			
		||||
                {
 | 
			
		||||
                  meta_plugin_manager_kill_window_effects (
 | 
			
		||||
		      plugin_mgr,
 | 
			
		||||
		      actor);
 | 
			
		||||
 | 
			
		||||
                  _meta_plugin_effect_started (plugin);
 | 
			
		||||
                  klass->unmaximize (plugin, actor,
 | 
			
		||||
                                     target_x, target_y,
 | 
			
		||||
                                     target_width, target_height);
 | 
			
		||||
                }
 | 
			
		||||
              break;
 | 
			
		||||
            default:
 | 
			
		||||
              g_warning ("Incorrect handler called for event %lu", event);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      g_warning ("Incorrect handler called for event %lu", event);
 | 
			
		||||
 | 
			
		||||
      l = l->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return retval;
 | 
			
		||||
@@ -250,7 +382,7 @@ meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
 | 
			
		||||
/*
 | 
			
		||||
 * The public method that the compositor hooks into for desktop switching.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns TRUE if the plugin handled the event type (i.e.,
 | 
			
		||||
 * Returns TRUE if at least one of the plugins handled the event type (i.e.,
 | 
			
		||||
 * if the return value is FALSE, there will be no subsequent call to the
 | 
			
		||||
 * manager completed() callback, and the compositor must ensure that any
 | 
			
		||||
 * appropriate post-effect cleanup is carried out.
 | 
			
		||||
@@ -261,21 +393,32 @@ meta_plugin_manager_switch_workspace (MetaPluginManager   *plugin_mgr,
 | 
			
		||||
                                      gint                 to,
 | 
			
		||||
                                      MetaMotionDirection  direction)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin *plugin = plugin_mgr->plugin;
 | 
			
		||||
  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
  MetaDisplay *display = meta_screen_get_display (plugin_mgr->screen);
 | 
			
		||||
  GList *l = plugin_mgr->plugins;
 | 
			
		||||
  gboolean retval = FALSE;
 | 
			
		||||
  MetaDisplay *display  = meta_screen_get_display (plugin_mgr->screen);
 | 
			
		||||
 | 
			
		||||
  if (display->display_opening)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (klass->switch_workspace)
 | 
			
		||||
  while (l)
 | 
			
		||||
    {
 | 
			
		||||
      retval = TRUE;
 | 
			
		||||
      meta_plugin_manager_kill_switch_workspace (plugin_mgr);
 | 
			
		||||
      MetaPlugin        *plugin = l->data;
 | 
			
		||||
      MetaPluginClass   *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
 | 
			
		||||
      _meta_plugin_effect_started (plugin);
 | 
			
		||||
      klass->switch_workspace (plugin, from, to, direction);
 | 
			
		||||
      if (!meta_plugin_disabled (plugin) &&
 | 
			
		||||
          (meta_plugin_features (plugin) & META_PLUGIN_SWITCH_WORKSPACE))
 | 
			
		||||
        {
 | 
			
		||||
          if (klass->switch_workspace)
 | 
			
		||||
            {
 | 
			
		||||
              retval = TRUE;
 | 
			
		||||
              meta_plugin_manager_kill_switch_workspace (plugin_mgr);
 | 
			
		||||
 | 
			
		||||
              _meta_plugin_effect_started (plugin);
 | 
			
		||||
              klass->switch_workspace (plugin, from, to, direction);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      l = l->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return retval;
 | 
			
		||||
@@ -284,7 +427,7 @@ meta_plugin_manager_switch_workspace (MetaPluginManager   *plugin_mgr,
 | 
			
		||||
/*
 | 
			
		||||
 * The public method that the compositor hooks into for desktop switching.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns TRUE if the plugin handled the event type (i.e.,
 | 
			
		||||
 * Returns TRUE if at least one of the plugins handled the event type (i.e.,
 | 
			
		||||
 * if the return value is FALSE, there will be no subsequent call to the
 | 
			
		||||
 * manager completed() callback, and the compositor must ensure that any
 | 
			
		||||
 * appropriate post-effect cleanup is carried out.
 | 
			
		||||
@@ -293,20 +436,49 @@ gboolean
 | 
			
		||||
meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr,
 | 
			
		||||
                                   XEvent            *xev)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin *plugin = plugin_mgr->plugin;
 | 
			
		||||
  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
  GList *l;
 | 
			
		||||
  gboolean have_plugin_xevent_func;
 | 
			
		||||
 | 
			
		||||
  if (!plugin_mgr)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  l = plugin_mgr->plugins;
 | 
			
		||||
 | 
			
		||||
  /* We need to make sure that clutter gets certain events, like
 | 
			
		||||
   * ConfigureNotify on the stage window. If there is a plugin that
 | 
			
		||||
   * provides an xevent_filter function, then it's the responsibility
 | 
			
		||||
   * of that plugin to pass events to Clutter. Otherwise, we send the
 | 
			
		||||
   * event directly to Clutter ourselves.
 | 
			
		||||
   *
 | 
			
		||||
   * What happens if there are two plugins with xevent_filter functions
 | 
			
		||||
   * is undefined; in general, multiple competing plugins are something
 | 
			
		||||
   * we don't support well or care much about.
 | 
			
		||||
   *
 | 
			
		||||
   * FIXME: Really, we should just always handle sending the event to
 | 
			
		||||
   *  clutter if a plugin doesn't report the event as handled by
 | 
			
		||||
   *  returning TRUE, but it doesn't seem worth breaking compatibility
 | 
			
		||||
   *  of the plugin interface right now to achieve this; the way it is
 | 
			
		||||
   *  now works fine in practice.
 | 
			
		||||
   */
 | 
			
		||||
  if (klass->xevent_filter && klass->xevent_filter (plugin, xev))
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  else
 | 
			
		||||
  have_plugin_xevent_func = FALSE;
 | 
			
		||||
 | 
			
		||||
  while (l)
 | 
			
		||||
    {
 | 
			
		||||
      MetaPlugin      *plugin = l->data;
 | 
			
		||||
      MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
 | 
			
		||||
      if (klass->xevent_filter)
 | 
			
		||||
        {
 | 
			
		||||
          have_plugin_xevent_func = TRUE;
 | 
			
		||||
          if (klass->xevent_filter (plugin, xev) == TRUE)
 | 
			
		||||
            return TRUE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      l = l->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!have_plugin_xevent_func)
 | 
			
		||||
    return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -46,9 +46,14 @@
 | 
			
		||||
 */
 | 
			
		||||
typedef struct MetaPluginManager MetaPluginManager;
 | 
			
		||||
 | 
			
		||||
MetaPluginManager * meta_plugin_manager_new (MetaScreen *screen);
 | 
			
		||||
MetaPluginManager * meta_plugin_manager_get         (MetaScreen *screen);
 | 
			
		||||
MetaPluginManager * meta_plugin_manager_get_default (void);
 | 
			
		||||
 | 
			
		||||
void     meta_plugin_manager_load         (const gchar       *plugin_name);
 | 
			
		||||
void     meta_plugin_manager_load         (MetaPluginManager *mgr,
 | 
			
		||||
                                           const gchar       *plugin_name);
 | 
			
		||||
void     meta_plugin_manager_register     (MetaPluginManager *mgr,
 | 
			
		||||
                                           GType              plugin_type);
 | 
			
		||||
void     meta_plugin_manager_initialize   (MetaPluginManager *mgr);
 | 
			
		||||
 | 
			
		||||
gboolean meta_plugin_manager_event_simple (MetaPluginManager *mgr,
 | 
			
		||||
                                           MetaWindowActor   *actor,
 | 
			
		||||
@@ -61,6 +66,10 @@ gboolean meta_plugin_manager_event_maximize    (MetaPluginManager *mgr,
 | 
			
		||||
                                                gint               target_y,
 | 
			
		||||
                                                gint               target_width,
 | 
			
		||||
                                                gint               target_height);
 | 
			
		||||
void     meta_plugin_manager_update_workspaces (MetaPluginManager *mgr);
 | 
			
		||||
 | 
			
		||||
void meta_plugin_manager_update_workspace (MetaPluginManager *mgr,
 | 
			
		||||
                                           MetaWorkspace     *w);
 | 
			
		||||
 | 
			
		||||
gboolean meta_plugin_manager_switch_workspace (MetaPluginManager   *mgr,
 | 
			
		||||
                                               gint                 from,
 | 
			
		||||
 
 | 
			
		||||
@@ -44,17 +44,74 @@ enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
  PROP_SCREEN,
 | 
			
		||||
  PROP_FEATURES,
 | 
			
		||||
  PROP_DISABLED,
 | 
			
		||||
  PROP_DEBUG_MODE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaPluginPrivate
 | 
			
		||||
{
 | 
			
		||||
  MetaScreen   *screen;
 | 
			
		||||
  gulong        features;
 | 
			
		||||
 | 
			
		||||
  gint          running;
 | 
			
		||||
 | 
			
		||||
  gboolean      disabled : 1;
 | 
			
		||||
  gboolean      debug    : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_plugin_set_features (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate  *priv     = plugin->priv;
 | 
			
		||||
  MetaPluginClass    *klass    = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
 | 
			
		||||
  priv->features = 0;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Feature flags: identify events that the plugin can handle; a plugin can
 | 
			
		||||
   * handle one or more events.
 | 
			
		||||
   */
 | 
			
		||||
  if (klass->minimize)
 | 
			
		||||
    priv->features |= META_PLUGIN_MINIMIZE;
 | 
			
		||||
 | 
			
		||||
  if (klass->maximize)
 | 
			
		||||
    priv->features |= META_PLUGIN_MAXIMIZE;
 | 
			
		||||
 | 
			
		||||
  if (klass->unmaximize)
 | 
			
		||||
    priv->features |= META_PLUGIN_UNMAXIMIZE;
 | 
			
		||||
 | 
			
		||||
  if (klass->map)
 | 
			
		||||
    priv->features |= META_PLUGIN_MAP;
 | 
			
		||||
 | 
			
		||||
  if (klass->destroy)
 | 
			
		||||
    priv->features |= META_PLUGIN_DESTROY;
 | 
			
		||||
 | 
			
		||||
  if (klass->switch_workspace)
 | 
			
		||||
    priv->features |= META_PLUGIN_SWITCH_WORKSPACE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_plugin_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  meta_plugin_set_features (META_PLUGIN (object));
 | 
			
		||||
 | 
			
		||||
  if (G_OBJECT_CLASS (meta_plugin_parent_class)->constructed)
 | 
			
		||||
      G_OBJECT_CLASS (meta_plugin_parent_class)->constructed (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_plugin_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  G_OBJECT_CLASS (meta_plugin_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_plugin_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  G_OBJECT_CLASS (meta_plugin_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_plugin_set_property (GObject      *object,
 | 
			
		||||
                          guint         prop_id,
 | 
			
		||||
@@ -68,6 +125,9 @@ meta_plugin_set_property (GObject      *object,
 | 
			
		||||
    case PROP_SCREEN:
 | 
			
		||||
      priv->screen = g_value_get_object (value);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_DISABLED:
 | 
			
		||||
      priv->disabled = g_value_get_boolean (value);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_DEBUG_MODE:
 | 
			
		||||
      priv->debug = g_value_get_boolean (value);
 | 
			
		||||
      break;
 | 
			
		||||
@@ -90,9 +150,15 @@ meta_plugin_get_property (GObject    *object,
 | 
			
		||||
    case PROP_SCREEN:
 | 
			
		||||
      g_value_set_object (value, priv->screen);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_DISABLED:
 | 
			
		||||
      g_value_set_boolean (value, priv->disabled);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_DEBUG_MODE:
 | 
			
		||||
      g_value_set_boolean (value, priv->debug);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_FEATURES:
 | 
			
		||||
      g_value_set_ulong (value, priv->features);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
@@ -105,6 +171,9 @@ meta_plugin_class_init (MetaPluginClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass      *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  gobject_class->constructed     = meta_plugin_constructed;
 | 
			
		||||
  gobject_class->finalize        = meta_plugin_finalize;
 | 
			
		||||
  gobject_class->dispose         = meta_plugin_dispose;
 | 
			
		||||
  gobject_class->set_property    = meta_plugin_set_property;
 | 
			
		||||
  gobject_class->get_property    = meta_plugin_get_property;
 | 
			
		||||
 | 
			
		||||
@@ -116,6 +185,22 @@ meta_plugin_class_init (MetaPluginClass *klass)
 | 
			
		||||
                                                        META_TYPE_SCREEN,
 | 
			
		||||
                                                        G_PARAM_READWRITE));
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (gobject_class,
 | 
			
		||||
				   PROP_FEATURES,
 | 
			
		||||
				   g_param_spec_ulong ("features",
 | 
			
		||||
                                                       "Features",
 | 
			
		||||
                                                       "Plugin Features",
 | 
			
		||||
                                                       0 , G_MAXULONG, 0,
 | 
			
		||||
                                                       G_PARAM_READABLE));
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (gobject_class,
 | 
			
		||||
				   PROP_DISABLED,
 | 
			
		||||
				   g_param_spec_boolean ("disabled",
 | 
			
		||||
                                                      "Plugin disabled",
 | 
			
		||||
                                                      "Plugin disabled",
 | 
			
		||||
                                                      FALSE,
 | 
			
		||||
                                                      G_PARAM_READWRITE));
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (gobject_class,
 | 
			
		||||
				   PROP_DEBUG_MODE,
 | 
			
		||||
				   g_param_spec_boolean ("debug-mode",
 | 
			
		||||
@@ -135,6 +220,22 @@ meta_plugin_init (MetaPlugin *self)
 | 
			
		||||
  self->priv = priv = META_PLUGIN_GET_PRIVATE (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
meta_plugin_features (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
 | 
			
		||||
  return priv->features;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_plugin_disabled (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
 | 
			
		||||
  return priv->disabled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_plugin_running  (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
@@ -162,6 +263,38 @@ meta_plugin_get_info (MetaPlugin *plugin)
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
meta_plugin_get_overlay_group (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
 | 
			
		||||
  return meta_get_overlay_group_for_screen (priv->screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
meta_plugin_get_stage (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
 | 
			
		||||
  return meta_get_stage_for_screen (priv->screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
meta_plugin_get_window_group (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
 | 
			
		||||
  return meta_get_window_group_for_screen (priv->screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
meta_plugin_get_background_actor (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
 | 
			
		||||
  return meta_get_background_actor_for_screen (priv->screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * _meta_plugin_effect_started:
 | 
			
		||||
 * @plugin: the plugin
 | 
			
		||||
@@ -182,7 +315,7 @@ meta_plugin_switch_workspace_completed (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
 | 
			
		||||
  MetaScreen *screen = priv->screen;
 | 
			
		||||
  MetaScreen *screen = meta_plugin_get_screen (plugin);
 | 
			
		||||
 | 
			
		||||
  if (priv->running-- < 0)
 | 
			
		||||
    {
 | 
			
		||||
@@ -256,6 +389,80 @@ meta_plugin_destroy_completed (MetaPlugin      *plugin,
 | 
			
		||||
  meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_DESTROY);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_query_screen_size (MetaPlugin *plugin,
 | 
			
		||||
                               int        *width,
 | 
			
		||||
                               int        *height)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
 | 
			
		||||
  meta_screen_get_size (priv->screen, width, height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_set_stage_reactive (MetaPlugin *plugin,
 | 
			
		||||
                                gboolean    reactive)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
  MetaScreen  *screen  = priv->screen;
 | 
			
		||||
 | 
			
		||||
  if (reactive)
 | 
			
		||||
    meta_set_stage_input_region (screen, None);
 | 
			
		||||
  else
 | 
			
		||||
    meta_empty_stage_input_region (screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_set_stage_input_area (MetaPlugin *plugin,
 | 
			
		||||
                                  gint x, gint y, gint width, gint height)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
  MetaScreen   *screen  = priv->screen;
 | 
			
		||||
  MetaDisplay  *display = meta_screen_get_display (screen);
 | 
			
		||||
  Display      *xdpy    = meta_display_get_xdisplay (display);
 | 
			
		||||
  XRectangle    rect;
 | 
			
		||||
  XserverRegion region;
 | 
			
		||||
 | 
			
		||||
  rect.x = x;
 | 
			
		||||
  rect.y = y;
 | 
			
		||||
  rect.width = width;
 | 
			
		||||
  rect.height = height;
 | 
			
		||||
 | 
			
		||||
  region = XFixesCreateRegion (xdpy, &rect, 1);
 | 
			
		||||
  meta_set_stage_input_region (screen, region);
 | 
			
		||||
  XFixesDestroyRegion (xdpy, region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_set_stage_input_region (MetaPlugin   *plugin,
 | 
			
		||||
                                    XserverRegion region)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
  MetaScreen  *screen  = priv->screen;
 | 
			
		||||
 | 
			
		||||
  meta_set_stage_input_region (screen, region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_plugin_get_window_actors:
 | 
			
		||||
 * @plugin: A #MetaPlugin
 | 
			
		||||
 *
 | 
			
		||||
 * This function returns all of the #MetaWindowActor objects referenced by Mutter, including
 | 
			
		||||
 * override-redirect windows.  The returned list is a snapshot of Mutter's current
 | 
			
		||||
 * stacking order, with the topmost window last.
 | 
			
		||||
 *
 | 
			
		||||
 * The 'restacked' signal of #MetaScreen signals when this value has changed.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none) (element-type MetaWindowActor): Windows in stacking order, topmost last
 | 
			
		||||
 */
 | 
			
		||||
GList *
 | 
			
		||||
meta_plugin_get_window_actors (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
 | 
			
		||||
 | 
			
		||||
  return meta_get_window_actors (priv->screen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_plugin_begin_modal:
 | 
			
		||||
 * @plugin: a #MetaPlugin
 | 
			
		||||
@@ -295,7 +502,7 @@ meta_plugin_begin_modal (MetaPlugin       *plugin,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_plugin_end_modal:
 | 
			
		||||
 * meta_plugin_end_modal
 | 
			
		||||
 * @plugin: a #MetaPlugin
 | 
			
		||||
 * @timestamp: the time used for releasing grabs
 | 
			
		||||
 *
 | 
			
		||||
@@ -314,6 +521,16 @@ meta_plugin_end_modal (MetaPlugin *plugin,
 | 
			
		||||
  meta_end_modal_for_plugin (priv->screen, plugin, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Display *
 | 
			
		||||
meta_plugin_get_xdisplay (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginPrivate *priv    = META_PLUGIN (plugin)->priv;
 | 
			
		||||
  MetaDisplay       *display = meta_screen_get_display (priv->screen);
 | 
			
		||||
  Display           *xdpy    = meta_display_get_xdisplay (display);
 | 
			
		||||
 | 
			
		||||
  return xdpy;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_plugin_get_screen:
 | 
			
		||||
 * @plugin: a #MetaPlugin
 | 
			
		||||
@@ -331,3 +548,19 @@ meta_plugin_get_screen (MetaPlugin *plugin)
 | 
			
		||||
 | 
			
		||||
  return priv->screen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_plugin_type_register:
 | 
			
		||||
 * @plugin_type: a #MetaPlugin type
 | 
			
		||||
 *
 | 
			
		||||
 * Register @plugin_type as a compositor plugin type to be used.
 | 
			
		||||
 * You must call this before calling meta_init().
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_type_register (GType plugin_type)
 | 
			
		||||
{
 | 
			
		||||
  MetaPluginManager *plugin_manager;
 | 
			
		||||
 | 
			
		||||
  plugin_manager = meta_plugin_manager_get_default ();
 | 
			
		||||
  meta_plugin_manager_register (plugin_manager, plugin_type);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -130,7 +130,7 @@ MetaShadowClassInfo default_shadow_classes[] = {
 | 
			
		||||
  { "popup-menu",    { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } },
 | 
			
		||||
 | 
			
		||||
  { "dropdown-menu", { 1, 10, 0, 1, 128 }, { 1, 10, 0, 1, 128 } },
 | 
			
		||||
  { "attached",      { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } }
 | 
			
		||||
  { "attached",      { 2, 50, 0, 1, 255 }, { 1, 50, 0, 1, 128 } }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);
 | 
			
		||||
@@ -442,7 +442,8 @@ meta_shadow_factory_class_init (MetaShadowFactoryClass *klass)
 | 
			
		||||
                  G_TYPE_FROM_CLASS (object_class),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0,
 | 
			
		||||
                  NULL, NULL, NULL,
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,11 @@
 | 
			
		||||
/*
 | 
			
		||||
 * shaped texture
 | 
			
		||||
 *
 | 
			
		||||
 * An actor to draw a masked texture.
 | 
			
		||||
 * An actor to draw a texture clipped to a list of rectangles
 | 
			
		||||
 *
 | 
			
		||||
 * Authored By Neil Roberts  <neil@linux.intel.com>
 | 
			
		||||
 * and Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2008 Intel Corporation
 | 
			
		||||
 * Copyright (C) 2012 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
@@ -27,37 +25,32 @@
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
 | 
			
		||||
#define COGL_ENABLE_EXPERIMENTAL_API
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-shaped-texture.h>
 | 
			
		||||
#include "meta-shaped-texture.h"
 | 
			
		||||
#include "meta-texture-tower.h"
 | 
			
		||||
#include "meta-texture-rectangle.h"
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
#include <cogl/cogl-texture-pixmap-x11.h>
 | 
			
		||||
#include <gdk/gdk.h> /* for gdk_rectangle_intersect() */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
static void meta_shaped_texture_dispose  (GObject    *object);
 | 
			
		||||
static void meta_shaped_texture_notify   (GObject    *object,
 | 
			
		||||
					  GParamSpec *pspec);
 | 
			
		||||
 | 
			
		||||
static void meta_shaped_texture_paint (ClutterActor       *actor);
 | 
			
		||||
static void meta_shaped_texture_pick  (ClutterActor       *actor,
 | 
			
		||||
				       const ClutterColor *color);
 | 
			
		||||
 | 
			
		||||
static void meta_shaped_texture_get_preferred_width (ClutterActor *self,
 | 
			
		||||
                                                     gfloat        for_height,
 | 
			
		||||
                                                     gfloat       *min_width_p,
 | 
			
		||||
                                                     gfloat       *natural_width_p);
 | 
			
		||||
static void meta_shaped_texture_update_area (ClutterX11TexturePixmap *texture,
 | 
			
		||||
					     int                      x,
 | 
			
		||||
					     int                      y,
 | 
			
		||||
					     int                      width,
 | 
			
		||||
					     int                      height);
 | 
			
		||||
 | 
			
		||||
static void meta_shaped_texture_get_preferred_height (ClutterActor *self,
 | 
			
		||||
                                                      gfloat        for_width,
 | 
			
		||||
                                                      gfloat       *min_height_p,
 | 
			
		||||
                                                      gfloat       *natural_height_p);
 | 
			
		||||
 | 
			
		||||
static gboolean meta_shaped_texture_get_paint_volume (ClutterActor *self, ClutterPaintVolume *volume);
 | 
			
		||||
static void meta_shaped_texture_dirty_mask (MetaShapedTexture *stex);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
 | 
			
		||||
               CLUTTER_TYPE_ACTOR);
 | 
			
		||||
               CLUTTER_X11_TYPE_TEXTURE_PIXMAP);
 | 
			
		||||
 | 
			
		||||
#define META_SHAPED_TEXTURE_GET_PRIVATE(obj) \
 | 
			
		||||
  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \
 | 
			
		||||
@@ -66,15 +59,19 @@ G_DEFINE_TYPE (MetaShapedTexture, meta_shaped_texture,
 | 
			
		||||
struct _MetaShapedTexturePrivate
 | 
			
		||||
{
 | 
			
		||||
  MetaTextureTower *paint_tower;
 | 
			
		||||
  Pixmap pixmap;
 | 
			
		||||
  CoglHandle texture;
 | 
			
		||||
  CoglHandle mask_texture;
 | 
			
		||||
  CoglHandle material;
 | 
			
		||||
  CoglHandle material_unshaped;
 | 
			
		||||
 | 
			
		||||
  cairo_region_t *clip_region;
 | 
			
		||||
  cairo_region_t *shape_region;
 | 
			
		||||
 | 
			
		||||
  guint tex_width, tex_height;
 | 
			
		||||
  cairo_region_t *overlay_region;
 | 
			
		||||
  cairo_path_t *overlay_path;
 | 
			
		||||
 | 
			
		||||
  cairo_region_t *visible_pixels_region;
 | 
			
		||||
 | 
			
		||||
  guint mask_width, mask_height;
 | 
			
		||||
 | 
			
		||||
  guint create_mipmaps : 1;
 | 
			
		||||
};
 | 
			
		||||
@@ -84,14 +81,15 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = (GObjectClass *) klass;
 | 
			
		||||
  ClutterActorClass *actor_class = (ClutterActorClass *) klass;
 | 
			
		||||
  ClutterX11TexturePixmapClass *x11_texture_class = (ClutterX11TexturePixmapClass *) klass;
 | 
			
		||||
 | 
			
		||||
  gobject_class->dispose = meta_shaped_texture_dispose;
 | 
			
		||||
  gobject_class->notify = meta_shaped_texture_notify;
 | 
			
		||||
 | 
			
		||||
  actor_class->get_preferred_width = meta_shaped_texture_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height = meta_shaped_texture_get_preferred_height;
 | 
			
		||||
  actor_class->paint = meta_shaped_texture_paint;
 | 
			
		||||
  actor_class->pick = meta_shaped_texture_pick;
 | 
			
		||||
  actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume;
 | 
			
		||||
 | 
			
		||||
  x11_texture_class->update_area = meta_shaped_texture_update_area;
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (MetaShapedTexturePrivate));
 | 
			
		||||
}
 | 
			
		||||
@@ -103,8 +101,11 @@ meta_shaped_texture_init (MetaShapedTexture *self)
 | 
			
		||||
 | 
			
		||||
  priv = self->priv = META_SHAPED_TEXTURE_GET_PRIVATE (self);
 | 
			
		||||
 | 
			
		||||
  priv->shape_region = NULL;
 | 
			
		||||
  priv->overlay_path = NULL;
 | 
			
		||||
  priv->overlay_region = NULL;
 | 
			
		||||
  priv->visible_pixels_region = NULL;
 | 
			
		||||
  priv->paint_tower = meta_texture_tower_new ();
 | 
			
		||||
  priv->texture = COGL_INVALID_HANDLE;
 | 
			
		||||
  priv->mask_texture = COGL_INVALID_HANDLE;
 | 
			
		||||
  priv->create_mipmaps = TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -119,6 +120,8 @@ meta_shaped_texture_dispose (GObject *object)
 | 
			
		||||
    meta_texture_tower_free (priv->paint_tower);
 | 
			
		||||
  priv->paint_tower = NULL;
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_dirty_mask (self);
 | 
			
		||||
 | 
			
		||||
  if (priv->material != COGL_INVALID_HANDLE)
 | 
			
		||||
    {
 | 
			
		||||
      cogl_handle_unref (priv->material);
 | 
			
		||||
@@ -129,18 +132,287 @@ meta_shaped_texture_dispose (GObject *object)
 | 
			
		||||
      cogl_handle_unref (priv->material_unshaped);
 | 
			
		||||
      priv->material_unshaped = COGL_INVALID_HANDLE;
 | 
			
		||||
    }
 | 
			
		||||
  if (priv->texture != COGL_INVALID_HANDLE)
 | 
			
		||||
    {
 | 
			
		||||
      cogl_handle_unref (priv->texture);
 | 
			
		||||
      priv->texture = COGL_INVALID_HANDLE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_set_mask_texture (self, COGL_INVALID_HANDLE);
 | 
			
		||||
  meta_shaped_texture_set_shape_region (self, NULL);
 | 
			
		||||
  meta_shaped_texture_set_clip_region (self, NULL);
 | 
			
		||||
  meta_shaped_texture_set_overlay_path (self, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_notify (GObject    *object,
 | 
			
		||||
			    GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  if (G_OBJECT_CLASS (meta_shaped_texture_parent_class)->notify)
 | 
			
		||||
    G_OBJECT_CLASS (meta_shaped_texture_parent_class)->notify (object, pspec);
 | 
			
		||||
 | 
			
		||||
  /* It seems like we could just do this out of update_area(), but unfortunately,
 | 
			
		||||
   * clutter_glx_texture_pixmap() doesn't call through the vtable on the
 | 
			
		||||
   * initial update_area, so we need to look for changes to the texture
 | 
			
		||||
   * explicitly.
 | 
			
		||||
   */
 | 
			
		||||
  if (strcmp (pspec->name, "cogl-texture") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      MetaShapedTexture *stex = (MetaShapedTexture *) object;
 | 
			
		||||
      MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
      meta_shaped_texture_clear (stex);
 | 
			
		||||
 | 
			
		||||
      if (priv->create_mipmaps)
 | 
			
		||||
	meta_texture_tower_set_base_texture (priv->paint_tower,
 | 
			
		||||
					       clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex)));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_dirty_mask (MetaShapedTexture *stex)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->visible_pixels_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_destroy (priv->visible_pixels_region);
 | 
			
		||||
      priv->visible_pixels_region = NULL;
 | 
			
		||||
 | 
			
		||||
      if (priv->mask_texture != COGL_INVALID_HANDLE)
 | 
			
		||||
        {
 | 
			
		||||
          cogl_handle_unref (priv->mask_texture);
 | 
			
		||||
          priv->mask_texture = COGL_INVALID_HANDLE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (priv->material != COGL_INVALID_HANDLE)
 | 
			
		||||
        cogl_material_set_layer (priv->material, 1, COGL_INVALID_HANDLE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
scan_visible_region (MetaShapedTexture *stex,
 | 
			
		||||
                     guchar            *mask_data,
 | 
			
		||||
                     int                stride)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
  cairo_region_t *visible_pixels_region;
 | 
			
		||||
  cairo_region_t *overlay_region;
 | 
			
		||||
  int i, n_rects;
 | 
			
		||||
 | 
			
		||||
  /* The visible pixels region contains all pixel values above 0.
 | 
			
		||||
   * This is somewhat complicated when there's an overlay: we
 | 
			
		||||
   * need to scan all regions potentially modified by it.
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  if (priv->visible_pixels_region)
 | 
			
		||||
    cairo_region_destroy (priv->visible_pixels_region);
 | 
			
		||||
 | 
			
		||||
  priv->visible_pixels_region = cairo_region_copy (priv->shape_region);
 | 
			
		||||
 | 
			
		||||
  visible_pixels_region = priv->visible_pixels_region;
 | 
			
		||||
  overlay_region = priv->overlay_region;
 | 
			
		||||
 | 
			
		||||
  /* With no overlay region, the visible region is defined
 | 
			
		||||
   * by the mask region, so we don't need to scan anything. */
 | 
			
		||||
  if (overlay_region == NULL)
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
  /* Subtract all the rectangles in the overlay region so that we can
 | 
			
		||||
   * scan all the pixels potentially added by the overlay path. */
 | 
			
		||||
  cairo_region_subtract (visible_pixels_region, overlay_region);
 | 
			
		||||
 | 
			
		||||
  n_rects = cairo_region_num_rectangles (overlay_region);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_rects; i++)
 | 
			
		||||
    {
 | 
			
		||||
      int x, y;
 | 
			
		||||
      cairo_rectangle_int_t rect;
 | 
			
		||||
 | 
			
		||||
      cairo_region_get_rectangle (overlay_region, i, &rect);
 | 
			
		||||
 | 
			
		||||
      for (y = rect.y; y < (rect.y + rect.height); y++)
 | 
			
		||||
        {
 | 
			
		||||
          for (x = rect.x; x < (rect.x + rect.width); x++)
 | 
			
		||||
            {
 | 
			
		||||
              int w = x;
 | 
			
		||||
              while (mask_data[y * stride + w] > 0 && w < (rect.x + rect.width))
 | 
			
		||||
                w++;
 | 
			
		||||
 | 
			
		||||
              if (w > 0)
 | 
			
		||||
                {
 | 
			
		||||
                  cairo_rectangle_int_t tmp;
 | 
			
		||||
                  tmp.x = x;
 | 
			
		||||
                  tmp.y = y;
 | 
			
		||||
                  tmp.width = w - x;
 | 
			
		||||
                  tmp.height = 1;
 | 
			
		||||
                  cairo_region_union_rectangle (visible_pixels_region, &tmp);
 | 
			
		||||
                  x = w;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
install_overlay_path (MetaShapedTexture *stex,
 | 
			
		||||
                      guchar            *mask_data,
 | 
			
		||||
                      int                tex_width,
 | 
			
		||||
                      int                tex_height,
 | 
			
		||||
                      int                stride)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
  int i, n_rects;
 | 
			
		||||
  cairo_t *cr;
 | 
			
		||||
  cairo_rectangle_int_t rect;
 | 
			
		||||
  cairo_surface_t *surface;
 | 
			
		||||
 | 
			
		||||
  if (priv->overlay_region == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  surface = cairo_image_surface_create_for_data (mask_data,
 | 
			
		||||
                                                 CAIRO_FORMAT_A8,
 | 
			
		||||
                                                 tex_width,
 | 
			
		||||
                                                 tex_height,
 | 
			
		||||
                                                 stride);
 | 
			
		||||
 | 
			
		||||
  cr = cairo_create (surface);
 | 
			
		||||
  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
 | 
			
		||||
 | 
			
		||||
  n_rects = cairo_region_num_rectangles (priv->overlay_region);
 | 
			
		||||
  for (i = 0; i < n_rects; i++)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_get_rectangle (priv->overlay_region, i, &rect);
 | 
			
		||||
      cairo_rectangle (cr, rect.x, rect.y, rect.width, rect.height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cairo_fill_preserve (cr);
 | 
			
		||||
  if (priv->overlay_path == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* If we have an overlay region but not an overlay path, then we
 | 
			
		||||
       * just need to clear the rectangles in the overlay region. */
 | 
			
		||||
      goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cairo_clip (cr);
 | 
			
		||||
 | 
			
		||||
  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
 | 
			
		||||
  cairo_set_source_rgba (cr, 1, 1, 1, 1);
 | 
			
		||||
 | 
			
		||||
  cairo_append_path (cr, priv->overlay_path);
 | 
			
		||||
  cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  cairo_destroy (cr);
 | 
			
		||||
  cairo_surface_destroy (surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_ensure_mask (MetaShapedTexture *stex)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
  CoglHandle paint_tex;
 | 
			
		||||
  guint tex_width, tex_height;
 | 
			
		||||
 | 
			
		||||
  paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
 | 
			
		||||
 | 
			
		||||
  if (paint_tex == COGL_INVALID_HANDLE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  tex_width = cogl_texture_get_width (paint_tex);
 | 
			
		||||
  tex_height = cogl_texture_get_height (paint_tex);
 | 
			
		||||
 | 
			
		||||
  /* If the mask texture we have was created for a different size then
 | 
			
		||||
     recreate it */
 | 
			
		||||
  if (priv->mask_texture != COGL_INVALID_HANDLE
 | 
			
		||||
      && (priv->mask_width != tex_width || priv->mask_height != tex_height))
 | 
			
		||||
    meta_shaped_texture_dirty_mask (stex);
 | 
			
		||||
 | 
			
		||||
  /* If we don't have a mask texture yet then create one */
 | 
			
		||||
  if (priv->visible_pixels_region == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      guchar *mask_data;
 | 
			
		||||
      int i;
 | 
			
		||||
      int n_rects;
 | 
			
		||||
      int stride;
 | 
			
		||||
      GLenum paint_gl_target;
 | 
			
		||||
 | 
			
		||||
      /* If we have no shape region and no (or an empty) overlay region, we
 | 
			
		||||
       * don't need to create a full mask texture, so quit early. */
 | 
			
		||||
      if (priv->shape_region == NULL &&
 | 
			
		||||
          (priv->overlay_region == NULL ||
 | 
			
		||||
           cairo_region_num_rectangles (priv->overlay_region) == 0))
 | 
			
		||||
        {
 | 
			
		||||
          /* With no mask, the visible region is just
 | 
			
		||||
           * {0, 0, tex_width, tex_height}. */
 | 
			
		||||
          cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
 | 
			
		||||
          priv->visible_pixels_region = cairo_region_create_rectangle (&rect);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, tex_width);
 | 
			
		||||
 | 
			
		||||
      /* Create data for an empty image */
 | 
			
		||||
      mask_data = g_malloc0 (stride * tex_height);
 | 
			
		||||
 | 
			
		||||
      n_rects = cairo_region_num_rectangles (priv->shape_region);
 | 
			
		||||
 | 
			
		||||
      /* Fill in each rectangle. */
 | 
			
		||||
      for (i = 0; i < n_rects; i ++)
 | 
			
		||||
        {
 | 
			
		||||
          cairo_rectangle_int_t rect;
 | 
			
		||||
          cairo_region_get_rectangle (priv->shape_region, i, &rect);
 | 
			
		||||
 | 
			
		||||
          gint x1 = rect.x, x2 = x1 + rect.width;
 | 
			
		||||
          gint y1 = rect.y, y2 = y1 + rect.height;
 | 
			
		||||
          guchar *p;
 | 
			
		||||
 | 
			
		||||
          /* Clip the rectangle to the size of the texture */
 | 
			
		||||
          x1 = CLAMP (x1, 0, (gint) tex_width - 1);
 | 
			
		||||
          x2 = CLAMP (x2, x1, (gint) tex_width);
 | 
			
		||||
          y1 = CLAMP (y1, 0, (gint) tex_height - 1);
 | 
			
		||||
          y2 = CLAMP (y2, y1, (gint) tex_height);
 | 
			
		||||
 | 
			
		||||
          /* Fill the rectangle */
 | 
			
		||||
          for (p = mask_data + y1 * stride + x1;
 | 
			
		||||
               y1 < y2;
 | 
			
		||||
               y1++, p += stride)
 | 
			
		||||
            memset (p, 255, x2 - x1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      install_overlay_path (stex, mask_data, tex_width, tex_height, stride);
 | 
			
		||||
      scan_visible_region (stex, mask_data, stride);
 | 
			
		||||
 | 
			
		||||
      cogl_texture_get_gl_texture (paint_tex, NULL, &paint_gl_target);
 | 
			
		||||
 | 
			
		||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
 | 
			
		||||
      if (paint_gl_target == GL_TEXTURE_RECTANGLE_ARB)
 | 
			
		||||
        {
 | 
			
		||||
          priv->mask_texture
 | 
			
		||||
            = meta_texture_rectangle_new (tex_width, tex_height,
 | 
			
		||||
                                          0, /* flags */
 | 
			
		||||
                                          /* data format */
 | 
			
		||||
                                          COGL_PIXEL_FORMAT_A_8,
 | 
			
		||||
                                          /* internal GL format */
 | 
			
		||||
                                          GL_ALPHA,
 | 
			
		||||
                                          /* internal cogl format */
 | 
			
		||||
                                          COGL_PIXEL_FORMAT_A_8,
 | 
			
		||||
                                          /* rowstride */
 | 
			
		||||
                                          stride,
 | 
			
		||||
                                          mask_data);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
 | 
			
		||||
        priv->mask_texture = cogl_texture_new_from_data (tex_width, tex_height,
 | 
			
		||||
                                                         COGL_TEXTURE_NONE,
 | 
			
		||||
                                                         COGL_PIXEL_FORMAT_A_8,
 | 
			
		||||
                                                         COGL_PIXEL_FORMAT_ANY,
 | 
			
		||||
                                                         stride,
 | 
			
		||||
                                                         mask_data);
 | 
			
		||||
 | 
			
		||||
      g_free (mask_data);
 | 
			
		||||
 | 
			
		||||
      priv->mask_width = tex_width;
 | 
			
		||||
      priv->mask_height = tex_height;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
@@ -179,20 +451,20 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
  if (priv->create_mipmaps)
 | 
			
		||||
    paint_tex = meta_texture_tower_get_paint_texture (priv->paint_tower);
 | 
			
		||||
  else
 | 
			
		||||
    paint_tex = priv->texture;
 | 
			
		||||
    paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
 | 
			
		||||
 | 
			
		||||
  if (paint_tex == COGL_INVALID_HANDLE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  tex_width = priv->tex_width;
 | 
			
		||||
  tex_height = priv->tex_height;
 | 
			
		||||
  tex_width = cogl_texture_get_width (paint_tex);
 | 
			
		||||
  tex_height = cogl_texture_get_height (paint_tex);
 | 
			
		||||
 | 
			
		||||
  if (tex_width == 0 || tex_height == 0) /* no contents yet */
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (priv->mask_texture == COGL_INVALID_HANDLE)
 | 
			
		||||
  if (priv->shape_region == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* Use a single-layer texture if we don't have a mask. */
 | 
			
		||||
      /* No region means an unclipped shape. Use a single-layer texture. */
 | 
			
		||||
 | 
			
		||||
      if (priv->material_unshaped == COGL_INVALID_HANDLE) 
 | 
			
		||||
        {
 | 
			
		||||
@@ -205,6 +477,8 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      meta_shaped_texture_ensure_mask (stex);
 | 
			
		||||
 | 
			
		||||
      if (priv->material == COGL_INVALID_HANDLE)
 | 
			
		||||
	{
 | 
			
		||||
	   if (G_UNLIKELY (material_template == COGL_INVALID_HANDLE))
 | 
			
		||||
@@ -238,7 +512,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
    {
 | 
			
		||||
      int n_rects;
 | 
			
		||||
      int i;
 | 
			
		||||
      cairo_rectangle_int_t tex_rect = { 0, 0, tex_width, tex_height };
 | 
			
		||||
 | 
			
		||||
      /* Limit to how many separate rectangles we'll draw; beyond this just
 | 
			
		||||
       * fall back and draw the whole thing */
 | 
			
		||||
@@ -256,9 +529,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
	      cairo_region_get_rectangle (priv->clip_region, i, &rect);
 | 
			
		||||
 | 
			
		||||
	      if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
 | 
			
		||||
		continue;
 | 
			
		||||
 | 
			
		||||
	      x1 = rect.x;
 | 
			
		||||
	      y1 = rect.y;
 | 
			
		||||
	      x2 = rect.x + rect.width;
 | 
			
		||||
@@ -295,7 +565,7 @@ meta_shaped_texture_pick (ClutterActor       *actor,
 | 
			
		||||
  MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  /* If there is no region then use the regular pick */
 | 
			
		||||
  if (priv->mask_texture == COGL_INVALID_HANDLE)
 | 
			
		||||
  if (priv->shape_region == NULL)
 | 
			
		||||
    CLUTTER_ACTOR_CLASS (meta_shaped_texture_parent_class)
 | 
			
		||||
      ->pick (actor, color);
 | 
			
		||||
  else if (clutter_actor_should_pick_paint (actor))
 | 
			
		||||
@@ -304,7 +574,7 @@ meta_shaped_texture_pick (ClutterActor       *actor,
 | 
			
		||||
      ClutterActorBox alloc;
 | 
			
		||||
      guint tex_width, tex_height;
 | 
			
		||||
 | 
			
		||||
      paint_tex = priv->texture;
 | 
			
		||||
      paint_tex = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex));
 | 
			
		||||
 | 
			
		||||
      if (paint_tex == COGL_INVALID_HANDLE)
 | 
			
		||||
        return;
 | 
			
		||||
@@ -315,6 +585,8 @@ meta_shaped_texture_pick (ClutterActor       *actor,
 | 
			
		||||
      if (tex_width == 0 || tex_height == 0) /* no contents yet */
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      meta_shaped_texture_ensure_mask (stex);
 | 
			
		||||
 | 
			
		||||
      cogl_set_source_color4ub (color->red, color->green, color->blue,
 | 
			
		||||
                                 color->alpha);
 | 
			
		||||
 | 
			
		||||
@@ -330,48 +602,19 @@ meta_shaped_texture_pick (ClutterActor       *actor,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_get_preferred_width (ClutterActor *self,
 | 
			
		||||
                                         gfloat        for_height,
 | 
			
		||||
                                         gfloat       *min_width_p,
 | 
			
		||||
                                         gfloat       *natural_width_p)
 | 
			
		||||
meta_shaped_texture_update_area (ClutterX11TexturePixmap *texture,
 | 
			
		||||
				 int                      x,
 | 
			
		||||
				 int                      y,
 | 
			
		||||
				 int                      width,
 | 
			
		||||
				 int                      height)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
  MetaShapedTexture *stex = (MetaShapedTexture *) texture;
 | 
			
		||||
  MetaShapedTexturePrivate *priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_SHAPED_TEXTURE (self));
 | 
			
		||||
  CLUTTER_X11_TEXTURE_PIXMAP_CLASS (meta_shaped_texture_parent_class)->update_area (texture,
 | 
			
		||||
                                                                                      x, y, width, height);
 | 
			
		||||
 | 
			
		||||
  priv = META_SHAPED_TEXTURE (self)->priv;
 | 
			
		||||
 | 
			
		||||
  if (min_width_p)
 | 
			
		||||
    *min_width_p = 0;
 | 
			
		||||
 | 
			
		||||
  if (natural_width_p)
 | 
			
		||||
    *natural_width_p = priv->tex_width;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_get_preferred_height (ClutterActor *self,
 | 
			
		||||
                                          gfloat        for_width,
 | 
			
		||||
                                          gfloat       *min_height_p,
 | 
			
		||||
                                          gfloat       *natural_height_p)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_SHAPED_TEXTURE (self));
 | 
			
		||||
 | 
			
		||||
  priv = META_SHAPED_TEXTURE (self)->priv;
 | 
			
		||||
 | 
			
		||||
  if (min_height_p)
 | 
			
		||||
    *min_height_p = 0;
 | 
			
		||||
 | 
			
		||||
  if (natural_height_p)
 | 
			
		||||
    *natural_height_p = priv->tex_height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_shaped_texture_get_paint_volume (ClutterActor *self,
 | 
			
		||||
                                      ClutterPaintVolume *volume)
 | 
			
		||||
{
 | 
			
		||||
  return clutter_paint_volume_set_from_allocation (volume, self);
 | 
			
		||||
  meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
@@ -397,16 +640,34 @@ meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
 | 
			
		||||
  if (create_mipmaps != priv->create_mipmaps)
 | 
			
		||||
    {
 | 
			
		||||
      CoglHandle base_texture;
 | 
			
		||||
 | 
			
		||||
      priv->create_mipmaps = create_mipmaps;
 | 
			
		||||
 | 
			
		||||
      base_texture = create_mipmaps ?
 | 
			
		||||
        priv->texture : COGL_INVALID_HANDLE;
 | 
			
		||||
	clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (stex)) : COGL_INVALID_HANDLE;
 | 
			
		||||
 | 
			
		||||
      meta_texture_tower_set_base_texture (priv->paint_tower, base_texture);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This is a workaround for deficiencies in the hack tower:
 | 
			
		||||
 *
 | 
			
		||||
 * When we call clutter_x11_texture_pixmap_set_pixmap(tp, None),
 | 
			
		||||
 * ClutterX11TexturePixmap knows that it has to get rid of the old texture, but
 | 
			
		||||
 * clutter_texture_set_cogl_texture(texture, COGL_INVALID_HANDLE) isn't allowed, so
 | 
			
		||||
 * it grabs the material for the texture and manually sets the texture in it. This means
 | 
			
		||||
 * that the "cogl-texture" property isn't notified, so we don't find out about it.
 | 
			
		||||
 *
 | 
			
		||||
 * And if we keep the CoglX11TexturePixmap around after the X pixmap is freed, then
 | 
			
		||||
 * we'll trigger X errors when we actually try to free it.
 | 
			
		||||
 *
 | 
			
		||||
 * The only correct thing to do here is to change our code to derive
 | 
			
		||||
 * from ClutterActor and get rid of the inheritance hack tower.  Once
 | 
			
		||||
 * we want to depend on Clutter-1.4 (which has CoglTexturePixmapX11),
 | 
			
		||||
 * that will be very easy to do.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
 | 
			
		||||
                                      CoglHandle         mask_texture)
 | 
			
		||||
meta_shaped_texture_clear (MetaShapedTexture *stex)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
 | 
			
		||||
@@ -414,98 +675,18 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
 | 
			
		||||
 | 
			
		||||
  priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->mask_texture != COGL_INVALID_HANDLE)
 | 
			
		||||
    {
 | 
			
		||||
      cogl_handle_unref (priv->mask_texture);
 | 
			
		||||
      priv->mask_texture = COGL_INVALID_HANDLE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (mask_texture != COGL_INVALID_HANDLE)
 | 
			
		||||
    {
 | 
			
		||||
      priv->mask_texture = mask_texture;
 | 
			
		||||
      cogl_handle_ref (priv->mask_texture);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_shaped_texture_update_area (MetaShapedTexture *stex,
 | 
			
		||||
				 int                x,
 | 
			
		||||
				 int                y,
 | 
			
		||||
				 int                width,
 | 
			
		||||
				 int                height)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
  const cairo_rectangle_int_t clip = { x, y, width, height };
 | 
			
		||||
 | 
			
		||||
  priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->texture == COGL_INVALID_HANDLE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  cogl_texture_pixmap_x11_update_area (priv->texture, x, y, width, height);
 | 
			
		||||
 | 
			
		||||
  meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_cogl_texture (MetaShapedTexture *stex,
 | 
			
		||||
                  CoglHandle         cogl_tex)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
  guint width, height;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
 | 
			
		||||
 | 
			
		||||
  priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->texture != COGL_INVALID_HANDLE)
 | 
			
		||||
    cogl_handle_unref (priv->texture);
 | 
			
		||||
 | 
			
		||||
  priv->texture = cogl_tex;
 | 
			
		||||
  meta_texture_tower_set_base_texture (priv->paint_tower, COGL_INVALID_HANDLE);
 | 
			
		||||
 | 
			
		||||
  if (priv->material != COGL_INVALID_HANDLE)
 | 
			
		||||
    cogl_material_set_layer (priv->material, 0, cogl_tex);
 | 
			
		||||
    cogl_material_set_layer (priv->material, 0, COGL_INVALID_HANDLE);
 | 
			
		||||
 | 
			
		||||
  if (priv->material_unshaped != COGL_INVALID_HANDLE)
 | 
			
		||||
    cogl_material_set_layer (priv->material_unshaped, 0, cogl_tex);
 | 
			
		||||
 | 
			
		||||
  if (cogl_tex != COGL_INVALID_HANDLE)
 | 
			
		||||
    {
 | 
			
		||||
      width = cogl_texture_get_width (cogl_tex);
 | 
			
		||||
      height = cogl_texture_get_height (cogl_tex);
 | 
			
		||||
 | 
			
		||||
      if (width != priv->tex_width ||
 | 
			
		||||
          height != priv->tex_height)
 | 
			
		||||
        {
 | 
			
		||||
          priv->tex_width = width;
 | 
			
		||||
          priv->tex_height = height;
 | 
			
		||||
 | 
			
		||||
          clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* size changed to 0 going to an invalid handle */
 | 
			
		||||
      priv->tex_width = 0;
 | 
			
		||||
      priv->tex_height = 0;
 | 
			
		||||
      clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
 | 
			
		||||
    cogl_material_set_layer (priv->material_unshaped, 0, COGL_INVALID_HANDLE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_shaped_texture_set_pixmap:
 | 
			
		||||
 * @stex: The #MetaShapedTexture
 | 
			
		||||
 * @pixmap: The pixmap you want the stex to assume
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
 | 
			
		||||
                                Pixmap             pixmap)
 | 
			
		||||
meta_shaped_texture_set_shape_region (MetaShapedTexture *stex,
 | 
			
		||||
                                      cairo_region_t    *region)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
 | 
			
		||||
@@ -513,42 +694,88 @@ meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
 | 
			
		||||
 | 
			
		||||
  priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->pixmap == pixmap)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv->pixmap = pixmap;
 | 
			
		||||
 | 
			
		||||
  if (pixmap != None)
 | 
			
		||||
  if (priv->shape_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      CoglContext *ctx =
 | 
			
		||||
        clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
      set_cogl_texture (stex, cogl_texture_pixmap_x11_new (ctx, pixmap, FALSE, NULL));
 | 
			
		||||
      cairo_region_destroy (priv->shape_region);
 | 
			
		||||
      priv->shape_region = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    set_cogl_texture (stex, COGL_INVALID_HANDLE);
 | 
			
		||||
 | 
			
		||||
  if (priv->create_mipmaps)
 | 
			
		||||
    meta_texture_tower_set_base_texture (priv->paint_tower, priv->texture);
 | 
			
		||||
  if (region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_reference (region);
 | 
			
		||||
      priv->shape_region = region;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_dirty_mask (stex);
 | 
			
		||||
  clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_shaped_texture_get_texture:
 | 
			
		||||
 * @stex: The #MetaShapedTexture
 | 
			
		||||
 * meta_shaped_texture_get_visible_pixels_region:
 | 
			
		||||
 * @stex: a #MetaShapedTexture
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): the unshaped texture
 | 
			
		||||
 * Return a region enclosing only visible pixels: those with
 | 
			
		||||
 * alpha values above 0.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a #cairo_region_t
 | 
			
		||||
 */
 | 
			
		||||
CoglHandle
 | 
			
		||||
meta_shaped_texture_get_texture (MetaShapedTexture *stex)
 | 
			
		||||
cairo_region_t *
 | 
			
		||||
meta_shaped_texture_get_visible_pixels_region (MetaShapedTexture *stex)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), COGL_INVALID_HANDLE);
 | 
			
		||||
  return stex->priv->texture;
 | 
			
		||||
  g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_ensure_mask (stex);
 | 
			
		||||
  return stex->priv->visible_pixels_region;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_shaped_texture_set_overlay_path:
 | 
			
		||||
 * @stex: a #MetaShapedTexture
 | 
			
		||||
 * @overlay_region: A region containing the parts of the mask to overlay.
 | 
			
		||||
 *   All rectangles in this region are wiped clear to full transparency,
 | 
			
		||||
 *   and the overlay path is clipped to this region.
 | 
			
		||||
 * @overlay_path (transfer full): This path will be painted onto the mask
 | 
			
		||||
 *   texture with a fully opaque source. Due to the lack of refcounting
 | 
			
		||||
 *   in #cairo_path_t, ownership of the path is assumed.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_shaped_texture_set_overlay_path (MetaShapedTexture *stex,
 | 
			
		||||
                                      cairo_region_t    *overlay_region,
 | 
			
		||||
                                      cairo_path_t      *overlay_path)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_SHAPED_TEXTURE (stex));
 | 
			
		||||
 | 
			
		||||
  priv = stex->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->overlay_region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_destroy (priv->overlay_region);
 | 
			
		||||
      priv->overlay_region = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (priv->overlay_path != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_path_destroy (priv->overlay_path);
 | 
			
		||||
      priv->overlay_path = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cairo_region_reference (overlay_region);
 | 
			
		||||
  priv->overlay_region = overlay_region;
 | 
			
		||||
 | 
			
		||||
  /* cairo_path_t does not have refcounting. */
 | 
			
		||||
  priv->overlay_path = overlay_path;
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_dirty_mask (stex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_shaped_texture_set_clip_region:
 | 
			
		||||
 * @stex: a #MetaShapedTexture
 | 
			
		||||
 * @frame: a #MetaShapedTexture
 | 
			
		||||
 * @clip_region: (transfer full): the region of the texture that
 | 
			
		||||
 *   is visible and should be painted.
 | 
			
		||||
 *   is visible and should be painted. OWNERSHIP IS ASSUMED BY
 | 
			
		||||
 *   THE FUNCTION (for efficiency to avoid a copy.)
 | 
			
		||||
 *
 | 
			
		||||
 * Provides a hint to the texture about what areas of the texture
 | 
			
		||||
 * are not completely obscured and thus need to be painted. This
 | 
			
		||||
@@ -574,106 +801,5 @@ meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
 | 
			
		||||
      priv->clip_region = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (clip_region)
 | 
			
		||||
    priv->clip_region = cairo_region_copy (clip_region);
 | 
			
		||||
  else
 | 
			
		||||
    priv->clip_region = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_shaped_texture_get_image:
 | 
			
		||||
 * @stex: A #MetaShapedTexture
 | 
			
		||||
 * @clip: A clipping rectangle, to help prevent extra processing.
 | 
			
		||||
 * In the case that the clipping rectangle is partially or fully
 | 
			
		||||
 * outside the bounds of the texture, the rectangle will be clipped.
 | 
			
		||||
 *
 | 
			
		||||
 * Flattens the two layers of the shaped texture into one ARGB32
 | 
			
		||||
 * image by alpha blending the two images, and returns the flattened
 | 
			
		||||
 * image.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer full): a new cairo surface to be freed with
 | 
			
		||||
 * cairo_surface_destroy().
 | 
			
		||||
 */
 | 
			
		||||
cairo_surface_t *
 | 
			
		||||
meta_shaped_texture_get_image (MetaShapedTexture     *stex,
 | 
			
		||||
                               cairo_rectangle_int_t *clip)
 | 
			
		||||
{
 | 
			
		||||
  CoglHandle texture, mask_texture;
 | 
			
		||||
  cairo_rectangle_int_t texture_rect = { 0, 0, 0, 0 };
 | 
			
		||||
  cairo_surface_t *surface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (META_IS_SHAPED_TEXTURE (stex), NULL);
 | 
			
		||||
 | 
			
		||||
  texture = stex->priv->texture;
 | 
			
		||||
 | 
			
		||||
  if (texture == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  texture_rect.width = cogl_texture_get_width (texture);
 | 
			
		||||
  texture_rect.height = cogl_texture_get_height (texture);
 | 
			
		||||
 | 
			
		||||
  if (clip != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* GdkRectangle is just a typedef of cairo_rectangle_int_t,
 | 
			
		||||
       * so we can use the gdk_rectangle_* APIs on these. */
 | 
			
		||||
      if (!gdk_rectangle_intersect (&texture_rect, clip, clip))
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (clip != NULL)
 | 
			
		||||
    texture = cogl_texture_new_from_sub_texture (texture,
 | 
			
		||||
                                                 clip->x,
 | 
			
		||||
                                                 clip->y,
 | 
			
		||||
                                                 clip->width,
 | 
			
		||||
                                                 clip->height);
 | 
			
		||||
 | 
			
		||||
  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
 | 
			
		||||
                                        cogl_texture_get_width (texture),
 | 
			
		||||
                                        cogl_texture_get_height (texture));
 | 
			
		||||
 | 
			
		||||
  cogl_texture_get_data (texture, CLUTTER_CAIRO_FORMAT_ARGB32,
 | 
			
		||||
                         cairo_image_surface_get_stride (surface),
 | 
			
		||||
                         cairo_image_surface_get_data (surface));
 | 
			
		||||
 | 
			
		||||
  cairo_surface_mark_dirty (surface);
 | 
			
		||||
 | 
			
		||||
  if (clip != NULL)
 | 
			
		||||
    cogl_object_unref (texture);
 | 
			
		||||
 | 
			
		||||
  mask_texture = stex->priv->mask_texture;
 | 
			
		||||
  if (mask_texture != COGL_INVALID_HANDLE)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_t *cr;
 | 
			
		||||
      cairo_surface_t *mask_surface;
 | 
			
		||||
 | 
			
		||||
      if (clip != NULL)
 | 
			
		||||
        mask_texture = cogl_texture_new_from_sub_texture (mask_texture,
 | 
			
		||||
                                                          clip->x,
 | 
			
		||||
                                                          clip->y,
 | 
			
		||||
                                                          clip->width,
 | 
			
		||||
                                                          clip->height);
 | 
			
		||||
 | 
			
		||||
      mask_surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
 | 
			
		||||
                                                 cogl_texture_get_width (mask_texture),
 | 
			
		||||
                                                 cogl_texture_get_height (mask_texture));
 | 
			
		||||
 | 
			
		||||
      cogl_texture_get_data (mask_texture, COGL_PIXEL_FORMAT_A_8,
 | 
			
		||||
                             cairo_image_surface_get_stride (mask_surface),
 | 
			
		||||
                             cairo_image_surface_get_data (mask_surface));
 | 
			
		||||
 | 
			
		||||
      cairo_surface_mark_dirty (mask_surface);
 | 
			
		||||
 | 
			
		||||
      cr = cairo_create (surface);
 | 
			
		||||
      cairo_set_source_surface (cr, mask_surface, 0, 0);
 | 
			
		||||
      cairo_set_operator (cr, CAIRO_OPERATOR_DEST_IN);
 | 
			
		||||
      cairo_paint (cr);
 | 
			
		||||
      cairo_destroy (cr);
 | 
			
		||||
 | 
			
		||||
      cairo_surface_destroy (mask_surface);
 | 
			
		||||
 | 
			
		||||
      if (clip != NULL)
 | 
			
		||||
        cogl_object_unref (mask_texture);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return surface;
 | 
			
		||||
  priv->clip_region = clip_region;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,8 +26,10 @@
 | 
			
		||||
#ifndef __META_SHAPED_TEXTURE_H__
 | 
			
		||||
#define __META_SHAPED_TEXTURE_H__
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
#include <clutter/x11/clutter-x11.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
@@ -44,12 +46,12 @@ typedef struct _MetaShapedTexturePrivate MetaShapedTexturePrivate;
 | 
			
		||||
 | 
			
		||||
struct _MetaShapedTextureClass
 | 
			
		||||
{
 | 
			
		||||
  ClutterActorClass parent_class;
 | 
			
		||||
  ClutterX11TexturePixmapClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaShapedTexture
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor parent;
 | 
			
		||||
  ClutterX11TexturePixmap parent;
 | 
			
		||||
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
@@ -61,27 +63,21 @@ ClutterActor *meta_shaped_texture_new (void);
 | 
			
		||||
void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
 | 
			
		||||
					     gboolean           create_mipmaps);
 | 
			
		||||
 | 
			
		||||
void meta_shaped_texture_update_area (MetaShapedTexture *stex,
 | 
			
		||||
                                      int                x,
 | 
			
		||||
                                      int                y,
 | 
			
		||||
                                      int                width,
 | 
			
		||||
                                      int                height);
 | 
			
		||||
void meta_shaped_texture_clear (MetaShapedTexture *stex);
 | 
			
		||||
 | 
			
		||||
void meta_shaped_texture_set_pixmap (MetaShapedTexture *stex,
 | 
			
		||||
                                     Pixmap             pixmap);
 | 
			
		||||
void meta_shaped_texture_set_shape_region (MetaShapedTexture *stex,
 | 
			
		||||
                                           cairo_region_t    *region);
 | 
			
		||||
 | 
			
		||||
CoglHandle meta_shaped_texture_get_texture (MetaShapedTexture *stex);
 | 
			
		||||
cairo_region_t *meta_shaped_texture_get_visible_pixels_region (MetaShapedTexture *stex);
 | 
			
		||||
 | 
			
		||||
void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
 | 
			
		||||
                                           CoglHandle         mask_texture);
 | 
			
		||||
void meta_shaped_texture_set_overlay_path (MetaShapedTexture *stex,
 | 
			
		||||
                                           cairo_region_t    *overlay_region,
 | 
			
		||||
                                           cairo_path_t      *overlay_path);
 | 
			
		||||
 | 
			
		||||
/* Assumes ownership of clip_region */
 | 
			
		||||
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
 | 
			
		||||
					  cairo_region_t    *clip_region);
 | 
			
		||||
 | 
			
		||||
cairo_surface_t * meta_shaped_texture_get_image (MetaShapedTexture     *stex,
 | 
			
		||||
                                                 cairo_rectangle_int_t *clip);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __META_SHAPED_TEXTURE_H__ */
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
 *
 | 
			
		||||
 * Authored By Neil Roberts  <neil@linux.intel.com>
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2011, 2012 Intel Corporation
 | 
			
		||||
 * Copyright (C) 2011 Intel Corporation
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
@@ -25,77 +25,94 @@
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
 | 
			
		||||
#define COGL_ENABLE_EXPERIMENTAL_API
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include "meta-texture-rectangle.h"
 | 
			
		||||
 | 
			
		||||
CoglTexture *
 | 
			
		||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
 | 
			
		||||
 | 
			
		||||
static void (* pf_glGetIntegerv) (GLenum pname, GLint *params);
 | 
			
		||||
static void (* pf_glTexImage2D) (GLenum target, GLint level,
 | 
			
		||||
                                 GLint internalFormat,
 | 
			
		||||
                                 GLsizei width, GLsizei height,
 | 
			
		||||
                                 GLint border, GLenum format, GLenum type,
 | 
			
		||||
                                 const GLvoid *pixels);
 | 
			
		||||
static void (* pf_glGenTextures) (GLsizei n, GLuint *textures);
 | 
			
		||||
static void (* pf_glDeleteTextures) (GLsizei n, const GLuint *texture);
 | 
			
		||||
static void (* pf_glBindTexture) (GLenum target, GLuint texture);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
rectangle_texture_destroy_cb (void *user_data)
 | 
			
		||||
{
 | 
			
		||||
  GLuint tex = GPOINTER_TO_UINT (user_data);
 | 
			
		||||
 | 
			
		||||
  pf_glDeleteTextures (1, &tex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
 | 
			
		||||
 | 
			
		||||
CoglHandle
 | 
			
		||||
meta_texture_rectangle_new (unsigned int width,
 | 
			
		||||
                            unsigned int height,
 | 
			
		||||
                            CoglTextureFlags flags,
 | 
			
		||||
                            CoglPixelFormat format,
 | 
			
		||||
                            CoglPixelFormat internal_format,
 | 
			
		||||
                            GLenum internal_gl_format,
 | 
			
		||||
                            GLenum internal_format,
 | 
			
		||||
                            unsigned int rowstride,
 | 
			
		||||
                            const guint8 *data,
 | 
			
		||||
                            GError **error)
 | 
			
		||||
                            const guint8 *data)
 | 
			
		||||
{
 | 
			
		||||
  ClutterBackend *backend =
 | 
			
		||||
    clutter_get_default_backend ();
 | 
			
		||||
  CoglContext *context =
 | 
			
		||||
    clutter_backend_get_cogl_context (backend);
 | 
			
		||||
  CoglTextureRectangle *tex_rect;
 | 
			
		||||
  CoglHandle cogl_tex = COGL_INVALID_HANDLE;
 | 
			
		||||
 | 
			
		||||
  tex_rect = cogl_texture_rectangle_new_with_size (context,
 | 
			
		||||
                                                   width, height,
 | 
			
		||||
                                                   internal_format,
 | 
			
		||||
                                                   error);
 | 
			
		||||
  if (tex_rect == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
 | 
			
		||||
 | 
			
		||||
  static CoglUserDataKey user_data_key;
 | 
			
		||||
  GLint old_binding;
 | 
			
		||||
  GLuint tex;
 | 
			
		||||
 | 
			
		||||
  if (pf_glGenTextures == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      pf_glGetIntegerv = (void *) cogl_get_proc_address ("glGetIntegerv");
 | 
			
		||||
      pf_glTexImage2D = (void *) cogl_get_proc_address ("glTexImage2D");
 | 
			
		||||
      pf_glGenTextures = (void *) cogl_get_proc_address ("glGenTextures");
 | 
			
		||||
      pf_glDeleteTextures = (void *) cogl_get_proc_address ("glDeleteTextures");
 | 
			
		||||
      pf_glBindTexture = (void *) cogl_get_proc_address ("glBindTexture");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  pf_glGenTextures (1, &tex);
 | 
			
		||||
  pf_glGetIntegerv (GL_TEXTURE_BINDING_RECTANGLE_ARB, &old_binding);
 | 
			
		||||
  pf_glBindTexture (GL_TEXTURE_RECTANGLE_ARB, tex);
 | 
			
		||||
  pf_glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
 | 
			
		||||
                   internal_gl_format, width, height,
 | 
			
		||||
                   0, internal_gl_format,
 | 
			
		||||
                   GL_UNSIGNED_BYTE, NULL);
 | 
			
		||||
  pf_glBindTexture (GL_TEXTURE_RECTANGLE_ARB, old_binding);
 | 
			
		||||
 | 
			
		||||
  cogl_tex = cogl_texture_new_from_foreign (tex,
 | 
			
		||||
                                            GL_TEXTURE_RECTANGLE_ARB,
 | 
			
		||||
                                            width, height,
 | 
			
		||||
                                            0, 0, /* no waste */
 | 
			
		||||
                                            internal_format);
 | 
			
		||||
 | 
			
		||||
  /* Cogl won't destroy the GL texture when a foreign texture is used
 | 
			
		||||
     so we need to destroy it manually. We can set a destroy
 | 
			
		||||
     notification callback to do this transparently */
 | 
			
		||||
  cogl_object_set_user_data (cogl_tex,
 | 
			
		||||
                             &user_data_key,
 | 
			
		||||
                             GUINT_TO_POINTER (tex),
 | 
			
		||||
                             rectangle_texture_destroy_cb);
 | 
			
		||||
 | 
			
		||||
  /* Use cogl_texture_set_region instead of uploading the data
 | 
			
		||||
     directly with GL calls so that we can let Cogl deal with setting
 | 
			
		||||
     the pixel store parameters and handling format conversion */
 | 
			
		||||
  if (data)
 | 
			
		||||
    cogl_texture_set_region (COGL_TEXTURE (tex_rect),
 | 
			
		||||
                             0, 0, /* src_x/y */
 | 
			
		||||
                             0, 0, /* dst_x/y */
 | 
			
		||||
                             width, height, /* dst_width/height */
 | 
			
		||||
                             width, height, /* width/height */
 | 
			
		||||
    cogl_texture_set_region (cogl_tex,
 | 
			
		||||
                             0, 0, /* src x/y */
 | 
			
		||||
                             0, 0, /* dst x/y */
 | 
			
		||||
                             width, height, /* dst width/height */
 | 
			
		||||
                             width, height, /* src width/height */
 | 
			
		||||
                             format,
 | 
			
		||||
                             rowstride,
 | 
			
		||||
                             data);
 | 
			
		||||
 | 
			
		||||
  return COGL_TEXTURE (tex_rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
texture_rectangle_check_cb (CoglTexture *sub_texture,
 | 
			
		||||
                            const float *sub_texture_coords,
 | 
			
		||||
                            const float *meta_coords,
 | 
			
		||||
                            void *user_data)
 | 
			
		||||
{
 | 
			
		||||
  gboolean *result = user_data;
 | 
			
		||||
 | 
			
		||||
  if (cogl_is_texture_rectangle (sub_texture))
 | 
			
		||||
    *result = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Determines if the given texture is using a rectangle texture as its
 | 
			
		||||
 * primitive texture type. Eventually this function could be replaced
 | 
			
		||||
 * with cogl_texture_get_type if Cogl makes that public.
 | 
			
		||||
 *
 | 
			
		||||
 * http://git.gnome.org/browse/cogl/commit/?h=8012eee31
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
meta_texture_rectangle_check (CoglTexture *texture)
 | 
			
		||||
{
 | 
			
		||||
  gboolean result = FALSE;
 | 
			
		||||
 | 
			
		||||
  cogl_meta_texture_foreach_in_region (COGL_META_TEXTURE (texture),
 | 
			
		||||
                                       0.0f, 0.0f, /* tx_1 / ty_1 */
 | 
			
		||||
                                       1.0f, 1.0f, /* tx_2 / ty_2 */
 | 
			
		||||
                                       COGL_PIPELINE_WRAP_MODE_REPEAT,
 | 
			
		||||
                                       COGL_PIPELINE_WRAP_MODE_REPEAT,
 | 
			
		||||
                                       texture_rectangle_check_cb,
 | 
			
		||||
                                       &result);
 | 
			
		||||
 | 
			
		||||
  return result;
 | 
			
		||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
 | 
			
		||||
 | 
			
		||||
  return cogl_tex;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,17 +30,15 @@
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
CoglTexture *
 | 
			
		||||
CoglHandle
 | 
			
		||||
meta_texture_rectangle_new (unsigned int width,
 | 
			
		||||
                            unsigned int height,
 | 
			
		||||
                            CoglTextureFlags flags,
 | 
			
		||||
                            CoglPixelFormat format,
 | 
			
		||||
                            CoglPixelFormat internal_format,
 | 
			
		||||
                            GLenum internal_gl_format,
 | 
			
		||||
                            GLenum internal_format,
 | 
			
		||||
                            unsigned int rowstride,
 | 
			
		||||
                            const guint8 *data,
 | 
			
		||||
                            GError **error);
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_texture_rectangle_check (CoglTexture *texture);
 | 
			
		||||
                            const guint8 *data);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -98,6 +98,18 @@ meta_texture_tower_free (MetaTextureTower *tower)
 | 
			
		||||
  g_slice_free (MetaTextureTower, tower);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
 | 
			
		||||
static gboolean
 | 
			
		||||
texture_is_rectangle (CoglHandle texture)
 | 
			
		||||
{
 | 
			
		||||
  GLuint gl_tex;
 | 
			
		||||
  GLenum gl_target;
 | 
			
		||||
 | 
			
		||||
  cogl_texture_get_gl_texture (texture, &gl_tex, &gl_target);
 | 
			
		||||
  return gl_target == GL_TEXTURE_RECTANGLE_ARB;
 | 
			
		||||
}
 | 
			
		||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_texture_tower_set_base_texture:
 | 
			
		||||
 * @tower: a #MetaTextureTower
 | 
			
		||||
@@ -186,9 +198,6 @@ meta_texture_tower_update_area (MetaTextureTower *tower,
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (tower != NULL);
 | 
			
		||||
 | 
			
		||||
  if (tower->textures[0] == COGL_INVALID_HANDLE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  texture_width = cogl_texture_get_width (tower->textures[0]);
 | 
			
		||||
  texture_height = cogl_texture_get_height (tower->textures[0]);
 | 
			
		||||
 | 
			
		||||
@@ -342,11 +351,13 @@ get_paint_level (int width, int height)
 | 
			
		||||
    return (int)(0.5 + lambda);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
 | 
			
		||||
static gboolean
 | 
			
		||||
is_power_of_two (int x)
 | 
			
		||||
{
 | 
			
		||||
  return (x & (x - 1)) == 0;
 | 
			
		||||
}
 | 
			
		||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
texture_tower_create_texture (MetaTextureTower *tower,
 | 
			
		||||
@@ -354,23 +365,25 @@ texture_tower_create_texture (MetaTextureTower *tower,
 | 
			
		||||
                              int               width,
 | 
			
		||||
                              int               height)
 | 
			
		||||
{
 | 
			
		||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
 | 
			
		||||
  if ((!is_power_of_two (width) || !is_power_of_two (height)) &&
 | 
			
		||||
      meta_texture_rectangle_check (tower->textures[level - 1]))
 | 
			
		||||
      texture_is_rectangle (tower->textures[level - 1]))
 | 
			
		||||
    {
 | 
			
		||||
      tower->textures[level] =
 | 
			
		||||
        meta_texture_rectangle_new (width, height,
 | 
			
		||||
                                    0, /* flags */
 | 
			
		||||
                                    /* data format */
 | 
			
		||||
                                    TEXTURE_FORMAT,
 | 
			
		||||
                                    /* internal GL format */
 | 
			
		||||
                                    GL_RGBA,
 | 
			
		||||
                                    /* internal cogl format */
 | 
			
		||||
                                    TEXTURE_FORMAT,
 | 
			
		||||
                                    /* rowstride */
 | 
			
		||||
                                    width * 4,
 | 
			
		||||
                                    /* data */
 | 
			
		||||
                                    NULL,
 | 
			
		||||
                                    /* error */
 | 
			
		||||
                                    NULL);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
#endif /* GL_TEXTURE_RECTANGLE_ARB */
 | 
			
		||||
    {
 | 
			
		||||
      tower->textures[level] = cogl_texture_new_with_size (width, height,
 | 
			
		||||
                                                           COGL_TEXTURE_NO_AUTO_MIPMAP,
 | 
			
		||||
@@ -546,7 +559,7 @@ texture_tower_revalidate_client (MetaTextureTower *tower,
 | 
			
		||||
                           4 * dest_width,
 | 
			
		||||
                           dest_data);
 | 
			
		||||
 | 
			
		||||
  if (dest_texture_height < source_texture_height)
 | 
			
		||||
  if (dest_height < source_texture_height)
 | 
			
		||||
    {
 | 
			
		||||
      g_free (source_tmp1);
 | 
			
		||||
      g_free (source_tmp2);
 | 
			
		||||
 
 | 
			
		||||
@@ -13,20 +13,17 @@
 | 
			
		||||
#define COGL_ENABLE_EXPERIMENTAL_API
 | 
			
		||||
#include <cogl/cogl-texture-pixmap-x11.h>
 | 
			
		||||
#include <gdk/gdk.h> /* for gdk_rectangle_union() */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <meta/display.h>
 | 
			
		||||
#include <meta/errors.h>
 | 
			
		||||
#include "frame.h"
 | 
			
		||||
#include <meta/window.h>
 | 
			
		||||
#include <meta/meta-shaped-texture.h>
 | 
			
		||||
#include "xprops.h"
 | 
			
		||||
 | 
			
		||||
#include "compositor-private.h"
 | 
			
		||||
#include "meta-shadow-factory-private.h"
 | 
			
		||||
#include "meta-shaped-texture.h"
 | 
			
		||||
#include "meta-window-actor-private.h"
 | 
			
		||||
#include "meta-texture-rectangle.h"
 | 
			
		||||
#include "region-utils.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  POSITION_CHANGED,
 | 
			
		||||
@@ -126,10 +123,15 @@ enum
 | 
			
		||||
  PROP_META_WINDOW = 1,
 | 
			
		||||
  PROP_META_SCREEN,
 | 
			
		||||
  PROP_X_WINDOW,
 | 
			
		||||
  PROP_X_WINDOW_ATTRIBUTES,
 | 
			
		||||
  PROP_NO_SHADOW,
 | 
			
		||||
  PROP_SHADOW_CLASS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_SHADOW_RADIUS 12
 | 
			
		||||
#define DEFAULT_SHADOW_X_OFFSET 0
 | 
			
		||||
#define DEFAULT_SHADOW_Y_OFFSET 8
 | 
			
		||||
 | 
			
		||||
static void meta_window_actor_dispose    (GObject *object);
 | 
			
		||||
static void meta_window_actor_finalize   (GObject *object);
 | 
			
		||||
static void meta_window_actor_constructed (GObject *object);
 | 
			
		||||
@@ -230,13 +232,15 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
 | 
			
		||||
    g_signal_new ("position-changed",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0, NULL, NULL, NULL,
 | 
			
		||||
                  0, NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
  signals[SIZE_CHANGED] =
 | 
			
		||||
    g_signal_new ("size-changed",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0, NULL, NULL, NULL,
 | 
			
		||||
                  0, NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -737,52 +741,74 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
 | 
			
		||||
      meta_window_is_fullscreen (priv->window))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * If we have two snap-tiled windows, we don't want the shadow to obstruct
 | 
			
		||||
   * the other window.
 | 
			
		||||
   */
 | 
			
		||||
  if (meta_window_get_tile_match (priv->window))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Always put a shadow around windows with a frame - This should override
 | 
			
		||||
   * the restriction about not putting a shadow around ARGB windows.
 | 
			
		||||
   */
 | 
			
		||||
  if (meta_window_get_frame (priv->window))
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  if (priv->window)
 | 
			
		||||
    {
 | 
			
		||||
      if (meta_window_get_frame (priv->window))
 | 
			
		||||
	{
 | 
			
		||||
	  meta_verbose ("Window 0x%x has shadow because it has a frame\n",
 | 
			
		||||
			(guint)priv->xwindow);
 | 
			
		||||
	  return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Do not add shadows to ARGB windows; eventually we should generate a
 | 
			
		||||
   * shadow from the input shape for such windows.
 | 
			
		||||
   */
 | 
			
		||||
  if (priv->argb32 || priv->opacity != 0xff)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("Window 0x%x has no shadow as it is ARGB\n",
 | 
			
		||||
		    (guint)priv->xwindow);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Add shadows to override redirect windows (e.g., Gtk menus).
 | 
			
		||||
   */
 | 
			
		||||
  if (priv->window->override_redirect)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("Window 0x%x has shadow because it is override redirect.\n",
 | 
			
		||||
		    (guint)priv->xwindow);
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Don't put shadow around DND icon windows
 | 
			
		||||
   */
 | 
			
		||||
  if (window_type == META_WINDOW_DND ||
 | 
			
		||||
      window_type == META_WINDOW_DESKTOP)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("Window 0x%x has no shadow as it is DND or Desktop\n",
 | 
			
		||||
		    (guint)priv->xwindow);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (window_type == META_WINDOW_MENU
 | 
			
		||||
#if 0
 | 
			
		||||
      || window_type == META_WINDOW_DROPDOWN_MENU
 | 
			
		||||
#endif
 | 
			
		||||
      )
 | 
			
		||||
    return TRUE;
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("Window 0x%x has shadow as it is a menu\n",
 | 
			
		||||
		    (guint)priv->xwindow);
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
  if (window_type == META_WINDOW_TOOLTIP)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("Window 0x%x has shadow as it is a tooltip\n",
 | 
			
		||||
		    (guint)priv->xwindow);
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  meta_verbose ("Window 0x%x has no shadow as it fell through\n",
 | 
			
		||||
		(guint)priv->xwindow);
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -920,20 +946,23 @@ static void
 | 
			
		||||
meta_window_actor_damage_all (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  CoglHandle texture;
 | 
			
		||||
  ClutterX11TexturePixmap *texture_x11 = CLUTTER_X11_TEXTURE_PIXMAP (priv->actor);
 | 
			
		||||
  guint pixmap_width = 0;
 | 
			
		||||
  guint pixmap_height = 0;
 | 
			
		||||
 | 
			
		||||
  if (!priv->needs_damage_all)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
 | 
			
		||||
  g_object_get (texture_x11,
 | 
			
		||||
                "pixmap-width", &pixmap_width,
 | 
			
		||||
                "pixmap-height", &pixmap_height,
 | 
			
		||||
                NULL);
 | 
			
		||||
 | 
			
		||||
  if (!priv->mapped || priv->needs_pixmap)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                   0, 0,
 | 
			
		||||
                                   cogl_texture_get_width (texture),
 | 
			
		||||
                                   cogl_texture_get_height (texture));
 | 
			
		||||
  clutter_x11_texture_pixmap_update_area (texture_x11,
 | 
			
		||||
                                          0,
 | 
			
		||||
                                          0,
 | 
			
		||||
                                          pixmap_width,
 | 
			
		||||
                                          pixmap_height);
 | 
			
		||||
 | 
			
		||||
  priv->needs_damage_all = FALSE;
 | 
			
		||||
}
 | 
			
		||||
@@ -1172,8 +1201,9 @@ meta_window_actor_detach (MetaWindowActor *self)
 | 
			
		||||
   * you are supposed to be able to free a GLXPixmap after freeing the underlying
 | 
			
		||||
   * pixmap, but it certainly doesn't work with current DRI/Mesa
 | 
			
		||||
   */
 | 
			
		||||
  meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                  None);
 | 
			
		||||
  clutter_x11_texture_pixmap_set_pixmap (CLUTTER_X11_TEXTURE_PIXMAP (priv->actor),
 | 
			
		||||
                                         None);
 | 
			
		||||
  meta_shaped_texture_clear (META_SHAPED_TEXTURE (priv->actor));
 | 
			
		||||
  cogl_flush();
 | 
			
		||||
 | 
			
		||||
  XFreePixmap (xdisplay, priv->back_pixmap);
 | 
			
		||||
@@ -1188,36 +1218,31 @@ meta_window_actor_should_unredirect (MetaWindowActor *self)
 | 
			
		||||
  MetaWindow *metaWindow = meta_window_actor_get_meta_window (self);
 | 
			
		||||
  MetaScreen *screen = meta_window_get_screen (metaWindow);
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  int screen_width, screen_height;
 | 
			
		||||
  MetaRectangle window_rect, monitor_rect;
 | 
			
		||||
  int num_monitors = meta_screen_get_n_monitors (screen);
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if (!meta_window_is_override_redirect (metaWindow))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (priv->opacity != 0xff)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (priv->argb32)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (metaWindow->has_shape)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  meta_screen_get_size (screen, &screen_width, &screen_height);
 | 
			
		||||
  meta_window_get_outer_rect (metaWindow, &window_rect);
 | 
			
		||||
 | 
			
		||||
  if (window_rect.x == 0 && window_rect.y == 0 &&
 | 
			
		||||
      window_rect.width == screen_width && window_rect.height == screen_height)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < num_monitors; i++)
 | 
			
		||||
  if (meta_window_is_override_redirect (metaWindow) && priv->opacity == 0xff && !priv->argb32)
 | 
			
		||||
    {
 | 
			
		||||
      meta_screen_get_monitor_geometry (screen , i, &monitor_rect);
 | 
			
		||||
      if (monitor_rect.x == window_rect.x && monitor_rect.y == window_rect.y &&
 | 
			
		||||
          monitor_rect.width == window_rect.width && monitor_rect.height == window_rect.height)
 | 
			
		||||
        return TRUE;
 | 
			
		||||
      int screen_width, screen_height;
 | 
			
		||||
      MetaRectangle window_rect;
 | 
			
		||||
      meta_screen_get_size (screen, &screen_width, &screen_height);
 | 
			
		||||
      meta_window_get_outer_rect (metaWindow, &window_rect);
 | 
			
		||||
 | 
			
		||||
      if (window_rect.x == 0 && window_rect.y == 0 &&
 | 
			
		||||
          window_rect.width == screen_width && window_rect.height == screen_height)
 | 
			
		||||
           return TRUE;
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          int num_monitors = meta_screen_get_n_monitors (screen);
 | 
			
		||||
          int i;
 | 
			
		||||
          MetaRectangle monitor_rect;
 | 
			
		||||
 | 
			
		||||
          for (i = 0; i < num_monitors; i++)
 | 
			
		||||
            {
 | 
			
		||||
              meta_screen_get_monitor_geometry (screen , i, &monitor_rect);
 | 
			
		||||
              if (monitor_rect.x == window_rect.x && monitor_rect.y == window_rect.y &&
 | 
			
		||||
                  monitor_rect.width == window_rect.width && monitor_rect.height == window_rect.height)
 | 
			
		||||
                    return TRUE;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
@@ -1227,24 +1252,19 @@ void
 | 
			
		||||
meta_window_actor_set_redirected (MetaWindowActor *self, gboolean state)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindow *metaWindow = meta_window_actor_get_meta_window (self);
 | 
			
		||||
  MetaDisplay *display = meta_window_get_display (metaWindow);
 | 
			
		||||
 | 
			
		||||
  Display *xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
  Display *xdisplay = meta_display_get_xdisplay (meta_window_get_display (metaWindow));
 | 
			
		||||
  Window  xwin = meta_window_actor_get_x_window (self);
 | 
			
		||||
 | 
			
		||||
  if (state)
 | 
			
		||||
    {
 | 
			
		||||
      meta_error_trap_push (display);
 | 
			
		||||
      XCompositeRedirectWindow (xdisplay, xwin, CompositeRedirectManual);
 | 
			
		||||
      meta_error_trap_pop (display);
 | 
			
		||||
      meta_window_actor_queue_create_pixmap (self);
 | 
			
		||||
      self->priv->unredirected = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      meta_error_trap_push (display);
 | 
			
		||||
      XCompositeUnredirectWindow (xdisplay, xwin, CompositeRedirectManual);
 | 
			
		||||
      meta_error_trap_pop (display);
 | 
			
		||||
      self->priv->unredirected = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1590,16 +1610,24 @@ meta_window_actor_update_bounding_region_and_borders (MetaWindowActor *self,
 | 
			
		||||
                                                      int              height)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  MetaFrame *frame;
 | 
			
		||||
  MetaFrameBorders borders;
 | 
			
		||||
  cairo_rectangle_int_t bounding_rectangle;
 | 
			
		||||
 | 
			
		||||
  meta_frame_calc_borders (priv->window->frame, &borders);
 | 
			
		||||
  bounding_rectangle.x = 0;
 | 
			
		||||
  bounding_rectangle.y = 0;
 | 
			
		||||
 | 
			
		||||
  bounding_rectangle.x = borders.invisible.left;
 | 
			
		||||
  bounding_rectangle.y = borders.invisible.top;
 | 
			
		||||
  frame = priv->window->frame;
 | 
			
		||||
  if (frame != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      meta_frame_calc_borders (frame, &borders);
 | 
			
		||||
 | 
			
		||||
  width -= borders.invisible.left + borders.invisible.right;
 | 
			
		||||
  height -= borders.invisible.top + borders.invisible.bottom;
 | 
			
		||||
      bounding_rectangle.x = borders.invisible.left;
 | 
			
		||||
      bounding_rectangle.y = borders.invisible.top;
 | 
			
		||||
 | 
			
		||||
      width -= borders.invisible.left + borders.invisible.right;
 | 
			
		||||
      height -= borders.invisible.top + borders.invisible.bottom;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  bounding_rectangle.width = width;
 | 
			
		||||
  bounding_rectangle.height = height;
 | 
			
		||||
@@ -1689,7 +1717,7 @@ meta_window_actor_get_obscured_region (MetaWindowActor *self)
 | 
			
		||||
#if 0
 | 
			
		||||
/* Print out a region; useful for debugging */
 | 
			
		||||
static void
 | 
			
		||||
print_region (cairo_region_t *region)
 | 
			
		||||
dump_region (cairo_region_t *region)
 | 
			
		||||
{
 | 
			
		||||
  int n_rects;
 | 
			
		||||
  int i;
 | 
			
		||||
@@ -1707,26 +1735,6 @@ print_region (cairo_region_t *region)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
/* Dump a region to a PNG file; useful for debugging */
 | 
			
		||||
static void
 | 
			
		||||
see_region (cairo_region_t *region,
 | 
			
		||||
            int             width,
 | 
			
		||||
            int             height,
 | 
			
		||||
            char           *filename)
 | 
			
		||||
{
 | 
			
		||||
  cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
 | 
			
		||||
  cairo_t *cr = cairo_create (surface);
 | 
			
		||||
 | 
			
		||||
  gdk_cairo_region (cr, region);
 | 
			
		||||
  cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
  cairo_surface_write_to_png (surface, filename);
 | 
			
		||||
  cairo_destroy (cr);
 | 
			
		||||
  cairo_surface_destroy (surface);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_window_actor_set_visible_region:
 | 
			
		||||
 * @self: a #MetaWindowActor
 | 
			
		||||
@@ -1742,9 +1750,22 @@ meta_window_actor_set_visible_region (MetaWindowActor *self,
 | 
			
		||||
                                      cairo_region_t  *visible_region)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  cairo_region_t *texture_clip_region = NULL;
 | 
			
		||||
 | 
			
		||||
  /* Get the area of the window texture that would be drawn if
 | 
			
		||||
   * we weren't obscured at all
 | 
			
		||||
   */
 | 
			
		||||
  texture_clip_region = meta_shaped_texture_get_visible_pixels_region (META_SHAPED_TEXTURE (priv->actor));
 | 
			
		||||
  texture_clip_region = cairo_region_copy (texture_clip_region);
 | 
			
		||||
 | 
			
		||||
  /* Then intersect that with the visible region to get the region
 | 
			
		||||
   * that we actually need to redraw.
 | 
			
		||||
   */
 | 
			
		||||
  cairo_region_intersect (texture_clip_region, visible_region);
 | 
			
		||||
 | 
			
		||||
  /* Assumes ownership */
 | 
			
		||||
  meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                       visible_region);
 | 
			
		||||
                                       texture_clip_region);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -1796,6 +1817,19 @@ meta_window_actor_reset_visible_regions (MetaWindowActor *self)
 | 
			
		||||
  meta_window_actor_clear_shadow_clip (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
texture_pixmap_using_extension (ClutterX11TexturePixmap *texture)
 | 
			
		||||
{
 | 
			
		||||
  ClutterTexture *self = CLUTTER_TEXTURE (texture);
 | 
			
		||||
  CoglHandle handle;
 | 
			
		||||
 | 
			
		||||
  handle = clutter_texture_get_cogl_texture (self);
 | 
			
		||||
 | 
			
		||||
  return handle != NULL &&
 | 
			
		||||
         cogl_is_texture_pixmap_x11 (handle) &&
 | 
			
		||||
         cogl_texture_pixmap_x11_is_using_tfp_extension (handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
check_needs_pixmap (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
@@ -1829,7 +1863,7 @@ check_needs_pixmap (MetaWindowActor *self)
 | 
			
		||||
 | 
			
		||||
  if (priv->back_pixmap == None)
 | 
			
		||||
    {
 | 
			
		||||
      CoglHandle texture;
 | 
			
		||||
      gint pxm_width, pxm_height;
 | 
			
		||||
 | 
			
		||||
      meta_error_trap_push (display);
 | 
			
		||||
 | 
			
		||||
@@ -1858,22 +1892,23 @@ check_needs_pixmap (MetaWindowActor *self)
 | 
			
		||||
        meta_shaped_texture_set_create_mipmaps (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                                FALSE);
 | 
			
		||||
 | 
			
		||||
      meta_shaped_texture_set_pixmap (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                      priv->back_pixmap);
 | 
			
		||||
 | 
			
		||||
      texture = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
 | 
			
		||||
 | 
			
		||||
      clutter_x11_texture_pixmap_set_pixmap
 | 
			
		||||
                       (CLUTTER_X11_TEXTURE_PIXMAP (priv->actor),
 | 
			
		||||
                        priv->back_pixmap);
 | 
			
		||||
      /*
 | 
			
		||||
       * This only works *after* actually setting the pixmap, so we have to
 | 
			
		||||
       * do it here.
 | 
			
		||||
       * See: http://bugzilla.clutter-project.org/show_bug.cgi?id=2236
 | 
			
		||||
       */
 | 
			
		||||
      if (G_UNLIKELY (!cogl_texture_pixmap_x11_is_using_tfp_extension (texture)))
 | 
			
		||||
      if (G_UNLIKELY (!texture_pixmap_using_extension (CLUTTER_X11_TEXTURE_PIXMAP (priv->actor))))
 | 
			
		||||
        g_warning ("NOTE: Not using GLX TFP!\n");
 | 
			
		||||
 | 
			
		||||
      meta_window_actor_update_bounding_region_and_borders (self,
 | 
			
		||||
                                                            cogl_texture_get_width (texture),
 | 
			
		||||
                                                            cogl_texture_get_height (texture));
 | 
			
		||||
      g_object_get (priv->actor,
 | 
			
		||||
                    "pixmap-width", &pxm_width,
 | 
			
		||||
                    "pixmap-height", &pxm_height,
 | 
			
		||||
                    NULL);
 | 
			
		||||
 | 
			
		||||
      meta_window_actor_update_bounding_region_and_borders (self, pxm_width, pxm_height);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  priv->needs_pixmap = FALSE;
 | 
			
		||||
@@ -1966,6 +2001,7 @@ meta_window_actor_process_damage (MetaWindowActor    *self,
 | 
			
		||||
                                  XDamageNotifyEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  ClutterX11TexturePixmap *texture_x11 = CLUTTER_X11_TEXTURE_PIXMAP (priv->actor);
 | 
			
		||||
 | 
			
		||||
  priv->received_damage = TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -1993,14 +2029,12 @@ meta_window_actor_process_damage (MetaWindowActor    *self,
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!priv->mapped || priv->needs_pixmap)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                   event->area.x,
 | 
			
		||||
                                   event->area.y,
 | 
			
		||||
                                   event->area.width,
 | 
			
		||||
                                   event->area.height);
 | 
			
		||||
  clutter_x11_texture_pixmap_update_area (texture_x11,
 | 
			
		||||
                                          event->area.x,
 | 
			
		||||
                                          event->area.y,
 | 
			
		||||
                                          event->area.width,
 | 
			
		||||
                                          event->area.height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -2017,197 +2051,121 @@ meta_window_actor_sync_visibility (MetaWindowActor *self)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define TAU (2*M_PI)
 | 
			
		||||
static inline void
 | 
			
		||||
set_integral_bounding_rect (cairo_rectangle_int_t *rect,
 | 
			
		||||
                            double x, double y,
 | 
			
		||||
                            double width, double height)
 | 
			
		||||
{
 | 
			
		||||
  rect->x = floor(x);
 | 
			
		||||
  rect->y = floor(y);
 | 
			
		||||
  rect->width = ceil(x + width) - rect->x;
 | 
			
		||||
  rect->height = ceil(y + height) - rect->y;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
install_corners (MetaWindow       *window,
 | 
			
		||||
                 MetaFrameBorders *borders,
 | 
			
		||||
                 cairo_t          *cr)
 | 
			
		||||
update_corners (MetaWindowActor   *self,
 | 
			
		||||
                MetaFrameBorders  *borders)
 | 
			
		||||
{
 | 
			
		||||
  float top_left, top_right, bottom_left, bottom_right;
 | 
			
		||||
  int x, y;
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  MetaRectangle outer;
 | 
			
		||||
  cairo_rectangle_int_t corner_rects[4];
 | 
			
		||||
  cairo_region_t *corner_region;
 | 
			
		||||
  cairo_path_t *corner_path;
 | 
			
		||||
  float top_left, top_right, bottom_left, bottom_right;
 | 
			
		||||
  float x, y;
 | 
			
		||||
 | 
			
		||||
  meta_frame_get_corner_radiuses (window->frame,
 | 
			
		||||
  /* need these to build a path */
 | 
			
		||||
  cairo_t *cr;
 | 
			
		||||
  cairo_surface_t *surface;
 | 
			
		||||
 | 
			
		||||
  if (!priv->window->frame)
 | 
			
		||||
    {
 | 
			
		||||
      meta_shaped_texture_set_overlay_path (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                            NULL, NULL);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_window_get_outer_rect (priv->window, &outer);
 | 
			
		||||
 | 
			
		||||
  meta_frame_get_corner_radiuses (priv->window->frame,
 | 
			
		||||
                                  &top_left,
 | 
			
		||||
                                  &top_right,
 | 
			
		||||
                                  &bottom_left,
 | 
			
		||||
                                  &bottom_right);
 | 
			
		||||
 | 
			
		||||
  meta_window_get_outer_rect (window, &outer);
 | 
			
		||||
  /* Unfortunately, cairo does not allow us to create a context
 | 
			
		||||
   * without a surface. Create a 0x0 image surface to "paint to"
 | 
			
		||||
   * so we can get the path. */
 | 
			
		||||
  surface = cairo_image_surface_create (CAIRO_FORMAT_A8,
 | 
			
		||||
                                        0, 0);
 | 
			
		||||
 | 
			
		||||
  cr = cairo_create (surface);
 | 
			
		||||
 | 
			
		||||
  /* top left */
 | 
			
		||||
  x = borders->invisible.left;
 | 
			
		||||
  y = borders->invisible.top;
 | 
			
		||||
 | 
			
		||||
  set_integral_bounding_rect (&corner_rects[0],
 | 
			
		||||
                              x, y, top_left, top_left);
 | 
			
		||||
 | 
			
		||||
  cairo_arc (cr,
 | 
			
		||||
             x + top_left,
 | 
			
		||||
             y + top_left,
 | 
			
		||||
             top_left,
 | 
			
		||||
             2 * TAU / 4,
 | 
			
		||||
             3 * TAU / 4);
 | 
			
		||||
             0, M_PI*2);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /* top right */
 | 
			
		||||
  x = borders->invisible.left + outer.width - top_right;
 | 
			
		||||
  y = borders->invisible.top;
 | 
			
		||||
 | 
			
		||||
  set_integral_bounding_rect (&corner_rects[1],
 | 
			
		||||
                              x, y, top_right, top_right);
 | 
			
		||||
 | 
			
		||||
  cairo_arc (cr,
 | 
			
		||||
             x,
 | 
			
		||||
             y + top_right,
 | 
			
		||||
             top_right,
 | 
			
		||||
             3 * TAU / 4,
 | 
			
		||||
             4 * TAU / 4);
 | 
			
		||||
             0, M_PI*2);
 | 
			
		||||
 | 
			
		||||
  /* bottom right */
 | 
			
		||||
  x = borders->invisible.left + outer.width - bottom_right;
 | 
			
		||||
  y = borders->invisible.top + outer.height - bottom_right;
 | 
			
		||||
 | 
			
		||||
  set_integral_bounding_rect (&corner_rects[2],
 | 
			
		||||
                              x, y, bottom_right, bottom_right);
 | 
			
		||||
 | 
			
		||||
  cairo_arc (cr,
 | 
			
		||||
             x,
 | 
			
		||||
             y,
 | 
			
		||||
             bottom_right,
 | 
			
		||||
             0 * TAU / 4,
 | 
			
		||||
             1 * TAU / 4);
 | 
			
		||||
             0, M_PI*2);
 | 
			
		||||
 | 
			
		||||
  /* bottom left */
 | 
			
		||||
  x = borders->invisible.left;
 | 
			
		||||
  y = borders->invisible.top + outer.height - bottom_left;
 | 
			
		||||
 | 
			
		||||
  set_integral_bounding_rect (&corner_rects[3],
 | 
			
		||||
                              x, y, bottom_left, bottom_left);
 | 
			
		||||
 | 
			
		||||
  cairo_arc (cr,
 | 
			
		||||
             x + bottom_left,
 | 
			
		||||
             y,
 | 
			
		||||
             bottom_left,
 | 
			
		||||
             1 * TAU / 4,
 | 
			
		||||
             2 * TAU / 4);
 | 
			
		||||
             0, M_PI*2);
 | 
			
		||||
 | 
			
		||||
  cairo_set_source_rgba (cr, 1, 1, 1, 1);
 | 
			
		||||
  cairo_fill (cr);
 | 
			
		||||
}
 | 
			
		||||
  corner_path = cairo_copy_path (cr);
 | 
			
		||||
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
scan_visible_region (guchar         *mask_data,
 | 
			
		||||
                     int             stride,
 | 
			
		||||
                     cairo_region_t *scan_area)
 | 
			
		||||
{
 | 
			
		||||
  int i, n_rects = cairo_region_num_rectangles (scan_area);
 | 
			
		||||
  MetaRegionBuilder builder;
 | 
			
		||||
 | 
			
		||||
  meta_region_builder_init (&builder);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_rects; i++)
 | 
			
		||||
    {
 | 
			
		||||
      int x, y;
 | 
			
		||||
      cairo_rectangle_int_t rect;
 | 
			
		||||
 | 
			
		||||
      cairo_region_get_rectangle (scan_area, i, &rect);
 | 
			
		||||
 | 
			
		||||
      for (y = rect.y; y < (rect.y + rect.height); y++)
 | 
			
		||||
        {
 | 
			
		||||
          for (x = rect.x; x < (rect.x + rect.width); x++)
 | 
			
		||||
            {
 | 
			
		||||
              int w = x;
 | 
			
		||||
              while (mask_data[y * stride + w] == 255 && w < (rect.x + rect.width))
 | 
			
		||||
                w++;
 | 
			
		||||
 | 
			
		||||
              if (w > 0)
 | 
			
		||||
                {
 | 
			
		||||
                  meta_region_builder_add_rectangle (&builder, x, y, w - x, 1);
 | 
			
		||||
                  x = w;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return meta_region_builder_finish (&builder);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
build_and_scan_frame_mask (MetaWindowActor       *self,
 | 
			
		||||
                           MetaFrameBorders      *borders,
 | 
			
		||||
                           cairo_rectangle_int_t *client_area,
 | 
			
		||||
                           cairo_region_t        *shape_region)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  guchar *mask_data;
 | 
			
		||||
  guint tex_width, tex_height;
 | 
			
		||||
  CoglHandle paint_tex, mask_texture;
 | 
			
		||||
  int stride;
 | 
			
		||||
  cairo_t *cr;
 | 
			
		||||
  cairo_surface_t *surface;
 | 
			
		||||
 | 
			
		||||
  paint_tex = meta_shaped_texture_get_texture (META_SHAPED_TEXTURE (priv->actor));
 | 
			
		||||
  if (paint_tex == COGL_INVALID_HANDLE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  tex_width = cogl_texture_get_width (paint_tex);
 | 
			
		||||
  tex_height = cogl_texture_get_height (paint_tex);
 | 
			
		||||
 | 
			
		||||
  stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, tex_width);
 | 
			
		||||
 | 
			
		||||
  /* Create data for an empty image */
 | 
			
		||||
  mask_data = g_malloc0 (stride * tex_height);
 | 
			
		||||
 | 
			
		||||
  surface = cairo_image_surface_create_for_data (mask_data,
 | 
			
		||||
                                                 CAIRO_FORMAT_A8,
 | 
			
		||||
                                                 tex_width,
 | 
			
		||||
                                                 tex_height,
 | 
			
		||||
                                                 stride);
 | 
			
		||||
  cr = cairo_create (surface);
 | 
			
		||||
 | 
			
		||||
  gdk_cairo_region (cr, shape_region);
 | 
			
		||||
  cairo_fill (cr);
 | 
			
		||||
 | 
			
		||||
  if (priv->window->frame != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_region_t *frame_paint_region, *scanned_region;
 | 
			
		||||
      cairo_rectangle_int_t rect = { 0, 0, tex_width, tex_height };
 | 
			
		||||
 | 
			
		||||
      /* Make sure we don't paint the frame over the client window. */
 | 
			
		||||
      frame_paint_region = cairo_region_create_rectangle (&rect);
 | 
			
		||||
      cairo_region_subtract_rectangle (frame_paint_region, client_area);
 | 
			
		||||
 | 
			
		||||
      gdk_cairo_region (cr, frame_paint_region);
 | 
			
		||||
      cairo_clip (cr);
 | 
			
		||||
 | 
			
		||||
      install_corners (priv->window, borders, cr);
 | 
			
		||||
 | 
			
		||||
      cairo_surface_flush (surface);
 | 
			
		||||
      scanned_region = scan_visible_region (mask_data, stride, frame_paint_region);
 | 
			
		||||
      cairo_region_union (shape_region, scanned_region);
 | 
			
		||||
      cairo_region_destroy (scanned_region);
 | 
			
		||||
      cairo_region_destroy (frame_paint_region);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cairo_destroy (cr);
 | 
			
		||||
  cairo_surface_destroy (surface);
 | 
			
		||||
  cairo_destroy (cr);
 | 
			
		||||
 | 
			
		||||
  if (meta_texture_rectangle_check (paint_tex))
 | 
			
		||||
    {
 | 
			
		||||
      mask_texture = meta_texture_rectangle_new (tex_width, tex_height,
 | 
			
		||||
                                                 COGL_PIXEL_FORMAT_A_8,
 | 
			
		||||
                                                 COGL_PIXEL_FORMAT_A_8,
 | 
			
		||||
                                                 stride,
 | 
			
		||||
                                                 mask_data,
 | 
			
		||||
                                                 NULL /* error */);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* Note: we don't allow slicing for this texture because we
 | 
			
		||||
       * need to use it with multi-texturing which doesn't support
 | 
			
		||||
       * sliced textures */
 | 
			
		||||
      mask_texture = cogl_texture_new_from_data (tex_width, tex_height,
 | 
			
		||||
                                                 COGL_TEXTURE_NO_SLICING,
 | 
			
		||||
                                                 COGL_PIXEL_FORMAT_A_8,
 | 
			
		||||
                                                 COGL_PIXEL_FORMAT_ANY,
 | 
			
		||||
                                                 stride,
 | 
			
		||||
                                                 mask_data);
 | 
			
		||||
    }
 | 
			
		||||
  corner_region = cairo_region_create_rectangles (corner_rects, 4);
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                        mask_texture);
 | 
			
		||||
  cogl_handle_unref (mask_texture);
 | 
			
		||||
  meta_shaped_texture_set_overlay_path (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                        corner_region, corner_path);
 | 
			
		||||
 | 
			
		||||
  cairo_region_destroy (corner_region);
 | 
			
		||||
 | 
			
		||||
  g_free (mask_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -2217,30 +2175,57 @@ check_needs_reshape (MetaWindowActor *self)
 | 
			
		||||
  MetaScreen *screen = priv->screen;
 | 
			
		||||
  MetaDisplay *display = meta_screen_get_display (screen);
 | 
			
		||||
  MetaFrameBorders borders;
 | 
			
		||||
  cairo_region_t *region = NULL;
 | 
			
		||||
  cairo_rectangle_int_t client_area;
 | 
			
		||||
  cairo_region_t *region;
 | 
			
		||||
 | 
			
		||||
  if (!priv->needs_reshape)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_frame_calc_borders (priv->window->frame, &borders);
 | 
			
		||||
 | 
			
		||||
  client_area.x = borders.total.left;
 | 
			
		||||
  client_area.y = borders.total.top;
 | 
			
		||||
  client_area.width = priv->window->rect.width;
 | 
			
		||||
  client_area.height = priv->window->rect.height;
 | 
			
		||||
 | 
			
		||||
  meta_shaped_texture_set_mask_texture (META_SHAPED_TEXTURE (priv->actor), COGL_INVALID_HANDLE);
 | 
			
		||||
  meta_shaped_texture_set_shape_region (META_SHAPED_TEXTURE (priv->actor), NULL);
 | 
			
		||||
  meta_window_actor_clear_shape_region (self);
 | 
			
		||||
 | 
			
		||||
  if (priv->window->frame)
 | 
			
		||||
    meta_frame_calc_borders (priv->window->frame, &borders);
 | 
			
		||||
  else
 | 
			
		||||
    meta_frame_borders_clear (&borders);
 | 
			
		||||
 | 
			
		||||
  region = meta_window_get_frame_bounds (priv->window);
 | 
			
		||||
  if (region != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* This returns the window's internal frame bounds region,
 | 
			
		||||
       * so we need to copy it because we modify it below. */
 | 
			
		||||
      region = cairo_region_copy (region);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* If we have no region, we have no frame. We have no frame,
 | 
			
		||||
       * so just use the bounding region instead */
 | 
			
		||||
      region = cairo_region_copy (priv->bounding_region);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SHAPE
 | 
			
		||||
  if (priv->window->has_shape)
 | 
			
		||||
    {
 | 
			
		||||
      /* Translate the set of XShape rectangles that we
 | 
			
		||||
       * get from the X server to a cairo_region. */
 | 
			
		||||
      Display *xdisplay = meta_display_get_xdisplay (display);
 | 
			
		||||
      XRectangle *rects;
 | 
			
		||||
      int n_rects, ordering;
 | 
			
		||||
      cairo_rectangle_int_t client_area;
 | 
			
		||||
 | 
			
		||||
      client_area.width = priv->window->rect.width;
 | 
			
		||||
      client_area.height = priv->window->rect.height;
 | 
			
		||||
 | 
			
		||||
      if (priv->window->frame)
 | 
			
		||||
        {
 | 
			
		||||
          client_area.x = borders.total.left;
 | 
			
		||||
          client_area.y = borders.total.top;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          client_area.x = 0;
 | 
			
		||||
          client_area.y = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* Punch out client area. */
 | 
			
		||||
      cairo_region_subtract_rectangle (region, &client_area);
 | 
			
		||||
 | 
			
		||||
      meta_error_trap_push (display);
 | 
			
		||||
      rects = XShapeGetRectangles (xdisplay,
 | 
			
		||||
@@ -2253,40 +2238,28 @@ check_needs_reshape (MetaWindowActor *self)
 | 
			
		||||
      if (rects)
 | 
			
		||||
        {
 | 
			
		||||
          int i;
 | 
			
		||||
          cairo_rectangle_int_t *cairo_rects = g_new (cairo_rectangle_int_t, n_rects);
 | 
			
		||||
 | 
			
		||||
          for (i = 0; i < n_rects; i ++)
 | 
			
		||||
            {
 | 
			
		||||
              cairo_rects[i].x = rects[i].x + client_area.x;
 | 
			
		||||
              cairo_rects[i].y = rects[i].y + client_area.y;
 | 
			
		||||
              cairo_rects[i].width = rects[i].width;
 | 
			
		||||
              cairo_rects[i].height = rects[i].height;
 | 
			
		||||
              cairo_rectangle_int_t rect = { rects[i].x + client_area.x,
 | 
			
		||||
                                             rects[i].y + client_area.y,
 | 
			
		||||
                                             rects[i].width,
 | 
			
		||||
                                             rects[i].height };
 | 
			
		||||
              cairo_region_union_rectangle (region, &rect);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          XFree (rects);
 | 
			
		||||
          region = cairo_region_create_rectangles (cairo_rects, n_rects);
 | 
			
		||||
          g_free (cairo_rects);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (region == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* If we don't have a shape on the server, that means that
 | 
			
		||||
       * we have an implicit shape of one rectangle covering the
 | 
			
		||||
       * entire window. */
 | 
			
		||||
      region = cairo_region_create_rectangle (&client_area);
 | 
			
		||||
    }
 | 
			
		||||
  meta_shaped_texture_set_shape_region (META_SHAPED_TEXTURE (priv->actor),
 | 
			
		||||
                                        region);
 | 
			
		||||
 | 
			
		||||
  /* This takes the region, generates a mask using GTK+
 | 
			
		||||
   * and scans the mask looking for all opaque pixels,
 | 
			
		||||
   * adding it to region.
 | 
			
		||||
   */
 | 
			
		||||
  build_and_scan_frame_mask (self, &borders, &client_area, region);
 | 
			
		||||
  meta_window_actor_update_shape_region (self, region);
 | 
			
		||||
 | 
			
		||||
  cairo_region_destroy (region);
 | 
			
		||||
 | 
			
		||||
  update_corners (self, &borders);
 | 
			
		||||
 | 
			
		||||
  priv->needs_reshape = FALSE;
 | 
			
		||||
  meta_window_actor_invalidate_shadow (self);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,28 +26,9 @@ struct _MetaWindowGroup
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaWindowGroup, meta_window_group, CLUTTER_TYPE_GROUP);
 | 
			
		||||
 | 
			
		||||
/* This file uses pixel-aligned region computation to determine what
 | 
			
		||||
 * can be clipped out. This only really works if everything is aligned
 | 
			
		||||
 * to the pixel grid - not scaled or rotated and at integer offsets.
 | 
			
		||||
 *
 | 
			
		||||
 * (This could be relaxed - if we turned off filtering for unscaled
 | 
			
		||||
 * windows then windows would be, by definition aligned to the pixel
 | 
			
		||||
 * grid. And for rectangular windows without a shape, the outline that
 | 
			
		||||
 * we draw for an unrotated window is always a rectangle because we
 | 
			
		||||
 * don't use antialasing for the window boundary - with or without
 | 
			
		||||
 * filtering, with or without a scale. But figuring out exactly
 | 
			
		||||
 * what pixels will be drawn by the graphics system in these cases
 | 
			
		||||
 * gets tricky, so we just go for the easiest part - no scale,
 | 
			
		||||
 * and at integer offsets.)
 | 
			
		||||
 *
 | 
			
		||||
 * The way we check for pixel-aligned is by looking at the
 | 
			
		||||
 * transformation into screen space of the allocation box of an actor
 | 
			
		||||
 * and and checking if the corners are "close enough" to integral
 | 
			
		||||
 * pixel values.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* The definition of "close enough" to integral pixel values is
 | 
			
		||||
 * equality when we convert to 24.8 fixed-point.
 | 
			
		||||
/* We want to find out if the window is "close enough" to
 | 
			
		||||
 * 1:1 transform. We do that by converting the transformed coordinates
 | 
			
		||||
 * to 24.8 fixed-point before checking if they look right.
 | 
			
		||||
 */
 | 
			
		||||
static inline int
 | 
			
		||||
round_to_fixed (float x)
 | 
			
		||||
@@ -55,24 +36,41 @@ round_to_fixed (float x)
 | 
			
		||||
  return roundf (x * 256);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This helper function checks if (according to our fixed point precision)
 | 
			
		||||
 * the vertices @verts form a box of width @widthf and height @heightf
 | 
			
		||||
 * located at integral coordinates. These coordinates are returned
 | 
			
		||||
 * in @x_origin and @y_origin.
 | 
			
		||||
/* We can only (easily) apply our logic for figuring out what a window
 | 
			
		||||
 * obscures if is not transformed. This function does that check and
 | 
			
		||||
 * as a side effect gets the position of the upper-left corner of the
 | 
			
		||||
 * actors.
 | 
			
		||||
 *
 | 
			
		||||
 * (We actually could handle scaled and non-integrally positioned actors
 | 
			
		||||
 * too as long as they weren't shaped - no filtering is done at the
 | 
			
		||||
 * edges so a rectangle stays a rectangle. But the gain from that is
 | 
			
		||||
 * small, especally since most of our windows are shaped. The simple
 | 
			
		||||
 * case we handle here is the case that matters when the user is just
 | 
			
		||||
 * using the desktop normally.)
 | 
			
		||||
 *
 | 
			
		||||
 * If we assume that the window group is untransformed (it better not
 | 
			
		||||
 * be!) then we could also make this determination by checking directly
 | 
			
		||||
 * if the actor itself is rotated, scaled, or at a non-integral position.
 | 
			
		||||
 * However, the criterion for "close enough" in that case get trickier,
 | 
			
		||||
 * since, for example, the allowed rotation depends on the size of
 | 
			
		||||
 * actor. The approach we take here is to just require everything
 | 
			
		||||
 * to be within 1/256th of a pixel.
 | 
			
		||||
 */
 | 
			
		||||
static gboolean
 | 
			
		||||
vertices_are_untransformed (ClutterVertex *verts,
 | 
			
		||||
                            float          widthf,
 | 
			
		||||
                            float          heightf,
 | 
			
		||||
                            int           *x_origin,
 | 
			
		||||
                            int           *y_origin)
 | 
			
		||||
actor_is_untransformed (ClutterActor *actor,
 | 
			
		||||
                        int          *x_origin,
 | 
			
		||||
                        int          *y_origin)
 | 
			
		||||
{
 | 
			
		||||
  gfloat widthf, heightf;
 | 
			
		||||
  int width, height;
 | 
			
		||||
  ClutterVertex verts[4];
 | 
			
		||||
  int v0x, v0y, v1x, v1y, v2x, v2y, v3x, v3y;
 | 
			
		||||
  int x, y;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_size (actor, &widthf, &heightf);
 | 
			
		||||
  width = round_to_fixed (widthf); height = round_to_fixed (heightf);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_abs_allocation_vertices (actor, verts);
 | 
			
		||||
  v0x = round_to_fixed (verts[0].x); v0y = round_to_fixed (verts[0].y);
 | 
			
		||||
  v1x = round_to_fixed (verts[1].x); v1y = round_to_fixed (verts[1].y);
 | 
			
		||||
  v2x = round_to_fixed (verts[2].x); v2y = round_to_fixed (verts[2].y);
 | 
			
		||||
@@ -103,118 +101,42 @@ vertices_are_untransformed (ClutterVertex *verts,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Check if an actor is "untransformed" - which actually means transformed by
 | 
			
		||||
 * at most a integer-translation. The integer translation, if any, is returned.
 | 
			
		||||
 */
 | 
			
		||||
#if CLUTTER_CHECK_VERSION(1, 9, 0)
 | 
			
		||||
#define has_effects clutter_actor_has_effects
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
actor_is_untransformed (ClutterActor *actor,
 | 
			
		||||
                        int          *x_origin,
 | 
			
		||||
                        int          *y_origin)
 | 
			
		||||
has_effects(ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  gfloat widthf, heightf;
 | 
			
		||||
  ClutterVertex verts[4];
 | 
			
		||||
  GList *list;
 | 
			
		||||
  gboolean ret;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_size (actor, &widthf, &heightf);
 | 
			
		||||
  clutter_actor_get_abs_allocation_vertices (actor, verts);
 | 
			
		||||
  list = clutter_actor_get_effects (actor);
 | 
			
		||||
  ret = list != NULL;
 | 
			
		||||
  g_list_free (list);
 | 
			
		||||
 | 
			
		||||
  return vertices_are_untransformed (verts, widthf, heightf, x_origin, y_origin);
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Help macros to scale from OpenGL <-1,1> coordinates system to
 | 
			
		||||
 * window coordinates ranging [0,window-size]. Borrowed from clutter-utils.c
 | 
			
		||||
 */
 | 
			
		||||
#define MTX_GL_SCALE_X(x,w,v1,v2) ((((((x) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2))
 | 
			
		||||
#define MTX_GL_SCALE_Y(y,w,v1,v2) ((v1) - (((((y) / (w)) + 1.0f) / 2.0f) * (v1)) + (v2))
 | 
			
		||||
 | 
			
		||||
/* Check if we're painting the MetaWindowGroup "untransformed". This can
 | 
			
		||||
 * differ from the result of actor_is_untransformed(window_group) if we're
 | 
			
		||||
 * inside a clone paint. The integer translation, if any, is returned.
 | 
			
		||||
 */
 | 
			
		||||
static gboolean
 | 
			
		||||
painting_untransformed (MetaWindowGroup *window_group,
 | 
			
		||||
                        int             *x_origin,
 | 
			
		||||
                        int             *y_origin)
 | 
			
		||||
{
 | 
			
		||||
  CoglMatrix modelview, projection, modelview_projection;
 | 
			
		||||
  ClutterVertex vertices[4];
 | 
			
		||||
  int width, height;
 | 
			
		||||
  float viewport[4];
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  cogl_get_modelview_matrix (&modelview);
 | 
			
		||||
  cogl_get_projection_matrix (&projection);
 | 
			
		||||
 | 
			
		||||
  cogl_matrix_multiply (&modelview_projection,
 | 
			
		||||
                        &projection,
 | 
			
		||||
                        &modelview);
 | 
			
		||||
 | 
			
		||||
  meta_screen_get_size (window_group->screen, &width, &height);
 | 
			
		||||
 | 
			
		||||
  vertices[0].x = 0;
 | 
			
		||||
  vertices[0].y = 0;
 | 
			
		||||
  vertices[0].z = 0;
 | 
			
		||||
  vertices[1].x = width;
 | 
			
		||||
  vertices[1].y = 0;
 | 
			
		||||
  vertices[1].z = 0;
 | 
			
		||||
  vertices[2].x = 0;
 | 
			
		||||
  vertices[2].y = height;
 | 
			
		||||
  vertices[2].z = 0;
 | 
			
		||||
  vertices[3].x = width;
 | 
			
		||||
  vertices[3].y = height;
 | 
			
		||||
  vertices[3].z = 0;
 | 
			
		||||
 | 
			
		||||
  cogl_get_viewport (viewport);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < 4; i++)
 | 
			
		||||
    {
 | 
			
		||||
      float w = 1;
 | 
			
		||||
      cogl_matrix_transform_point (&modelview_projection, &vertices[i].x, &vertices[i].y, &vertices[i].z, &w);
 | 
			
		||||
      vertices[i].x = MTX_GL_SCALE_X (vertices[i].x, w,
 | 
			
		||||
                                      viewport[2], viewport[0]);
 | 
			
		||||
      vertices[i].y = MTX_GL_SCALE_Y (vertices[i].y, w,
 | 
			
		||||
                                      viewport[3], viewport[1]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return vertices_are_untransformed (vertices, width, height, x_origin, y_origin);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *visible_region;
 | 
			
		||||
  cairo_region_t *unredirected_window_region = NULL;
 | 
			
		||||
  ClutterActor *stage;
 | 
			
		||||
  cairo_rectangle_int_t visible_rect;
 | 
			
		||||
  cairo_rectangle_int_t visible_rect, unredirected_rect;
 | 
			
		||||
  GList *children, *l;
 | 
			
		||||
  int paint_x_origin, paint_y_origin;
 | 
			
		||||
  int actor_x_origin, actor_y_origin;
 | 
			
		||||
  int paint_x_offset, paint_y_offset;
 | 
			
		||||
 | 
			
		||||
  MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
 | 
			
		||||
  MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
 | 
			
		||||
 | 
			
		||||
  /* Normally we expect an actor to be drawn at it's position on the screen.
 | 
			
		||||
   * However, if we're inside the paint of a ClutterClone, that won't be the
 | 
			
		||||
   * case and we need to compensate. We look at the position of the window
 | 
			
		||||
   * group under the current model-view matrix and the position of the actor.
 | 
			
		||||
   * If they are both simply integer translations, then we can compensate
 | 
			
		||||
   * easily, otherwise we give up.
 | 
			
		||||
   *
 | 
			
		||||
   * Possible cleanup: work entirely in paint space - we can compute the
 | 
			
		||||
   * combination of the model-view matrix with the local matrix for each child
 | 
			
		||||
   * actor and get a total transformation for that actor for how we are
 | 
			
		||||
   * painting currently, and never worry about how actors are positioned
 | 
			
		||||
   * on the stage.
 | 
			
		||||
   */
 | 
			
		||||
  if (!painting_untransformed (window_group, &paint_x_origin, &paint_y_origin) ||
 | 
			
		||||
      !actor_is_untransformed (actor, &actor_x_origin, &actor_y_origin))
 | 
			
		||||
  if (info->unredirected_window != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
 | 
			
		||||
      return;
 | 
			
		||||
      meta_window_actor_get_shape_bounds (META_WINDOW_ACTOR (info->unredirected_window), &unredirected_rect);
 | 
			
		||||
      unredirected_window_region = cairo_region_create_rectangle (&unredirected_rect);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  paint_x_offset = paint_x_origin - actor_x_origin;
 | 
			
		||||
  paint_y_offset = paint_y_origin - actor_y_origin;
 | 
			
		||||
 | 
			
		||||
  /* We walk the list from top to bottom (opposite of painting order),
 | 
			
		||||
   * and subtract the opaque area of each window out of the visible
 | 
			
		||||
   * region that we pass to the windows below.
 | 
			
		||||
@@ -234,23 +156,14 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
  visible_region = cairo_region_create_rectangle (&visible_rect);
 | 
			
		||||
 | 
			
		||||
  if (info->unredirected_window != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t unredirected_rect;
 | 
			
		||||
      MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
 | 
			
		||||
 | 
			
		||||
      meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect);
 | 
			
		||||
      cairo_region_subtract_rectangle (visible_region, &unredirected_rect);
 | 
			
		||||
    }
 | 
			
		||||
  if (unredirected_window_region)
 | 
			
		||||
    cairo_region_subtract (visible_region, unredirected_window_region);
 | 
			
		||||
 | 
			
		||||
  for (l = children; l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      if (!CLUTTER_ACTOR_IS_VISIBLE (l->data))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (l->data == info->unredirected_window)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      /* If an actor has effects applied, then that can change the area
 | 
			
		||||
       * it paints and the opacity, so we no longer can figure out what
 | 
			
		||||
       * portion of the actor is obscured and what portion of the screen
 | 
			
		||||
@@ -267,20 +180,17 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
       * as well for the same reason, but omitted for simplicity in the
 | 
			
		||||
       * hopes that no-one will do that.
 | 
			
		||||
       */
 | 
			
		||||
      if (clutter_actor_has_effects (l->data))
 | 
			
		||||
      if (has_effects (l->data))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (META_IS_WINDOW_ACTOR (l->data))
 | 
			
		||||
        {
 | 
			
		||||
          MetaWindowActor *window_actor = l->data;
 | 
			
		||||
          int x, y;
 | 
			
		||||
          gboolean x, y;
 | 
			
		||||
 | 
			
		||||
          if (!actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y))
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
          x += paint_x_offset;
 | 
			
		||||
          y += paint_y_offset;
 | 
			
		||||
 | 
			
		||||
          /* Temporarily move to the coordinate system of the actor */
 | 
			
		||||
          cairo_region_translate (visible_region, - x, - y);
 | 
			
		||||
 | 
			
		||||
@@ -299,22 +209,15 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
      else if (META_IS_BACKGROUND_ACTOR (l->data))
 | 
			
		||||
        {
 | 
			
		||||
          MetaBackgroundActor *background_actor = l->data;
 | 
			
		||||
          int x, y;
 | 
			
		||||
 | 
			
		||||
          if (!actor_is_untransformed (CLUTTER_ACTOR (background_actor), &x, &y))
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
          x += paint_x_offset;
 | 
			
		||||
          y += paint_y_offset;
 | 
			
		||||
 | 
			
		||||
          cairo_region_translate (visible_region, - x, - y);
 | 
			
		||||
          meta_background_actor_set_visible_region (background_actor, visible_region);
 | 
			
		||||
          cairo_region_translate (visible_region, x, y);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  cairo_region_destroy (visible_region);
 | 
			
		||||
 | 
			
		||||
  if (unredirected_window_region)
 | 
			
		||||
    cairo_region_destroy (unredirected_window_region);
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
 | 
			
		||||
 | 
			
		||||
  /* Now that we are done painting, unset the visible regions (they will
 | 
			
		||||
@@ -325,6 +228,7 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
      if (META_IS_WINDOW_ACTOR (l->data))
 | 
			
		||||
        {
 | 
			
		||||
          MetaWindowActor *window_actor = l->data;
 | 
			
		||||
          window_actor = l->data;
 | 
			
		||||
          meta_window_actor_reset_visible_regions (window_actor);
 | 
			
		||||
        }
 | 
			
		||||
      else if (META_IS_BACKGROUND_ACTOR (l->data))
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,3 @@ pkglib_LTLIBRARIES = default.la
 | 
			
		||||
install-exec-hook:
 | 
			
		||||
	-rm $(DESTDIR)$(pkglibdir)/*.a
 | 
			
		||||
	-rm $(DESTDIR)$(pkglibdir)/*.la
 | 
			
		||||
 | 
			
		||||
# Since we removed the .la file, 'make uninstall' doesn't work properly,
 | 
			
		||||
# since it counts on libtool to remove the .la files, so just kill the
 | 
			
		||||
# .so file manually.
 | 
			
		||||
uninstall-local:
 | 
			
		||||
	-rm -f $(DESTDIR)$(pkglibdir)/default.so
 | 
			
		||||
 
 | 
			
		||||
@@ -112,6 +112,8 @@ struct _MetaDefaultPluginPrivate
 | 
			
		||||
  ClutterActor          *desktop2;
 | 
			
		||||
 | 
			
		||||
  MetaPluginInfo         info;
 | 
			
		||||
 | 
			
		||||
  gboolean               debug_mode : 1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -180,6 +182,34 @@ meta_default_plugin_get_property (GObject    *object,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
start (MetaPlugin *plugin)
 | 
			
		||||
{
 | 
			
		||||
  MetaDefaultPluginPrivate *priv   = META_DEFAULT_PLUGIN (plugin)->priv;
 | 
			
		||||
 | 
			
		||||
  guint destroy_timeout  = DESTROY_TIMEOUT;
 | 
			
		||||
  guint minimize_timeout = MINIMIZE_TIMEOUT;
 | 
			
		||||
  guint maximize_timeout = MAXIMIZE_TIMEOUT;
 | 
			
		||||
  guint map_timeout      = MAP_TIMEOUT;
 | 
			
		||||
  guint switch_timeout   = SWITCH_TIMEOUT;
 | 
			
		||||
 | 
			
		||||
  if (meta_plugin_debug_mode (plugin))
 | 
			
		||||
    {
 | 
			
		||||
      g_debug ("Plugin %s: Entering debug mode.", priv->info.name);
 | 
			
		||||
 | 
			
		||||
      priv->debug_mode = TRUE;
 | 
			
		||||
 | 
			
		||||
      /*
 | 
			
		||||
       * Double the effect duration to make them easier to observe.
 | 
			
		||||
       */
 | 
			
		||||
      destroy_timeout  *= 2;
 | 
			
		||||
      minimize_timeout *= 2;
 | 
			
		||||
      maximize_timeout *= 2;
 | 
			
		||||
      map_timeout      *= 2;
 | 
			
		||||
      switch_timeout   *= 2;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_default_plugin_class_init (MetaDefaultPluginClass *klass)
 | 
			
		||||
{
 | 
			
		||||
@@ -191,6 +221,7 @@ meta_default_plugin_class_init (MetaDefaultPluginClass *klass)
 | 
			
		||||
  gobject_class->set_property    = meta_default_plugin_set_property;
 | 
			
		||||
  gobject_class->get_property    = meta_default_plugin_get_property;
 | 
			
		||||
 | 
			
		||||
  plugin_class->start            = start;
 | 
			
		||||
  plugin_class->map              = map;
 | 
			
		||||
  plugin_class->minimize         = minimize;
 | 
			
		||||
  plugin_class->maximize         = maximize;
 | 
			
		||||
@@ -253,8 +284,7 @@ on_switch_workspace_effect_complete (ClutterTimeline *timeline, gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin               *plugin  = META_PLUGIN (data);
 | 
			
		||||
  MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
 | 
			
		||||
  MetaScreen *screen = meta_plugin_get_screen (plugin);
 | 
			
		||||
  GList *l = meta_get_window_actors (screen);
 | 
			
		||||
  GList        *l     = meta_plugin_get_window_actors (plugin);
 | 
			
		||||
 | 
			
		||||
  while (l)
 | 
			
		||||
    {
 | 
			
		||||
@@ -287,7 +317,6 @@ switch_workspace (MetaPlugin *plugin,
 | 
			
		||||
                  gint from, gint to,
 | 
			
		||||
                  MetaMotionDirection direction)
 | 
			
		||||
{
 | 
			
		||||
  MetaScreen *screen;
 | 
			
		||||
  MetaDefaultPluginPrivate *priv = META_DEFAULT_PLUGIN (plugin)->priv;
 | 
			
		||||
  GList        *l;
 | 
			
		||||
  ClutterActor *workspace0  = clutter_group_new ();
 | 
			
		||||
@@ -296,13 +325,11 @@ switch_workspace (MetaPlugin *plugin,
 | 
			
		||||
  int           screen_width, screen_height;
 | 
			
		||||
  ClutterAnimation *animation;
 | 
			
		||||
 | 
			
		||||
  screen = meta_plugin_get_screen (plugin);
 | 
			
		||||
  stage = meta_get_stage_for_screen (screen);
 | 
			
		||||
 | 
			
		||||
  meta_screen_get_size (screen,
 | 
			
		||||
                        &screen_width,
 | 
			
		||||
                        &screen_height);
 | 
			
		||||
  stage = meta_plugin_get_stage (plugin);
 | 
			
		||||
 | 
			
		||||
  meta_plugin_query_screen_size (plugin,
 | 
			
		||||
					      &screen_width,
 | 
			
		||||
					      &screen_height);
 | 
			
		||||
  clutter_actor_set_anchor_point (workspace1,
 | 
			
		||||
                                  screen_width,
 | 
			
		||||
                                  screen_height);
 | 
			
		||||
@@ -321,7 +348,7 @@ switch_workspace (MetaPlugin *plugin,
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  l = g_list_last (meta_get_window_actors (screen));
 | 
			
		||||
  l = g_list_last (meta_plugin_get_window_actors (plugin));
 | 
			
		||||
 | 
			
		||||
  while (l)
 | 
			
		||||
    {
 | 
			
		||||
@@ -419,19 +446,12 @@ static void
 | 
			
		||||
minimize (MetaPlugin *plugin, MetaWindowActor *window_actor)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowType type;
 | 
			
		||||
  MetaRectangle icon_geometry;
 | 
			
		||||
  MetaWindow *meta_window = meta_window_actor_get_meta_window (window_actor);
 | 
			
		||||
  ClutterActor *actor  = CLUTTER_ACTOR (window_actor);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  type = meta_window_get_window_type (meta_window);
 | 
			
		||||
 | 
			
		||||
  if (!meta_window_get_icon_geometry(meta_window, &icon_geometry))
 | 
			
		||||
    {
 | 
			
		||||
      icon_geometry.x = 0;
 | 
			
		||||
      icon_geometry.y = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (type == META_WINDOW_NORMAL)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterAnimation *animation;
 | 
			
		||||
@@ -448,8 +468,6 @@ minimize (MetaPlugin *plugin, MetaWindowActor *window_actor)
 | 
			
		||||
                                         MINIMIZE_TIMEOUT,
 | 
			
		||||
                                         "scale-x", 0.0,
 | 
			
		||||
                                         "scale-y", 0.0,
 | 
			
		||||
                                         "x", (double)icon_geometry.x,
 | 
			
		||||
                                         "y", (double)icon_geometry.y,
 | 
			
		||||
                                         NULL);
 | 
			
		||||
      apriv->tml_minimize = clutter_animation_get_timeline (animation);
 | 
			
		||||
      data->plugin = plugin;
 | 
			
		||||
 
 | 
			
		||||
@@ -43,17 +43,34 @@
 | 
			
		||||
/* Optimium performance seems to be with MAX_CHUNK_RECTANGLES=4; 8 is about 10% slower.
 | 
			
		||||
 * But using 8 may be more robust to systems with slow malloc(). */
 | 
			
		||||
#define MAX_CHUNK_RECTANGLES 8
 | 
			
		||||
#define MAX_LEVELS 16
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  /* To merge regions in binary tree order, we need to keep track of
 | 
			
		||||
   * the regions that we've already merged together at different
 | 
			
		||||
   * levels of the tree. We fill in an array in the pattern:
 | 
			
		||||
   *
 | 
			
		||||
   * |a  |
 | 
			
		||||
   * |b  |a  |
 | 
			
		||||
   * |c  |   |ab |
 | 
			
		||||
   * |d  |c  |ab |
 | 
			
		||||
   * |e  |   |   |abcd|
 | 
			
		||||
   */
 | 
			
		||||
  cairo_region_t *levels[MAX_LEVELS];
 | 
			
		||||
  int n_levels;
 | 
			
		||||
} MetaRegionBuilder;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_region_builder_init (MetaRegionBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  for (i = 0; i < META_REGION_BUILDER_MAX_LEVELS; i++)
 | 
			
		||||
  for (i = 0; i < MAX_LEVELS; i++)
 | 
			
		||||
    builder->levels[i] = NULL;
 | 
			
		||||
  builder->n_levels = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
static void
 | 
			
		||||
meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
 | 
			
		||||
                                   int                x,
 | 
			
		||||
                                   int                y,
 | 
			
		||||
@@ -78,7 +95,7 @@ meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
 | 
			
		||||
        {
 | 
			
		||||
          if (builder->levels[i] == NULL)
 | 
			
		||||
            {
 | 
			
		||||
              if (i < META_REGION_BUILDER_MAX_LEVELS)
 | 
			
		||||
              if (i < MAX_LEVELS)
 | 
			
		||||
                {
 | 
			
		||||
                  builder->levels[i] = builder->levels[i - 1];
 | 
			
		||||
                  builder->levels[i - 1] = NULL;
 | 
			
		||||
@@ -98,7 +115,7 @@ meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cairo_region_t *
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
meta_region_builder_finish (MetaRegionBuilder *builder)
 | 
			
		||||
{
 | 
			
		||||
  cairo_region_t *result = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -63,32 +63,6 @@ struct _MetaRegionIterator {
 | 
			
		||||
  cairo_rectangle_int_t next_rectangle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaRegionBuilder MetaRegionBuilder;
 | 
			
		||||
 | 
			
		||||
#define META_REGION_BUILDER_MAX_LEVELS 16
 | 
			
		||||
struct _MetaRegionBuilder {
 | 
			
		||||
  /* To merge regions in binary tree order, we need to keep track of
 | 
			
		||||
   * the regions that we've already merged together at different
 | 
			
		||||
   * levels of the tree. We fill in an array in the pattern:
 | 
			
		||||
   *
 | 
			
		||||
   * |a  |
 | 
			
		||||
   * |b  |a  |
 | 
			
		||||
   * |c  |   |ab |
 | 
			
		||||
   * |d  |c  |ab |
 | 
			
		||||
   * |e  |   |   |abcd|
 | 
			
		||||
   */
 | 
			
		||||
  cairo_region_t *levels[META_REGION_BUILDER_MAX_LEVELS];
 | 
			
		||||
  int n_levels;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void     meta_region_builder_init       (MetaRegionBuilder *builder);
 | 
			
		||||
void     meta_region_builder_add_rectangle (MetaRegionBuilder *builder,
 | 
			
		||||
                                            int                x,
 | 
			
		||||
                                            int                y,
 | 
			
		||||
                                            int                width,
 | 
			
		||||
                                            int                height);
 | 
			
		||||
cairo_region_t * meta_region_builder_finish (MetaRegionBuilder *builder);
 | 
			
		||||
 | 
			
		||||
void     meta_region_iterator_init      (MetaRegionIterator *iter,
 | 
			
		||||
                                         cairo_region_t     *region);
 | 
			
		||||
gboolean meta_region_iterator_at_end    (MetaRegionIterator *iter);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										400
									
								
								src/core/all-keybindings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										400
									
								
								src/core/all-keybindings.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,400 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2008 Thomas Thurman
 | 
			
		||||
 * 
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A list of screen keybinding information.
 | 
			
		||||
 *
 | 
			
		||||
 * Each action which can have a keystroke bound to it is listed below.
 | 
			
		||||
 * To use this file, define keybind() to be a seven-argument macro (you can
 | 
			
		||||
 * throw any of the arguments you please away), include this file,
 | 
			
		||||
 * and then undefine the macro again.
 | 
			
		||||
 *
 | 
			
		||||
 * (If you aren't familiar with this technique, sometimes called "x-macros",
 | 
			
		||||
 * see DDJ of May 2001: <http://www.ddj.com/cpp/184401387>.)
 | 
			
		||||
 *
 | 
			
		||||
 * This makes it possible to keep all information about all the keybindings
 | 
			
		||||
 * in the same place.  The only exception is the code to run when an action
 | 
			
		||||
 * is actually invoked; while we *could* have put that in this file, it would
 | 
			
		||||
 * have made debugging ridiculously difficult.  Instead, each action should
 | 
			
		||||
 * have a corresponding static function named handle_<name>() in
 | 
			
		||||
 * keybindings.c.
 | 
			
		||||
 *
 | 
			
		||||
 * The arguments to keybind() are:
 | 
			
		||||
 *   1) the name of the binding; a bareword identifier
 | 
			
		||||
 *              (it's fine if it happens to clash with a C reserved word)
 | 
			
		||||
 *   2) the name of the function which implements it.
 | 
			
		||||
 *              Clearly we could have guessed this from the binding very often,
 | 
			
		||||
 *              but we choose to write it in full for the benefit of grep.
 | 
			
		||||
 *   3) an integer parameter to pass to the handler
 | 
			
		||||
 *   4) a set of boolean flags, ORed together:
 | 
			
		||||
 *       BINDING_PER_WINDOW  - this is a window-based binding.
 | 
			
		||||
 *                             It is only valid if there is a
 | 
			
		||||
 *                             current window, and will operate in
 | 
			
		||||
 *                             some way on that window.
 | 
			
		||||
 *       BINDING_REVERSES    - the binding can reverse if you hold down Shift
 | 
			
		||||
 *       BINDING_IS_REVERSED - the same, but the senses are reversed from the
 | 
			
		||||
 *                             handler's point of view (let me know if I should
 | 
			
		||||
 *                             explain this better)
 | 
			
		||||
 *      or 0 if no flag applies.
 | 
			
		||||
 *
 | 
			
		||||
 *   5) a string representing the default binding.
 | 
			
		||||
 *          If this is NULL, the action is unbound by default.
 | 
			
		||||
 *          Please use NULL and not "disabled".
 | 
			
		||||
 *   6) a short description.
 | 
			
		||||
 *          It must be marked translatable (i.e. inside "_(...)").
 | 
			
		||||
 *
 | 
			
		||||
 * Don't try to do XML entity escaping anywhere in the strings.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef keybind
 | 
			
		||||
#error "keybind () must be defined when you include screen-bindings.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/***********************************/
 | 
			
		||||
 | 
			
		||||
#ifndef _BINDINGS_DEFINED_CONSTANTS
 | 
			
		||||
#define _BINDINGS_DEFINED_CONSTANTS 1
 | 
			
		||||
 | 
			
		||||
#define BINDING_PER_WINDOW    0x01
 | 
			
		||||
#define BINDING_REVERSES      0x02
 | 
			
		||||
#define BINDING_IS_REVERSED   0x04
 | 
			
		||||
 | 
			
		||||
#endif /* _BINDINGS_DEFINED_CONSTANTS */
 | 
			
		||||
 | 
			
		||||
/***********************************/
 | 
			
		||||
 | 
			
		||||
/* convenience, since in this file they must always be set together */
 | 
			
		||||
#define REVERSES_AND_REVERSED (BINDING_REVERSES | BINDING_IS_REVERSED)
 | 
			
		||||
 | 
			
		||||
keybind (switch_to_workspace_1,  handle_switch_to_workspace, 0, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 1"))
 | 
			
		||||
keybind (switch_to_workspace_2,  handle_switch_to_workspace, 1, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 2"))
 | 
			
		||||
keybind (switch_to_workspace_3,  handle_switch_to_workspace, 2, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 3"))
 | 
			
		||||
keybind (switch_to_workspace_4,  handle_switch_to_workspace, 3, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 4"))
 | 
			
		||||
keybind (switch_to_workspace_5,  handle_switch_to_workspace, 4, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 5"))
 | 
			
		||||
keybind (switch_to_workspace_6,  handle_switch_to_workspace, 5, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 6"))
 | 
			
		||||
keybind (switch_to_workspace_7,  handle_switch_to_workspace, 6, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 7"))
 | 
			
		||||
keybind (switch_to_workspace_8,  handle_switch_to_workspace, 7, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 8"))
 | 
			
		||||
keybind (switch_to_workspace_9,  handle_switch_to_workspace, 8, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 9"))
 | 
			
		||||
keybind (switch_to_workspace_10, handle_switch_to_workspace, 9, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 10"))
 | 
			
		||||
keybind (switch_to_workspace_11, handle_switch_to_workspace, 10, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 11"))
 | 
			
		||||
keybind (switch_to_workspace_12, handle_switch_to_workspace, 11, 0, NULL,
 | 
			
		||||
        _("Switch to workspace 12"))
 | 
			
		||||
 | 
			
		||||
/* META_MOTION_* are negative, and so distinct from workspace numbers,
 | 
			
		||||
 * which are always zero or positive.
 | 
			
		||||
 * If you make use of these constants, you will need to include workspace.h
 | 
			
		||||
 * (which you're probably using already for other reasons anyway).
 | 
			
		||||
 * If your definition of keybind() throws them away, you don't need to include
 | 
			
		||||
 * workspace.h, of course.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
keybind (switch_to_workspace_left, handle_switch_to_workspace,
 | 
			
		||||
         META_MOTION_LEFT, 0, "<Control><Alt>Left",
 | 
			
		||||
        _("Switch to workspace on the left of the current workspace"))
 | 
			
		||||
 | 
			
		||||
keybind (switch_to_workspace_right, handle_switch_to_workspace,
 | 
			
		||||
         META_MOTION_RIGHT, 0, "<Control><Alt>Right",
 | 
			
		||||
        _("Switch to workspace on the right of the current workspace"))
 | 
			
		||||
 | 
			
		||||
keybind (switch_to_workspace_up, handle_switch_to_workspace,
 | 
			
		||||
         META_MOTION_UP, 0, "<Control><Alt>Up",
 | 
			
		||||
        _("Switch to workspace above the current workspace"))
 | 
			
		||||
 | 
			
		||||
keybind (switch_to_workspace_down, handle_switch_to_workspace,
 | 
			
		||||
         META_MOTION_DOWN, 0, "<Control><Alt>Down",
 | 
			
		||||
        _("Switch to workspace below the current workspace"))
 | 
			
		||||
 | 
			
		||||
/***********************************/
 | 
			
		||||
 | 
			
		||||
/* The ones which have inverses.  These can't be bound to any keystroke
 | 
			
		||||
 * containing Shift because Shift will invert their "backward" state.
 | 
			
		||||
 *
 | 
			
		||||
 * TODO: "NORMAL" and "DOCKS" should be renamed to the same name as their
 | 
			
		||||
 * action, for obviousness.
 | 
			
		||||
 *
 | 
			
		||||
 * TODO: handle_switch and handle_cycle should probably really be the
 | 
			
		||||
 * same function checking a bit in the parameter for difference.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
keybind (switch_group,              handle_switch,        META_TAB_LIST_GROUP,
 | 
			
		||||
         BINDING_REVERSES,       "<Alt>Above_Tab",
 | 
			
		||||
        _("Move between windows of an application, using a popup window"))
 | 
			
		||||
keybind (switch_group_backward,    handle_switch,        META_TAB_LIST_GROUP,
 | 
			
		||||
         REVERSES_AND_REVERSED,  NULL,
 | 
			
		||||
        _("Move backward between windows of an application, "
 | 
			
		||||
          "using a popup window"))
 | 
			
		||||
keybind (switch_windows,            handle_switch,        META_TAB_LIST_NORMAL,
 | 
			
		||||
         BINDING_REVERSES,       "<Alt>Tab",
 | 
			
		||||
        _("Move between windows, using a popup window"))
 | 
			
		||||
keybind (switch_windows_backward,  handle_switch,        META_TAB_LIST_NORMAL,
 | 
			
		||||
         REVERSES_AND_REVERSED,  NULL,
 | 
			
		||||
        _("Move backward between windows, using a popup window"))
 | 
			
		||||
keybind (switch_panels,             handle_switch,        META_TAB_LIST_DOCKS,
 | 
			
		||||
         BINDING_REVERSES,       "<Control><Alt>Tab",
 | 
			
		||||
        _("Move between panels and the desktop, using a popup window"))
 | 
			
		||||
keybind (switch_panels_backward,   handle_switch,        META_TAB_LIST_DOCKS,
 | 
			
		||||
         REVERSES_AND_REVERSED,  NULL,
 | 
			
		||||
         _("Move backward between panels and the desktop, "
 | 
			
		||||
          "using a popup window"))
 | 
			
		||||
 | 
			
		||||
keybind (cycle_group,               handle_cycle,         META_TAB_LIST_GROUP,
 | 
			
		||||
        BINDING_REVERSES,        "<Alt>F6",
 | 
			
		||||
        _("Move between windows of an application immediately"))
 | 
			
		||||
keybind (cycle_group_backward,     handle_cycle,         META_TAB_LIST_GROUP,
 | 
			
		||||
        REVERSES_AND_REVERSED,   NULL,
 | 
			
		||||
        _("Move backward between windows of an application immediately"))
 | 
			
		||||
keybind (cycle_windows,             handle_cycle,         META_TAB_LIST_NORMAL,
 | 
			
		||||
        BINDING_REVERSES,        "<Alt>Escape",
 | 
			
		||||
        _("Move between windows immediately"))
 | 
			
		||||
keybind (cycle_windows_backward,   handle_cycle,         META_TAB_LIST_NORMAL,
 | 
			
		||||
        REVERSES_AND_REVERSED,   NULL,
 | 
			
		||||
        _("Move backward between windows immediately"))
 | 
			
		||||
keybind (cycle_panels,              handle_cycle,         META_TAB_LIST_DOCKS,
 | 
			
		||||
        BINDING_REVERSES,        "<Control><Alt>Escape",
 | 
			
		||||
        _("Move between panels and the desktop immediately"))
 | 
			
		||||
keybind (cycle_panels_backward,    handle_cycle,         META_TAB_LIST_DOCKS,
 | 
			
		||||
        REVERSES_AND_REVERSED,   NULL,
 | 
			
		||||
        _("Move backward between panels and the desktop immediately"))
 | 
			
		||||
 | 
			
		||||
/***********************************/
 | 
			
		||||
 | 
			
		||||
/* These two are special pseudo-bindings that are provided for allowing
 | 
			
		||||
 * custom handlers, but will never be bound to a key. While a tab
 | 
			
		||||
 * grab is in effect, they are invoked for releasing the primary modifier
 | 
			
		||||
 * or pressing some unbound key, respectively.
 | 
			
		||||
 */
 | 
			
		||||
keybind (tab_popup_select,        handle_tab_popup_select, 0, 0, NULL,
 | 
			
		||||
         "Select window from tab popup")
 | 
			
		||||
keybind (tab_popup_cancel,        handle_tab_popup_cancel, 0, 0, NULL,
 | 
			
		||||
         "Cancel tab popup")
 | 
			
		||||
 | 
			
		||||
/***********************************/
 | 
			
		||||
     
 | 
			
		||||
keybind (show_desktop, handle_show_desktop, 0, 0, "<Control><Alt>d",
 | 
			
		||||
      _("Hide all normal windows and set focus to the desktop"))
 | 
			
		||||
keybind (panel_main_menu, handle_panel,
 | 
			
		||||
       META_KEYBINDING_ACTION_PANEL_MAIN_MENU, 0, "<Alt>F1",
 | 
			
		||||
      _("Show the panel's main menu"))
 | 
			
		||||
keybind (panel_run_dialog, handle_panel,
 | 
			
		||||
       META_KEYBINDING_ACTION_PANEL_RUN_DIALOG, 0, "<Alt>F2",
 | 
			
		||||
      _("Show the panel's \"Run Application\" dialog box"))
 | 
			
		||||
keybind (toggle_recording, handle_toggle_recording, 0, 0, "<Control><Shift><Alt>r",
 | 
			
		||||
         _("Start or stop recording the session"))
 | 
			
		||||
 | 
			
		||||
/* Yes, the param is offset by one.  Historical reasons.  (Maybe worth fixing
 | 
			
		||||
 * at some point.)  The description is NULL here because the stanza is
 | 
			
		||||
 * irregularly shaped in mutter.schemas.in.  This will probably be fixed
 | 
			
		||||
 * as well.
 | 
			
		||||
 */
 | 
			
		||||
keybind (run_command_1,  handle_run_command,  0, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_2,  handle_run_command,  1, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_3,  handle_run_command,  2, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_4,  handle_run_command,  3, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_5,  handle_run_command,  4, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_6,  handle_run_command,  5, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_7,  handle_run_command,  6, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_8,  handle_run_command,  7, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_9,  handle_run_command,  8, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_10, handle_run_command,  9, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_11, handle_run_command, 10, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_12, handle_run_command, 11, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_13, handle_run_command, 12, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_14, handle_run_command, 13, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_15, handle_run_command, 14, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_16, handle_run_command, 15, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_17, handle_run_command, 16, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_18, handle_run_command, 17, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_19, handle_run_command, 18, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_20, handle_run_command, 19, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_21, handle_run_command, 20, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_22, handle_run_command, 21, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_23, handle_run_command, 22, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_24, handle_run_command, 23, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_25, handle_run_command, 24, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_26, handle_run_command, 25, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_27, handle_run_command, 26, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_28, handle_run_command, 27, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_29, handle_run_command, 28, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_30, handle_run_command, 29, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_31, handle_run_command, 30, 0, NULL, NULL)
 | 
			
		||||
keybind (run_command_32, handle_run_command, 31, 0, NULL, NULL)
 | 
			
		||||
 | 
			
		||||
keybind (run_command_screenshot, handle_run_command, 32, 0, "Print",
 | 
			
		||||
      _("Take a screenshot"))
 | 
			
		||||
keybind (run_command_window_screenshot, handle_run_command, 33, 0,"<Alt>Print",
 | 
			
		||||
      _("Take a screenshot of a window"))
 | 
			
		||||
 | 
			
		||||
keybind (run_command_terminal, handle_run_terminal, 0, 0, NULL, _("Run a terminal"))
 | 
			
		||||
 | 
			
		||||
/* No description because this is undocumented */
 | 
			
		||||
keybind (set_spew_mark, handle_set_spew_mark, 0, 0, NULL, NULL)
 | 
			
		||||
 | 
			
		||||
#undef REVERSES_AND_REVERSED
 | 
			
		||||
 | 
			
		||||
/************************ PER WINDOW BINDINGS ************************/
 | 
			
		||||
 | 
			
		||||
/* These take a window as an extra parameter; they have no effect
 | 
			
		||||
 * if no window is active.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
keybind (activate_window_menu, handle_activate_window_menu, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, "<Alt>space",
 | 
			
		||||
        _("Activate the window menu"))
 | 
			
		||||
keybind (toggle_fullscreen, handle_toggle_fullscreen, 0, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Toggle fullscreen mode"))
 | 
			
		||||
keybind (toggle_maximized, handle_toggle_maximized, 0, BINDING_PER_WINDOW, "<Alt>F10",
 | 
			
		||||
        _("Toggle maximization state"))
 | 
			
		||||
keybind (toggle_above, handle_toggle_above, 0, BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Toggle whether a window will always be visible over other windows"))
 | 
			
		||||
keybind (maximize, handle_maximize, 0, BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Maximize window"))
 | 
			
		||||
keybind (unmaximize, handle_unmaximize, 0, BINDING_PER_WINDOW, "<Alt>F5",
 | 
			
		||||
        _("Restore window"))
 | 
			
		||||
keybind (toggle_shaded, handle_toggle_shaded, 0, BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Toggle shaded state"))
 | 
			
		||||
keybind (minimize, handle_minimize, 0, BINDING_PER_WINDOW, "<Alt>F9",
 | 
			
		||||
        _("Minimize window"))
 | 
			
		||||
keybind (close, handle_close, 0, BINDING_PER_WINDOW, "<Alt>F4",
 | 
			
		||||
        _("Close window"))
 | 
			
		||||
keybind (begin_move, handle_begin_move, 0, BINDING_PER_WINDOW, "<Alt>F7",
 | 
			
		||||
        _("Move window"))
 | 
			
		||||
keybind (begin_resize, handle_begin_resize, 0, BINDING_PER_WINDOW, "<Alt>F8",
 | 
			
		||||
        _("Resize window"))
 | 
			
		||||
keybind (toggle_on_all_workspaces, handle_toggle_on_all_workspaces, 0,
 | 
			
		||||
         BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Toggle whether window is on all workspaces or just one"))
 | 
			
		||||
 | 
			
		||||
keybind (move_to_workspace_1, handle_move_to_workspace, 0, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 1"))
 | 
			
		||||
keybind (move_to_workspace_2, handle_move_to_workspace, 1, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 2"))
 | 
			
		||||
keybind (move_to_workspace_3, handle_move_to_workspace, 2, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 3"))
 | 
			
		||||
keybind (move_to_workspace_4, handle_move_to_workspace, 3, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 4"))
 | 
			
		||||
keybind (move_to_workspace_5, handle_move_to_workspace, 4, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 5"))
 | 
			
		||||
keybind (move_to_workspace_6, handle_move_to_workspace, 5, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 6"))
 | 
			
		||||
keybind (move_to_workspace_7, handle_move_to_workspace, 6, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 7"))
 | 
			
		||||
keybind (move_to_workspace_8, handle_move_to_workspace, 7, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 8"))
 | 
			
		||||
keybind (move_to_workspace_9, handle_move_to_workspace, 8, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 9"))
 | 
			
		||||
keybind (move_to_workspace_10, handle_move_to_workspace, 9, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 10"))
 | 
			
		||||
keybind (move_to_workspace_11, handle_move_to_workspace, 10, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 11"))
 | 
			
		||||
keybind (move_to_workspace_12, handle_move_to_workspace, 11, BINDING_PER_WINDOW,
 | 
			
		||||
        NULL,
 | 
			
		||||
        _("Move window to workspace 12"))
 | 
			
		||||
 | 
			
		||||
/* META_MOTION_* are negative, and so distinct from workspace numbers,
 | 
			
		||||
 * which are always zero or positive.
 | 
			
		||||
 * If you make use of these constants, you will need to include workspace.h
 | 
			
		||||
 * (which you're probably using already for other reasons anyway).
 | 
			
		||||
 * If your definition of keybind() throws them away, you don't need to include
 | 
			
		||||
 * workspace.h, of course.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
keybind (move_to_workspace_left, handle_move_to_workspace,
 | 
			
		||||
         META_MOTION_LEFT, BINDING_PER_WINDOW, "<Control><Shift><Alt>Left",
 | 
			
		||||
        _("Move window one workspace to the left"))
 | 
			
		||||
keybind (move_to_workspace_right, handle_move_to_workspace,
 | 
			
		||||
         META_MOTION_RIGHT, BINDING_PER_WINDOW, "<Control><Shift><Alt>Right",
 | 
			
		||||
        _("Move window one workspace to the right"))
 | 
			
		||||
keybind (move_to_workspace_up, handle_move_to_workspace,
 | 
			
		||||
         META_MOTION_UP, BINDING_PER_WINDOW, "<Control><Shift><Alt>Up",
 | 
			
		||||
        _("Move window one workspace up"))
 | 
			
		||||
keybind (move_to_workspace_down, handle_move_to_workspace,
 | 
			
		||||
         META_MOTION_DOWN, BINDING_PER_WINDOW, "<Control><Shift><Alt>Down",
 | 
			
		||||
        _("Move window one workspace down"))
 | 
			
		||||
 | 
			
		||||
keybind (raise_or_lower, handle_raise_or_lower, 0, BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Raise window if it's covered by another window, otherwise lower it"))
 | 
			
		||||
keybind (raise, handle_raise, 0, BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Raise window above other windows"))
 | 
			
		||||
keybind (lower, handle_lower, 0, BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Lower window below other windows"))
 | 
			
		||||
 | 
			
		||||
keybind (maximize_vertically, handle_maximize_vertically, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Maximize window vertically"))
 | 
			
		||||
 | 
			
		||||
keybind (maximize_horizontally, handle_maximize_horizontally, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Maximize window horizontally"))
 | 
			
		||||
 | 
			
		||||
keybind (move_to_corner_nw, handle_move_to_corner_nw, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Move window to north-west (top left) corner"))
 | 
			
		||||
keybind (move_to_corner_ne, handle_move_to_corner_ne, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Move window to north-east (top right) corner"))
 | 
			
		||||
keybind (move_to_corner_sw, handle_move_to_corner_sw, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Move window to south-west (bottom left) corner"))
 | 
			
		||||
keybind (move_to_corner_se, handle_move_to_corner_se, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Move window to south-east (bottom right) corner"))
 | 
			
		||||
 | 
			
		||||
keybind (move_to_side_n, handle_move_to_side_n, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Move window to north (top) side of screen"))
 | 
			
		||||
keybind (move_to_side_s, handle_move_to_side_s, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Move window to south (bottom) side of screen"))
 | 
			
		||||
keybind (move_to_side_e, handle_move_to_side_e, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Move window to east (right) side of screen"))
 | 
			
		||||
keybind (move_to_side_w, handle_move_to_side_w, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Move window to west (left) side of screen"))
 | 
			
		||||
keybind (move_to_center, handle_move_to_center, 0,
 | 
			
		||||
        BINDING_PER_WINDOW, NULL,
 | 
			
		||||
        _("Move window to center of screen"))
 | 
			
		||||
 | 
			
		||||
/* eof all-keybindings.h */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										120
									
								
								src/core/bell.c
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								src/core/bell.c
									
									
									
									
									
								
							@@ -23,8 +23,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:Bell
 | 
			
		||||
 * @short_description: Ring the bell or flash the screen
 | 
			
		||||
 * \file bell.c Ring the bell or flash the screen
 | 
			
		||||
 *
 | 
			
		||||
 * Sometimes, X programs "ring the bell", whatever that means. Mutter lets
 | 
			
		||||
 * the user configure the bell to be audible or visible (aka visual), and
 | 
			
		||||
@@ -58,10 +57,6 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * bell_flash_screen:
 | 
			
		||||
 * @display:  The display which owns the screen (rather redundant)
 | 
			
		||||
 * @screen:   The screen to flash
 | 
			
		||||
 *
 | 
			
		||||
 * Flashes one entire screen.  This is done by making a window the size of the
 | 
			
		||||
 * whole screen (or reusing the old one, if it's still around), mapping it,
 | 
			
		||||
 * painting it white and then black, and then unmapping it. We set saveunder so
 | 
			
		||||
@@ -70,12 +65,14 @@
 | 
			
		||||
 * Unlike frame flashes, we don't do fullscreen flashes with a timeout; rather,
 | 
			
		||||
 * we do them in one go, because we don't have to rely on the theme code
 | 
			
		||||
 * redrawing the frame for us in order to do the flash.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 * Bug: The way I read it, this appears not to do the flash
 | 
			
		||||
 *
 | 
			
		||||
 * \param display  The display which owns the screen (rather redundant)
 | 
			
		||||
 * \param screen   The screen to flash
 | 
			
		||||
 *
 | 
			
		||||
 * \bug The way I read it, this appears not to do the flash
 | 
			
		||||
 * the first time we flash a particular display. Am I wrong?
 | 
			
		||||
 *
 | 
			
		||||
 * Bug: This appears to destroy our current XSync status.
 | 
			
		||||
 * \bug This appears to destroy our current XSync status.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
bell_flash_screen (MetaDisplay *display, 
 | 
			
		||||
@@ -133,22 +130,21 @@ bell_flash_screen (MetaDisplay *display,
 | 
			
		||||
      XFreeGC (display->xdisplay, gc);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK &&
 | 
			
		||||
  if (meta_prefs_get_focus_mode () != META_FOCUS_MODE_CLICK &&
 | 
			
		||||
      !display->mouse_mode)
 | 
			
		||||
    meta_display_increment_focus_sentinel (display);
 | 
			
		||||
  XFlush (display->xdisplay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * bell_flash_fullscreen:
 | 
			
		||||
 * @display: The display the event came in on
 | 
			
		||||
 * @xkb_ev: The bell event
 | 
			
		||||
 *
 | 
			
		||||
 * Flashes one screen, or all screens, in response to a bell event.
 | 
			
		||||
 * If the event is on a particular window, flash the screen that
 | 
			
		||||
 * window is on. Otherwise, flash every screen on this display.
 | 
			
		||||
 *
 | 
			
		||||
 * If the configure script found we had no XKB, this does not exist.
 | 
			
		||||
 *
 | 
			
		||||
 * \param display  The display the event came in on
 | 
			
		||||
 * \param xkb_ev   The bell event
 | 
			
		||||
 */
 | 
			
		||||
#ifdef HAVE_XKB
 | 
			
		||||
static void
 | 
			
		||||
@@ -186,21 +182,17 @@ bell_flash_fullscreen (MetaDisplay *display,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * bell_unflash_frame:
 | 
			
		||||
 * @data: The frame to unflash, cast to a gpointer so it can go into
 | 
			
		||||
 *        a callback function.
 | 
			
		||||
 *
 | 
			
		||||
 * Makes a frame be not flashed; this is the timeout half of
 | 
			
		||||
 * bell_flash_window_frame(). This is done simply by clearing the
 | 
			
		||||
 * flash flag and queuing a redraw of the frame.
 | 
			
		||||
 *
 | 
			
		||||
 * If the configure script found we had no XKB, this does not exist.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: Always FALSE, so we don't get called again.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Bug: This is the parallel to bell_flash_window_frame(), so it should
 | 
			
		||||
 * \param data  The frame to unflash, cast to a gpointer so it can go into
 | 
			
		||||
 *              a callback function.
 | 
			
		||||
 * \return Always FALSE, so we don't get called again.
 | 
			
		||||
 *
 | 
			
		||||
 * \bug This is the parallel to bell_flash_window_frame(), so it should
 | 
			
		||||
 * really be called meta_bell_unflash_window_frame().
 | 
			
		||||
 */
 | 
			
		||||
static gboolean 
 | 
			
		||||
@@ -213,9 +205,6 @@ bell_unflash_frame (gpointer data)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * bell_flash_window_frame:
 | 
			
		||||
 * @window: The window to flash
 | 
			
		||||
 *
 | 
			
		||||
 * Makes a frame flash and then return to normal shortly afterwards.
 | 
			
		||||
 * This is done by setting a flag so that the theme
 | 
			
		||||
 * code will temporarily draw the frame as focussed if it's unfocussed and
 | 
			
		||||
@@ -223,6 +212,8 @@ bell_unflash_frame (gpointer data)
 | 
			
		||||
 * that the flag can be unset and the frame re-redrawn.
 | 
			
		||||
 *
 | 
			
		||||
 * If the configure script found we had no XKB, this does not exist.
 | 
			
		||||
 *
 | 
			
		||||
 * \param window  The window to flash
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
bell_flash_window_frame (MetaWindow *window)
 | 
			
		||||
@@ -239,27 +230,51 @@ bell_flash_window_frame (MetaWindow *window)
 | 
			
		||||
      bell_unflash_frame, window->frame, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaWindow *
 | 
			
		||||
get_flash_window (MetaDisplay *display,
 | 
			
		||||
                  XkbAnyEvent *xkb_ev)
 | 
			
		||||
{
 | 
			
		||||
  XkbBellNotifyEvent *xkb_bell_event;
 | 
			
		||||
  MetaWindow *window;
 | 
			
		||||
 | 
			
		||||
  g_assert (xkb_ev->xkb_type == XkbBellNotify);
 | 
			
		||||
 | 
			
		||||
  xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
 | 
			
		||||
  window = meta_display_lookup_x_window (display, xkb_bell_event->window);
 | 
			
		||||
 | 
			
		||||
  if (!window &&
 | 
			
		||||
      g_hash_table_size (display->focus_info) == 1)
 | 
			
		||||
    {
 | 
			
		||||
      GHashTableIter iter;
 | 
			
		||||
      MetaFocusInfo *info;
 | 
			
		||||
 | 
			
		||||
      /* If there is only one focused window, use it */
 | 
			
		||||
      g_hash_table_iter_init (&iter, display->focus_info);
 | 
			
		||||
 | 
			
		||||
      if (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info) &&
 | 
			
		||||
          info->focus_window && info->focus_window->frame)
 | 
			
		||||
        window = info->focus_window;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * bell_flash_frame:
 | 
			
		||||
 * @display:  The display the bell event came in on
 | 
			
		||||
 * @xkb_ev:   The bell event we just received
 | 
			
		||||
 *
 | 
			
		||||
 * Flashes the frame of the focussed window. If there is no focussed window,
 | 
			
		||||
 * flashes the screen.
 | 
			
		||||
 *
 | 
			
		||||
 * \param display  The display the bell event came in on
 | 
			
		||||
 * \param xkb_ev   The bell event we just received
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
bell_flash_frame (MetaDisplay *display, 
 | 
			
		||||
		  XkbAnyEvent *xkb_ev)
 | 
			
		||||
{
 | 
			
		||||
  XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
 | 
			
		||||
  MetaWindow *window;
 | 
			
		||||
  
 | 
			
		||||
  g_assert (xkb_ev->xkb_type == XkbBellNotify);
 | 
			
		||||
  window = meta_display_lookup_x_window (display, xkb_bell_event->window);
 | 
			
		||||
  if (!window && (display->focus_window))
 | 
			
		||||
    {
 | 
			
		||||
      window = display->focus_window;
 | 
			
		||||
    }
 | 
			
		||||
  window = get_flash_window (display, xkb_ev);
 | 
			
		||||
 | 
			
		||||
  if (window && window->frame)
 | 
			
		||||
    {
 | 
			
		||||
      bell_flash_window_frame (window);
 | 
			
		||||
@@ -271,18 +286,15 @@ bell_flash_frame (MetaDisplay *display,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * bell_visual_notify:
 | 
			
		||||
 * @display: The display the bell event came in on
 | 
			
		||||
 * @xkb_ev: The bell event we just received
 | 
			
		||||
 *
 | 
			
		||||
 * Gives the user some kind of visual bell substitute, in response to a
 | 
			
		||||
 * bell event. What this is depends on the "visual bell type" pref.
 | 
			
		||||
 *
 | 
			
		||||
 * If the configure script found we had no XKB, this does not exist.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Bug: This should be merged with meta_bell_notify().
 | 
			
		||||
 *
 | 
			
		||||
 * \param display  The display the bell event came in on
 | 
			
		||||
 * \param xkb_ev   The bell event we just received
 | 
			
		||||
 *
 | 
			
		||||
 * \bug This should be merged with meta_bell_notify().
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
bell_visual_notify (MetaDisplay *display, 
 | 
			
		||||
@@ -290,12 +302,15 @@ bell_visual_notify (MetaDisplay *display,
 | 
			
		||||
{
 | 
			
		||||
  switch (meta_prefs_get_visual_bell_type ()) 
 | 
			
		||||
    {
 | 
			
		||||
    case G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH:
 | 
			
		||||
    case META_VISUAL_BELL_FULLSCREEN_FLASH:
 | 
			
		||||
      bell_flash_fullscreen (display, xkb_ev);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DESKTOP_VISUAL_BELL_FRAME_FLASH:
 | 
			
		||||
    case META_VISUAL_BELL_FRAME_FLASH:
 | 
			
		||||
      bell_flash_frame (display, xkb_ev); /* does nothing yet */
 | 
			
		||||
      break;
 | 
			
		||||
    case META_VISUAL_BELL_INVALID:
 | 
			
		||||
      /* do nothing */
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -304,7 +319,7 @@ meta_bell_notify (MetaDisplay *display,
 | 
			
		||||
		  XkbAnyEvent *xkb_ev)
 | 
			
		||||
{
 | 
			
		||||
  /* flash something */
 | 
			
		||||
  if (meta_prefs_get_visual_bell ())
 | 
			
		||||
  if (meta_prefs_get_visual_bell ()) 
 | 
			
		||||
    bell_visual_notify (display, xkb_ev);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LIBCANBERRA
 | 
			
		||||
@@ -320,9 +335,7 @@ meta_bell_notify (MetaDisplay *display,
 | 
			
		||||
      ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event"));
 | 
			
		||||
      ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent");
 | 
			
		||||
 | 
			
		||||
      window = meta_display_lookup_x_window (display, xkb_bell_event->window);
 | 
			
		||||
      if (!window && (display->focus_window) && (display->focus_window->frame))
 | 
			
		||||
        window = display->focus_window;
 | 
			
		||||
      window = get_flash_window (display, xkb_ev);
 | 
			
		||||
 | 
			
		||||
      if (window)
 | 
			
		||||
        {
 | 
			
		||||
@@ -420,13 +433,12 @@ meta_bell_shutdown (MetaDisplay *display)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_bell_notify_frame_destroy:
 | 
			
		||||
 * @frame: The frame which is being destroyed
 | 
			
		||||
 *
 | 
			
		||||
 * Deals with a frame being destroyed. This is important because if we're
 | 
			
		||||
 * using a visual bell, we might be flashing the edges of the frame, and
 | 
			
		||||
 * so we'd have a timeout function waiting ready to un-flash them. If the
 | 
			
		||||
 * frame's going away, we can tell the timeout not to bother.
 | 
			
		||||
 *
 | 
			
		||||
 * \param frame  The frame which is being destroyed
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_bell_notify_frame_destroy (MetaFrame *frame)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,17 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \file bell.h Ring the bell or flash the screen
 | 
			
		||||
 *
 | 
			
		||||
 * Sometimes, X programs "ring the bell", whatever that means. Mutter lets
 | 
			
		||||
 * the user configure the bell to be audible or visible (aka visual), and
 | 
			
		||||
 * if it's visual it can be configured to be frame-flash or fullscreen-flash.
 | 
			
		||||
 * We never get told about audible bells; X handles them just fine by itself.
 | 
			
		||||
 *
 | 
			
		||||
 * The visual bell was the result of a discussion in Bugzilla here:
 | 
			
		||||
 * <http://bugzilla.gnome.org/show_bug.cgi?id=99886>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2002 Sun Microsystems Inc.
 | 
			
		||||
 * 
 | 
			
		||||
 
 | 
			
		||||
@@ -625,6 +625,7 @@ meta_rectangle_get_minimal_spanning_set_for_region (
 | 
			
		||||
  *temp_rect = *basic_rect;
 | 
			
		||||
  ret = g_list_prepend (NULL, temp_rect);
 | 
			
		||||
 | 
			
		||||
  strut_iter = all_struts;
 | 
			
		||||
  for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
 | 
			
		||||
    {
 | 
			
		||||
      GList *rect_iter; 
 | 
			
		||||
 
 | 
			
		||||
@@ -119,7 +119,6 @@ typedef struct
 | 
			
		||||
  MetaRectangle        orig;
 | 
			
		||||
  MetaRectangle        current;
 | 
			
		||||
  MetaFrameBorders    *borders;
 | 
			
		||||
  gboolean             must_free_borders;
 | 
			
		||||
  ActionType           action_type;
 | 
			
		||||
  gboolean             is_user_action;
 | 
			
		||||
 | 
			
		||||
@@ -338,7 +337,7 @@ meta_window_constrain (MetaWindow          *window,
 | 
			
		||||
   * not gobject-style--gobject would be more pain than it's worth) or
 | 
			
		||||
   * smart pointers would be so much nicer here.  *shrug*
 | 
			
		||||
   */
 | 
			
		||||
  if (info.must_free_borders)
 | 
			
		||||
  if (!orig_borders)
 | 
			
		||||
    g_free (info.borders);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -359,15 +358,9 @@ setup_constraint_info (ConstraintInfo      *info,
 | 
			
		||||
 | 
			
		||||
  /* Create a fake frame geometry if none really exists */
 | 
			
		||||
  if (orig_borders && !window->fullscreen)
 | 
			
		||||
    {
 | 
			
		||||
      info->borders = orig_borders;
 | 
			
		||||
      info->must_free_borders = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
    info->borders = orig_borders;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      info->borders = g_new0 (MetaFrameBorders, 1);
 | 
			
		||||
      info->must_free_borders = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
    info->borders = g_new0 (MetaFrameBorders, 1);
 | 
			
		||||
 | 
			
		||||
  if (flags & META_IS_MOVE_ACTION && flags & META_IS_RESIZE_ACTION)
 | 
			
		||||
    info->action_type = ACTION_MOVE_AND_RESIZE;
 | 
			
		||||
@@ -446,13 +439,9 @@ setup_constraint_info (ConstraintInfo      *info,
 | 
			
		||||
                                         monitor_info->number);
 | 
			
		||||
 | 
			
		||||
  /* Workaround braindead legacy apps that don't know how to
 | 
			
		||||
   * fullscreen themselves properly - don't get fooled by
 | 
			
		||||
   * windows which hide their titlebar when maximized; that's
 | 
			
		||||
   * not the same as fullscreen, even if there are no struts
 | 
			
		||||
   * making the workarea smaller than the monitor.
 | 
			
		||||
   * fullscreen themselves properly.
 | 
			
		||||
   */
 | 
			
		||||
  if (meta_prefs_get_force_fullscreen() &&
 | 
			
		||||
      !window->hide_titlebar_when_maximized &&
 | 
			
		||||
      meta_rectangle_equal (new, &monitor_info->rect) &&
 | 
			
		||||
      window->has_fullscreen_func &&
 | 
			
		||||
      !window->fullscreen)
 | 
			
		||||
@@ -580,7 +569,7 @@ place_window_if_needed(MetaWindow     *window,
 | 
			
		||||
                 META_MAXIMIZE_VERTICAL : 0), &info->current);
 | 
			
		||||
 | 
			
		||||
          /* maximization may have changed frame geometry */
 | 
			
		||||
          if (!window->fullscreen)
 | 
			
		||||
          if (window->frame && !window->fullscreen)
 | 
			
		||||
            meta_frame_calc_borders (window->frame, info->borders);
 | 
			
		||||
 | 
			
		||||
          if (window->fullscreen_after_placement)
 | 
			
		||||
@@ -764,12 +753,21 @@ constrain_modal_dialog (MetaWindow         *window,
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  x = parent->rect.x + (parent->rect.width / 2  - info->current.width / 2);
 | 
			
		||||
  y = parent->rect.y + (parent->rect.height / 2 - info->current.height / 2);
 | 
			
		||||
  y = 0;
 | 
			
		||||
  if (parent->frame)
 | 
			
		||||
    {
 | 
			
		||||
      MetaFrameBorders borders;
 | 
			
		||||
 | 
			
		||||
      x += parent->frame->rect.x;
 | 
			
		||||
      y += parent->frame->rect.y;
 | 
			
		||||
 | 
			
		||||
      meta_frame_calc_borders (parent->frame, &borders);
 | 
			
		||||
      y += borders.total.top;
 | 
			
		||||
 | 
			
		||||
      y += info->borders->visible.top;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    y = parent->rect.y + info->borders->visible.top;
 | 
			
		||||
 | 
			
		||||
  constraint_already_satisfied = (x == info->current.x) && (y == info->current.y);
 | 
			
		||||
 | 
			
		||||
@@ -1365,15 +1363,18 @@ constrain_titlebar_visible (MetaWindow         *window,
 | 
			
		||||
  int bottom_amount;
 | 
			
		||||
  int horiz_amount_offscreen, vert_amount_offscreen;
 | 
			
		||||
  int horiz_amount_onscreen,  vert_amount_onscreen;
 | 
			
		||||
  MetaGrabInfo *grab_info;
 | 
			
		||||
 | 
			
		||||
  if (priority > PRIORITY_TITLEBAR_VISIBLE)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  grab_info = window->cur_grab;
 | 
			
		||||
 | 
			
		||||
  /* Allow the titlebar beyond the top of the screen only if the user wasn't
 | 
			
		||||
   * clicking on the frame to start the move.
 | 
			
		||||
   */
 | 
			
		||||
  unconstrained_user_action =
 | 
			
		||||
    info->is_user_action && !window->display->grab_frame_action;
 | 
			
		||||
    info->is_user_action && (!grab_info || !grab_info->grab_frame_action);
 | 
			
		||||
 | 
			
		||||
  /* Exit early if we know the constraint won't apply--note that this constraint
 | 
			
		||||
   * is only meant for normal windows (e.g. we don't want docks to be shoved 
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										244
									
								
								src/core/core.c
									
									
									
									
									
								
							
							
						
						
									
										244
									
								
								src/core/core.c
									
									
									
									
									
								
							@@ -27,9 +27,15 @@
 | 
			
		||||
#include "core.h"
 | 
			
		||||
#include "frame.h"
 | 
			
		||||
#include "workspace-private.h"
 | 
			
		||||
#include "input-events.h"
 | 
			
		||||
#include <meta/prefs.h>
 | 
			
		||||
#include <meta/errors.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XINPUT2
 | 
			
		||||
#include <X11/extensions/XInput2.h>
 | 
			
		||||
#include "devices-xi2.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Looks up the MetaWindow representing the frame of the given X window.
 | 
			
		||||
 * Used as a helper function by a bunch of the functions below.
 | 
			
		||||
 *
 | 
			
		||||
@@ -212,7 +218,7 @@ lower_window_and_transients (MetaWindow *window,
 | 
			
		||||
 | 
			
		||||
  meta_window_foreach_transient (window, lower_window_and_transients, NULL);
 | 
			
		||||
 | 
			
		||||
  if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK &&
 | 
			
		||||
  if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
 | 
			
		||||
      meta_prefs_get_raise_on_click ())
 | 
			
		||||
    {
 | 
			
		||||
      /* Move window to the back of the focusing workspace's MRU list.
 | 
			
		||||
@@ -245,9 +251,19 @@ lower_window_and_transients (MetaWindow *window,
 | 
			
		||||
void
 | 
			
		||||
meta_core_user_lower_and_unfocus (Display *xdisplay,
 | 
			
		||||
                                  Window   frame_xwindow,
 | 
			
		||||
                                  int      device_id,
 | 
			
		||||
                                  guint32  timestamp)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindow *window = get_window (xdisplay, frame_xwindow);
 | 
			
		||||
  MetaDevice *pointer;
 | 
			
		||||
 | 
			
		||||
  pointer = meta_device_map_lookup (window->display->device_map, device_id);
 | 
			
		||||
 | 
			
		||||
  if (pointer == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (!META_IS_DEVICE_POINTER (pointer))
 | 
			
		||||
    pointer = meta_device_get_paired_device (pointer);
 | 
			
		||||
 | 
			
		||||
  lower_window_and_transients (window, NULL);
 | 
			
		||||
 | 
			
		||||
@@ -256,6 +272,7 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
 | 
			
		||||
  * this will be invoked via keyboard action or by a mouse action;
 | 
			
		||||
  * in either case the window or a modal child will have been focused.) */
 | 
			
		||||
  meta_workspace_focus_default_window (window->screen->active_workspace,
 | 
			
		||||
                                       pointer,
 | 
			
		||||
                                       NULL,
 | 
			
		||||
                                       timestamp);
 | 
			
		||||
}
 | 
			
		||||
@@ -263,16 +280,21 @@ meta_core_user_lower_and_unfocus (Display *xdisplay,
 | 
			
		||||
void
 | 
			
		||||
meta_core_lower_beneath_grab_window (Display *xdisplay,
 | 
			
		||||
                                     Window   xwindow,
 | 
			
		||||
                                     int      device_id,
 | 
			
		||||
                                     guint32  timestamp)
 | 
			
		||||
{
 | 
			
		||||
  XWindowChanges changes;
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  MetaScreen *screen;
 | 
			
		||||
  MetaWindow *grab_window;
 | 
			
		||||
  MetaDevice *pointer;
 | 
			
		||||
  MetaGrabInfo *grab_info;
 | 
			
		||||
 | 
			
		||||
  display = meta_display_for_x_display (xdisplay);
 | 
			
		||||
  screen = meta_display_screen_for_xwindow (display, xwindow);
 | 
			
		||||
  grab_window = display->grab_window;
 | 
			
		||||
  pointer = meta_device_map_lookup (display->device_map, device_id);
 | 
			
		||||
  grab_info = meta_display_get_grab_info (display, pointer);
 | 
			
		||||
  grab_window = grab_info->grab_window;
 | 
			
		||||
 | 
			
		||||
  if (grab_window == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
@@ -491,18 +513,27 @@ meta_core_get_active_workspace (Screen *xscreen)
 | 
			
		||||
void
 | 
			
		||||
meta_core_show_window_menu (Display *xdisplay,
 | 
			
		||||
                            Window   frame_xwindow,
 | 
			
		||||
                            int      device_id,
 | 
			
		||||
                            int      root_x,
 | 
			
		||||
                            int      root_y,
 | 
			
		||||
                            int      button,
 | 
			
		||||
                            guint32  timestamp)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindow *window = get_window (xdisplay, frame_xwindow);
 | 
			
		||||
  
 | 
			
		||||
  MetaDevice *device;
 | 
			
		||||
 | 
			
		||||
  /* There is already a menu popped up,
 | 
			
		||||
   * most likely from another device
 | 
			
		||||
   */
 | 
			
		||||
  if (window->menu)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (meta_prefs_get_raise_on_click ())
 | 
			
		||||
    meta_window_raise (window);
 | 
			
		||||
  meta_window_focus (window, timestamp);
 | 
			
		||||
 | 
			
		||||
  meta_window_show_menu (window, root_x, root_y, button, timestamp);
 | 
			
		||||
  device = meta_device_map_lookup (window->display->device_map, device_id);
 | 
			
		||||
  meta_window_show_menu (window, device, root_x, root_y, button, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -538,70 +569,70 @@ meta_core_get_menu_accelerator (MetaMenuOp           menu_op,
 | 
			
		||||
      break;
 | 
			
		||||
    case META_MENU_OP_UNSTICK:
 | 
			
		||||
    case META_MENU_OP_STICK:
 | 
			
		||||
      name = "toggle-on-all-workspaces";
 | 
			
		||||
      name = "toggle_on_all_workspaces";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_MENU_OP_ABOVE:
 | 
			
		||||
    case META_MENU_OP_UNABOVE:
 | 
			
		||||
      name = "toggle-above";
 | 
			
		||||
      name = "toggle_above";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_MENU_OP_WORKSPACES:
 | 
			
		||||
      switch (workspace)
 | 
			
		||||
        {
 | 
			
		||||
        case 1:
 | 
			
		||||
          name = "move-to-workspace-1";
 | 
			
		||||
          name = "move_to_workspace_1";
 | 
			
		||||
          break;
 | 
			
		||||
        case 2:
 | 
			
		||||
          name = "move-to-workspace-2";
 | 
			
		||||
          name = "move_to_workspace_2";
 | 
			
		||||
          break;
 | 
			
		||||
        case 3:
 | 
			
		||||
          name = "move-to-workspace-3";
 | 
			
		||||
          name = "move_to_workspace_3";
 | 
			
		||||
          break; 
 | 
			
		||||
        case 4:
 | 
			
		||||
          name = "move-to-workspace-4";
 | 
			
		||||
          name = "move_to_workspace_4";
 | 
			
		||||
          break; 
 | 
			
		||||
        case 5:
 | 
			
		||||
          name = "move-to-workspace-5";
 | 
			
		||||
          name = "move_to_workspace_5";
 | 
			
		||||
          break; 
 | 
			
		||||
        case 6:
 | 
			
		||||
          name = "move-to-workspace-6";
 | 
			
		||||
          name = "move_to_workspace_6";
 | 
			
		||||
          break; 
 | 
			
		||||
        case 7:
 | 
			
		||||
          name = "move-to-workspace-7";
 | 
			
		||||
          name = "move_to_workspace_7";
 | 
			
		||||
          break; 
 | 
			
		||||
        case 8:
 | 
			
		||||
          name = "move-to-workspace-8";
 | 
			
		||||
          name = "move_to_workspace_8";
 | 
			
		||||
          break; 
 | 
			
		||||
        case 9:
 | 
			
		||||
          name = "move-to-workspace-9";
 | 
			
		||||
          name = "move_to_workspace_9";
 | 
			
		||||
          break; 
 | 
			
		||||
        case 10:
 | 
			
		||||
          name = "move-to-workspace-10";
 | 
			
		||||
          name = "move_to_workspace_10";
 | 
			
		||||
          break;
 | 
			
		||||
        case 11:
 | 
			
		||||
          name = "move-to-workspace-11";
 | 
			
		||||
          name = "move_to_workspace_11";
 | 
			
		||||
          break;
 | 
			
		||||
        case 12:
 | 
			
		||||
          name = "move-to-workspace-12";
 | 
			
		||||
          name = "move_to_workspace_12";
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    case META_MENU_OP_MOVE:
 | 
			
		||||
      name = "begin-move";
 | 
			
		||||
      name = "begin_move";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_MENU_OP_RESIZE:
 | 
			
		||||
      name = "begin-resize";
 | 
			
		||||
      name = "begin_resize";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_MENU_OP_MOVE_LEFT:
 | 
			
		||||
      name = "move-to-workspace-left";
 | 
			
		||||
      name = "move_to_workspace_left";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_MENU_OP_MOVE_RIGHT:
 | 
			
		||||
      name = "move-to-workspace-right";
 | 
			
		||||
      name = "move_to_workspace_right";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_MENU_OP_MOVE_UP:
 | 
			
		||||
      name = "move-to-workspace-up";
 | 
			
		||||
      name = "move_to_workspace_up";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_MENU_OP_MOVE_DOWN:
 | 
			
		||||
      name = "move-to-workspace-down";
 | 
			
		||||
      name = "move_to_workspace_down";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_MENU_OP_RECOVER:
 | 
			
		||||
      /* No keybinding for this one */
 | 
			
		||||
@@ -638,6 +669,7 @@ meta_core_get_workspace_name_with_index (Display *xdisplay,
 | 
			
		||||
gboolean
 | 
			
		||||
meta_core_begin_grab_op (Display    *xdisplay,
 | 
			
		||||
                         Window      frame_xwindow,
 | 
			
		||||
                         int         device_id,
 | 
			
		||||
                         MetaGrabOp  op,
 | 
			
		||||
                         gboolean    pointer_already_grabbed,
 | 
			
		||||
                         gboolean    frame_action,
 | 
			
		||||
@@ -650,13 +682,16 @@ meta_core_begin_grab_op (Display    *xdisplay,
 | 
			
		||||
  MetaWindow *window = get_window (xdisplay, frame_xwindow);
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  MetaScreen *screen;
 | 
			
		||||
  
 | 
			
		||||
  MetaDevice *device;
 | 
			
		||||
 | 
			
		||||
  display = meta_display_for_x_display (xdisplay);
 | 
			
		||||
  screen = meta_display_screen_for_xwindow (display, frame_xwindow);
 | 
			
		||||
 | 
			
		||||
  g_assert (screen != NULL);
 | 
			
		||||
  
 | 
			
		||||
  return meta_display_begin_grab_op (display, screen, window,
 | 
			
		||||
 | 
			
		||||
  device = meta_device_map_lookup (display->device_map, device_id);
 | 
			
		||||
 | 
			
		||||
  return meta_display_begin_grab_op (display, screen, window, device,
 | 
			
		||||
                                     op, pointer_already_grabbed,
 | 
			
		||||
                                     frame_action,
 | 
			
		||||
                                     button, modmask,
 | 
			
		||||
@@ -665,57 +700,58 @@ meta_core_begin_grab_op (Display    *xdisplay,
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_core_end_grab_op (Display *xdisplay,
 | 
			
		||||
                       int      device_id,
 | 
			
		||||
                       guint32  timestamp)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  
 | 
			
		||||
  display = meta_display_for_x_display (xdisplay);
 | 
			
		||||
  MetaDevice *device;
 | 
			
		||||
 | 
			
		||||
  meta_display_end_grab_op (display, timestamp);
 | 
			
		||||
  display = meta_display_for_x_display (xdisplay);
 | 
			
		||||
  device = meta_device_map_lookup (display->device_map, device_id);
 | 
			
		||||
 | 
			
		||||
  meta_display_end_grab_op (display, device, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaGrabOp
 | 
			
		||||
meta_core_get_grab_op (Display *xdisplay)
 | 
			
		||||
meta_core_frame_has_grab (Display    *xdisplay,
 | 
			
		||||
                          Window      frame_xwindow,
 | 
			
		||||
                          gint       *device_id,
 | 
			
		||||
                          gint       *button_ret)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  
 | 
			
		||||
  display = meta_display_for_x_display (xdisplay);
 | 
			
		||||
  MetaWindow *window;
 | 
			
		||||
 | 
			
		||||
  return display->grab_op;
 | 
			
		||||
  window = get_window (xdisplay, frame_xwindow);
 | 
			
		||||
 | 
			
		||||
  if (window != NULL &&
 | 
			
		||||
      window->cur_grab != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (button_ret)
 | 
			
		||||
        *button_ret = window->cur_grab->grab_button;
 | 
			
		||||
 | 
			
		||||
      if (device_id)
 | 
			
		||||
        *device_id = meta_device_get_id (window->cur_grab->grab_pointer);
 | 
			
		||||
 | 
			
		||||
      return window->cur_grab->grab_op;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return META_GRAB_OP_NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Window
 | 
			
		||||
meta_core_get_grab_frame (Display *xdisplay)
 | 
			
		||||
meta_core_get_frame (Display *xdisplay,
 | 
			
		||||
                     Window   client_xwindow)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  
 | 
			
		||||
  MetaWindow *window;
 | 
			
		||||
 | 
			
		||||
  display = meta_display_for_x_display (xdisplay);
 | 
			
		||||
  window = meta_display_lookup_x_window (display, client_xwindow);
 | 
			
		||||
 | 
			
		||||
  g_assert (display != NULL);
 | 
			
		||||
  g_assert (display->grab_op == META_GRAB_OP_NONE || 
 | 
			
		||||
            display->grab_screen != NULL);
 | 
			
		||||
  g_assert (display->grab_op == META_GRAB_OP_NONE ||
 | 
			
		||||
            display->grab_screen->display->xdisplay == xdisplay);
 | 
			
		||||
  
 | 
			
		||||
  if (display->grab_op != META_GRAB_OP_NONE &&
 | 
			
		||||
      display->grab_window &&
 | 
			
		||||
      display->grab_window->frame)
 | 
			
		||||
    return display->grab_window->frame->xwindow;
 | 
			
		||||
  else
 | 
			
		||||
    return None;
 | 
			
		||||
}
 | 
			
		||||
  if (window &&
 | 
			
		||||
      window->frame)
 | 
			
		||||
    return window->frame->xwindow;
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
meta_core_get_grab_button (Display  *xdisplay)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  
 | 
			
		||||
  display = meta_display_for_x_display (xdisplay);
 | 
			
		||||
 | 
			
		||||
  if (display->grab_op == META_GRAB_OP_NONE)
 | 
			
		||||
    return -1;
 | 
			
		||||
  
 | 
			
		||||
  return display->grab_button;
 | 
			
		||||
  return None;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -731,13 +767,24 @@ meta_core_grab_buttons  (Display *xdisplay,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_core_set_screen_cursor (Display *xdisplay,
 | 
			
		||||
                             Window   frame_on_screen,
 | 
			
		||||
                             MetaCursor cursor)
 | 
			
		||||
meta_core_set_screen_cursor (Display    *xdisplay,
 | 
			
		||||
                             Window      frame_on_screen,
 | 
			
		||||
                             gint        device_id,
 | 
			
		||||
                             MetaCursor  cursor)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindow *window = get_window (xdisplay, frame_on_screen);
 | 
			
		||||
  MetaDevice *pointer;
 | 
			
		||||
 | 
			
		||||
  meta_frame_set_screen_cursor (window->frame, cursor);
 | 
			
		||||
  pointer = meta_device_map_lookup (window->display->device_map,
 | 
			
		||||
                                    device_id);
 | 
			
		||||
 | 
			
		||||
  if (pointer == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (!META_IS_DEVICE_POINTER (pointer))
 | 
			
		||||
    pointer = meta_device_get_paired_device (pointer);
 | 
			
		||||
 | 
			
		||||
  meta_frame_set_screen_cursor (window->frame, pointer, cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -775,3 +822,70 @@ meta_invalidate_default_icons (void)
 | 
			
		||||
  g_slist_free (windows);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Selects events on an xwindow, using XInput2 if available/in use,
 | 
			
		||||
 * this function doesn't require the xwindow to have a backing
 | 
			
		||||
 * MetaWindow.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_core_select_events (Display  *xdisplay,
 | 
			
		||||
                         Window    xwindow,
 | 
			
		||||
                         gint      evmask,
 | 
			
		||||
                         gboolean  preserve_old_mask)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = meta_display_for_x_display (xdisplay);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XINPUT2
 | 
			
		||||
  if (display->have_xinput2)
 | 
			
		||||
    {
 | 
			
		||||
      XIEventMask mask;
 | 
			
		||||
 | 
			
		||||
      mask.deviceid = XIAllMasterDevices;
 | 
			
		||||
      mask.mask = meta_device_xi2_translate_event_mask (evmask,
 | 
			
		||||
                                                        &mask.mask_len);
 | 
			
		||||
 | 
			
		||||
      if (preserve_old_mask)
 | 
			
		||||
        {
 | 
			
		||||
          XIEventMask *prev;
 | 
			
		||||
          gint n_masks, i, j;
 | 
			
		||||
 | 
			
		||||
          prev = XIGetSelectedEvents (xdisplay, xwindow, &n_masks);
 | 
			
		||||
 | 
			
		||||
          for (i = 0; i < n_masks; i++)
 | 
			
		||||
            {
 | 
			
		||||
              if (prev[i].deviceid != XIAllMasterDevices)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
              for (j = 0; j < MIN (mask.mask_len, prev[i].mask_len); j++)
 | 
			
		||||
                mask.mask[j] |= prev[i].mask[j];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          XFree (prev);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      XISelectEvents (xdisplay, xwindow, &mask, 1);
 | 
			
		||||
 | 
			
		||||
      /* Unset any input event so they are only handled via XInput2 */
 | 
			
		||||
      evmask &= ~(META_INPUT_TOUCH_EVENTS_MASK |
 | 
			
		||||
                  KeyPressMask | KeyReleaseMask |
 | 
			
		||||
                  ButtonPressMask | ButtonReleaseMask |
 | 
			
		||||
                  EnterWindowMask | LeaveWindowMask |
 | 
			
		||||
                  PointerMotionMask | PointerMotionHintMask |
 | 
			
		||||
                  Button1MotionMask | Button2MotionMask |
 | 
			
		||||
                  Button3MotionMask | Button4MotionMask |
 | 
			
		||||
                  Button5MotionMask | ButtonMotionMask |
 | 
			
		||||
                  FocusChangeMask);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (preserve_old_mask)
 | 
			
		||||
    {
 | 
			
		||||
      XWindowAttributes attr;
 | 
			
		||||
 | 
			
		||||
      if (XGetWindowAttributes (xdisplay, xwindow, &attr))
 | 
			
		||||
        evmask |= attr.your_event_mask;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  XSelectInput (xdisplay, xwindow, evmask);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -110,6 +110,7 @@ void meta_core_user_raise   (Display *xdisplay,
 | 
			
		||||
                             Window   frame_xwindow);
 | 
			
		||||
void meta_core_user_lower_and_unfocus (Display *xdisplay,
 | 
			
		||||
                                       Window   frame_xwindow,
 | 
			
		||||
                                       int      device_id,
 | 
			
		||||
                                       guint32  timestamp);
 | 
			
		||||
 | 
			
		||||
void meta_core_user_focus   (Display *xdisplay,
 | 
			
		||||
@@ -118,6 +119,7 @@ void meta_core_user_focus   (Display *xdisplay,
 | 
			
		||||
 | 
			
		||||
void meta_core_lower_beneath_grab_window (Display *xdisplay,
 | 
			
		||||
                                          Window   xwindow,
 | 
			
		||||
                                          int      device_id,
 | 
			
		||||
                                          guint32  timestamp);
 | 
			
		||||
 | 
			
		||||
void meta_core_minimize         (Display *xdisplay,
 | 
			
		||||
@@ -163,6 +165,7 @@ const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
 | 
			
		||||
 | 
			
		||||
void meta_core_show_window_menu (Display *xdisplay,
 | 
			
		||||
                                 Window   frame_xwindow,
 | 
			
		||||
                                 int      device_id,
 | 
			
		||||
                                 int      root_x,
 | 
			
		||||
                                 int      root_y,
 | 
			
		||||
                                 int      button,
 | 
			
		||||
@@ -175,6 +178,7 @@ void meta_core_get_menu_accelerator (MetaMenuOp           menu_op,
 | 
			
		||||
 | 
			
		||||
gboolean   meta_core_begin_grab_op (Display    *xdisplay,
 | 
			
		||||
                                    Window      frame_xwindow,
 | 
			
		||||
                                    int         device_id,
 | 
			
		||||
                                    MetaGrabOp  op,
 | 
			
		||||
                                    gboolean    pointer_already_grabbed,
 | 
			
		||||
                                    gboolean    frame_action,
 | 
			
		||||
@@ -184,18 +188,29 @@ gboolean   meta_core_begin_grab_op (Display    *xdisplay,
 | 
			
		||||
                                    int         root_x,
 | 
			
		||||
                                    int         root_y);
 | 
			
		||||
void       meta_core_end_grab_op   (Display    *xdisplay,
 | 
			
		||||
                                    int         device_id,
 | 
			
		||||
                                    guint32     timestamp);
 | 
			
		||||
MetaGrabOp meta_core_get_grab_op     (Display    *xdisplay);
 | 
			
		||||
Window     meta_core_get_grab_frame  (Display   *xdisplay);
 | 
			
		||||
int        meta_core_get_grab_button (Display  *xdisplay);
 | 
			
		||||
 | 
			
		||||
MetaGrabOp meta_core_frame_has_grab  (Display    *xdisplay,
 | 
			
		||||
                                      Window      frame_xwindow,
 | 
			
		||||
                                      gint       *device_id,
 | 
			
		||||
                                      gint       *button_ret);
 | 
			
		||||
Window     meta_core_get_frame       (Display    *xdisplay,
 | 
			
		||||
                                      Window      client_xwindow);
 | 
			
		||||
 | 
			
		||||
void       meta_core_grab_buttons  (Display *xdisplay,
 | 
			
		||||
                                    Window   frame_xwindow);
 | 
			
		||||
 | 
			
		||||
void       meta_core_set_screen_cursor (Display *xdisplay,
 | 
			
		||||
                                        Window   frame_on_screen,
 | 
			
		||||
                                        MetaCursor cursor);
 | 
			
		||||
void       meta_core_set_screen_cursor (Display    *xdisplay,
 | 
			
		||||
                                        Window      frame_on_screen,
 | 
			
		||||
                                        int         device_id,
 | 
			
		||||
                                        MetaCursor  cursor);
 | 
			
		||||
 | 
			
		||||
void       meta_core_select_events     (Display  *xdisplay,
 | 
			
		||||
                                        Window    xwindow,
 | 
			
		||||
                                        gint      evmask,
 | 
			
		||||
                                        gboolean  preserve_old_mask);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Used because we ignore EnterNotify when a window is unmapped that
 | 
			
		||||
 * really shouldn't cause focus changes, by comparing the event serial
 | 
			
		||||
 
 | 
			
		||||
@@ -108,16 +108,13 @@ delete_ping_timeout_func (MetaDisplay *display,
 | 
			
		||||
 | 
			
		||||
  /* Translators: %s is a window title */
 | 
			
		||||
  if (window_title)
 | 
			
		||||
    {
 | 
			
		||||
      char *title = g_strdup_printf ("“%s”", window_title);
 | 
			
		||||
      tmp = g_strdup_printf (_("%s is not responding."), title);
 | 
			
		||||
      g_free (title);
 | 
			
		||||
    }
 | 
			
		||||
    tmp = g_markup_printf_escaped (_("<tt>%s</tt> is not responding."),
 | 
			
		||||
                                   window_title);
 | 
			
		||||
  else
 | 
			
		||||
    tmp = g_strdup (_("Application is not responding."));
 | 
			
		||||
 | 
			
		||||
  window_content = g_strdup_printf (
 | 
			
		||||
      "<big><b>%s</b></big>\n\n%s",
 | 
			
		||||
      "<big><b>%s</b></big>\n\n<i>%s</i>",
 | 
			
		||||
      tmp,
 | 
			
		||||
      _("You may choose to wait a short while for it to "
 | 
			
		||||
        "continue or force the application to quit entirely."));
 | 
			
		||||
@@ -126,8 +123,7 @@ delete_ping_timeout_func (MetaDisplay *display,
 | 
			
		||||
    meta_show_dialog ("--question",
 | 
			
		||||
                      window_content, NULL,
 | 
			
		||||
                      window->screen->screen_name,
 | 
			
		||||
                      _("_Wait"), _("_Force Quit"),
 | 
			
		||||
                      "face-sad-symbolic", window->xwindow,
 | 
			
		||||
                      _("_Wait"), _("_Force Quit"), window->xwindow,
 | 
			
		||||
                      NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  g_free (window_content);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										69
									
								
								src/core/device-keyboard.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/core/device-keyboard.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Keyboard device abstraction */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Carlos Garnacho
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "device-keyboard.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (MetaDeviceKeyboard,
 | 
			
		||||
                        meta_device_keyboard,
 | 
			
		||||
                        META_TYPE_DEVICE)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_keyboard_class_init (MetaDeviceKeyboardClass *klass)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_keyboard_init (MetaDeviceKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Window
 | 
			
		||||
meta_device_keyboard_get_focus_window (MetaDeviceKeyboard *keyboard)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceKeyboardClass *klass;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (META_IS_DEVICE_KEYBOARD (keyboard), None);
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_KEYBOARD_GET_CLASS (keyboard);
 | 
			
		||||
 | 
			
		||||
  if (!klass->get_focus_window)
 | 
			
		||||
    return None;
 | 
			
		||||
 | 
			
		||||
  return (klass->get_focus_window) (keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_device_keyboard_set_focus_window (MetaDeviceKeyboard *keyboard,
 | 
			
		||||
                                       Window              xwindow,
 | 
			
		||||
                                       Time                timestamp)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceKeyboardClass *klass;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_DEVICE_KEYBOARD (keyboard));
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_KEYBOARD_GET_CLASS (keyboard);
 | 
			
		||||
 | 
			
		||||
  if (klass->set_focus_window)
 | 
			
		||||
    (klass->set_focus_window) (keyboard, xwindow, timestamp);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								src/core/device-keyboard.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/core/device-keyboard.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \file device-keyboard.h  Keyboard device abstraction
 | 
			
		||||
 *
 | 
			
		||||
 * Input devices.
 | 
			
		||||
 * This file contains the internal abstraction of keyboard devices so
 | 
			
		||||
 * XInput2/core events can be handled similarly.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Carlos Garnacho
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_DEVICE_KEYBOARD_H
 | 
			
		||||
#define META_DEVICE_KEYBOARD_H
 | 
			
		||||
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
#include "device-private.h"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_DEVICE_KEYBOARD            (meta_device_keyboard_get_type ())
 | 
			
		||||
#define META_DEVICE_KEYBOARD(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_KEYBOARD, MetaDeviceKeyboard))
 | 
			
		||||
#define META_DEVICE_KEYBOARD_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_KEYBOARD, MetaDeviceKeyboardClass))
 | 
			
		||||
#define META_IS_DEVICE_KEYBOARD(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_KEYBOARD))
 | 
			
		||||
#define META_IS_DEVICE_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_KEYBOARD))
 | 
			
		||||
#define META_DEVICE_KEYBOARD_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_KEYBOARD, MetaDeviceKeyboardClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaDeviceKeyboard MetaDeviceKeyboard;
 | 
			
		||||
typedef struct _MetaDeviceKeyboardClass MetaDeviceKeyboardClass;
 | 
			
		||||
 | 
			
		||||
struct _MetaDeviceKeyboard
 | 
			
		||||
{
 | 
			
		||||
  MetaDevice parent_instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaDeviceKeyboardClass
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceClass parent_instance;
 | 
			
		||||
 | 
			
		||||
  Window (* get_focus_window) (MetaDeviceKeyboard *keyboard);
 | 
			
		||||
  void   (* set_focus_window) (MetaDeviceKeyboard *keyboard,
 | 
			
		||||
                               Window              xwindow,
 | 
			
		||||
                               Time                timestamp);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType    meta_device_keyboard_get_type   (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
Window   meta_device_keyboard_get_focus_window (MetaDeviceKeyboard *keyboard);
 | 
			
		||||
void     meta_device_keyboard_set_focus_window (MetaDeviceKeyboard *keyboard,
 | 
			
		||||
                                                Window              xwindow,
 | 
			
		||||
                                                Time                timestamp);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* META_DEVICE_KEYBOARD_H */
 | 
			
		||||
							
								
								
									
										134
									
								
								src/core/device-map-core.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								src/core/device-map-core.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Input device map, core protocol implementation */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Carlos Garnacho
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "device-map-core.h"
 | 
			
		||||
#include "devices-core.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaDeviceMapCore, meta_device_map_core, META_TYPE_DEVICE_MAP)
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_device_map_core_grab_key (MetaDeviceMap *device_map,
 | 
			
		||||
                               Window         xwindow,
 | 
			
		||||
                               guint          keycode,
 | 
			
		||||
                               guint          modifiers,
 | 
			
		||||
                               gboolean       sync)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  gint retval;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
  retval = XGrabKey (display->xdisplay, keycode, modifiers,
 | 
			
		||||
                     xwindow, True,
 | 
			
		||||
                     GrabModeAsync, /* Never care about the other device */
 | 
			
		||||
                     (sync) ? GrabModeSync : GrabModeAsync);
 | 
			
		||||
 | 
			
		||||
  return (retval == Success);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_core_ungrab_key (MetaDeviceMap *device_map,
 | 
			
		||||
                                 Window         xwindow,
 | 
			
		||||
                                 guint          keycode,
 | 
			
		||||
                                 guint          modifiers)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
  XUngrabKey (display->xdisplay, keycode, modifiers, xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_device_map_core_grab_button (MetaDeviceMap *device_map,
 | 
			
		||||
                                  Window         xwindow,
 | 
			
		||||
                                  guint          n_button,
 | 
			
		||||
                                  guint          modifiers,
 | 
			
		||||
                                  guint          evmask,
 | 
			
		||||
                                  gboolean       sync)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  gint retval;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
  retval = XGrabButton (display->xdisplay, n_button,
 | 
			
		||||
                        modifiers, xwindow, False,
 | 
			
		||||
                        evmask,
 | 
			
		||||
                        (sync) ? GrabModeSync : GrabModeAsync,
 | 
			
		||||
                        GrabModeAsync, /* Never care about the other device */
 | 
			
		||||
                        None, None);
 | 
			
		||||
 | 
			
		||||
  return (retval == Success);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_core_ungrab_button (MetaDeviceMap *device_map,
 | 
			
		||||
                                    Window         xwindow,
 | 
			
		||||
                                    guint          n_button,
 | 
			
		||||
                                    guint          modifiers)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
  XUngrabButton (display->xdisplay, n_button, modifiers, xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_core_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMap *device_map = META_DEVICE_MAP (object);
 | 
			
		||||
  MetaDevice *pointer, *keyboard;
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
 | 
			
		||||
  /* Insert core devices */
 | 
			
		||||
  pointer = meta_device_pointer_core_new (display);
 | 
			
		||||
  meta_device_map_add_device (device_map, pointer);
 | 
			
		||||
 | 
			
		||||
  keyboard = meta_device_keyboard_core_new (display);
 | 
			
		||||
  meta_device_map_add_device (device_map, keyboard);
 | 
			
		||||
 | 
			
		||||
  meta_device_pair_devices (pointer, keyboard);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (pointer);
 | 
			
		||||
  g_object_unref (keyboard);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_core_class_init (MetaDeviceMapCoreClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapClass *device_map_class = META_DEVICE_MAP_CLASS (klass);
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->constructed = meta_device_map_core_constructed;
 | 
			
		||||
 | 
			
		||||
  device_map_class->grab_key = meta_device_map_core_grab_key;
 | 
			
		||||
  device_map_class->ungrab_key = meta_device_map_core_ungrab_key;
 | 
			
		||||
  device_map_class->grab_button = meta_device_map_core_grab_button;
 | 
			
		||||
  device_map_class->ungrab_button = meta_device_map_core_ungrab_button;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_core_init (MetaDeviceMapCore *device_map)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								src/core/device-map-core.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/core/device-map-core.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \file device-map-core.h  device map for core devices
 | 
			
		||||
 *
 | 
			
		||||
 * Input devices.
 | 
			
		||||
 * This file contains the core protocol implementation of the device map
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Carlos Garnacho
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_DEVICE_MAP_CORE_H
 | 
			
		||||
#define META_DEVICE_MAP_CORE_H
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaDeviceMapCore MetaDeviceMapCore;
 | 
			
		||||
typedef struct _MetaDeviceMapCoreClass MetaDeviceMapCoreClass;
 | 
			
		||||
 | 
			
		||||
#include "device-map-private.h"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_DEVICE_MAP_CORE            (meta_device_map_core_get_type ())
 | 
			
		||||
#define META_DEVICE_MAP_CORE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_MAP_CORE, MetaDeviceMapCore))
 | 
			
		||||
#define META_DEVICE_MAP_CORE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_MAP_CORE, MetaDeviceMapCoreClass))
 | 
			
		||||
#define META_IS_DEVICE_MAP_CORE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_MAP_CORE))
 | 
			
		||||
#define META_IS_DEVICE_MAP_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_MAP_CORE))
 | 
			
		||||
#define META_DEVICE_MAP_CORE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_MAP_CORE, MetaDeviceMapCoreClass))
 | 
			
		||||
 | 
			
		||||
struct _MetaDeviceMapCore
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMap parent_instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaDeviceMapCoreClass
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType           meta_device_map_core_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
#endif /* META_DEVICE_MAP_CORE_H */
 | 
			
		||||
							
								
								
									
										120
									
								
								src/core/device-map-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/core/device-map-private.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \file device-map.h  object containing input devices
 | 
			
		||||
 *
 | 
			
		||||
 * Input devices.
 | 
			
		||||
 * This file contains the device map, used to find out the device behind
 | 
			
		||||
 * XInput2/core events.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Carlos Garnacho
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_DEVICE_MAP_PRIVATE_H
 | 
			
		||||
#define META_DEVICE_MAP_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
#include <meta/device-map.h>
 | 
			
		||||
#include <meta/device.h>
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
#include "device-private.h"
 | 
			
		||||
 | 
			
		||||
/* Device IDs for Virtual Core Pointer/Keyboard,
 | 
			
		||||
 * use only in case of emergency.
 | 
			
		||||
 */
 | 
			
		||||
#define META_CORE_POINTER_ID  2
 | 
			
		||||
#define META_CORE_KEYBOARD_ID 3
 | 
			
		||||
 | 
			
		||||
struct _MetaDeviceMap
 | 
			
		||||
{
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
  gpointer priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaDeviceMapClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_instance;
 | 
			
		||||
 | 
			
		||||
  void (* device_added)   (MetaDeviceMap *device_map,
 | 
			
		||||
                           MetaDevice    *device);
 | 
			
		||||
  void (* device_removed) (MetaDeviceMap *device_map,
 | 
			
		||||
                           MetaDevice    *device);
 | 
			
		||||
 | 
			
		||||
  gboolean (* grab_key)       (MetaDeviceMap *device_map,
 | 
			
		||||
                               Window         xwindow,
 | 
			
		||||
                               guint          keycode,
 | 
			
		||||
                               guint          modifiers,
 | 
			
		||||
                               gboolean       sync);
 | 
			
		||||
  void     (* ungrab_key)     (MetaDeviceMap *device_map,
 | 
			
		||||
                               Window         xwindow,
 | 
			
		||||
                               guint          keycode,
 | 
			
		||||
                               guint          modifiers);
 | 
			
		||||
 | 
			
		||||
  gboolean (* grab_button)    (MetaDeviceMap *device_map,
 | 
			
		||||
                               Window         xwindow,
 | 
			
		||||
                               guint          n_button,
 | 
			
		||||
                               guint          modifiers,
 | 
			
		||||
                               guint          evmask,
 | 
			
		||||
                               gboolean       sync);
 | 
			
		||||
  void     (* ungrab_button)  (MetaDeviceMap *pointer,
 | 
			
		||||
                               Window         xwindow,
 | 
			
		||||
                               guint          n_button,
 | 
			
		||||
                               guint          modifiers);
 | 
			
		||||
  void     (* grab_touch)     (MetaDeviceMap *pointer,
 | 
			
		||||
                               Window         xwindow);
 | 
			
		||||
  void     (* ungrab_touch)   (MetaDeviceMap *pointer,
 | 
			
		||||
                               Window         xwindow);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType           meta_device_map_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
MetaDeviceMap * meta_device_map_new    (MetaDisplay   *display,
 | 
			
		||||
                                        gboolean       force_core);
 | 
			
		||||
 | 
			
		||||
void            meta_device_map_add_device    (MetaDeviceMap *device_map,
 | 
			
		||||
                                               MetaDevice    *device);
 | 
			
		||||
void            meta_device_map_remove_device (MetaDeviceMap *device_map,
 | 
			
		||||
                                               MetaDevice    *device);
 | 
			
		||||
 | 
			
		||||
gboolean meta_device_map_grab_key        (MetaDeviceMap      *device_map,
 | 
			
		||||
                                          Window              xwindow,
 | 
			
		||||
                                          guint               keycode,
 | 
			
		||||
                                          guint               modifiers,
 | 
			
		||||
                                          gboolean            sync);
 | 
			
		||||
void     meta_device_map_ungrab_key      (MetaDeviceMap      *device_map,
 | 
			
		||||
                                          Window              xwindow,
 | 
			
		||||
                                          guint               keycode,
 | 
			
		||||
                                          guint               modifiers);
 | 
			
		||||
gboolean meta_device_map_grab_button     (MetaDeviceMap      *device_map,
 | 
			
		||||
                                          Window              xwindow,
 | 
			
		||||
                                          guint               n_button,
 | 
			
		||||
                                          guint               modifiers,
 | 
			
		||||
                                          guint               evmask,
 | 
			
		||||
                                          gboolean            sync);
 | 
			
		||||
void     meta_device_map_ungrab_button   (MetaDeviceMap      *device_map,
 | 
			
		||||
                                          Window              xwindow,
 | 
			
		||||
                                          guint               n_button,
 | 
			
		||||
                                          guint               modifiers);
 | 
			
		||||
 | 
			
		||||
void     meta_device_map_grab_touch      (MetaDeviceMap      *device_map,
 | 
			
		||||
                                          Window              xwindow);
 | 
			
		||||
void     meta_device_map_ungrab_touch    (MetaDeviceMap      *device_map,
 | 
			
		||||
                                          Window              xwindow);
 | 
			
		||||
 | 
			
		||||
#endif /* META_DEVICE_MAP_PRIVATE_H */
 | 
			
		||||
							
								
								
									
										323
									
								
								src/core/device-map-xi2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								src/core/device-map-xi2.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,323 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Input device map, XInput2 implementation */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Carlos Garnacho
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "device-map-xi2.h"
 | 
			
		||||
#include <X11/extensions/XInput2.h>
 | 
			
		||||
#include "devices-xi2.h"
 | 
			
		||||
#include "input-events.h"
 | 
			
		||||
 | 
			
		||||
#define XINPUT2_VERSION_MAJOR 2
 | 
			
		||||
#define XINPUT2_VERSION_MINOR 0
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaDeviceMapXI2, meta_device_map_xi2, META_TYPE_DEVICE_MAP)
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_device_map_xi2_grab_key (MetaDeviceMap *device_map,
 | 
			
		||||
                              Window         xwindow,
 | 
			
		||||
                              guint          keycode,
 | 
			
		||||
                              guint          modifiers,
 | 
			
		||||
                              gboolean       sync)
 | 
			
		||||
{
 | 
			
		||||
  XIGrabModifiers mods = { modifiers, 0 };
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  XIEventMask mask;
 | 
			
		||||
  gint retval;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
 | 
			
		||||
  mask.deviceid = XIAllMasterDevices;
 | 
			
		||||
  mask.mask = meta_device_xi2_translate_event_mask (KeyPressMask |
 | 
			
		||||
                                                    KeyReleaseMask,
 | 
			
		||||
                                                    &mask.mask_len);
 | 
			
		||||
 | 
			
		||||
  retval = XIGrabKeycode (display->xdisplay,
 | 
			
		||||
                          XIAllMasterDevices,
 | 
			
		||||
                          keycode, xwindow,
 | 
			
		||||
                          (sync) ? GrabModeSync : GrabModeAsync,
 | 
			
		||||
                          GrabModeAsync, /* Never care about the other device */
 | 
			
		||||
                          True, &mask, 1, &mods);
 | 
			
		||||
 | 
			
		||||
  return (retval == Success);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_xi2_ungrab_key (MetaDeviceMap *device_map,
 | 
			
		||||
                                Window         xwindow,
 | 
			
		||||
                                guint          keycode,
 | 
			
		||||
                                guint          modifiers)
 | 
			
		||||
{
 | 
			
		||||
  XIGrabModifiers mods = { modifiers, 0 };
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
  XIUngrabKeycode (display->xdisplay,
 | 
			
		||||
                   XIAllMasterDevices,
 | 
			
		||||
                   keycode, xwindow,
 | 
			
		||||
                   1, &mods);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_device_map_xi2_grab_button (MetaDeviceMap *device_map,
 | 
			
		||||
                                 Window         xwindow,
 | 
			
		||||
                                 guint          n_button,
 | 
			
		||||
                                 guint          modifiers,
 | 
			
		||||
                                 guint          evmask,
 | 
			
		||||
                                 gboolean       sync)
 | 
			
		||||
{
 | 
			
		||||
  XIGrabModifiers mods = { modifiers, 0 };
 | 
			
		||||
  XIEventMask mask;
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  int retval;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
 | 
			
		||||
  mask.deviceid = XIAllMasterDevices;
 | 
			
		||||
  mask.mask = meta_device_xi2_translate_event_mask (evmask, &mask.mask_len);
 | 
			
		||||
 | 
			
		||||
  retval = XIGrabButton (display->xdisplay,
 | 
			
		||||
                         XIAllMasterDevices,
 | 
			
		||||
                         n_button, xwindow, None,
 | 
			
		||||
                         (sync) ? GrabModeSync : GrabModeAsync,
 | 
			
		||||
                         GrabModeAsync, /* Never care about the other device */
 | 
			
		||||
                         False, &mask, 1, &mods);
 | 
			
		||||
 | 
			
		||||
  return (retval == Success);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_xi2_ungrab_button (MetaDeviceMap *device_map,
 | 
			
		||||
                                   Window         xwindow,
 | 
			
		||||
                                   guint          n_button,
 | 
			
		||||
                                   guint          modifiers)
 | 
			
		||||
{
 | 
			
		||||
  XIGrabModifiers mods = { modifiers, 0 };
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
  XIUngrabButton (display->xdisplay,
 | 
			
		||||
                  XIAllMasterDevices,
 | 
			
		||||
                  n_button, xwindow, 1, &mods);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaDevice *
 | 
			
		||||
create_device_from_info (MetaDeviceMap *device_map,
 | 
			
		||||
                         gint           use,
 | 
			
		||||
                         gint           device_id)
 | 
			
		||||
{
 | 
			
		||||
  MetaDevice *device = NULL;
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
 | 
			
		||||
  if (use == XIMasterPointer ||
 | 
			
		||||
      use == XISlavePointer)
 | 
			
		||||
    device = meta_device_pointer_xi2_new (display, device_id);
 | 
			
		||||
  else if (use == XIMasterKeyboard)
 | 
			
		||||
    device = meta_device_keyboard_xi2_new (display, device_id);
 | 
			
		||||
 | 
			
		||||
  return device;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
pair_devices (gpointer key,
 | 
			
		||||
              gpointer value,
 | 
			
		||||
              gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaDevice *device1, *device2;
 | 
			
		||||
  MetaDeviceMap *device_map;
 | 
			
		||||
 | 
			
		||||
  device_map = user_data;
 | 
			
		||||
  device1 = meta_device_map_lookup (device_map, GPOINTER_TO_INT (key));
 | 
			
		||||
  device2 = meta_device_map_lookup (device_map, GPOINTER_TO_INT (value));
 | 
			
		||||
 | 
			
		||||
  meta_device_pair_devices (device1, device2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_xi2_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMap *device_map = META_DEVICE_MAP (object);
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  XIDeviceInfo *info;
 | 
			
		||||
  GHashTable *pairs;
 | 
			
		||||
  int n_devices, i;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
 | 
			
		||||
  /* We're only interested in master devices,
 | 
			
		||||
   * detached slave devices are left for applications
 | 
			
		||||
   * to handle.
 | 
			
		||||
   */
 | 
			
		||||
  info = XIQueryDevice (display->xdisplay, XIAllDevices, &n_devices);
 | 
			
		||||
  pairs = g_hash_table_new (NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_devices; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaDevice *device;
 | 
			
		||||
 | 
			
		||||
      device = create_device_from_info (device_map, info[i].use,
 | 
			
		||||
                                        info[i].deviceid);
 | 
			
		||||
      if (device)
 | 
			
		||||
        {
 | 
			
		||||
          meta_device_map_add_device (device_map, device);
 | 
			
		||||
 | 
			
		||||
          if (info[i].use == XIMasterPointer ||
 | 
			
		||||
              info[i].use == XIMasterKeyboard)
 | 
			
		||||
            g_hash_table_insert (pairs,
 | 
			
		||||
                                 GINT_TO_POINTER (info[i].deviceid),
 | 
			
		||||
                                 GINT_TO_POINTER (info[i].attachment));
 | 
			
		||||
 | 
			
		||||
          g_object_unref (device);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_hash_table_foreach (pairs, pair_devices, device_map);
 | 
			
		||||
  g_hash_table_destroy (pairs);
 | 
			
		||||
 | 
			
		||||
  XIFreeDeviceInfo (info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_xi2_grab_touch (MetaDeviceMap *device_map,
 | 
			
		||||
                                Window         xwindow)
 | 
			
		||||
{
 | 
			
		||||
  XIGrabModifiers unused = { 0 };
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  XIEventMask mask;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
 | 
			
		||||
  g_message ("Grabbing passively on touch begin\n");
 | 
			
		||||
 | 
			
		||||
  mask.deviceid = XIAllMasterDevices;
 | 
			
		||||
  mask.mask = meta_device_xi2_translate_event_mask (META_INPUT_TOUCH_EVENTS_MASK |
 | 
			
		||||
                                                    ButtonPressMask |
 | 
			
		||||
                                                    ButtonReleaseMask |
 | 
			
		||||
                                                    PointerMotionMask |
 | 
			
		||||
                                                    KeyPressMask |
 | 
			
		||||
                                                    KeyReleaseMask,
 | 
			
		||||
                                                    &mask.mask_len);
 | 
			
		||||
  XIGrabTouchBegin (display->xdisplay,
 | 
			
		||||
                    XIAllMasterDevices,
 | 
			
		||||
                    xwindow, True,
 | 
			
		||||
                    &mask, 1, &unused);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_xi2_ungrab_touch (MetaDeviceMap *device_map,
 | 
			
		||||
                                  Window         xwindow)
 | 
			
		||||
{
 | 
			
		||||
  XIGrabModifiers unused = { 0 };
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (device_map);
 | 
			
		||||
  XIUngrabTouchBegin (display->xdisplay,
 | 
			
		||||
                      XIAllMasterDevices,
 | 
			
		||||
                      xwindow, 0, &unused);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_xi2_class_init (MetaDeviceMapXI2Class *klass)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapClass *device_map_class = META_DEVICE_MAP_CLASS (klass);
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->constructed = meta_device_map_xi2_constructed;
 | 
			
		||||
 | 
			
		||||
  device_map_class->grab_key = meta_device_map_xi2_grab_key;
 | 
			
		||||
  device_map_class->ungrab_key = meta_device_map_xi2_ungrab_key;
 | 
			
		||||
  device_map_class->grab_button = meta_device_map_xi2_grab_button;
 | 
			
		||||
  device_map_class->ungrab_button = meta_device_map_xi2_ungrab_button;
 | 
			
		||||
  device_map_class->grab_touch = meta_device_map_xi2_grab_touch;
 | 
			
		||||
  device_map_class->ungrab_touch = meta_device_map_xi2_ungrab_touch;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_xi2_init (MetaDeviceMapXI2 *device_map)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_device_map_xi2_handle_hierarchy_event (MetaDeviceMapXI2 *device_map,
 | 
			
		||||
                                            XEvent           *ev)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
 | 
			
		||||
  display = meta_device_map_get_display (META_DEVICE_MAP (device_map));
 | 
			
		||||
 | 
			
		||||
  if (ev->type == GenericEvent &&
 | 
			
		||||
      ev->xcookie.extension == display->xinput2_opcode)
 | 
			
		||||
    {
 | 
			
		||||
      XIHierarchyEvent *xev;
 | 
			
		||||
      GHashTable *pairs;
 | 
			
		||||
      gint i;
 | 
			
		||||
 | 
			
		||||
      g_assert (display->have_xinput2 == TRUE);
 | 
			
		||||
 | 
			
		||||
      xev = (XIHierarchyEvent *) ev->xcookie.data;
 | 
			
		||||
 | 
			
		||||
      if (xev->evtype != XI_HierarchyChanged)
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
      pairs = g_hash_table_new (NULL, NULL);
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < xev->num_info; i++)
 | 
			
		||||
        {
 | 
			
		||||
          if (xev->info[i].flags & XIMasterAdded ||
 | 
			
		||||
              xev->info[i].flags & XISlaveAdded)
 | 
			
		||||
            {
 | 
			
		||||
              MetaDevice *device;
 | 
			
		||||
 | 
			
		||||
              device = create_device_from_info (META_DEVICE_MAP (device_map),
 | 
			
		||||
                                                xev->info[i].use,
 | 
			
		||||
                                                xev->info[i].deviceid);
 | 
			
		||||
 | 
			
		||||
              if (device &&
 | 
			
		||||
                  xev->info[i].flags & XIMasterAdded)
 | 
			
		||||
                g_hash_table_insert (pairs,
 | 
			
		||||
                                     GINT_TO_POINTER (xev->info[i].deviceid),
 | 
			
		||||
                                     GINT_TO_POINTER (xev->info[i].attachment));
 | 
			
		||||
            }
 | 
			
		||||
          else if (xev->info[i].flags & XIMasterRemoved ||
 | 
			
		||||
                   xev->info[i].flags & XISlaveRemoved)
 | 
			
		||||
            {
 | 
			
		||||
              MetaDevice *device;
 | 
			
		||||
 | 
			
		||||
              device = meta_device_map_lookup (META_DEVICE_MAP (device_map),
 | 
			
		||||
                                               xev->info[i].deviceid);
 | 
			
		||||
 | 
			
		||||
              if (device)
 | 
			
		||||
                meta_device_map_remove_device (META_DEVICE_MAP (device_map),
 | 
			
		||||
                                               device);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      g_hash_table_foreach (pairs, pair_devices, device_map);
 | 
			
		||||
      g_hash_table_destroy (pairs);
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								src/core/device-map-xi2.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/core/device-map-xi2.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \file device-map-xi2.h  device map for XInput2 devices
 | 
			
		||||
 *
 | 
			
		||||
 * Input devices.
 | 
			
		||||
 * This file contains the XInput2 implementation of the device map
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Carlos Garnacho
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_DEVICE_MAP_XI2_H
 | 
			
		||||
#define META_DEVICE_MAP_XI2_H
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaDeviceMapXI2 MetaDeviceMapXI2;
 | 
			
		||||
typedef struct _MetaDeviceMapXI2Class MetaDeviceMapXI2Class;
 | 
			
		||||
 | 
			
		||||
#include "device-map-private.h"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_DEVICE_MAP_XI2            (meta_device_map_xi2_get_type ())
 | 
			
		||||
#define META_DEVICE_MAP_XI2(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_MAP_XI2, MetaDeviceMapXI2))
 | 
			
		||||
#define META_DEVICE_MAP_XI2_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_MAP_XI2, MetaDeviceMapXI2Class))
 | 
			
		||||
#define META_IS_DEVICE_MAP_XI2(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_MAP_XI2))
 | 
			
		||||
#define META_IS_DEVICE_MAP_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_MAP_XI2))
 | 
			
		||||
#define META_DEVICE_MAP_XI2_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_MAP_XI2, MetaDeviceMapXI2Class))
 | 
			
		||||
 | 
			
		||||
struct _MetaDeviceMapXI2
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMap parent_instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaDeviceMapXI2Class
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType           meta_device_map_xi2_get_type        (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
gboolean meta_device_map_xi2_handle_hierarchy_event (MetaDeviceMapXI2 *device_map,
 | 
			
		||||
                                                     XEvent           *ev);
 | 
			
		||||
 | 
			
		||||
#endif /* META_DEVICE_MAP_XI2_H */
 | 
			
		||||
							
								
								
									
										429
									
								
								src/core/device-map.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										429
									
								
								src/core/device-map.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,429 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Input device map */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Carlos Garnacho
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "device-map-private.h"
 | 
			
		||||
#include "device-map-core.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XINPUT2
 | 
			
		||||
#include <X11/extensions/XInput2.h>
 | 
			
		||||
#include "device-map-xi2.h"
 | 
			
		||||
 | 
			
		||||
#define XINPUT2_VERSION_MAJOR 2
 | 
			
		||||
#define XINPUT2_VERSION_MINOR 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaDeviceMap, meta_device_map, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
typedef struct MetaDeviceMapPrivate MetaDeviceMapPrivate;
 | 
			
		||||
 | 
			
		||||
struct MetaDeviceMapPrivate
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
  GHashTable *devices;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  PROP_0,
 | 
			
		||||
  PROP_DISPLAY
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  DEVICE_ADDED,
 | 
			
		||||
  DEVICE_REMOVED,
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_get_property (GObject    *object,
 | 
			
		||||
                              guint       param_id,
 | 
			
		||||
                              GValue     *value,
 | 
			
		||||
                              GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  priv = META_DEVICE_MAP (object)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (param_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_DISPLAY:
 | 
			
		||||
      g_value_set_object (value, priv->display);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_set_property (GObject      *object,
 | 
			
		||||
                              guint         param_id,
 | 
			
		||||
                              const GValue *value,
 | 
			
		||||
                              GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  priv = META_DEVICE_MAP (object)->priv;
 | 
			
		||||
 | 
			
		||||
  switch (param_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_DISPLAY:
 | 
			
		||||
      priv->display = g_value_get_object (value);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapPrivate *priv;
 | 
			
		||||
  GHashTableIter iter;
 | 
			
		||||
  MetaDevice *device;
 | 
			
		||||
 | 
			
		||||
  priv = META_DEVICE_MAP (object)->priv;
 | 
			
		||||
  g_hash_table_iter_init (&iter, priv->devices);
 | 
			
		||||
 | 
			
		||||
  while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &device))
 | 
			
		||||
    {
 | 
			
		||||
      /* Detach the device */
 | 
			
		||||
      g_hash_table_iter_steal (&iter);
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (object, signals[DEVICE_REMOVED], 0, device);
 | 
			
		||||
      g_object_unref (device);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_hash_table_destroy (priv->devices);
 | 
			
		||||
  G_OBJECT_CLASS (meta_device_map_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_class_init (MetaDeviceMapClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->get_property = meta_device_map_get_property;
 | 
			
		||||
  object_class->set_property = meta_device_map_set_property;
 | 
			
		||||
  object_class->finalize = meta_device_map_finalize;
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_DISPLAY,
 | 
			
		||||
                                   g_param_spec_object ("display",
 | 
			
		||||
                                                        "Display",
 | 
			
		||||
                                                        "Display",
 | 
			
		||||
                                                        META_TYPE_DISPLAY,
 | 
			
		||||
                                                        G_PARAM_READWRITE |
 | 
			
		||||
                                                        G_PARAM_CONSTRUCT_ONLY));
 | 
			
		||||
  signals[DEVICE_ADDED] =
 | 
			
		||||
    g_signal_new ("device-added",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0,
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                  G_TYPE_NONE, 1, META_TYPE_DEVICE);
 | 
			
		||||
  signals[DEVICE_REMOVED] =
 | 
			
		||||
    g_signal_new ("device-removed",
 | 
			
		||||
                  G_TYPE_FROM_CLASS (klass),
 | 
			
		||||
                  G_SIGNAL_RUN_LAST,
 | 
			
		||||
                  0,
 | 
			
		||||
                  NULL, NULL,
 | 
			
		||||
                  g_cclosure_marshal_VOID__OBJECT,
 | 
			
		||||
                  G_TYPE_NONE, 1, META_TYPE_DEVICE);
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (MetaDeviceMapPrivate));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_map_init (MetaDeviceMap *device_map)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  priv = device_map->priv = G_TYPE_INSTANCE_GET_PRIVATE (device_map,
 | 
			
		||||
                                                         META_TYPE_DEVICE_MAP,
 | 
			
		||||
                                                         MetaDeviceMapPrivate);
 | 
			
		||||
  priv->devices = g_hash_table_new_full (NULL, NULL, NULL,
 | 
			
		||||
                                         (GDestroyNotify) g_object_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_device_map_add_device (MetaDeviceMap *device_map,
 | 
			
		||||
                            MetaDevice    *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  priv = device_map->priv;
 | 
			
		||||
  g_hash_table_insert (priv->devices,
 | 
			
		||||
                       GINT_TO_POINTER (meta_device_get_id (device)),
 | 
			
		||||
                       g_object_ref (device));
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (device_map, signals[DEVICE_ADDED], 0, device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_device_map_remove_device (MetaDeviceMap *device_map,
 | 
			
		||||
                               MetaDevice    *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  priv = device_map->priv;
 | 
			
		||||
 | 
			
		||||
  if (g_hash_table_steal (priv->devices,
 | 
			
		||||
                          GINT_TO_POINTER (meta_device_get_id (device))))
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_emit (device_map, signals[DEVICE_REMOVED], 0, device);
 | 
			
		||||
      g_object_unref (device);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XINPUT2
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
initialize_xinput (MetaDisplay *display)
 | 
			
		||||
{
 | 
			
		||||
  int major, minor, opcode;
 | 
			
		||||
  int unused;
 | 
			
		||||
 | 
			
		||||
  if (!XQueryExtension (display->xdisplay,
 | 
			
		||||
                        "XInputExtension",
 | 
			
		||||
                        &opcode, &unused, &unused))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  major = XI_2_Major;
 | 
			
		||||
#ifdef HAVE_XTOUCH
 | 
			
		||||
  minor = XI_2_1_Minor;
 | 
			
		||||
#else
 | 
			
		||||
  minor = XI_2_Minor;
 | 
			
		||||
#endif /* HAVE_XTOUCH */
 | 
			
		||||
 | 
			
		||||
  XIQueryVersion (display->xdisplay, &major, &minor);
 | 
			
		||||
 | 
			
		||||
  if (major == XI_2_Major &&
 | 
			
		||||
      (
 | 
			
		||||
#ifdef HAVE_XTOUCH
 | 
			
		||||
       minor == XI_2_1_Minor ||
 | 
			
		||||
#endif /* HAVE_XTOUCH */
 | 
			
		||||
       minor == XI_2_Minor))
 | 
			
		||||
    {
 | 
			
		||||
      display->have_xinput2 = TRUE;
 | 
			
		||||
      display->have_xtouch = (minor >= XI_2_1_Minor);
 | 
			
		||||
      display->xinput2_opcode = opcode;
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* HAVE_XINPUT2 */
 | 
			
		||||
 | 
			
		||||
MetaDeviceMap *
 | 
			
		||||
meta_device_map_new (MetaDisplay *display,
 | 
			
		||||
                     gboolean     force_core)
 | 
			
		||||
{
 | 
			
		||||
  GType type = META_TYPE_DEVICE_MAP_CORE;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XINPUT2
 | 
			
		||||
  if (!force_core &&
 | 
			
		||||
      initialize_xinput (display))
 | 
			
		||||
    type = META_TYPE_DEVICE_MAP_XI2;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return g_object_new (type,
 | 
			
		||||
                       "display", display,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_device_map_lookup:
 | 
			
		||||
 * @device_map: a #MetaDeviceMap
 | 
			
		||||
 * @device_id: ID for a device
 | 
			
		||||
 *
 | 
			
		||||
 * returns the device corresponding to @device_id
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): (allow-none): The matching device, or %NULL.
 | 
			
		||||
 **/
 | 
			
		||||
MetaDevice *
 | 
			
		||||
meta_device_map_lookup (MetaDeviceMap *device_map,
 | 
			
		||||
                        gint           device_id)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), NULL);
 | 
			
		||||
 | 
			
		||||
  priv = device_map->priv;
 | 
			
		||||
  return g_hash_table_lookup (priv->devices,
 | 
			
		||||
                              GINT_TO_POINTER (device_id));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_device_map_get_display:
 | 
			
		||||
 * @device_map: a #MetaDeviceMap
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the #MetaDisplay to which @device_map belongs to.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): The #MetaDisplay.
 | 
			
		||||
 **/
 | 
			
		||||
MetaDisplay *
 | 
			
		||||
meta_device_map_get_display (MetaDeviceMap *device_map)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), NULL);
 | 
			
		||||
 | 
			
		||||
  priv = device_map->priv;
 | 
			
		||||
  return priv->display;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_device_map_list_devices:
 | 
			
		||||
 * @device_map: a #MetaDeviceMap
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the list of devices that @device_map holds.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (element-type Meta.Device) (transfer container): the list
 | 
			
		||||
 *          of devices, the contained objects are owned by @device_map
 | 
			
		||||
 *          and should not be unref'ed. The list must be freed with
 | 
			
		||||
 *          g_list_free().
 | 
			
		||||
 **/
 | 
			
		||||
GList *
 | 
			
		||||
meta_device_map_list_devices (MetaDeviceMap *device_map)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), NULL);
 | 
			
		||||
 | 
			
		||||
  priv = device_map->priv;
 | 
			
		||||
  return g_hash_table_get_values (priv->devices);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_device_map_grab_key (MetaDeviceMap *device_map,
 | 
			
		||||
                          Window         xwindow,
 | 
			
		||||
                          guint          keycode,
 | 
			
		||||
                          guint          modifiers,
 | 
			
		||||
                          gboolean       sync)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapClass *klass;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), FALSE);
 | 
			
		||||
  g_return_val_if_fail (xwindow != None, FALSE);
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_MAP_GET_CLASS (device_map);
 | 
			
		||||
 | 
			
		||||
  if (!klass->grab_key)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return (klass->grab_key) (device_map, xwindow, keycode, modifiers, sync);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_device_map_ungrab_key (MetaDeviceMap *device_map,
 | 
			
		||||
                            Window         xwindow,
 | 
			
		||||
                            guint          keycode,
 | 
			
		||||
                            guint          modifiers)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapClass *klass;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_DEVICE_MAP (device_map));
 | 
			
		||||
  g_return_if_fail (xwindow != None);
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_MAP_GET_CLASS (device_map);
 | 
			
		||||
 | 
			
		||||
  if (klass->ungrab_key)
 | 
			
		||||
    (klass->ungrab_key) (device_map, xwindow, keycode, modifiers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_device_map_grab_button (MetaDeviceMap *device_map,
 | 
			
		||||
                             Window         xwindow,
 | 
			
		||||
                             guint          n_button,
 | 
			
		||||
                             guint          modifiers,
 | 
			
		||||
                             guint          evmask,
 | 
			
		||||
                             gboolean       sync)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapClass *klass;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (META_IS_DEVICE_MAP (device_map), FALSE);
 | 
			
		||||
  g_return_val_if_fail (xwindow != None, FALSE);
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_MAP_GET_CLASS (device_map);
 | 
			
		||||
 | 
			
		||||
  if (!klass->grab_button)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return (klass->grab_button) (device_map, xwindow, n_button,
 | 
			
		||||
                               modifiers, evmask, sync);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_device_map_ungrab_button (MetaDeviceMap *device_map,
 | 
			
		||||
                               Window         xwindow,
 | 
			
		||||
                               guint          n_button,
 | 
			
		||||
                               guint          modifiers)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapClass *klass;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_DEVICE_MAP (device_map));
 | 
			
		||||
  g_return_if_fail (xwindow != None);
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_MAP_GET_CLASS (device_map);
 | 
			
		||||
 | 
			
		||||
  if (klass->ungrab_button)
 | 
			
		||||
    (klass->ungrab_button) (device_map, xwindow, n_button, modifiers);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_device_map_grab_touch (MetaDeviceMap *device_map,
 | 
			
		||||
                            Window         xwindow)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapClass *klass;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_DEVICE_MAP (device_map));
 | 
			
		||||
  g_return_if_fail (xwindow != None);
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_MAP_GET_CLASS (device_map);
 | 
			
		||||
 | 
			
		||||
  if (klass->grab_touch)
 | 
			
		||||
    (klass->grab_touch) (device_map, xwindow);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_device_map_ungrab_touch (MetaDeviceMap *device_map,
 | 
			
		||||
                              Window         xwindow)
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceMapClass *klass;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_DEVICE_MAP (device_map));
 | 
			
		||||
  g_return_if_fail (xwindow != None);
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_MAP_GET_CLASS (device_map);
 | 
			
		||||
 | 
			
		||||
  if (klass->ungrab_touch)
 | 
			
		||||
    (klass->ungrab_touch) (device_map, xwindow);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										124
									
								
								src/core/device-pointer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/core/device-pointer.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Pointer device abstraction */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Carlos Garnacho
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "device-pointer.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (MetaDevicePointer,
 | 
			
		||||
                        meta_device_pointer,
 | 
			
		||||
                        META_TYPE_DEVICE)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_pointer_class_init (MetaDevicePointerClass *klass)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_device_pointer_init (MetaDevicePointer *pointer)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_device_pointer_warp (MetaDevicePointer *pointer,
 | 
			
		||||
                          MetaScreen        *screen,
 | 
			
		||||
                          gint               x,
 | 
			
		||||
                          gint               y)
 | 
			
		||||
{
 | 
			
		||||
  MetaDevicePointerClass *klass;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_DEVICE_POINTER (pointer));
 | 
			
		||||
  g_return_if_fail (META_IS_SCREEN (screen));
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_POINTER_GET_CLASS (pointer);
 | 
			
		||||
 | 
			
		||||
  if (klass->warp)
 | 
			
		||||
    (klass->warp) (pointer, screen, x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_device_pointer_set_window_cursor (MetaDevicePointer *pointer,
 | 
			
		||||
                                       Window             xwindow,
 | 
			
		||||
                                       MetaCursor         cursor)
 | 
			
		||||
{
 | 
			
		||||
  MetaDevicePointerClass *klass;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_DEVICE_POINTER (pointer));
 | 
			
		||||
  g_return_if_fail (xwindow != None);
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_POINTER_GET_CLASS (pointer);
 | 
			
		||||
 | 
			
		||||
  if (klass->set_window_cursor)
 | 
			
		||||
    (klass->set_window_cursor) (pointer, xwindow, cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_device_pointer_query_position (MetaDevicePointer *pointer,
 | 
			
		||||
                                    Window             xwindow,
 | 
			
		||||
                                    Window            *root_ret,
 | 
			
		||||
                                    Window            *child_ret,
 | 
			
		||||
                                    gint              *root_x_ret,
 | 
			
		||||
                                    gint              *root_y_ret,
 | 
			
		||||
                                    gint              *x_ret,
 | 
			
		||||
                                    gint              *y_ret,
 | 
			
		||||
                                    guint             *mask_ret)
 | 
			
		||||
{
 | 
			
		||||
  MetaDevicePointerClass *klass;
 | 
			
		||||
  gint root_x, root_y, x, y;
 | 
			
		||||
  Window root, child;
 | 
			
		||||
  gboolean retval;
 | 
			
		||||
  guint mask;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (META_IS_DEVICE_POINTER (pointer), FALSE);
 | 
			
		||||
  g_return_val_if_fail (xwindow != None, FALSE);
 | 
			
		||||
 | 
			
		||||
  klass = META_DEVICE_POINTER_GET_CLASS (pointer);
 | 
			
		||||
 | 
			
		||||
  if (!klass->query_position)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  retval = (klass->query_position) (pointer, xwindow, &root, &child,
 | 
			
		||||
                                    &root_x, &root_y, &x, &y, &mask);
 | 
			
		||||
 | 
			
		||||
  if (root_ret)
 | 
			
		||||
    *root_ret = root;
 | 
			
		||||
 | 
			
		||||
  if (child_ret)
 | 
			
		||||
    *child_ret = child;
 | 
			
		||||
 | 
			
		||||
  if (root_x_ret)
 | 
			
		||||
    *root_x_ret = root_x;
 | 
			
		||||
 | 
			
		||||
  if (root_y_ret)
 | 
			
		||||
    *root_y_ret = root_y;
 | 
			
		||||
 | 
			
		||||
  if (x_ret)
 | 
			
		||||
    *x_ret = x;
 | 
			
		||||
 | 
			
		||||
  if (y_ret)
 | 
			
		||||
    *y_ret = y;
 | 
			
		||||
 | 
			
		||||
  if (mask_ret)
 | 
			
		||||
    *mask_ret = mask;
 | 
			
		||||
 | 
			
		||||
  return retval;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										95
									
								
								src/core/device-pointer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/core/device-pointer.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,95 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \file device-pointer.h  Pointer device abstraction
 | 
			
		||||
 *
 | 
			
		||||
 * Input devices.
 | 
			
		||||
 * This file contains the internal abstraction of pointer devices so
 | 
			
		||||
 * XInput2/core events can be handled similarly.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2011 Carlos Garnacho
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
 * License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful, but
 | 
			
		||||
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 | 
			
		||||
 * 02111-1307, USA.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_DEVICE_POINTER_H
 | 
			
		||||
#define META_DEVICE_POINTER_H
 | 
			
		||||
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
#include <meta/screen.h>
 | 
			
		||||
#include "device-private.h"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_DEVICE_POINTER            (meta_device_pointer_get_type ())
 | 
			
		||||
#define META_DEVICE_POINTER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_POINTER, MetaDevicePointer))
 | 
			
		||||
#define META_DEVICE_POINTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_DEVICE_POINTER, MetaDevicePointerClass))
 | 
			
		||||
#define META_IS_DEVICE_POINTER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_POINTER))
 | 
			
		||||
#define META_IS_DEVICE_POINTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_DEVICE_POINTER))
 | 
			
		||||
#define META_DEVICE_POINTER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_DEVICE_POINTER, MetaDevicePointerClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaDevicePointer MetaDevicePointer;
 | 
			
		||||
typedef struct _MetaDevicePointerClass MetaDevicePointerClass;
 | 
			
		||||
 | 
			
		||||
struct _MetaDevicePointer
 | 
			
		||||
{
 | 
			
		||||
  MetaDevice parent_instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaDevicePointerClass
 | 
			
		||||
{
 | 
			
		||||
  MetaDeviceClass parent_instance;
 | 
			
		||||
 | 
			
		||||
  void     (* warp)           (MetaDevicePointer *pointer,
 | 
			
		||||
                               MetaScreen        *screen,
 | 
			
		||||
                               gint               x,
 | 
			
		||||
                               gint               y);
 | 
			
		||||
 | 
			
		||||
  void (* set_window_cursor)  (MetaDevicePointer *pointer,
 | 
			
		||||
                               Window             xwindow,
 | 
			
		||||
                               MetaCursor         cursor);
 | 
			
		||||
  gboolean (* query_position) (MetaDevicePointer *pointer,
 | 
			
		||||
                               Window             xwindow,
 | 
			
		||||
                               Window            *root,
 | 
			
		||||
                               Window            *child,
 | 
			
		||||
                               gint              *root_x,
 | 
			
		||||
                               gint              *root_y,
 | 
			
		||||
                               gint              *x,
 | 
			
		||||
                               gint              *y,
 | 
			
		||||
                               guint             *mask);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType    meta_device_pointer_get_type      (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void     meta_device_pointer_warp              (MetaDevicePointer *pointer,
 | 
			
		||||
                                                MetaScreen        *screen,
 | 
			
		||||
                                                gint               x,
 | 
			
		||||
                                                gint               y);
 | 
			
		||||
void     meta_device_pointer_set_window_cursor (MetaDevicePointer *pointer,
 | 
			
		||||
						Window             xwindow,
 | 
			
		||||
						MetaCursor         cursor);
 | 
			
		||||
 | 
			
		||||
gboolean meta_device_pointer_query_position    (MetaDevicePointer *pointer,
 | 
			
		||||
                                                Window             xwindow,
 | 
			
		||||
                                                Window            *root,
 | 
			
		||||
                                                Window            *child,
 | 
			
		||||
                                                gint              *root_x,
 | 
			
		||||
                                                gint              *root_y,
 | 
			
		||||
                                                gint              *x,
 | 
			
		||||
                                                gint              *y,
 | 
			
		||||
                                                guint             *mask);
 | 
			
		||||
 | 
			
		||||
#endif /* META_DEVICE_POINTER_H */
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user