Compare commits
	
		
			3 Commits
		
	
	
		
			3.16.1.1
			...
			3.12.1-way
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					e947d2f544 | ||
| 
						 | 
					12e8d04c16 | ||
| 
						 | 
					783dbf9390 | 
							
								
								
									
										35
									
								
								.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
aclocal.m4
 | 
			
		||||
confdefs.h
 | 
			
		||||
config.cache
 | 
			
		||||
config.guess
 | 
			
		||||
config.h
 | 
			
		||||
config.log
 | 
			
		||||
config.status
 | 
			
		||||
config.sub
 | 
			
		||||
configure
 | 
			
		||||
configure.scan
 | 
			
		||||
libtool
 | 
			
		||||
ltconfig
 | 
			
		||||
ltmain.sh
 | 
			
		||||
stamp-h
 | 
			
		||||
stamp-h.in
 | 
			
		||||
stamp-h1
 | 
			
		||||
stamp.h
 | 
			
		||||
version.h
 | 
			
		||||
config.h.in
 | 
			
		||||
install-sh
 | 
			
		||||
missing
 | 
			
		||||
mkinstalldirs
 | 
			
		||||
INSTALL
 | 
			
		||||
intl
 | 
			
		||||
ABOUT-NLS
 | 
			
		||||
COPYING
 | 
			
		||||
intltool-*
 | 
			
		||||
metacity.spec
 | 
			
		||||
autom4te.cache
 | 
			
		||||
compile
 | 
			
		||||
depcomp
 | 
			
		||||
omf.make
 | 
			
		||||
xmldocs.make
 | 
			
		||||
							
								
								
									
										43
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -3,7 +3,6 @@ Makefile.in
 | 
			
		||||
Makefile.in.in
 | 
			
		||||
aclocal.m4
 | 
			
		||||
autom4te.cache
 | 
			
		||||
build-aux
 | 
			
		||||
compile
 | 
			
		||||
config.guess
 | 
			
		||||
config.h
 | 
			
		||||
@@ -20,11 +19,11 @@ libtool
 | 
			
		||||
ltmain.sh
 | 
			
		||||
missing
 | 
			
		||||
.deps
 | 
			
		||||
50-mutter-navigation.xml
 | 
			
		||||
50-mutter-system.xml
 | 
			
		||||
50-mutter-windows.xml
 | 
			
		||||
mutter.desktop
 | 
			
		||||
mutter-wayland.desktop
 | 
			
		||||
src/50-mutter-navigation.xml
 | 
			
		||||
src/50-mutter-system.xml
 | 
			
		||||
src/50-mutter-windows.xml
 | 
			
		||||
src/mutter-wm.desktop
 | 
			
		||||
src/mutter-wayland.desktop
 | 
			
		||||
*.o
 | 
			
		||||
*.a
 | 
			
		||||
*.lo
 | 
			
		||||
@@ -33,6 +32,10 @@ mutter-wayland.desktop
 | 
			
		||||
*.swp
 | 
			
		||||
*.gir
 | 
			
		||||
*.typelib
 | 
			
		||||
tidy-enum-types.[ch]
 | 
			
		||||
tidy-marshal.[ch]
 | 
			
		||||
stamp-tidy-enum-types.h
 | 
			
		||||
stamp-tidy-marshal.h
 | 
			
		||||
stamp-h1
 | 
			
		||||
*.gmo
 | 
			
		||||
*.make
 | 
			
		||||
@@ -41,12 +44,11 @@ stamp-it
 | 
			
		||||
.intltool-merge-cache
 | 
			
		||||
POTFILES
 | 
			
		||||
po/*.pot
 | 
			
		||||
libmutter.pc
 | 
			
		||||
mutter
 | 
			
		||||
mutter-restart-helper
 | 
			
		||||
mutter-test-client
 | 
			
		||||
mutter-test-runner
 | 
			
		||||
mutter-all.test
 | 
			
		||||
50-metacity-desktop-key.xml
 | 
			
		||||
50-metacity-key.xml
 | 
			
		||||
libmutter-wayland.pc
 | 
			
		||||
mutter-wayland
 | 
			
		||||
mutter-launch
 | 
			
		||||
org.gnome.mutter.gschema.valid
 | 
			
		||||
org.gnome.mutter.gschema.xml
 | 
			
		||||
org.gnome.mutter.wayland.gschema.valid
 | 
			
		||||
@@ -54,7 +56,19 @@ org.gnome.mutter.wayland.gschema.xml
 | 
			
		||||
testasyncgetprop
 | 
			
		||||
testboxes
 | 
			
		||||
testgradient
 | 
			
		||||
m4/*
 | 
			
		||||
mutter-grayscale
 | 
			
		||||
mutter-mag
 | 
			
		||||
mutter-message
 | 
			
		||||
mutter-window-demo
 | 
			
		||||
focus-window
 | 
			
		||||
test-attached
 | 
			
		||||
test-focus
 | 
			
		||||
test-gravity
 | 
			
		||||
test-resizing
 | 
			
		||||
test-size-hints
 | 
			
		||||
# We can't say just "wm-tester" here or it will ignore the directory
 | 
			
		||||
# rather than the binary
 | 
			
		||||
src/wm-tester/wm-tester
 | 
			
		||||
INSTALL
 | 
			
		||||
mkinstalldirs
 | 
			
		||||
src/mutter-enum-types.[ch]
 | 
			
		||||
@@ -63,14 +77,13 @@ src/mutter-marshal.[ch]
 | 
			
		||||
src/stamp-mutter-marshal.h
 | 
			
		||||
src/meta-dbus-display-config.[ch]
 | 
			
		||||
src/meta-dbus-idle-monitor.[ch]
 | 
			
		||||
src/meta-dbus-login1.[ch]
 | 
			
		||||
src/mutter-plugins.pc
 | 
			
		||||
src/gtk-shell-protocol.c
 | 
			
		||||
src/gtk-shell-server-protocol.h
 | 
			
		||||
src/xdg-shell-protocol.c
 | 
			
		||||
src/xdg-shell-server-protocol.h
 | 
			
		||||
src/xserver-protocol.c
 | 
			
		||||
src/xserver-server-protocol.h
 | 
			
		||||
src/meta/meta-version.h
 | 
			
		||||
doc/reference/*.args
 | 
			
		||||
doc/reference/*.bak
 | 
			
		||||
doc/reference/*.hierarchy
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								Makefile.am
									
									
									
									
									
								
							@@ -1,13 +1,8 @@
 | 
			
		||||
 | 
			
		||||
SUBDIRS = data src po doc
 | 
			
		||||
SUBDIRS=src po doc
 | 
			
		||||
 | 
			
		||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
 | 
			
		||||
 | 
			
		||||
DISTCLEANFILES = \
 | 
			
		||||
	intltool-extract \
 | 
			
		||||
	intltool-merge \
 | 
			
		||||
	intltool-update \
 | 
			
		||||
	po/stamp-it \
 | 
			
		||||
	po/.intltool-merge-cache
 | 
			
		||||
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
 | 
			
		||||
 | 
			
		||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
 | 
			
		||||
 | 
			
		||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										330
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										330
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,333 +1,9 @@
 | 
			
		||||
3.16.1.1
 | 
			
		||||
========
 | 
			
		||||
* Prevent a crash when switching VTs or adding input devices [Carlos; #747886]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Carlos Garnacho
 | 
			
		||||
 | 
			
		||||
3.16.1
 | 
			
		||||
3.12.1
 | 
			
		||||
======
 | 
			
		||||
* Add function to refresh all background instances [Rui; #739178]
 | 
			
		||||
* Fix swapped scroll methods on wayland [Ondrej; #746870]
 | 
			
		||||
* Manually activate stage to fix accessibility on wayland [Ray, Rui; #746670]
 | 
			
		||||
* Center pointer on primary monitor on startup [Carlos; #746896]
 | 
			
		||||
* wayland: Reword synchronized state application semantics [Jonas; #743617]
 | 
			
		||||
* Ensure input settings are applied on startup [Rui; #747434]
 | 
			
		||||
* Misc. bug fixes [Jonas, Giovanni, Calvin, Ray, Rui; #744932, #746509, #746692,
 | 
			
		||||
  #746510, #746545, #747263]
 | 
			
		||||
* Fix crash when running as X11 compositor [Adel; #727115]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Giovanni Campagna, Carlos Garnacho, Ondrej Holy, Rui Matos,
 | 
			
		||||
  Jasper St. Pierre, Ray Strode, Calvin Walton
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Khaled Hosny [ar], Marek Černocký [cs]
 | 
			
		||||
 | 
			
		||||
3.16.0
 | 
			
		||||
======
 | 
			
		||||
* wayland: Don't skip notifying about initial maximized state [Jonas; #745303]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Kjartan Maraas [nb], Jiri Grönroos [fi], Andika Triwidada [id],
 | 
			
		||||
  Inaki Larranaga Murgoitio [eu], Ask H. Larsen [da], Muhammet Kara [tr]
 | 
			
		||||
 | 
			
		||||
3.15.92
 | 
			
		||||
=======
 | 
			
		||||
* Ensure pointer visibility on monitor changes [Rui, Marek; #745121, #745752]
 | 
			
		||||
* Fix geometry of shaded windows [Florian; #746145]
 | 
			
		||||
* Take over cursor visibility handling from gsd [Carlos; #712775]
 | 
			
		||||
* Fix touch interaction on window decorations [Carlos; #745335]
 | 
			
		||||
* Add options for libinput_config_click_method [Carlos; #746290]
 | 
			
		||||
* Scale window decorations on HiDPI displays [Florian; #744354]
 | 
			
		||||
* Misc. bug fixes [Carlos, Ray, Rui; #745163, #746295, #746098, #745734]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Marek Chalupa, Carlos Garnacho, Rui Matos, Florian Müllner,
 | 
			
		||||
  Jasper St. Pierre, Ray Strode
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Piotr Drąg [pl], Milo Casagrande [it], Changwoo Ryu [ko],
 | 
			
		||||
  Daniel Korostil [uk], Baurzhan Muftakhidinov [kk], Trần Ngọc Quân [vi],
 | 
			
		||||
  Alexander Shopov [bg], Jordi Mas [ca], Samir Ribic [bs], A S Alam [pa],
 | 
			
		||||
  Matej Urbančič [sl]
 | 
			
		||||
 | 
			
		||||
3.15.91
 | 
			
		||||
=======
 | 
			
		||||
* wayland: Fix nested compositor mode [Jonas; #745401]
 | 
			
		||||
* wayland: Fix pointer constraining [Marek; #727337]
 | 
			
		||||
* wayland: Fix input region on HiDPI [Jonas; #744933]
 | 
			
		||||
* Allow themes to style buttons differently based on function [Horst; #745108]
 | 
			
		||||
* Misc. bug fixes and cleanups [Ray, Rui, Alban; #745141, #745118, #745476,
 | 
			
		||||
  #745442]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Alban Browaeys, Marek Chalupa, Horst, Rui Matos,
 | 
			
		||||
  Jasper St. Pierre, Ray Strode
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Chao-Hsiung Liao [zh_TW], Efstathios Iosifidis [el], Dušan Kazik [sk],
 | 
			
		||||
  Balázs Úr [hu], Daniel Mustieles [es], Claude Paroz [fr], Stas Solovey [ru],
 | 
			
		||||
  Yosef Or Boczko [he], Rafael Ferreira [pt_BR], Aurimas Černius [lt],
 | 
			
		||||
  Fran Dieguez [gl], Anders Jonsson [sv], Мирослав Николић [sr, sr@latin]
 | 
			
		||||
 | 
			
		||||
3.15.90
 | 
			
		||||
=======
 | 
			
		||||
* Initialize MetaOutput even when we can't get the EDID [Rui; #743412]
 | 
			
		||||
* Expose MetaMonitorManager to introspection [Rui; #743745]
 | 
			
		||||
* Fix flash on unredirection [Chris; #743858]
 | 
			
		||||
* Update xdg-shell implementation to v5 [Jonas; #744452]
 | 
			
		||||
* Do not try to use seat devices that aren't (yet) present [Ray; #744640]
 | 
			
		||||
* Add keybindings for switching to VT8-VT12 [Ray; #744800]
 | 
			
		||||
* Misc bug fixes [Jonas, Cosimo; #743678, #744500]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Jasper St. Pierre,
 | 
			
		||||
  Ray Strode, Chris Wilson
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Yosef Or Boczko [he], Yuri Myasoedov [ru], Kristjan SCHMIDT [eo],
 | 
			
		||||
  Matej Urbančič [sl], Dušan Kazik [sk]
 | 
			
		||||
 | 
			
		||||
3.15.4
 | 
			
		||||
======
 | 
			
		||||
* Use GTK+ theme for window decorations instead of metacity [Florian; #741917]
 | 
			
		||||
* Export the same EDID information on X11 and wayland [Carlos; #742882]
 | 
			
		||||
* Apply input device configuration on wayland [Carlos; #739397]
 | 
			
		||||
* Implement pointer barriers on wayland [Jonas; #706655]
 | 
			
		||||
* Misc. bug fixes (Ting-Wei, Rui, Ikey, Florian, Marek, Jonas; #741829,
 | 
			
		||||
  #738630, #737463, #698995, #727893, #742825, #742824, #742841, #743173,
 | 
			
		||||
  #743189, #743217, #743254]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Giovanni Campagna, Marek Chalupa, Ikey Doherty, Adel Gadllah,
 | 
			
		||||
  Carlos Garnacho, Ting-Wei Lan, Rui Matos, Florian Müllner, Jasper St. Pierre,
 | 
			
		||||
  Rico Tzschichholz
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Matej Urbančič [sl], Balázs Úr [hu], Marek Černocký [cs],
 | 
			
		||||
  Inaki Larranaga Murgoitio [eu], Rafael Ferreira [pt_BR],
 | 
			
		||||
  Daniel Mustieles [es], Fran Dieguez [gl]
 | 
			
		||||
 | 
			
		||||
3.15.3
 | 
			
		||||
======
 | 
			
		||||
* Don't leave left-over frames queued [Owen; #738686]
 | 
			
		||||
* Set CRTC configuration even if it might be redundant [Rui; #740838]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Rui Matos, Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Trần Ngọc Quân [vi], Muhammet Kara [tr]
 | 
			
		||||
 | 
			
		||||
3.15.2
 | 
			
		||||
======
 | 
			
		||||
* Don't enable hiDPI on monitors with broken EDID [Bastien; #734839]
 | 
			
		||||
* Prevent crash applying monitor config for a closed lid [Rui; #739450]
 | 
			
		||||
* Fix "flicker" during startup transition [Ray; #740377]
 | 
			
		||||
* Misc. bug fixes [Lan, Florian, Carlos; #731521, #740133, #738890]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Emmanuele Bassi, Carlos Garnacho, Jonathon Jongsma, Ting-Wei Lan, Rui Matos,
 | 
			
		||||
  Florian Müllner, Bastien Nocera, Jasper St. Pierre, Ray Strode
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Kjartan Maraas [nb]
 | 
			
		||||
 | 
			
		||||
3.15.1
 | 
			
		||||
======
 | 
			
		||||
* Use GResources for theme loading [Cosimo; #736936]
 | 
			
		||||
* Fix headerbar drag getting stuck on xwayland [Carlos; #738411]
 | 
			
		||||
* Fix wayland hiDPI regressions [Adel; #739161]
 | 
			
		||||
* Misc bug fixes and cleanups [Jasper, Rui, Carlos; #662962, #738630, #738888,
 | 
			
		||||
  #738890]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Cosimo Cecchi, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner,
 | 
			
		||||
  Jasper St. Pierre
 | 
			
		||||
 | 
			
		||||
3.14.1
 | 
			
		||||
======
 | 
			
		||||
* Fix move-titlebar-onscreen function [Florian; #736915]
 | 
			
		||||
* Fix stacking of the guard window [Owen; #737233]
 | 
			
		||||
* Fix keycode lookup for non-default layouts [Rui; #737134]
 | 
			
		||||
* Fix workspaces-only-on-primary handling [Florian; #737178]
 | 
			
		||||
* Don't unstick sticky windows on workspace removal [Florian; #737625]
 | 
			
		||||
* Do not auto-minimize fullscreen windows [Jasper; #705177]
 | 
			
		||||
* Upload keymap to newly added keyboard devices [Rui; #737673]
 | 
			
		||||
* Apply keyboard repeat settings [Rui; #728055]
 | 
			
		||||
* Don't send pressed keys on enter [Rui; #727178]
 | 
			
		||||
* Fix build without wayland/native [Rico; #738225]
 | 
			
		||||
* Send modifiers after the key event [Rui; #738238]
 | 
			
		||||
* Fix unredirect heuristic [Adel; #738271]
 | 
			
		||||
* Do not show system chrome over fullscreen windows [Florian; #693991]
 | 
			
		||||
* Misc. bug fixes [Florian, Adel, Tom; #737135, #737581, #738146, #738384]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Tom Beckmann, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner,
 | 
			
		||||
  Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Krishnababu Krothapalli [te], Мирослав Николић [sr, sr@latin],
 | 
			
		||||
  Alexander Shopov [bg], Saibal Ray [bn_IN], Milo Casagrande [it],
 | 
			
		||||
  Rūdolfs Mazurs [lv]
 | 
			
		||||
 | 
			
		||||
3.14.0
 | 
			
		||||
======
 | 
			
		||||
* Fix placement of popup windows on wayland [Jasper; #736812]
 | 
			
		||||
* Only increment serial once per event [Jasper; #736840]
 | 
			
		||||
* Fix window positioning regression with non-GTK+ toolkits [Owen; #736719]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jasper St. Pierre, Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Saibal Ray [bn_IN], Dušan Kazik [sk], Manoj Kumar Giri [or],
 | 
			
		||||
  Christian Kirbach [de], Ask H. Larsen [da], YunQiang Su [zh_CN],
 | 
			
		||||
  Bernd Homuth [de], Shankar Prasad [kn], Petr Kovar [cs], Rajesh Ranjan [hi]
 | 
			
		||||
 | 
			
		||||
3.13.92
 | 
			
		||||
=======
 | 
			
		||||
* Rewrite background code [Owen; #735637, #736568]
 | 
			
		||||
* Fix size in nested mode [Owen; #736279]
 | 
			
		||||
* Fix destroy animation of background windows [Florian; #735927]
 | 
			
		||||
* Wire keymap changes up to the wayland frontend [Rui; #736433]
 | 
			
		||||
* Add a test framework and stacking tests [Owen; #736505]
 | 
			
		||||
* Simplify handling of the merged X and wayland stack [Owen; #736559]
 | 
			
		||||
* Fix cursor size on HiDPI [Adel; #729337]
 | 
			
		||||
* Misc. bug fixes [Owen; #735632, #736589, #736694]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Adel Gadllah, Rui Matos, Florian Müllner, Jasper St. Pierre, Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Andika Triwidada [id], Piotr Drąg [pl], Changwoo Ryu [ko],
 | 
			
		||||
  Kjartan Maraas [nb], Ville-Pekka Vainio [fi], Yuri Myasoedov [ru],
 | 
			
		||||
  Aurimas Černius [lt], Balázs Úr [hu], Sweta Kothari [gu], A S Alam [pa],
 | 
			
		||||
  Sandeep Sheshrao Shedmake [mr], Shantha kumar [ta], Gil Forcada [ca],
 | 
			
		||||
  Carles Ferrando [ca@valencia], Mattias Eriksson [sv]
 | 
			
		||||
 | 
			
		||||
3.13.91
 | 
			
		||||
=======
 | 
			
		||||
* Misc. bug fixes [Carlos; #735452]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Adel Gadllah, Carlos Garnacho, Rui Matos, Jasper St. Pierre,
 | 
			
		||||
  Rico Tzschichholz
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Chao-Hsiung Liao po/zh_HK, zh_TW.po, Enrico Nicoletto [pt_BR],
 | 
			
		||||
  Kjartan Maraas [nb], Fran Diéguez [gl], Yosef Or Boczko [he],
 | 
			
		||||
  Maria  Mavridou [el], Claude Paroz [fr]
 | 
			
		||||
 | 
			
		||||
3.13.90
 | 
			
		||||
=======
 | 
			
		||||
* Only call XSync() once per frame [Rui; #728464]
 | 
			
		||||
* Update capabilities on device list changes [Carlos; #733563]
 | 
			
		||||
* Make use of GLSL optional [Adel; #733623]
 | 
			
		||||
* Handle gestures and touch events on wayland [Carlos; #733631]
 | 
			
		||||
* Add support for unminimize compositor effects [Cosimo; #733789]
 | 
			
		||||
* Always set the frame background to None [Giovanni; #734054]
 | 
			
		||||
* Add backend methods to handle keymaps [Rui; #734301]
 | 
			
		||||
* Actually mark revalidated MetaTextureTower levels as valid [Owen; #734400]
 | 
			
		||||
* Rely on explicit -backward switcher keybindings instead of <shift>-magic
 | 
			
		||||
  [Christophe; #732295, #732385]
 | 
			
		||||
* Misc. bug fixes and cleanups [Rui, Adel, Christophe; #727178, #734852,
 | 
			
		||||
  #734960]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Emmanuele Bassi, Giovanni Campagna, Cosimo Cecchi, Piotr Drąg,
 | 
			
		||||
  Christophe Fergeau, Adel Gadllah, Carlos Garnacho, Rui Matos,
 | 
			
		||||
  Florian Müllner, Jasper St. Pierre, Rico Tzschichholz, Olav Vitters,
 | 
			
		||||
  Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Kjartan Maraas [nb], Inaki Larranaga Murgoitio [eu], Lasse Liehu [fi],
 | 
			
		||||
  ngoswami [as], Daniel Mustieles [es]
 | 
			
		||||
 | 
			
		||||
3.13.4
 | 
			
		||||
======
 | 
			
		||||
* Fix move/resize operations for wayland clients [Marek; #731237]
 | 
			
		||||
* Add ::first-frame signal to MetaWindowActor [Owen; #732343]
 | 
			
		||||
* Handle keysyms without the XF86 prefix [Owen; #727993]
 | 
			
		||||
* Add touch gesture support [Carlos]
 | 
			
		||||
* Fix a deadlock when exiting [Owen; #733068]
 | 
			
		||||
* Add framework for restarting the compositor with nice visuals
 | 
			
		||||
  [Owen; #733026]
 | 
			
		||||
* Toggle seat capabilities on VT switch [Carlos; #733563]
 | 
			
		||||
* Misc bug fixes [Florian, Owen; #732695, #732350]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Tom Beckmann, Giovanni Campagna, Marek Chalupa, Adel Gadllah,
 | 
			
		||||
  Carlos Garnacho, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz,
 | 
			
		||||
  Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Yuri Myasoedov [ru], Fran Diéguez [gl], Aurimas Černius [lt], MarMav [el],
 | 
			
		||||
  Enrico Nicoletto [pt_BR]
 | 
			
		||||
 | 
			
		||||
3.13.3
 | 
			
		||||
======
 | 
			
		||||
* Improve behavior of window buttons with compositor menus [Florian; #731058]
 | 
			
		||||
* Implement touch support on wayland [Carlos; #724442]
 | 
			
		||||
* Update window shadows [Nikita; #731866]
 | 
			
		||||
* Keep windows on the preferred output [Florian; #731760]
 | 
			
		||||
* Misc bug fixes [Jonas, Florian, Jasper; #729601, #730681, #731353, #731332,
 | 
			
		||||
  #730527, #662962]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Nikita Churaev, Carlos Garnacho, Florian Müllner,
 | 
			
		||||
  Jasper St. Pierre, Rico Tzschichholz
 | 
			
		||||
 | 
			
		||||
3.13.2
 | 
			
		||||
======
 | 
			
		||||
* Add basic HiDPI support on wayland [Adel; #728902]
 | 
			
		||||
* Fix crash when monitors change during suspend [Giovanni; #725637]
 | 
			
		||||
* Replace mutter-launch with logind integration [Jasper; #724604]
 | 
			
		||||
* Move window menu into the compositor [Jasper; #726352]
 | 
			
		||||
* Fix delayed focus-follows-mouse support [Florian; #730541]
 | 
			
		||||
* Support fallback app menu in window decorations [Florian; #730752]
 | 
			
		||||
* Misc. bug fixes and cleanups [Giovanni, Jonas, Jasper; #729732, #729602,
 | 
			
		||||
  #726714]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Giovanni Campagna, Adel Gadllah, Florian Müllner,
 | 
			
		||||
  Jasper St. Pierre, Rico Tzschichholz
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Pau Iranzo [ca], Daniel Mustieles [es]
 | 
			
		||||
 | 
			
		||||
3.13.1
 | 
			
		||||
======
 | 
			
		||||
* Fix opacity values from _NET_WM_WINDOW_OPACITY [Nirbheek; #727874]
 | 
			
		||||
* Merge wayland branch [Jasper, Giovanni, Robert B., Neil, Adel, Rui, Jonas,
 | 
			
		||||
  Lionel, Tim, Owen, Florian, Colin W., Cosimo, Ray, Kalev, Pavel, Robert A.,
 | 
			
		||||
  Magdalen, Marek, Matthias, Alban, Seán, Daniel, Stefano, Carlos, Colin G.,
 | 
			
		||||
  Andreas, Alexander, Ryan, Marc-André, Asad, Alberto, Bastien, Hans,
 | 
			
		||||
  Debarshi, Sindhu, Andika, Rico, Olav]
 | 
			
		||||
* Don't prevent workspace switches for present_with_time() [Florian; #728018]
 | 
			
		||||
* Add shortcuts for switching to the last workspace [Elad; #659288]
 | 
			
		||||
* Make move/resize menu items behave like the keybindings [Jasper; #728617]
 | 
			
		||||
* Misc. bug fixes and cleanups  [Jasper, Bastien, Florian, Adel; #720631,
 | 
			
		||||
  #727979, #728423, #728395, #729044]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Elad Alfassa, Robert Ancell, Magdalen Berns, Robert Bragg,
 | 
			
		||||
  Giovanni Campagna, Cosimo Cecchi, Marek Chalupa, Nirbheek Chauhan,
 | 
			
		||||
  Matthias Clasen, Alban Crequy, Seán de Búrca, Daniel Drake, Jason Ekstrand,
 | 
			
		||||
  Stefano Facchini, Adel Gadllah, Carlos Garnacho, Colin Guthrie,
 | 
			
		||||
  Andreas Heider, Lionel Landwerlin, Alexander Larsson, Kalev Lember,
 | 
			
		||||
  Ryan Lortie, Tim Lunn, Marc-André Lureau, Rui Matos, Asad Mehmood,
 | 
			
		||||
  Alberto Milone, Florian Müllner, Bastien Nocera, Hans Petter Jansson,
 | 
			
		||||
  Debarshi Ray, Neil Roberts, Sindhu S, Jasper St. Pierre, Ray Strode,
 | 
			
		||||
  Andika Triwidada, Rico Tzschichholz, Pavel Vasin, Olav Vitters,
 | 
			
		||||
  Colin Walters, A. Walton, Owen W. Taylor
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Inaki Larranaga Murgoitio [eu], marablack3 [el], Daniel Mustieles [es],
 | 
			
		||||
  Fran Diéguez [gl], Yosef Or Boczko [he], Dirgita [id]
 | 
			
		||||
  Matthias Clasen, Adel Gadllah, Florian Müllner, Jasper St. Pierre
 | 
			
		||||
 | 
			
		||||
3.12.0
 | 
			
		||||
======
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,8 @@
 | 
			
		||||
srcdir=`dirname $0`
 | 
			
		||||
test -z "$srcdir" && srcdir=.
 | 
			
		||||
 | 
			
		||||
REQUIRED_AUTOMAKE_VERSION=1.11
 | 
			
		||||
PKG_NAME="mutter"
 | 
			
		||||
REQUIRED_AUTOMAKE_VERSION=1.10
 | 
			
		||||
 | 
			
		||||
(test -f $srcdir/configure.ac \
 | 
			
		||||
  && test -d $srcdir/src) || {
 | 
			
		||||
@@ -18,4 +19,4 @@ which gnome-autogen.sh || {
 | 
			
		||||
    echo "your distribution's package manager)."
 | 
			
		||||
    exit 1
 | 
			
		||||
}
 | 
			
		||||
. gnome-autogen.sh
 | 
			
		||||
USE_GNOME2_MACROS=1 USE_COMMON_DOC_BUILD=yes . gnome-autogen.sh
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										202
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										202
									
								
								configure.ac
									
									
									
									
									
								
							@@ -1,8 +1,9 @@
 | 
			
		||||
AC_PREREQ(2.62)
 | 
			
		||||
AC_PREREQ(2.50)
 | 
			
		||||
AC_CONFIG_MACRO_DIR([m4])
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_major_version], [3])
 | 
			
		||||
m4_define([mutter_minor_version], [16])
 | 
			
		||||
m4_define([mutter_micro_version], [1.1])
 | 
			
		||||
m4_define([mutter_minor_version], [12])
 | 
			
		||||
m4_define([mutter_micro_version], [1])
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_version],
 | 
			
		||||
          [mutter_major_version.mutter_minor_version.mutter_micro_version])
 | 
			
		||||
@@ -12,8 +13,6 @@ m4_define([mutter_plugin_api_version], [3])
 | 
			
		||||
AC_INIT([mutter], [mutter_version],
 | 
			
		||||
        [http://bugzilla.gnome.org/enter_bug.cgi?product=mutter])
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_MACRO_DIR([m4])
 | 
			
		||||
AC_CONFIG_AUX_DIR([build-aux])
 | 
			
		||||
AC_CONFIG_SRCDIR(src/core/display.c)
 | 
			
		||||
AC_CONFIG_HEADERS(config.h)
 | 
			
		||||
 | 
			
		||||
@@ -21,6 +20,10 @@ AM_INIT_AUTOMAKE([1.11 foreign no-dist-gzip dist-xz tar-ustar subdir-objects])
 | 
			
		||||
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
 | 
			
		||||
AM_MAINTAINER_MODE([enable])
 | 
			
		||||
 | 
			
		||||
# Change pkglibdir and pkgdatadir to mutter-wayland instead of mutter
 | 
			
		||||
PACKAGE="mutter-wayland"
 | 
			
		||||
AC_SUBST([PACKAGE], [$PACKAGE])
 | 
			
		||||
 | 
			
		||||
MUTTER_MAJOR_VERSION=mutter_major_version
 | 
			
		||||
MUTTER_MINOR_VERSION=mutter_minor_version
 | 
			
		||||
MUTTER_MICRO_VERSION=mutter_micro_version
 | 
			
		||||
@@ -36,18 +39,16 @@ AC_SUBST(MUTTER_PLUGIN_DIR)
 | 
			
		||||
# Honor aclocal flags
 | 
			
		||||
AC_SUBST(ACLOCAL_AMFLAGS, "\${ACLOCAL_FLAGS}")
 | 
			
		||||
 | 
			
		||||
GETTEXT_PACKAGE=mutter
 | 
			
		||||
GETTEXT_PACKAGE=mutter-wayland
 | 
			
		||||
AC_SUBST(GETTEXT_PACKAGE)
 | 
			
		||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Name of default gettext domain])
 | 
			
		||||
 | 
			
		||||
LT_PREREQ([2.2.6])
 | 
			
		||||
LT_INIT([disable-static])
 | 
			
		||||
IT_PROG_INTLTOOL([0.41])
 | 
			
		||||
IT_PROG_INTLTOOL([0.34.90])
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
AC_PROG_CC_C_O
 | 
			
		||||
AC_PROG_INSTALL
 | 
			
		||||
AC_ISC_POSIX
 | 
			
		||||
AC_HEADER_STDC
 | 
			
		||||
PKG_PROG_PKG_CONFIG([0.21])
 | 
			
		||||
AC_LIBTOOL_WIN32_DLL
 | 
			
		||||
AM_PROG_LIBTOOL
 | 
			
		||||
 | 
			
		||||
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
 | 
			
		||||
AM_PATH_GLIB_2_0()
 | 
			
		||||
@@ -71,28 +72,16 @@ CANBERRA_GTK_VERSION=0.26
 | 
			
		||||
CLUTTER_PACKAGE=clutter-1.0
 | 
			
		||||
 | 
			
		||||
MUTTER_PC_MODULES="
 | 
			
		||||
   gtk+-3.0 >= 3.9.11
 | 
			
		||||
   gio-unix-2.0 >= 2.35.1
 | 
			
		||||
   gtk+-3.0 >= 3.3.7
 | 
			
		||||
   gio-2.0 >= 2.25.10
 | 
			
		||||
   pango >= 1.2.0
 | 
			
		||||
   cairo >= 1.10.0
 | 
			
		||||
   gsettings-desktop-schemas >= 3.15.92
 | 
			
		||||
   $CLUTTER_PACKAGE >= 1.21.3
 | 
			
		||||
   gsettings-desktop-schemas >= 3.7.3
 | 
			
		||||
   xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
 | 
			
		||||
   $CLUTTER_PACKAGE >= 1.17.5
 | 
			
		||||
   cogl-1.0 >= 1.17.1
 | 
			
		||||
   upower-glib >= 0.99.0
 | 
			
		||||
   gnome-desktop-3.0
 | 
			
		||||
   xcomposite >= 0.2
 | 
			
		||||
   xcursor
 | 
			
		||||
   xdamage
 | 
			
		||||
   xext
 | 
			
		||||
   xfixes
 | 
			
		||||
   xi >= 1.6.0
 | 
			
		||||
   xkbfile
 | 
			
		||||
   xkeyboard-config
 | 
			
		||||
   xkbcommon >= 0.4.3
 | 
			
		||||
   xkbcommon-x11
 | 
			
		||||
   xrender
 | 
			
		||||
   x11-xcb
 | 
			
		||||
   xcb-randr
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
GLIB_GSETTINGS
 | 
			
		||||
@@ -121,18 +110,37 @@ AC_ARG_WITH(libcanberra,
 | 
			
		||||
                 [disable the use of libcanberra for playing sounds]),,
 | 
			
		||||
  with_libcanberra=auto)
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(xsync,
 | 
			
		||||
  AC_HELP_STRING([--disable-xsync],
 | 
			
		||||
                 [disable mutter's use of the XSync extension]),,
 | 
			
		||||
  enable_xsync=auto)
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(shape,
 | 
			
		||||
  AC_HELP_STRING([--disable-shape],
 | 
			
		||||
                 [disable mutter's use of the shaped window extension]),,
 | 
			
		||||
  enable_shape=auto)
 | 
			
		||||
 | 
			
		||||
## Wayland support requires the xserver.xml protocol extension found in the weston
 | 
			
		||||
## repository but since there aren't currently established conventions for
 | 
			
		||||
## installing and discovering these we simply require a location to be given
 | 
			
		||||
## explicitly...
 | 
			
		||||
AC_ARG_WITH([wayland-protocols],
 | 
			
		||||
            [AS_HELP_STRING([--with-wayland-protocols], [Location for wayland extension protocol specs])],
 | 
			
		||||
            [
 | 
			
		||||
            ],
 | 
			
		||||
            [])
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH([xwayland-path],
 | 
			
		||||
            [AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])],
 | 
			
		||||
            [XWAYLAND_PATH="$withval"],
 | 
			
		||||
            [XWAYLAND_PATH="$bindir/Xwayland"])
 | 
			
		||||
            [XWAYLAND_PATH="$bindir/Xorg"])
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(installed_tests,
 | 
			
		||||
              AS_HELP_STRING([--enable-installed-tests],
 | 
			
		||||
                             [Install test programs (default: no)]),,
 | 
			
		||||
              [enable_installed_tests=no])
 | 
			
		||||
AM_CONDITIONAL(BUILDOPT_INSTALL_TESTS, test x$enable_installed_tests = xyes)
 | 
			
		||||
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)
 | 
			
		||||
PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login)
 | 
			
		||||
 | 
			
		||||
# Unconditionally use this dir to avoid a circular dep with gnomecc
 | 
			
		||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
 | 
			
		||||
@@ -197,44 +205,17 @@ if test x$found_introspection != xno; then
 | 
			
		||||
  AC_SUBST(META_GIR)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcursor"
 | 
			
		||||
 | 
			
		||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
 | 
			
		||||
AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
 | 
			
		||||
  AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols]))
 | 
			
		||||
AC_SUBST([WAYLAND_SCANNER])
 | 
			
		||||
AC_SUBST(XWAYLAND_PATH)
 | 
			
		||||
 | 
			
		||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server libdrm"
 | 
			
		||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
 | 
			
		||||
 | 
			
		||||
MUTTER_NATIVE_BACKEND_MODULES="clutter-egl-1.0 libdrm libsystemd libinput gudev-1.0 gbm >= 10.3"
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(native-backend,
 | 
			
		||||
  AS_HELP_STRING([--disable-native-backend], [disable mutter native (KMS) backend]),,
 | 
			
		||||
  enable_native_backend=auto
 | 
			
		||||
)
 | 
			
		||||
AS_IF([test "$enable_native_backend" = "yes"], [have_native_backend=yes],
 | 
			
		||||
      [test "$enable_native_backend" = "auto"], PKG_CHECK_EXISTS([$MUTTER_NATIVE_BACKEND_MODULES], [have_native_backend=yes]))
 | 
			
		||||
 | 
			
		||||
AS_IF([test "$have_native_backend" = "yes"], [
 | 
			
		||||
  PKG_CHECK_MODULES([MUTTER_NATIVE_BACKEND], [$MUTTER_NATIVE_BACKEND_MODULES])
 | 
			
		||||
  AC_DEFINE([HAVE_NATIVE_BACKEND],[1], [Define if you want to enable the native (KMS) backend based on systemd])
 | 
			
		||||
])
 | 
			
		||||
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test "$have_native_backend" = "yes"])
 | 
			
		||||
 | 
			
		||||
MUTTER_WAYLAND_MODULES="clutter-wayland-1.0 clutter-wayland-compositor-1.0 wayland-server >= 1.6.90"
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(wayland,
 | 
			
		||||
  AS_HELP_STRING([--disable-wayland], [disable mutter on wayland support]),,
 | 
			
		||||
  enable_wayland=auto
 | 
			
		||||
)
 | 
			
		||||
AS_IF([test "$enable_wayland" = "yes"], [have_wayland=yes],
 | 
			
		||||
      [test "$enable_wayland" = "auto"], PKG_CHECK_EXISTS([$MUTTER_WAYLAND_MODULES], [have_wayland=yes]))
 | 
			
		||||
 | 
			
		||||
AS_IF([test "$have_wayland" = "yes"], [
 | 
			
		||||
  PKG_CHECK_MODULES([MUTTER_WAYLAND], [$MUTTER_WAYLAND_MODULES])
 | 
			
		||||
  AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
 | 
			
		||||
  AS_IF([test $WAYLAND_SCANNER = "no"],
 | 
			
		||||
    [AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])])
 | 
			
		||||
  AC_SUBST([WAYLAND_SCANNER])
 | 
			
		||||
  AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
 | 
			
		||||
])
 | 
			
		||||
AM_CONDITIONAL([HAVE_WAYLAND],[test "$have_wayland" = "yes"])
 | 
			
		||||
 | 
			
		||||
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
 | 
			
		||||
                 AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))
 | 
			
		||||
 | 
			
		||||
@@ -271,8 +252,38 @@ if test x$have_xinerama = xno; then
 | 
			
		||||
   AC_MSG_ERROR([Xinerama extension was not found])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_DEFINE_UNQUOTED([XKB_BASE], ["`$PKG_CONFIG --variable xkb_base xkeyboard-config`"],
 | 
			
		||||
                               [XKB base dir])
 | 
			
		||||
SHAPE_LIBS=
 | 
			
		||||
found_shape=no
 | 
			
		||||
AC_CHECK_LIB(Xext, XShapeQueryExtension,
 | 
			
		||||
               [AC_CHECK_HEADER(X11/extensions/shape.h,
 | 
			
		||||
                                SHAPE_LIBS=-lXext found_shape=yes)],
 | 
			
		||||
               , $ALL_X_LIBS)
 | 
			
		||||
 | 
			
		||||
if test x$enable_shape = xno; then
 | 
			
		||||
   found_shape=no
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test x$enable_shape = xyes; then
 | 
			
		||||
   if test "$found_shape" = "no"; then
 | 
			
		||||
      AC_MSG_ERROR([--enable-shape forced and Shape not found])
 | 
			
		||||
      exit 1
 | 
			
		||||
   fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test "x$found_shape" = "xyes"; then
 | 
			
		||||
   AC_DEFINE(HAVE_SHAPE, , [Have the shape extension library])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
found_xkb=no
 | 
			
		||||
AC_CHECK_LIB(X11, XkbQueryExtension,
 | 
			
		||||
               [AC_CHECK_HEADER(X11/XKBlib.h,
 | 
			
		||||
                                found_xkb=yes)],
 | 
			
		||||
	, $ALL_X_LIBS)
 | 
			
		||||
 | 
			
		||||
if test "x$found_xkb" = "xyes"; then
 | 
			
		||||
   AC_DEFINE(HAVE_XKB, , [Have keyboard extension library])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
RANDR_LIBS=
 | 
			
		||||
found_randr=no
 | 
			
		||||
@@ -280,13 +291,37 @@ AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration,
 | 
			
		||||
               [AC_CHECK_HEADER(X11/extensions/Xrandr.h,
 | 
			
		||||
                                RANDR_LIBS=-lXrandr found_randr=yes,,
 | 
			
		||||
				[#include <X11/Xlib.h>])],
 | 
			
		||||
               , -lXext $ALL_X_LIBS)
 | 
			
		||||
               , -lXrender -lXext $ALL_X_LIBS)
 | 
			
		||||
 | 
			
		||||
if test "x$found_randr" = "xyes"; then
 | 
			
		||||
   AC_DEFINE(HAVE_RANDR, , [Have the Xrandr extension library])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
MUTTER_LIBS="$MUTTER_LIBS $RANDR_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
 | 
			
		||||
XSYNC_LIBS=
 | 
			
		||||
found_xsync=no
 | 
			
		||||
AC_CHECK_LIB(Xext, XSyncQueryExtension,
 | 
			
		||||
               [AC_CHECK_HEADER(X11/extensions/sync.h,
 | 
			
		||||
                                found_xsync=yes,,
 | 
			
		||||
				[#include <X11/Xlib.h>])],
 | 
			
		||||
               , $ALL_X_LIBS)
 | 
			
		||||
 | 
			
		||||
if test x$enable_xsync = xno; then
 | 
			
		||||
   found_xsync=no
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test x$enable_xsync = xyes; then
 | 
			
		||||
   if test "$found_xsync" = "no"; then
 | 
			
		||||
      AC_MSG_ERROR([--enable-xsync forced and XSync not found])
 | 
			
		||||
      exit 1
 | 
			
		||||
   fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test "x$found_xsync" = "xyes"; then
 | 
			
		||||
   XSYNC_LIBS=-lXext
 | 
			
		||||
   AC_DEFINE(HAVE_XSYNC, , [Have the Xsync extension library])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
MUTTER_LIBS="$MUTTER_LIBS $XSYNC_LIBS $RANDR_LIBS $SHAPE_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
 | 
			
		||||
 | 
			
		||||
found_sm=no
 | 
			
		||||
case "$MUTTER_LIBS" in
 | 
			
		||||
@@ -318,6 +353,17 @@ fi
 | 
			
		||||
 | 
			
		||||
AM_CONDITIONAL(HAVE_SM, test "$found_sm" = "yes")
 | 
			
		||||
 | 
			
		||||
HOST_ALIAS=$host_alias
 | 
			
		||||
AC_SUBST(HOST_ALIAS)
 | 
			
		||||
 | 
			
		||||
AC_PATH_PROG(GDK_PIXBUF_CSOURCE, gdk-pixbuf-csource, no)
 | 
			
		||||
 | 
			
		||||
if test x"$GDK_PIXBUF_CSOURCE" = xno; then
 | 
			
		||||
  AC_MSG_ERROR([gdk-pixbuf-csource executable not found in your path - should be installed with GTK])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
AC_SUBST(GDK_PIXBUF_CSOURCE)
 | 
			
		||||
 | 
			
		||||
AC_PATH_PROG(ZENITY, zenity, no)
 | 
			
		||||
if test x"$ZENITY" = xno; then
 | 
			
		||||
  AC_MSG_ERROR([zenity not found in your path - needed for dialogs])
 | 
			
		||||
@@ -400,15 +446,13 @@ changequote([,])dnl
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_FILES([
 | 
			
		||||
Makefile
 | 
			
		||||
data/Makefile
 | 
			
		||||
doc/Makefile
 | 
			
		||||
doc/man/Makefile
 | 
			
		||||
doc/reference/Makefile
 | 
			
		||||
doc/reference/meta-docs.sgml
 | 
			
		||||
src/Makefile
 | 
			
		||||
src/libmutter.pc
 | 
			
		||||
src/libmutter-wayland.pc
 | 
			
		||||
src/compositor/plugins/Makefile
 | 
			
		||||
src/meta/meta-version.h
 | 
			
		||||
po/Makefile.in
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
@@ -424,7 +468,7 @@ fi
 | 
			
		||||
 | 
			
		||||
dnl ==========================================================================
 | 
			
		||||
echo "
 | 
			
		||||
mutter-$VERSION
 | 
			
		||||
mutter-wayland-$VERSION
 | 
			
		||||
 | 
			
		||||
	prefix:                   ${prefix}
 | 
			
		||||
	source code location:	  ${srcdir}
 | 
			
		||||
@@ -434,8 +478,8 @@ mutter-$VERSION
 | 
			
		||||
	libcanberra:              ${have_libcanberra}
 | 
			
		||||
	Introspection:            ${found_introspection}
 | 
			
		||||
	Session management:       ${found_sm}
 | 
			
		||||
	Wayland:                  ${have_wayland}
 | 
			
		||||
	Native (KMS) backend:     ${have_native_backend}
 | 
			
		||||
	Shape extension:          ${found_shape}
 | 
			
		||||
	Xsync:                    ${found_xsync}
 | 
			
		||||
"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
desktopfiles_in_files = \
 | 
			
		||||
	mutter.desktop.in \
 | 
			
		||||
	mutter-wayland.desktop.in
 | 
			
		||||
desktopfilesdir = $(datadir)/applications
 | 
			
		||||
desktopfiles_DATA = $(desktopfiles_in_files:.desktop.in=.desktop)
 | 
			
		||||
 | 
			
		||||
@INTLTOOL_DESKTOP_RULE@
 | 
			
		||||
 | 
			
		||||
xml_in_files = \
 | 
			
		||||
        50-mutter-navigation.xml.in \
 | 
			
		||||
        50-mutter-system.xml.in \
 | 
			
		||||
        50-mutter-windows.xml.in
 | 
			
		||||
xmldir = $(GNOME_KEYBINDINGS_KEYSDIR)
 | 
			
		||||
xml_DATA = $(xml_in_files:.xml.in=.xml)
 | 
			
		||||
 | 
			
		||||
gschema_in_files = \
 | 
			
		||||
	org.gnome.mutter.gschema.xml.in	\
 | 
			
		||||
	org.gnome.mutter.wayland.gschema.xml.in
 | 
			
		||||
gsettings_SCHEMAS = $(gschema_in_files:.xml.in=.xml)
 | 
			
		||||
 | 
			
		||||
@INTLTOOL_XML_NOMERGE_RULE@
 | 
			
		||||
@GSETTINGS_RULES@
 | 
			
		||||
 | 
			
		||||
convertdir = $(datadir)/GConf/gsettings
 | 
			
		||||
convert_DATA = mutter-schemas.convert
 | 
			
		||||
 | 
			
		||||
CLEANFILES = \
 | 
			
		||||
	$(desktopfiles_DATA) \
 | 
			
		||||
	$(gsettings_SCHEMAS) \
 | 
			
		||||
	$(xml_DATA)
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = \
 | 
			
		||||
	$(convert_DATA) \
 | 
			
		||||
	$(desktopfiles_in_files) \
 | 
			
		||||
	$(gschema_in_files) \
 | 
			
		||||
	$(xml_in_files)
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
[Desktop Entry]
 | 
			
		||||
Type=Application
 | 
			
		||||
_Name=Mutter
 | 
			
		||||
Exec=mutter
 | 
			
		||||
NoDisplay=true
 | 
			
		||||
# name of loadable control center module
 | 
			
		||||
X-GNOME-WMSettingsModule=metacity
 | 
			
		||||
# name we put on the WM spec check window
 | 
			
		||||
X-GNOME-WMName=Mutter
 | 
			
		||||
# back compat only 
 | 
			
		||||
X-GnomeWMSettingsLibrary=metacity
 | 
			
		||||
X-GNOME-Bugzilla-Bugzilla=GNOME
 | 
			
		||||
X-GNOME-Bugzilla-Product=mutter
 | 
			
		||||
X-GNOME-Bugzilla-Component=general
 | 
			
		||||
X-GNOME-Autostart-Phase=WindowManager
 | 
			
		||||
X-GNOME-Provides=windowmanager
 | 
			
		||||
X-GNOME-Autostart-Notify=true
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
SUBDIRS = man reference
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = dialogs.txt code-overview.txt \
 | 
			
		||||
EXTRA_DIST=theme-format.txt dialogs.txt code-overview.txt \
 | 
			
		||||
	how-to-get-focus-right.txt rationales.txt
 | 
			
		||||
 
 | 
			
		||||
@@ -79,9 +79,10 @@ IGNORE_HFILES= \
 | 
			
		||||
	iconcache.h \
 | 
			
		||||
	inlinepixbufs.h \
 | 
			
		||||
	keybindings-private.h \
 | 
			
		||||
	menu.h \
 | 
			
		||||
	metaaccellabel.h \
 | 
			
		||||
	meta-background-actor-private.h \
 | 
			
		||||
	meta-background-group-private.h \
 | 
			
		||||
	meta-dbus-login1.h \
 | 
			
		||||
	meta-module.h \
 | 
			
		||||
	meta-plugin-manager.h \
 | 
			
		||||
	meta-shadow-factory-private.h \
 | 
			
		||||
@@ -112,24 +113,6 @@ IGNORE_HFILES= \
 | 
			
		||||
	xprops.h \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if !HAVE_NATIVE_BACKEND
 | 
			
		||||
IGNORE_HFILES+= \
 | 
			
		||||
	meta-backend-native.h \
 | 
			
		||||
	meta-barrier-native.h \
 | 
			
		||||
	meta-cursor-renderer-native.h \
 | 
			
		||||
	meta-idle-monitor-native.h \
 | 
			
		||||
	meta-input-settings-native.h \
 | 
			
		||||
	meta-monitor-manager-kms.h \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if !HAVE_WAYLAND
 | 
			
		||||
IGNORE_HFILES += \
 | 
			
		||||
	meta-surface-actor-wayland.h	\
 | 
			
		||||
	wayland				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
MKDB_OPTIONS+=--ignore-files="$(IGNORE_HFILES)"
 | 
			
		||||
 | 
			
		||||
# Images to copy into HTML directory.
 | 
			
		||||
@@ -157,7 +140,7 @@ expand_content_files= \
 | 
			
		||||
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
 | 
			
		||||
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
 | 
			
		||||
GTKDOC_CFLAGS=$(MUTTER_CFLAGS)
 | 
			
		||||
GTKDOC_LIBS=$(MUTTER_LIBS) $(top_builddir)/src/libmutter.la
 | 
			
		||||
GTKDOC_LIBS=$(MUTTER_LIBS) $(top_builddir)/src/libmutter-wayland.la
 | 
			
		||||
 | 
			
		||||
# This includes the standard gtk-doc make rules, copied by gtkdocize.
 | 
			
		||||
include $(top_srcdir)/gtk-doc.make
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@
 | 
			
		||||
    <title>Mutter Core Reference</title>
 | 
			
		||||
    <xi:include href="xml/main.xml"/>
 | 
			
		||||
    <xi:include href="xml/common.xml"/>
 | 
			
		||||
    <xi:include href="xml/gradient.xml"/>
 | 
			
		||||
    <xi:include href="xml/prefs.xml"/>
 | 
			
		||||
    <xi:include href="xml/util.xml"/>
 | 
			
		||||
    <xi:include href="xml/errors.xml"/>
 | 
			
		||||
 
 | 
			
		||||
@@ -172,6 +172,15 @@ meta_error_trap_push_with_return
 | 
			
		||||
meta_error_trap_pop_with_return
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>gradient</FILE>
 | 
			
		||||
MetaGradientType
 | 
			
		||||
meta_gradient_create_simple
 | 
			
		||||
meta_gradient_create_multi
 | 
			
		||||
meta_gradient_create_interwoven
 | 
			
		||||
meta_gradient_add_alpha
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>group</FILE>
 | 
			
		||||
MetaGroup
 | 
			
		||||
@@ -291,7 +300,6 @@ MetaPluginVersion
 | 
			
		||||
META_PLUGIN_DECLARE
 | 
			
		||||
meta_plugin_switch_workspace_completed
 | 
			
		||||
meta_plugin_minimize_completed
 | 
			
		||||
meta_plugin_unminimize_completed
 | 
			
		||||
meta_plugin_maximize_completed
 | 
			
		||||
meta_plugin_unmaximize_completed
 | 
			
		||||
meta_plugin_map_completed
 | 
			
		||||
@@ -547,8 +555,9 @@ meta_window_is_monitor_sized
 | 
			
		||||
meta_window_is_override_redirect
 | 
			
		||||
meta_window_is_skip_taskbar
 | 
			
		||||
meta_window_get_rect
 | 
			
		||||
meta_window_get_buffer_rect
 | 
			
		||||
meta_window_get_input_rect
 | 
			
		||||
meta_window_get_frame_rect
 | 
			
		||||
meta_window_get_outer_rect
 | 
			
		||||
meta_window_client_rect_to_frame_rect
 | 
			
		||||
meta_window_frame_rect_to_client_rect
 | 
			
		||||
meta_window_get_screen
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										396
									
								
								doc/theme-format.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										396
									
								
								doc/theme-format.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,396 @@
 | 
			
		||||
Themes are in a simple XML-subset format. There are multiple versions
 | 
			
		||||
of the theme format, and a given theme can support more than one format.
 | 
			
		||||
 | 
			
		||||
Version 1:     THEMEDIR/metacity-1/metacity-theme-1.xml
 | 
			
		||||
  (original metacity format)
 | 
			
		||||
Version 2:     THEMEDIR/metacity-1/metacity-theme-2.xml
 | 
			
		||||
Version 3:     THEMEDIR/metacity-1/metacity-theme-3.xml
 | 
			
		||||
 | 
			
		||||
The subdirectory name is "metacity-1" in all versions.
 | 
			
		||||
 | 
			
		||||
As you might expect, older versions of metacity will not understand
 | 
			
		||||
newer theme formats. However, newer versions will use old themes.
 | 
			
		||||
Metacity will always use the newest theme format it understands that
 | 
			
		||||
the X server supports. Some format versions are only supported if you
 | 
			
		||||
have the right X server features.
 | 
			
		||||
 | 
			
		||||
Each format *requires* the corresponding filename. If you put version
 | 
			
		||||
2 format features in the metacity-1/metacity-theme-1.xml file, then
 | 
			
		||||
metacity will get angry.
 | 
			
		||||
 | 
			
		||||
This document has separate sections for each format version. You may
 | 
			
		||||
want to read the document in reverse order, since the base features
 | 
			
		||||
are discussed under version 1.
 | 
			
		||||
 | 
			
		||||
New Features in Theme Format Version 3.4
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
An additional color type is added to pick up custom colors defined
 | 
			
		||||
in the GTK+ theme's CSS:
 | 
			
		||||
 | 
			
		||||
  gtk:custom(name,fallback)
 | 
			
		||||
 | 
			
		||||
where <name> refers to a custom color defined with @define-color in
 | 
			
		||||
the GTK+ theme, and <fallback> provides an alternative color definition
 | 
			
		||||
in case the color referenced by <name> is not found.
 | 
			
		||||
 | 
			
		||||
New Features in Theme Format Version 3.3
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Add two additional button background functions - left_single_background and
 | 
			
		||||
right_single_background - for button groups with just a single button.
 | 
			
		||||
 | 
			
		||||
There are now additional frame states to style left/right tiled windows
 | 
			
		||||
differently ("tiled_left", "tiled_right", "tiled_left_and_shaded",
 | 
			
		||||
"tiled_right_and_shaded").
 | 
			
		||||
 | 
			
		||||
New Features in Theme Format Version 3.2
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
A new window type 'attached' is added for modal dialogs which are
 | 
			
		||||
attached to their parent window. (When the attach_modal_dialogs preference
 | 
			
		||||
is turned on.) If no style is defined for the 'attached' window type,
 | 
			
		||||
the 'border' window type will be used instead.
 | 
			
		||||
 | 
			
		||||
New Features in Theme Format Version 3.1
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Additional predefined variables are added for positioning expressions:
 | 
			
		||||
 | 
			
		||||
 frame_x_center: the X center of the entire frame, with respect to the
 | 
			
		||||
     piece currently being drawn.
 | 
			
		||||
 frame_y_center: the Y center of the entire frame, with respect to the
 | 
			
		||||
     piece currently being drawn.
 | 
			
		||||
 | 
			
		||||
The <title/> element now supports an "ellipsize_width" attribute. When
 | 
			
		||||
specified, this gives a width at which to ellipsize the title. If not
 | 
			
		||||
specified, the title will simply be clipped to the title area.
 | 
			
		||||
 | 
			
		||||
New Features in Theme Format Version 3
 | 
			
		||||
======================================
 | 
			
		||||
 | 
			
		||||
Format version 3 has exactly one new feature; any element in the file
 | 
			
		||||
can now have a version attribute:
 | 
			
		||||
 | 
			
		||||
  version="[<|<=|=>|>] MAJOR.MINOR"
 | 
			
		||||
 | 
			
		||||
(< and > should be to be entity escaped as < and >). If this
 | 
			
		||||
version check is not met, then the element and its children will be
 | 
			
		||||
ignored. This allows having alternate sections of the theme file for
 | 
			
		||||
older and newer version of the Metacity theme format.
 | 
			
		||||
 | 
			
		||||
When placed on the toplevel <metacity_theme> element, an unsatisfied
 | 
			
		||||
version check will not just cause the contents of the file to be
 | 
			
		||||
ignored, it will also cause the lookup of a theme file to proceed on
 | 
			
		||||
and look for an older format 2 or format 1 file. This allows making a
 | 
			
		||||
metacity-theme-3.xml file that is only used the format version 3.2 or
 | 
			
		||||
newer is supported, and using metacity-theme-1.xml for older window
 | 
			
		||||
managers.
 | 
			
		||||
 | 
			
		||||
New Features in Theme Format Version 2
 | 
			
		||||
======================================
 | 
			
		||||
 | 
			
		||||
The optional attributes rounded_top_left, rounded_top_right,
 | 
			
		||||
rounded_bottom_left and rounded_bottom_right on <frame_geometry>
 | 
			
		||||
should now be the radius of the corner in pixels. You may still use
 | 
			
		||||
the values "false" for 0 and "true" for 5, which means v1 values will
 | 
			
		||||
still work just fine.
 | 
			
		||||
 | 
			
		||||
<frame_geometry> has a new optional attribute, hide_buttons. If this
 | 
			
		||||
is true, no buttons will be displayed on the titlebar.
 | 
			
		||||
 | 
			
		||||
Anywhere you can use a positive integer, you can use an integer constant.
 | 
			
		||||
 | 
			
		||||
As well as constant integers and reals, you may define constant colours,
 | 
			
		||||
thus:
 | 
			
		||||
  <constant name="RevoltingPink" value="#FF00FF"/>
 | 
			
		||||
  <constant name="Background" value="gtk:bg[NORMAL]"/>
 | 
			
		||||
 | 
			
		||||
<frame_style> has two new optional attributes, background and alpha.
 | 
			
		||||
If you specify alpha, you must specify background. background is a
 | 
			
		||||
colour used for the background of the frame. alpha is the transparency
 | 
			
		||||
as a real between 0.0 and 1.0. If the current X server does not support
 | 
			
		||||
alpha channels, the value is ignored.
 | 
			
		||||
 | 
			
		||||
The filename attribute of <image> may begin with "theme:". If so, the
 | 
			
		||||
rest of the string is the name of a theme icon. The 64x64 version of the
 | 
			
		||||
icon is used, except for fallback mini_icons, which use the 16x16 version.
 | 
			
		||||
This does not affect ordinary resizing. For example:
 | 
			
		||||
  <button function="close" state="normal">
 | 
			
		||||
    <draw_ops>
 | 
			
		||||
      <include name="active_button"/>
 | 
			
		||||
      <image filename="theme:gnome-logout" x="2" y="2"
 | 
			
		||||
          width="width-4" height="height-4"/>
 | 
			
		||||
      <!-- Note: not "theme:gnome-logout.png" or similar. -->
 | 
			
		||||
    </draw_ops>
 | 
			
		||||
  </button>
 | 
			
		||||
 | 
			
		||||
<menu_icon>s are parsed but ignored.
 | 
			
		||||
 | 
			
		||||
Fallback icons can be specified using <fallback>. There are two
 | 
			
		||||
optional arguments, icon and mini_icon. The values of these arguments
 | 
			
		||||
are identical to that of the filename attribute of <image>. Fallback
 | 
			
		||||
icons are used when a window does not supply its own icon. If a fallback
 | 
			
		||||
icon is not specified with <fallback>, Metacity will use a built-in
 | 
			
		||||
icon, as in metacity-theme-1.
 | 
			
		||||
 | 
			
		||||
The <arc> element, as well as the original start_angle and end_angle
 | 
			
		||||
attributes, may be given from and to attributes. The values of these
 | 
			
		||||
attributes are given in degrees clockwise, with 0 being straight up.
 | 
			
		||||
For example:
 | 
			
		||||
  <arc from="0.0" to="90.0" filled="true" color="#FF00FF"
 | 
			
		||||
      x="0" y="5" width="15" height="15"/>
 | 
			
		||||
 | 
			
		||||
<frame state="shaded"> may now take an optional resize attribute, with
 | 
			
		||||
the same interpretation as the resize attribute on <frame state="normal">.
 | 
			
		||||
If this attribute is omitted for state="shaded", it defaults to "both".
 | 
			
		||||
(If it is omitted for state="normal", it remains an error.)
 | 
			
		||||
 | 
			
		||||
In addition to the four <button> functions which are required in
 | 
			
		||||
metacity-theme-1, there are six new functions in metacity-theme-2:
 | 
			
		||||
shade, unshade, above, unabove, stick and unstick.
 | 
			
		||||
      
 | 
			
		||||
Overview of Theme Format Version 1
 | 
			
		||||
==================================
 | 
			
		||||
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<metacity_theme>
 | 
			
		||||
<!-- Only one info section is allowed -->
 | 
			
		||||
<info>
 | 
			
		||||
  <name>Foo</name>
 | 
			
		||||
  <author>Foo P. Bar</author>
 | 
			
		||||
  <copyright>whoever, 2002</copyright>
 | 
			
		||||
  <date>Jan 31 2005</date>
 | 
			
		||||
  <description>A sentence about the theme.</description>
 | 
			
		||||
</info>
 | 
			
		||||
 | 
			
		||||
<!-- define a frame geometry to be referenced later -->
 | 
			
		||||
<!-- frame_geometry has an optional has_title attribute which 
 | 
			
		||||
     determines whether the title text height is included in the 
 | 
			
		||||
     height calculation. if not specified, defaults to true.
 | 
			
		||||
     It also has an optional text_size="medium" attribute
 | 
			
		||||
     (same sizes as with Pango markup, xx-small thru medium thru
 | 
			
		||||
     xx-large) 
 | 
			
		||||
 | 
			
		||||
     Finally it has optional args rounded_top_left=true, 
 | 
			
		||||
     rounded_top_right=true, rounded_bottom_left=true,
 | 
			
		||||
     rounded_bottom_right=true.
 | 
			
		||||
 | 
			
		||||
     -->
 | 
			
		||||
<frame_geometry name="normal" has_title="true" title_scale="medium">
 | 
			
		||||
  <distance name="left_width" value="6"/>
 | 
			
		||||
  <distance name="right_width" value="6"/>
 | 
			
		||||
  <distance name="bottom_height" value="7"/>
 | 
			
		||||
  <distance name="left_titlebar_edge" value="6"/>
 | 
			
		||||
  <distance name="right_titlebar_edge" value="6"/>
 | 
			
		||||
  <distance name="button_width" value="17"/>
 | 
			
		||||
  <distance name="button_height" value="17"/>
 | 
			
		||||
  <!-- alternative to button_width button_height distances -->
 | 
			
		||||
  <aspect_ratio name="button" value="1.0"/>
 | 
			
		||||
  <distance name="title_vertical_pad" value="4"/>
 | 
			
		||||
  <border name="title_border" left="3" right="12" top="4" bottom="3"/>
 | 
			
		||||
  <border name="button_border" left="0" right="0" top="1" bottom="1"/>
 | 
			
		||||
</frame_geometry>
 | 
			
		||||
 | 
			
		||||
<!-- inheritance is allowed; simply overwrites values from parent -->
 | 
			
		||||
<frame_geometry name="borderless" parent="normal">
 | 
			
		||||
  <distance name="left_width" value="0"/>
 | 
			
		||||
  <distance name="right_width" value="0"/>
 | 
			
		||||
  <distance name="bottom_height" value="0"/>
 | 
			
		||||
  <distance name="left_titlebar_edge" value="0"/>
 | 
			
		||||
  <distance name="right_titlebar_edge" value="0"/>
 | 
			
		||||
</frame_geometry>
 | 
			
		||||
 | 
			
		||||
<!-- define a constant to use in positions/sizes of draw operations;
 | 
			
		||||
     constant names must start with a capital letter.
 | 
			
		||||
  -->
 | 
			
		||||
<constant name="LineOffset" value="3"/>
 | 
			
		||||
 | 
			
		||||
<!-- define drawing operations to be referenced later; 
 | 
			
		||||
     these draw-op lists can also be placed inline. 
 | 
			
		||||
 | 
			
		||||
     Positions/lengths are given as expressions.
 | 
			
		||||
     Operators are: +,-,*,/,%,`max`,`min`
 | 
			
		||||
     All operators are infix including `max` and `min`, 
 | 
			
		||||
      i.e. "2 `max` 5"
 | 
			
		||||
     
 | 
			
		||||
     Some variables are predefined, and constants can also 
 | 
			
		||||
     be used. Variables are:
 | 
			
		||||
 | 
			
		||||
       width - width of target area
 | 
			
		||||
       height - height of target area
 | 
			
		||||
       object_width - natural width of object being drawn
 | 
			
		||||
       object_height - natural height of object being drawn
 | 
			
		||||
       left_width - distance from left of frame to client window
 | 
			
		||||
       right_width - distance from right of frame to client window
 | 
			
		||||
       top_height - distance from top of frame to client window
 | 
			
		||||
       bottom_height - distance from bottom of frame to client window
 | 
			
		||||
       mini_icon_width - width of mini icon for window
 | 
			
		||||
       mini_icon_height - height of mini icon
 | 
			
		||||
       icon_width - width of large icon
 | 
			
		||||
       icon_height - height of large icon
 | 
			
		||||
       title_width - width of title text
 | 
			
		||||
       title_height - height of title text
 | 
			
		||||
 | 
			
		||||
    All these are always defined, except object_width/object_height 
 | 
			
		||||
    which only exists for <image> right now.
 | 
			
		||||
 | 
			
		||||
  -->
 | 
			
		||||
 | 
			
		||||
<draw_ops name="demo_all_ops">
 | 
			
		||||
  <line color="#00FF00" x1="LineOffset" y1="0" x2="0" y2="height"/>
 | 
			
		||||
  <line color="gtk:fg[NORMAL]" 
 | 
			
		||||
        x1="width - 1" y1="0" x2="width - 1" y2="height" 
 | 
			
		||||
        width="3" dash_on_length="2" dash_off_length="3"/>
 | 
			
		||||
  <rectangle color="blend/gtk:fg[NORMAL]/gtk:bg[NORMAL]/0.7"
 | 
			
		||||
             x="0" y="0" width="width - 1" height="height - 1" filled="true"/>
 | 
			
		||||
  <arc color="dark gray" x="0" y="0" width="width - 1" height="height - 1" 
 | 
			
		||||
       filled="false" start_angle="30" extent_angle="180"/>
 | 
			
		||||
  <tint color="orange" alpha="0.5" x="0" y="0" width="width" height="height"/>
 | 
			
		||||
 <!-- may be vertical, horizontal, diagonal -->
 | 
			
		||||
  <gradient type="diagonal" 
 | 
			
		||||
            x="10" y="30" width="width / 3" height="height / 4">
 | 
			
		||||
    <!-- any number of colors allowed here. A color can be 
 | 
			
		||||
         a color name like "blue" (look at gcolorsel), a hex color
 | 
			
		||||
         as in HTML (#FFBB99), or a color from the gtk theme 
 | 
			
		||||
         given as "gtk:base[NORMAL]", "gtk:fg[ACTIVE]", etc.
 | 
			
		||||
       -->
 | 
			
		||||
    <color value="gtk:fg[SELECTED]"/>
 | 
			
		||||
    <!-- color obtained by a 0.5 alpha composite of the second color onto the first -->
 | 
			
		||||
    <color value="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.5"/>
 | 
			
		||||
  </gradient>
 | 
			
		||||
  <!-- image has an optional colorize="#color" attribute to give the
 | 
			
		||||
       image a certain color -->
 | 
			
		||||
  <image filename="foo.png" alpha="0.7"
 | 
			
		||||
         x="10" y="30" width="width / 3" height="height / 4"/>
 | 
			
		||||
  <gtk_arrow state="normal" shadow="in" arrow="up"
 | 
			
		||||
             filled="true"
 | 
			
		||||
             x="2" y="2" width="width - 4" height="height - 4"/>
 | 
			
		||||
  <gtk_box state="normal" shadow="out"
 | 
			
		||||
           x="2" y="2" width="width - 4" height="height - 4"/>
 | 
			
		||||
  <gtk_vline state="normal" x="2" y1="0" y2="height"/>
 | 
			
		||||
  <!-- window's icon -->
 | 
			
		||||
  <icon alpha="0.7"
 | 
			
		||||
        x="10" y="30" width="width / 3" height="height / 4"/>
 | 
			
		||||
  <!-- window's title -->
 | 
			
		||||
  <title color="gtk:text[NORMAL]" x="20" y="30"/>
 | 
			
		||||
  <!-- include another draw ops list; has optional x/y/width/height attrs -->
 | 
			
		||||
  <include name="some_other_draw_ops"/>
 | 
			
		||||
  <!-- tile another draw ops list; has optional
 | 
			
		||||
       x/y/width/height/tile_xoffset/tile_yoffset -->
 | 
			
		||||
  <tile name="some_other_draw_ops" tile_width="10" tile_height="10"/>
 | 
			
		||||
</draw_ops>
 | 
			
		||||
 | 
			
		||||
<frame_style name="normal" geometry="normal">
 | 
			
		||||
  <!-- How to draw each piece of the frame.
 | 
			
		||||
       For each piece, a draw_ops can be given inline or referenced 
 | 
			
		||||
       by name. If a piece is omitted, then nothing will be drawn 
 | 
			
		||||
       for that piece.
 | 
			
		||||
 | 
			
		||||
       For each piece, the "width" and "height" variables in 
 | 
			
		||||
       coordinate expressions refers to the dimensions of the piece, 
 | 
			
		||||
       the origin is at the top left of the piece.
 | 
			
		||||
  
 | 
			
		||||
       So <rectangle x="0" y="0" width="width-1" height="height-1"/>
 | 
			
		||||
       will outline a piece.
 | 
			
		||||
    -->
 | 
			
		||||
 | 
			
		||||
  <piece position="entire_background" draw_ops="demo_all_ops"/>
 | 
			
		||||
  <piece position="left_titlebar_edge">
 | 
			
		||||
    <draw_ops>
 | 
			
		||||
      <line color="#00FF00" x1="0" y1="0" x2="0" y2="height"/>
 | 
			
		||||
    </draw_ops>
 | 
			
		||||
  </piece>
 | 
			
		||||
 | 
			
		||||
  <!-- The complete list of frame pieces:
 | 
			
		||||
 | 
			
		||||
       entire_background: whole frame
 | 
			
		||||
       titlebar: entire area above the app's window 
 | 
			
		||||
       titlebar_middle: area of titlebar_background not considered
 | 
			
		||||
                        part of an edge
 | 
			
		||||
       left_titlebar_edge: left side of titlebar background
 | 
			
		||||
       right_titlebar_edge: right side of titlebar background
 | 
			
		||||
       top_titlebar_edge: top side of titlebar background
 | 
			
		||||
       bottom_titlebar_edge: bottom side of titlebar background 
 | 
			
		||||
       title: the title area (doesn't include buttons)
 | 
			
		||||
       left_edge: left edge of the frame
 | 
			
		||||
       right_edge: right edge of the frame
 | 
			
		||||
       bottom_edge: bottom edge of the frame
 | 
			
		||||
       overlay: same area as entire_background, but drawn after 
 | 
			
		||||
                drawing all sub-pieces instead of before
 | 
			
		||||
 | 
			
		||||
   -->
 | 
			
		||||
 | 
			
		||||
  <!-- For buttons, drawing methods have to be provided for 
 | 
			
		||||
       each of three states: 
 | 
			
		||||
          normal, pressed, prelight
 | 
			
		||||
       and the button function or position must be provided:
 | 
			
		||||
          close, maximize, minimize, menu, 
 | 
			
		||||
          left_left_background, left_middle_background,
 | 
			
		||||
          left_right_background, right_left_background, 
 | 
			
		||||
          right_middle_background, right_right_background
 | 
			
		||||
       So a working theme needs 3*4 = 12 button declarations
 | 
			
		||||
       and a theme may have up to 3*10 = 30 button declarations
 | 
			
		||||
       in order to handle button-rearrangement preferences.
 | 
			
		||||
 
 | 
			
		||||
       (The name "function" for the attribute is from before the 
 | 
			
		||||
        background values existed.)
 | 
			
		||||
    -->
 | 
			
		||||
 | 
			
		||||
  <button function="close" state="normal" draw_ops="previously_named"/>
 | 
			
		||||
  <button function="menu" state="normal">
 | 
			
		||||
    <draw_ops>
 | 
			
		||||
      <icon alpha="0.7"
 | 
			
		||||
            x="0" y="0" width="object_width" height="object_height"/>
 | 
			
		||||
    </draw_ops>
 | 
			
		||||
  </button>
 | 
			
		||||
 | 
			
		||||
</frame_style>
 | 
			
		||||
 | 
			
		||||
<!-- styles can inherit from each other with the parent="" attribute. 
 | 
			
		||||
     In a subclass anything can be re-specified to override 
 | 
			
		||||
     the parent style. -->
 | 
			
		||||
<frame_style name="focused" parent="normal">
 | 
			
		||||
  <piece position="title">
 | 
			
		||||
    <draw_ops>
 | 
			
		||||
      <rectangle color="gtk:bg[SELECTED]"
 | 
			
		||||
                 x="0" y="0" width="width-1" height="height-1"/>
 | 
			
		||||
      <title color="gtk:fg[SELECTED]" x="(width - title_width) / 2"
 | 
			
		||||
                                      y="(height - title_height) / 2"/>
 | 
			
		||||
    </draw_ops>
 | 
			
		||||
  </piece>
 | 
			
		||||
</frame_style>
 | 
			
		||||
 | 
			
		||||
<!-- Maps styles to states of frame. 
 | 
			
		||||
 | 
			
		||||
     Focus: yes (focused), no (not focused)
 | 
			
		||||
     Window states: normal, maximized, shaded, maximized_and_shaded
 | 
			
		||||
     Window resizability: none, vertical, horizontal, both
 | 
			
		||||
 | 
			
		||||
     Everything unspecified just does the same as
 | 
			
		||||
     unfocused/normal/both.
 | 
			
		||||
 | 
			
		||||
     only state="normal" needs a resize="" attribute.
 | 
			
		||||
 -->
 | 
			
		||||
<frame_style_set name="normal">
 | 
			
		||||
<frame focus="yes" state="normal" resize="both" style="focused"/>
 | 
			
		||||
<frame focus="no" state="normal" resize="both" style="normal"/>
 | 
			
		||||
</frame_style_set>
 | 
			
		||||
 | 
			
		||||
<!-- Each window type needs a style set 
 | 
			
		||||
     Types: normal, dialog, modal_dialog, menu, utility, border
 | 
			
		||||
  -->
 | 
			
		||||
<window type="normal" style_set="normal"/>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<!-- For menu icons, drawing methods are needed for the same 
 | 
			
		||||
     four types as the buttons, and GTK states
 | 
			
		||||
     (insensitive,prelight,normal,etc.)
 | 
			
		||||
  -->
 | 
			
		||||
 | 
			
		||||
<menu_icon function="close" state="normal" draw_ops="previously_named"/>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</metacity_theme>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -21,10 +21,10 @@ environment.</description>
 | 
			
		||||
  -->
 | 
			
		||||
  <mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnome-shell-list" />
 | 
			
		||||
  <download-page rdf:resource="http://download.gnome.org/sources/mutter/" />
 | 
			
		||||
  <download-page rdf:resource="http://download.gnome.org/sources/mutter-wayland/" />
 | 
			
		||||
  <bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" />
 | 
			
		||||
 | 
			
		||||
  <category rdf:resource="http://api.gnome.org/doap-extensions#core" />
 | 
			
		||||
  <programming-language>C</programming-language>
 | 
			
		||||
  <category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
 | 
			
		||||
 | 
			
		||||
  <maintainer>
 | 
			
		||||
    <foaf:Person>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,8 @@
 | 
			
		||||
# List of source files containing translatable strings.
 | 
			
		||||
# Please keep this file sorted alphabetically.
 | 
			
		||||
data/50-mutter-navigation.xml.in
 | 
			
		||||
data/50-mutter-system.xml.in
 | 
			
		||||
data/50-mutter-windows.xml.in
 | 
			
		||||
data/mutter.desktop.in
 | 
			
		||||
data/org.gnome.mutter.gschema.xml.in
 | 
			
		||||
data/org.gnome.mutter.wayland.gschema.xml.in
 | 
			
		||||
src/50-mutter-navigation.xml.in
 | 
			
		||||
src/50-mutter-system.xml.in
 | 
			
		||||
src/50-mutter-windows.xml.in
 | 
			
		||||
src/backends/meta-monitor-manager.c
 | 
			
		||||
src/compositor/compositor.c
 | 
			
		||||
src/compositor/meta-background.c
 | 
			
		||||
@@ -19,10 +16,17 @@ src/core/main.c
 | 
			
		||||
src/core/mutter.c
 | 
			
		||||
src/core/prefs.c
 | 
			
		||||
src/core/screen.c
 | 
			
		||||
src/x11/session.c
 | 
			
		||||
src/core/util.c
 | 
			
		||||
src/core/window.c
 | 
			
		||||
src/ui/frames.c
 | 
			
		||||
src/ui/theme.c
 | 
			
		||||
src/x11/session.c
 | 
			
		||||
src/x11/window-props.c
 | 
			
		||||
src/x11/xprops.c
 | 
			
		||||
src/mutter-wayland.desktop.in
 | 
			
		||||
src/org.gnome.mutter.gschema.xml.in
 | 
			
		||||
src/org.gnome.mutter.wayland.gschema.xml.in
 | 
			
		||||
src/ui/frames.c
 | 
			
		||||
src/ui/menu.c
 | 
			
		||||
src/ui/metaaccellabel.c
 | 
			
		||||
src/ui/resizepopup.c
 | 
			
		||||
src/ui/theme.c
 | 
			
		||||
src/ui/theme-parser.c
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1,2 @@
 | 
			
		||||
data/mutter-wayland.desktop.in
 | 
			
		||||
src/metacity.schemas.in
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2681
									
								
								po/bn_IN.po
									
									
									
									
									
								
							
							
						
						
									
										2681
									
								
								po/bn_IN.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										3703
									
								
								po/ca@valencia.po
									
									
									
									
									
								
							
							
						
						
									
										3703
									
								
								po/ca@valencia.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2811
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
							
						
						
									
										2811
									
								
								po/pt_BR.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2610
									
								
								po/sr@latin.po
									
									
									
									
									
								
							
							
						
						
									
										2610
									
								
								po/sr@latin.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2018
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
							
						
						
									
										2018
									
								
								po/zh_CN.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1397
									
								
								po/zh_HK.po
									
									
									
									
									
								
							
							
						
						
									
										1397
									
								
								po/zh_HK.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2245
									
								
								po/zh_TW.po
									
									
									
									
									
								
							
							
						
						
									
										2245
									
								
								po/zh_TW.po
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -17,9 +17,6 @@
 | 
			
		||||
	<KeyListEntry name="move-to-workspace-4"
 | 
			
		||||
	              _description="Move window to workspace 4" />
 | 
			
		||||
 | 
			
		||||
        <KeyListEntry name="move-to-workspace-last"
 | 
			
		||||
                      _description="Move window to last workspace" />
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="move-to-workspace-left"
 | 
			
		||||
	              _description="Move window one workspace to the left" />
 | 
			
		||||
 | 
			
		||||
@@ -45,68 +42,26 @@
 | 
			
		||||
	              _description="Move window one monitor down" />
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-applications"
 | 
			
		||||
	              reverse-entry="switch-applications-backward"
 | 
			
		||||
	              _description="Switch applications"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-applications-backward"
 | 
			
		||||
	              reverse-entry="switch-applications"
 | 
			
		||||
	              hidden="true"
 | 
			
		||||
	              _description="Switch to previous application"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-windows"
 | 
			
		||||
	              reverse-entry="switch-windows-backward"
 | 
			
		||||
	              _description="Switch windows"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-windows-backward"
 | 
			
		||||
	              reverse-entry="switch-windows"
 | 
			
		||||
	              hidden="true"
 | 
			
		||||
	              _description="Switch to previous window"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-group"
 | 
			
		||||
	              reverse-entry="switch-group-backward"
 | 
			
		||||
	              _description="Switch windows of an application"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-group-backward"
 | 
			
		||||
	              reverse-entry="switch-group"
 | 
			
		||||
	              hidden="true"
 | 
			
		||||
	              _description="Switch to previous window of an application"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-panels"
 | 
			
		||||
	              reverse-entry="switch-panels-backward"
 | 
			
		||||
	              _description="Switch system controls"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-panels-backward"
 | 
			
		||||
	              reverse-entry="switch-panels"
 | 
			
		||||
	              hidden="true"
 | 
			
		||||
	              _description="Switch to previous system control"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="cycle-windows"
 | 
			
		||||
	              reverse-entry="cycle-windows-backward"
 | 
			
		||||
	              _description="Switch windows directly"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="cycle-windows-backward"
 | 
			
		||||
	              reverse-entry="cycle-windows"
 | 
			
		||||
	              hidden="true"
 | 
			
		||||
	              _description="Switch directly to previous window"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="cycle-group"
 | 
			
		||||
	              reverse-entry="cycle-group-backward"
 | 
			
		||||
	              _description="Switch windows of an app directly"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="cycle-group-backward"
 | 
			
		||||
	              reverse-entry="cycle-group"
 | 
			
		||||
	              hidden="true"
 | 
			
		||||
	              _description="Switch directly to previous window of an app"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="cycle-panels"
 | 
			
		||||
	              reverse-entry="cycle-panels-backward"
 | 
			
		||||
	              _description="Switch system controls directly"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="cycle-panels-backward"
 | 
			
		||||
	              reverse-entry="cycle-panels"
 | 
			
		||||
	              hidden="true"
 | 
			
		||||
	              _description="Switch directly to previous system control"/>
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="show-desktop"
 | 
			
		||||
	              _description="Hide all normal windows"/>
 | 
			
		||||
 | 
			
		||||
@@ -122,9 +77,6 @@
 | 
			
		||||
	<KeyListEntry name="switch-to-workspace-4"
 | 
			
		||||
	              _description="Switch to workspace 4" />
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-to-workspace-last"
 | 
			
		||||
	              _description="Switch to last workspace" />
 | 
			
		||||
 | 
			
		||||
	<KeyListEntry name="switch-to-workspace-left"
 | 
			
		||||
	              _description="Move to workspace left" />
 | 
			
		||||
 | 
			
		||||
@@ -1,49 +0,0 @@
 | 
			
		||||
# A framework for running scripted tests
 | 
			
		||||
 | 
			
		||||
if HAVE_WAYLAND
 | 
			
		||||
 | 
			
		||||
if BUILDOPT_INSTALL_TESTS
 | 
			
		||||
stackingdir = $(pkgdatadir)/tests/stacking
 | 
			
		||||
dist_stacking_DATA =				\
 | 
			
		||||
	tests/stacking/basic-x11.metatest	\
 | 
			
		||||
	tests/stacking/basic-wayland.metatest	\
 | 
			
		||||
	tests/stacking/minimized.metatest   	\
 | 
			
		||||
	tests/stacking/mixed-windows.metatest   \
 | 
			
		||||
	tests/stacking/override-redirect.metatest
 | 
			
		||||
 | 
			
		||||
mutter-all.test: tests/mutter-all.test.in
 | 
			
		||||
	$(AM_V_GEN) sed  -e "s|@libexecdir[@]|$(libexecdir)|g"  $< > $@.tmp && mv $@.tmp $@
 | 
			
		||||
 | 
			
		||||
installedtestsdir = $(datadir)/installed-tests/mutter
 | 
			
		||||
installedtests_DATA = mutter-all.test
 | 
			
		||||
 | 
			
		||||
installedtestsbindir = $(libexecdir)/installed-tests/mutter
 | 
			
		||||
installedtestsbin_PROGRAMS = mutter-test-client mutter-test-runner
 | 
			
		||||
else
 | 
			
		||||
noinst_PROGRAMS += mutter-test-client mutter-test-runner
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST += tests/mutter-all.test.in
 | 
			
		||||
 | 
			
		||||
mutter_test_client_SOURCES = tests/test-client.c
 | 
			
		||||
mutter_test_client_LDADD = $(MUTTER_LIBS) libmutter.la
 | 
			
		||||
 | 
			
		||||
mutter_test_runner_SOURCES = tests/test-runner.c
 | 
			
		||||
mutter_test_runner_LDADD = $(MUTTER_LIBS) libmutter.la
 | 
			
		||||
 | 
			
		||||
.PHONY: run-tests
 | 
			
		||||
 | 
			
		||||
run-tests: mutter-test-client mutter-test-runner
 | 
			
		||||
	./mutter-test-runner $(dist_stacking_DATA)
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Some random test programs for bits of the code
 | 
			
		||||
 | 
			
		||||
testboxes_SOURCES = core/testboxes.c
 | 
			
		||||
testasyncgetprop_SOURCES = x11/testasyncgetprop.c
 | 
			
		||||
 | 
			
		||||
noinst_PROGRAMS+=testboxes testasyncgetprop
 | 
			
		||||
 | 
			
		||||
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
 | 
			
		||||
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
 | 
			
		||||
							
								
								
									
										281
									
								
								src/Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										281
									
								
								src/Makefile.am
									
									
									
									
									
								
							@@ -1,107 +1,88 @@
 | 
			
		||||
# Flag build for parallelism; see https://savannah.gnu.org/patch/?6905
 | 
			
		||||
.AUTOPARALLEL:
 | 
			
		||||
 | 
			
		||||
lib_LTLIBRARIES = libmutter.la
 | 
			
		||||
lib_LTLIBRARIES = libmutter-wayland.la
 | 
			
		||||
 | 
			
		||||
SUBDIRS=compositor/plugins
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST =
 | 
			
		||||
NULL =
 | 
			
		||||
 | 
			
		||||
AM_CPPFLAGS = \
 | 
			
		||||
INCLUDES=								\
 | 
			
		||||
	-DCLUTTER_ENABLE_COMPOSITOR_API					\
 | 
			
		||||
	-DCLUTTER_ENABLE_EXPERIMENTAL_API				\
 | 
			
		||||
	-DCOGL_ENABLE_EXPERIMENTAL_API					\
 | 
			
		||||
	-DCOGL_ENABLE_EXPERIMENTAL_2_0_API                              \
 | 
			
		||||
	-DCLUTTER_DISABLE_DEPRECATION_WARNINGS				\
 | 
			
		||||
	-DCOGL_DISABLE_DEPRECATION_WARNINGS				\
 | 
			
		||||
	$(MUTTER_CFLAGS)						\
 | 
			
		||||
	$(MUTTER_NATIVE_BACKEND_CFLAGS)					\
 | 
			
		||||
	-I$(builddir)							\
 | 
			
		||||
	-I$(top_builddir)						\
 | 
			
		||||
	-I$(srcdir)							\
 | 
			
		||||
	-I$(srcdir)/backends						\
 | 
			
		||||
	-I$(srcdir)/core						\
 | 
			
		||||
	-I$(srcdir)/ui							\
 | 
			
		||||
	-I$(srcdir)/compositor						\
 | 
			
		||||
	-DMUTTER_LIBEXECDIR=\"$(libexecdir)\"				\
 | 
			
		||||
	-DMUTTER_LOCALEDIR=\"$(localedir)\"				\
 | 
			
		||||
	-DHOST_ALIAS=\"@HOST_ALIAS@\"					\
 | 
			
		||||
	-DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\"		\
 | 
			
		||||
	-DMUTTER_PKGDATADIR=\"$(pkgdatadir)\"				\
 | 
			
		||||
	-DMUTTER_DATADIR=\"$(datadir)\"					\
 | 
			
		||||
	-DG_LOG_DOMAIN=\"mutter\"					\
 | 
			
		||||
	-DSN_API_NOT_YET_FROZEN=1					\
 | 
			
		||||
	-DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION)			\
 | 
			
		||||
	-DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION)			\
 | 
			
		||||
	-DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION)			\
 | 
			
		||||
	-DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION)	\
 | 
			
		||||
	-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\"				\
 | 
			
		||||
	-DMUTTER_PLUGIN_DIR=\"$(MUTTER_PLUGIN_DIR)\"			\
 | 
			
		||||
	-DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\"			\
 | 
			
		||||
	-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\"			\
 | 
			
		||||
	-DXWAYLAND_PATH=\"$(XWAYLAND_PATH)\"				\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
	-DXWAYLAND_PATH='"@XWAYLAND_PATH@"'
 | 
			
		||||
 | 
			
		||||
mutter_built_sources = \
 | 
			
		||||
	$(dbus_idle_built_sources)		\
 | 
			
		||||
	$(dbus_display_config_built_sources)	\
 | 
			
		||||
	$(dbus_login1_built_sources)		\
 | 
			
		||||
	mutter-enum-types.h 			\
 | 
			
		||||
	mutter-enum-types.c			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if HAVE_WAYLAND
 | 
			
		||||
mutter_built_sources += \
 | 
			
		||||
	gtk-shell-protocol.c			\
 | 
			
		||||
	gtk-shell-server-protocol.h		\
 | 
			
		||||
	xdg-shell-protocol.c			\
 | 
			
		||||
	xdg-shell-server-protocol.h		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
endif
 | 
			
		||||
	xserver-protocol.c			\
 | 
			
		||||
	xserver-server-protocol.h
 | 
			
		||||
 | 
			
		||||
wayland_protocols =				\
 | 
			
		||||
wayland_protocols = \
 | 
			
		||||
	wayland/protocol/gtk-shell.xml		\
 | 
			
		||||
	wayland/protocol/xdg-shell.xml		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
	wayland/protocol/xserver.xml
 | 
			
		||||
 | 
			
		||||
libmutter_la_SOURCES =				\
 | 
			
		||||
libmutter_wayland_la_SOURCES =			\
 | 
			
		||||
	backends/meta-backend.c			\
 | 
			
		||||
	meta/meta-backend.h			\
 | 
			
		||||
	backends/meta-backend-private.h		\
 | 
			
		||||
	backends/meta-barrier.c			\
 | 
			
		||||
	backends/meta-barrier-private.h		\
 | 
			
		||||
	backends/meta-backend.h			\
 | 
			
		||||
	backends/meta-cursor.c			\
 | 
			
		||||
	backends/meta-cursor.h			\
 | 
			
		||||
	backends/meta-cursor-private.h		\
 | 
			
		||||
	backends/meta-cursor-tracker.c		\
 | 
			
		||||
	backends/meta-cursor-tracker-private.h	\
 | 
			
		||||
	backends/meta-cursor-renderer.c		\
 | 
			
		||||
	backends/meta-cursor-renderer.h		\
 | 
			
		||||
	backends/meta-display-config-shared.h	\
 | 
			
		||||
	backends/meta-idle-monitor.c		\
 | 
			
		||||
	backends/meta-idle-monitor-private.h	\
 | 
			
		||||
	backends/meta-idle-monitor-dbus.c	\
 | 
			
		||||
	backends/meta-idle-monitor-dbus.h	\
 | 
			
		||||
	backends/meta-input-settings.c		\
 | 
			
		||||
	backends/meta-input-settings-private.h	\
 | 
			
		||||
	backends/meta-monitor-config.c		\
 | 
			
		||||
	backends/meta-monitor-config.h		\
 | 
			
		||||
	backends/meta-monitor-manager.c		\
 | 
			
		||||
	meta/meta-monitor-manager.h		\
 | 
			
		||||
	backends/meta-monitor-manager-private.h	\
 | 
			
		||||
	backends/meta-monitor-manager.h		\
 | 
			
		||||
	backends/meta-monitor-manager-dummy.c	\
 | 
			
		||||
	backends/meta-monitor-manager-dummy.h	\
 | 
			
		||||
	backends/meta-stage.h			\
 | 
			
		||||
	backends/meta-stage.c			\
 | 
			
		||||
	backends/edid-parse.c			\
 | 
			
		||||
	backends/edid.h				\
 | 
			
		||||
	backends/x11/meta-backend-x11.c			\
 | 
			
		||||
	backends/x11/meta-backend-x11.h			\
 | 
			
		||||
	backends/x11/meta-barrier-x11.c			\
 | 
			
		||||
	backends/x11/meta-barrier-x11.h			\
 | 
			
		||||
	backends/x11/meta-cursor-renderer-x11.c		\
 | 
			
		||||
	backends/x11/meta-cursor-renderer-x11.h		\
 | 
			
		||||
	backends/native/meta-idle-monitor-native.c	\
 | 
			
		||||
	backends/native/meta-idle-monitor-native.h	\
 | 
			
		||||
	backends/native/meta-monitor-manager-kms.c	\
 | 
			
		||||
	backends/native/meta-monitor-manager-kms.h	\
 | 
			
		||||
	backends/native/meta-weston-launch.c		\
 | 
			
		||||
	backends/native/meta-weston-launch.h		\
 | 
			
		||||
	backends/x11/meta-idle-monitor-xsync.c		\
 | 
			
		||||
	backends/x11/meta-idle-monitor-xsync.h		\
 | 
			
		||||
	backends/x11/meta-input-settings-x11.c		\
 | 
			
		||||
	backends/x11/meta-input-settings-x11.h		\
 | 
			
		||||
	backends/x11/meta-monitor-manager-xrandr.c	\
 | 
			
		||||
	backends/x11/meta-monitor-manager-xrandr.h	\
 | 
			
		||||
	core/meta-accel-parse.c			\
 | 
			
		||||
	core/meta-accel-parse.h			\
 | 
			
		||||
	core/above-tab-keycode.c		\
 | 
			
		||||
	core/barrier.c				\
 | 
			
		||||
	meta/barrier.h				\
 | 
			
		||||
	core/bell.c				\
 | 
			
		||||
	core/bell.h				\
 | 
			
		||||
@@ -115,17 +96,11 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	compositor/compositor.c			\
 | 
			
		||||
	compositor/compositor-private.h		\
 | 
			
		||||
	compositor/meta-background.c		\
 | 
			
		||||
	compositor/meta-background-private.h	\
 | 
			
		||||
	compositor/meta-background-actor.c	\
 | 
			
		||||
	compositor/meta-background-actor-private.h	\
 | 
			
		||||
	compositor/meta-background-image.c	\
 | 
			
		||||
	compositor/meta-background-group.c	\
 | 
			
		||||
	compositor/meta-cullable.c		\
 | 
			
		||||
	compositor/meta-cullable.h		\
 | 
			
		||||
	compositor/meta-dnd-actor.c		\
 | 
			
		||||
	compositor/meta-dnd-actor-private.h	\
 | 
			
		||||
	compositor/meta-feedback-actor.c	\
 | 
			
		||||
	compositor/meta-feedback-actor-private.h	\
 | 
			
		||||
	compositor/meta-module.c		\
 | 
			
		||||
	compositor/meta-module.h		\
 | 
			
		||||
	compositor/meta-plugin.c		\
 | 
			
		||||
@@ -139,6 +114,8 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	compositor/meta-surface-actor.h		\
 | 
			
		||||
	compositor/meta-surface-actor-x11.c	\
 | 
			
		||||
	compositor/meta-surface-actor-x11.h	\
 | 
			
		||||
	compositor/meta-surface-actor-wayland.c	\
 | 
			
		||||
	compositor/meta-surface-actor-wayland.h	\
 | 
			
		||||
	compositor/meta-texture-rectangle.c	\
 | 
			
		||||
	compositor/meta-texture-rectangle.h	\
 | 
			
		||||
	compositor/meta-texture-tower.c		\
 | 
			
		||||
@@ -154,7 +131,6 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	meta/compositor.h			\
 | 
			
		||||
	meta/meta-background.h			\
 | 
			
		||||
	meta/meta-background-actor.h		\
 | 
			
		||||
	meta/meta-background-image.h		\
 | 
			
		||||
	meta/meta-background-group.h		\
 | 
			
		||||
	meta/meta-plugin.h			\
 | 
			
		||||
	meta/meta-shadow-factory.h		\
 | 
			
		||||
@@ -175,8 +151,8 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	meta/errors.h				\
 | 
			
		||||
	core/frame.c				\
 | 
			
		||||
	core/frame.h				\
 | 
			
		||||
	core/meta-gesture-tracker.c		\
 | 
			
		||||
	core/meta-gesture-tracker-private.h	\
 | 
			
		||||
	ui/gradient.c				\
 | 
			
		||||
	meta/gradient.h				\
 | 
			
		||||
	core/keybindings.c			\
 | 
			
		||||
	core/keybindings-private.h		\
 | 
			
		||||
	core/main.c				\
 | 
			
		||||
@@ -188,7 +164,6 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	core/screen-private.h			\
 | 
			
		||||
	meta/screen.h				\
 | 
			
		||||
	meta/types.h				\
 | 
			
		||||
	core/restart.c				\
 | 
			
		||||
	core/stack.c				\
 | 
			
		||||
	core/stack.h				\
 | 
			
		||||
	core/stack-tracker.c			\
 | 
			
		||||
@@ -206,6 +181,13 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	ui/ui.h					\
 | 
			
		||||
	ui/frames.c				\
 | 
			
		||||
	ui/frames.h				\
 | 
			
		||||
	ui/menu.c				\
 | 
			
		||||
	ui/menu.h				\
 | 
			
		||||
	ui/metaaccellabel.c			\
 | 
			
		||||
	ui/metaaccellabel.h			\
 | 
			
		||||
	ui/resizepopup.c			\
 | 
			
		||||
	ui/resizepopup.h			\
 | 
			
		||||
	ui/theme-parser.c			\
 | 
			
		||||
	ui/theme.c				\
 | 
			
		||||
	meta/theme.h				\
 | 
			
		||||
	ui/theme-private.h			\
 | 
			
		||||
@@ -214,8 +196,6 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	x11/iconcache.h				\
 | 
			
		||||
	x11/async-getprop.c			\
 | 
			
		||||
	x11/async-getprop.h			\
 | 
			
		||||
	x11/events.c				\
 | 
			
		||||
	x11/events.h				\
 | 
			
		||||
	x11/group-private.h			\
 | 
			
		||||
	x11/group-props.c			\
 | 
			
		||||
	x11/group-props.h			\
 | 
			
		||||
@@ -231,75 +211,37 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	x11/xprops.c				\
 | 
			
		||||
	x11/xprops.h				\
 | 
			
		||||
	x11/mutter-Xatomtype.h			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if HAVE_WAYLAND
 | 
			
		||||
libmutter_la_SOURCES +=				\
 | 
			
		||||
	compositor/meta-surface-actor-wayland.c	\
 | 
			
		||||
	compositor/meta-surface-actor-wayland.h	\
 | 
			
		||||
	wayland/meta-wayland.c			\
 | 
			
		||||
	wayland/meta-wayland.h			\
 | 
			
		||||
	wayland/meta-wayland-private.h		\
 | 
			
		||||
	wayland/meta-xwayland.c			\
 | 
			
		||||
	wayland/meta-xwayland.h			\
 | 
			
		||||
	wayland/meta-xwayland-private.h		\
 | 
			
		||||
	wayland/meta-wayland-buffer.c      	\
 | 
			
		||||
	wayland/meta-wayland-buffer.h      	\
 | 
			
		||||
	wayland/meta-wayland-region.c      	\
 | 
			
		||||
	wayland/meta-wayland-region.h      	\
 | 
			
		||||
	wayland/meta-xwayland.c			\
 | 
			
		||||
	wayland/meta-wayland-data-device.c      \
 | 
			
		||||
	wayland/meta-wayland-data-device.h      \
 | 
			
		||||
	wayland/meta-wayland-keyboard.c		\
 | 
			
		||||
	wayland/meta-wayland-keyboard.h		\
 | 
			
		||||
	wayland/meta-wayland-pointer.c		\
 | 
			
		||||
	wayland/meta-wayland-pointer.h		\
 | 
			
		||||
	wayland/meta-wayland-popup.c		\
 | 
			
		||||
	wayland/meta-wayland-popup.h		\
 | 
			
		||||
	wayland/meta-wayland-seat.c		\
 | 
			
		||||
	wayland/meta-wayland-seat.h		\
 | 
			
		||||
	wayland/meta-wayland-touch.c		\
 | 
			
		||||
	wayland/meta-wayland-touch.h		\
 | 
			
		||||
	wayland/meta-wayland-stage.h		\
 | 
			
		||||
	wayland/meta-wayland-stage.c		\
 | 
			
		||||
	wayland/meta-wayland-surface.c		\
 | 
			
		||||
	wayland/meta-wayland-surface.h		\
 | 
			
		||||
	wayland/meta-wayland-types.h		\
 | 
			
		||||
	wayland/meta-wayland-versions.h		\
 | 
			
		||||
	wayland/meta-wayland-outputs.c		\
 | 
			
		||||
	wayland/meta-wayland-outputs.h		\
 | 
			
		||||
	wayland/window-wayland.c		\
 | 
			
		||||
	wayland/window-wayland.h		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
endif
 | 
			
		||||
	wayland/window-wayland.h
 | 
			
		||||
 | 
			
		||||
if HAVE_NATIVE_BACKEND
 | 
			
		||||
libmutter_la_SOURCES +=					\
 | 
			
		||||
	backends/native/meta-backend-native.c		\
 | 
			
		||||
	backends/native/meta-backend-native.h		\
 | 
			
		||||
	backends/native/meta-backend-native-private.h	\
 | 
			
		||||
	backends/native/meta-barrier-native.c		\
 | 
			
		||||
	backends/native/meta-barrier-native.h		\
 | 
			
		||||
	backends/native/meta-cursor-renderer-native.c	\
 | 
			
		||||
	backends/native/meta-cursor-renderer-native.h	\
 | 
			
		||||
	backends/native/meta-idle-monitor-native.c	\
 | 
			
		||||
	backends/native/meta-idle-monitor-native.h	\
 | 
			
		||||
	backends/native/meta-input-settings-native.c	\
 | 
			
		||||
	backends/native/meta-input-settings-native.h	\
 | 
			
		||||
	backends/native/meta-monitor-manager-kms.c	\
 | 
			
		||||
	backends/native/meta-monitor-manager-kms.h	\
 | 
			
		||||
	backends/native/meta-launcher.c			\
 | 
			
		||||
	backends/native/meta-launcher.h			\
 | 
			
		||||
	backends/native/dbus-utils.c			\
 | 
			
		||||
	backends/native/dbus-utils.h			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
endif
 | 
			
		||||
nodist_libmutter_wayland_la_SOURCES =		\
 | 
			
		||||
	$(mutter_built_sources)
 | 
			
		||||
 | 
			
		||||
nodist_libmutter_la_SOURCES = $(mutter_built_sources)
 | 
			
		||||
 | 
			
		||||
libmutter_la_LDFLAGS = -no-undefined -export-symbols-regex "^(meta|ag)_.*"
 | 
			
		||||
libmutter_la_LIBADD  = $(MUTTER_LIBS) $(MUTTER_NATIVE_BACKEND_LIBS)
 | 
			
		||||
libmutter_wayland_la_LDFLAGS = -no-undefined
 | 
			
		||||
libmutter_wayland_la_LIBADD  = $(MUTTER_LIBS)
 | 
			
		||||
 | 
			
		||||
# Headers installed for plugins; introspected information will
 | 
			
		||||
# be extracted into Mutter-<version>.gir
 | 
			
		||||
libmutterinclude_headers =			\
 | 
			
		||||
libmutterinclude_base_headers =		\
 | 
			
		||||
	meta/barrier.h				\
 | 
			
		||||
	meta/boxes.h				\
 | 
			
		||||
	meta/common.h				\
 | 
			
		||||
@@ -307,18 +249,16 @@ libmutterinclude_headers =			\
 | 
			
		||||
	meta/compositor.h			\
 | 
			
		||||
	meta/display.h				\
 | 
			
		||||
	meta/errors.h				\
 | 
			
		||||
	meta/gradient.h				\
 | 
			
		||||
	meta/group.h				\
 | 
			
		||||
	meta/keybindings.h			\
 | 
			
		||||
	meta/main.h				\
 | 
			
		||||
	meta/meta-backend.h			\
 | 
			
		||||
	meta/meta-background.h			\
 | 
			
		||||
	meta/meta-background-actor.h		\
 | 
			
		||||
	meta/meta-background-image.h		\
 | 
			
		||||
	meta/meta-background-group.h		\
 | 
			
		||||
	meta/meta-background.h			\
 | 
			
		||||
	meta/meta-cursor-tracker.h		\
 | 
			
		||||
	meta/meta-idle-monitor.h		\
 | 
			
		||||
	meta/meta-plugin.h			\
 | 
			
		||||
	meta/meta-monitor-manager.h		\
 | 
			
		||||
	meta/meta-shaped-texture.h		\
 | 
			
		||||
	meta/meta-shadow-factory.h		\
 | 
			
		||||
	meta/meta-window-actor.h		\
 | 
			
		||||
@@ -328,41 +268,36 @@ libmutterinclude_headers =			\
 | 
			
		||||
	meta/types.h				\
 | 
			
		||||
	meta/util.h				\
 | 
			
		||||
	meta/window.h				\
 | 
			
		||||
	meta/workspace.h			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
libmutterinclude_built_headers =		\
 | 
			
		||||
	meta/meta-version.h
 | 
			
		||||
 | 
			
		||||
libmutterinclude_base_headers =			\
 | 
			
		||||
	$(libmutterinclude_headers)		\
 | 
			
		||||
	$(libmutterinclude_built_headers)
 | 
			
		||||
	meta/workspace.h
 | 
			
		||||
 | 
			
		||||
# Excluded from scanning for introspection but installed
 | 
			
		||||
# atomnames.h: macros cause problems for scanning process
 | 
			
		||||
libmutterinclude_extra_headers =		\
 | 
			
		||||
	meta/atomnames.h
 | 
			
		||||
 | 
			
		||||
libmutterincludedir = $(includedir)/mutter/meta
 | 
			
		||||
libmutterincludedir = $(includedir)/mutter-wayland/meta
 | 
			
		||||
 | 
			
		||||
libmutterinclude_HEADERS =			\
 | 
			
		||||
	$(libmutterinclude_headers)		\
 | 
			
		||||
	$(libmutterinclude_base_headers)	\
 | 
			
		||||
	$(libmutterinclude_extra_headers)
 | 
			
		||||
 | 
			
		||||
nodist_libmutterinclude_HEADERS =		\
 | 
			
		||||
	$(libmutterinclude_built_headers)
 | 
			
		||||
bin_PROGRAMS=mutter-wayland
 | 
			
		||||
 | 
			
		||||
bin_PROGRAMS=mutter
 | 
			
		||||
noinst_PROGRAMS=
 | 
			
		||||
mutter_wayland_SOURCES = core/mutter.c
 | 
			
		||||
mutter_wayland_LDADD = $(MUTTER_LIBS) libmutter-wayland.la
 | 
			
		||||
 | 
			
		||||
mutter_SOURCES = core/mutter.c
 | 
			
		||||
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
 | 
			
		||||
bin_PROGRAMS+=mutter-launch
 | 
			
		||||
 | 
			
		||||
libexec_PROGRAMS = mutter-restart-helper
 | 
			
		||||
mutter_restart_helper_SOURCES = core/restart-helper.c
 | 
			
		||||
mutter_restart_helper_LDADD = $(MUTTER_LIBS)
 | 
			
		||||
mutter_launch_SOURCES = 			\
 | 
			
		||||
	backends/native/weston-launch.c 	\
 | 
			
		||||
	backends/native/weston-launch.h
 | 
			
		||||
 | 
			
		||||
include Makefile-tests.am
 | 
			
		||||
mutter_launch_CFLAGS = $(MUTTER_LAUNCH_CFLAGS) -DLIBDIR=\"$(libdir)\"
 | 
			
		||||
mutter_launch_LDFLAGS = $(MUTTER_LAUNCH_LIBS) -lpam
 | 
			
		||||
 | 
			
		||||
install-exec-hook:
 | 
			
		||||
	-chown root $(DESTDIR)$(bindir)/mutter-launch
 | 
			
		||||
	-chmod u+s $(DESTDIR)$(bindir)/mutter-launch
 | 
			
		||||
 | 
			
		||||
if HAVE_INTROSPECTION
 | 
			
		||||
include $(INTROSPECTION_MAKEFILE)
 | 
			
		||||
@@ -384,46 +319,83 @@ typelib_DATA = Meta-$(api_version).typelib
 | 
			
		||||
 | 
			
		||||
INTROSPECTION_GIRS = Meta-$(api_version).gir
 | 
			
		||||
 | 
			
		||||
Meta-$(api_version).gir: libmutter.la
 | 
			
		||||
Meta-$(api_version).gir: libmutter-wayland.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 Cogl-1.0
 | 
			
		||||
@META_GIR@_EXPORT_PACKAGES = libmutter
 | 
			
		||||
@META_GIR@_CFLAGS = $(AM_CPPFLAGS)
 | 
			
		||||
@META_GIR@_LIBS = libmutter.la
 | 
			
		||||
@META_GIR@_EXPORT_PACKAGES = libmutter-wayland
 | 
			
		||||
@META_GIR@_CFLAGS = $(INCLUDES)
 | 
			
		||||
@META_GIR@_LIBS = libmutter-wayland.la
 | 
			
		||||
@META_GIR@_FILES =				\
 | 
			
		||||
	mutter-enum-types.h			\
 | 
			
		||||
	$(libmutterinclude_base_headers)	\
 | 
			
		||||
	$(filter %.c,$(libmutter_la_SOURCES) $(nodist_libmutter_la_SOURCES))
 | 
			
		||||
	$(filter %.c,$(libmutter_wayland_la_SOURCES) $(nodist_libmutter_wayland_la_SOURCES))
 | 
			
		||||
@META_GIR@_SCANNERFLAGS = --warn-all --warn-error
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
testboxes_SOURCES = core/testboxes.c
 | 
			
		||||
testgradient_SOURCES = ui/testgradient.c
 | 
			
		||||
testasyncgetprop_SOURCES = x11/testasyncgetprop.c
 | 
			
		||||
 | 
			
		||||
noinst_PROGRAMS=testboxes testgradient testasyncgetprop
 | 
			
		||||
 | 
			
		||||
testboxes_LDADD = $(MUTTER_LIBS) libmutter-wayland.la
 | 
			
		||||
testgradient_LDADD = $(MUTTER_LIBS) libmutter-wayland.la
 | 
			
		||||
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter-wayland.la
 | 
			
		||||
 | 
			
		||||
@INTLTOOL_DESKTOP_RULE@
 | 
			
		||||
 | 
			
		||||
desktopfilesdir=$(datadir)/applications
 | 
			
		||||
desktopfiles_in_files=mutter-wayland.desktop.in
 | 
			
		||||
desktopfiles_files=$(desktopfiles_in_files:.desktop.in=.desktop)
 | 
			
		||||
desktopfiles_DATA = $(desktopfiles_files)
 | 
			
		||||
 | 
			
		||||
xmldir       = @GNOME_KEYBINDINGS_KEYSDIR@
 | 
			
		||||
xml_in_files = \
 | 
			
		||||
        50-mutter-navigation.xml.in	\
 | 
			
		||||
        50-mutter-system.xml.in		\
 | 
			
		||||
        50-mutter-windows.xml.in
 | 
			
		||||
xml_DATA     = $(xml_in_files:.xml.in=.xml)
 | 
			
		||||
 | 
			
		||||
dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
 | 
			
		||||
 | 
			
		||||
gsettings_SCHEMAS = org.gnome.mutter.gschema.xml org.gnome.mutter.wayland.gschema.xml
 | 
			
		||||
@INTLTOOL_XML_NOMERGE_RULE@
 | 
			
		||||
@GSETTINGS_RULES@
 | 
			
		||||
 | 
			
		||||
convertdir = $(datadir)/GConf/gsettings
 | 
			
		||||
convert_DATA = mutter-schemas.convert
 | 
			
		||||
 | 
			
		||||
CLEANFILES =					\
 | 
			
		||||
	mutter-wayland.desktop			\
 | 
			
		||||
	mutter-wm.desktop			\
 | 
			
		||||
	org.gnome.mutter.gschema.xml		\
 | 
			
		||||
	org.gnome.mutter.wayland.gschema.xml	\
 | 
			
		||||
	$(xml_DATA)				\
 | 
			
		||||
	$(mutter_built_sources)			\
 | 
			
		||||
	$(typelib_DATA)				\
 | 
			
		||||
	$(gir_DATA)
 | 
			
		||||
 | 
			
		||||
DISTCLEANFILES = 				\
 | 
			
		||||
	$(libmutterinclude_built_headers)
 | 
			
		||||
 | 
			
		||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
			
		||||
pkgconfig_DATA = libmutter.pc
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST +=					\
 | 
			
		||||
	$(wayland_protocols)			\
 | 
			
		||||
	libmutter.pc.in				\
 | 
			
		||||
	mutter-enum-types.h.in			\
 | 
			
		||||
	mutter-enum-types.c.in			\
 | 
			
		||||
	org.freedesktop.login1.xml		\
 | 
			
		||||
pkgconfig_DATA = libmutter-wayland.pc
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST=$(desktopfiles_files) 	\
 | 
			
		||||
	$(wmproperties_files)		\
 | 
			
		||||
	$(IMAGES) 			\
 | 
			
		||||
	$(desktopfiles_in_files)	\
 | 
			
		||||
	$(wmproperties_in_files)	\
 | 
			
		||||
	$(xml_in_files)			\
 | 
			
		||||
	$(wayland_protocols)		\
 | 
			
		||||
	org.gnome.mutter.gschema.xml.in \
 | 
			
		||||
	org.gnome.mutter.wayland.gschema.xml.in \
 | 
			
		||||
	mutter-schemas.convert \
 | 
			
		||||
	libmutter-wayland.pc.in \
 | 
			
		||||
	mutter-enum-types.h.in \
 | 
			
		||||
	mutter-enum-types.c.in \
 | 
			
		||||
	org.gnome.Mutter.DisplayConfig.xml	\
 | 
			
		||||
	org.gnome.Mutter.IdleMonitor.xml	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES =					\
 | 
			
		||||
	$(mutter_built_sources)			\
 | 
			
		||||
	$(libmutterinclude_built_headers)
 | 
			
		||||
	org.gnome.Mutter.IdleMonitor.xml
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES = $(mutter_built_sources)
 | 
			
		||||
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
 | 
			
		||||
CLEANFILES += $(MUTTER_STAMP_FILES)
 | 
			
		||||
 | 
			
		||||
@@ -463,15 +435,6 @@ $(dbus_idle_built_sources) : Makefile.am org.gnome.Mutter.IdleMonitor.xml
 | 
			
		||||
		--c-generate-object-manager						\
 | 
			
		||||
		$(srcdir)/org.gnome.Mutter.IdleMonitor.xml
 | 
			
		||||
 | 
			
		||||
dbus_login1_built_sources = meta-dbus-login1.c meta-dbus-login1.h
 | 
			
		||||
 | 
			
		||||
$(dbus_login1_built_sources) : Makefile.am org.freedesktop.login1.xml
 | 
			
		||||
	$(AM_V_GEN)gdbus-codegen							\
 | 
			
		||||
		--interface-prefix org.freedesktop.login1				\
 | 
			
		||||
		--c-namespace Login1							\
 | 
			
		||||
		--generate-c-code meta-dbus-login1					\
 | 
			
		||||
		$(srcdir)/org.freedesktop.login1.xml
 | 
			
		||||
 | 
			
		||||
%-protocol.c : $(srcdir)/wayland/protocol/%.xml
 | 
			
		||||
	$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
 | 
			
		||||
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml
 | 
			
		||||
 
 | 
			
		||||
@@ -179,7 +179,7 @@ decode_display_parameters (const uchar *edid, MonitorInfo *info)
 | 
			
		||||
  else if (edid[0x16] == 0)
 | 
			
		||||
    {
 | 
			
		||||
      info->width_mm = -1;
 | 
			
		||||
      info->height_mm = -1;
 | 
			
		||||
      info->height_mm = -1; 
 | 
			
		||||
      info->aspect_ratio = 100.0 / (edid[0x15] + 99);
 | 
			
		||||
    }
 | 
			
		||||
  else if (edid[0x15] == 0)
 | 
			
		||||
@@ -267,7 +267,7 @@ decode_color_characteristics (const uchar *edid, MonitorInfo *info)
 | 
			
		||||
static int
 | 
			
		||||
decode_established_timings (const uchar *edid, MonitorInfo *info)
 | 
			
		||||
{
 | 
			
		||||
  static const Timing established[][8] =
 | 
			
		||||
  static const Timing established[][8] = 
 | 
			
		||||
    {
 | 
			
		||||
      {
 | 
			
		||||
        { 800, 600, 60 },
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
/* edid.h
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright 2007, 2008, Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * This file is part of the Gnome Library.
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * The Gnome Library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Library General Public License as
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
@@ -13,12 +13,12 @@
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Library General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * You should have received a copy of the GNU Library General Public
 | 
			
		||||
 * License along with the Gnome Library; see the file COPYING.LIB.  If not,
 | 
			
		||||
 * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 | 
			
		||||
 * Boston, MA 02110-1301, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * 
 | 
			
		||||
 * Author: Soren Sandmann <sandmann@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@@ -177,7 +177,7 @@ struct MonitorInfo
 | 
			
		||||
  DetailedTiming detailed_timings[4];	/* If monitor has a preferred
 | 
			
		||||
                                         * mode, it is the first one
 | 
			
		||||
                                         * (whether it has, is
 | 
			
		||||
                                         * determined by the
 | 
			
		||||
                                         * determined by the 
 | 
			
		||||
                                         * preferred_timing_includes
 | 
			
		||||
                                         * bit.
 | 
			
		||||
                                         */
 | 
			
		||||
@@ -189,5 +189,7 @@ struct MonitorInfo
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MonitorInfo *decode_edid (const uchar *data);
 | 
			
		||||
char *make_display_name (const MonitorInfo *info);
 | 
			
		||||
char *make_display_size_string (int width_mm, int height_mm);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,113 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef META_BACKEND_PRIVATE_H
 | 
			
		||||
#define META_BACKEND_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include <xkbcommon/xkbcommon.h>
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-backend.h>
 | 
			
		||||
#include <meta/meta-idle-monitor.h>
 | 
			
		||||
#include "meta-cursor-renderer.h"
 | 
			
		||||
#include "meta-monitor-manager-private.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_XKB_RULES_FILE "evdev"
 | 
			
		||||
#define DEFAULT_XKB_MODEL "pc105+inet"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_BACKEND             (meta_backend_get_type ())
 | 
			
		||||
#define META_BACKEND(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKEND, MetaBackend))
 | 
			
		||||
#define META_BACKEND_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_BACKEND, MetaBackendClass))
 | 
			
		||||
#define META_IS_BACKEND(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BACKEND))
 | 
			
		||||
#define META_IS_BACKEND_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_BACKEND))
 | 
			
		||||
#define META_BACKEND_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_BACKEND, MetaBackendClass))
 | 
			
		||||
 | 
			
		||||
struct _MetaBackend
 | 
			
		||||
{
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  GHashTable *device_monitors;
 | 
			
		||||
  gint current_device_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaBackendClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  void (* post_init) (MetaBackend *backend);
 | 
			
		||||
 | 
			
		||||
  MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend,
 | 
			
		||||
                                             int          device_id);
 | 
			
		||||
  MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend);
 | 
			
		||||
  MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend);
 | 
			
		||||
 | 
			
		||||
  gboolean (* grab_device) (MetaBackend *backend,
 | 
			
		||||
                            int          device_id,
 | 
			
		||||
                            uint32_t     timestamp);
 | 
			
		||||
  gboolean (* ungrab_device) (MetaBackend *backend,
 | 
			
		||||
                              int          device_id,
 | 
			
		||||
                              uint32_t     timestamp);
 | 
			
		||||
 | 
			
		||||
  void (* warp_pointer) (MetaBackend *backend,
 | 
			
		||||
                         int          x,
 | 
			
		||||
                         int          y);
 | 
			
		||||
 | 
			
		||||
  void (* set_keymap) (MetaBackend *backend,
 | 
			
		||||
                       const char  *layouts,
 | 
			
		||||
                       const char  *variants,
 | 
			
		||||
                       const char  *options);
 | 
			
		||||
 | 
			
		||||
  struct xkb_keymap * (* get_keymap) (MetaBackend *backend);
 | 
			
		||||
 | 
			
		||||
  void (* lock_layout_group) (MetaBackend *backend,
 | 
			
		||||
                              guint        idx);
 | 
			
		||||
 | 
			
		||||
  void (* update_screen_size) (MetaBackend *backend, int width, int height);
 | 
			
		||||
  void (* select_stage_events) (MetaBackend *backend);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
 | 
			
		||||
                                                 int          device_id);
 | 
			
		||||
MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend);
 | 
			
		||||
MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
 | 
			
		||||
 | 
			
		||||
gboolean meta_backend_grab_device (MetaBackend *backend,
 | 
			
		||||
                                   int          device_id,
 | 
			
		||||
                                   uint32_t     timestamp);
 | 
			
		||||
gboolean meta_backend_ungrab_device (MetaBackend *backend,
 | 
			
		||||
                                     int          device_id,
 | 
			
		||||
                                     uint32_t     timestamp);
 | 
			
		||||
 | 
			
		||||
void meta_backend_warp_pointer (MetaBackend *backend,
 | 
			
		||||
                                int          x,
 | 
			
		||||
                                int          y);
 | 
			
		||||
 | 
			
		||||
struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
 | 
			
		||||
 | 
			
		||||
void meta_backend_update_last_device (MetaBackend *backend,
 | 
			
		||||
                                      int          device_id);
 | 
			
		||||
 | 
			
		||||
#endif /* META_BACKEND_PRIVATE_H */
 | 
			
		||||
@@ -24,547 +24,15 @@
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-backend.h>
 | 
			
		||||
#include "meta-backend-private.h"
 | 
			
		||||
#include "meta-input-settings-private.h"
 | 
			
		||||
#include "meta-backend.h"
 | 
			
		||||
#include <meta/main.h>
 | 
			
		||||
 | 
			
		||||
#include "backends/x11/meta-backend-x11.h"
 | 
			
		||||
#include "meta-cursor-tracker-private.h"
 | 
			
		||||
#include "meta-stage.h"
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <clutter/x11/clutter-x11.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
#include "backends/native/meta-backend-native.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "backends/meta-idle-monitor-private.h"
 | 
			
		||||
 | 
			
		||||
#include "backends/meta-monitor-manager-dummy.h"
 | 
			
		||||
 | 
			
		||||
static MetaBackend *_backend;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_get_backend:
 | 
			
		||||
 *
 | 
			
		||||
 * Accessor for the singleton MetaBackend.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): The only #MetaBackend there is.
 | 
			
		||||
 */
 | 
			
		||||
MetaBackend *
 | 
			
		||||
meta_get_backend (void)
 | 
			
		||||
{
 | 
			
		||||
  return _backend;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct _MetaBackendPrivate
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManager *monitor_manager;
 | 
			
		||||
  MetaCursorRenderer *cursor_renderer;
 | 
			
		||||
  MetaInputSettings *input_settings;
 | 
			
		||||
 | 
			
		||||
  ClutterActor *stage;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _MetaBackendPrivate MetaBackendPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaBackend, meta_backend, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = META_BACKEND (object);
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
 | 
			
		||||
  g_clear_object (&priv->monitor_manager);
 | 
			
		||||
  g_clear_object (&priv->input_settings);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_destroy (backend->device_monitors);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_sync_screen_size (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
  int width, height;
 | 
			
		||||
 | 
			
		||||
  meta_monitor_manager_get_screen_size (priv->monitor_manager, &width, &height);
 | 
			
		||||
 | 
			
		||||
  META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
center_pointer (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
  MetaMonitorInfo *monitors, *primary;
 | 
			
		||||
  guint n_monitors;
 | 
			
		||||
 | 
			
		||||
  monitors = meta_monitor_manager_get_monitor_infos (priv->monitor_manager, &n_monitors);
 | 
			
		||||
  primary = &monitors[meta_monitor_manager_get_primary_index (priv->monitor_manager)];
 | 
			
		||||
  meta_backend_warp_pointer (backend,
 | 
			
		||||
                             primary->rect.x + primary->rect.width / 2,
 | 
			
		||||
                             primary->rect.y + primary->rect.height / 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_monitors_changed (MetaMonitorManager *monitors,
 | 
			
		||||
                     gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = META_BACKEND (user_data);
 | 
			
		||||
  ClutterDeviceManager *manager = clutter_device_manager_get_default ();
 | 
			
		||||
  ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
 | 
			
		||||
  ClutterPoint point;
 | 
			
		||||
 | 
			
		||||
  meta_backend_sync_screen_size (backend);
 | 
			
		||||
 | 
			
		||||
  if (clutter_input_device_get_coords (device, NULL, &point))
 | 
			
		||||
    {
 | 
			
		||||
      /* If we're outside all monitors, warp the pointer back inside */
 | 
			
		||||
      if (meta_monitor_manager_get_monitor_at_point (monitors, point.x, point.y) < 0)
 | 
			
		||||
        center_pointer (backend);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaIdleMonitor *
 | 
			
		||||
meta_backend_create_idle_monitor (MetaBackend *backend,
 | 
			
		||||
                                  int          device_id)
 | 
			
		||||
{
 | 
			
		||||
  return META_BACKEND_GET_CLASS (backend)->create_idle_monitor (backend, device_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_device_monitor (MetaBackend *backend,
 | 
			
		||||
                       int          device_id)
 | 
			
		||||
{
 | 
			
		||||
  MetaIdleMonitor *idle_monitor;
 | 
			
		||||
 | 
			
		||||
  g_assert (g_hash_table_lookup (backend->device_monitors, &device_id) == NULL);
 | 
			
		||||
 | 
			
		||||
  idle_monitor = meta_backend_create_idle_monitor (backend, device_id);
 | 
			
		||||
  g_hash_table_insert (backend->device_monitors, &idle_monitor->device_id, idle_monitor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_device_monitor (MetaBackend *backend,
 | 
			
		||||
                        int          device_id)
 | 
			
		||||
{
 | 
			
		||||
  g_hash_table_remove (backend->device_monitors, &device_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_device_added (ClutterDeviceManager *device_manager,
 | 
			
		||||
                 ClutterInputDevice   *device,
 | 
			
		||||
                 gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = META_BACKEND (user_data);
 | 
			
		||||
  int device_id = clutter_input_device_get_device_id (device);
 | 
			
		||||
 | 
			
		||||
  create_device_monitor (backend, device_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline gboolean
 | 
			
		||||
device_is_slave_touchscreen (ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  return (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER &&
 | 
			
		||||
          clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline gboolean
 | 
			
		||||
check_has_pointing_device (ClutterDeviceManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  const GSList *devices;
 | 
			
		||||
 | 
			
		||||
  devices = clutter_device_manager_peek_devices (manager);
 | 
			
		||||
 | 
			
		||||
  for (; devices; devices = devices->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterInputDevice *device = devices->data;
 | 
			
		||||
 | 
			
		||||
      if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
 | 
			
		||||
        continue;
 | 
			
		||||
      if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE ||
 | 
			
		||||
          clutter_input_device_get_device_type (device) == CLUTTER_KEYBOARD_DEVICE)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline gboolean
 | 
			
		||||
check_has_slave_touchscreen (ClutterDeviceManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  const GSList *devices;
 | 
			
		||||
 | 
			
		||||
  devices = clutter_device_manager_peek_devices (manager);
 | 
			
		||||
 | 
			
		||||
  for (; devices; devices = devices->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterInputDevice *device = devices->data;
 | 
			
		||||
 | 
			
		||||
      if (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER &&
 | 
			
		||||
          clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE)
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
on_device_removed (ClutterDeviceManager *device_manager,
 | 
			
		||||
                   ClutterInputDevice   *device,
 | 
			
		||||
                   gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = META_BACKEND (user_data);
 | 
			
		||||
  int device_id = clutter_input_device_get_device_id (device);
 | 
			
		||||
 | 
			
		||||
  destroy_device_monitor (backend, device_id);
 | 
			
		||||
 | 
			
		||||
  /* If the device the user last interacted goes away, check again pointer
 | 
			
		||||
   * visibility.
 | 
			
		||||
   */
 | 
			
		||||
  if (backend->current_device_id == device_id)
 | 
			
		||||
    {
 | 
			
		||||
      MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
 | 
			
		||||
      gboolean has_touchscreen, has_pointing_device;
 | 
			
		||||
      ClutterInputDeviceType device_type;
 | 
			
		||||
 | 
			
		||||
      device_type = clutter_input_device_get_device_type (device);
 | 
			
		||||
      has_touchscreen = check_has_slave_touchscreen (device_manager);
 | 
			
		||||
 | 
			
		||||
      if (device_type == CLUTTER_TOUCHSCREEN_DEVICE && has_touchscreen)
 | 
			
		||||
        {
 | 
			
		||||
          /* There's more touchscreens left, keep the pointer hidden */
 | 
			
		||||
          meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE);
 | 
			
		||||
        }
 | 
			
		||||
      else if (device_type != CLUTTER_KEYBOARD_DEVICE)
 | 
			
		||||
        {
 | 
			
		||||
          has_pointing_device = check_has_pointing_device (device_manager);
 | 
			
		||||
          meta_cursor_tracker_set_pointer_visible (cursor_tracker,
 | 
			
		||||
                                                   has_pointing_device &&
 | 
			
		||||
                                                   !has_touchscreen);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaMonitorManager *
 | 
			
		||||
create_monitor_manager (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  if (g_getenv ("META_DUMMY_MONITORS"))
 | 
			
		||||
    return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
 | 
			
		||||
 | 
			
		||||
  return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_real_post_init (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
 | 
			
		||||
  priv->stage = meta_stage_new ();
 | 
			
		||||
  clutter_actor_realize (priv->stage);
 | 
			
		||||
  META_BACKEND_GET_CLASS (backend)->select_stage_events (backend);
 | 
			
		||||
 | 
			
		||||
  priv->monitor_manager = create_monitor_manager (backend);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect (priv->monitor_manager, "monitors-changed",
 | 
			
		||||
                    G_CALLBACK (on_monitors_changed), backend);
 | 
			
		||||
  meta_backend_sync_screen_size (backend);
 | 
			
		||||
 | 
			
		||||
  priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
 | 
			
		||||
 | 
			
		||||
  backend->device_monitors = g_hash_table_new_full (g_int_hash, g_int_equal,
 | 
			
		||||
                                                    NULL, (GDestroyNotify) g_object_unref);
 | 
			
		||||
 | 
			
		||||
  {
 | 
			
		||||
    MetaCursorTracker *cursor_tracker;
 | 
			
		||||
    ClutterDeviceManager *manager;
 | 
			
		||||
    gboolean has_touchscreen = FALSE;
 | 
			
		||||
    GSList *devices, *l;
 | 
			
		||||
 | 
			
		||||
    /* Create the core device monitor. */
 | 
			
		||||
    create_device_monitor (backend, 0);
 | 
			
		||||
 | 
			
		||||
    manager = clutter_device_manager_get_default ();
 | 
			
		||||
    g_signal_connect_object (manager, "device-added",
 | 
			
		||||
                             G_CALLBACK (on_device_added), backend, 0);
 | 
			
		||||
    g_signal_connect_object (manager, "device-removed",
 | 
			
		||||
                             G_CALLBACK (on_device_removed), backend, 0);
 | 
			
		||||
 | 
			
		||||
    devices = clutter_device_manager_list_devices (manager);
 | 
			
		||||
 | 
			
		||||
    for (l = devices; l != NULL; l = l->next)
 | 
			
		||||
      {
 | 
			
		||||
        ClutterInputDevice *device = l->data;
 | 
			
		||||
        on_device_added (manager, device, backend);
 | 
			
		||||
        has_touchscreen |= device_is_slave_touchscreen (device);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
 | 
			
		||||
    meta_cursor_tracker_set_pointer_visible (cursor_tracker, !has_touchscreen);
 | 
			
		||||
 | 
			
		||||
    g_slist_free (devices);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  priv->input_settings = meta_input_settings_create ();
 | 
			
		||||
 | 
			
		||||
  center_pointer (backend);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaCursorRenderer *
 | 
			
		||||
meta_backend_real_create_cursor_renderer (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  return meta_cursor_renderer_new ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_backend_real_grab_device (MetaBackend *backend,
 | 
			
		||||
                               int          device_id,
 | 
			
		||||
                               uint32_t     timestamp)
 | 
			
		||||
{
 | 
			
		||||
  /* Do nothing */
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_backend_real_ungrab_device (MetaBackend *backend,
 | 
			
		||||
                                 int          device_id,
 | 
			
		||||
                                 uint32_t     timestamp)
 | 
			
		||||
{
 | 
			
		||||
  /* Do nothing */
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_real_update_screen_size (MetaBackend *backend,
 | 
			
		||||
                                      int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_set_size (priv->stage, width, height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_real_select_stage_events (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  /* Do nothing */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_class_init (MetaBackendClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = meta_backend_finalize;
 | 
			
		||||
 | 
			
		||||
  klass->post_init = meta_backend_real_post_init;
 | 
			
		||||
  klass->create_cursor_renderer = meta_backend_real_create_cursor_renderer;
 | 
			
		||||
  klass->grab_device = meta_backend_real_grab_device;
 | 
			
		||||
  klass->ungrab_device = meta_backend_real_ungrab_device;
 | 
			
		||||
  klass->update_screen_size = meta_backend_real_update_screen_size;
 | 
			
		||||
  klass->select_stage_events = meta_backend_real_select_stage_events;
 | 
			
		||||
 | 
			
		||||
  g_signal_new ("keymap-changed",
 | 
			
		||||
                G_TYPE_FROM_CLASS (object_class),
 | 
			
		||||
                G_SIGNAL_RUN_LAST,
 | 
			
		||||
                0,
 | 
			
		||||
                NULL, NULL, NULL,
 | 
			
		||||
                G_TYPE_NONE, 0);
 | 
			
		||||
  g_signal_new ("keymap-layout-group-changed",
 | 
			
		||||
                G_TYPE_FROM_CLASS (object_class),
 | 
			
		||||
                G_SIGNAL_RUN_LAST,
 | 
			
		||||
                0,
 | 
			
		||||
                NULL, NULL, NULL,
 | 
			
		||||
                G_TYPE_NONE, 1, G_TYPE_UINT);
 | 
			
		||||
  g_signal_new ("last-device-changed",
 | 
			
		||||
                G_TYPE_FROM_CLASS (object_class),
 | 
			
		||||
                G_SIGNAL_RUN_LAST,
 | 
			
		||||
                0,
 | 
			
		||||
                NULL, NULL, NULL,
 | 
			
		||||
                G_TYPE_NONE, 1, G_TYPE_INT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_init (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  _backend = backend;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_post_init (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  META_BACKEND_GET_CLASS (backend)->post_init (backend);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_get_idle_monitor: (skip)
 | 
			
		||||
 */
 | 
			
		||||
MetaIdleMonitor *
 | 
			
		||||
meta_backend_get_idle_monitor (MetaBackend *backend,
 | 
			
		||||
                               int          device_id)
 | 
			
		||||
{
 | 
			
		||||
  return g_hash_table_lookup (backend->device_monitors, &device_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_get_monitor_manager: (skip)
 | 
			
		||||
 */
 | 
			
		||||
MetaMonitorManager *
 | 
			
		||||
meta_backend_get_monitor_manager (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
 | 
			
		||||
  return priv->monitor_manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_get_cursor_renderer: (skip)
 | 
			
		||||
 */
 | 
			
		||||
MetaCursorRenderer *
 | 
			
		||||
meta_backend_get_cursor_renderer (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
 | 
			
		||||
  return priv->cursor_renderer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_grab_device: (skip)
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
meta_backend_grab_device (MetaBackend *backend,
 | 
			
		||||
                          int          device_id,
 | 
			
		||||
                          uint32_t     timestamp)
 | 
			
		||||
{
 | 
			
		||||
  return META_BACKEND_GET_CLASS (backend)->grab_device (backend, device_id, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_ungrab_device: (skip)
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
meta_backend_ungrab_device (MetaBackend *backend,
 | 
			
		||||
                            int          device_id,
 | 
			
		||||
                            uint32_t     timestamp)
 | 
			
		||||
{
 | 
			
		||||
  return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_warp_pointer: (skip)
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_backend_warp_pointer (MetaBackend *backend,
 | 
			
		||||
                           int          x,
 | 
			
		||||
                           int          y)
 | 
			
		||||
{
 | 
			
		||||
  META_BACKEND_GET_CLASS (backend)->warp_pointer (backend, x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_backend_set_keymap (MetaBackend *backend,
 | 
			
		||||
                         const char  *layouts,
 | 
			
		||||
                         const char  *variants,
 | 
			
		||||
                         const char  *options)
 | 
			
		||||
{
 | 
			
		||||
  META_BACKEND_GET_CLASS (backend)->set_keymap (backend, layouts, variants, options);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_get_keymap: (skip)
 | 
			
		||||
 */
 | 
			
		||||
struct xkb_keymap *
 | 
			
		||||
meta_backend_get_keymap (MetaBackend *backend)
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
  return META_BACKEND_GET_CLASS (backend)->get_keymap (backend);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_backend_lock_layout_group (MetaBackend *backend,
 | 
			
		||||
                                guint idx)
 | 
			
		||||
{
 | 
			
		||||
  META_BACKEND_GET_CLASS (backend)->lock_layout_group (backend, idx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_backend_get_stage:
 | 
			
		||||
 * @backend: A #MetaBackend
 | 
			
		||||
 *
 | 
			
		||||
 * Gets the global #ClutterStage that's managed by this backend.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): the #ClutterStage
 | 
			
		||||
 */
 | 
			
		||||
ClutterActor *
 | 
			
		||||
meta_backend_get_stage (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 | 
			
		||||
  return priv->stage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_backend_update_last_device (MetaBackend *backend,
 | 
			
		||||
                                 int          device_id)
 | 
			
		||||
{
 | 
			
		||||
  ClutterInputDeviceType device_type;
 | 
			
		||||
  MetaCursorTracker *cursor_tracker;
 | 
			
		||||
  ClutterDeviceManager *manager;
 | 
			
		||||
  ClutterInputDevice *device;
 | 
			
		||||
 | 
			
		||||
  if (backend->current_device_id == device_id)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  manager = clutter_device_manager_get_default ();
 | 
			
		||||
  device = clutter_device_manager_get_device (manager, device_id);
 | 
			
		||||
 | 
			
		||||
  if (!device ||
 | 
			
		||||
      clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  device_type = clutter_input_device_get_device_type (device);
 | 
			
		||||
 | 
			
		||||
  cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
 | 
			
		||||
  backend->current_device_id = device_id;
 | 
			
		||||
  g_signal_emit_by_name (backend, "last-device-changed", device_id);
 | 
			
		||||
 | 
			
		||||
  if (device_type == CLUTTER_KEYBOARD_DEVICE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  switch (device_type)
 | 
			
		||||
    {
 | 
			
		||||
    case CLUTTER_TOUCHSCREEN_DEVICE:
 | 
			
		||||
      meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      meta_cursor_tracker_set_pointer_visible (cursor_tracker, TRUE);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GType
 | 
			
		||||
get_backend_type (void)
 | 
			
		||||
{
 | 
			
		||||
#if defined(CLUTTER_WINDOWING_X11)
 | 
			
		||||
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
 | 
			
		||||
    return META_TYPE_BACKEND_X11;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
 | 
			
		||||
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
 | 
			
		||||
    return META_TYPE_BACKEND_NATIVE;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  g_assert_not_reached ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_create_backend (void)
 | 
			
		||||
{
 | 
			
		||||
  /* meta_backend_init() above install the backend globally so
 | 
			
		||||
   * so meta_get_backend() works even during initialization. */
 | 
			
		||||
  g_object_new (get_backend_type (), NULL);
 | 
			
		||||
}
 | 
			
		||||
#include "backends/native/meta-weston-launch.h"
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
 | 
			
		||||
/* Mutter is responsible for pulling events off the X queue, so Clutter
 | 
			
		||||
 * doesn't need (and shouldn't) run its normal event source which polls
 | 
			
		||||
@@ -614,30 +82,76 @@ static GSourceFuncs event_funcs = {
 | 
			
		||||
  event_dispatch
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_clutter_init: (skip)
 | 
			
		||||
 */
 | 
			
		||||
static MetaLauncher *launcher;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_clutter_init (void)
 | 
			
		||||
{
 | 
			
		||||
  ClutterSettings *clutter_settings;
 | 
			
		||||
  GSource *source;
 | 
			
		||||
 | 
			
		||||
  meta_create_backend ();
 | 
			
		||||
  /* When running as an X11 compositor, we install our own event filter and
 | 
			
		||||
   * pass events to Clutter explicitly, so we need to prevent Clutter from
 | 
			
		||||
   * handling our events.
 | 
			
		||||
   *
 | 
			
		||||
   * However, when running as a Wayland compostior under X11 nested, Clutter
 | 
			
		||||
   * Clutter needs to see events related to its own window. We need to
 | 
			
		||||
   * eventually replace this with a proper frontend / backend split: Clutter
 | 
			
		||||
   * under nested is connecting to the "host X server" to get its events it
 | 
			
		||||
   * needs to put up a window, and GTK+ is connecting to the "inner X server".
 | 
			
		||||
   * The two would the same in the X11 compositor case, but not when running
 | 
			
		||||
   * XWayland as a Wayland compositor.
 | 
			
		||||
   */
 | 
			
		||||
  if (!meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      clutter_x11_set_display (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
 | 
			
		||||
      clutter_x11_disable_event_retrieval ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* If we're running on bare metal, we're a display server,
 | 
			
		||||
   * so start talking to weston-launch. */
 | 
			
		||||
#if defined(CLUTTER_WINDOWING_EGL)
 | 
			
		||||
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
 | 
			
		||||
    launcher = meta_launcher_new ();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
 | 
			
		||||
    g_error ("Unable to initialize Clutter.\n");
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * XXX: We cannot handle high dpi scaling yet, so fix the scale to 1
 | 
			
		||||
   * for now.
 | 
			
		||||
   */
 | 
			
		||||
  clutter_settings = clutter_settings_get_default ();
 | 
			
		||||
  g_object_set (clutter_settings, "window-scaling-factor", 1, NULL);
 | 
			
		||||
 | 
			
		||||
  source = g_source_new (&event_funcs, sizeof (GSource));
 | 
			
		||||
  g_source_attach (source, NULL);
 | 
			
		||||
  g_source_unref (source);
 | 
			
		||||
 | 
			
		||||
  meta_backend_post_init (_backend);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_activate_vt (int vt, GError **error)
 | 
			
		||||
{
 | 
			
		||||
  if (launcher)
 | 
			
		||||
    return meta_launcher_activate_vt (launcher, vt, error);
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      g_debug ("Ignoring VT switch keybinding, not running as display server");
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_activate_session:
 | 
			
		||||
 *
 | 
			
		||||
 * Tells mutter to activate the session. When mutter is a
 | 
			
		||||
 * Wayland compositor, this tells logind to switch over to
 | 
			
		||||
 * the new session.
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
meta_activate_session (void)
 | 
			
		||||
{
 | 
			
		||||
  GError *error = NULL;
 | 
			
		||||
 | 
			
		||||
  if (!meta_launcher_activate_vt (launcher, -1, &error))
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("Could not activate session: %s\n", error->message);
 | 
			
		||||
      g_error_free (error);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,11 +22,13 @@
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef DBUS_UTILS_H
 | 
			
		||||
#define DBUS_UTILS_H
 | 
			
		||||
#ifndef META_BACKEND_H
 | 
			
		||||
#define META_BACKEND_H
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
get_escaped_dbus_path (const char *prefix,
 | 
			
		||||
                       const char *component);
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#endif /* DBUS_UTILS_H */
 | 
			
		||||
void meta_clutter_init (void);
 | 
			
		||||
 | 
			
		||||
gboolean meta_activate_vt (int vt, GError **error);
 | 
			
		||||
 | 
			
		||||
#endif /* META_BACKEND_H */
 | 
			
		||||
@@ -1,81 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014-2015 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 *     Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_BARRIER_PRIVATE_H
 | 
			
		||||
#define META_BARRIER_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_BARRIER_IMPL            (meta_barrier_impl_get_type ())
 | 
			
		||||
#define META_BARRIER_IMPL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER_IMPL, MetaBarrierImpl))
 | 
			
		||||
#define META_BARRIER_IMPL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_BARRIER_IMPL, MetaBarrierImplClass))
 | 
			
		||||
#define META_IS_BARRIER_IMPL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER_IMPL))
 | 
			
		||||
#define META_IS_BARRIER_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_BARRIER_IMPL))
 | 
			
		||||
#define META_BARRIER_IMPL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_BARRIER_IMPL, MetaBarrierImplClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaBarrierImpl        MetaBarrierImpl;
 | 
			
		||||
typedef struct _MetaBarrierImplClass   MetaBarrierImplClass;
 | 
			
		||||
 | 
			
		||||
struct _MetaBarrierImpl
 | 
			
		||||
{
 | 
			
		||||
  GObject parent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaBarrierImplClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  gboolean (*is_active) (MetaBarrierImpl *barrier);
 | 
			
		||||
  void (*release) (MetaBarrierImpl  *barrier,
 | 
			
		||||
                   MetaBarrierEvent *event);
 | 
			
		||||
  void (*destroy) (MetaBarrierImpl *barrier);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType meta_barrier_impl_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void _meta_barrier_emit_hit_signal (MetaBarrier      *barrier,
 | 
			
		||||
                                    MetaBarrierEvent *event);
 | 
			
		||||
void _meta_barrier_emit_left_signal (MetaBarrier      *barrier,
 | 
			
		||||
                                     MetaBarrierEvent *event);
 | 
			
		||||
 | 
			
		||||
void meta_barrier_event_unref (MetaBarrierEvent *event);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
struct _MetaBarrierPrivate
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display;
 | 
			
		||||
 | 
			
		||||
  int x1;
 | 
			
		||||
  int y1;
 | 
			
		||||
  int x2;
 | 
			
		||||
  int y2;
 | 
			
		||||
 | 
			
		||||
  MetaBarrierDirection directions;
 | 
			
		||||
 | 
			
		||||
  MetaBarrierImpl *impl;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* META_BARRIER_PRIVATE_H */
 | 
			
		||||
@@ -25,24 +25,17 @@
 | 
			
		||||
#include "meta-cursor.h"
 | 
			
		||||
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
#include <gbm.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  CoglTexture2D *texture;
 | 
			
		||||
  int hot_x, hot_y;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
  struct gbm_bo *bo;
 | 
			
		||||
#endif
 | 
			
		||||
  int hot_x, hot_y;
 | 
			
		||||
} MetaCursorImage;
 | 
			
		||||
 | 
			
		||||
struct _MetaCursorReference {
 | 
			
		||||
  int ref_count;
 | 
			
		||||
 | 
			
		||||
  MetaCursor cursor;
 | 
			
		||||
  MetaCursorImage image;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -50,10 +43,8 @@ CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor
 | 
			
		||||
                                                     int                 *hot_x,
 | 
			
		||||
                                                     int                 *hot_y);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
 | 
			
		||||
                                                 int                 *hot_x,
 | 
			
		||||
                                                 int                 *hot_y);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* META_CURSOR_PRIVATE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,175 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "meta-cursor-renderer.h"
 | 
			
		||||
#include "meta-cursor-private.h"
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-backend.h>
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-stage.h"
 | 
			
		||||
 | 
			
		||||
struct _MetaCursorRendererPrivate
 | 
			
		||||
{
 | 
			
		||||
  int current_x, current_y;
 | 
			
		||||
  MetaRectangle current_rect;
 | 
			
		||||
 | 
			
		||||
  MetaCursorReference *displayed_cursor;
 | 
			
		||||
  gboolean handled_by_backend;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
queue_redraw (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
  ClutterActor *stage = meta_backend_get_stage (backend);
 | 
			
		||||
  CoglTexture *texture;
 | 
			
		||||
 | 
			
		||||
  /* During early initialization, we can have no stage */
 | 
			
		||||
  if (!stage)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (priv->displayed_cursor && !priv->handled_by_backend)
 | 
			
		||||
    texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, NULL, NULL);
 | 
			
		||||
  else
 | 
			
		||||
    texture = NULL;
 | 
			
		||||
 | 
			
		||||
  meta_stage_set_cursor (META_STAGE (stage), texture, &priv->current_rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_renderer_class_init (MetaCursorRendererClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  klass->update_cursor = meta_cursor_renderer_real_update_cursor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_renderer_init (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_cursor (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
  gboolean handled_by_backend;
 | 
			
		||||
  gboolean should_redraw = FALSE;
 | 
			
		||||
 | 
			
		||||
  if (priv->displayed_cursor)
 | 
			
		||||
    {
 | 
			
		||||
      CoglTexture *texture;
 | 
			
		||||
      int hot_x, hot_y;
 | 
			
		||||
 | 
			
		||||
      texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
 | 
			
		||||
 | 
			
		||||
      priv->current_rect.x = priv->current_x - hot_x;
 | 
			
		||||
      priv->current_rect.y = priv->current_y - hot_y;
 | 
			
		||||
      priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
 | 
			
		||||
      priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      priv->current_rect.x = 0;
 | 
			
		||||
      priv->current_rect.y = 0;
 | 
			
		||||
      priv->current_rect.width = 0;
 | 
			
		||||
      priv->current_rect.height = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
 | 
			
		||||
  if (handled_by_backend != priv->handled_by_backend)
 | 
			
		||||
    {
 | 
			
		||||
      priv->handled_by_backend = handled_by_backend;
 | 
			
		||||
      should_redraw = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!handled_by_backend)
 | 
			
		||||
    should_redraw = TRUE;
 | 
			
		||||
 | 
			
		||||
  if (should_redraw)
 | 
			
		||||
    queue_redraw (renderer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaCursorRenderer *
 | 
			
		||||
meta_cursor_renderer_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (META_TYPE_CURSOR_RENDERER, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_renderer_set_cursor (MetaCursorRenderer  *renderer,
 | 
			
		||||
                                 MetaCursorReference *cursor)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
  if (priv->displayed_cursor == cursor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv->displayed_cursor = cursor;
 | 
			
		||||
  update_cursor (renderer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
 | 
			
		||||
                                   int x, int y)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  priv->current_x = x;
 | 
			
		||||
  priv->current_y = y;
 | 
			
		||||
 | 
			
		||||
  update_cursor (renderer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaCursorReference *
 | 
			
		||||
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
  return priv->displayed_cursor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const MetaRectangle *
 | 
			
		||||
meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
  return &priv->current_rect;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,68 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_CURSOR_RENDERER_H
 | 
			
		||||
#define META_CURSOR_RENDERER_H
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include <meta/screen.h>
 | 
			
		||||
#include "meta-cursor.h"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_CURSOR_RENDERER            (meta_cursor_renderer_get_type ())
 | 
			
		||||
#define META_CURSOR_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER, MetaCursorRenderer))
 | 
			
		||||
#define META_CURSOR_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass))
 | 
			
		||||
#define META_IS_CURSOR_RENDERER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER))
 | 
			
		||||
#define META_IS_CURSOR_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_CURSOR_RENDERER))
 | 
			
		||||
#define META_CURSOR_RENDERER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaCursorRenderer        MetaCursorRenderer;
 | 
			
		||||
typedef struct _MetaCursorRendererClass   MetaCursorRendererClass;
 | 
			
		||||
 | 
			
		||||
struct _MetaCursorRenderer
 | 
			
		||||
{
 | 
			
		||||
  GObject parent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaCursorRendererClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  gboolean (* update_cursor) (MetaCursorRenderer *renderer);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType meta_cursor_renderer_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
MetaCursorRenderer * meta_cursor_renderer_new (void);
 | 
			
		||||
 | 
			
		||||
void meta_cursor_renderer_set_cursor (MetaCursorRenderer  *renderer,
 | 
			
		||||
                                      MetaCursorReference *cursor);
 | 
			
		||||
 | 
			
		||||
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
 | 
			
		||||
                                        int x, int y);
 | 
			
		||||
 | 
			
		||||
MetaCursorReference * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
 | 
			
		||||
const MetaRectangle * meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer);
 | 
			
		||||
 | 
			
		||||
#endif /* META_CURSOR_RENDERER_H */
 | 
			
		||||
@@ -23,20 +23,35 @@
 | 
			
		||||
#define META_CURSOR_TRACKER_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-cursor-tracker.h>
 | 
			
		||||
#include <wayland-server.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-cursor.h"
 | 
			
		||||
#include "meta-cursor-renderer.h"
 | 
			
		||||
 | 
			
		||||
struct _MetaCursorTracker {
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
 | 
			
		||||
  MetaCursorRenderer *renderer;
 | 
			
		||||
  MetaScreen *screen;
 | 
			
		||||
 | 
			
		||||
  gboolean is_showing;
 | 
			
		||||
  gboolean has_hw_cursor;
 | 
			
		||||
 | 
			
		||||
  /* The cursor tracker stores the cursor for the current grab
 | 
			
		||||
   * operation, the cursor for the window with pointer focus, and
 | 
			
		||||
   * the cursor for the root window, which contains either the
 | 
			
		||||
   * default arrow cursor or the 'busy' hourglass if we're launching
 | 
			
		||||
   * an app.
 | 
			
		||||
   *
 | 
			
		||||
   * We choose the first one available -- if there's a grab cursor,
 | 
			
		||||
   * we choose that cursor, if there's window cursor, we choose that,
 | 
			
		||||
   * otherwise we choose the root cursor.
 | 
			
		||||
   *
 | 
			
		||||
   * The displayed_cursor contains the chosen cursor.
 | 
			
		||||
   */
 | 
			
		||||
  MetaCursorReference *displayed_cursor;
 | 
			
		||||
 | 
			
		||||
  /* Wayland clients can set a NULL buffer as their cursor
 | 
			
		||||
  MetaCursorReference *grab_cursor;
 | 
			
		||||
 | 
			
		||||
  /* Wayland clients can set a NULL buffer as their cursor 
 | 
			
		||||
   * explicitly, which means that we shouldn't display anything.
 | 
			
		||||
   * So, we can't simply store a NULL in window_cursor to
 | 
			
		||||
   * determine an unset window cursor; we need an extra boolean.
 | 
			
		||||
@@ -46,8 +61,16 @@ struct _MetaCursorTracker {
 | 
			
		||||
 | 
			
		||||
  MetaCursorReference *root_cursor;
 | 
			
		||||
 | 
			
		||||
  /* The cursor from the X11 server. */
 | 
			
		||||
  MetaCursorReference *xfixes_cursor;
 | 
			
		||||
  MetaCursorReference *theme_cursors[META_CURSOR_LAST];
 | 
			
		||||
 | 
			
		||||
  int current_x, current_y;
 | 
			
		||||
  MetaRectangle current_rect;
 | 
			
		||||
  MetaRectangle previous_rect;
 | 
			
		||||
  gboolean previous_is_valid;
 | 
			
		||||
 | 
			
		||||
  CoglPipeline *pipeline;
 | 
			
		||||
  int drm_fd;
 | 
			
		||||
  struct gbm_device *gbm;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaCursorTrackerClass {
 | 
			
		||||
@@ -57,6 +80,8 @@ struct _MetaCursorTrackerClass {
 | 
			
		||||
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
 | 
			
		||||
					    XEvent            *xevent);
 | 
			
		||||
 | 
			
		||||
void     meta_cursor_tracker_set_grab_cursor     (MetaCursorTracker   *tracker,
 | 
			
		||||
                                                  MetaCursorReference *cursor);
 | 
			
		||||
void     meta_cursor_tracker_set_window_cursor   (MetaCursorTracker   *tracker,
 | 
			
		||||
                                                  MetaCursorReference *cursor);
 | 
			
		||||
void     meta_cursor_tracker_unset_window_cursor (MetaCursorTracker   *tracker);
 | 
			
		||||
@@ -66,7 +91,8 @@ void     meta_cursor_tracker_set_root_cursor     (MetaCursorTracker   *tracker,
 | 
			
		||||
void     meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
 | 
			
		||||
					      int                new_x,
 | 
			
		||||
					      int                new_y);
 | 
			
		||||
void     meta_cursor_tracker_paint           (MetaCursorTracker *tracker);
 | 
			
		||||
 | 
			
		||||
MetaCursorReference * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
 | 
			
		||||
void     meta_cursor_tracker_force_update (MetaCursorTracker *tracker);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright 2013 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
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
@@ -27,78 +27,49 @@
 | 
			
		||||
 *                     pointer abstraction"
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include "meta-cursor-tracker-private.h"
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <meta/main.h>
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
#include <meta/errors.h>
 | 
			
		||||
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
#include <cogl/cogl-wayland-server.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <gbm.h>
 | 
			
		||||
 | 
			
		||||
#include <gdk/gdk.h>
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
#include <X11/extensions/Xfixes.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-backend-private.h"
 | 
			
		||||
#include "meta-cursor-private.h"
 | 
			
		||||
#include "meta-cursor-tracker-private.h"
 | 
			
		||||
#include "screen-private.h"
 | 
			
		||||
#include "meta-monitor-manager.h"
 | 
			
		||||
 | 
			
		||||
#include "wayland/meta-wayland-private.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  CURSOR_CHANGED,
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
    CURSOR_CHANGED,
 | 
			
		||||
    LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL];
 | 
			
		||||
 | 
			
		||||
static MetaCursorReference *
 | 
			
		||||
get_displayed_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display = meta_get_display ();
 | 
			
		||||
 | 
			
		||||
  if (!tracker->is_showing)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  if (meta_display_windows_are_interactable (display))
 | 
			
		||||
    {
 | 
			
		||||
      if (tracker->has_window_cursor)
 | 
			
		||||
        return tracker->window_cursor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return tracker->root_cursor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_displayed_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  meta_cursor_renderer_set_cursor (tracker->renderer, tracker->displayed_cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
sync_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker);
 | 
			
		||||
 | 
			
		||||
  if (tracker->displayed_cursor == displayed_cursor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref);
 | 
			
		||||
  if (displayed_cursor)
 | 
			
		||||
    tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor);
 | 
			
		||||
 | 
			
		||||
  update_displayed_cursor (tracker);
 | 
			
		||||
  g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
 | 
			
		||||
}
 | 
			
		||||
static void meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
 | 
			
		||||
                                                        MetaCRTC          *crtc,
 | 
			
		||||
                                                        gboolean           has_hw_cursor);
 | 
			
		||||
static void sync_cursor (MetaCursorTracker *tracker);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_tracker_init (MetaCursorTracker *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
  /* (JS) Best (?) that can be assumed since XFixes doesn't provide a way of
 | 
			
		||||
     detecting if the system mouse cursor is showing or not.
 | 
			
		||||
 | 
			
		||||
  self->renderer = meta_backend_get_cursor_renderer (backend);
 | 
			
		||||
     On wayland we start with the cursor showing
 | 
			
		||||
  */
 | 
			
		||||
  self->is_showing = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -106,12 +77,22 @@ static void
 | 
			
		||||
meta_cursor_tracker_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorTracker *self = META_CURSOR_TRACKER (object);
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if (self->displayed_cursor)
 | 
			
		||||
    meta_cursor_reference_unref (self->displayed_cursor);
 | 
			
		||||
  if (self->root_cursor)
 | 
			
		||||
    meta_cursor_reference_unref (self->root_cursor);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < META_CURSOR_LAST; i++)
 | 
			
		||||
    if (self->theme_cursors[i])
 | 
			
		||||
      meta_cursor_reference_unref (self->theme_cursors[i]);
 | 
			
		||||
 | 
			
		||||
  if (self->pipeline)
 | 
			
		||||
    cogl_object_unref (self->pipeline);
 | 
			
		||||
  if (self->gbm)
 | 
			
		||||
    gbm_device_destroy (self->gbm);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -130,13 +111,80 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
 | 
			
		||||
                                          G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaCursorTracker *
 | 
			
		||||
meta_cursor_tracker_new (void)
 | 
			
		||||
static void
 | 
			
		||||
on_monitors_changed (MetaMonitorManager *monitors,
 | 
			
		||||
                     MetaCursorTracker  *tracker)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
 | 
			
		||||
  MetaCRTC *crtcs;
 | 
			
		||||
  unsigned int i, n_crtcs;
 | 
			
		||||
 | 
			
		||||
  if (!tracker->has_hw_cursor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* Go through the new list of monitors, find out where the cursor is */
 | 
			
		||||
  meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_crtcs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaRectangle *rect = &crtcs[i].rect;
 | 
			
		||||
      gboolean has;
 | 
			
		||||
 | 
			
		||||
      has = meta_rectangle_overlap (&tracker->current_rect, rect);
 | 
			
		||||
 | 
			
		||||
      /* Need to do it unconditionally here, our tracking is
 | 
			
		||||
         wrong because we reloaded the CRTCs */
 | 
			
		||||
      meta_cursor_tracker_set_crtc_has_hw_cursor (tracker, &crtcs[i], has);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaCursorTracker *_cursor_tracker;
 | 
			
		||||
static MetaCursorTracker *
 | 
			
		||||
make_wayland_cursor_tracker (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandCompositor *compositor;
 | 
			
		||||
  CoglContext *ctx;
 | 
			
		||||
  MetaMonitorManager *monitors;
 | 
			
		||||
  MetaCursorTracker *self;
 | 
			
		||||
 | 
			
		||||
  self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
 | 
			
		||||
  self->screen = screen;
 | 
			
		||||
 | 
			
		||||
  ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
  self->pipeline = cogl_pipeline_new (ctx);
 | 
			
		||||
 | 
			
		||||
  compositor = meta_wayland_compositor_get_default ();
 | 
			
		||||
  compositor->seat->cursor_tracker = self;
 | 
			
		||||
  meta_cursor_tracker_update_position (self,
 | 
			
		||||
                                       wl_fixed_to_int (compositor->seat->pointer.x),
 | 
			
		||||
                                       wl_fixed_to_int (compositor->seat->pointer.y));
 | 
			
		||||
 | 
			
		||||
#if defined(CLUTTER_WINDOWING_EGL)
 | 
			
		||||
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
 | 
			
		||||
    {
 | 
			
		||||
      CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx));
 | 
			
		||||
      self->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
 | 
			
		||||
      self->gbm = gbm_create_device (self->drm_fd);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  monitors = meta_monitor_manager_get ();
 | 
			
		||||
  g_signal_connect_object (monitors, "monitors-changed",
 | 
			
		||||
                           G_CALLBACK (on_monitors_changed), self, 0);
 | 
			
		||||
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaCursorTracker *
 | 
			
		||||
make_x11_cursor_tracker (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorTracker *self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
 | 
			
		||||
  self->screen = screen;
 | 
			
		||||
 | 
			
		||||
  XFixesSelectCursorInput (screen->display->xdisplay,
 | 
			
		||||
                           screen->xroot,
 | 
			
		||||
                           XFixesDisplayCursorNotifyMask);
 | 
			
		||||
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_cursor_tracker_get_for_screen:
 | 
			
		||||
@@ -149,10 +197,18 @@ static MetaCursorTracker *_cursor_tracker;
 | 
			
		||||
MetaCursorTracker *
 | 
			
		||||
meta_cursor_tracker_get_for_screen (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  if (!_cursor_tracker)
 | 
			
		||||
    _cursor_tracker = meta_cursor_tracker_new ();
 | 
			
		||||
  MetaCursorTracker *self;
 | 
			
		||||
 | 
			
		||||
  return _cursor_tracker;
 | 
			
		||||
  if (screen->cursor_tracker)
 | 
			
		||||
    return screen->cursor_tracker;
 | 
			
		||||
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    self = make_wayland_cursor_tracker (screen);
 | 
			
		||||
  else
 | 
			
		||||
    self = make_x11_cursor_tracker (screen);
 | 
			
		||||
 | 
			
		||||
  screen->cursor_tracker = self;
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -171,21 +227,19 @@ gboolean
 | 
			
		||||
meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
 | 
			
		||||
                                   XEvent            *xevent)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display = meta_get_display ();
 | 
			
		||||
  XFixesCursorNotifyEvent *notify_event;
 | 
			
		||||
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  if (xevent->xany.type != display->xfixes_event_base + XFixesCursorNotify)
 | 
			
		||||
  if (xevent->xany.type != tracker->screen->display->xfixes_event_base + XFixesCursorNotify)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  notify_event = (XFixesCursorNotifyEvent *)xevent;
 | 
			
		||||
  if (notify_event->subtype != XFixesDisplayCursorNotify)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref);
 | 
			
		||||
  g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
 | 
			
		||||
  set_window_cursor (tracker, FALSE, NULL);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -209,17 +263,16 @@ meta_cursor_reference_take_texture (CoglTexture2D *texture,
 | 
			
		||||
static void
 | 
			
		||||
ensure_xfixes_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay *display = meta_get_display ();
 | 
			
		||||
  XFixesCursorImage *cursor_image;
 | 
			
		||||
  CoglTexture2D *sprite;
 | 
			
		||||
  guint8 *cursor_data;
 | 
			
		||||
  gboolean free_cursor_data;
 | 
			
		||||
  CoglContext *ctx;
 | 
			
		||||
 | 
			
		||||
  if (tracker->xfixes_cursor)
 | 
			
		||||
  if (tracker->has_window_cursor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  cursor_image = XFixesGetCursorImage (display->xdisplay);
 | 
			
		||||
  cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay);
 | 
			
		||||
  if (!cursor_image)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
@@ -266,7 +319,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
      MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite,
 | 
			
		||||
                                                                        cursor_image->xhot,
 | 
			
		||||
                                                                        cursor_image->yhot);
 | 
			
		||||
      tracker->xfixes_cursor = cursor;
 | 
			
		||||
      set_window_cursor (tracker, TRUE, cursor);
 | 
			
		||||
    }
 | 
			
		||||
  XFree (cursor_image);
 | 
			
		||||
}
 | 
			
		||||
@@ -279,22 +332,13 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
CoglTexture *
 | 
			
		||||
meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorReference *cursor;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL);
 | 
			
		||||
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      cursor = tracker->displayed_cursor;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      ensure_xfixes_cursor (tracker);
 | 
			
		||||
      cursor = tracker->xfixes_cursor;
 | 
			
		||||
    }
 | 
			
		||||
  if (!meta_is_wayland_compositor ())
 | 
			
		||||
    ensure_xfixes_cursor (tracker);
 | 
			
		||||
 | 
			
		||||
  if (cursor)
 | 
			
		||||
    return meta_cursor_reference_get_cogl_texture (cursor, NULL, NULL);
 | 
			
		||||
  if (tracker->displayed_cursor)
 | 
			
		||||
    return meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, NULL, NULL);
 | 
			
		||||
  else
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
@@ -311,22 +355,13 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
 | 
			
		||||
                             int               *x,
 | 
			
		||||
                             int               *y)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorReference *cursor;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
 | 
			
		||||
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      cursor = tracker->displayed_cursor;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      ensure_xfixes_cursor (tracker);
 | 
			
		||||
      cursor = tracker->xfixes_cursor;
 | 
			
		||||
    }
 | 
			
		||||
  if (!meta_is_wayland_compositor ())
 | 
			
		||||
    ensure_xfixes_cursor (tracker);
 | 
			
		||||
 | 
			
		||||
  if (cursor)
 | 
			
		||||
    meta_cursor_reference_get_cogl_texture (cursor, x, y);
 | 
			
		||||
  if (tracker->displayed_cursor)
 | 
			
		||||
    meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, x, y);
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (x)
 | 
			
		||||
@@ -336,6 +371,17 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_set_grab_cursor (MetaCursorTracker   *tracker,
 | 
			
		||||
                                     MetaCursorReference *cursor)
 | 
			
		||||
{
 | 
			
		||||
  g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref);
 | 
			
		||||
  if (cursor)
 | 
			
		||||
    tracker->grab_cursor = meta_cursor_reference_ref (cursor);
 | 
			
		||||
 | 
			
		||||
  sync_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_set_window_cursor (MetaCursorTracker   *tracker,
 | 
			
		||||
                                       MetaCursorReference *cursor)
 | 
			
		||||
@@ -360,6 +406,184 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker   *tracker,
 | 
			
		||||
  sync_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
should_have_hw_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  if (tracker->displayed_cursor)
 | 
			
		||||
    return (meta_cursor_reference_get_gbm_bo (tracker->displayed_cursor, NULL, NULL) != NULL);
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_hw_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManager *monitors;
 | 
			
		||||
  MetaCRTC *crtcs;
 | 
			
		||||
  unsigned int i, n_crtcs;
 | 
			
		||||
  gboolean enabled;
 | 
			
		||||
 | 
			
		||||
  enabled = should_have_hw_cursor (tracker);
 | 
			
		||||
  tracker->has_hw_cursor = enabled;
 | 
			
		||||
 | 
			
		||||
  monitors = meta_monitor_manager_get ();
 | 
			
		||||
  meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_crtcs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaRectangle *rect = &crtcs[i].rect;
 | 
			
		||||
      gboolean has;
 | 
			
		||||
 | 
			
		||||
      has = enabled && meta_rectangle_overlap (&tracker->current_rect, rect);
 | 
			
		||||
 | 
			
		||||
      if (has || crtcs[i].has_hw_cursor)
 | 
			
		||||
        meta_cursor_tracker_set_crtc_has_hw_cursor (tracker, &crtcs[i], has);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
move_hw_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManager *monitors;
 | 
			
		||||
  MetaCRTC *crtcs;
 | 
			
		||||
  unsigned int i, n_crtcs;
 | 
			
		||||
 | 
			
		||||
  monitors = meta_monitor_manager_get ();
 | 
			
		||||
  meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  g_assert (tracker->has_hw_cursor);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_crtcs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaRectangle *rect = &crtcs[i].rect;
 | 
			
		||||
      gboolean has;
 | 
			
		||||
 | 
			
		||||
      has = meta_rectangle_overlap (&tracker->current_rect, rect);
 | 
			
		||||
 | 
			
		||||
      if (has != crtcs[i].has_hw_cursor)
 | 
			
		||||
        meta_cursor_tracker_set_crtc_has_hw_cursor (tracker, &crtcs[i], has);
 | 
			
		||||
      if (has)
 | 
			
		||||
        drmModeMoveCursor (tracker->drm_fd, crtcs[i].crtc_id,
 | 
			
		||||
                           tracker->current_rect.x - rect->x,
 | 
			
		||||
                           tracker->current_rect.y - rect->y);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaCursorReference *
 | 
			
		||||
get_displayed_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  if (!tracker->is_showing)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  if (tracker->grab_cursor)
 | 
			
		||||
    return tracker->grab_cursor;
 | 
			
		||||
 | 
			
		||||
  if (tracker->has_window_cursor)
 | 
			
		||||
    return tracker->window_cursor;
 | 
			
		||||
 | 
			
		||||
  return tracker->root_cursor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_displayed_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      if (tracker->displayed_cursor)
 | 
			
		||||
        {
 | 
			
		||||
          CoglTexture *texture = meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, NULL, NULL);
 | 
			
		||||
          cogl_pipeline_set_layer_texture (tracker->pipeline, 0, texture);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL);
 | 
			
		||||
 | 
			
		||||
      update_hw_cursor (tracker);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
sync_displayed_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker);
 | 
			
		||||
 | 
			
		||||
  if (tracker->displayed_cursor == displayed_cursor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref);
 | 
			
		||||
  if (displayed_cursor)
 | 
			
		||||
    tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor);
 | 
			
		||||
 | 
			
		||||
  update_displayed_cursor (tracker);
 | 
			
		||||
  g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
 | 
			
		||||
  ClutterActor *stage = compositor->stage;
 | 
			
		||||
  cairo_rectangle_int_t clip;
 | 
			
		||||
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  /* Clear the location the cursor was at before, if we need to. */
 | 
			
		||||
  if (tracker->previous_is_valid)
 | 
			
		||||
    {
 | 
			
		||||
      clip.x = tracker->previous_rect.x;
 | 
			
		||||
      clip.y = tracker->previous_rect.y;
 | 
			
		||||
      clip.width = tracker->previous_rect.width;
 | 
			
		||||
      clip.height = tracker->previous_rect.height;
 | 
			
		||||
      clutter_actor_queue_redraw_with_clip (stage, &clip);
 | 
			
		||||
      tracker->previous_is_valid = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (tracker->has_hw_cursor || !tracker->displayed_cursor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  clip.x = tracker->current_rect.x;
 | 
			
		||||
  clip.y = tracker->current_rect.y;
 | 
			
		||||
  clip.width = tracker->current_rect.width;
 | 
			
		||||
  clip.height = tracker->current_rect.height;
 | 
			
		||||
  clutter_actor_queue_redraw_with_clip (stage, &clip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
sync_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorReference *displayed_cursor;
 | 
			
		||||
 | 
			
		||||
  sync_displayed_cursor (tracker);
 | 
			
		||||
  displayed_cursor = tracker->displayed_cursor;
 | 
			
		||||
 | 
			
		||||
  if (displayed_cursor)
 | 
			
		||||
    {
 | 
			
		||||
      CoglTexture *texture;
 | 
			
		||||
      int hot_x, hot_y;
 | 
			
		||||
 | 
			
		||||
      texture = meta_cursor_reference_get_cogl_texture (displayed_cursor, &hot_x, &hot_y);
 | 
			
		||||
 | 
			
		||||
      tracker->current_rect.x = tracker->current_x - hot_x;
 | 
			
		||||
      tracker->current_rect.y = tracker->current_y - hot_y;
 | 
			
		||||
      tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
 | 
			
		||||
      tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      tracker->current_rect.x = 0;
 | 
			
		||||
      tracker->current_rect.y = 0;
 | 
			
		||||
      tracker->current_rect.width = 0;
 | 
			
		||||
      tracker->current_rect.height = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      if (tracker->has_hw_cursor)
 | 
			
		||||
        move_hw_cursor (tracker);
 | 
			
		||||
      else
 | 
			
		||||
        meta_cursor_tracker_queue_redraw (tracker);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
 | 
			
		||||
                                     int                new_x,
 | 
			
		||||
@@ -367,7 +591,61 @@ meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
 | 
			
		||||
{
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  meta_cursor_renderer_set_position (tracker->renderer, new_x, new_y);
 | 
			
		||||
  tracker->current_x = new_x;
 | 
			
		||||
  tracker->current_y = new_y;
 | 
			
		||||
 | 
			
		||||
  sync_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_paint (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  if (tracker->has_hw_cursor || !tracker->displayed_cursor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
 | 
			
		||||
                                   tracker->pipeline,
 | 
			
		||||
                                   tracker->current_rect.x,
 | 
			
		||||
                                   tracker->current_rect.y,
 | 
			
		||||
                                   tracker->current_rect.x +
 | 
			
		||||
                                   tracker->current_rect.width,
 | 
			
		||||
                                   tracker->current_rect.y +
 | 
			
		||||
                                   tracker->current_rect.height);
 | 
			
		||||
 | 
			
		||||
  tracker->previous_rect = tracker->current_rect;
 | 
			
		||||
  tracker->previous_is_valid = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
 | 
			
		||||
                                            MetaCRTC          *crtc,
 | 
			
		||||
                                            gboolean           has)
 | 
			
		||||
{
 | 
			
		||||
  if (has)
 | 
			
		||||
    {
 | 
			
		||||
      MetaCursorReference *displayed_cursor = tracker->displayed_cursor;
 | 
			
		||||
      struct gbm_bo *bo;
 | 
			
		||||
      union gbm_bo_handle handle;
 | 
			
		||||
      int width, height;
 | 
			
		||||
      int hot_x, hot_y;
 | 
			
		||||
 | 
			
		||||
      bo = meta_cursor_reference_get_gbm_bo (displayed_cursor, &hot_x, &hot_y);
 | 
			
		||||
 | 
			
		||||
      handle = gbm_bo_get_handle (bo);
 | 
			
		||||
      width = gbm_bo_get_width (bo);
 | 
			
		||||
      height = gbm_bo_get_height (bo);
 | 
			
		||||
 | 
			
		||||
      drmModeSetCursor2 (tracker->drm_fd, crtc->crtc_id, handle.u32,
 | 
			
		||||
                         width, height, hot_x, hot_y);
 | 
			
		||||
      crtc->has_hw_cursor = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      drmModeSetCursor2 (tracker->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
 | 
			
		||||
      crtc->has_hw_cursor = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -435,11 +713,26 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
 | 
			
		||||
    return;
 | 
			
		||||
  tracker->is_showing = visible;
 | 
			
		||||
 | 
			
		||||
  sync_cursor (tracker);
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    {
 | 
			
		||||
      sync_cursor (tracker);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (visible)
 | 
			
		||||
        XFixesShowCursor (tracker->screen->display->xdisplay,
 | 
			
		||||
                          tracker->screen->xroot);
 | 
			
		||||
      else
 | 
			
		||||
        XFixesHideCursor (tracker->screen->display->xdisplay,
 | 
			
		||||
                          tracker->screen->xroot);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaCursorReference *
 | 
			
		||||
meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker)
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_tracker_force_update (MetaCursorTracker *tracker)
 | 
			
		||||
{
 | 
			
		||||
  return tracker->displayed_cursor;
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  update_hw_cursor (tracker);
 | 
			
		||||
  sync_cursor (tracker);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,11 +27,7 @@
 | 
			
		||||
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
#include "screen-private.h"
 | 
			
		||||
#include "meta-backend-private.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
#include "backends/native/meta-cursor-renderer-native.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "meta-cursor-tracker-private.h" /* for tracker->gbm */
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
@@ -39,9 +35,7 @@
 | 
			
		||||
#include <X11/extensions/Xfixes.h>
 | 
			
		||||
#include <X11/Xcursor/Xcursor.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
#include <cogl/cogl-wayland-server.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
MetaCursorReference *
 | 
			
		||||
meta_cursor_reference_ref (MetaCursorReference *self)
 | 
			
		||||
@@ -55,13 +49,9 @@ meta_cursor_reference_ref (MetaCursorReference *self)
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_image_free (MetaCursorImage *image)
 | 
			
		||||
{
 | 
			
		||||
  if (image->texture)
 | 
			
		||||
    cogl_object_unref (image->texture);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
  cogl_object_unref (image->texture);
 | 
			
		||||
  if (image->bo)
 | 
			
		||||
    gbm_bo_destroy (image->bo);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -80,146 +70,168 @@ meta_cursor_reference_unref (MetaCursorReference *self)
 | 
			
		||||
    meta_cursor_reference_free (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
translate_meta_cursor (MetaCursor cursor)
 | 
			
		||||
static void
 | 
			
		||||
translate_meta_cursor (MetaCursor   cursor,
 | 
			
		||||
                       guint       *glyph_out,
 | 
			
		||||
                       const char **name_out)
 | 
			
		||||
{
 | 
			
		||||
  guint glyph = XC_num_glyphs;
 | 
			
		||||
  const char *name = NULL;
 | 
			
		||||
 | 
			
		||||
  switch (cursor)
 | 
			
		||||
    {
 | 
			
		||||
    case META_CURSOR_DEFAULT:
 | 
			
		||||
      return "left_ptr";
 | 
			
		||||
      glyph = XC_left_ptr;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_NORTH_RESIZE:
 | 
			
		||||
      return "top_side";
 | 
			
		||||
      glyph = XC_top_side;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_SOUTH_RESIZE:
 | 
			
		||||
      return "bottom_side";
 | 
			
		||||
      glyph = XC_bottom_side;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_WEST_RESIZE:
 | 
			
		||||
      return "left_side";
 | 
			
		||||
      glyph = XC_left_side;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_EAST_RESIZE:
 | 
			
		||||
      return "right_side";
 | 
			
		||||
      glyph = XC_right_side;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_SE_RESIZE:
 | 
			
		||||
      return "bottom_right_corner";
 | 
			
		||||
      glyph = XC_bottom_right_corner;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_SW_RESIZE:
 | 
			
		||||
      return "bottom_left_corner";
 | 
			
		||||
      glyph = XC_bottom_left_corner;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_NE_RESIZE:
 | 
			
		||||
      return "top_right_corner";
 | 
			
		||||
      glyph = XC_top_right_corner;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_NW_RESIZE:
 | 
			
		||||
      return "top_left_corner";
 | 
			
		||||
      glyph = XC_top_left_corner;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
 | 
			
		||||
      return "fleur";
 | 
			
		||||
      glyph = XC_fleur;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_BUSY:
 | 
			
		||||
      return "watch";
 | 
			
		||||
      glyph = XC_watch;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_DND_IN_DRAG:
 | 
			
		||||
      return "dnd-none";
 | 
			
		||||
      name = "dnd-none";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_DND_MOVE:
 | 
			
		||||
      return "dnd-move";
 | 
			
		||||
      name = "dnd-move";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_DND_COPY:
 | 
			
		||||
      return "dnd-copy";
 | 
			
		||||
      name = "dnd-copy";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_DND_UNSUPPORTED_TARGET:
 | 
			
		||||
      return "dnd-none";
 | 
			
		||||
      name = "dnd-none";
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_POINTING_HAND:
 | 
			
		||||
      return "hand2";
 | 
			
		||||
      glyph = XC_hand2;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_CROSSHAIR:
 | 
			
		||||
      return "crosshair";
 | 
			
		||||
      glyph = XC_crosshair;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_CURSOR_IBEAM:
 | 
			
		||||
      return "xterm";
 | 
			
		||||
      glyph = XC_xterm;
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      g_assert_not_reached ();
 | 
			
		||||
      glyph = 0; /* silence compiler */
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_assert_not_reached ();
 | 
			
		||||
  *glyph_out = glyph;
 | 
			
		||||
  *name_out = name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Cursor
 | 
			
		||||
load_cursor_on_server (MetaDisplay *display,
 | 
			
		||||
                       MetaCursor   cursor)
 | 
			
		||||
{
 | 
			
		||||
  Cursor xcursor;
 | 
			
		||||
  guint glyph;
 | 
			
		||||
  const char *name;
 | 
			
		||||
 | 
			
		||||
  translate_meta_cursor (cursor, &glyph, &name);
 | 
			
		||||
 | 
			
		||||
  if (name != NULL)
 | 
			
		||||
    xcursor = XcursorLibraryLoadCursor (display->xdisplay, name);
 | 
			
		||||
  else
 | 
			
		||||
    xcursor = XCreateFontCursor (display->xdisplay, glyph);
 | 
			
		||||
 | 
			
		||||
  return xcursor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Cursor
 | 
			
		||||
meta_cursor_create_x_cursor (Display    *xdisplay,
 | 
			
		||||
                             MetaCursor  cursor)
 | 
			
		||||
meta_display_create_x_cursor (MetaDisplay *display,
 | 
			
		||||
                              MetaCursor cursor)
 | 
			
		||||
{
 | 
			
		||||
  return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
 | 
			
		||||
  return load_cursor_on_server (display, cursor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XcursorImage *
 | 
			
		||||
load_cursor_on_client (MetaCursor cursor)
 | 
			
		||||
load_cursor_on_client (MetaDisplay *display,
 | 
			
		||||
                       MetaCursor   cursor)
 | 
			
		||||
{
 | 
			
		||||
  return XcursorLibraryLoadImage (translate_meta_cursor (cursor),
 | 
			
		||||
                                  meta_prefs_get_cursor_theme (),
 | 
			
		||||
                                  meta_prefs_get_cursor_size ());
 | 
			
		||||
  XcursorImage *image;
 | 
			
		||||
  guint glyph;
 | 
			
		||||
  const char *name;
 | 
			
		||||
  const char *theme = XcursorGetTheme (display->xdisplay);
 | 
			
		||||
  int size = XcursorGetDefaultSize (display->xdisplay);
 | 
			
		||||
 | 
			
		||||
  translate_meta_cursor (cursor, &glyph, &name);
 | 
			
		||||
 | 
			
		||||
  if (name != NULL)
 | 
			
		||||
    image = XcursorLibraryLoadImage (name, theme, size);
 | 
			
		||||
  else
 | 
			
		||||
    image = XcursorShapeLoadImage (glyph, theme, size);
 | 
			
		||||
 | 
			
		||||
  return image;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
static void
 | 
			
		||||
get_hardware_cursor_size (uint64_t *cursor_width, uint64_t *cursor_height)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *meta_backend = meta_get_backend ();
 | 
			
		||||
  MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
 | 
			
		||||
 | 
			
		||||
  if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
 | 
			
		||||
    {
 | 
			
		||||
      meta_cursor_renderer_native_get_cursor_size (META_CURSOR_RENDERER_NATIVE (renderer), cursor_width, cursor_height);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_assert_not_reached ();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
 | 
			
		||||
                                   MetaCursorImage   *image,
 | 
			
		||||
                                   uint8_t           *pixels,
 | 
			
		||||
                                   uint               width,
 | 
			
		||||
                                   uint               height,
 | 
			
		||||
                                   int                width,
 | 
			
		||||
                                   int                height,
 | 
			
		||||
                                   int                rowstride,
 | 
			
		||||
                                   uint32_t           gbm_format)
 | 
			
		||||
{
 | 
			
		||||
  uint64_t cursor_width, cursor_height;
 | 
			
		||||
  get_hardware_cursor_size (&cursor_width, &cursor_height);
 | 
			
		||||
 | 
			
		||||
  if (width > cursor_width || height > cursor_height)
 | 
			
		||||
  if (width > 64 || height > 64)
 | 
			
		||||
    {
 | 
			
		||||
      meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
 | 
			
		||||
                    (unsigned int)cursor_width, (unsigned int)cursor_height);
 | 
			
		||||
      meta_warning ("Invalid theme cursor size (must be at most 64x64)\n");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (gbm_device_is_format_supported (gbm, gbm_format,
 | 
			
		||||
                                      GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
 | 
			
		||||
                                      GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE))
 | 
			
		||||
    {
 | 
			
		||||
      uint8_t buf[4 * cursor_width * cursor_height];
 | 
			
		||||
      uint i;
 | 
			
		||||
      uint8_t buf[4 * 64 * 64];
 | 
			
		||||
      int i;
 | 
			
		||||
 | 
			
		||||
      image->bo = gbm_bo_create (gbm, cursor_width, cursor_height,
 | 
			
		||||
                                 gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
 | 
			
		||||
      image->bo = gbm_bo_create (gbm, 64, 64,
 | 
			
		||||
                                 gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
 | 
			
		||||
 | 
			
		||||
      memset (buf, 0, sizeof(buf));
 | 
			
		||||
      for (i = 0; i < height; i++)
 | 
			
		||||
        memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
 | 
			
		||||
        memcpy (buf + i * 4 * 64, pixels + i * rowstride, width * 4);
 | 
			
		||||
 | 
			
		||||
      gbm_bo_write (image->bo, buf, cursor_width * cursor_height * 4);
 | 
			
		||||
      gbm_bo_write (image->bo, buf, 64 * 64 * 4);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    meta_warning ("HW cursor for format %d not supported\n", gbm_format);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
static struct gbm_device *
 | 
			
		||||
get_gbm_device (void)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *meta_backend = meta_get_backend ();
 | 
			
		||||
  MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
 | 
			
		||||
 | 
			
		||||
  if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
 | 
			
		||||
    return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer));
 | 
			
		||||
  else
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_image_load_from_xcursor_image (MetaCursorImage   *image,
 | 
			
		||||
meta_cursor_image_load_from_xcursor_image (MetaCursorTracker *tracker,
 | 
			
		||||
                                           MetaCursorImage   *image,
 | 
			
		||||
                                           XcursorImage      *xc_image)
 | 
			
		||||
{
 | 
			
		||||
  uint width, height, rowstride;
 | 
			
		||||
  int width, height, rowstride;
 | 
			
		||||
  CoglPixelFormat cogl_format;
 | 
			
		||||
  uint32_t gbm_format;
 | 
			
		||||
  ClutterBackend *clutter_backend;
 | 
			
		||||
  CoglContext *cogl_context;
 | 
			
		||||
 | 
			
		||||
@@ -227,6 +239,7 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorImage   *image,
 | 
			
		||||
  height          = xc_image->height;
 | 
			
		||||
  rowstride       = width * 4;
 | 
			
		||||
 | 
			
		||||
  gbm_format = GBM_FORMAT_ARGB8888;
 | 
			
		||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
 | 
			
		||||
  cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
 | 
			
		||||
#else
 | 
			
		||||
@@ -245,53 +258,48 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorImage   *image,
 | 
			
		||||
                                                  (uint8_t *) xc_image->pixels,
 | 
			
		||||
                                                  NULL);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
  struct gbm_device *gbm = get_gbm_device ();
 | 
			
		||||
  if (gbm)
 | 
			
		||||
    meta_cursor_image_load_gbm_buffer (gbm,
 | 
			
		||||
  if (tracker->gbm)
 | 
			
		||||
    meta_cursor_image_load_gbm_buffer (tracker->gbm,
 | 
			
		||||
                                       image,
 | 
			
		||||
                                       (uint8_t *) xc_image->pixels,
 | 
			
		||||
                                       width, height, rowstride,
 | 
			
		||||
                                       GBM_FORMAT_ARGB8888);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_cursor_image (MetaCursorReference *cursor)
 | 
			
		||||
{
 | 
			
		||||
  XcursorImage *image;
 | 
			
		||||
 | 
			
		||||
  /* Either cursors are loaded from X cursors or buffers. Since
 | 
			
		||||
   * buffers are converted over immediately, we can make sure to
 | 
			
		||||
   * load this directly. */
 | 
			
		||||
  g_assert (cursor->cursor != META_CURSOR_NONE);
 | 
			
		||||
 | 
			
		||||
  image = load_cursor_on_client (cursor->cursor);
 | 
			
		||||
  if (!image)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_cursor_image_load_from_xcursor_image (&cursor->image, image);
 | 
			
		||||
  XcursorImageDestroy (image);
 | 
			
		||||
                                       gbm_format);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaCursorReference *
 | 
			
		||||
meta_cursor_reference_from_theme (MetaCursor cursor)
 | 
			
		||||
meta_cursor_reference_from_theme (MetaCursorTracker  *tracker,
 | 
			
		||||
                                  MetaCursor          cursor)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorReference *self = g_slice_new0 (MetaCursorReference);
 | 
			
		||||
  MetaCursorReference *self;
 | 
			
		||||
  XcursorImage *image;
 | 
			
		||||
 | 
			
		||||
  if (tracker->theme_cursors[cursor])
 | 
			
		||||
    return meta_cursor_reference_ref (tracker->theme_cursors[cursor]);
 | 
			
		||||
 | 
			
		||||
  image = load_cursor_on_client (tracker->screen->display, cursor);
 | 
			
		||||
  if (!image)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  self = g_slice_new0 (MetaCursorReference);
 | 
			
		||||
  self->ref_count = 1;
 | 
			
		||||
  self->cursor = cursor;
 | 
			
		||||
  meta_cursor_image_load_from_xcursor_image (tracker, &self->image, image);
 | 
			
		||||
 | 
			
		||||
  XcursorImageDestroy (image);
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_image_load_from_buffer (MetaCursorImage    *image,
 | 
			
		||||
meta_cursor_image_load_from_buffer (MetaCursorTracker  *tracker,
 | 
			
		||||
                                    MetaCursorImage    *image,
 | 
			
		||||
                                    struct wl_resource *buffer,
 | 
			
		||||
                                    int                 hot_x,
 | 
			
		||||
                                    int                 hot_y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterBackend *backend;
 | 
			
		||||
  CoglContext *cogl_context;
 | 
			
		||||
  struct wl_shm_buffer *shm_buffer;
 | 
			
		||||
  uint32_t gbm_format;
 | 
			
		||||
  int width, height;
 | 
			
		||||
 | 
			
		||||
  image->hot_x = hot_x;
 | 
			
		||||
  image->hot_y = hot_y;
 | 
			
		||||
@@ -301,24 +309,16 @@ meta_cursor_image_load_from_buffer (MetaCursorImage    *image,
 | 
			
		||||
 | 
			
		||||
  image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
  struct gbm_device *gbm = get_gbm_device ();
 | 
			
		||||
  if (gbm)
 | 
			
		||||
  width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
 | 
			
		||||
  height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
 | 
			
		||||
 | 
			
		||||
  shm_buffer = wl_shm_buffer_get (buffer);
 | 
			
		||||
  if (shm_buffer)
 | 
			
		||||
    {
 | 
			
		||||
      uint32_t gbm_format;
 | 
			
		||||
      uint64_t cursor_width, cursor_height;
 | 
			
		||||
      uint width, height;
 | 
			
		||||
 | 
			
		||||
      width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
 | 
			
		||||
      height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
 | 
			
		||||
 | 
			
		||||
      struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
 | 
			
		||||
      if (shm_buffer)
 | 
			
		||||
      if (tracker->gbm)
 | 
			
		||||
        {
 | 
			
		||||
          int rowstride = wl_shm_buffer_get_stride (shm_buffer);
 | 
			
		||||
 | 
			
		||||
          wl_shm_buffer_begin_access (shm_buffer);
 | 
			
		||||
 | 
			
		||||
          switch (wl_shm_buffer_get_format (shm_buffer))
 | 
			
		||||
            {
 | 
			
		||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
 | 
			
		||||
@@ -341,40 +341,40 @@ meta_cursor_image_load_from_buffer (MetaCursorImage    *image,
 | 
			
		||||
              gbm_format = GBM_FORMAT_ARGB8888;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          meta_cursor_image_load_gbm_buffer (gbm,
 | 
			
		||||
          meta_cursor_image_load_gbm_buffer (tracker->gbm,
 | 
			
		||||
                                             image,
 | 
			
		||||
                                             (uint8_t *) wl_shm_buffer_get_data (shm_buffer),
 | 
			
		||||
                                             width, height, rowstride,
 | 
			
		||||
                                             gbm_format);
 | 
			
		||||
 | 
			
		||||
          wl_shm_buffer_end_access (shm_buffer);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses
 | 
			
		||||
         that, so themed cursors must be padded with transparent pixels to fill the
 | 
			
		||||
         overlay. This is trivial if we have CPU access to the data, but it's not
 | 
			
		||||
         possible if the buffer is in GPU memory (and possibly tiled too), so if we
 | 
			
		||||
         don't get the right size, we fallback to GL.
 | 
			
		||||
      */
 | 
			
		||||
      if (width != 64 || height != 64)
 | 
			
		||||
        {
 | 
			
		||||
          /* HW cursors have a predefined size (at least 64x64), which usually is bigger than cursor theme
 | 
			
		||||
             size, so themed cursors must be padded with transparent pixels to fill the
 | 
			
		||||
             overlay. This is trivial if we have CPU access to the data, but it's not
 | 
			
		||||
             possible if the buffer is in GPU memory (and possibly tiled too), so if we
 | 
			
		||||
             don't get the right size, we fallback to GL.
 | 
			
		||||
          */
 | 
			
		||||
          get_hardware_cursor_size (&cursor_width, &cursor_height);
 | 
			
		||||
          meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
          if (width != cursor_width || height != cursor_height)
 | 
			
		||||
            {
 | 
			
		||||
              meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER, buffer, GBM_BO_USE_CURSOR);
 | 
			
		||||
      if (tracker->gbm)
 | 
			
		||||
        {
 | 
			
		||||
          image->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER,
 | 
			
		||||
                                     buffer, GBM_BO_USE_CURSOR_64X64);
 | 
			
		||||
          if (!image->bo)
 | 
			
		||||
            meta_warning ("Importing HW cursor from wl_buffer failed\n");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaCursorReference *
 | 
			
		||||
meta_cursor_reference_from_buffer (struct wl_resource *buffer,
 | 
			
		||||
meta_cursor_reference_from_buffer (MetaCursorTracker  *tracker,
 | 
			
		||||
                                   struct wl_resource *buffer,
 | 
			
		||||
                                   int                 hot_x,
 | 
			
		||||
                                   int                 hot_y)
 | 
			
		||||
{
 | 
			
		||||
@@ -382,47 +382,31 @@ meta_cursor_reference_from_buffer (struct wl_resource *buffer,
 | 
			
		||||
 | 
			
		||||
  self = g_slice_new0 (MetaCursorReference);
 | 
			
		||||
  self->ref_count = 1;
 | 
			
		||||
  meta_cursor_image_load_from_buffer (&self->image, buffer, hot_x, hot_y);
 | 
			
		||||
  meta_cursor_image_load_from_buffer (tracker, &self->image, buffer, hot_x, hot_y);
 | 
			
		||||
 | 
			
		||||
  return self;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
CoglTexture *
 | 
			
		||||
meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
 | 
			
		||||
                                        int                 *hot_x,
 | 
			
		||||
                                        int                 *hot_y)
 | 
			
		||||
{
 | 
			
		||||
  if (!cursor->image.texture)
 | 
			
		||||
    load_cursor_image (cursor);
 | 
			
		||||
 | 
			
		||||
  if (hot_x)
 | 
			
		||||
    *hot_x = cursor->image.hot_x;
 | 
			
		||||
  if (hot_y)
 | 
			
		||||
    *hot_y = cursor->image.hot_y;
 | 
			
		||||
 | 
			
		||||
  return COGL_TEXTURE (cursor->image.texture);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
struct gbm_bo *
 | 
			
		||||
meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
 | 
			
		||||
                                  int                 *hot_x,
 | 
			
		||||
                                  int                 *hot_y)
 | 
			
		||||
{
 | 
			
		||||
  if (!cursor->image.bo)
 | 
			
		||||
    load_cursor_image (cursor);
 | 
			
		||||
 | 
			
		||||
  if (hot_x)
 | 
			
		||||
    *hot_x = cursor->image.hot_x;
 | 
			
		||||
  if (hot_y)
 | 
			
		||||
    *hot_y = cursor->image.hot_y;
 | 
			
		||||
  return cursor->image.bo;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
MetaCursor
 | 
			
		||||
meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor)
 | 
			
		||||
{
 | 
			
		||||
  return cursor->cursor;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,20 +27,16 @@ typedef struct _MetaCursorReference MetaCursorReference;
 | 
			
		||||
MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor);
 | 
			
		||||
void meta_cursor_reference_unref (MetaCursorReference *cursor);
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-cursor-tracker.h>
 | 
			
		||||
#include <meta/common.h>
 | 
			
		||||
 | 
			
		||||
MetaCursorReference * meta_cursor_reference_from_theme  (MetaCursor          cursor);
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
#include <wayland-server.h>
 | 
			
		||||
MetaCursorReference * meta_cursor_reference_from_buffer (struct wl_resource *buffer,
 | 
			
		||||
 | 
			
		||||
MetaCursorReference * meta_cursor_reference_from_theme  (MetaCursorTracker  *tracker,
 | 
			
		||||
                                                         MetaCursor          cursor);
 | 
			
		||||
 | 
			
		||||
MetaCursorReference * meta_cursor_reference_from_buffer (MetaCursorTracker  *tracker,
 | 
			
		||||
                                                         struct wl_resource *buffer,
 | 
			
		||||
                                                         int                 hot_x,
 | 
			
		||||
                                                         int                 hot_y);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
MetaCursor meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor);
 | 
			
		||||
 | 
			
		||||
Cursor meta_cursor_create_x_cursor (Display    *xdisplay,
 | 
			
		||||
                                    MetaCursor  cursor);
 | 
			
		||||
 | 
			
		||||
#endif /* META_CURSOR_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
/*
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2013 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
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -180,9 +180,6 @@ create_monitor_skeleton (GDBusObjectManagerServer *manager,
 | 
			
		||||
  meta_dbus_object_skeleton_set_idle_monitor (object, skeleton);
 | 
			
		||||
 | 
			
		||||
  g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
 | 
			
		||||
 | 
			
		||||
  g_object_unref (skeleton);
 | 
			
		||||
  g_object_unref (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright 2013 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
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright 2013 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
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
@@ -38,7 +38,8 @@
 | 
			
		||||
#include <meta/meta-idle-monitor.h>
 | 
			
		||||
#include "meta-idle-monitor-private.h"
 | 
			
		||||
#include "meta-idle-monitor-dbus.h"
 | 
			
		||||
#include "meta-backend-private.h"
 | 
			
		||||
#include "backends/x11/meta-idle-monitor-xsync.h"
 | 
			
		||||
#include "backends/native/meta-idle-monitor-native.h"
 | 
			
		||||
 | 
			
		||||
G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer));
 | 
			
		||||
 | 
			
		||||
@@ -53,6 +54,9 @@ static GParamSpec *obj_props[PROP_LAST];
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaIdleMonitor, meta_idle_monitor, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static MetaIdleMonitor *device_monitors[256];
 | 
			
		||||
static int              device_id_max;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_meta_idle_monitor_watch_fire (MetaIdleMonitorWatch *watch)
 | 
			
		||||
{
 | 
			
		||||
@@ -156,6 +160,36 @@ meta_idle_monitor_init (MetaIdleMonitor *monitor)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GType
 | 
			
		||||
get_idle_monitor_type (void)
 | 
			
		||||
{
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    return META_TYPE_IDLE_MONITOR_NATIVE;
 | 
			
		||||
  else
 | 
			
		||||
    return META_TYPE_IDLE_MONITOR_XSYNC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
ensure_device_monitor (int device_id)
 | 
			
		||||
{
 | 
			
		||||
  if (device_monitors[device_id])
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  device_monitors[device_id] = g_object_new (get_idle_monitor_type (),
 | 
			
		||||
                                             "device-id", device_id,
 | 
			
		||||
                                             NULL);
 | 
			
		||||
  device_id_max = MAX (device_id_max, device_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* FIXME -- destroy device monitors at some point */
 | 
			
		||||
G_GNUC_UNUSED static void
 | 
			
		||||
destroy_device_monitor (int device_id)
 | 
			
		||||
{
 | 
			
		||||
  g_clear_object (&device_monitors[device_id]);
 | 
			
		||||
  if (device_id == device_id_max)
 | 
			
		||||
    device_id_max--;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_idle_monitor_get_core:
 | 
			
		||||
 *
 | 
			
		||||
@@ -166,8 +200,8 @@ meta_idle_monitor_init (MetaIdleMonitor *monitor)
 | 
			
		||||
MetaIdleMonitor *
 | 
			
		||||
meta_idle_monitor_get_core (void)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
  return meta_backend_get_idle_monitor (backend, 0);
 | 
			
		||||
  ensure_device_monitor (0);
 | 
			
		||||
  return device_monitors[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -181,8 +215,10 @@ meta_idle_monitor_get_core (void)
 | 
			
		||||
MetaIdleMonitor *
 | 
			
		||||
meta_idle_monitor_get_for_device (int device_id)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
  return meta_backend_get_idle_monitor (backend, device_id);
 | 
			
		||||
  g_return_val_if_fail (device_id > 0 && device_id < 256, NULL);
 | 
			
		||||
 | 
			
		||||
  ensure_device_monitor (device_id);
 | 
			
		||||
  return device_monitors[device_id];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaIdleMonitorWatch *
 | 
			
		||||
@@ -210,9 +246,9 @@ make_watch (MetaIdleMonitor           *monitor,
 | 
			
		||||
 * meta_idle_monitor_add_idle_watch:
 | 
			
		||||
 * @monitor: A #MetaIdleMonitor
 | 
			
		||||
 * @interval_msec: The idletime interval, in milliseconds
 | 
			
		||||
 * @callback: (nullable): The callback to call when the user has
 | 
			
		||||
 * @callback: (allow-none): The callback to call when the user has
 | 
			
		||||
 *     accumulated @interval_msec milliseconds of idle time.
 | 
			
		||||
 * @user_data: (nullable): The user data to pass to the callback
 | 
			
		||||
 * @user_data: (allow-none): The user data to pass to the callback
 | 
			
		||||
 * @notify: A #GDestroyNotify
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a watch id
 | 
			
		||||
@@ -252,9 +288,9 @@ meta_idle_monitor_add_idle_watch (MetaIdleMonitor	       *monitor,
 | 
			
		||||
/**
 | 
			
		||||
 * meta_idle_monitor_add_user_active_watch:
 | 
			
		||||
 * @monitor: A #MetaIdleMonitor
 | 
			
		||||
 * @callback: (nullable): The callback to call when the user is
 | 
			
		||||
 * @callback: (allow-none): The callback to call when the user is
 | 
			
		||||
 *     active again.
 | 
			
		||||
 * @user_data: (nullable): The user data to pass to the callback
 | 
			
		||||
 * @user_data: (allow-none): The user data to pass to the callback
 | 
			
		||||
 * @notify: A #GDestroyNotify
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a watch id
 | 
			
		||||
@@ -316,3 +352,16 @@ meta_idle_monitor_get_idletime (MetaIdleMonitor *monitor)
 | 
			
		||||
{
 | 
			
		||||
  return META_IDLE_MONITOR_GET_CLASS (monitor)->get_idletime (monitor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_idle_monitor_xsync_handle_xevent_all (XEvent *xevent)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i <= device_id_max; i++)
 | 
			
		||||
    if (device_monitors[i])
 | 
			
		||||
      meta_idle_monitor_xsync_handle_xevent (device_monitors[i], (XSyncAlarmNotifyEvent*)xevent);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,87 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2014 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
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Carlos Garnacho <carlosg@gnome.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_INPUT_SETTINGS_PRIVATE_H
 | 
			
		||||
#define META_INPUT_SETTINGS_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_INPUT_SETTINGS             (meta_input_settings_get_type ())
 | 
			
		||||
#define META_INPUT_SETTINGS(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS, MetaInputSettings))
 | 
			
		||||
#define META_INPUT_SETTINGS_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_INPUT_SETTINGS, MetaInputSettingsClass))
 | 
			
		||||
#define META_IS_INPUT_SETTINGS(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS))
 | 
			
		||||
#define META_IS_INPUT_SETTINGS_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_INPUT_SETTINGS))
 | 
			
		||||
#define META_INPUT_SETTINGS_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_INPUT_SETTINGS, MetaInputSettingsClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaInputSettings MetaInputSettings;
 | 
			
		||||
typedef struct _MetaInputSettingsClass MetaInputSettingsClass;
 | 
			
		||||
 | 
			
		||||
struct _MetaInputSettings
 | 
			
		||||
{
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaInputSettingsClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  void (* set_send_events)   (MetaInputSettings        *settings,
 | 
			
		||||
                              ClutterInputDevice       *device,
 | 
			
		||||
                              GDesktopDeviceSendEvents  mode);
 | 
			
		||||
  void (* set_matrix)        (MetaInputSettings  *settings,
 | 
			
		||||
                              ClutterInputDevice *device,
 | 
			
		||||
                              gfloat              matrix[6]);
 | 
			
		||||
  void (* set_speed)         (MetaInputSettings  *settings,
 | 
			
		||||
                              ClutterInputDevice *device,
 | 
			
		||||
                              gdouble             speed);
 | 
			
		||||
  void (* set_left_handed)   (MetaInputSettings  *settings,
 | 
			
		||||
                              ClutterInputDevice *device,
 | 
			
		||||
                              gboolean            enabled);
 | 
			
		||||
  void (* set_tap_enabled)   (MetaInputSettings  *settings,
 | 
			
		||||
                              ClutterInputDevice *device,
 | 
			
		||||
                              gboolean            enabled);
 | 
			
		||||
  void (* set_invert_scroll) (MetaInputSettings  *settings,
 | 
			
		||||
                              ClutterInputDevice *device,
 | 
			
		||||
                              gboolean            inverted);
 | 
			
		||||
  void (* set_scroll_method) (MetaInputSettings            *settings,
 | 
			
		||||
                              ClutterInputDevice           *device,
 | 
			
		||||
                              GDesktopTouchpadScrollMethod  mode);
 | 
			
		||||
  void (* set_scroll_button) (MetaInputSettings  *settings,
 | 
			
		||||
                              ClutterInputDevice *device,
 | 
			
		||||
                              guint               button);
 | 
			
		||||
 | 
			
		||||
  void (* set_click_method)  (MetaInputSettings            *settings,
 | 
			
		||||
                              ClutterInputDevice           *device,
 | 
			
		||||
                              GDesktopTouchpadClickMethod   mode);
 | 
			
		||||
 | 
			
		||||
  void (* set_keyboard_repeat) (MetaInputSettings *settings,
 | 
			
		||||
                                gboolean           repeat,
 | 
			
		||||
                                guint              delay,
 | 
			
		||||
                                guint              interval);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType meta_input_settings_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
MetaInputSettings * meta_input_settings_create (void);
 | 
			
		||||
 | 
			
		||||
#endif /* META_INPUT_SETTINGS_PRIVATE_H */
 | 
			
		||||
@@ -1,895 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2014 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
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Carlos Garnacho <carlosg@gnome.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SECTION:input-settings
 | 
			
		||||
 * @title: MetaInputSettings
 | 
			
		||||
 * @short_description: Mutter input device configuration
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-backend-private.h"
 | 
			
		||||
#include "meta-input-settings-private.h"
 | 
			
		||||
#include "x11/meta-input-settings-x11.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
#include "native/meta-backend-native.h"
 | 
			
		||||
#include "native/meta-input-settings-native.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaInputSettingsPrivate MetaInputSettingsPrivate;
 | 
			
		||||
typedef struct _DeviceMappingInfo DeviceMappingInfo;
 | 
			
		||||
 | 
			
		||||
struct _DeviceMappingInfo
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettings *input_settings;
 | 
			
		||||
  ClutterInputDevice *device;
 | 
			
		||||
  GSettings *settings;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaInputSettingsPrivate
 | 
			
		||||
{
 | 
			
		||||
  ClutterDeviceManager *device_manager;
 | 
			
		||||
  MetaMonitorManager *monitor_manager;
 | 
			
		||||
  guint monitors_changed_id;
 | 
			
		||||
 | 
			
		||||
  GSettings *mouse_settings;
 | 
			
		||||
  GSettings *touchpad_settings;
 | 
			
		||||
  GSettings *trackball_settings;
 | 
			
		||||
  GSettings *keyboard_settings;
 | 
			
		||||
 | 
			
		||||
  GHashTable *mappable_devices;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef void (*ConfigBoolFunc)   (MetaInputSettings  *input_settings,
 | 
			
		||||
                                  ClutterInputDevice *device,
 | 
			
		||||
                                  gboolean            setting);
 | 
			
		||||
typedef void (*ConfigDoubleFunc) (MetaInputSettings  *input_settings,
 | 
			
		||||
                                  ClutterInputDevice *device,
 | 
			
		||||
                                  gdouble             value);
 | 
			
		||||
typedef void (*ConfigUintFunc)   (MetaInputSettings  *input_settings,
 | 
			
		||||
                                  ClutterInputDevice *device,
 | 
			
		||||
                                  guint               value);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static GSList *
 | 
			
		||||
meta_input_settings_get_devices (MetaInputSettings      *settings,
 | 
			
		||||
                                 ClutterInputDeviceType  type)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  const GSList *devices;
 | 
			
		||||
  GSList *list = NULL;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (settings);
 | 
			
		||||
  devices = clutter_device_manager_peek_devices (priv->device_manager);
 | 
			
		||||
 | 
			
		||||
  while (devices)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterInputDevice *device = devices->data;
 | 
			
		||||
 | 
			
		||||
      if (clutter_input_device_get_device_type (device) == type &&
 | 
			
		||||
          clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER)
 | 
			
		||||
        list = g_slist_prepend (list, device);
 | 
			
		||||
 | 
			
		||||
      devices = devices->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_input_settings_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettings *settings = META_INPUT_SETTINGS (object);
 | 
			
		||||
  MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (settings);
 | 
			
		||||
 | 
			
		||||
  g_clear_object (&priv->mouse_settings);
 | 
			
		||||
  g_clear_object (&priv->touchpad_settings);
 | 
			
		||||
  g_clear_object (&priv->trackball_settings);
 | 
			
		||||
  g_clear_object (&priv->keyboard_settings);
 | 
			
		||||
  g_clear_pointer (&priv->mappable_devices, g_hash_table_unref);
 | 
			
		||||
 | 
			
		||||
  if (priv->monitors_changed_id && priv->monitor_manager)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_handler_disconnect (priv->monitor_manager,
 | 
			
		||||
                                   priv->monitors_changed_id);
 | 
			
		||||
      priv->monitors_changed_id = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_clear_object (&priv->monitor_manager);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_input_settings_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
settings_device_set_bool_setting (MetaInputSettings  *input_settings,
 | 
			
		||||
                                  ClutterInputDevice *device,
 | 
			
		||||
                                  ConfigBoolFunc      func,
 | 
			
		||||
                                  gboolean            enabled)
 | 
			
		||||
{
 | 
			
		||||
  func (input_settings, device, enabled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
settings_set_bool_setting (MetaInputSettings      *input_settings,
 | 
			
		||||
                           ClutterInputDeviceType  type,
 | 
			
		||||
                           ConfigBoolFunc          func,
 | 
			
		||||
                           gboolean                enabled)
 | 
			
		||||
{
 | 
			
		||||
  GSList *devices, *d;
 | 
			
		||||
 | 
			
		||||
  devices = meta_input_settings_get_devices (input_settings, type);
 | 
			
		||||
 | 
			
		||||
  for (d = devices; d; d = d->next)
 | 
			
		||||
    settings_device_set_bool_setting (input_settings, d->data, func, enabled);
 | 
			
		||||
 | 
			
		||||
  g_slist_free (devices);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
settings_device_set_double_setting (MetaInputSettings  *input_settings,
 | 
			
		||||
                                    ClutterInputDevice *device,
 | 
			
		||||
                                    ConfigDoubleFunc    func,
 | 
			
		||||
                                    gdouble             value)
 | 
			
		||||
{
 | 
			
		||||
  func (input_settings, device, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
settings_set_double_setting (MetaInputSettings      *input_settings,
 | 
			
		||||
                             ClutterInputDeviceType  type,
 | 
			
		||||
                             ConfigDoubleFunc        func,
 | 
			
		||||
                             gdouble                 value)
 | 
			
		||||
{
 | 
			
		||||
  GSList *devices, *d;
 | 
			
		||||
 | 
			
		||||
  devices = meta_input_settings_get_devices (input_settings, type);
 | 
			
		||||
 | 
			
		||||
  for (d = devices; d; d = d->next)
 | 
			
		||||
    settings_device_set_double_setting (input_settings, d->data, func, value);
 | 
			
		||||
 | 
			
		||||
  g_slist_free (devices);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
settings_device_set_uint_setting (MetaInputSettings  *input_settings,
 | 
			
		||||
                                  ClutterInputDevice *device,
 | 
			
		||||
                                  ConfigUintFunc      func,
 | 
			
		||||
                                  guint               value)
 | 
			
		||||
{
 | 
			
		||||
  (func) (input_settings, device, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
settings_set_uint_setting (MetaInputSettings      *input_settings,
 | 
			
		||||
                           ClutterInputDeviceType  type,
 | 
			
		||||
                           ConfigUintFunc          func,
 | 
			
		||||
                           guint                   value)
 | 
			
		||||
{
 | 
			
		||||
  GSList *devices, *d;
 | 
			
		||||
 | 
			
		||||
  devices = meta_input_settings_get_devices (input_settings, type);
 | 
			
		||||
 | 
			
		||||
  for (d = devices; d; d = d->next)
 | 
			
		||||
    settings_device_set_uint_setting (input_settings, d->data, func, value);
 | 
			
		||||
 | 
			
		||||
  g_slist_free (devices);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_touchpad_left_handed (MetaInputSettings  *input_settings,
 | 
			
		||||
                             ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsClass *input_settings_class;
 | 
			
		||||
  GDesktopTouchpadHandedness handedness;
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  gboolean enabled = FALSE;
 | 
			
		||||
 | 
			
		||||
  if (device &&
 | 
			
		||||
      clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
 | 
			
		||||
  handedness = g_settings_get_enum (priv->touchpad_settings, "left-handed");
 | 
			
		||||
 | 
			
		||||
  switch (handedness)
 | 
			
		||||
    {
 | 
			
		||||
    case G_DESKTOP_TOUCHPAD_HANDEDNESS_RIGHT:
 | 
			
		||||
      enabled = FALSE;
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT:
 | 
			
		||||
      enabled = TRUE;
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE:
 | 
			
		||||
      enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      g_assert_not_reached ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (device)
 | 
			
		||||
    {
 | 
			
		||||
      settings_device_set_bool_setting (input_settings, device,
 | 
			
		||||
                                        input_settings_class->set_left_handed,
 | 
			
		||||
                                        enabled);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
 | 
			
		||||
                                 input_settings_class->set_left_handed,
 | 
			
		||||
                                 enabled);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_mouse_left_handed (MetaInputSettings  *input_settings,
 | 
			
		||||
                          ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsClass *input_settings_class;
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  gboolean enabled;
 | 
			
		||||
 | 
			
		||||
  if (device &&
 | 
			
		||||
      clutter_input_device_get_device_type (device) != CLUTTER_POINTER_DEVICE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
 | 
			
		||||
  enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
 | 
			
		||||
 | 
			
		||||
  if (device)
 | 
			
		||||
    {
 | 
			
		||||
      settings_device_set_bool_setting (input_settings, device,
 | 
			
		||||
                                        input_settings_class->set_left_handed,
 | 
			
		||||
                                        enabled);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      GDesktopTouchpadHandedness touchpad_handedness;
 | 
			
		||||
 | 
			
		||||
      settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE,
 | 
			
		||||
                                 input_settings_class->set_left_handed,
 | 
			
		||||
                                 enabled);
 | 
			
		||||
 | 
			
		||||
      touchpad_handedness = g_settings_get_enum (priv->touchpad_settings,
 | 
			
		||||
                                                 "left-handed");
 | 
			
		||||
 | 
			
		||||
      /* Also update touchpads if they're following mouse settings */
 | 
			
		||||
      if (touchpad_handedness == G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE)
 | 
			
		||||
        update_touchpad_left_handed (input_settings, NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSettings *
 | 
			
		||||
get_settings_for_device_type (MetaInputSettings      *input_settings,
 | 
			
		||||
                              ClutterInputDeviceType  type)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  switch (type)
 | 
			
		||||
    {
 | 
			
		||||
    case CLUTTER_POINTER_DEVICE:
 | 
			
		||||
      return priv->mouse_settings;
 | 
			
		||||
    case CLUTTER_TOUCHPAD_DEVICE:
 | 
			
		||||
      return priv->touchpad_settings;
 | 
			
		||||
    default:
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_device_speed (MetaInputSettings      *input_settings,
 | 
			
		||||
                     ClutterInputDevice     *device)
 | 
			
		||||
{
 | 
			
		||||
  GSettings *settings;
 | 
			
		||||
  ConfigDoubleFunc func;
 | 
			
		||||
  const gchar *key = "speed";
 | 
			
		||||
 | 
			
		||||
  func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_speed;
 | 
			
		||||
 | 
			
		||||
  if (device)
 | 
			
		||||
    {
 | 
			
		||||
      settings = get_settings_for_device_type (input_settings,
 | 
			
		||||
                                               clutter_input_device_get_device_type (device));
 | 
			
		||||
      if (!settings)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      settings_device_set_double_setting (input_settings, device, func,
 | 
			
		||||
                                          g_settings_get_double (settings, key));
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      settings = get_settings_for_device_type (input_settings, CLUTTER_POINTER_DEVICE);
 | 
			
		||||
      settings_set_double_setting (input_settings, CLUTTER_POINTER_DEVICE, func,
 | 
			
		||||
                                   g_settings_get_double (settings, key));
 | 
			
		||||
      settings = get_settings_for_device_type (input_settings, CLUTTER_TOUCHPAD_DEVICE);
 | 
			
		||||
      settings_set_double_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, func,
 | 
			
		||||
                                   g_settings_get_double (settings, key));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_device_natural_scroll (MetaInputSettings      *input_settings,
 | 
			
		||||
                              ClutterInputDevice     *device)
 | 
			
		||||
{
 | 
			
		||||
  GSettings *settings;
 | 
			
		||||
  ConfigBoolFunc func;
 | 
			
		||||
  const gchar *key = "natural-scroll";
 | 
			
		||||
 | 
			
		||||
  func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_invert_scroll;
 | 
			
		||||
 | 
			
		||||
  if (device)
 | 
			
		||||
    {
 | 
			
		||||
      settings = get_settings_for_device_type (input_settings,
 | 
			
		||||
                                               clutter_input_device_get_device_type (device));
 | 
			
		||||
      if (!settings)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      settings_device_set_bool_setting (input_settings, device, func,
 | 
			
		||||
                                        g_settings_get_boolean (settings, key));
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      settings = get_settings_for_device_type (input_settings, CLUTTER_POINTER_DEVICE);
 | 
			
		||||
      settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE, func,
 | 
			
		||||
                                 g_settings_get_boolean (settings, key));
 | 
			
		||||
      settings = get_settings_for_device_type (input_settings, CLUTTER_TOUCHPAD_DEVICE);
 | 
			
		||||
      settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, func,
 | 
			
		||||
                                 g_settings_get_boolean (settings, key));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_touchpad_tap_enabled (MetaInputSettings  *input_settings,
 | 
			
		||||
                             ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsClass *input_settings_class;
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  gboolean enabled;
 | 
			
		||||
 | 
			
		||||
  if (device &&
 | 
			
		||||
      clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
 | 
			
		||||
  enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
 | 
			
		||||
 | 
			
		||||
  if (device)
 | 
			
		||||
    {
 | 
			
		||||
      settings_device_set_bool_setting (input_settings, device,
 | 
			
		||||
                                        input_settings_class->set_tap_enabled,
 | 
			
		||||
                                        enabled);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
 | 
			
		||||
                                 input_settings_class->set_tap_enabled,
 | 
			
		||||
                                 enabled);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_touchpad_scroll_method (MetaInputSettings *input_settings,
 | 
			
		||||
                               ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsClass *input_settings_class;
 | 
			
		||||
  GDesktopTouchpadScrollMethod method;
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  if (device &&
 | 
			
		||||
      clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
 | 
			
		||||
  method = g_settings_get_enum (priv->touchpad_settings, "scroll-method");
 | 
			
		||||
 | 
			
		||||
  if (device)
 | 
			
		||||
    {
 | 
			
		||||
      settings_device_set_uint_setting (input_settings, device,
 | 
			
		||||
                                        input_settings_class->set_scroll_method,
 | 
			
		||||
                                        method);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
 | 
			
		||||
                                 (ConfigUintFunc) input_settings_class->set_scroll_method,
 | 
			
		||||
                                 method);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_touchpad_click_method (MetaInputSettings *input_settings,
 | 
			
		||||
                              ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsClass *input_settings_class;
 | 
			
		||||
  GDesktopTouchpadScrollMethod method;
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  if (device &&
 | 
			
		||||
      clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
 | 
			
		||||
  method = g_settings_get_enum (priv->touchpad_settings, "click-method");
 | 
			
		||||
 | 
			
		||||
  if (device)
 | 
			
		||||
    {
 | 
			
		||||
      settings_device_set_uint_setting (input_settings, device,
 | 
			
		||||
                                        input_settings_class->set_click_method,
 | 
			
		||||
                                        method);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
 | 
			
		||||
                                 (ConfigUintFunc) input_settings_class->set_click_method,
 | 
			
		||||
                                 method);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_touchpad_send_events (MetaInputSettings  *input_settings,
 | 
			
		||||
                             ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsClass *input_settings_class;
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  GDesktopDeviceSendEvents mode;
 | 
			
		||||
 | 
			
		||||
  if (device &&
 | 
			
		||||
      clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
 | 
			
		||||
  mode = g_settings_get_enum (priv->touchpad_settings, "send-events");
 | 
			
		||||
 | 
			
		||||
  if (device)
 | 
			
		||||
    {
 | 
			
		||||
      settings_device_set_uint_setting (input_settings, device,
 | 
			
		||||
                                        input_settings_class->set_send_events,
 | 
			
		||||
                                        mode);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
 | 
			
		||||
                                 input_settings_class->set_send_events,
 | 
			
		||||
                                 mode);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
device_is_trackball (ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  gboolean is_trackball;
 | 
			
		||||
  char *name;
 | 
			
		||||
 | 
			
		||||
  if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  name = g_ascii_strdown (clutter_input_device_get_device_name (device), -1);
 | 
			
		||||
  is_trackball = strstr (name, "trackball") != NULL;
 | 
			
		||||
  g_free (name);
 | 
			
		||||
 | 
			
		||||
  return is_trackball;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_trackball_scroll_button (MetaInputSettings  *input_settings,
 | 
			
		||||
                                ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsClass *input_settings_class;
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  guint button;
 | 
			
		||||
 | 
			
		||||
  if (device && !device_is_trackball (device))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
 | 
			
		||||
  /* This key is 'i' in the schema but it also specifies a minimum
 | 
			
		||||
   * range of 0 so the cast here is safe. */
 | 
			
		||||
  button = (guint) g_settings_get_int (priv->trackball_settings, "scroll-wheel-emulation-button");
 | 
			
		||||
 | 
			
		||||
  if (device)
 | 
			
		||||
    {
 | 
			
		||||
      input_settings_class->set_scroll_button (input_settings, device, button);
 | 
			
		||||
    }
 | 
			
		||||
  else if (!device)
 | 
			
		||||
    {
 | 
			
		||||
      MetaInputSettingsPrivate *priv;
 | 
			
		||||
      const GSList *devices;
 | 
			
		||||
 | 
			
		||||
      priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
      devices = clutter_device_manager_peek_devices (priv->device_manager);
 | 
			
		||||
 | 
			
		||||
      while (devices)
 | 
			
		||||
        {
 | 
			
		||||
          ClutterInputDevice *device = devices->data;
 | 
			
		||||
 | 
			
		||||
          if (device_is_trackball (device))
 | 
			
		||||
            input_settings_class->set_scroll_button (input_settings, device, button);
 | 
			
		||||
 | 
			
		||||
          devices = devices->next;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_keyboard_repeat (MetaInputSettings *input_settings)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsClass *input_settings_class;
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  guint delay, interval;
 | 
			
		||||
  gboolean repeat;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  repeat = g_settings_get_boolean (priv->keyboard_settings, "repeat");
 | 
			
		||||
  delay = g_settings_get_uint (priv->keyboard_settings, "delay");
 | 
			
		||||
  interval = g_settings_get_uint (priv->keyboard_settings, "repeat-interval");
 | 
			
		||||
 | 
			
		||||
  input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
 | 
			
		||||
  input_settings_class->set_keyboard_repeat (input_settings,
 | 
			
		||||
                                             repeat, delay, interval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaOutput *
 | 
			
		||||
meta_input_settings_find_output (MetaInputSettings  *input_settings,
 | 
			
		||||
                                 GSettings          *settings,
 | 
			
		||||
                                 ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  guint n_values, n_outputs, i;
 | 
			
		||||
  MetaOutput *outputs;
 | 
			
		||||
  gchar **edid;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  edid = g_settings_get_strv (settings, "display");
 | 
			
		||||
  n_values = g_strv_length (edid);
 | 
			
		||||
 | 
			
		||||
  if (n_values != 3)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("EDID configuration for device '%s' "
 | 
			
		||||
                 "is incorrect, must have 3 values",
 | 
			
		||||
                 clutter_input_device_get_device_name (device));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!*edid[0] && !*edid[1] && !*edid[2])
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  outputs = meta_monitor_manager_get_outputs (priv->monitor_manager,
 | 
			
		||||
                                              &n_outputs);
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (g_strcmp0 (outputs[i].vendor, edid[0]) == 0 &&
 | 
			
		||||
          g_strcmp0 (outputs[i].product, edid[1]) == 0 &&
 | 
			
		||||
          g_strcmp0 (outputs[i].serial, edid[2]) == 0)
 | 
			
		||||
        return &outputs[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_device_display (MetaInputSettings  *input_settings,
 | 
			
		||||
                       GSettings          *settings,
 | 
			
		||||
                       ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsClass *input_settings_class;
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  gfloat matrix[6] = { 1, 0, 0, 0, 1, 0 };
 | 
			
		||||
  MetaOutput *output;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
 | 
			
		||||
  output = meta_input_settings_find_output (input_settings, settings, device);
 | 
			
		||||
 | 
			
		||||
  if (output)
 | 
			
		||||
    meta_monitor_manager_get_monitor_matrix (priv->monitor_manager,
 | 
			
		||||
                                             output, matrix);
 | 
			
		||||
 | 
			
		||||
  input_settings_class->set_matrix (input_settings, device, matrix);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_input_settings_changed_cb (GSettings  *settings,
 | 
			
		||||
                                const char *key,
 | 
			
		||||
                                gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data);
 | 
			
		||||
  MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
 | 
			
		||||
  if (settings == priv->mouse_settings)
 | 
			
		||||
    {
 | 
			
		||||
      if (strcmp (key, "left-handed") == 0)
 | 
			
		||||
        update_mouse_left_handed (input_settings, NULL);
 | 
			
		||||
      else if (strcmp (key, "speed") == 0)
 | 
			
		||||
        update_device_speed (input_settings, NULL);
 | 
			
		||||
      else if (strcmp (key, "natural-scroll") == 0)
 | 
			
		||||
        update_device_natural_scroll (input_settings, NULL);
 | 
			
		||||
    }
 | 
			
		||||
  else if (settings == priv->touchpad_settings)
 | 
			
		||||
    {
 | 
			
		||||
      if (strcmp (key, "left-handed") == 0)
 | 
			
		||||
        update_touchpad_left_handed (input_settings, NULL);
 | 
			
		||||
      else if (strcmp (key, "speed") == 0)
 | 
			
		||||
        update_device_speed (input_settings, NULL);
 | 
			
		||||
      else if (strcmp (key, "natural-scroll") == 0)
 | 
			
		||||
        update_device_natural_scroll (input_settings, NULL);
 | 
			
		||||
      else if (strcmp (key, "tap-to-click") == 0)
 | 
			
		||||
        update_touchpad_tap_enabled (input_settings, NULL);
 | 
			
		||||
      else if (strcmp (key, "send-events") == 0)
 | 
			
		||||
        update_touchpad_send_events (input_settings, NULL);
 | 
			
		||||
      else if (strcmp (key, "scroll-method") == 0)
 | 
			
		||||
        update_touchpad_scroll_method (input_settings, NULL);
 | 
			
		||||
      else if (strcmp (key, "click-method") == 0)
 | 
			
		||||
        update_touchpad_click_method (input_settings, NULL);
 | 
			
		||||
    }
 | 
			
		||||
  else if (settings == priv->trackball_settings)
 | 
			
		||||
    {
 | 
			
		||||
      if (strcmp (key, "scroll-wheel-emulation-button") == 0)
 | 
			
		||||
        update_trackball_scroll_button (input_settings, NULL);
 | 
			
		||||
    }
 | 
			
		||||
  else if (settings == priv->keyboard_settings)
 | 
			
		||||
    {
 | 
			
		||||
      if (strcmp (key, "repeat") == 0 ||
 | 
			
		||||
          strcmp (key, "repeat-interval") == 0 ||
 | 
			
		||||
          strcmp (key, "delay") == 0)
 | 
			
		||||
        update_keyboard_repeat (input_settings);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mapped_device_changed_cb (GSettings         *settings,
 | 
			
		||||
                          const gchar       *key,
 | 
			
		||||
                          DeviceMappingInfo *info)
 | 
			
		||||
{
 | 
			
		||||
  if (strcmp (key, "display") == 0)
 | 
			
		||||
    update_device_display (info->input_settings, settings, info->device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSettings *
 | 
			
		||||
lookup_device_settings (ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  const gchar *group, *schema, *vendor, *product;
 | 
			
		||||
  ClutterInputDeviceType type;
 | 
			
		||||
  GSettings *settings;
 | 
			
		||||
  gchar *path;
 | 
			
		||||
 | 
			
		||||
  type = clutter_input_device_get_device_type (device);
 | 
			
		||||
 | 
			
		||||
  if (type == CLUTTER_TOUCHSCREEN_DEVICE)
 | 
			
		||||
    {
 | 
			
		||||
      group = "touchscreens";
 | 
			
		||||
      schema = "org.gnome.desktop.peripherals.touchscreen";
 | 
			
		||||
    }
 | 
			
		||||
  else if (type == CLUTTER_TABLET_DEVICE ||
 | 
			
		||||
           type == CLUTTER_PEN_DEVICE ||
 | 
			
		||||
           type == CLUTTER_ERASER_DEVICE ||
 | 
			
		||||
           type == CLUTTER_CURSOR_DEVICE)
 | 
			
		||||
    {
 | 
			
		||||
      group = "tablets";
 | 
			
		||||
      schema = "org.gnome.desktop.peripherals.tablet";
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  vendor = clutter_input_device_get_vendor_id (device);
 | 
			
		||||
  product = clutter_input_device_get_product_id (device);
 | 
			
		||||
  path = g_strdup_printf ("/org/gnome/desktop/peripherals/%s/%s:%s/",
 | 
			
		||||
                          group, vendor, product);
 | 
			
		||||
 | 
			
		||||
  settings = g_settings_new_with_path (schema, path);
 | 
			
		||||
  g_free (path);
 | 
			
		||||
 | 
			
		||||
  return settings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
monitors_changed_cb (MetaMonitorManager *monitor_manager,
 | 
			
		||||
                     MetaInputSettings  *input_settings)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  ClutterInputDevice *device;
 | 
			
		||||
  GSettings *settings;
 | 
			
		||||
  GHashTableIter iter;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  g_hash_table_iter_init (&iter, priv->mappable_devices);
 | 
			
		||||
 | 
			
		||||
  while (g_hash_table_iter_next (&iter, (gpointer *) &device,
 | 
			
		||||
                                 (gpointer *) &settings))
 | 
			
		||||
    update_device_display (input_settings, settings, device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
check_add_mappable_device (MetaInputSettings  *input_settings,
 | 
			
		||||
                           ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  DeviceMappingInfo *info;
 | 
			
		||||
  GSettings *settings;
 | 
			
		||||
 | 
			
		||||
  settings = lookup_device_settings (device);
 | 
			
		||||
 | 
			
		||||
  if (!settings)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
 | 
			
		||||
  info = g_new0 (DeviceMappingInfo, 1);
 | 
			
		||||
  info->input_settings = input_settings;
 | 
			
		||||
  info->device = device;
 | 
			
		||||
  info->settings = settings;
 | 
			
		||||
 | 
			
		||||
  g_signal_connect_data (settings, "changed",
 | 
			
		||||
                         G_CALLBACK (mapped_device_changed_cb),
 | 
			
		||||
                         info, (GClosureNotify) g_free, 0);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_insert (priv->mappable_devices, device, settings);
 | 
			
		||||
 | 
			
		||||
  update_device_display (input_settings, settings, device);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
apply_device_settings (MetaInputSettings  *input_settings,
 | 
			
		||||
                       ClutterInputDevice *device)
 | 
			
		||||
{
 | 
			
		||||
  update_mouse_left_handed (input_settings, device);
 | 
			
		||||
  update_device_speed (input_settings, device);
 | 
			
		||||
  update_device_natural_scroll (input_settings, device);
 | 
			
		||||
 | 
			
		||||
  update_touchpad_left_handed (input_settings, device);
 | 
			
		||||
  update_device_speed (input_settings, device);
 | 
			
		||||
  update_device_natural_scroll (input_settings, device);
 | 
			
		||||
  update_touchpad_tap_enabled (input_settings, device);
 | 
			
		||||
  update_touchpad_send_events (input_settings, device);
 | 
			
		||||
  update_touchpad_scroll_method (input_settings, device);
 | 
			
		||||
  update_touchpad_click_method (input_settings, device);
 | 
			
		||||
 | 
			
		||||
  update_trackball_scroll_button (input_settings, device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_input_settings_device_added (ClutterDeviceManager *device_manager,
 | 
			
		||||
                                  ClutterInputDevice   *device,
 | 
			
		||||
                                  MetaInputSettings    *input_settings)
 | 
			
		||||
{
 | 
			
		||||
  if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  apply_device_settings (input_settings, device);
 | 
			
		||||
  check_add_mappable_device (input_settings, device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_input_settings_device_removed (ClutterDeviceManager *device_manager,
 | 
			
		||||
                                    ClutterInputDevice   *device,
 | 
			
		||||
                                    MetaInputSettings    *input_settings)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  g_hash_table_remove (priv->mappable_devices, device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
check_mappable_devices (MetaInputSettings *input_settings)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
  const GSList *devices, *l;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (input_settings);
 | 
			
		||||
  devices = clutter_device_manager_peek_devices (priv->device_manager);
 | 
			
		||||
 | 
			
		||||
  for (l = devices; l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      ClutterInputDevice *device = l->data;
 | 
			
		||||
 | 
			
		||||
      if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      check_add_mappable_device (input_settings, device);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_input_settings_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettings *input_settings = META_INPUT_SETTINGS (object);
 | 
			
		||||
 | 
			
		||||
  apply_device_settings (input_settings, NULL);
 | 
			
		||||
  update_keyboard_repeat (input_settings);
 | 
			
		||||
  check_mappable_devices (input_settings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_input_settings_class_init (MetaInputSettingsClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->dispose = meta_input_settings_dispose;
 | 
			
		||||
  object_class->constructed = meta_input_settings_constructed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_input_settings_init (MetaInputSettings *settings)
 | 
			
		||||
{
 | 
			
		||||
  MetaInputSettingsPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  priv = meta_input_settings_get_instance_private (settings);
 | 
			
		||||
  priv->device_manager = clutter_device_manager_get_default ();
 | 
			
		||||
  g_signal_connect (priv->device_manager, "device-added",
 | 
			
		||||
                    G_CALLBACK (meta_input_settings_device_added), settings);
 | 
			
		||||
  g_signal_connect (priv->device_manager, "device-removed",
 | 
			
		||||
                    G_CALLBACK (meta_input_settings_device_removed), settings);
 | 
			
		||||
 | 
			
		||||
  priv->mouse_settings = g_settings_new ("org.gnome.desktop.peripherals.mouse");
 | 
			
		||||
  g_signal_connect (priv->mouse_settings, "changed",
 | 
			
		||||
                    G_CALLBACK (meta_input_settings_changed_cb), settings);
 | 
			
		||||
 | 
			
		||||
  priv->touchpad_settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
 | 
			
		||||
  g_signal_connect (priv->touchpad_settings, "changed",
 | 
			
		||||
                    G_CALLBACK (meta_input_settings_changed_cb), settings);
 | 
			
		||||
 | 
			
		||||
  priv->trackball_settings = g_settings_new ("org.gnome.desktop.peripherals.trackball");
 | 
			
		||||
  g_signal_connect (priv->trackball_settings, "changed",
 | 
			
		||||
                    G_CALLBACK (meta_input_settings_changed_cb), settings);
 | 
			
		||||
 | 
			
		||||
  priv->keyboard_settings = g_settings_new ("org.gnome.desktop.peripherals.keyboard");
 | 
			
		||||
  g_signal_connect (priv->keyboard_settings, "changed",
 | 
			
		||||
                    G_CALLBACK (meta_input_settings_changed_cb), settings);
 | 
			
		||||
 | 
			
		||||
  priv->mappable_devices =
 | 
			
		||||
    g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref);
 | 
			
		||||
 | 
			
		||||
  priv->monitor_manager = g_object_ref (meta_monitor_manager_get ());
 | 
			
		||||
  g_signal_connect (priv->monitor_manager, "monitors-changed",
 | 
			
		||||
                    G_CALLBACK (monitors_changed_cb), settings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaInputSettings *
 | 
			
		||||
meta_input_settings_create (void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
  MetaBackend *backend;
 | 
			
		||||
 | 
			
		||||
  backend = meta_get_backend ();
 | 
			
		||||
 | 
			
		||||
  if (META_IS_BACKEND_NATIVE (backend))
 | 
			
		||||
    return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
  if (!meta_is_wayland_compositor ())
 | 
			
		||||
    return g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL);
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2001, 2002 Havoc Pennington
 | 
			
		||||
 * Copyright (C) 2002, 2003 Red Hat Inc.
 | 
			
		||||
 * Some ICCCM manager selection code derived from fvwm2,
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * Copyright (C) 2003 Rob Adams
 | 
			
		||||
 * Copyright (C) 2004-2006 Elijah Newren
 | 
			
		||||
 * Copyright (C) 2013 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
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
@@ -34,7 +34,6 @@
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "boxes-private.h"
 | 
			
		||||
#include "meta-monitor-config.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
@@ -61,14 +60,13 @@ typedef struct {
 | 
			
		||||
  gboolean enabled;
 | 
			
		||||
  MetaRectangle rect;
 | 
			
		||||
  float refresh_rate;
 | 
			
		||||
  MetaMonitorTransform transform;
 | 
			
		||||
  enum wl_output_transform transform;
 | 
			
		||||
 | 
			
		||||
  gboolean is_primary;
 | 
			
		||||
  gboolean is_presentation;
 | 
			
		||||
} MetaOutputConfig;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  guint refcount;
 | 
			
		||||
  MetaOutputKey *keys;
 | 
			
		||||
  MetaOutputConfig *outputs;
 | 
			
		||||
  unsigned int n_outputs;
 | 
			
		||||
@@ -79,7 +77,7 @@ struct _MetaMonitorConfig {
 | 
			
		||||
 | 
			
		||||
  GHashTable *configs;
 | 
			
		||||
  MetaConfiguration *current;
 | 
			
		||||
  gboolean current_is_for_laptop_lid;
 | 
			
		||||
  gboolean current_is_stored;
 | 
			
		||||
  MetaConfiguration *previous;
 | 
			
		||||
 | 
			
		||||
  GFile *file;
 | 
			
		||||
@@ -125,29 +123,11 @@ config_clear (MetaConfiguration *config)
 | 
			
		||||
  g_free (config->outputs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaConfiguration *
 | 
			
		||||
config_ref (MetaConfiguration *config)
 | 
			
		||||
{
 | 
			
		||||
  config->refcount++;
 | 
			
		||||
  return config;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
config_unref (MetaConfiguration *config)
 | 
			
		||||
config_free (gpointer config)
 | 
			
		||||
{
 | 
			
		||||
  if (--config->refcount == 0)
 | 
			
		||||
    {
 | 
			
		||||
      config_clear (config);
 | 
			
		||||
      g_slice_free (MetaConfiguration, config);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaConfiguration *
 | 
			
		||||
config_new (void)
 | 
			
		||||
{
 | 
			
		||||
  MetaConfiguration *config = g_slice_new0 (MetaConfiguration);
 | 
			
		||||
  config->refcount = 1;
 | 
			
		||||
  return config;
 | 
			
		||||
  config_clear (config);
 | 
			
		||||
  g_slice_free (MetaConfiguration, config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned long
 | 
			
		||||
@@ -239,7 +219,7 @@ meta_monitor_config_init (MetaMonitorConfig *self)
 | 
			
		||||
  const char *filename;
 | 
			
		||||
  char *path;
 | 
			
		||||
 | 
			
		||||
  self->configs = g_hash_table_new_full (config_hash, config_equal, NULL, (GDestroyNotify) config_unref);
 | 
			
		||||
  self->configs = g_hash_table_new_full (config_hash, config_equal, NULL, config_free);
 | 
			
		||||
 | 
			
		||||
  filename = g_getenv ("MUTTER_MONITOR_FILENAME");
 | 
			
		||||
  if (filename == NULL)
 | 
			
		||||
@@ -590,7 +570,7 @@ is_all_whitespace (const char *text,
 | 
			
		||||
                   gsize       text_len)
 | 
			
		||||
{
 | 
			
		||||
  gsize i;
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  for (i = 0; i < text_len; i++)
 | 
			
		||||
    if (!g_ascii_isspace (text[i]))
 | 
			
		||||
      return FALSE;
 | 
			
		||||
@@ -675,20 +655,20 @@ handle_text (GMarkupParseContext *context,
 | 
			
		||||
        else if (strcmp (parser->output_field, "rotation") == 0)
 | 
			
		||||
          {
 | 
			
		||||
            if (strncmp (text, "normal", text_len) == 0)
 | 
			
		||||
              parser->output.transform = META_MONITOR_TRANSFORM_NORMAL;
 | 
			
		||||
              parser->output.transform = WL_OUTPUT_TRANSFORM_NORMAL;
 | 
			
		||||
            else if (strncmp (text, "left", text_len) == 0)
 | 
			
		||||
              parser->output.transform = META_MONITOR_TRANSFORM_90;
 | 
			
		||||
              parser->output.transform = WL_OUTPUT_TRANSFORM_90;
 | 
			
		||||
            else if (strncmp (text, "upside_down", text_len) == 0)
 | 
			
		||||
              parser->output.transform = META_MONITOR_TRANSFORM_180;
 | 
			
		||||
              parser->output.transform = WL_OUTPUT_TRANSFORM_180;
 | 
			
		||||
            else if (strncmp (text, "right", text_len) == 0)
 | 
			
		||||
              parser->output.transform = META_MONITOR_TRANSFORM_270;
 | 
			
		||||
              parser->output.transform = WL_OUTPUT_TRANSFORM_270;
 | 
			
		||||
            else
 | 
			
		||||
              g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
 | 
			
		||||
                           "Invalid rotation type %.*s", (int)text_len, text);
 | 
			
		||||
          }
 | 
			
		||||
        else if (strcmp (parser->output_field, "reflect_x") == 0)
 | 
			
		||||
          parser->output.transform += read_bool (text, text_len, error) ?
 | 
			
		||||
            META_MONITOR_TRANSFORM_FLIPPED : 0;
 | 
			
		||||
            WL_OUTPUT_TRANSFORM_FLIPPED : 0;
 | 
			
		||||
        else if (strcmp (parser->output_field, "reflect_y") == 0)
 | 
			
		||||
          {
 | 
			
		||||
            /* FIXME (look at the rotation map in monitor.c) */
 | 
			
		||||
@@ -815,6 +795,27 @@ make_config_key (MetaConfiguration *key,
 | 
			
		||||
  key->n_outputs = o;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_monitor_config_match_current (MetaMonitorConfig  *self,
 | 
			
		||||
                                   MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  MetaOutput *outputs;
 | 
			
		||||
  unsigned n_outputs;
 | 
			
		||||
  MetaConfiguration key;
 | 
			
		||||
  gboolean ok;
 | 
			
		||||
 | 
			
		||||
  if (self->current == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
 | 
			
		||||
 | 
			
		||||
  make_config_key (&key, outputs, n_outputs, -1);
 | 
			
		||||
  ok = config_equal (&key, self->current);
 | 
			
		||||
 | 
			
		||||
  config_clear (&key);
 | 
			
		||||
  return ok;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
@@ -839,9 +840,6 @@ meta_monitor_config_get_stored (MetaMonitorConfig *self,
 | 
			
		||||
  MetaConfiguration key;
 | 
			
		||||
  MetaConfiguration *stored;
 | 
			
		||||
 | 
			
		||||
  if (n_outputs == 0)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  make_config_key (&key, outputs, n_outputs, -1);
 | 
			
		||||
  stored = g_hash_table_lookup (self->configs, &key);
 | 
			
		||||
 | 
			
		||||
@@ -849,45 +847,56 @@ meta_monitor_config_get_stored (MetaMonitorConfig *self,
 | 
			
		||||
  return stored;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_current (MetaMonitorConfig *self,
 | 
			
		||||
             MetaConfiguration *config)
 | 
			
		||||
{
 | 
			
		||||
  g_clear_pointer (&self->previous, (GDestroyNotify) config_unref);
 | 
			
		||||
  self->previous = self->current;
 | 
			
		||||
  self->current = config_ref (config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
apply_configuration (MetaMonitorConfig  *self,
 | 
			
		||||
                     MetaConfiguration  *config,
 | 
			
		||||
		     MetaMonitorManager *manager)
 | 
			
		||||
		     MetaMonitorManager *manager,
 | 
			
		||||
                     gboolean            stored)
 | 
			
		||||
{
 | 
			
		||||
  GPtrArray *crtcs, *outputs;
 | 
			
		||||
  gboolean ret = FALSE;
 | 
			
		||||
 | 
			
		||||
  crtcs = g_ptr_array_new_full (config->n_outputs, (GDestroyNotify)meta_crtc_info_free);
 | 
			
		||||
  outputs = g_ptr_array_new_full (config->n_outputs, (GDestroyNotify)meta_output_info_free);
 | 
			
		||||
 | 
			
		||||
  if (!meta_monitor_config_assign_crtcs (config, manager, crtcs, outputs))
 | 
			
		||||
    goto out;
 | 
			
		||||
    {
 | 
			
		||||
      g_ptr_array_unref (crtcs);
 | 
			
		||||
      g_ptr_array_unref (outputs);
 | 
			
		||||
      if (!stored)
 | 
			
		||||
        config_free (config);
 | 
			
		||||
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_monitor_manager_apply_configuration (manager,
 | 
			
		||||
                                            (MetaCRTCInfo**)crtcs->pdata, crtcs->len,
 | 
			
		||||
                                            (MetaOutputInfo**)outputs->pdata, outputs->len);
 | 
			
		||||
 | 
			
		||||
  set_current (self, config);
 | 
			
		||||
  /* Stored (persistent) configurations override the previous one always.
 | 
			
		||||
     Also, we clear the previous configuration if the current one (which is
 | 
			
		||||
     about to become previous) is stored.
 | 
			
		||||
  */
 | 
			
		||||
  if (stored ||
 | 
			
		||||
      (self->current && self->current_is_stored))
 | 
			
		||||
    {
 | 
			
		||||
      if (self->previous)
 | 
			
		||||
        config_free (self->previous);
 | 
			
		||||
      self->previous = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      self->previous = self->current;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* If true, we'll be overridden at the end of this call
 | 
			
		||||
   * inside turn_off_laptop_display / apply_configuration_with_lid */
 | 
			
		||||
  self->current_is_for_laptop_lid = FALSE;
 | 
			
		||||
  self->current = config;
 | 
			
		||||
  self->current_is_stored = stored;
 | 
			
		||||
 | 
			
		||||
  ret = TRUE;
 | 
			
		||||
  if (self->current == self->previous)
 | 
			
		||||
    self->previous = NULL;
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  g_ptr_array_unref (crtcs);
 | 
			
		||||
  g_ptr_array_unref (outputs);
 | 
			
		||||
  return ret;
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
@@ -898,20 +907,6 @@ key_is_laptop (MetaOutputKey *key)
 | 
			
		||||
    g_str_has_prefix (key->connector, "eDP");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
output_is_laptop (MetaOutput *output)
 | 
			
		||||
{
 | 
			
		||||
  /* FIXME: extend with better heuristics */
 | 
			
		||||
  switch (output->connector_type)
 | 
			
		||||
    {
 | 
			
		||||
    case META_CONNECTOR_TYPE_eDP:
 | 
			
		||||
    case META_CONNECTOR_TYPE_LVDS:
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    default:
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
laptop_display_is_on (MetaConfiguration *config)
 | 
			
		||||
{
 | 
			
		||||
@@ -929,19 +924,6 @@ laptop_display_is_on (MetaConfiguration *config)
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
multiple_outputs_are_enabled (MetaConfiguration *config)
 | 
			
		||||
{
 | 
			
		||||
  unsigned int i, enabled;
 | 
			
		||||
 | 
			
		||||
  enabled = 0;
 | 
			
		||||
  for (i = 0; i < config->n_outputs; i++)
 | 
			
		||||
    if (config->outputs[i].enabled)
 | 
			
		||||
      enabled++;
 | 
			
		||||
 | 
			
		||||
  return enabled > 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaConfiguration *
 | 
			
		||||
make_laptop_lid_config (MetaConfiguration  *reference)
 | 
			
		||||
{
 | 
			
		||||
@@ -951,9 +933,9 @@ make_laptop_lid_config (MetaConfiguration  *reference)
 | 
			
		||||
  int x_after, y_after;
 | 
			
		||||
  int x_offset, y_offset;
 | 
			
		||||
 | 
			
		||||
  g_assert (multiple_outputs_are_enabled (reference));
 | 
			
		||||
  g_assert (reference->n_outputs > 1);
 | 
			
		||||
 | 
			
		||||
  new = config_new ();
 | 
			
		||||
  new = g_slice_new0 (MetaConfiguration);
 | 
			
		||||
  new->n_outputs = reference->n_outputs;
 | 
			
		||||
  new->keys = g_new0 (MetaOutputKey, reference->n_outputs);
 | 
			
		||||
  new->outputs = g_new0 (MetaOutputConfig, reference->n_outputs);
 | 
			
		||||
@@ -970,7 +952,8 @@ make_laptop_lid_config (MetaConfiguration  *reference)
 | 
			
		||||
      new->keys[i].product = g_strdup (current_key->product);
 | 
			
		||||
      new->keys[i].serial = g_strdup (current_key->serial);
 | 
			
		||||
 | 
			
		||||
      if (key_is_laptop (current_key))
 | 
			
		||||
      if (g_str_has_prefix (current_key->connector, "LVDS") ||
 | 
			
		||||
          g_str_has_prefix (current_key->connector, "eDP"))
 | 
			
		||||
        {
 | 
			
		||||
          new->outputs[i].enabled = FALSE;
 | 
			
		||||
          x_after = current_output->rect.x;
 | 
			
		||||
@@ -1007,32 +990,6 @@ make_laptop_lid_config (MetaConfiguration  *reference)
 | 
			
		||||
  return new;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
apply_configuration_with_lid (MetaMonitorConfig  *self,
 | 
			
		||||
                              MetaConfiguration  *config,
 | 
			
		||||
                              MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  if (self->lid_is_closed &&
 | 
			
		||||
      multiple_outputs_are_enabled (config) &&
 | 
			
		||||
      laptop_display_is_on (config))
 | 
			
		||||
    {
 | 
			
		||||
      MetaConfiguration *laptop_lid_config = make_laptop_lid_config (config);
 | 
			
		||||
      if (apply_configuration (self, laptop_lid_config, manager))
 | 
			
		||||
        {
 | 
			
		||||
          self->current_is_for_laptop_lid = TRUE;
 | 
			
		||||
          config_unref (laptop_lid_config);
 | 
			
		||||
          return TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          config_unref (laptop_lid_config);
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    return apply_configuration (self, config, manager);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_monitor_config_apply_stored (MetaMonitorConfig  *self,
 | 
			
		||||
				  MetaMonitorManager *manager)
 | 
			
		||||
@@ -1045,7 +1002,15 @@ meta_monitor_config_apply_stored (MetaMonitorConfig  *self,
 | 
			
		||||
  stored = meta_monitor_config_get_stored (self, outputs, n_outputs);
 | 
			
		||||
 | 
			
		||||
  if (stored)
 | 
			
		||||
    return apply_configuration_with_lid (self, stored, manager);
 | 
			
		||||
    {
 | 
			
		||||
      if (self->lid_is_closed &&
 | 
			
		||||
          stored->n_outputs > 1 &&
 | 
			
		||||
          laptop_display_is_on (stored))
 | 
			
		||||
        return apply_configuration (self, make_laptop_lid_config (stored),
 | 
			
		||||
                                    manager, FALSE);
 | 
			
		||||
      else
 | 
			
		||||
        return apply_configuration (self, stored, manager, TRUE);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
@@ -1074,7 +1039,8 @@ find_primary_output (MetaOutput *outputs,
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (output_is_laptop (&outputs[i]))
 | 
			
		||||
      if (g_str_has_prefix (outputs[i].name, "LVDS") ||
 | 
			
		||||
          g_str_has_prefix (outputs[i].name, "eDP"))
 | 
			
		||||
        return &outputs[i];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1094,123 +1060,47 @@ find_primary_output (MetaOutput *outputs,
 | 
			
		||||
  return best;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
init_config_from_preferred_mode (MetaOutputConfig *config,
 | 
			
		||||
                                 MetaOutput *output)
 | 
			
		||||
static MetaConfiguration *
 | 
			
		||||
make_default_config (MetaMonitorConfig *self,
 | 
			
		||||
                     MetaOutput        *outputs,
 | 
			
		||||
                     unsigned           n_outputs,
 | 
			
		||||
                     int                max_width,
 | 
			
		||||
                     int                max_height)
 | 
			
		||||
{
 | 
			
		||||
  config->enabled = TRUE;
 | 
			
		||||
  config->rect.x = 0;
 | 
			
		||||
  config->rect.y = 0;
 | 
			
		||||
  config->rect.width = output->preferred_mode->width;
 | 
			
		||||
  config->rect.height = output->preferred_mode->height;
 | 
			
		||||
  config->refresh_rate = output->preferred_mode->refresh_rate;
 | 
			
		||||
  config->transform = META_MONITOR_TRANSFORM_NORMAL;
 | 
			
		||||
  config->is_primary = FALSE;
 | 
			
		||||
  config->is_presentation = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function handles configuring the outputs when the driver provides a
 | 
			
		||||
 * suggested layout position for each output. This is done in recent versions
 | 
			
		||||
 * of qxl and allows displays to be aligned on the guest in the same order as
 | 
			
		||||
 * they are aligned on the client.
 | 
			
		||||
 */
 | 
			
		||||
static gboolean
 | 
			
		||||
make_suggested_config (MetaMonitorConfig *self,
 | 
			
		||||
                       MetaOutput        *outputs,
 | 
			
		||||
                       unsigned           n_outputs,
 | 
			
		||||
                       int                max_width,
 | 
			
		||||
                       int                max_height,
 | 
			
		||||
                       MetaConfiguration *config)
 | 
			
		||||
{
 | 
			
		||||
  unsigned int i;
 | 
			
		||||
  MetaOutput *primary;
 | 
			
		||||
  GList *region = NULL;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (config != NULL, FALSE);
 | 
			
		||||
  primary = find_primary_output (outputs, n_outputs);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      gboolean is_primary = (&outputs[i] == primary);
 | 
			
		||||
 | 
			
		||||
      if (outputs[i].suggested_x < 0 || outputs[i].suggested_y < 0)
 | 
			
		||||
          return FALSE;
 | 
			
		||||
 | 
			
		||||
      init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
 | 
			
		||||
      config->outputs[i].is_primary = is_primary;
 | 
			
		||||
 | 
			
		||||
      config->outputs[i].rect.x = outputs[i].suggested_x;
 | 
			
		||||
      config->outputs[i].rect.y = outputs[i].suggested_y;
 | 
			
		||||
 | 
			
		||||
      /* Reject the configuration if the suggested positions result in
 | 
			
		||||
       * overlapping displays */
 | 
			
		||||
      if (meta_rectangle_overlaps_with_region (region, &config->outputs[i].rect))
 | 
			
		||||
        {
 | 
			
		||||
          g_warning ("Overlapping outputs, rejecting suggested configuration");
 | 
			
		||||
          g_list_free (region);
 | 
			
		||||
          return FALSE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      region = g_list_prepend (region, &config->outputs[i].rect);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_list_free (region);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
make_linear_config (MetaMonitorConfig *self,
 | 
			
		||||
                    MetaOutput        *outputs,
 | 
			
		||||
                    unsigned           n_outputs,
 | 
			
		||||
                    int                max_width,
 | 
			
		||||
                    int                max_height,
 | 
			
		||||
                    MetaConfiguration *config)
 | 
			
		||||
{
 | 
			
		||||
  MetaOutput *primary;
 | 
			
		||||
  unsigned i;
 | 
			
		||||
  int x;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (config != NULL);
 | 
			
		||||
 | 
			
		||||
  primary = find_primary_output (outputs, n_outputs);
 | 
			
		||||
 | 
			
		||||
  x = primary->preferred_mode->width;
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      gboolean is_primary = (&outputs[i] == primary);
 | 
			
		||||
 | 
			
		||||
      init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
 | 
			
		||||
      config->outputs[i].is_primary = is_primary;
 | 
			
		||||
 | 
			
		||||
      if (is_primary)
 | 
			
		||||
        {
 | 
			
		||||
          config->outputs[i].rect.x = 0;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          config->outputs[i].rect.x = x;
 | 
			
		||||
          x += config->outputs[i].rect.width;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Search for a configuration that includes one less screen, then add the new
 | 
			
		||||
 * one as a presentation screen in preferred mode.
 | 
			
		||||
 *
 | 
			
		||||
 * XXX: but presentation mode is not implemented in the control-center or in
 | 
			
		||||
 * mutter core, so let's do extended for now.
 | 
			
		||||
  */
 | 
			
		||||
static gboolean
 | 
			
		||||
extend_stored_config (MetaMonitorConfig *self,
 | 
			
		||||
                      MetaOutput        *outputs,
 | 
			
		||||
                      unsigned           n_outputs,
 | 
			
		||||
                      int                max_width,
 | 
			
		||||
                      int                max_height,
 | 
			
		||||
                      MetaConfiguration *config)
 | 
			
		||||
{
 | 
			
		||||
  int x, y;
 | 
			
		||||
  unsigned i, j;
 | 
			
		||||
  int x, y;
 | 
			
		||||
  MetaConfiguration *ret;
 | 
			
		||||
  MetaOutput *primary;
 | 
			
		||||
 | 
			
		||||
  ret = g_slice_new (MetaConfiguration);
 | 
			
		||||
  make_config_key (ret, outputs, n_outputs, -1);
 | 
			
		||||
  ret->outputs = g_new0 (MetaOutputConfig, n_outputs);
 | 
			
		||||
 | 
			
		||||
  /* Special case the simple case: one output, primary at preferred mode,
 | 
			
		||||
     nothing else to do */
 | 
			
		||||
  if (n_outputs == 1)
 | 
			
		||||
    {
 | 
			
		||||
      ret->outputs[0].enabled = TRUE;
 | 
			
		||||
      ret->outputs[0].rect.x = 0;
 | 
			
		||||
      ret->outputs[0].rect.y = 0;
 | 
			
		||||
      ret->outputs[0].rect.width = outputs[0].preferred_mode->width;
 | 
			
		||||
      ret->outputs[0].rect.height = outputs[0].preferred_mode->height;
 | 
			
		||||
      ret->outputs[0].refresh_rate = outputs[0].preferred_mode->refresh_rate;
 | 
			
		||||
      ret->outputs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL;
 | 
			
		||||
      ret->outputs[0].is_primary = TRUE;
 | 
			
		||||
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* If we reach this point, this is either the first time mutter runs
 | 
			
		||||
     on this system ever, or we just hotplugged a new screen.
 | 
			
		||||
     In the latter case, search for a configuration that includes one
 | 
			
		||||
     less screen, then add the new one as a presentation screen
 | 
			
		||||
     in preferred mode.
 | 
			
		||||
 | 
			
		||||
     XXX: but presentation mode is not implemented in the control-center
 | 
			
		||||
     or in mutter core, so let's do extended for now.
 | 
			
		||||
  */
 | 
			
		||||
  x = 0;
 | 
			
		||||
  y = 0;
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
@@ -1228,80 +1118,69 @@ extend_stored_config (MetaMonitorConfig *self,
 | 
			
		||||
            {
 | 
			
		||||
              if (j < i)
 | 
			
		||||
                {
 | 
			
		||||
                  g_assert (output_key_equal (&config->keys[j], &ref->keys[j]));
 | 
			
		||||
                  config->outputs[j] = ref->outputs[j];
 | 
			
		||||
                  g_assert (output_key_equal (&ret->keys[j], &ref->keys[j]));
 | 
			
		||||
                  ret->outputs[j] = ref->outputs[j];
 | 
			
		||||
                  x = MAX (x, ref->outputs[j].rect.x + ref->outputs[j].rect.width);
 | 
			
		||||
                  y = MAX (y, ref->outputs[j].rect.y + ref->outputs[j].rect.height);
 | 
			
		||||
                }
 | 
			
		||||
              else if (j > i)
 | 
			
		||||
                {
 | 
			
		||||
                  g_assert (output_key_equal (&config->keys[j], &ref->keys[j - 1]));
 | 
			
		||||
                  config->outputs[j] = ref->outputs[j - 1];
 | 
			
		||||
                  g_assert (output_key_equal (&ret->keys[j], &ref->keys[j - 1]));
 | 
			
		||||
                  ret->outputs[j] = ref->outputs[j - 1];
 | 
			
		||||
                  x = MAX (x, ref->outputs[j - 1].rect.x + ref->outputs[j - 1].rect.width);
 | 
			
		||||
                  y = MAX (y, ref->outputs[j - 1].rect.y + ref->outputs[j - 1].rect.height);
 | 
			
		||||
                }
 | 
			
		||||
              else
 | 
			
		||||
                {
 | 
			
		||||
                  init_config_from_preferred_mode (&config->outputs[j], &outputs[0]);
 | 
			
		||||
                  ret->outputs[j].enabled = TRUE;
 | 
			
		||||
                  ret->outputs[j].rect.x = 0;
 | 
			
		||||
                  ret->outputs[j].rect.y = 0;
 | 
			
		||||
                  ret->outputs[j].rect.width = outputs[0].preferred_mode->width;
 | 
			
		||||
                  ret->outputs[j].rect.height = outputs[0].preferred_mode->height;
 | 
			
		||||
                  ret->outputs[j].refresh_rate = outputs[0].preferred_mode->refresh_rate;
 | 
			
		||||
                  ret->outputs[j].transform = WL_OUTPUT_TRANSFORM_NORMAL;
 | 
			
		||||
                  ret->outputs[j].is_primary = FALSE;
 | 
			
		||||
                  ret->outputs[j].is_presentation = FALSE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          /* Place the new output at the right end of the screen, if it fits,
 | 
			
		||||
             otherwise below it, otherwise disable it (or apply_configuration will fail) */
 | 
			
		||||
          if (x + config->outputs[i].rect.width <= max_width)
 | 
			
		||||
            config->outputs[i].rect.x = x;
 | 
			
		||||
          else if (y + config->outputs[i].rect.height <= max_height)
 | 
			
		||||
            config->outputs[i].rect.y = y;
 | 
			
		||||
          if (x + ret->outputs[i].rect.width <= max_width)
 | 
			
		||||
            ret->outputs[i].rect.x = x;
 | 
			
		||||
          else if (y + ret->outputs[i].rect.height <= max_height)
 | 
			
		||||
            ret->outputs[i].rect.y = y;
 | 
			
		||||
          else
 | 
			
		||||
            config->outputs[i].enabled = FALSE;
 | 
			
		||||
            ret->outputs[i].enabled = FALSE;
 | 
			
		||||
 | 
			
		||||
          return TRUE;
 | 
			
		||||
          return ret;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
  /* No previous configuration found, try with a really default one, which
 | 
			
		||||
     is one primary that goes first and the rest to the right of it, extended.
 | 
			
		||||
  */
 | 
			
		||||
  primary = find_primary_output (outputs, n_outputs);
 | 
			
		||||
 | 
			
		||||
static MetaConfiguration *
 | 
			
		||||
make_default_config (MetaMonitorConfig *self,
 | 
			
		||||
                     MetaOutput        *outputs,
 | 
			
		||||
                     unsigned           n_outputs,
 | 
			
		||||
                     int                max_width,
 | 
			
		||||
                     int                max_height,
 | 
			
		||||
                     gboolean           use_stored_config)
 | 
			
		||||
{
 | 
			
		||||
  MetaConfiguration *ret = NULL;
 | 
			
		||||
  unsigned i;
 | 
			
		||||
 | 
			
		||||
  ret = config_new ();
 | 
			
		||||
  make_config_key (ret, outputs, n_outputs, -1);
 | 
			
		||||
  ret->outputs = g_new0 (MetaOutputConfig, n_outputs);
 | 
			
		||||
 | 
			
		||||
  /* Special case the simple case: one output, primary at preferred mode,
 | 
			
		||||
     nothing else to do */
 | 
			
		||||
  if (n_outputs == 1)
 | 
			
		||||
    {
 | 
			
		||||
      init_config_from_preferred_mode (&ret->outputs[0], &outputs[0]);
 | 
			
		||||
      ret->outputs[0].is_primary = TRUE;
 | 
			
		||||
      goto check_limits;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (make_suggested_config (self, outputs, n_outputs, max_width, max_height, ret))
 | 
			
		||||
      goto check_limits;
 | 
			
		||||
 | 
			
		||||
  if (use_stored_config &&
 | 
			
		||||
      extend_stored_config (self, outputs, n_outputs, max_width, max_height, ret))
 | 
			
		||||
      goto check_limits;
 | 
			
		||||
 | 
			
		||||
  make_linear_config (self, outputs, n_outputs, max_width, max_height, ret);
 | 
			
		||||
 | 
			
		||||
check_limits:
 | 
			
		||||
  /* Disable outputs that would go beyond framebuffer limits */
 | 
			
		||||
  x = primary->preferred_mode->width;
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
        if ((ret->outputs[i].rect.x + ret->outputs[i].rect.width > max_width)
 | 
			
		||||
            || (ret->outputs[i].rect.y + ret->outputs[i].rect.height > max_height))
 | 
			
		||||
          ret->outputs[i].enabled = FALSE;
 | 
			
		||||
      MetaOutput *output = &outputs[i];
 | 
			
		||||
 | 
			
		||||
      ret->outputs[i].enabled = TRUE;
 | 
			
		||||
      ret->outputs[i].rect.x = (output == primary) ? 0 : x;
 | 
			
		||||
      ret->outputs[i].rect.y = 0;
 | 
			
		||||
      ret->outputs[i].rect.width = output->preferred_mode->width;
 | 
			
		||||
      ret->outputs[i].rect.height = output->preferred_mode->height;
 | 
			
		||||
      ret->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
 | 
			
		||||
      ret->outputs[i].transform = WL_OUTPUT_TRANSFORM_NORMAL;
 | 
			
		||||
      ret->outputs[i].is_primary = (output == primary);
 | 
			
		||||
 | 
			
		||||
      /* Disable outputs that would go beyond framebuffer limits */
 | 
			
		||||
      if (ret->outputs[i].rect.x + ret->outputs[i].rect.width > max_width)
 | 
			
		||||
        ret->outputs[i].enabled = FALSE;
 | 
			
		||||
      else if (output != primary)
 | 
			
		||||
        x += output->preferred_mode->width;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
@@ -1313,7 +1192,7 @@ ensure_at_least_one_output (MetaMonitorConfig  *self,
 | 
			
		||||
                            MetaOutput         *outputs,
 | 
			
		||||
                            unsigned            n_outputs)
 | 
			
		||||
{
 | 
			
		||||
  MetaConfiguration *config;
 | 
			
		||||
  MetaConfiguration *ret;
 | 
			
		||||
  MetaOutput *primary;
 | 
			
		||||
  unsigned i;
 | 
			
		||||
 | 
			
		||||
@@ -1324,29 +1203,34 @@ ensure_at_least_one_output (MetaMonitorConfig  *self,
 | 
			
		||||
 | 
			
		||||
  /* Oh no, we don't! Activate the primary one and disable everything else */
 | 
			
		||||
 | 
			
		||||
  config = config_new ();
 | 
			
		||||
  make_config_key (config, outputs, n_outputs, -1);
 | 
			
		||||
  config->outputs = g_new0 (MetaOutputConfig, n_outputs);
 | 
			
		||||
  ret = g_slice_new (MetaConfiguration);
 | 
			
		||||
  make_config_key (ret, outputs, n_outputs, -1);
 | 
			
		||||
  ret->outputs = g_new0 (MetaOutputConfig, n_outputs);
 | 
			
		||||
 | 
			
		||||
  primary = find_primary_output (outputs, n_outputs);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      gboolean is_primary = (&outputs[i] == primary);
 | 
			
		||||
      MetaOutput *output = &outputs[i];
 | 
			
		||||
 | 
			
		||||
      if (is_primary)
 | 
			
		||||
      if (output == primary)
 | 
			
		||||
        {
 | 
			
		||||
          init_config_from_preferred_mode (&config->outputs[i], &outputs[0]);
 | 
			
		||||
          config->outputs[i].is_primary = TRUE;
 | 
			
		||||
          ret->outputs[i].enabled = TRUE;
 | 
			
		||||
          ret->outputs[i].rect.x = 0;
 | 
			
		||||
          ret->outputs[i].rect.y = 0;
 | 
			
		||||
          ret->outputs[i].rect.width = output->preferred_mode->width;
 | 
			
		||||
          ret->outputs[i].rect.height = output->preferred_mode->height;
 | 
			
		||||
          ret->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
 | 
			
		||||
          ret->outputs[i].transform = WL_OUTPUT_TRANSFORM_NORMAL;
 | 
			
		||||
          ret->outputs[i].is_primary = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          config->outputs[i].enabled = FALSE;
 | 
			
		||||
          ret->outputs[i].enabled = FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  apply_configuration (self, config, manager);
 | 
			
		||||
  config_unref (config);
 | 
			
		||||
  apply_configuration (self, ret, manager, FALSE);
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1357,34 +1241,29 @@ meta_monitor_config_make_default (MetaMonitorConfig  *self,
 | 
			
		||||
  MetaOutput *outputs;
 | 
			
		||||
  MetaConfiguration *default_config;
 | 
			
		||||
  unsigned n_outputs;
 | 
			
		||||
  gboolean ok = FALSE;
 | 
			
		||||
  gboolean ok;
 | 
			
		||||
  int max_width, max_height;
 | 
			
		||||
  gboolean use_stored_config;
 | 
			
		||||
 | 
			
		||||
  outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
 | 
			
		||||
  meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height);
 | 
			
		||||
 | 
			
		||||
  if (n_outputs == 0)
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("No output connected, not applying configuration\n");
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* if the device has hotplug_mode_update, it's possible that the
 | 
			
		||||
   * current display configuration does not match a stored configuration.
 | 
			
		||||
   * Since extend_existing_config() tries to build a configuration that is
 | 
			
		||||
   * based on a previously-stored configuration, it's quite likely that the
 | 
			
		||||
   * resulting config will fail. Even if it doesn't fail, it may result in
 | 
			
		||||
   * an unexpected configuration, so don't attempt to use a stored config
 | 
			
		||||
   * in this situation. */
 | 
			
		||||
  use_stored_config = !meta_monitor_manager_has_hotplug_mode_update (manager);
 | 
			
		||||
  default_config = make_default_config (self, outputs, n_outputs, max_width, max_height, use_stored_config);
 | 
			
		||||
  default_config = make_default_config (self, outputs, n_outputs, max_width, max_height);
 | 
			
		||||
 | 
			
		||||
  if (default_config != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      ok = apply_configuration_with_lid (self, default_config, manager);
 | 
			
		||||
      config_unref (default_config);
 | 
			
		||||
      if (self->lid_is_closed &&
 | 
			
		||||
          default_config->n_outputs > 1 &&
 | 
			
		||||
          laptop_display_is_on (default_config))
 | 
			
		||||
        {
 | 
			
		||||
          ok = apply_configuration (self, make_laptop_lid_config (default_config),
 | 
			
		||||
                                    manager, FALSE);
 | 
			
		||||
          config_free (default_config);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        ok = apply_configuration (self, default_config, manager, FALSE);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    ok = FALSE;
 | 
			
		||||
 | 
			
		||||
  if (!ok)
 | 
			
		||||
    {
 | 
			
		||||
@@ -1421,7 +1300,7 @@ meta_monitor_config_update_current (MetaMonitorConfig  *self,
 | 
			
		||||
 | 
			
		||||
  outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
 | 
			
		||||
 | 
			
		||||
  current = config_new ();
 | 
			
		||||
  current = g_slice_new (MetaConfiguration);
 | 
			
		||||
  current->n_outputs = n_outputs;
 | 
			
		||||
  current->outputs = g_new0 (MetaOutputConfig, n_outputs);
 | 
			
		||||
  current->keys = g_new0 (MetaOutputKey, n_outputs);
 | 
			
		||||
@@ -1434,11 +1313,15 @@ meta_monitor_config_update_current (MetaMonitorConfig  *self,
 | 
			
		||||
 | 
			
		||||
  if (self->current && config_equal_full (current, self->current))
 | 
			
		||||
    {
 | 
			
		||||
      config_unref (current);
 | 
			
		||||
      config_free (current);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  set_current (self, current);
 | 
			
		||||
  if (self->current && !self->current_is_stored)
 | 
			
		||||
    config_free (self->current);
 | 
			
		||||
 | 
			
		||||
  self->current = current;
 | 
			
		||||
  self->current_is_stored = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -1446,17 +1329,7 @@ meta_monitor_config_restore_previous (MetaMonitorConfig  *self,
 | 
			
		||||
                                      MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  if (self->previous)
 | 
			
		||||
    {
 | 
			
		||||
      /* The user chose to restore the previous configuration. In this
 | 
			
		||||
       * case, restore the previous configuration. */
 | 
			
		||||
      MetaConfiguration *prev_config = config_ref (self->previous);
 | 
			
		||||
      apply_configuration (self, prev_config, manager);
 | 
			
		||||
      config_unref (prev_config);
 | 
			
		||||
 | 
			
		||||
      /* After this, self->previous contains the rejected configuration.
 | 
			
		||||
       * Since it was rejected, nuke it. */
 | 
			
		||||
      g_clear_pointer (&self->previous, (GDestroyNotify) config_unref);
 | 
			
		||||
    }
 | 
			
		||||
    apply_configuration (self, self->previous, manager, FALSE);
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if (!meta_monitor_config_apply_stored (self, manager))
 | 
			
		||||
@@ -1470,13 +1343,11 @@ turn_off_laptop_display (MetaMonitorConfig  *self,
 | 
			
		||||
{
 | 
			
		||||
  MetaConfiguration *new;
 | 
			
		||||
 | 
			
		||||
  if (!multiple_outputs_are_enabled (self->current))
 | 
			
		||||
  if (self->current->n_outputs == 1)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  new = make_laptop_lid_config (self->current);
 | 
			
		||||
  apply_configuration (self, new, manager);
 | 
			
		||||
  config_unref (new);
 | 
			
		||||
  self->current_is_for_laptop_lid = TRUE;
 | 
			
		||||
  apply_configuration (self, new, manager, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -1496,7 +1367,7 @@ power_client_changed_cb (UpClient   *client,
 | 
			
		||||
 | 
			
		||||
      if (is_closed)
 | 
			
		||||
        turn_off_laptop_display (self, manager);
 | 
			
		||||
      else if (self->current_is_for_laptop_lid)
 | 
			
		||||
      else
 | 
			
		||||
        meta_monitor_config_restore_previous (self, manager);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1605,7 +1476,7 @@ meta_monitor_config_save (MetaMonitorConfig *self)
 | 
			
		||||
                                      output->rect.x,
 | 
			
		||||
                                      output->rect.y,
 | 
			
		||||
                                      rotation_map[output->transform & 0x3],
 | 
			
		||||
                                      output->transform >= META_MONITOR_TRANSFORM_FLIPPED ? "yes" : "no",
 | 
			
		||||
                                      output->transform >= WL_OUTPUT_TRANSFORM_FLIPPED ? "yes" : "no",
 | 
			
		||||
                                      output->is_primary ? "yes" : "no",
 | 
			
		||||
                                      output->is_presentation ? "yes" : "no");
 | 
			
		||||
            }
 | 
			
		||||
@@ -1634,7 +1505,16 @@ meta_monitor_config_save (MetaMonitorConfig *self)
 | 
			
		||||
void
 | 
			
		||||
meta_monitor_config_make_persistent (MetaMonitorConfig *self)
 | 
			
		||||
{
 | 
			
		||||
  g_hash_table_replace (self->configs, self->current, config_ref (self->current));
 | 
			
		||||
  if (self->current_is_stored)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  self->current_is_stored = TRUE;
 | 
			
		||||
  g_hash_table_replace (self->configs, self->current, self->current);
 | 
			
		||||
 | 
			
		||||
  if (self->previous)
 | 
			
		||||
    config_free (self->previous);
 | 
			
		||||
  self->previous = NULL;
 | 
			
		||||
 | 
			
		||||
  meta_monitor_config_save (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1705,13 +1585,13 @@ output_supports_mode (MetaOutput      *output,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
crtc_assignment_assign (CrtcAssignment       *assign,
 | 
			
		||||
			MetaCRTC             *crtc,
 | 
			
		||||
			MetaMonitorMode      *mode,
 | 
			
		||||
			int                   x,
 | 
			
		||||
			int                   y,
 | 
			
		||||
			MetaMonitorTransform  transform,
 | 
			
		||||
			MetaOutput           *output)
 | 
			
		||||
crtc_assignment_assign (CrtcAssignment            *assign,
 | 
			
		||||
			MetaCRTC                  *crtc,
 | 
			
		||||
			MetaMonitorMode           *mode,
 | 
			
		||||
			int                        x,
 | 
			
		||||
			int                        y,
 | 
			
		||||
			enum wl_output_transform   transform,
 | 
			
		||||
			MetaOutput                *output)
 | 
			
		||||
{
 | 
			
		||||
  MetaCRTCInfo *info = g_hash_table_lookup (assign->info, crtc);
 | 
			
		||||
 | 
			
		||||
@@ -1873,6 +1753,7 @@ real_assign_crtcs (CrtcAssignment     *assignment,
 | 
			
		||||
                                output_config->transform,
 | 
			
		||||
                                pass);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                  if (crtc_assignment_assign (assignment, crtc, &modes[j],
 | 
			
		||||
                                              output_config->rect.x, output_config->rect.y,
 | 
			
		||||
                                              output_config->transform,
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
#ifndef META_MONITOR_CONFIG_H
 | 
			
		||||
#define META_MONITOR_CONFIG_H
 | 
			
		||||
 | 
			
		||||
#include "meta-monitor-manager-private.h"
 | 
			
		||||
#include "meta-monitor-manager.h"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_MONITOR_CONFIG            (meta_monitor_config_get_type ())
 | 
			
		||||
#define META_MONITOR_CONFIG(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfig))
 | 
			
		||||
@@ -36,6 +36,9 @@ GType meta_monitor_config_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
MetaMonitorConfig *meta_monitor_config_new (void);
 | 
			
		||||
 | 
			
		||||
gboolean           meta_monitor_config_match_current (MetaMonitorConfig  *config,
 | 
			
		||||
                                                      MetaMonitorManager *manager);
 | 
			
		||||
 | 
			
		||||
gboolean           meta_monitor_config_apply_stored (MetaMonitorConfig  *config,
 | 
			
		||||
                                                     MetaMonitorManager *manager);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@
 | 
			
		||||
 | 
			
		||||
#include "meta-monitor-manager-dummy.h"
 | 
			
		||||
 | 
			
		||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
 | 
			
		||||
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
 | 
			
		||||
 | 
			
		||||
struct _MetaMonitorManagerDummy
 | 
			
		||||
{
 | 
			
		||||
@@ -66,8 +66,8 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
 | 
			
		||||
  manager->crtcs[0].rect.width = manager->modes[0].width;
 | 
			
		||||
  manager->crtcs[0].rect.height = manager->modes[0].height;
 | 
			
		||||
  manager->crtcs[0].current_mode = &manager->modes[0];
 | 
			
		||||
  manager->crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
 | 
			
		||||
  manager->crtcs[0].all_transforms = ALL_TRANSFORMS;
 | 
			
		||||
  manager->crtcs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL;
 | 
			
		||||
  manager->crtcs[0].all_transforms = ALL_WL_TRANSFORMS;
 | 
			
		||||
  manager->crtcs[0].is_dirty = FALSE;
 | 
			
		||||
  manager->crtcs[0].logical_monitor = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -75,7 +75,7 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
 | 
			
		||||
  manager->n_outputs = 1;
 | 
			
		||||
 | 
			
		||||
  manager->outputs[0].crtc = &manager->crtcs[0];
 | 
			
		||||
  manager->outputs[0].winsys_id = 1;
 | 
			
		||||
  manager->outputs[0].output_id = 1;
 | 
			
		||||
  manager->outputs[0].name = g_strdup ("LVDS");
 | 
			
		||||
  manager->outputs[0].vendor = g_strdup ("MetaProducts Inc.");
 | 
			
		||||
  manager->outputs[0].product = g_strdup ("unknown");
 | 
			
		||||
@@ -95,8 +95,6 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
 | 
			
		||||
  manager->outputs[0].backlight = -1;
 | 
			
		||||
  manager->outputs[0].backlight_min = 0;
 | 
			
		||||
  manager->outputs[0].backlight_max = 0;
 | 
			
		||||
  manager->outputs[0].connector_type = META_CONNECTOR_TYPE_LVDS;
 | 
			
		||||
  manager->outputs[0].scale = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
#ifndef META_MONITOR_MANAGER_DUMMY_H
 | 
			
		||||
#define META_MONITOR_MANAGER_DUMMY_H
 | 
			
		||||
 | 
			
		||||
#include "meta-monitor-manager-private.h"
 | 
			
		||||
#include "meta-monitor-manager.h"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_MONITOR_MANAGER_DUMMY            (meta_monitor_manager_dummy_get_type ())
 | 
			
		||||
#define META_MONITOR_MANAGER_DUMMY(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummy))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2001, 2002 Havoc Pennington
 | 
			
		||||
 * Copyright (C) 2002, 2003 Red Hat Inc.
 | 
			
		||||
 * Some ICCCM manager selection code derived from fvwm2,
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * Copyright (C) 2003 Rob Adams
 | 
			
		||||
 * Copyright (C) 2004-2006 Elijah Newren
 | 
			
		||||
 * Copyright (C) 2013 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
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
@@ -18,14 +18,14 @@
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "meta-monitor-manager-private.h"
 | 
			
		||||
#include "meta-monitor-manager.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
@@ -35,26 +35,20 @@
 | 
			
		||||
#include <meta/main.h>
 | 
			
		||||
#include "util-private.h"
 | 
			
		||||
#include <meta/errors.h>
 | 
			
		||||
#include "edid.h"
 | 
			
		||||
#include "meta-monitor-config.h"
 | 
			
		||||
#include "backends/native/meta-monitor-manager-kms.h"
 | 
			
		||||
#include "backends/x11/meta-monitor-manager-xrandr.h"
 | 
			
		||||
#include "meta-backend-private.h"
 | 
			
		||||
#include "meta-monitor-manager-dummy.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  CONFIRM_DISPLAY_CHANGE,
 | 
			
		||||
  SIGNALS_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Array index matches MetaMonitorTransform */
 | 
			
		||||
static gfloat transform_matrices[][6] = {
 | 
			
		||||
  {  1,  0,  0,  0,  1,  0 }, /* normal */
 | 
			
		||||
  {  0, -1,  1,  1,  0,  0 }, /* 90° */
 | 
			
		||||
  { -1,  0,  1,  0, -1,  1 }, /* 180° */
 | 
			
		||||
  {  0,  1,  0, -1,  0,  1 }, /* 270° */
 | 
			
		||||
  { -1,  0,  1,  0,  1,  0 }, /* normal flipped */
 | 
			
		||||
  {  0,  1,  0,  1,  0,  0 }, /* 90° flipped */
 | 
			
		||||
  {  1,  0,  0,  0, -1,  1 }, /* 180° flipped */
 | 
			
		||||
  {  0, -1,  1, -1,  0,  1 }, /* 270° flipped */
 | 
			
		||||
enum {
 | 
			
		||||
  PROP_0,
 | 
			
		||||
  PROP_POWER_SAVE_MODE,
 | 
			
		||||
  PROP_LAST
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int signals[SIGNALS_LAST];
 | 
			
		||||
@@ -71,6 +65,14 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
read_current_config (MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  manager->serial++;
 | 
			
		||||
 | 
			
		||||
  META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * make_logical_config:
 | 
			
		||||
 *
 | 
			
		||||
@@ -124,7 +126,7 @@ make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
          */
 | 
			
		||||
          info.is_presentation = TRUE;
 | 
			
		||||
          info.in_fullscreen = -1;
 | 
			
		||||
          info.winsys_id = 0;
 | 
			
		||||
          info.output_id = 0;
 | 
			
		||||
 | 
			
		||||
          g_array_append_val (monitor_infos, info);
 | 
			
		||||
 | 
			
		||||
@@ -155,8 +157,8 @@ make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
      info->is_primary = info->is_primary || output->is_primary;
 | 
			
		||||
      info->is_presentation = info->is_presentation && output->is_presentation;
 | 
			
		||||
 | 
			
		||||
      if (output->is_primary || info->winsys_id == 0)
 | 
			
		||||
        info->winsys_id = output->winsys_id;
 | 
			
		||||
      if (output->is_primary || info->output_id == 0)
 | 
			
		||||
        info->output_id = output->output_id;
 | 
			
		||||
 | 
			
		||||
      if (info->is_primary)
 | 
			
		||||
        manager->primary_monitor_index = info->number;
 | 
			
		||||
@@ -166,29 +168,56 @@ make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
  manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
power_save_mode_changed (MetaMonitorManager *manager,
 | 
			
		||||
                         GParamSpec         *pspec,
 | 
			
		||||
                         gpointer            user_data)
 | 
			
		||||
static GType
 | 
			
		||||
get_default_backend (void)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManagerClass *klass;
 | 
			
		||||
  int mode = meta_dbus_display_config_get_power_save_mode (META_DBUS_DISPLAY_CONFIG (manager));
 | 
			
		||||
#if defined(CLUTTER_WINDOWING_EGL)
 | 
			
		||||
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
 | 
			
		||||
    return META_TYPE_MONITOR_MANAGER_KMS;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  if (mode == META_POWER_SAVE_UNSUPPORTED)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* If DPMS is unsupported, force the property back. */
 | 
			
		||||
  if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED)
 | 
			
		||||
#if defined(CLUTTER_WINDOWING_X11)
 | 
			
		||||
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
 | 
			
		||||
    {
 | 
			
		||||
      meta_dbus_display_config_set_power_save_mode (META_DBUS_DISPLAY_CONFIG (manager), META_POWER_SAVE_UNSUPPORTED);
 | 
			
		||||
      return;
 | 
			
		||||
      /* If we're a Wayland compositor using the X11 backend,
 | 
			
		||||
       * we're a nested configuration, so return the dummy
 | 
			
		||||
       * monitor setup. */
 | 
			
		||||
      if (meta_is_wayland_compositor ())
 | 
			
		||||
        return META_TYPE_MONITOR_MANAGER_DUMMY;
 | 
			
		||||
      else
 | 
			
		||||
        return META_TYPE_MONITOR_MANAGER_XRANDR;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  klass = META_MONITOR_MANAGER_GET_CLASS (manager);
 | 
			
		||||
  if (klass->set_power_save_mode)
 | 
			
		||||
    klass->set_power_save_mode (manager, mode);
 | 
			
		||||
#if defined(CLUTTER_WINDOWING_WAYLAND)
 | 
			
		||||
  if (clutter_check_windowing_backend (CLUTTER_WINDOWING_WAYLAND))
 | 
			
		||||
    {
 | 
			
		||||
      /* Use the dummy implementation on Wayland for now.
 | 
			
		||||
       * In the future, we should support wl_fullscreen_output
 | 
			
		||||
       * which will have CRTC management in the protocol. */
 | 
			
		||||
      return META_TYPE_MONITOR_MANAGER_DUMMY;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  manager->power_save_mode = mode;
 | 
			
		||||
  g_assert_not_reached ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaMonitorManager *
 | 
			
		||||
meta_monitor_manager_new (void)
 | 
			
		||||
{
 | 
			
		||||
  const char *env;
 | 
			
		||||
  GType type;
 | 
			
		||||
 | 
			
		||||
  env = g_getenv ("META_DEBUG_MULTIMONITOR");
 | 
			
		||||
 | 
			
		||||
  if (env == NULL)
 | 
			
		||||
    type = get_default_backend ();
 | 
			
		||||
  else if (strcmp (env, "xrandr") == 0)
 | 
			
		||||
    type = META_TYPE_MONITOR_MANAGER_XRANDR;
 | 
			
		||||
  else
 | 
			
		||||
    type = META_TYPE_MONITOR_MANAGER;
 | 
			
		||||
 | 
			
		||||
  return g_object_new (type, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -196,14 +225,11 @@ meta_monitor_manager_constructed (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
 | 
			
		||||
 | 
			
		||||
  g_signal_connect_object (manager, "notify::power-save-mode",
 | 
			
		||||
                           G_CALLBACK (power_save_mode_changed), manager, 0);
 | 
			
		||||
 | 
			
		||||
  manager->in_init = TRUE;
 | 
			
		||||
 | 
			
		||||
  manager->config = meta_monitor_config_new ();
 | 
			
		||||
 | 
			
		||||
  meta_monitor_manager_read_current_config (manager);
 | 
			
		||||
  read_current_config (manager);
 | 
			
		||||
 | 
			
		||||
  if (!meta_monitor_config_apply_stored (manager->config, manager))
 | 
			
		||||
    meta_monitor_config_make_default (manager->config, manager);
 | 
			
		||||
@@ -216,7 +242,24 @@ meta_monitor_manager_constructed (GObject *object)
 | 
			
		||||
     so this is not needed.
 | 
			
		||||
  */
 | 
			
		||||
  if (META_IS_MONITOR_MANAGER_XRANDR (manager))
 | 
			
		||||
    meta_monitor_manager_read_current_config (manager);
 | 
			
		||||
    {
 | 
			
		||||
      MetaOutput *old_outputs;
 | 
			
		||||
      MetaCRTC *old_crtcs;
 | 
			
		||||
      MetaMonitorMode *old_modes;
 | 
			
		||||
      unsigned int n_old_outputs, n_old_modes;
 | 
			
		||||
 | 
			
		||||
      old_outputs = manager->outputs;
 | 
			
		||||
      n_old_outputs = manager->n_outputs;
 | 
			
		||||
      old_modes = manager->modes;
 | 
			
		||||
      n_old_modes = manager->n_modes;
 | 
			
		||||
      old_crtcs = manager->crtcs;
 | 
			
		||||
 | 
			
		||||
      read_current_config (manager);
 | 
			
		||||
 | 
			
		||||
      meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
 | 
			
		||||
      meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
 | 
			
		||||
      g_free (old_crtcs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  make_logical_config (manager);
 | 
			
		||||
  initialize_dbus_interface (manager);
 | 
			
		||||
@@ -225,6 +268,23 @@ meta_monitor_manager_constructed (GObject *object)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_monitor_manager_set_power_save_mode (MetaMonitorManager *manager,
 | 
			
		||||
                                          MetaPowerSave       mode)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManagerClass *klass;
 | 
			
		||||
 | 
			
		||||
  if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED ||
 | 
			
		||||
      mode == META_POWER_SAVE_UNSUPPORTED)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  klass = META_MONITOR_MANAGER_GET_CLASS (manager);
 | 
			
		||||
  if (klass->set_power_save_mode)
 | 
			
		||||
    klass->set_power_save_mode (manager, mode);
 | 
			
		||||
 | 
			
		||||
  manager->power_save_mode = mode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
 | 
			
		||||
                                        int         n_old_outputs)
 | 
			
		||||
{
 | 
			
		||||
@@ -247,7 +307,7 @@ meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
 | 
			
		||||
  g_free (old_outputs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
void
 | 
			
		||||
meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
 | 
			
		||||
                                      int              n_old_modes)
 | 
			
		||||
{
 | 
			
		||||
@@ -291,6 +351,44 @@ meta_monitor_manager_dispose (GObject *object)
 | 
			
		||||
  G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_monitor_manager_set_property (GObject      *object,
 | 
			
		||||
                                   guint         prop_id,
 | 
			
		||||
                                   const GValue *value,
 | 
			
		||||
                                   GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManager *self = META_MONITOR_MANAGER (object);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_POWER_SAVE_MODE:
 | 
			
		||||
      meta_monitor_manager_set_power_save_mode (self, g_value_get_int (value));
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_monitor_manager_get_property (GObject      *object,
 | 
			
		||||
                                   guint         prop_id,
 | 
			
		||||
                                   GValue       *value,
 | 
			
		||||
                                   GParamSpec   *pspec)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManager *self = META_MONITOR_MANAGER (object);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_POWER_SAVE_MODE:
 | 
			
		||||
      g_value_set_int (value, self->power_save_mode);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GBytes *
 | 
			
		||||
meta_monitor_manager_real_read_edid (MetaMonitorManager *manager,
 | 
			
		||||
                                     MetaOutput         *output)
 | 
			
		||||
@@ -311,6 +409,8 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->constructed = meta_monitor_manager_constructed;
 | 
			
		||||
  object_class->get_property = meta_monitor_manager_get_property;
 | 
			
		||||
  object_class->set_property = meta_monitor_manager_set_property;
 | 
			
		||||
  object_class->dispose = meta_monitor_manager_dispose;
 | 
			
		||||
  object_class->finalize = meta_monitor_manager_finalize;
 | 
			
		||||
 | 
			
		||||
@@ -324,6 +424,8 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
 | 
			
		||||
		  0,
 | 
			
		||||
                  NULL, NULL, NULL,
 | 
			
		||||
		  G_TYPE_NONE, 0);
 | 
			
		||||
 | 
			
		||||
  g_object_class_override_property (object_class, PROP_POWER_SAVE_MODE, "power-save-mode");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const double known_diagonals[] = {
 | 
			
		||||
@@ -357,14 +459,11 @@ make_display_name (MetaMonitorManager *manager,
 | 
			
		||||
  char *vendor_name = NULL;
 | 
			
		||||
  char *ret;
 | 
			
		||||
 | 
			
		||||
  switch (output->connector_type)
 | 
			
		||||
  if (g_str_has_prefix (output->name, "LVDS") ||
 | 
			
		||||
      g_str_has_prefix (output->name, "eDP"))
 | 
			
		||||
    {
 | 
			
		||||
    case META_CONNECTOR_TYPE_LVDS:
 | 
			
		||||
    case META_CONNECTOR_TYPE_eDP:
 | 
			
		||||
      ret = g_strdup (_("Built-in display"));
 | 
			
		||||
      goto out;
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (output->width_mm > 0 && output->height_mm > 0)
 | 
			
		||||
@@ -412,32 +511,6 @@ make_display_name (MetaMonitorManager *manager,
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
get_connector_type_name (MetaConnectorType connector_type)
 | 
			
		||||
{
 | 
			
		||||
  switch (connector_type)
 | 
			
		||||
    {
 | 
			
		||||
    case META_CONNECTOR_TYPE_Unknown: return "Unknown";
 | 
			
		||||
    case META_CONNECTOR_TYPE_VGA: return "VGA";
 | 
			
		||||
    case META_CONNECTOR_TYPE_DVII: return "DVII";
 | 
			
		||||
    case META_CONNECTOR_TYPE_DVID: return "DVID";
 | 
			
		||||
    case META_CONNECTOR_TYPE_DVIA: return "DVIA";
 | 
			
		||||
    case META_CONNECTOR_TYPE_Composite: return "Composite";
 | 
			
		||||
    case META_CONNECTOR_TYPE_SVIDEO: return "SVIDEO";
 | 
			
		||||
    case META_CONNECTOR_TYPE_LVDS: return "LVDS";
 | 
			
		||||
    case META_CONNECTOR_TYPE_Component: return "Component";
 | 
			
		||||
    case META_CONNECTOR_TYPE_9PinDIN: return "9PinDIN";
 | 
			
		||||
    case META_CONNECTOR_TYPE_DisplayPort: return "DisplayPort";
 | 
			
		||||
    case META_CONNECTOR_TYPE_HDMIA: return "HDMIA";
 | 
			
		||||
    case META_CONNECTOR_TYPE_HDMIB: return "HDMIB";
 | 
			
		||||
    case META_CONNECTOR_TYPE_TV: return "TV";
 | 
			
		||||
    case META_CONNECTOR_TYPE_eDP: return "eDP";
 | 
			
		||||
    case META_CONNECTOR_TYPE_VIRTUAL: return "VIRTUAL";
 | 
			
		||||
    case META_CONNECTOR_TYPE_DSI: return "DSI";
 | 
			
		||||
    default: g_assert_not_reached ();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
 | 
			
		||||
                                           GDBusMethodInvocation *invocation)
 | 
			
		||||
@@ -457,19 +530,19 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
 | 
			
		||||
      GVariantBuilder transforms;
 | 
			
		||||
 | 
			
		||||
      g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
 | 
			
		||||
      for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++)
 | 
			
		||||
      for (j = 0; j <= WL_OUTPUT_TRANSFORM_FLIPPED_270; j++)
 | 
			
		||||
        if (crtc->all_transforms & (1 << j))
 | 
			
		||||
          g_variant_builder_add (&transforms, "u", j);
 | 
			
		||||
 | 
			
		||||
      g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
 | 
			
		||||
                             i, /* ID */
 | 
			
		||||
                             (gint64)crtc->crtc_id,
 | 
			
		||||
                             crtc->crtc_id,
 | 
			
		||||
                             (int)crtc->rect.x,
 | 
			
		||||
                             (int)crtc->rect.y,
 | 
			
		||||
                             (int)crtc->rect.width,
 | 
			
		||||
                             (int)crtc->rect.height,
 | 
			
		||||
                             (int)(crtc->current_mode ? crtc->current_mode - manager->modes : -1),
 | 
			
		||||
                             (guint32)crtc->transform,
 | 
			
		||||
                             crtc->transform,
 | 
			
		||||
                             &transforms,
 | 
			
		||||
                             NULL /* properties */);
 | 
			
		||||
    }
 | 
			
		||||
@@ -518,8 +591,6 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
 | 
			
		||||
                             g_variant_new_boolean (output->is_primary));
 | 
			
		||||
      g_variant_builder_add (&properties, "{sv}", "presentation",
 | 
			
		||||
                             g_variant_new_boolean (output->is_presentation));
 | 
			
		||||
      g_variant_builder_add (&properties, "{sv}", "connector-type",
 | 
			
		||||
                             g_variant_new_string (get_connector_type_name (output->connector_type)));
 | 
			
		||||
 | 
			
		||||
      edid_file = manager_class->get_edid_file (manager, output);
 | 
			
		||||
      if (edid_file)
 | 
			
		||||
@@ -542,7 +613,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
 | 
			
		||||
 | 
			
		||||
      g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
 | 
			
		||||
                             i, /* ID */
 | 
			
		||||
                             (gint64)output->winsys_id,
 | 
			
		||||
                             output->output_id,
 | 
			
		||||
                             (int)(output->crtc ? output->crtc - manager->crtcs : -1),
 | 
			
		||||
                             &crtcs,
 | 
			
		||||
                             output->name,
 | 
			
		||||
@@ -557,9 +628,9 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
 | 
			
		||||
 | 
			
		||||
      g_variant_builder_add (&mode_builder, "(uxuud)",
 | 
			
		||||
                             i, /* ID */
 | 
			
		||||
                             (gint64)mode->mode_id,
 | 
			
		||||
                             (guint32)mode->width,
 | 
			
		||||
                             (guint32)mode->height,
 | 
			
		||||
                             mode->mode_id,
 | 
			
		||||
                             mode->width,
 | 
			
		||||
                             mode->height,
 | 
			
		||||
                             (double)mode->refresh_rate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -649,7 +720,7 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto
 | 
			
		||||
  int new_mode, x, y;
 | 
			
		||||
  int new_screen_width, new_screen_height;
 | 
			
		||||
  guint transform;
 | 
			
		||||
  guint output_index;
 | 
			
		||||
  guint output_id;
 | 
			
		||||
  GPtrArray *crtc_infos, *output_infos;
 | 
			
		||||
 | 
			
		||||
  if (serial != manager->serial)
 | 
			
		||||
@@ -676,6 +747,7 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto
 | 
			
		||||
      MetaOutput *first_output;
 | 
			
		||||
      MetaCRTC *crtc;
 | 
			
		||||
      MetaMonitorMode *mode;
 | 
			
		||||
      guint output_id;
 | 
			
		||||
 | 
			
		||||
      crtc_info = g_slice_new (MetaCRTCInfo);
 | 
			
		||||
      crtc_info->outputs = g_ptr_array_new ();
 | 
			
		||||
@@ -737,8 +809,8 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto
 | 
			
		||||
          crtc_info->y = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (transform < META_MONITOR_TRANSFORM_NORMAL ||
 | 
			
		||||
          transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
 | 
			
		||||
      if (transform < WL_OUTPUT_TRANSFORM_NORMAL ||
 | 
			
		||||
          transform > WL_OUTPUT_TRANSFORM_FLIPPED_270 ||
 | 
			
		||||
          ((crtc->all_transforms & (1 << transform)) == 0))
 | 
			
		||||
        {
 | 
			
		||||
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
 | 
			
		||||
@@ -749,18 +821,18 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto
 | 
			
		||||
      crtc_info->transform = transform;
 | 
			
		||||
 | 
			
		||||
      first_output = NULL;
 | 
			
		||||
      while (g_variant_iter_loop (nested_outputs, "u", &output_index))
 | 
			
		||||
      while (g_variant_iter_loop (nested_outputs, "u", &output_id))
 | 
			
		||||
        {
 | 
			
		||||
          MetaOutput *output;
 | 
			
		||||
 | 
			
		||||
          if (output_index >= manager->n_outputs)
 | 
			
		||||
          if (output_id >= manager->n_outputs)
 | 
			
		||||
            {
 | 
			
		||||
              g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
 | 
			
		||||
                                                     G_DBUS_ERROR_INVALID_ARGS,
 | 
			
		||||
                                                     "Invalid output id");
 | 
			
		||||
              return TRUE;
 | 
			
		||||
            }
 | 
			
		||||
          output = &manager->outputs[output_index];
 | 
			
		||||
          output = &manager->outputs[output_id];
 | 
			
		||||
 | 
			
		||||
          if (!output_can_config (output, crtc, mode))
 | 
			
		||||
            {
 | 
			
		||||
@@ -805,12 +877,12 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_variant_iter_init (&output_iter, outputs);
 | 
			
		||||
  while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_index, &properties))
 | 
			
		||||
  while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_id, &properties))
 | 
			
		||||
    {
 | 
			
		||||
      MetaOutputInfo *output_info;
 | 
			
		||||
      gboolean primary, presentation;
 | 
			
		||||
 | 
			
		||||
      if (output_index >= manager->n_outputs)
 | 
			
		||||
      if (output_id >= manager->n_outputs)
 | 
			
		||||
        {
 | 
			
		||||
          g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
 | 
			
		||||
                                                 G_DBUS_ERROR_INVALID_ARGS,
 | 
			
		||||
@@ -819,7 +891,7 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      output_info = g_slice_new0 (MetaOutputInfo);
 | 
			
		||||
      output_info->output = &manager->outputs[output_index];
 | 
			
		||||
      output_info->output = &manager->outputs[output_id];
 | 
			
		||||
 | 
			
		||||
      if (g_variant_lookup (properties, "primary", "b", &primary))
 | 
			
		||||
        output_info->is_primary = primary;
 | 
			
		||||
@@ -833,7 +905,7 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto
 | 
			
		||||
  /* If we were in progress of making a persistent change and we see a
 | 
			
		||||
     new request, it's likely that the old one failed in some way, so
 | 
			
		||||
     don't save it, but also don't queue for restoring it.
 | 
			
		||||
  */
 | 
			
		||||
  */ 
 | 
			
		||||
  if (manager->persistent_timeout_id && persistent)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_remove (manager->persistent_timeout_id);
 | 
			
		||||
@@ -859,7 +931,6 @@ meta_monitor_manager_handle_apply_configuration  (MetaDBusDisplayConfig *skeleto
 | 
			
		||||
  if (persistent)
 | 
			
		||||
    {
 | 
			
		||||
      manager->persistent_timeout_id = g_timeout_add_seconds (20, save_config_timeout, manager);
 | 
			
		||||
      g_source_set_name_by_id (manager->persistent_timeout_id, "[mutter] save_config_timeout");
 | 
			
		||||
      g_signal_emit (manager, signals[CONFIRM_DISPLAY_CHANGE], 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -890,7 +961,7 @@ static gboolean
 | 
			
		||||
meta_monitor_manager_handle_change_backlight  (MetaDBusDisplayConfig *skeleton,
 | 
			
		||||
                                               GDBusMethodInvocation *invocation,
 | 
			
		||||
                                               guint                  serial,
 | 
			
		||||
                                               guint                  output_index,
 | 
			
		||||
                                               guint                  output_id,
 | 
			
		||||
                                               gint                   value)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton);
 | 
			
		||||
@@ -904,14 +975,14 @@ meta_monitor_manager_handle_change_backlight  (MetaDBusDisplayConfig *skeleton,
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (output_index >= manager->n_outputs)
 | 
			
		||||
  if (output_id >= manager->n_outputs)
 | 
			
		||||
    {
 | 
			
		||||
      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
 | 
			
		||||
                                             G_DBUS_ERROR_INVALID_ARGS,
 | 
			
		||||
                                             "Invalid output id");
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  output = &manager->outputs[output_index];
 | 
			
		||||
  output = &manager->outputs[output_id];
 | 
			
		||||
 | 
			
		||||
  if (value < 0 || value > 100)
 | 
			
		||||
    {
 | 
			
		||||
@@ -1107,19 +1178,20 @@ initialize_dbus_interface (MetaMonitorManager *manager)
 | 
			
		||||
                                          g_object_unref);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_monitor_manager_get:
 | 
			
		||||
 *
 | 
			
		||||
 * Accessor for the singleton MetaMonitorManager.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: (transfer none): The only #MetaMonitorManager there is.
 | 
			
		||||
 */
 | 
			
		||||
static MetaMonitorManager *global_monitor_manager;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_monitor_manager_initialize (void)
 | 
			
		||||
{
 | 
			
		||||
  global_monitor_manager = meta_monitor_manager_new ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaMonitorManager *
 | 
			
		||||
meta_monitor_manager_get (void)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
  g_assert (global_monitor_manager != NULL);
 | 
			
		||||
 | 
			
		||||
  return meta_backend_get_monitor_manager (backend);
 | 
			
		||||
  return global_monitor_manager;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaMonitorInfo *
 | 
			
		||||
@@ -1188,31 +1260,6 @@ meta_monitor_manager_get_screen_limits (MetaMonitorManager *manager,
 | 
			
		||||
  *height = manager->max_screen_height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  MetaOutput *old_outputs;
 | 
			
		||||
  MetaCRTC *old_crtcs;
 | 
			
		||||
  MetaMonitorMode *old_modes;
 | 
			
		||||
  unsigned int n_old_outputs, n_old_modes;
 | 
			
		||||
 | 
			
		||||
  /* Some implementations of read_current use the existing information
 | 
			
		||||
   * we have available, so don't free the old configuration until after
 | 
			
		||||
   * read_current finishes. */
 | 
			
		||||
  old_outputs = manager->outputs;
 | 
			
		||||
  n_old_outputs = manager->n_outputs;
 | 
			
		||||
  old_modes = manager->modes;
 | 
			
		||||
  n_old_modes = manager->n_modes;
 | 
			
		||||
  old_crtcs = manager->crtcs;
 | 
			
		||||
 | 
			
		||||
  manager->serial++;
 | 
			
		||||
  META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
 | 
			
		||||
 | 
			
		||||
  meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
 | 
			
		||||
  meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
 | 
			
		||||
  g_free (old_crtcs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
@@ -1230,165 +1277,16 @@ meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
 | 
			
		||||
  g_free (old_monitor_infos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_output_parse_edid (MetaOutput *meta_output,
 | 
			
		||||
                        GBytes     *edid)
 | 
			
		||||
{
 | 
			
		||||
  MonitorInfo *parsed_edid;
 | 
			
		||||
  gsize len;
 | 
			
		||||
 | 
			
		||||
  if (!edid)
 | 
			
		||||
    goto out;
 | 
			
		||||
 | 
			
		||||
  parsed_edid = decode_edid (g_bytes_get_data (edid, &len));
 | 
			
		||||
 | 
			
		||||
  if (parsed_edid)
 | 
			
		||||
    {
 | 
			
		||||
      meta_output->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
 | 
			
		||||
      if (parsed_edid->dsc_product_name[0])
 | 
			
		||||
        meta_output->product = g_strndup (parsed_edid->dsc_product_name, 14);
 | 
			
		||||
      else
 | 
			
		||||
        meta_output->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code);
 | 
			
		||||
      if (parsed_edid->dsc_serial_number[0])
 | 
			
		||||
        meta_output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
 | 
			
		||||
      else
 | 
			
		||||
        meta_output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
 | 
			
		||||
 | 
			
		||||
      g_free (parsed_edid);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  if (!meta_output->vendor)
 | 
			
		||||
    {
 | 
			
		||||
      meta_output->vendor = g_strdup ("unknown");
 | 
			
		||||
      meta_output->product = g_strdup ("unknown");
 | 
			
		||||
      meta_output->serial = g_strdup ("unknown");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_monitor_manager_on_hotplug (MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  gboolean applied_config = FALSE;
 | 
			
		||||
 | 
			
		||||
  /* If the monitor has hotplug_mode_update (which is used by VMs), don't bother
 | 
			
		||||
   * applying our stored configuration, because it's likely the user just resizing
 | 
			
		||||
   * the window.
 | 
			
		||||
   */
 | 
			
		||||
  if (!meta_monitor_manager_has_hotplug_mode_update (manager))
 | 
			
		||||
    {
 | 
			
		||||
      if (meta_monitor_config_apply_stored (manager->config, manager))
 | 
			
		||||
        applied_config = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* If we haven't applied any configuration, apply the default configuration. */
 | 
			
		||||
  if (!applied_config)
 | 
			
		||||
    meta_monitor_config_make_default (manager->config, manager);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
calculate_viewport_matrix (MetaMonitorManager *manager,
 | 
			
		||||
                           MetaOutput         *output,
 | 
			
		||||
                           gfloat              viewport[6])
 | 
			
		||||
{
 | 
			
		||||
  gfloat x, y, width, height;
 | 
			
		||||
 | 
			
		||||
  if (!output->crtc)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  x = (float) output->crtc->rect.x / manager->screen_width;
 | 
			
		||||
  y = (float) output->crtc->rect.y / manager->screen_height;
 | 
			
		||||
  width  = (float) output->crtc->rect.width / manager->screen_width;
 | 
			
		||||
  height = (float) output->crtc->rect.height / manager->screen_height;
 | 
			
		||||
 | 
			
		||||
  viewport[0] = width;
 | 
			
		||||
  viewport[1] = 0.0f;
 | 
			
		||||
  viewport[2] = x;
 | 
			
		||||
  viewport[3] = 0.0f;
 | 
			
		||||
  viewport[4] = height;
 | 
			
		||||
  viewport[5] = y;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void
 | 
			
		||||
multiply_matrix (float a[6],
 | 
			
		||||
		 float b[6],
 | 
			
		||||
		 float res[6])
 | 
			
		||||
{
 | 
			
		||||
  res[0] = a[0] * b[0] + a[1] * b[3];
 | 
			
		||||
  res[1] = a[0] * b[1] + a[1] * b[4];
 | 
			
		||||
  res[2] = a[0] * b[2] + a[1] * b[5] + a[2];
 | 
			
		||||
  res[3] = a[3] * b[0] + a[4] * b[3];
 | 
			
		||||
  res[4] = a[3] * b[1] + a[4] * b[4];
 | 
			
		||||
  res[5] = a[3] * b[2] + a[4] * b[5] + a[5];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
 | 
			
		||||
                                         MetaOutput         *output,
 | 
			
		||||
                                         gfloat              matrix[6])
 | 
			
		||||
meta_monitor_manager_handle_xevent (MetaMonitorManager *manager,
 | 
			
		||||
                                    XEvent             *event)
 | 
			
		||||
{
 | 
			
		||||
  gfloat viewport[9];
 | 
			
		||||
  MetaMonitorManagerClass *klass;
 | 
			
		||||
 | 
			
		||||
  if (!calculate_viewport_matrix (manager, output, viewport))
 | 
			
		||||
  klass = META_MONITOR_MANAGER_GET_CLASS (manager);
 | 
			
		||||
  if (klass->handle_xevent)
 | 
			
		||||
    return klass->handle_xevent (manager, event);
 | 
			
		||||
  else
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  multiply_matrix (viewport, transform_matrices[output->crtc->transform],
 | 
			
		||||
                   matrix);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_monitor_manager_get_output_geometry:
 | 
			
		||||
 * @manager: A #MetaMonitorManager
 | 
			
		||||
 * @id: A valid #MetaOutput id
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: The monitor index or -1 if @id isn't valid or the output
 | 
			
		||||
 * isn't associated with a logical monitor.
 | 
			
		||||
 */
 | 
			
		||||
gint
 | 
			
		||||
meta_monitor_manager_get_monitor_for_output (MetaMonitorManager *manager,
 | 
			
		||||
                                             guint               id)
 | 
			
		||||
{
 | 
			
		||||
  MetaOutput *output;
 | 
			
		||||
  guint i;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (META_IS_MONITOR_MANAGER (manager), -1);
 | 
			
		||||
  g_return_val_if_fail (id < manager->n_outputs, -1);
 | 
			
		||||
 | 
			
		||||
  output = &manager->outputs[id];
 | 
			
		||||
  if (!output || !output->crtc)
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < manager->n_monitor_infos; i++)
 | 
			
		||||
    if (meta_rectangle_contains_rect (&manager->monitor_infos[i].rect,
 | 
			
		||||
                                      &output->crtc->rect))
 | 
			
		||||
      return i;
 | 
			
		||||
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gint
 | 
			
		||||
meta_monitor_manager_get_monitor_at_point (MetaMonitorManager *manager,
 | 
			
		||||
                                           gfloat              x,
 | 
			
		||||
                                           gfloat              y)
 | 
			
		||||
{
 | 
			
		||||
  unsigned int i;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < manager->n_monitor_infos; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaMonitorInfo *monitor = &manager->monitor_infos[i];
 | 
			
		||||
      int left, right, top, bottom;
 | 
			
		||||
 | 
			
		||||
      left = monitor->rect.x;
 | 
			
		||||
      right = left + monitor->rect.width;
 | 
			
		||||
      top = monitor->rect.y;
 | 
			
		||||
      bottom = top + monitor->rect.height;
 | 
			
		||||
 | 
			
		||||
      if ((x >= left) && (x < right) && (y >= top) && (y < bottom))
 | 
			
		||||
	return i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,12 +12,12 @@
 | 
			
		||||
 * at MetaScreen instead.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
/* 
 | 
			
		||||
 * Copyright (C) 2001 Havoc Pennington
 | 
			
		||||
 * Copyright (C) 2003 Rob Adams
 | 
			
		||||
 * Copyright (C) 2004-2006 Elijah Newren
 | 
			
		||||
 * Copyright (C) 2013 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
 | 
			
		||||
 * published by the Free Software Foundation; either version 2 of the
 | 
			
		||||
@@ -27,7 +27,7 @@
 | 
			
		||||
 * 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
@@ -41,60 +41,30 @@
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
#include <meta/screen.h>
 | 
			
		||||
#include "stack-tracker.h"
 | 
			
		||||
#include <meta/meta-monitor-manager.h>
 | 
			
		||||
#include "ui.h"
 | 
			
		||||
#include <wayland-server.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-display-config-shared.h"
 | 
			
		||||
#include "meta-dbus-display-config.h"
 | 
			
		||||
#include "meta-cursor.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaMonitorManagerClass    MetaMonitorManagerClass;
 | 
			
		||||
typedef struct _MetaMonitorManager         MetaMonitorManager;
 | 
			
		||||
typedef struct _MetaMonitorConfigClass    MetaMonitorConfigClass;
 | 
			
		||||
typedef struct _MetaMonitorConfig         MetaMonitorConfig;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaCRTC MetaCRTC;
 | 
			
		||||
typedef struct _MetaOutput MetaOutput;
 | 
			
		||||
typedef struct _MetaCRTC MetaCRTC;
 | 
			
		||||
typedef struct _MetaMonitorMode MetaMonitorMode;
 | 
			
		||||
typedef struct _MetaMonitorInfo MetaMonitorInfo;
 | 
			
		||||
typedef struct _MetaCRTCInfo MetaCRTCInfo;
 | 
			
		||||
typedef struct _MetaOutputInfo MetaOutputInfo;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  META_MONITOR_TRANSFORM_NORMAL,
 | 
			
		||||
  META_MONITOR_TRANSFORM_90,
 | 
			
		||||
  META_MONITOR_TRANSFORM_180,
 | 
			
		||||
  META_MONITOR_TRANSFORM_270,
 | 
			
		||||
  META_MONITOR_TRANSFORM_FLIPPED,
 | 
			
		||||
  META_MONITOR_TRANSFORM_FLIPPED_90,
 | 
			
		||||
  META_MONITOR_TRANSFORM_FLIPPED_180,
 | 
			
		||||
  META_MONITOR_TRANSFORM_FLIPPED_270,
 | 
			
		||||
} MetaMonitorTransform;
 | 
			
		||||
 | 
			
		||||
/* This matches the values in drm_mode.h */
 | 
			
		||||
typedef enum {
 | 
			
		||||
  META_CONNECTOR_TYPE_Unknown = 0,
 | 
			
		||||
  META_CONNECTOR_TYPE_VGA = 1,
 | 
			
		||||
  META_CONNECTOR_TYPE_DVII = 2,
 | 
			
		||||
  META_CONNECTOR_TYPE_DVID = 3,
 | 
			
		||||
  META_CONNECTOR_TYPE_DVIA = 4,
 | 
			
		||||
  META_CONNECTOR_TYPE_Composite = 5,
 | 
			
		||||
  META_CONNECTOR_TYPE_SVIDEO = 6,
 | 
			
		||||
  META_CONNECTOR_TYPE_LVDS = 7,
 | 
			
		||||
  META_CONNECTOR_TYPE_Component = 8,
 | 
			
		||||
  META_CONNECTOR_TYPE_9PinDIN = 9,
 | 
			
		||||
  META_CONNECTOR_TYPE_DisplayPort = 10,
 | 
			
		||||
  META_CONNECTOR_TYPE_HDMIA = 11,
 | 
			
		||||
  META_CONNECTOR_TYPE_HDMIB = 12,
 | 
			
		||||
  META_CONNECTOR_TYPE_TV = 13,
 | 
			
		||||
  META_CONNECTOR_TYPE_eDP = 14,
 | 
			
		||||
  META_CONNECTOR_TYPE_VIRTUAL = 15,
 | 
			
		||||
  META_CONNECTOR_TYPE_DSI = 16,
 | 
			
		||||
} MetaConnectorType;
 | 
			
		||||
 | 
			
		||||
struct _MetaOutput
 | 
			
		||||
{
 | 
			
		||||
  /* The CRTC driving this output, NULL if the output is not enabled */
 | 
			
		||||
  MetaCRTC *crtc;
 | 
			
		||||
  /* The low-level ID of this output, used to apply back configuration */
 | 
			
		||||
  glong winsys_id;
 | 
			
		||||
  glong output_id;
 | 
			
		||||
  char *name;
 | 
			
		||||
  char *vendor;
 | 
			
		||||
  char *product;
 | 
			
		||||
@@ -102,9 +72,6 @@ struct _MetaOutput
 | 
			
		||||
  int width_mm;
 | 
			
		||||
  int height_mm;
 | 
			
		||||
  CoglSubpixelOrder subpixel_order;
 | 
			
		||||
  int scale;
 | 
			
		||||
 | 
			
		||||
  MetaConnectorType connector_type;
 | 
			
		||||
 | 
			
		||||
  MetaMonitorMode *preferred_mode;
 | 
			
		||||
  MetaMonitorMode **modes;
 | 
			
		||||
@@ -138,8 +105,6 @@ struct _MetaOutput
 | 
			
		||||
 | 
			
		||||
  /* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
 | 
			
		||||
  gboolean hotplug_mode_update;
 | 
			
		||||
  gint suggested_x;
 | 
			
		||||
  gint suggested_y;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaCRTC
 | 
			
		||||
@@ -147,7 +112,7 @@ struct _MetaCRTC
 | 
			
		||||
  glong crtc_id;
 | 
			
		||||
  MetaRectangle rect;
 | 
			
		||||
  MetaMonitorMode *current_mode;
 | 
			
		||||
  MetaMonitorTransform transform;
 | 
			
		||||
  enum wl_output_transform transform;
 | 
			
		||||
  unsigned int all_transforms;
 | 
			
		||||
 | 
			
		||||
  /* Only used to build the logical configuration
 | 
			
		||||
@@ -158,7 +123,8 @@ struct _MetaCRTC
 | 
			
		||||
  /* Used when changing configuration */
 | 
			
		||||
  gboolean is_dirty;
 | 
			
		||||
 | 
			
		||||
  MetaCursorReference *cursor;
 | 
			
		||||
  /* Updated by MetaCursorTracker */
 | 
			
		||||
  gboolean has_hw_cursor;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaMonitorMode
 | 
			
		||||
@@ -195,14 +161,14 @@ struct _MetaMonitorInfo
 | 
			
		||||
  gboolean in_fullscreen;
 | 
			
		||||
 | 
			
		||||
  /* The primary or first output for this monitor, 0 if we can't figure out.
 | 
			
		||||
     It can be matched to a winsys_id of a MetaOutput.
 | 
			
		||||
     It can be matched to an output_id of a MetaOutput.
 | 
			
		||||
 | 
			
		||||
     This is used as an opaque token on reconfiguration when switching from
 | 
			
		||||
     clone to extened, to decide on what output the windows should go next
 | 
			
		||||
     (it's an attempt to keep windows on the same monitor, and preferably on
 | 
			
		||||
     the primary one).
 | 
			
		||||
  */
 | 
			
		||||
  glong winsys_id;
 | 
			
		||||
  glong output_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -218,13 +184,13 @@ struct _MetaCRTCInfo {
 | 
			
		||||
  MetaMonitorMode          *mode;
 | 
			
		||||
  int                       x;
 | 
			
		||||
  int                       y;
 | 
			
		||||
  MetaMonitorTransform      transform;
 | 
			
		||||
  enum wl_output_transform  transform;
 | 
			
		||||
  GPtrArray                *outputs;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * MetaOutputInfo:
 | 
			
		||||
 * this is the same as MetaCRTCInfo, but for outputs
 | 
			
		||||
 * this is the same as MetaOutputInfo, but for CRTCs
 | 
			
		||||
 */
 | 
			
		||||
struct _MetaOutputInfo {
 | 
			
		||||
  MetaOutput  *output;
 | 
			
		||||
@@ -319,8 +285,16 @@ struct _MetaMonitorManagerClass
 | 
			
		||||
                          unsigned short     *,
 | 
			
		||||
                          unsigned short     *,
 | 
			
		||||
                          unsigned short     *);
 | 
			
		||||
 | 
			
		||||
  gboolean (*handle_xevent) (MetaMonitorManager *,
 | 
			
		||||
                             XEvent             *);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType meta_monitor_manager_get_type (void);
 | 
			
		||||
 | 
			
		||||
void                meta_monitor_manager_initialize (void);
 | 
			
		||||
MetaMonitorManager *meta_monitor_manager_get  (void);
 | 
			
		||||
 | 
			
		||||
void                meta_monitor_manager_rebuild_derived   (MetaMonitorManager *manager);
 | 
			
		||||
 | 
			
		||||
MetaMonitorInfo    *meta_monitor_manager_get_monitor_infos (MetaMonitorManager *manager,
 | 
			
		||||
@@ -339,6 +313,9 @@ void                meta_monitor_manager_get_resources     (MetaMonitorManager
 | 
			
		||||
 | 
			
		||||
int                 meta_monitor_manager_get_primary_index (MetaMonitorManager *manager);
 | 
			
		||||
 | 
			
		||||
gboolean            meta_monitor_manager_handle_xevent     (MetaMonitorManager *manager,
 | 
			
		||||
                                                            XEvent             *event);
 | 
			
		||||
 | 
			
		||||
void                meta_monitor_manager_get_screen_size   (MetaMonitorManager *manager,
 | 
			
		||||
                                                            int                *width,
 | 
			
		||||
                                                            int                *height);
 | 
			
		||||
@@ -356,28 +333,19 @@ void                meta_monitor_manager_apply_configuration (MetaMonitorManager
 | 
			
		||||
void                meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
 | 
			
		||||
                                                                gboolean            ok);
 | 
			
		||||
 | 
			
		||||
void               meta_output_parse_edid (MetaOutput *output,
 | 
			
		||||
                                           GBytes     *edid);
 | 
			
		||||
 | 
			
		||||
void               meta_crtc_info_free   (MetaCRTCInfo   *info);
 | 
			
		||||
void               meta_output_info_free (MetaOutputInfo *info);
 | 
			
		||||
 | 
			
		||||
void               meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
 | 
			
		||||
                                                           int         n_old_outputs);
 | 
			
		||||
void               meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
 | 
			
		||||
                                                         int              n_old_modes);
 | 
			
		||||
gboolean           meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager);
 | 
			
		||||
void               meta_monitor_manager_read_current_config (MetaMonitorManager *manager);
 | 
			
		||||
void               meta_monitor_manager_on_hotplug (MetaMonitorManager *manager);
 | 
			
		||||
 | 
			
		||||
gboolean           meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
 | 
			
		||||
                                                            MetaOutput         *output,
 | 
			
		||||
                                                            gfloat              matrix[6]);
 | 
			
		||||
 | 
			
		||||
gint               meta_monitor_manager_get_monitor_at_point (MetaMonitorManager *manager,
 | 
			
		||||
                                                              gfloat              x,
 | 
			
		||||
                                                              gfloat              y);
 | 
			
		||||
 | 
			
		||||
/* Returns true if transform causes width and height to be inverted
 | 
			
		||||
   This is true for the odd transforms in the enum */
 | 
			
		||||
static inline gboolean
 | 
			
		||||
meta_monitor_transform_is_rotated (MetaMonitorTransform transform)
 | 
			
		||||
meta_monitor_transform_is_rotated (enum wl_output_transform transform)
 | 
			
		||||
{
 | 
			
		||||
  return (transform % 2);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,264 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-stage.h"
 | 
			
		||||
 | 
			
		||||
#include "meta-cursor-private.h"
 | 
			
		||||
#include <meta/meta-backend.h>
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  gboolean enabled;
 | 
			
		||||
 | 
			
		||||
  CoglPipeline *pipeline;
 | 
			
		||||
  CoglTexture *texture;
 | 
			
		||||
 | 
			
		||||
  MetaRectangle current_rect;
 | 
			
		||||
  MetaRectangle previous_rect;
 | 
			
		||||
  gboolean previous_is_valid;
 | 
			
		||||
} MetaOverlay;
 | 
			
		||||
 | 
			
		||||
struct _MetaStagePrivate {
 | 
			
		||||
  MetaOverlay cursor_overlay;
 | 
			
		||||
  gboolean is_active;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _MetaStagePrivate MetaStagePrivate;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaStage, meta_stage, CLUTTER_TYPE_STAGE);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_overlay_init (MetaOverlay *overlay)
 | 
			
		||||
{
 | 
			
		||||
  CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
 | 
			
		||||
 | 
			
		||||
  overlay->pipeline = cogl_pipeline_new (ctx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_overlay_free (MetaOverlay *overlay)
 | 
			
		||||
{
 | 
			
		||||
  if (overlay->pipeline)
 | 
			
		||||
    cogl_object_unref (overlay->pipeline);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_overlay_set (MetaOverlay   *overlay,
 | 
			
		||||
                  CoglTexture   *texture,
 | 
			
		||||
                  MetaRectangle *rect)
 | 
			
		||||
{
 | 
			
		||||
  if (overlay->texture != texture)
 | 
			
		||||
    {
 | 
			
		||||
      overlay->texture = texture;
 | 
			
		||||
 | 
			
		||||
      if (texture)
 | 
			
		||||
        {
 | 
			
		||||
          cogl_pipeline_set_layer_texture (overlay->pipeline, 0, texture);
 | 
			
		||||
          overlay->enabled = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          cogl_pipeline_set_layer_texture (overlay->pipeline, 0, NULL);
 | 
			
		||||
          overlay->enabled = FALSE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  overlay->current_rect = *rect;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_overlay_paint (MetaOverlay *overlay)
 | 
			
		||||
{
 | 
			
		||||
  if (!overlay->enabled)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_assert (meta_is_wayland_compositor ());
 | 
			
		||||
 | 
			
		||||
  cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
 | 
			
		||||
                                   overlay->pipeline,
 | 
			
		||||
                                   overlay->current_rect.x,
 | 
			
		||||
                                   overlay->current_rect.y,
 | 
			
		||||
                                   overlay->current_rect.x +
 | 
			
		||||
                                   overlay->current_rect.width,
 | 
			
		||||
                                   overlay->current_rect.y +
 | 
			
		||||
                                   overlay->current_rect.height);
 | 
			
		||||
 | 
			
		||||
  overlay->previous_rect = overlay->current_rect;
 | 
			
		||||
  overlay->previous_is_valid = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_stage_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaStage *stage = META_STAGE (object);
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
 | 
			
		||||
  meta_overlay_free (&priv->cursor_overlay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_stage_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  MetaStage *stage = META_STAGE (actor);
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
 | 
			
		||||
 | 
			
		||||
  meta_overlay_paint (&priv->cursor_overlay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_stage_activate (ClutterStage *actor)
 | 
			
		||||
{
 | 
			
		||||
  MetaStage *stage = META_STAGE (actor);
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
 | 
			
		||||
  CLUTTER_STAGE_CLASS (meta_stage_parent_class)->activate (actor);
 | 
			
		||||
 | 
			
		||||
  priv->is_active = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_stage_deactivate (ClutterStage *actor)
 | 
			
		||||
{
 | 
			
		||||
  MetaStage *stage = META_STAGE (actor);
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
 | 
			
		||||
  CLUTTER_STAGE_CLASS (meta_stage_parent_class)->deactivate (actor);
 | 
			
		||||
 | 
			
		||||
  priv->is_active = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_stage_class_init (MetaStageClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageClass *stage_class = (ClutterStageClass *) klass;
 | 
			
		||||
  ClutterActorClass *actor_class = (ClutterActorClass *) klass;
 | 
			
		||||
  GObjectClass *object_class = (GObjectClass *) klass;
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = meta_stage_finalize;
 | 
			
		||||
 | 
			
		||||
  actor_class->paint = meta_stage_paint;
 | 
			
		||||
 | 
			
		||||
  stage_class->activate = meta_stage_activate;
 | 
			
		||||
  stage_class->deactivate = meta_stage_deactivate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_stage_init (MetaStage *stage)
 | 
			
		||||
{
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
 | 
			
		||||
  meta_overlay_init (&priv->cursor_overlay);
 | 
			
		||||
 | 
			
		||||
  clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ClutterActor *
 | 
			
		||||
meta_stage_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (META_TYPE_STAGE,
 | 
			
		||||
                       "cursor-visible", FALSE,
 | 
			
		||||
                       NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
queue_redraw_for_overlay (MetaStage   *stage,
 | 
			
		||||
                          MetaOverlay *overlay)
 | 
			
		||||
{
 | 
			
		||||
  cairo_rectangle_int_t clip;
 | 
			
		||||
 | 
			
		||||
  /* Clear the location the overlay was at before, if we need to. */
 | 
			
		||||
  if (overlay->previous_is_valid)
 | 
			
		||||
    {
 | 
			
		||||
      clip.x = overlay->previous_rect.x;
 | 
			
		||||
      clip.y = overlay->previous_rect.y;
 | 
			
		||||
      clip.width = overlay->previous_rect.width;
 | 
			
		||||
      clip.height = overlay->previous_rect.height;
 | 
			
		||||
      clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
 | 
			
		||||
      overlay->previous_is_valid = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Draw the overlay at the new position */
 | 
			
		||||
  if (overlay->enabled)
 | 
			
		||||
    {
 | 
			
		||||
      clip.x = overlay->current_rect.x;
 | 
			
		||||
      clip.y = overlay->current_rect.y;
 | 
			
		||||
      clip.width = overlay->current_rect.width;
 | 
			
		||||
      clip.height = overlay->current_rect.height;
 | 
			
		||||
      clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_stage_set_cursor (MetaStage     *stage,
 | 
			
		||||
                       CoglTexture   *texture,
 | 
			
		||||
                       MetaRectangle *rect)
 | 
			
		||||
{
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
 | 
			
		||||
  g_assert (meta_is_wayland_compositor () || texture == NULL);
 | 
			
		||||
 | 
			
		||||
  meta_overlay_set (&priv->cursor_overlay, texture, rect);
 | 
			
		||||
  queue_redraw_for_overlay (stage, &priv->cursor_overlay);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_stage_set_active (MetaStage *stage,
 | 
			
		||||
                       gboolean   is_active)
 | 
			
		||||
{
 | 
			
		||||
  MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
 | 
			
		||||
  ClutterEvent event = { 0 };
 | 
			
		||||
 | 
			
		||||
  /* Used by the native backend to inform accessibility technologies
 | 
			
		||||
   * about when the stage loses and gains input focus.
 | 
			
		||||
   *
 | 
			
		||||
   * For the X11 backend, clutter transparently takes care of this
 | 
			
		||||
   * for us.
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  if (priv->is_active == is_active)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  event.type = CLUTTER_STAGE_STATE;
 | 
			
		||||
  clutter_event_set_stage (&event, CLUTTER_STAGE (stage));
 | 
			
		||||
  event.stage_state.changed_mask = CLUTTER_STAGE_STATE_ACTIVATED;
 | 
			
		||||
 | 
			
		||||
  if (is_active)
 | 
			
		||||
    event.stage_state.new_state = CLUTTER_STAGE_STATE_ACTIVATED;
 | 
			
		||||
 | 
			
		||||
  /* Emitting this StageState event will result in the stage getting
 | 
			
		||||
   * activated or deactivated (with the activated or deactivated signal
 | 
			
		||||
   * getting emitted from the stage)
 | 
			
		||||
   *
 | 
			
		||||
   * FIXME: This won't update ClutterStage's own notion of its
 | 
			
		||||
   * activeness. For that we would need to somehow trigger a
 | 
			
		||||
   * _clutter_stage_update_state call, which will probably
 | 
			
		||||
   * require new API in clutter. In practice, nothing relies
 | 
			
		||||
   * on the ClutterStage's own notion of activeness when using
 | 
			
		||||
   * the EGL backend.
 | 
			
		||||
   *
 | 
			
		||||
   * See http://bugzilla.gnome.org/746670
 | 
			
		||||
   */
 | 
			
		||||
  clutter_stage_event (CLUTTER_STAGE (stage), &event);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,62 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2012 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
 | 
			
		||||
 * 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_STAGE_H
 | 
			
		||||
#define META_STAGE_H
 | 
			
		||||
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-cursor.h"
 | 
			
		||||
#include <meta/boxes.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_STAGE            (meta_stage_get_type ())
 | 
			
		||||
#define META_STAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_STAGE, MetaStage))
 | 
			
		||||
#define META_STAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_STAGE, MetaStageClass))
 | 
			
		||||
#define META_IS_STAGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_STAGE))
 | 
			
		||||
#define META_IS_STAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_STAGE))
 | 
			
		||||
#define META_STAGE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_STAGE, MetaStageClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaStage      MetaStage;
 | 
			
		||||
typedef struct _MetaStageClass MetaStageClass;
 | 
			
		||||
 | 
			
		||||
struct _MetaStageClass
 | 
			
		||||
{
 | 
			
		||||
  ClutterStageClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaStage
 | 
			
		||||
{
 | 
			
		||||
  ClutterStage parent;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType             meta_stage_get_type                (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
ClutterActor     *meta_stage_new                     (void);
 | 
			
		||||
 | 
			
		||||
void meta_stage_set_cursor (MetaStage     *stage,
 | 
			
		||||
                            CoglTexture   *texture,
 | 
			
		||||
                            MetaRectangle *rect);
 | 
			
		||||
 | 
			
		||||
void meta_stage_set_active (MetaStage *stage,
 | 
			
		||||
                            gboolean   is_active);
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* META_STAGE_H */
 | 
			
		||||
@@ -1,107 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2014 Red Hat
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * Written by:
 | 
			
		||||
 *     Jasper St. Pierre <jstpierre@mecheye.net>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include "dbus-utils.h"
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
/* Stolen from tp_escape_as_identifier, from tp-glib,
 | 
			
		||||
 * which follows the same escaping convention as systemd.
 | 
			
		||||
 */
 | 
			
		||||
static inline gboolean
 | 
			
		||||
_esc_ident_bad (gchar c, gboolean is_first)
 | 
			
		||||
{
 | 
			
		||||
  return ((c < 'a' || c > 'z') &&
 | 
			
		||||
          (c < 'A' || c > 'Z') &&
 | 
			
		||||
          (c < '0' || c > '9' || is_first));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gchar *
 | 
			
		||||
escape_dbus_component (const gchar *name)
 | 
			
		||||
{
 | 
			
		||||
  gboolean bad = FALSE;
 | 
			
		||||
  size_t len = 0;
 | 
			
		||||
  GString *op;
 | 
			
		||||
  const gchar *ptr, *first_ok;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (name != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  /* fast path for empty name */
 | 
			
		||||
  if (name[0] == '\0')
 | 
			
		||||
    return g_strdup ("_");
 | 
			
		||||
 | 
			
		||||
  for (ptr = name; *ptr; ptr++)
 | 
			
		||||
    {
 | 
			
		||||
      if (_esc_ident_bad (*ptr, ptr == name))
 | 
			
		||||
        {
 | 
			
		||||
          bad = TRUE;
 | 
			
		||||
          len += 3;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        len++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* fast path if it's clean */
 | 
			
		||||
  if (!bad)
 | 
			
		||||
    return g_strdup (name);
 | 
			
		||||
 | 
			
		||||
  /* If strictly less than ptr, first_ok is the first uncopied safe character.
 | 
			
		||||
   */
 | 
			
		||||
  first_ok = name;
 | 
			
		||||
  op = g_string_sized_new (len);
 | 
			
		||||
  for (ptr = name; *ptr; ptr++)
 | 
			
		||||
    {
 | 
			
		||||
      if (_esc_ident_bad (*ptr, ptr == name))
 | 
			
		||||
        {
 | 
			
		||||
          /* copy preceding safe characters if any */
 | 
			
		||||
          if (first_ok < ptr)
 | 
			
		||||
            {
 | 
			
		||||
              g_string_append_len (op, first_ok, ptr - first_ok);
 | 
			
		||||
            }
 | 
			
		||||
          /* escape the unsafe character */
 | 
			
		||||
          g_string_append_printf (op, "_%02x", (unsigned char)(*ptr));
 | 
			
		||||
          /* restart after it */
 | 
			
		||||
          first_ok = ptr + 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  /* copy trailing safe characters if any */
 | 
			
		||||
  if (first_ok < ptr)
 | 
			
		||||
    {
 | 
			
		||||
      g_string_append_len (op, first_ok, ptr - first_ok);
 | 
			
		||||
    }
 | 
			
		||||
  return g_string_free (op, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
get_escaped_dbus_path (const char *prefix,
 | 
			
		||||
                       const char *component)
 | 
			
		||||
{
 | 
			
		||||
  char *escaped_component = escape_dbus_component (component);
 | 
			
		||||
  char *path = g_strconcat (prefix, "/", escaped_component, NULL);
 | 
			
		||||
 | 
			
		||||
  g_free (escaped_component);
 | 
			
		||||
  return path;
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user