Compare commits
	
		
			128 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					a84f714808 | ||
| 
						 | 
					b41873dced | ||
| 
						 | 
					0a9511b24b | ||
| 
						 | 
					17438ced91 | ||
| 
						 | 
					27c7512e4d | ||
| 
						 | 
					124888764d | ||
| 
						 | 
					7e1c6ff2a2 | ||
| 
						 | 
					2fb8da0d5a | ||
| 
						 | 
					ad51c52b69 | ||
| 
						 | 
					1b22da0039 | ||
| 
						 | 
					8329e97502 | ||
| 
						 | 
					74ca936a00 | ||
| 
						 | 
					141760057b | ||
| 
						 | 
					e648f2c244 | ||
| 
						 | 
					f01247d815 | ||
| 
						 | 
					db6caa2c49 | ||
| 
						 | 
					fbd237bc66 | ||
| 
						 | 
					f6c9261bf6 | ||
| 
						 | 
					14b0a83f64 | ||
| 
						 | 
					441efd17ce | ||
| 
						 | 
					208da2316d | ||
| 
						 | 
					3b993131e8 | ||
| 
						 | 
					117f57f74c | ||
| 
						 | 
					b97ebc4124 | ||
| 
						 | 
					5d10196919 | ||
| 
						 | 
					f295349e26 | ||
| 
						 | 
					eb023ff2c9 | ||
| 
						 | 
					ba7c524a18 | ||
| 
						 | 
					dc99af40f3 | ||
| 
						 | 
					1576b7d5a6 | ||
| 
						 | 
					6ec7fa2cbd | ||
| 
						 | 
					bede9970de | ||
| 
						 | 
					5f1bcc124f | ||
| 
						 | 
					4d3419607a | ||
| 
						 | 
					7dc0b0e602 | ||
| 
						 | 
					1545d4e638 | ||
| 
						 | 
					a191554cf6 | ||
| 
						 | 
					b33a82eb7c | ||
| 
						 | 
					2705c87f74 | ||
| 
						 | 
					9fc1c919e8 | ||
| 
						 | 
					9f04c58ffe | ||
| 
						 | 
					7de1f3a7be | ||
| 
						 | 
					fd443ecf2a | ||
| 
						 | 
					8979e52a6c | ||
| 
						 | 
					e8dd5601e7 | ||
| 
						 | 
					ccca810daf | ||
| 
						 | 
					693456b644 | ||
| 
						 | 
					aacc3d5628 | ||
| 
						 | 
					1ea8efdeda | ||
| 
						 | 
					a3fbbaabe8 | ||
| 
						 | 
					d5d95b2834 | ||
| 
						 | 
					659b8ed471 | ||
| 
						 | 
					94bce5a00f | ||
| 
						 | 
					91b7dedf36 | ||
| 
						 | 
					aa1c819941 | ||
| 
						 | 
					be7e994abd | ||
| 
						 | 
					6c05eb583e | ||
| 
						 | 
					5547c98f97 | ||
| 
						 | 
					ea4979e182 | ||
| 
						 | 
					8da5761ffc | ||
| 
						 | 
					aea71fbd01 | ||
| 
						 | 
					b55f792302 | ||
| 
						 | 
					dd060d78ce | ||
| 
						 | 
					3fe281ada9 | ||
| 
						 | 
					f041b35b9b | ||
| 
						 | 
					afa58746ea | ||
| 
						 | 
					6dbec6f81b | ||
| 
						 | 
					2cbaa6660c | ||
| 
						 | 
					d74b0d5be8 | ||
| 
						 | 
					6b82f61dba | ||
| 
						 | 
					4c6866741d | ||
| 
						 | 
					84baf4e181 | ||
| 
						 | 
					3962f1d982 | ||
| 
						 | 
					414be07a69 | ||
| 
						 | 
					7f3ada7831 | ||
| 
						 | 
					12771a555a | ||
| 
						 | 
					92d6a69153 | ||
| 
						 | 
					734402e14d | ||
| 
						 | 
					5d360a9bce | ||
| 
						 | 
					f8cf5e373c | ||
| 
						 | 
					8df3fa4e67 | ||
| 
						 | 
					bbf2b4e60e | ||
| 
						 | 
					bb4dcd62ec | ||
| 
						 | 
					2345b9c6ad | ||
| 
						 | 
					af7cc87bfa | ||
| 
						 | 
					af3b599cbb | ||
| 
						 | 
					0e73ceb4bd | ||
| 
						 | 
					82a7060cdb | ||
| 
						 | 
					09120132ef | ||
| 
						 | 
					cdac4d0e92 | ||
| 
						 | 
					6aead0c67c | ||
| 
						 | 
					d593a61b39 | ||
| 
						 | 
					9747277b7e | ||
| 
						 | 
					989f9630a4 | ||
| 
						 | 
					daa15d94fd | ||
| 
						 | 
					999b99a077 | ||
| 
						 | 
					fd0b366a96 | ||
| 
						 | 
					320e2d452f | ||
| 
						 | 
					4d5dd01b7d | ||
| 
						 | 
					103c88bd72 | ||
| 
						 | 
					64cf87cfe1 | ||
| 
						 | 
					9f65edd4f5 | ||
| 
						 | 
					ea2496c80a | ||
| 
						 | 
					0c30ceddbe | ||
| 
						 | 
					5c9846c53a | ||
| 
						 | 
					2a8563ab23 | ||
| 
						 | 
					6a77d9722a | ||
| 
						 | 
					ef296031cb | ||
| 
						 | 
					e2d6028924 | ||
| 
						 | 
					4d80a4cc31 | ||
| 
						 | 
					4a968c3b4e | ||
| 
						 | 
					ccb7833e99 | ||
| 
						 | 
					b449ba942a | ||
| 
						 | 
					f53eea2c1c | ||
| 
						 | 
					b62db404ee | ||
| 
						 | 
					90a28e7b1c | ||
| 
						 | 
					8d51a9db5b | ||
| 
						 | 
					b39c00f344 | ||
| 
						 | 
					83ce71c3bf | ||
| 
						 | 
					f9d869a3dd | ||
| 
						 | 
					0b0ce4193f | ||
| 
						 | 
					719d8bd0c7 | ||
| 
						 | 
					4fc1811c15 | ||
| 
						 | 
					4b5f5abb4f | ||
| 
						 | 
					95ad52ba58 | ||
| 
						 | 
					dac30a222e | ||
| 
						 | 
					7d1b593fbd | ||
| 
						 | 
					d6a7559750 | 
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -57,10 +57,8 @@ testgradient
 | 
			
		||||
m4/*
 | 
			
		||||
INSTALL
 | 
			
		||||
mkinstalldirs
 | 
			
		||||
src/mutter-enum-types.[ch]
 | 
			
		||||
src/stamp-mutter-enum-types.h
 | 
			
		||||
src/mutter-marshal.[ch]
 | 
			
		||||
src/stamp-mutter-marshal.h
 | 
			
		||||
meta-enum-types.[ch]
 | 
			
		||||
src/stamp-meta-enum-types.h
 | 
			
		||||
src/meta-dbus-display-config.[ch]
 | 
			
		||||
src/meta-dbus-idle-monitor.[ch]
 | 
			
		||||
src/meta-dbus-login1.[ch]
 | 
			
		||||
 
 | 
			
		||||
@@ -9,5 +9,3 @@ DISTCLEANFILES = \
 | 
			
		||||
	intltool-update \
 | 
			
		||||
	po/stamp-it \
 | 
			
		||||
	po/.intltool-merge-cache
 | 
			
		||||
 | 
			
		||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,3 +1,41 @@
 | 
			
		||||
3.17.4
 | 
			
		||||
======
 | 
			
		||||
* nested: Allow basic configuration of dummy outputs [Jonas; #747089]
 | 
			
		||||
* Send wl_surface.enter and wl_surface.leave on output changes [Jonas; #744453]
 | 
			
		||||
* Improve HiDPI handling on wayland [Jonas; #745655, #744934]
 | 
			
		||||
* Implement compositor-side animated cursors [Carlos; #752342]
 | 
			
		||||
* Misc. bug fixes [Peter, Marek, Carlos, Matthias, Rui; #750816, #751884,
 | 
			
		||||
  #752248, #752551, #752552, #752673, #752674]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Marek Chalupa, Matthias Clasen, Carlos Garnacho, Peter Hutterer,
 | 
			
		||||
  Rui Matos, Florian Müllner, Jasper St. Pierre
 | 
			
		||||
 | 
			
		||||
3.17.3
 | 
			
		||||
======
 | 
			
		||||
* Add X11/wayland clipboard interaction [Carlos; #738312]
 | 
			
		||||
* Support VM monitor layout hints on wayland [Thomas; #750363]
 | 
			
		||||
* Misc. bug fixes [Rui, Jonas, Olivier, Carlos, Ting-Wei, Peter, Florian;
 | 
			
		||||
  #749994, #750256, #749716, #748705, #750552, #751036, #750007, #751136,
 | 
			
		||||
  #750552, #751471, #751715, #750680]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Jonas Ådahl, Dave Airlie, Cosimo Cecchi, Olivier Fourdan, Carlos Garnacho,
 | 
			
		||||
  Thomas Hellstrom, Peter Hutterer, Ting-Wei Lan, Jasper Lievisse Adriaanse,
 | 
			
		||||
  Rui Matos, Florian Müllner, Jasper St. Pierre
 | 
			
		||||
 | 
			
		||||
Translations:
 | 
			
		||||
  Marek Černocký [cs], Christian Kirbach [de], Pedro Albuquerque [pt]
 | 
			
		||||
 | 
			
		||||
3.17.2
 | 
			
		||||
======
 | 
			
		||||
* Honor default value for click method setting [Rui; #746290]
 | 
			
		||||
* Add X11/wayland clipboard interoperation [Carlos; #738312]
 | 
			
		||||
* Misc. bug fixes [Rui; #749076, #749711]
 | 
			
		||||
 | 
			
		||||
Contributors:
 | 
			
		||||
  Carlos Garnacho, Rui Matos, Jasper St. Pierre
 | 
			
		||||
 | 
			
		||||
3.17.1
 | 
			
		||||
======
 | 
			
		||||
* Add public method to get neighboring monitor [Florian; #633994]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								configure.ac
									
									
									
									
									
								
							@@ -2,7 +2,7 @@ AC_PREREQ(2.62)
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_major_version], [3])
 | 
			
		||||
m4_define([mutter_minor_version], [17])
 | 
			
		||||
m4_define([mutter_micro_version], [1])
 | 
			
		||||
m4_define([mutter_micro_version], [4])
 | 
			
		||||
 | 
			
		||||
m4_define([mutter_version],
 | 
			
		||||
          [mutter_major_version.mutter_minor_version.mutter_micro_version])
 | 
			
		||||
@@ -52,19 +52,6 @@ PKG_PROG_PKG_CONFIG([0.21])
 | 
			
		||||
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
 | 
			
		||||
AM_PATH_GLIB_2_0()
 | 
			
		||||
 | 
			
		||||
#### Integer sizes
 | 
			
		||||
 | 
			
		||||
AC_CHECK_SIZEOF(char)
 | 
			
		||||
AC_CHECK_SIZEOF(short)
 | 
			
		||||
AC_CHECK_SIZEOF(long)
 | 
			
		||||
AC_CHECK_SIZEOF(int)
 | 
			
		||||
AC_CHECK_SIZEOF(void *)
 | 
			
		||||
AC_CHECK_SIZEOF(long long)
 | 
			
		||||
AC_CHECK_SIZEOF(__int64)
 | 
			
		||||
 | 
			
		||||
## byte order
 | 
			
		||||
AC_C_BIGENDIAN
 | 
			
		||||
 | 
			
		||||
CANBERRA_GTK=libcanberra-gtk3
 | 
			
		||||
CANBERRA_GTK_VERSION=0.26
 | 
			
		||||
 | 
			
		||||
@@ -284,6 +271,8 @@ AC_CHECK_LIB(Xrandr, XRRUpdateConfiguration,
 | 
			
		||||
 | 
			
		||||
if test "x$found_randr" = "xyes"; then
 | 
			
		||||
   AC_DEFINE(HAVE_RANDR, , [Have the Xrandr extension library])
 | 
			
		||||
   PKG_CHECK_EXISTS([xrandr >= 1.5.0],
 | 
			
		||||
                 AC_DEFINE([HAVE_XRANDR15],[1],[Define if you have support for XRandR 1.5 or greater]))
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
MUTTER_LIBS="$MUTTER_LIBS $RANDR_LIBS $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm"
 | 
			
		||||
@@ -330,8 +319,6 @@ if test "x$enable_debug" = "xyes"; then
 | 
			
		||||
	CFLAGS="$CFLAGS -g -O"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
 | 
			
		||||
 | 
			
		||||
#### Warnings (last since -Werror can disturb other tests)
 | 
			
		||||
 | 
			
		||||
# Stay command-line compatible with the gnome-common configure option. Here
 | 
			
		||||
@@ -403,8 +390,6 @@ Makefile
 | 
			
		||||
data/Makefile
 | 
			
		||||
doc/Makefile
 | 
			
		||||
doc/man/Makefile
 | 
			
		||||
doc/reference/Makefile
 | 
			
		||||
doc/reference/meta-docs.sgml
 | 
			
		||||
src/Makefile
 | 
			
		||||
src/libmutter.pc
 | 
			
		||||
src/compositor/plugins/Makefile
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
SUBDIRS = man reference
 | 
			
		||||
SUBDIRS = man
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = dialogs.txt code-overview.txt \
 | 
			
		||||
	how-to-get-focus-right.txt rationales.txt
 | 
			
		||||
 
 | 
			
		||||
@@ -1,183 +0,0 @@
 | 
			
		||||
## Process this file with automake to produce Makefile.in
 | 
			
		||||
 | 
			
		||||
# We require automake 1.6 at least.
 | 
			
		||||
AUTOMAKE_OPTIONS = 1.6
 | 
			
		||||
 | 
			
		||||
# This is a blank Makefile.am for using gtk-doc.
 | 
			
		||||
# Copy this to your project's API docs directory and modify the variables to
 | 
			
		||||
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
 | 
			
		||||
# of using the various options.
 | 
			
		||||
 | 
			
		||||
# The name of the module, e.g. 'glib'.
 | 
			
		||||
DOC_MODULE=meta
 | 
			
		||||
 | 
			
		||||
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
 | 
			
		||||
#DOC_MODULE_VERSION=2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# The top-level SGML file. You can change this if you want to.
 | 
			
		||||
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
 | 
			
		||||
 | 
			
		||||
# Directories containing the source code, relative to $(srcdir).
 | 
			
		||||
# gtk-doc will search all .c and .h files beneath these paths
 | 
			
		||||
# for inline comments documenting functions and macros.
 | 
			
		||||
# e.g. DOC_SOURCE_DIR=../../../gtk ../../../gdk
 | 
			
		||||
DOC_SOURCE_DIR=../../src/
 | 
			
		||||
 | 
			
		||||
# Extra options to pass to gtkdoc-scangobj. Not normally needed.
 | 
			
		||||
SCANGOBJ_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-scan.
 | 
			
		||||
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
 | 
			
		||||
SCAN_OPTIONS=--rebuild-types
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mkdb.
 | 
			
		||||
# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml
 | 
			
		||||
MKDB_OPTIONS=--xml-mode --output-format=xml
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mktmpl
 | 
			
		||||
# e.g. MKTMPL_OPTIONS=--only-section-tmpl
 | 
			
		||||
MKTMPL_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mkhtml
 | 
			
		||||
MKHTML_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-fixref. Not normally needed.
 | 
			
		||||
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
 | 
			
		||||
FIXXREF_OPTIONS=
 | 
			
		||||
 | 
			
		||||
# Used for dependencies. The docs will be rebuilt if any of these change.
 | 
			
		||||
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
 | 
			
		||||
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
 | 
			
		||||
HFILE_GLOB=$(top_srcdir)/src/*/*.h
 | 
			
		||||
CFILE_GLOB=$(top_srcdir)/src/*/*.c
 | 
			
		||||
 | 
			
		||||
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
 | 
			
		||||
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
 | 
			
		||||
EXTRA_HFILES=
 | 
			
		||||
 | 
			
		||||
# Header files or dirs to ignore when scanning. Use base file/dir names
 | 
			
		||||
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
 | 
			
		||||
IGNORE_HFILES= \
 | 
			
		||||
	async-getprop.h \
 | 
			
		||||
	atoms.h \
 | 
			
		||||
	bell.h \
 | 
			
		||||
	boxes-private.h \
 | 
			
		||||
	clutter-utils.h \
 | 
			
		||||
	cogl-utils.h \
 | 
			
		||||
	compositor-private.h \
 | 
			
		||||
	constraints.h \
 | 
			
		||||
	core.h \
 | 
			
		||||
	display-private.h \
 | 
			
		||||
	draw-workspace.h \
 | 
			
		||||
	edge-resistance.h \
 | 
			
		||||
	eventqueue.h \
 | 
			
		||||
	frame.h \
 | 
			
		||||
	frames.h \
 | 
			
		||||
	group-private.h \
 | 
			
		||||
	group-props.h \
 | 
			
		||||
	iconcache.h \
 | 
			
		||||
	inlinepixbufs.h \
 | 
			
		||||
	keybindings-private.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 \
 | 
			
		||||
	meta-texture-rectangle.h \
 | 
			
		||||
	meta-texture-tower.h \
 | 
			
		||||
	meta-window-actor-private.h \
 | 
			
		||||
	meta-window-group.h \
 | 
			
		||||
	meta-window-shape.h \
 | 
			
		||||
	mutter-enum-types.h \
 | 
			
		||||
	mutter-Xatomtype.h \
 | 
			
		||||
	place.h \
 | 
			
		||||
	preview-widget.h \
 | 
			
		||||
	region-utils.h \
 | 
			
		||||
	resizepopup.h \
 | 
			
		||||
	screen-private.h \
 | 
			
		||||
	session.h \
 | 
			
		||||
	stack.h \
 | 
			
		||||
	stack-tracker.h \
 | 
			
		||||
	stamp-mutter-enum-types.h \
 | 
			
		||||
	tabpopup.h \
 | 
			
		||||
	theme.h \
 | 
			
		||||
	theme-private.h \
 | 
			
		||||
	tile-preview.h \
 | 
			
		||||
	ui.h \
 | 
			
		||||
	window-private.h \
 | 
			
		||||
	window-props.h \
 | 
			
		||||
	workspace-private.h \
 | 
			
		||||
	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.
 | 
			
		||||
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
 | 
			
		||||
HTML_IMAGES=
 | 
			
		||||
 | 
			
		||||
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
 | 
			
		||||
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
 | 
			
		||||
content_files= \
 | 
			
		||||
	mutter-overview.xml \
 | 
			
		||||
	running-mutter.xml \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
 | 
			
		||||
# These files must be listed here *and* in content_files
 | 
			
		||||
# e.g. expand_content_files=running.sgml
 | 
			
		||||
expand_content_files= \
 | 
			
		||||
	mutter-overview.xml \
 | 
			
		||||
	running-mutter.xml \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
 | 
			
		||||
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
 | 
			
		||||
# signals and properties.
 | 
			
		||||
# 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
 | 
			
		||||
 | 
			
		||||
# This includes the standard gtk-doc make rules, copied by gtkdocize.
 | 
			
		||||
include $(top_srcdir)/gtk-doc.make
 | 
			
		||||
 | 
			
		||||
# Other files to distribute
 | 
			
		||||
# e.g. EXTRA_DIST += version.xml.in
 | 
			
		||||
EXTRA_DIST +=
 | 
			
		||||
 | 
			
		||||
# Files not to distribute
 | 
			
		||||
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
 | 
			
		||||
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
 | 
			
		||||
DISTCLEANFILES = $(DOC_MODULES).types
 | 
			
		||||
 | 
			
		||||
# Comment this out if you want 'make check' to test you doc status
 | 
			
		||||
# and run some sanity checks
 | 
			
		||||
if ENABLE_GTK_DOC
 | 
			
		||||
TESTS_ENVIRONMENT = cd $(srcdir) && \
 | 
			
		||||
  DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
 | 
			
		||||
  SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
 | 
			
		||||
#TESTS = $(GTKDOC_CHECK)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
-include $(top_srcdir)/git.mk
 | 
			
		||||
@@ -1,58 +0,0 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
 | 
			
		||||
               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
 | 
			
		||||
[
 | 
			
		||||
  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
 | 
			
		||||
  <!ENTITY version "@VERSION@">
 | 
			
		||||
]>
 | 
			
		||||
<book id="index">
 | 
			
		||||
  <bookinfo>
 | 
			
		||||
    <title>Mutter Reference Manual</title>
 | 
			
		||||
    <releaseinfo>
 | 
			
		||||
      This document is for Mutter &version;.
 | 
			
		||||
      The latest version of this documentation can be found on-line at
 | 
			
		||||
      <ulink role="online-location" url="http://developer.gnome.org/meta/">http://developer.gnome.org/meta/</ulink>.
 | 
			
		||||
    </releaseinfo>
 | 
			
		||||
  </bookinfo>
 | 
			
		||||
 | 
			
		||||
  <xi:include href="xml/mutter-overview.xml"/>
 | 
			
		||||
  <xi:include href="xml/running-mutter.xml"/>
 | 
			
		||||
 | 
			
		||||
  <part id="core-reference">
 | 
			
		||||
    <title>Mutter Core Reference</title>
 | 
			
		||||
    <xi:include href="xml/main.xml"/>
 | 
			
		||||
    <xi:include href="xml/common.xml"/>
 | 
			
		||||
    <xi:include href="xml/prefs.xml"/>
 | 
			
		||||
    <xi:include href="xml/util.xml"/>
 | 
			
		||||
    <xi:include href="xml/errors.xml"/>
 | 
			
		||||
    <xi:include href="xml/meta-plugin.xml"/>
 | 
			
		||||
    <xi:include href="xml/barrier.xml"/>
 | 
			
		||||
    <xi:include href="xml/boxes.xml"/>
 | 
			
		||||
    <xi:include href="xml/compositor.xml"/>
 | 
			
		||||
    <xi:include href="xml/display.xml"/>
 | 
			
		||||
    <xi:include href="xml/group.xml"/>
 | 
			
		||||
    <xi:include href="xml/keybindings.xml"/>
 | 
			
		||||
    <xi:include href="xml/meta-background-actor.xml"/>
 | 
			
		||||
    <xi:include href="xml/meta-shadow-factory.xml"/>
 | 
			
		||||
    <xi:include href="xml/meta-shaped-texture.xml"/>
 | 
			
		||||
    <xi:include href="xml/meta-window-actor.xml"/>
 | 
			
		||||
    <xi:include href="xml/screen.xml"/>
 | 
			
		||||
    <xi:include href="xml/window.xml"/>
 | 
			
		||||
    <xi:include href="xml/workspace.xml"/>
 | 
			
		||||
  </part>
 | 
			
		||||
 | 
			
		||||
  <chapter id="object-tree">
 | 
			
		||||
    <title>Object Hierarchy</title>
 | 
			
		||||
     <xi:include href="xml/tree_index.sgml"/>
 | 
			
		||||
  </chapter>
 | 
			
		||||
  <index id="api-index-full">
 | 
			
		||||
    <title>API Index</title>
 | 
			
		||||
    <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
 | 
			
		||||
  </index>
 | 
			
		||||
  <index id="deprecated-api-index" role="deprecated">
 | 
			
		||||
    <title>Index of deprecated API</title>
 | 
			
		||||
    <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
 | 
			
		||||
  </index>
 | 
			
		||||
 | 
			
		||||
  <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
 | 
			
		||||
</book>
 | 
			
		||||
@@ -1,674 +0,0 @@
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>barrier</FILE>
 | 
			
		||||
<TITLE>MetaBarrier</TITLE>
 | 
			
		||||
MetaBarrier
 | 
			
		||||
MetaBarrierClass
 | 
			
		||||
meta_barrier_is_active
 | 
			
		||||
meta_barrier_destroy
 | 
			
		||||
meta_barrier_release
 | 
			
		||||
MetaBarrierDirection
 | 
			
		||||
MetaBarrierEvent
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_BARRIER
 | 
			
		||||
META_BARRIER_CLASS
 | 
			
		||||
META_BARRIER_GET_CLASS
 | 
			
		||||
META_IS_BARRIER
 | 
			
		||||
META_IS_BARRIER_CLASS
 | 
			
		||||
META_TYPE_BARRIER
 | 
			
		||||
META_TYPE_BARRIER_EVENT
 | 
			
		||||
MetaBarrierPrivate
 | 
			
		||||
meta_barrier_event_get_type
 | 
			
		||||
meta_barrier_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>boxes</FILE>
 | 
			
		||||
MetaRectangle
 | 
			
		||||
MetaStrut
 | 
			
		||||
MetaEdgeType
 | 
			
		||||
MetaEdge
 | 
			
		||||
meta_rectangle_copy
 | 
			
		||||
meta_rectangle_free
 | 
			
		||||
meta_rect
 | 
			
		||||
meta_rectangle_area
 | 
			
		||||
meta_rectangle_intersect
 | 
			
		||||
meta_rectangle_equal
 | 
			
		||||
meta_rectangle_union
 | 
			
		||||
meta_rectangle_overlap
 | 
			
		||||
meta_rectangle_vert_overlap
 | 
			
		||||
meta_rectangle_horiz_overlap
 | 
			
		||||
meta_rectangle_could_fit_rect
 | 
			
		||||
meta_rectangle_contains_rect
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_TYPE_RECTANGLE
 | 
			
		||||
meta_rectangle_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>common</FILE>
 | 
			
		||||
META_VIRTUAL_CORE_POINTER_ID
 | 
			
		||||
META_VIRTUAL_CORE_KEYBOARD_ID
 | 
			
		||||
MetaFrameFlags
 | 
			
		||||
MetaMenuOp
 | 
			
		||||
MetaWindowMenuFunc
 | 
			
		||||
MetaGrabOp
 | 
			
		||||
MetaCursor
 | 
			
		||||
MetaFrameType
 | 
			
		||||
MetaVirtualModifier
 | 
			
		||||
MetaDirection
 | 
			
		||||
MetaMotionDirection
 | 
			
		||||
MetaSide
 | 
			
		||||
MetaButtonFunction
 | 
			
		||||
MAX_BUTTONS_PER_CORNER
 | 
			
		||||
MetaButtonLayout
 | 
			
		||||
MetaFrameBorders
 | 
			
		||||
meta_frame_borders_clear
 | 
			
		||||
META_ICON_WIDTH
 | 
			
		||||
META_ICON_HEIGHT
 | 
			
		||||
META_MINI_ICON_WIDTH
 | 
			
		||||
META_MINI_ICON_HEIGHT
 | 
			
		||||
META_DEFAULT_ICON_NAME
 | 
			
		||||
META_PRIORITY_RESIZE
 | 
			
		||||
META_PRIORITY_BEFORE_REDRAW
 | 
			
		||||
META_PRIORITY_REDRAW
 | 
			
		||||
META_PRIORITY_PREFS_NOTIFY
 | 
			
		||||
POINT_IN_RECT
 | 
			
		||||
MetaStackLayer
 | 
			
		||||
MetaWindowMenu
 | 
			
		||||
MetaResizePopup
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>compositor</FILE>
 | 
			
		||||
MetaCompEffect
 | 
			
		||||
MetaCompositor
 | 
			
		||||
meta_compositor_new
 | 
			
		||||
meta_compositor_destroy
 | 
			
		||||
meta_compositor_manage_screen
 | 
			
		||||
meta_compositor_unmanage_screen
 | 
			
		||||
meta_compositor_window_shape_changed
 | 
			
		||||
meta_compositor_process_event
 | 
			
		||||
meta_compositor_filter_keybinding
 | 
			
		||||
meta_compositor_add_window
 | 
			
		||||
meta_compositor_remove_window
 | 
			
		||||
meta_compositor_show_window
 | 
			
		||||
meta_compositor_hide_window
 | 
			
		||||
meta_compositor_switch_workspace
 | 
			
		||||
meta_compositor_maximize_window
 | 
			
		||||
meta_compositor_unmaximize_window
 | 
			
		||||
meta_compositor_sync_window_geometry
 | 
			
		||||
meta_compositor_set_updates_frozen
 | 
			
		||||
meta_compositor_queue_frame_drawn
 | 
			
		||||
meta_compositor_sync_stack
 | 
			
		||||
meta_compositor_sync_screen_size
 | 
			
		||||
meta_compositor_flash_screen
 | 
			
		||||
meta_get_stage_for_screen
 | 
			
		||||
meta_get_overlay_group_for_screen
 | 
			
		||||
meta_get_overlay_window
 | 
			
		||||
meta_get_window_actors
 | 
			
		||||
meta_get_window_group_for_screen
 | 
			
		||||
meta_get_top_window_group_for_screen
 | 
			
		||||
meta_disable_unredirect_for_screen
 | 
			
		||||
meta_enable_unredirect_for_screen
 | 
			
		||||
meta_set_stage_input_region
 | 
			
		||||
meta_empty_stage_input_region
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>display</FILE>
 | 
			
		||||
MetaTabList
 | 
			
		||||
MetaTabShowType
 | 
			
		||||
meta_XFree
 | 
			
		||||
meta_display_get_compositor_version
 | 
			
		||||
meta_display_get_xinput_opcode
 | 
			
		||||
meta_display_supports_extended_barriers
 | 
			
		||||
meta_display_get_xdisplay
 | 
			
		||||
meta_display_get_compositor
 | 
			
		||||
meta_display_get_screens
 | 
			
		||||
meta_display_has_shape
 | 
			
		||||
meta_display_screen_for_root
 | 
			
		||||
meta_display_get_focus_window
 | 
			
		||||
meta_display_xwindow_is_a_no_focus_window
 | 
			
		||||
meta_display_get_damage_event_base
 | 
			
		||||
meta_display_get_shape_event_base
 | 
			
		||||
meta_display_xserver_time_is_before
 | 
			
		||||
meta_display_get_last_user_time
 | 
			
		||||
meta_display_get_current_time
 | 
			
		||||
meta_display_get_current_time_roundtrip
 | 
			
		||||
meta_display_get_ignored_modifier_mask
 | 
			
		||||
meta_display_get_tab_list
 | 
			
		||||
meta_display_get_tab_next
 | 
			
		||||
meta_display_get_tab_current
 | 
			
		||||
meta_display_begin_grab_op
 | 
			
		||||
meta_display_end_grab_op
 | 
			
		||||
meta_display_get_grab_op
 | 
			
		||||
meta_display_add_keybinding
 | 
			
		||||
meta_display_remove_keybinding
 | 
			
		||||
meta_display_get_keybinding_action
 | 
			
		||||
meta_display_set_input_focus_window
 | 
			
		||||
meta_display_focus_the_no_focus_window
 | 
			
		||||
meta_display_sort_windows_by_stacking
 | 
			
		||||
meta_display_get_leader_window
 | 
			
		||||
meta_display_add_ignored_crossing_serial
 | 
			
		||||
meta_display_unmanage_screen
 | 
			
		||||
meta_display_clear_mouse_mode
 | 
			
		||||
MetaDisplay
 | 
			
		||||
MetaDisplayClass
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_DISPLAY
 | 
			
		||||
META_DISPLAY_CLASS
 | 
			
		||||
META_DISPLAY_GET_CLASS
 | 
			
		||||
META_IS_DISPLAY
 | 
			
		||||
META_IS_DISPLAY_CLASS
 | 
			
		||||
META_TYPE_DISPLAY
 | 
			
		||||
meta_display_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>errors</FILE>
 | 
			
		||||
meta_error_trap_push
 | 
			
		||||
meta_error_trap_pop
 | 
			
		||||
meta_error_trap_push_with_return
 | 
			
		||||
meta_error_trap_pop_with_return
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>group</FILE>
 | 
			
		||||
MetaGroup
 | 
			
		||||
meta_window_get_group
 | 
			
		||||
meta_window_compute_group
 | 
			
		||||
meta_window_shutdown_group
 | 
			
		||||
meta_window_group_leader_changed
 | 
			
		||||
meta_display_lookup_group
 | 
			
		||||
meta_group_list_windows
 | 
			
		||||
meta_group_update_layers
 | 
			
		||||
meta_group_get_startup_id
 | 
			
		||||
meta_group_get_size
 | 
			
		||||
meta_group_property_notify
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>keybindings</FILE>
 | 
			
		||||
MetaKeyBinding
 | 
			
		||||
META_TYPE_KEY_BINDING
 | 
			
		||||
meta_key_binding_get_name
 | 
			
		||||
meta_key_binding_get_modifiers
 | 
			
		||||
meta_key_binding_get_mask
 | 
			
		||||
meta_key_binding_is_builtin
 | 
			
		||||
meta_keybindings_set_custom_handler
 | 
			
		||||
meta_screen_ungrab_all_keys
 | 
			
		||||
meta_screen_grab_all_keys
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>main</FILE>
 | 
			
		||||
meta_get_option_context
 | 
			
		||||
meta_init
 | 
			
		||||
meta_run
 | 
			
		||||
meta_get_replace_current_wm
 | 
			
		||||
meta_set_wm_name
 | 
			
		||||
meta_set_gnome_wm_keybindings
 | 
			
		||||
MetaExitCode
 | 
			
		||||
meta_exit
 | 
			
		||||
meta_quit
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>meta-background</FILE>
 | 
			
		||||
<TITLE>MetaBackground</TITLE>
 | 
			
		||||
MetaBackgroundEffects
 | 
			
		||||
MetaBackground
 | 
			
		||||
MetaBackgroundClass
 | 
			
		||||
meta_background_new
 | 
			
		||||
meta_background_copy
 | 
			
		||||
meta_background_load_gradient
 | 
			
		||||
meta_background_load_color
 | 
			
		||||
meta_background_load_still_frame
 | 
			
		||||
meta_background_load_file_async
 | 
			
		||||
meta_background_load_file_finish
 | 
			
		||||
meta_background_get_filename
 | 
			
		||||
meta_background_get_style
 | 
			
		||||
meta_background_get_shading
 | 
			
		||||
meta_background_get_color
 | 
			
		||||
meta_background_get_second_color
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_BACKGROUND
 | 
			
		||||
META_BACKGROUND_CLASS
 | 
			
		||||
META_BACKGROUND_GET_CLASS
 | 
			
		||||
META_IS_BACKGROUND
 | 
			
		||||
META_IS_BACKGROUND_CLASS
 | 
			
		||||
META_TYPE_BACKGROUND
 | 
			
		||||
MetaBackgroundPrivate
 | 
			
		||||
meta_background_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>meta-background-actor</FILE>
 | 
			
		||||
<TITLE>MetaBackgroundActor</TITLE>
 | 
			
		||||
MetaBackgroundActor
 | 
			
		||||
MetaBackgroundActorClass
 | 
			
		||||
meta_background_actor_new_for_screen
 | 
			
		||||
MetaSnippetHook
 | 
			
		||||
meta_background_actor_add_glsl_snippet
 | 
			
		||||
meta_background_actor_set_uniform_float
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_BACKGROUND_ACTOR
 | 
			
		||||
META_BACKGROUND_ACTOR_CLASS
 | 
			
		||||
META_BACKGROUND_ACTOR_GET_CLASS
 | 
			
		||||
META_IS_BACKGROUND_ACTOR
 | 
			
		||||
META_IS_BACKGROUND_ACTOR_CLASS
 | 
			
		||||
META_TYPE_BACKGROUND_ACTOR
 | 
			
		||||
MetaBackgroundActorPrivate
 | 
			
		||||
meta_background_actor_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>meta-background-group</FILE>
 | 
			
		||||
<TITLE>MetaBackgroundGroup</TITLE>
 | 
			
		||||
MetaBackgroundGroupClass
 | 
			
		||||
meta_background_group_new
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_BACKGROUND_GROUP
 | 
			
		||||
META_BACKGROUND_GROUP_CLASS
 | 
			
		||||
META_BACKGROUND_GROUP_GET_CLASS
 | 
			
		||||
META_IS_BACKGROUND_GROUP
 | 
			
		||||
META_IS_BACKGROUND_GROUP_CLASS
 | 
			
		||||
META_TYPE_BACKGROUND_GROUP
 | 
			
		||||
MetaBackgroundGroupPrivate
 | 
			
		||||
meta_background_group_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>meta-plugin</FILE>
 | 
			
		||||
<TITLE>MetaPlugin</TITLE>
 | 
			
		||||
MetaPlugin
 | 
			
		||||
MetaPluginClass
 | 
			
		||||
MetaPluginInfo
 | 
			
		||||
meta_plugin_running
 | 
			
		||||
meta_plugin_debug_mode
 | 
			
		||||
meta_plugin_get_info
 | 
			
		||||
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
 | 
			
		||||
meta_plugin_destroy_completed
 | 
			
		||||
MetaModalOptions
 | 
			
		||||
meta_plugin_begin_modal
 | 
			
		||||
meta_plugin_end_modal
 | 
			
		||||
meta_plugin_get_screen
 | 
			
		||||
meta_plugin_manager_set_plugin_type
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_IS_PLUGIN
 | 
			
		||||
META_IS_PLUGIN_CLASS
 | 
			
		||||
META_PLUGIN
 | 
			
		||||
META_PLUGIN_CLASS
 | 
			
		||||
META_PLUGIN_GET_CLASS
 | 
			
		||||
META_TYPE_PLUGIN
 | 
			
		||||
MetaPluginPrivate
 | 
			
		||||
meta_plugin_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>meta-shadow-factory</FILE>
 | 
			
		||||
MetaShadowParams
 | 
			
		||||
meta_shadow_factory_get_default
 | 
			
		||||
meta_shadow_factory_set_params
 | 
			
		||||
meta_shadow_factory_get_params
 | 
			
		||||
MetaShadowFactory
 | 
			
		||||
MetaShadowFactoryClass
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_IS_SHADOW_FACTORY
 | 
			
		||||
META_IS_SHADOW_FACTORY_CLASS
 | 
			
		||||
META_SHADOW_FACTORY
 | 
			
		||||
META_SHADOW_FACTORY_CLASS
 | 
			
		||||
META_SHADOW_FACTORY_GET_CLASS
 | 
			
		||||
META_TYPE_SHADOW_FACTORY
 | 
			
		||||
meta_shadow_factory_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>meta-shaped-texture</FILE>
 | 
			
		||||
<TITLE>MetaShapedTexture</TITLE>
 | 
			
		||||
MetaShapedTexture
 | 
			
		||||
MetaShapedTextureClass
 | 
			
		||||
meta_shaped_texture_new
 | 
			
		||||
meta_shaped_texture_set_create_mipmaps
 | 
			
		||||
meta_shaped_texture_update_area
 | 
			
		||||
meta_shaped_texture_set_pixmap
 | 
			
		||||
meta_shaped_texture_get_texture
 | 
			
		||||
meta_shaped_texture_set_mask_texture
 | 
			
		||||
meta_shaped_texture_set_clip_region
 | 
			
		||||
meta_shaped_texture_get_image
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_IS_SHAPED_TEXTURE
 | 
			
		||||
META_IS_SHAPED_TEXTURE_CLASS
 | 
			
		||||
META_SHAPED_TEXTURE
 | 
			
		||||
META_SHAPED_TEXTURE_CLASS
 | 
			
		||||
META_SHAPED_TEXTURE_GET_CLASS
 | 
			
		||||
META_TYPE_SHAPED_TEXTURE
 | 
			
		||||
MetaShapedTexturePrivate
 | 
			
		||||
meta_shaped_texture_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>meta-window-actor</FILE>
 | 
			
		||||
<TITLE>MetaWindowActor</TITLE>
 | 
			
		||||
MetaWindowActor
 | 
			
		||||
MetaWindowActorClass
 | 
			
		||||
meta_window_actor_get_x_window
 | 
			
		||||
meta_window_actor_get_workspace
 | 
			
		||||
meta_window_actor_get_meta_window
 | 
			
		||||
meta_window_actor_get_texture
 | 
			
		||||
meta_window_actor_is_override_redirect
 | 
			
		||||
meta_window_actor_get_description
 | 
			
		||||
meta_window_actor_showing_on_its_workspace
 | 
			
		||||
meta_window_actor_is_destroyed
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_IS_WINDOW_ACTOR
 | 
			
		||||
META_IS_WINDOW_ACTOR_CLASS
 | 
			
		||||
META_TYPE_WINDOW_ACTOR
 | 
			
		||||
META_WINDOW_ACTOR
 | 
			
		||||
META_WINDOW_ACTOR_CLASS
 | 
			
		||||
META_WINDOW_ACTOR_GET_CLASS
 | 
			
		||||
MetaWindowActorPrivate
 | 
			
		||||
meta_window_actor_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>meta-cullable</FILE>
 | 
			
		||||
<TITLE>MetaCullable</TITLE>
 | 
			
		||||
MetaCullable
 | 
			
		||||
MetaCullableInterface
 | 
			
		||||
meta_cullable_cull_out
 | 
			
		||||
meta_cullable_reset_culling
 | 
			
		||||
meta_cullable_cull_out_children
 | 
			
		||||
meta_cullable_reset_culling_children
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_TYPE_CULLABLE
 | 
			
		||||
META_CULLABLE
 | 
			
		||||
META_IS_CULLABLE
 | 
			
		||||
META_CULLABLE_GET_IFACE
 | 
			
		||||
meta_cullable_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>prefs</FILE>
 | 
			
		||||
MetaPreference
 | 
			
		||||
MetaPrefsChangedFunc
 | 
			
		||||
meta_prefs_add_listener
 | 
			
		||||
meta_prefs_remove_listener
 | 
			
		||||
meta_prefs_init
 | 
			
		||||
meta_prefs_override_preference_schema
 | 
			
		||||
meta_preference_to_string
 | 
			
		||||
meta_prefs_get_mouse_button_mods
 | 
			
		||||
meta_prefs_get_mouse_button_resize
 | 
			
		||||
meta_prefs_get_mouse_button_menu
 | 
			
		||||
meta_prefs_get_focus_mode
 | 
			
		||||
meta_prefs_get_focus_new_windows
 | 
			
		||||
meta_prefs_get_attach_modal_dialogs
 | 
			
		||||
meta_prefs_get_raise_on_click
 | 
			
		||||
meta_prefs_get_theme
 | 
			
		||||
meta_prefs_get_titlebar_font
 | 
			
		||||
meta_prefs_get_num_workspaces
 | 
			
		||||
meta_prefs_get_dynamic_workspaces
 | 
			
		||||
meta_prefs_get_disable_workarounds
 | 
			
		||||
meta_prefs_get_auto_raise
 | 
			
		||||
meta_prefs_get_auto_raise_delay
 | 
			
		||||
meta_prefs_get_focus_change_on_pointer_rest
 | 
			
		||||
meta_prefs_get_gnome_accessibility
 | 
			
		||||
meta_prefs_get_gnome_animations
 | 
			
		||||
meta_prefs_get_edge_tiling
 | 
			
		||||
meta_prefs_get_auto_maximize
 | 
			
		||||
meta_prefs_get_button_layout
 | 
			
		||||
meta_prefs_get_action_double_click_titlebar
 | 
			
		||||
meta_prefs_get_action_middle_click_titlebar
 | 
			
		||||
meta_prefs_get_action_right_click_titlebar
 | 
			
		||||
meta_prefs_set_num_workspaces
 | 
			
		||||
meta_prefs_get_workspace_name
 | 
			
		||||
meta_prefs_change_workspace_name
 | 
			
		||||
meta_prefs_get_cursor_theme
 | 
			
		||||
meta_prefs_get_cursor_size
 | 
			
		||||
meta_prefs_get_compositing_manager
 | 
			
		||||
meta_prefs_get_force_fullscreen
 | 
			
		||||
meta_prefs_set_force_fullscreen
 | 
			
		||||
meta_prefs_get_workspaces_only_on_primary
 | 
			
		||||
meta_prefs_get_no_tab_popup
 | 
			
		||||
meta_prefs_set_no_tab_popup
 | 
			
		||||
meta_prefs_get_draggable_border_width
 | 
			
		||||
meta_prefs_get_ignore_request_hide_titlebar
 | 
			
		||||
meta_prefs_set_ignore_request_hide_titlebar
 | 
			
		||||
MetaKeyBindingAction
 | 
			
		||||
MetaKeyBindingFlags
 | 
			
		||||
MetaKeyCombo
 | 
			
		||||
MetaKeyHandlerFunc
 | 
			
		||||
meta_prefs_get_keybindings
 | 
			
		||||
meta_prefs_get_keybinding_action
 | 
			
		||||
meta_prefs_get_window_binding
 | 
			
		||||
meta_prefs_get_overlay_binding
 | 
			
		||||
meta_prefs_get_visual_bell
 | 
			
		||||
meta_prefs_bell_is_audible
 | 
			
		||||
meta_prefs_get_visual_bell_type
 | 
			
		||||
MetaKeyHandler
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
meta_key_binding_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>screen</FILE>
 | 
			
		||||
MetaScreen
 | 
			
		||||
MetaScreenClass
 | 
			
		||||
meta_screen_get_screen_number
 | 
			
		||||
meta_screen_get_display
 | 
			
		||||
meta_screen_get_xroot
 | 
			
		||||
meta_screen_get_size
 | 
			
		||||
meta_screen_get_compositor_data
 | 
			
		||||
meta_screen_set_compositor_data
 | 
			
		||||
meta_screen_for_x_screen
 | 
			
		||||
meta_screen_set_cm_selection
 | 
			
		||||
meta_screen_unset_cm_selection
 | 
			
		||||
meta_screen_get_startup_sequences
 | 
			
		||||
meta_screen_get_workspaces
 | 
			
		||||
meta_screen_get_n_workspaces
 | 
			
		||||
meta_screen_get_workspace_by_index
 | 
			
		||||
meta_screen_remove_workspace
 | 
			
		||||
meta_screen_append_new_workspace
 | 
			
		||||
meta_screen_get_active_workspace_index
 | 
			
		||||
meta_screen_get_active_workspace
 | 
			
		||||
meta_screen_get_n_monitors
 | 
			
		||||
meta_screen_get_primary_monitor
 | 
			
		||||
meta_screen_get_current_monitor
 | 
			
		||||
meta_screen_get_monitor_geometry
 | 
			
		||||
meta_screen_get_monitor_index_for_rect
 | 
			
		||||
meta_screen_focus_default_window
 | 
			
		||||
MetaScreenCorner
 | 
			
		||||
meta_screen_override_workspace_layout
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_IS_SCREEN
 | 
			
		||||
META_IS_SCREEN_CLASS
 | 
			
		||||
META_SCREEN
 | 
			
		||||
META_SCREEN_CLASS
 | 
			
		||||
META_SCREEN_GET_CLASS
 | 
			
		||||
META_TYPE_SCREEN
 | 
			
		||||
meta_screen_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>util</FILE>
 | 
			
		||||
meta_is_verbose
 | 
			
		||||
meta_set_verbose
 | 
			
		||||
meta_is_debugging
 | 
			
		||||
meta_set_debugging
 | 
			
		||||
meta_is_syncing
 | 
			
		||||
meta_set_syncing
 | 
			
		||||
meta_set_replace_current_wm
 | 
			
		||||
meta_debug_spew_real
 | 
			
		||||
meta_verbose_real
 | 
			
		||||
meta_bug
 | 
			
		||||
meta_warning
 | 
			
		||||
meta_fatal
 | 
			
		||||
MetaDebugTopic
 | 
			
		||||
meta_topic_real
 | 
			
		||||
meta_add_verbose_topic
 | 
			
		||||
meta_remove_verbose_topic
 | 
			
		||||
meta_push_no_msg_prefix
 | 
			
		||||
meta_pop_no_msg_prefix
 | 
			
		||||
meta_unsigned_long_equal
 | 
			
		||||
meta_unsigned_long_hash
 | 
			
		||||
meta_frame_type_to_string
 | 
			
		||||
meta_gravity_to_string
 | 
			
		||||
_
 | 
			
		||||
N_
 | 
			
		||||
meta_g_utf8_strndup
 | 
			
		||||
meta_free_gslist_and_elements
 | 
			
		||||
meta_show_dialog
 | 
			
		||||
meta_debug_spew
 | 
			
		||||
meta_verbose
 | 
			
		||||
meta_topic
 | 
			
		||||
MetaLaterType
 | 
			
		||||
meta_later_add
 | 
			
		||||
meta_later_remove
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>window</FILE>
 | 
			
		||||
MetaWindow
 | 
			
		||||
MetaWindowClass
 | 
			
		||||
MetaWindowType
 | 
			
		||||
MetaMaximizeFlags
 | 
			
		||||
meta_window_get_frame
 | 
			
		||||
meta_window_has_focus
 | 
			
		||||
meta_window_appears_focused
 | 
			
		||||
meta_window_is_shaded
 | 
			
		||||
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_frame_rect
 | 
			
		||||
meta_window_client_rect_to_frame_rect
 | 
			
		||||
meta_window_frame_rect_to_client_rect
 | 
			
		||||
meta_window_get_screen
 | 
			
		||||
meta_window_get_display
 | 
			
		||||
meta_window_get_xwindow
 | 
			
		||||
meta_window_get_window_type
 | 
			
		||||
meta_window_get_window_type_atom
 | 
			
		||||
meta_window_get_workspace
 | 
			
		||||
meta_window_get_monitor
 | 
			
		||||
meta_window_is_on_all_workspaces
 | 
			
		||||
meta_window_located_on_workspace
 | 
			
		||||
meta_window_is_hidden
 | 
			
		||||
meta_window_activate
 | 
			
		||||
meta_window_activate_with_workspace
 | 
			
		||||
meta_window_get_description
 | 
			
		||||
meta_window_get_wm_class
 | 
			
		||||
meta_window_get_wm_class_instance
 | 
			
		||||
meta_window_showing_on_its_workspace
 | 
			
		||||
meta_window_get_gtk_application_id
 | 
			
		||||
meta_window_get_gtk_unique_bus_name
 | 
			
		||||
meta_window_get_gtk_application_object_path
 | 
			
		||||
meta_window_get_gtk_window_object_path
 | 
			
		||||
meta_window_get_gtk_app_menu_object_path
 | 
			
		||||
meta_window_get_gtk_menubar_object_path
 | 
			
		||||
meta_window_move
 | 
			
		||||
meta_window_move_frame
 | 
			
		||||
meta_window_move_resize_frame
 | 
			
		||||
meta_window_move_to_monitor
 | 
			
		||||
meta_window_resize
 | 
			
		||||
meta_window_set_demands_attention
 | 
			
		||||
meta_window_unset_demands_attention
 | 
			
		||||
meta_window_get_startup_id
 | 
			
		||||
meta_window_change_workspace_by_index
 | 
			
		||||
meta_window_change_workspace
 | 
			
		||||
meta_window_get_compositor_private
 | 
			
		||||
meta_window_set_compositor_private
 | 
			
		||||
meta_window_configure_notify
 | 
			
		||||
meta_window_get_role
 | 
			
		||||
meta_window_get_layer
 | 
			
		||||
meta_window_find_root_ancestor
 | 
			
		||||
meta_window_is_ancestor_of_transient
 | 
			
		||||
MetaWindowForeachFunc
 | 
			
		||||
meta_window_foreach_transient
 | 
			
		||||
meta_window_foreach_ancestor
 | 
			
		||||
meta_window_get_maximized
 | 
			
		||||
meta_window_is_fullscreen
 | 
			
		||||
meta_window_is_on_primary_monitor
 | 
			
		||||
meta_window_requested_bypass_compositor
 | 
			
		||||
meta_window_requested_dont_bypass_compositor
 | 
			
		||||
meta_window_is_mapped
 | 
			
		||||
meta_window_toplevel_is_mapped
 | 
			
		||||
meta_window_get_icon_geometry
 | 
			
		||||
meta_window_set_icon_geometry
 | 
			
		||||
meta_window_maximize
 | 
			
		||||
meta_window_unmaximize
 | 
			
		||||
meta_window_minimize
 | 
			
		||||
meta_window_unminimize
 | 
			
		||||
meta_window_raise
 | 
			
		||||
meta_window_lower
 | 
			
		||||
meta_window_get_title
 | 
			
		||||
meta_window_get_transient_for
 | 
			
		||||
meta_window_get_transient_for_as_xid
 | 
			
		||||
meta_window_delete
 | 
			
		||||
meta_window_get_stable_sequence
 | 
			
		||||
meta_window_get_user_time
 | 
			
		||||
meta_window_get_pid
 | 
			
		||||
meta_window_get_client_machine
 | 
			
		||||
meta_window_is_remote
 | 
			
		||||
meta_window_is_modal
 | 
			
		||||
meta_window_is_attached_dialog
 | 
			
		||||
meta_window_get_mutter_hints
 | 
			
		||||
meta_window_get_frame_type
 | 
			
		||||
meta_window_get_frame_bounds
 | 
			
		||||
meta_window_get_tile_match
 | 
			
		||||
meta_window_make_fullscreen
 | 
			
		||||
meta_window_unmake_fullscreen
 | 
			
		||||
meta_window_make_above
 | 
			
		||||
meta_window_unmake_above
 | 
			
		||||
meta_window_shade
 | 
			
		||||
meta_window_unshade
 | 
			
		||||
meta_window_stick
 | 
			
		||||
meta_window_unstick
 | 
			
		||||
meta_window_kill
 | 
			
		||||
meta_window_focus
 | 
			
		||||
meta_window_check_alive
 | 
			
		||||
meta_window_get_work_area_current_monitor
 | 
			
		||||
meta_window_get_work_area_for_monitor
 | 
			
		||||
meta_window_get_work_area_all_monitors
 | 
			
		||||
meta_window_begin_grab_op
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_IS_WINDOW
 | 
			
		||||
META_IS_WINDOW_CLASS
 | 
			
		||||
META_TYPE_WINDOW
 | 
			
		||||
META_WINDOW
 | 
			
		||||
META_WINDOW_CLASS
 | 
			
		||||
META_WINDOW_GET_CLASS
 | 
			
		||||
meta_window_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
<SECTION>
 | 
			
		||||
<FILE>workspace</FILE>
 | 
			
		||||
MetaWorkspace
 | 
			
		||||
MetaWorkspaceClass
 | 
			
		||||
meta_workspace_index
 | 
			
		||||
meta_workspace_get_screen
 | 
			
		||||
meta_workspace_list_windows
 | 
			
		||||
meta_workspace_get_work_area_for_monitor
 | 
			
		||||
meta_workspace_get_work_area_all_monitors
 | 
			
		||||
meta_workspace_activate
 | 
			
		||||
meta_workspace_activate_with_focus
 | 
			
		||||
meta_workspace_update_window_hints
 | 
			
		||||
meta_workspace_set_builtin_struts
 | 
			
		||||
meta_workspace_get_neighbor
 | 
			
		||||
<SUBSECTION Standard>
 | 
			
		||||
META_IS_WORKSPACE
 | 
			
		||||
META_IS_WORKSPACE_CLASS
 | 
			
		||||
META_TYPE_WORKSPACE
 | 
			
		||||
META_WORKSPACE
 | 
			
		||||
META_WORKSPACE_CLASS
 | 
			
		||||
META_WORKSPACE_GET_CLASS
 | 
			
		||||
meta_workspace_get_type
 | 
			
		||||
</SECTION>
 | 
			
		||||
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
<part id="mutter-overview">
 | 
			
		||||
 | 
			
		||||
  <title>Overview</title>
 | 
			
		||||
 | 
			
		||||
  <partintro>
 | 
			
		||||
 | 
			
		||||
    <para>Mutter is a GObject-based library for creating compositing window managers.</para>
 | 
			
		||||
 | 
			
		||||
    <para>Compositors that wish to use Mutter must implement a subclass of #MetaPlugin and register it with meta_plugin_manager_set_plugin_type() before calling meta_init() but after g_type_init().</para>
 | 
			
		||||
 | 
			
		||||
    <para>#MetaPlugin provides virtual functions that allow to override default behavior in the window management code, such as the effect to perform when a window is created or when switching workspaces.</para>
 | 
			
		||||
 | 
			
		||||
  </partintro>
 | 
			
		||||
 | 
			
		||||
</part>
 | 
			
		||||
@@ -1,100 +0,0 @@
 | 
			
		||||
<part id="running-mutter">
 | 
			
		||||
 | 
			
		||||
  <title>Running Mutter</title>
 | 
			
		||||
 | 
			
		||||
  <partintro>
 | 
			
		||||
 | 
			
		||||
    <section id="environment-variables">
 | 
			
		||||
      <title>Environment Variables</title>
 | 
			
		||||
 | 
			
		||||
      <para>
 | 
			
		||||
        Mutter automatically checks environment variables during
 | 
			
		||||
        its initialization. These environment variables are meant
 | 
			
		||||
        as debug tools or overrides for default behaviours:
 | 
			
		||||
      </para>
 | 
			
		||||
 | 
			
		||||
      <variablelist>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_VERBOSE</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Enable verbose mode, in which more information is printed to the console. Mutter needs to be built with the --enable-verbose-mode option (enabled by default). For more fine-grained control of the output, see meta_add_verbose_topic().</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_DEBUG</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Traps and prints X errors to the console.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_G_FATAL_WARNINGS</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Causes any logging from the domains Mutter, Gtk, Gdk, Pango or GLib to terminate the process (only when using the log functions in GLib).</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_USE_LOGFILE</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Log all messages to a temporary file.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_DEBUG_XINERAMA</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Log extra information about support of the XINERAMA extension.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_DEBUG_SM</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Log extra information about session management.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_DEBUG_BUTTON_GRABS</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Log extra information about button grabs.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_SYNC</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Call XSync after each X call.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_DISPLAY</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Name of the X11 display to use.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>META_DISABLE_MIPMAPS</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Disable use of mipmaps for the textures that back window pixmaps.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_USE_STATIC_GRAVITY</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Enable support for clients with static bit-gravity.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_WM_CLASS_FILTER</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Comma-separated list of WM_CLASS names to which to restrict Mutter to.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
        <varlistentry>
 | 
			
		||||
          <term>MUTTER_DISABLE_FALLBACK_COLOR</term>
 | 
			
		||||
          <listitem>
 | 
			
		||||
            <para>Disable fallback for themed colors, for easier detection of typographical errors.</para>
 | 
			
		||||
          </listitem>
 | 
			
		||||
        </varlistentry>
 | 
			
		||||
      </variablelist>
 | 
			
		||||
 | 
			
		||||
    </section>
 | 
			
		||||
 | 
			
		||||
  </partintro>
 | 
			
		||||
</part>
 | 
			
		||||
							
								
								
									
										66
									
								
								po/cs.po
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								po/cs.po
									
									
									
									
									
								
							@@ -30,91 +30,91 @@ msgstr "Navigace"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:2
 | 
			
		||||
msgid "Move window to workspace 1"
 | 
			
		||||
msgstr "Přesunout okno na plochu 1"
 | 
			
		||||
msgstr "Přesunout okno na pracovní plochu 1"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:3
 | 
			
		||||
msgid "Move window to workspace 2"
 | 
			
		||||
msgstr "Přesunout okno na plochu 2"
 | 
			
		||||
msgstr "Přesunout okno na pracovní plochu 2"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:4
 | 
			
		||||
msgid "Move window to workspace 3"
 | 
			
		||||
msgstr "Přesunout okno na plochu 3"
 | 
			
		||||
msgstr "Přesunout okno na pracovní plochu 3"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:5
 | 
			
		||||
msgid "Move window to workspace 4"
 | 
			
		||||
msgstr "Přesunout okno na plochu 4"
 | 
			
		||||
msgstr "Přesunout okno na pracovní plochu 4"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:6
 | 
			
		||||
msgid "Move window to last workspace"
 | 
			
		||||
msgstr "Přesunout okno na poslední plochu"
 | 
			
		||||
msgstr "Přesunout okno na poslední pracovní plochu"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:7
 | 
			
		||||
msgid "Move window one workspace to the left"
 | 
			
		||||
msgstr "Přesunout okno o plochu doleva"
 | 
			
		||||
msgstr "Přesunout okno o jednu pracovní plochu doleva"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:8
 | 
			
		||||
msgid "Move window one workspace to the right"
 | 
			
		||||
msgstr "Přesunout okno o plochu doprava"
 | 
			
		||||
msgstr "Přesunout okno o jednu pracovní plochu doprava"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:9
 | 
			
		||||
msgid "Move window one workspace up"
 | 
			
		||||
msgstr "Přesunout okno o plochu nahoru"
 | 
			
		||||
msgstr "Přesunout okno o jednu pracovní plochu nahoru"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:10
 | 
			
		||||
msgid "Move window one workspace down"
 | 
			
		||||
msgstr "Přesunout okno o plochu dolů"
 | 
			
		||||
msgstr "Přesunout okno o jednu pracovní plochu dolů"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:11
 | 
			
		||||
msgid "Move window one monitor to the left"
 | 
			
		||||
msgstr "Přesunout okno o monitor doleva"
 | 
			
		||||
msgstr "Přesunout okno o jeden monitor doleva"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:12
 | 
			
		||||
msgid "Move window one monitor to the right"
 | 
			
		||||
msgstr "Přesunout okno o monitor doprava"
 | 
			
		||||
msgstr "Přesunout okno o jeden monitor doprava"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:13
 | 
			
		||||
msgid "Move window one monitor up"
 | 
			
		||||
msgstr "Přesunout okno o monitor nahoru"
 | 
			
		||||
msgstr "Přesunout okno o jeden monitor nahoru"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:14
 | 
			
		||||
msgid "Move window one monitor down"
 | 
			
		||||
msgstr "Přesunout okno o monitor dolů"
 | 
			
		||||
msgstr "Přesunout okno o jeden monitor dolů"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:15
 | 
			
		||||
msgid "Switch applications"
 | 
			
		||||
msgstr "Přepnout mezi aplikacemi"
 | 
			
		||||
msgstr "Přepnout do jiné aplikace"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:16
 | 
			
		||||
msgid "Switch to previous application"
 | 
			
		||||
msgstr "Přepnout na předchozí aplikaci"
 | 
			
		||||
msgstr "Přepnout do předchozí aplikaci"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:17
 | 
			
		||||
msgid "Switch windows"
 | 
			
		||||
msgstr "Přepnout mezi okny"
 | 
			
		||||
msgstr "Přepnout do jiného okna"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:18
 | 
			
		||||
msgid "Switch to previous window"
 | 
			
		||||
msgstr "Přepnout na předchozí okno"
 | 
			
		||||
msgstr "Přepnout do minulého okna"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:19
 | 
			
		||||
msgid "Switch windows of an application"
 | 
			
		||||
msgstr "Přepnout mezi okny aplikace"
 | 
			
		||||
msgstr "Přepnout do jiného okna aplikace"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:20
 | 
			
		||||
msgid "Switch to previous window of an application"
 | 
			
		||||
msgstr "Přepnout na předchozí okno aplikace"
 | 
			
		||||
msgstr "Přepnout do předchozího okna aplikace"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:21
 | 
			
		||||
msgid "Switch system controls"
 | 
			
		||||
msgstr "Přepnout mezi systémovými ovládacími prvky"
 | 
			
		||||
msgstr "Přepnout na systémový ovládací prvek"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:22
 | 
			
		||||
msgid "Switch to previous system control"
 | 
			
		||||
msgstr "Přepnout na předchozí systémové ovládací prvky"
 | 
			
		||||
msgstr "Přepnout na minulý systémový ovládací prvek"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:23
 | 
			
		||||
msgid "Switch windows directly"
 | 
			
		||||
msgstr "Přepnout přímo mezi okny"
 | 
			
		||||
msgstr "Přepnout do minulého okna"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:24
 | 
			
		||||
msgid "Switch directly to previous window"
 | 
			
		||||
@@ -122,15 +122,15 @@ msgstr "Přepnout přímo na předchozí okno"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:25
 | 
			
		||||
msgid "Switch windows of an app directly"
 | 
			
		||||
msgstr "Přepnout přímo mezi okny aplikace"
 | 
			
		||||
msgstr "Přepnout do jiného okna aplikace"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:26
 | 
			
		||||
msgid "Switch directly to previous window of an app"
 | 
			
		||||
msgstr "Přepnout přímo na předchozí okno aplikace"
 | 
			
		||||
msgstr "Přepnout do předchozího okna aplikace"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:27
 | 
			
		||||
msgid "Switch system controls directly"
 | 
			
		||||
msgstr "Přepnout přímo mezi systémovými ovládacími prvky"
 | 
			
		||||
msgstr "Přepnout na minulý systémový ovládací prvek"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-navigation.xml.in.h:28
 | 
			
		||||
msgid "Switch directly to previous system control"
 | 
			
		||||
@@ -198,7 +198,7 @@ msgstr "Aktivovat nabídku okna"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:3
 | 
			
		||||
msgid "Toggle fullscreen mode"
 | 
			
		||||
msgstr "Přepnout režim na celou obrazovku"
 | 
			
		||||
msgstr "Přepnout režim celé obrazovky"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:4
 | 
			
		||||
msgid "Toggle maximization state"
 | 
			
		||||
@@ -210,7 +210,7 @@ msgstr "Maximalizovat okno"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:6
 | 
			
		||||
msgid "Restore window"
 | 
			
		||||
msgstr "Obnovit okno"
 | 
			
		||||
msgstr "Obnovit velikost okna"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:7
 | 
			
		||||
msgid "Toggle shaded state"
 | 
			
		||||
@@ -234,20 +234,20 @@ msgstr "Změnit velikost okna"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:12
 | 
			
		||||
msgid "Toggle window on all workspaces or one"
 | 
			
		||||
msgstr "Přepnout výskyt okna na všech plochách nebo jen na jedné"
 | 
			
		||||
msgstr "Přepnout okno na všechny/jednu pracovní plochu"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:13
 | 
			
		||||
msgid "Raise window if covered, otherwise lower it"
 | 
			
		||||
msgstr ""
 | 
			
		||||
"Přenést okno do popředí, pokud je zakryté, jinak jej odsunout do pozadí"
 | 
			
		||||
"Když je okno zakryté vynést jej do popředí, jinak odsunout do pozadí"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:14
 | 
			
		||||
msgid "Raise window above other windows"
 | 
			
		||||
msgstr "Přenést okno do popředí nad ostatní okna"
 | 
			
		||||
msgstr "Vynést okno do popředí nad ostatní okna"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:15
 | 
			
		||||
msgid "Lower window below other windows"
 | 
			
		||||
msgstr "Odsunout okno do pozadí pod ostatní okna"
 | 
			
		||||
msgstr "Odsunout okno do pozadí za ostatní okna"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:16
 | 
			
		||||
msgid "Maximize window vertically"
 | 
			
		||||
@@ -259,11 +259,11 @@ msgstr "Maximalizovat okno vodorovně"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:18
 | 
			
		||||
msgid "View split on left"
 | 
			
		||||
msgstr "Zobrazit rozdělení nalevo"
 | 
			
		||||
msgstr "Rozdělit okno přes levou půlku obrazovky"
 | 
			
		||||
 | 
			
		||||
#: ../data/50-mutter-windows.xml.in.h:19
 | 
			
		||||
msgid "View split on right"
 | 
			
		||||
msgstr "Zobrazit rozdělení napravo"
 | 
			
		||||
msgstr "Rozdělit okno přes pravou půlku obrazovky"
 | 
			
		||||
 | 
			
		||||
#: ../data/mutter.desktop.in.h:1
 | 
			
		||||
msgid "Mutter"
 | 
			
		||||
 
 | 
			
		||||
@@ -41,9 +41,6 @@ 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
 | 
			
		||||
 | 
			
		||||
noinst_PROGRAMS += testboxes
 | 
			
		||||
 
 | 
			
		||||
@@ -39,8 +39,8 @@ mutter_built_sources = \
 | 
			
		||||
	$(dbus_idle_built_sources)		\
 | 
			
		||||
	$(dbus_display_config_built_sources)	\
 | 
			
		||||
	$(dbus_login1_built_sources)		\
 | 
			
		||||
	mutter-enum-types.h 			\
 | 
			
		||||
	mutter-enum-types.c			\
 | 
			
		||||
	meta/meta-enum-types.h			\
 | 
			
		||||
	meta-enum-types.c			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if HAVE_WAYLAND
 | 
			
		||||
@@ -132,7 +132,6 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	compositor/meta-plugin-manager.c	\
 | 
			
		||||
	compositor/meta-plugin-manager.h	\
 | 
			
		||||
	compositor/meta-shadow-factory.c	\
 | 
			
		||||
	compositor/meta-shadow-factory-private.h	\
 | 
			
		||||
	compositor/meta-shaped-texture.c	\
 | 
			
		||||
	compositor/meta-shaped-texture-private.h 	\
 | 
			
		||||
	compositor/meta-surface-actor.c		\
 | 
			
		||||
@@ -148,7 +147,6 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	compositor/meta-window-group.c		\
 | 
			
		||||
	compositor/meta-window-group.h		\
 | 
			
		||||
	compositor/meta-window-shape.c		\
 | 
			
		||||
	compositor/meta-window-shape.h		\
 | 
			
		||||
	compositor/region-utils.c		\
 | 
			
		||||
	compositor/region-utils.h		\
 | 
			
		||||
	meta/compositor.h			\
 | 
			
		||||
@@ -159,6 +157,7 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	meta/meta-plugin.h			\
 | 
			
		||||
	meta/meta-shadow-factory.h		\
 | 
			
		||||
	meta/meta-window-actor.h		\
 | 
			
		||||
	meta/meta-window-shape.h		\
 | 
			
		||||
	meta/compositor-mutter.h 		\
 | 
			
		||||
	core/constraints.c			\
 | 
			
		||||
	core/constraints.h			\
 | 
			
		||||
@@ -210,8 +209,6 @@ libmutter_la_SOURCES =				\
 | 
			
		||||
	meta/theme.h				\
 | 
			
		||||
	ui/theme-private.h			\
 | 
			
		||||
	ui/ui.c					\
 | 
			
		||||
	x11/async-getprop.c			\
 | 
			
		||||
	x11/async-getprop.h			\
 | 
			
		||||
	x11/atomnames.h				\
 | 
			
		||||
	x11/events.c				\
 | 
			
		||||
	x11/events.h				\
 | 
			
		||||
@@ -243,6 +240,8 @@ libmutter_la_SOURCES +=				\
 | 
			
		||||
	wayland/meta-wayland-private.h		\
 | 
			
		||||
	wayland/meta-xwayland.c			\
 | 
			
		||||
	wayland/meta-xwayland.h			\
 | 
			
		||||
	wayland/meta-xwayland-selection.c	\
 | 
			
		||||
	wayland/meta-xwayland-selection-private.h	\
 | 
			
		||||
	wayland/meta-xwayland-private.h		\
 | 
			
		||||
	wayland/meta-wayland-buffer.c      	\
 | 
			
		||||
	wayland/meta-wayland-buffer.h      	\
 | 
			
		||||
@@ -250,6 +249,7 @@ libmutter_la_SOURCES +=				\
 | 
			
		||||
	wayland/meta-wayland-region.h      	\
 | 
			
		||||
	wayland/meta-wayland-data-device.c      \
 | 
			
		||||
	wayland/meta-wayland-data-device.h      \
 | 
			
		||||
	wayland/meta-wayland-data-device-private.h	\
 | 
			
		||||
	wayland/meta-wayland-keyboard.c		\
 | 
			
		||||
	wayland/meta-wayland-keyboard.h		\
 | 
			
		||||
	wayland/meta-wayland-pointer.c		\
 | 
			
		||||
@@ -323,6 +323,7 @@ libmutterinclude_headers =			\
 | 
			
		||||
	meta/meta-shaped-texture.h		\
 | 
			
		||||
	meta/meta-shadow-factory.h		\
 | 
			
		||||
	meta/meta-window-actor.h		\
 | 
			
		||||
	meta/meta-window-shape.h		\
 | 
			
		||||
	meta/prefs.h				\
 | 
			
		||||
	meta/screen.h				\
 | 
			
		||||
	meta/theme.h				\
 | 
			
		||||
@@ -333,7 +334,9 @@ libmutterinclude_headers =			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
libmutterinclude_built_headers =		\
 | 
			
		||||
	meta/meta-version.h
 | 
			
		||||
	meta/meta-version.h			\
 | 
			
		||||
	meta/meta-enum-types.h			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
libmutterinclude_base_headers =			\
 | 
			
		||||
	$(libmutterinclude_headers)		\
 | 
			
		||||
@@ -385,7 +388,6 @@ Meta-$(api_version).gir: libmutter.la
 | 
			
		||||
@META_GIR@_CFLAGS = $(AM_CPPFLAGS)
 | 
			
		||||
@META_GIR@_LIBS = libmutter.la
 | 
			
		||||
@META_GIR@_FILES =				\
 | 
			
		||||
	mutter-enum-types.h			\
 | 
			
		||||
	$(libmutterinclude_base_headers)	\
 | 
			
		||||
	$(filter %.c,$(libmutter_la_SOURCES) $(nodist_libmutter_la_SOURCES))
 | 
			
		||||
@META_GIR@_SCANNERFLAGS = --warn-all --warn-error
 | 
			
		||||
@@ -408,8 +410,8 @@ pkgconfig_DATA = libmutter.pc
 | 
			
		||||
EXTRA_DIST +=					\
 | 
			
		||||
	$(wayland_protocols)			\
 | 
			
		||||
	libmutter.pc.in				\
 | 
			
		||||
	mutter-enum-types.h.in			\
 | 
			
		||||
	mutter-enum-types.c.in			\
 | 
			
		||||
	meta-enum-types.h.in			\
 | 
			
		||||
	meta-enum-types.c.in			\
 | 
			
		||||
	org.freedesktop.login1.xml		\
 | 
			
		||||
	org.gnome.Mutter.DisplayConfig.xml	\
 | 
			
		||||
	org.gnome.Mutter.IdleMonitor.xml	\
 | 
			
		||||
@@ -419,26 +421,26 @@ BUILT_SOURCES =					\
 | 
			
		||||
	$(mutter_built_sources)			\
 | 
			
		||||
	$(libmutterinclude_built_headers)
 | 
			
		||||
 | 
			
		||||
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
 | 
			
		||||
MUTTER_STAMP_FILES = stamp-meta-enum-types.h
 | 
			
		||||
CLEANFILES += $(MUTTER_STAMP_FILES)
 | 
			
		||||
 | 
			
		||||
mutter-enum-types.h: stamp-mutter-enum-types.h Makefile
 | 
			
		||||
meta/meta-enum-types.h: stamp-meta-enum-types.h Makefile
 | 
			
		||||
	@true
 | 
			
		||||
stamp-mutter-enum-types.h: $(libmutterinclude_base_headers) mutter-enum-types.h.in
 | 
			
		||||
stamp-meta-enum-types.h: $(libmutterinclude_headers) meta-enum-types.h.in
 | 
			
		||||
	$(AM_V_GEN) ( cd $(srcdir) && \
 | 
			
		||||
	  $(GLIB_MKENUMS) \
 | 
			
		||||
	    --template mutter-enum-types.h.in \
 | 
			
		||||
	    --template meta-enum-types.h.in \
 | 
			
		||||
	  $(libmutterinclude_base_headers) ) >> xgen-teth && \
 | 
			
		||||
	(cmp -s xgen-teth mutter-enum-types.h || cp xgen-teth mutter-enum-types.h) && \
 | 
			
		||||
	(cmp -s xgen-teth meta/meta-enum-types.h || cp xgen-teth meta/meta-enum-types.h) && \
 | 
			
		||||
	rm -f xgen-teth && \
 | 
			
		||||
	echo timestamp > $(@F)
 | 
			
		||||
 | 
			
		||||
mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in
 | 
			
		||||
meta-enum-types.c: stamp-meta-enum-types.h meta-enum-types.c.in
 | 
			
		||||
	  $(AM_V_GEN) ( cd $(srcdir) && \
 | 
			
		||||
	  $(GLIB_MKENUMS) \
 | 
			
		||||
	    --template mutter-enum-types.c.in \
 | 
			
		||||
	    --template meta-enum-types.c.in \
 | 
			
		||||
	  $(libmutterinclude_base_headers) ) >> xgen-tetc && \
 | 
			
		||||
	cp xgen-tetc mutter-enum-types.c && \
 | 
			
		||||
	cp xgen-tetc meta-enum-types.c && \
 | 
			
		||||
	rm -f xgen-tetc
 | 
			
		||||
 | 
			
		||||
dbus_display_config_built_sources = meta-dbus-display-config.c meta-dbus-display-config.h
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
#include "backends/native/meta-barrier-native.h"
 | 
			
		||||
#include "backends/x11/meta-backend-x11.h"
 | 
			
		||||
#include "backends/x11/meta-barrier-x11.h"
 | 
			
		||||
#include "mutter-enum-types.h"
 | 
			
		||||
#include <meta/meta-enum-types.h>
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaBarrier, meta_barrier, G_TYPE_OBJECT)
 | 
			
		||||
G_DEFINE_TYPE (MetaBarrierImpl, meta_barrier_impl, G_TYPE_OBJECT)
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
 | 
			
		||||
#include "meta-cursor.h"
 | 
			
		||||
 | 
			
		||||
#include <X11/Xcursor/Xcursor.h>
 | 
			
		||||
#include <cogl/cogl.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
@@ -42,6 +43,8 @@ typedef struct {
 | 
			
		||||
struct _MetaCursorReference {
 | 
			
		||||
  int ref_count;
 | 
			
		||||
 | 
			
		||||
  int current_frame;
 | 
			
		||||
  XcursorImages *xcursor_images;
 | 
			
		||||
  MetaCursor cursor;
 | 
			
		||||
  MetaCursorImage image;
 | 
			
		||||
};
 | 
			
		||||
@@ -56,4 +59,8 @@ struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
 | 
			
		||||
                                                 int                 *hot_y);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
gboolean meta_cursor_reference_is_animated            (MetaCursorReference *self);
 | 
			
		||||
void     meta_cursor_reference_tick_frame             (MetaCursorReference *self);
 | 
			
		||||
guint    meta_cursor_reference_get_current_frame_time (MetaCursorReference *self);
 | 
			
		||||
 | 
			
		||||
#endif /* META_CURSOR_PRIVATE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -144,6 +144,13 @@ meta_cursor_renderer_set_cursor (MetaCursorRenderer  *renderer,
 | 
			
		||||
  update_cursor (renderer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
  update_cursor (renderer);
 | 
			
		||||
  queue_redraw (renderer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
 | 
			
		||||
                                   int x, int y)
 | 
			
		||||
 
 | 
			
		||||
@@ -61,6 +61,7 @@ void meta_cursor_renderer_set_cursor (MetaCursorRenderer  *renderer,
 | 
			
		||||
 | 
			
		||||
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
 | 
			
		||||
                                        int x, int y);
 | 
			
		||||
void meta_cursor_renderer_force_update (MetaCursorRenderer *renderer);
 | 
			
		||||
 | 
			
		||||
MetaCursorReference * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
 | 
			
		||||
const MetaRectangle * meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer);
 | 
			
		||||
 
 | 
			
		||||
@@ -67,6 +67,8 @@ meta_cursor_image_free (MetaCursorImage *image)
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_reference_free (MetaCursorReference *self)
 | 
			
		||||
{
 | 
			
		||||
  if (self->xcursor_images)
 | 
			
		||||
    XcursorImagesDestroy (self->xcursor_images);
 | 
			
		||||
  meta_cursor_image_free (&self->image);
 | 
			
		||||
  g_slice_free (MetaCursorReference, self);
 | 
			
		||||
}
 | 
			
		||||
@@ -135,12 +137,12 @@ meta_cursor_create_x_cursor (Display    *xdisplay,
 | 
			
		||||
  return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XcursorImage *
 | 
			
		||||
static XcursorImages *
 | 
			
		||||
load_cursor_on_client (MetaCursor cursor)
 | 
			
		||||
{
 | 
			
		||||
  return XcursorLibraryLoadImage (translate_meta_cursor (cursor),
 | 
			
		||||
                                  meta_prefs_get_cursor_theme (),
 | 
			
		||||
                                  meta_prefs_get_cursor_size ());
 | 
			
		||||
  return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
 | 
			
		||||
                                   meta_prefs_get_cursor_theme (),
 | 
			
		||||
                                   meta_prefs_get_cursor_size ());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NATIVE_BACKEND
 | 
			
		||||
@@ -256,6 +258,46 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorImage   *image,
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static XcursorImage *
 | 
			
		||||
meta_cursor_reference_get_current_frame_image (MetaCursorReference *self)
 | 
			
		||||
{
 | 
			
		||||
  return self->xcursor_images->images[self->current_frame];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_cursor_reference_tick_frame (MetaCursorReference *self)
 | 
			
		||||
{
 | 
			
		||||
  XcursorImage *image;
 | 
			
		||||
 | 
			
		||||
  if (!meta_cursor_reference_is_animated (self))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  self->current_frame++;
 | 
			
		||||
 | 
			
		||||
  if (self->current_frame >= self->xcursor_images->nimage)
 | 
			
		||||
    self->current_frame = 0;
 | 
			
		||||
 | 
			
		||||
  meta_cursor_image_free (&self->image);
 | 
			
		||||
  image = meta_cursor_reference_get_current_frame_image (self);
 | 
			
		||||
  meta_cursor_image_load_from_xcursor_image (&self->image, image);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
guint
 | 
			
		||||
meta_cursor_reference_get_current_frame_time (MetaCursorReference *self)
 | 
			
		||||
{
 | 
			
		||||
  if (!meta_cursor_reference_is_animated (self))
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  return self->xcursor_images->images[self->current_frame]->delay;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_cursor_reference_is_animated (MetaCursorReference *self)
 | 
			
		||||
{
 | 
			
		||||
  return (self->xcursor_images &&
 | 
			
		||||
          self->xcursor_images->nimage > 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_cursor_image (MetaCursorReference *cursor)
 | 
			
		||||
{
 | 
			
		||||
@@ -266,12 +308,16 @@ load_cursor_image (MetaCursorReference *cursor)
 | 
			
		||||
   * load this directly. */
 | 
			
		||||
  g_assert (cursor->cursor != META_CURSOR_NONE);
 | 
			
		||||
 | 
			
		||||
  image = load_cursor_on_client (cursor->cursor);
 | 
			
		||||
  if (!image)
 | 
			
		||||
    return;
 | 
			
		||||
  if (!cursor->xcursor_images)
 | 
			
		||||
    {
 | 
			
		||||
      cursor->current_frame = 0;
 | 
			
		||||
      cursor->xcursor_images = load_cursor_on_client (cursor->cursor);
 | 
			
		||||
      if (!cursor->xcursor_images)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  image = meta_cursor_reference_get_current_frame_image (cursor);
 | 
			
		||||
  meta_cursor_image_load_from_xcursor_image (&cursor->image, image);
 | 
			
		||||
  XcursorImageDestroy (image);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaCursorReference *
 | 
			
		||||
 
 | 
			
		||||
@@ -489,8 +489,8 @@ handle_end_element (GMarkupParseContext  *context,
 | 
			
		||||
              }
 | 
			
		||||
            else
 | 
			
		||||
              {
 | 
			
		||||
                if (parser->output.rect.width == 0 &&
 | 
			
		||||
                    parser->output.rect.width == 0)
 | 
			
		||||
                if (parser->output.rect.width == 0 ||
 | 
			
		||||
                    parser->output.rect.height == 0)
 | 
			
		||||
                  parser->output.enabled = FALSE;
 | 
			
		||||
                else
 | 
			
		||||
                  parser->output.enabled = TRUE;
 | 
			
		||||
@@ -886,14 +886,14 @@ apply_configuration (MetaMonitorConfig  *self,
 | 
			
		||||
                     MetaConfiguration  *config,
 | 
			
		||||
		     MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  GPtrArray *crtcs, *outputs;
 | 
			
		||||
  gboolean ret = FALSE;
 | 
			
		||||
  g_autoptr(GPtrArray) crtcs = NULL;
 | 
			
		||||
  g_autoptr(GPtrArray) outputs = NULL;
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  meta_monitor_manager_apply_configuration (manager,
 | 
			
		||||
                                            (MetaCRTCInfo**)crtcs->pdata, crtcs->len,
 | 
			
		||||
@@ -905,12 +905,7 @@ apply_configuration (MetaMonitorConfig  *self,
 | 
			
		||||
   * inside turn_off_laptop_display / apply_configuration_with_lid */
 | 
			
		||||
  self->current_is_for_laptop_lid = FALSE;
 | 
			
		||||
 | 
			
		||||
  ret = TRUE;
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  g_ptr_array_unref (crtcs);
 | 
			
		||||
  g_ptr_array_unref (outputs);
 | 
			
		||||
  return ret;
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
@@ -1079,12 +1074,12 @@ meta_monitor_config_apply_stored (MetaMonitorConfig  *self,
 | 
			
		||||
 * which are internal monitors), or failing that, the one with the
 | 
			
		||||
 * best resolution
 | 
			
		||||
 */
 | 
			
		||||
static MetaOutput *
 | 
			
		||||
static int
 | 
			
		||||
find_primary_output (MetaOutput *outputs,
 | 
			
		||||
                     unsigned    n_outputs)
 | 
			
		||||
{
 | 
			
		||||
  unsigned i;
 | 
			
		||||
  MetaOutput *best;
 | 
			
		||||
  int best;
 | 
			
		||||
  int best_width, best_height;
 | 
			
		||||
 | 
			
		||||
  g_assert (n_outputs >= 1);
 | 
			
		||||
@@ -1092,23 +1087,23 @@ find_primary_output (MetaOutput *outputs,
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (outputs[i].is_primary)
 | 
			
		||||
        return &outputs[i];
 | 
			
		||||
        return i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (output_is_laptop (&outputs[i]))
 | 
			
		||||
        return &outputs[i];
 | 
			
		||||
        return i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  best = NULL;
 | 
			
		||||
  best = -1;
 | 
			
		||||
  best_width = 0; best_height = 0;
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (outputs[i].preferred_mode->width * outputs[i].preferred_mode->height >
 | 
			
		||||
          best_width * best_height)
 | 
			
		||||
        {
 | 
			
		||||
          best = &outputs[i];
 | 
			
		||||
          best = i;
 | 
			
		||||
          best_width = outputs[i].preferred_mode->width;
 | 
			
		||||
          best_height = outputs[i].preferred_mode->height;
 | 
			
		||||
        }
 | 
			
		||||
@@ -1146,7 +1141,7 @@ make_suggested_config (MetaMonitorConfig *self,
 | 
			
		||||
                       MetaConfiguration *config)
 | 
			
		||||
{
 | 
			
		||||
  unsigned int i;
 | 
			
		||||
  MetaOutput *primary;
 | 
			
		||||
  int primary;
 | 
			
		||||
  GList *region = NULL;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (config != NULL, FALSE);
 | 
			
		||||
@@ -1154,7 +1149,7 @@ make_suggested_config (MetaMonitorConfig *self,
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      gboolean is_primary = (&outputs[i] == primary);
 | 
			
		||||
      gboolean is_primary = ((int)i == primary);
 | 
			
		||||
 | 
			
		||||
      if (outputs[i].suggested_x < 0 || outputs[i].suggested_y < 0)
 | 
			
		||||
          return FALSE;
 | 
			
		||||
@@ -1181,6 +1176,81 @@ make_suggested_config (MetaMonitorConfig *self,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
config_one_untiled_output (MetaOutput *outputs,
 | 
			
		||||
                           MetaConfiguration *config,
 | 
			
		||||
                           int idx, gboolean is_primary,
 | 
			
		||||
                           int *x, unsigned long *output_configured_bitmap)
 | 
			
		||||
{
 | 
			
		||||
  MetaOutput *output = &outputs[idx];
 | 
			
		||||
 | 
			
		||||
  if (*output_configured_bitmap & (1 << idx))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  init_config_from_preferred_mode (&config->outputs[idx], output);
 | 
			
		||||
  config->outputs[idx].is_primary = is_primary;
 | 
			
		||||
  config->outputs[idx].rect.x = *x;
 | 
			
		||||
  *x += config->outputs[idx].rect.width;
 | 
			
		||||
  *output_configured_bitmap |= (1 << idx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
config_one_tiled_group (MetaOutput *outputs,
 | 
			
		||||
                        MetaConfiguration *config,
 | 
			
		||||
                        int base_idx, gboolean is_primary,
 | 
			
		||||
                        int n_outputs,
 | 
			
		||||
                        int *x, unsigned long *output_configured_bitmap)
 | 
			
		||||
{
 | 
			
		||||
  guint32 num_h_tile, num_v_tile, ht, vt;
 | 
			
		||||
  int j;
 | 
			
		||||
  int cur_x, cur_y, addx = 0;
 | 
			
		||||
 | 
			
		||||
  if (*output_configured_bitmap & (1 << base_idx))
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
  if (outputs[base_idx].tile_info.group_id == 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  cur_x = cur_y = 0;
 | 
			
		||||
  num_h_tile = outputs[base_idx].tile_info.max_h_tiles;
 | 
			
		||||
  num_v_tile = outputs[base_idx].tile_info.max_v_tiles;
 | 
			
		||||
 | 
			
		||||
  /* iterate over horizontal tiles */
 | 
			
		||||
  cur_x = *x;
 | 
			
		||||
  for (ht = 0; ht < num_h_tile; ht++)
 | 
			
		||||
    {
 | 
			
		||||
      cur_y = 0;
 | 
			
		||||
      addx = 0;
 | 
			
		||||
      for (vt = 0; vt < num_v_tile; vt++)
 | 
			
		||||
        {
 | 
			
		||||
          for (j = 0; j < n_outputs; j++)
 | 
			
		||||
            {
 | 
			
		||||
              if (outputs[j].tile_info.group_id != outputs[base_idx].tile_info.group_id)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
              if (outputs[j].tile_info.loc_h_tile != ht ||
 | 
			
		||||
                  outputs[j].tile_info.loc_v_tile != vt)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
              if (ht == 0 && vt == 0 && is_primary)
 | 
			
		||||
                config->outputs[j].is_primary = TRUE;
 | 
			
		||||
 | 
			
		||||
              init_config_from_preferred_mode (&config->outputs[j], &outputs[j]);
 | 
			
		||||
              config->outputs[j].rect.x = cur_x;
 | 
			
		||||
              config->outputs[j].rect.y = cur_y;
 | 
			
		||||
 | 
			
		||||
              *output_configured_bitmap |= (1 << j);
 | 
			
		||||
              cur_y += outputs[j].tile_info.tile_h;
 | 
			
		||||
              if (vt == 0)
 | 
			
		||||
                addx += outputs[j].tile_info.tile_w;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
      cur_x += addx;
 | 
			
		||||
    }
 | 
			
		||||
  *x = cur_x;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
make_linear_config (MetaMonitorConfig *self,
 | 
			
		||||
                    MetaOutput        *outputs,
 | 
			
		||||
@@ -1189,31 +1259,41 @@ make_linear_config (MetaMonitorConfig *self,
 | 
			
		||||
                    int                max_height,
 | 
			
		||||
                    MetaConfiguration *config)
 | 
			
		||||
{
 | 
			
		||||
  MetaOutput *primary;
 | 
			
		||||
  unsigned long output_configured_bitmap = 0;
 | 
			
		||||
  unsigned i;
 | 
			
		||||
  int x;
 | 
			
		||||
  int primary;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (config != NULL);
 | 
			
		||||
 | 
			
		||||
  primary = find_primary_output (outputs, n_outputs);
 | 
			
		||||
 | 
			
		||||
  x = primary->preferred_mode->width;
 | 
			
		||||
  x = 0;
 | 
			
		||||
  /* set the primary up first at 0 */
 | 
			
		||||
  if (outputs[primary].tile_info.group_id)
 | 
			
		||||
    {
 | 
			
		||||
      config_one_tiled_group (outputs, config, primary, TRUE, n_outputs,
 | 
			
		||||
                              &x, &output_configured_bitmap);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      config_one_untiled_output (outputs, config, primary, TRUE,
 | 
			
		||||
                                 &x, &output_configured_bitmap);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* then add other tiled monitors */
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      gboolean is_primary = (&outputs[i] == primary);
 | 
			
		||||
      config_one_tiled_group (outputs, config, i, FALSE, n_outputs,
 | 
			
		||||
                              &x, &output_configured_bitmap);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
      init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
 | 
			
		||||
      config->outputs[i].is_primary = is_primary;
 | 
			
		||||
  /* then add remaining monitors */
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      config_one_untiled_output (outputs, config, i, FALSE,
 | 
			
		||||
                                 &x, &output_configured_bitmap);
 | 
			
		||||
 | 
			
		||||
      if (is_primary)
 | 
			
		||||
        {
 | 
			
		||||
          config->outputs[i].rect.x = 0;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          config->outputs[i].rect.x = x;
 | 
			
		||||
          x += config->outputs[i].rect.width;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1337,7 +1417,7 @@ ensure_at_least_one_output (MetaMonitorConfig  *self,
 | 
			
		||||
                            unsigned            n_outputs)
 | 
			
		||||
{
 | 
			
		||||
  MetaConfiguration *config;
 | 
			
		||||
  MetaOutput *primary;
 | 
			
		||||
  int primary;
 | 
			
		||||
  unsigned i;
 | 
			
		||||
 | 
			
		||||
  /* Check that we have at least one active output */
 | 
			
		||||
@@ -1355,7 +1435,7 @@ ensure_at_least_one_output (MetaMonitorConfig  *self,
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      gboolean is_primary = (&outputs[i] == primary);
 | 
			
		||||
      gboolean is_primary = ((int)i == primary);
 | 
			
		||||
 | 
			
		||||
      if (is_primary)
 | 
			
		||||
        {
 | 
			
		||||
@@ -1840,7 +1920,6 @@ real_assign_crtcs (CrtcAssignment     *assignment,
 | 
			
		||||
  MetaOutputKey *output_key;
 | 
			
		||||
  MetaOutputConfig *output_config;
 | 
			
		||||
  unsigned int i;
 | 
			
		||||
  gboolean success;
 | 
			
		||||
 | 
			
		||||
  if (output_num == assignment->config->n_outputs)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
@@ -1857,8 +1936,6 @@ real_assign_crtcs (CrtcAssignment     *assignment,
 | 
			
		||||
                                      &crtcs, &n_crtcs,
 | 
			
		||||
                                      &outputs, &n_outputs);
 | 
			
		||||
 | 
			
		||||
  success = FALSE;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_crtcs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaCRTC *crtc = &crtcs[i];
 | 
			
		||||
@@ -1905,10 +1982,7 @@ real_assign_crtcs (CrtcAssignment     *assignment,
 | 
			
		||||
                                              output))
 | 
			
		||||
                    {
 | 
			
		||||
                      if (real_assign_crtcs (assignment, output_num + 1))
 | 
			
		||||
                        {
 | 
			
		||||
                          success = TRUE;
 | 
			
		||||
                          goto out;
 | 
			
		||||
                        }
 | 
			
		||||
                        return TRUE;
 | 
			
		||||
 | 
			
		||||
                      crtc_assignment_unassign (assignment, crtc, output);
 | 
			
		||||
                    }
 | 
			
		||||
@@ -1917,8 +1991,7 @@ real_assign_crtcs (CrtcAssignment     *assignment,
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
  return success;
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,10 @@
 | 
			
		||||
 | 
			
		||||
#include "meta-monitor-manager-dummy.h"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include <meta/util.h>
 | 
			
		||||
 | 
			
		||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
 | 
			
		||||
 | 
			
		||||
struct _MetaMonitorManagerDummy
 | 
			
		||||
@@ -44,9 +48,69 @@ G_DEFINE_TYPE (MetaMonitorManagerDummy, meta_monitor_manager_dummy, META_TYPE_MO
 | 
			
		||||
static void
 | 
			
		||||
meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  unsigned int num_monitors = 1;
 | 
			
		||||
  int *monitor_scales = NULL;
 | 
			
		||||
  const char *num_monitors_str;
 | 
			
		||||
  const char *monitor_scales_str;
 | 
			
		||||
  unsigned int i;
 | 
			
		||||
  int current_x = 0;
 | 
			
		||||
 | 
			
		||||
  /* To control what monitor configuration is generated, there are two available
 | 
			
		||||
   * environmental variables that can be used:
 | 
			
		||||
   *
 | 
			
		||||
   * MUTTER_DEBUG_NUM_DUMMY_MONITORS
 | 
			
		||||
   *
 | 
			
		||||
   * Specifies the number of dummy monitors to include in the stage. Every
 | 
			
		||||
   * monitor is 1024x786 pixels and they are placed on a horizontal row.
 | 
			
		||||
   *
 | 
			
		||||
   * MUTTER_DEBUG_DUMMY_MONITOR_SCALES
 | 
			
		||||
   *
 | 
			
		||||
   * A comma separated list that specifies the scales of the dummy monitors.
 | 
			
		||||
   *
 | 
			
		||||
   * For example the following configuration results in two monitors, where the
 | 
			
		||||
   * first one has the monitor scale 1, and the other the monitor scale 2.
 | 
			
		||||
   *
 | 
			
		||||
   * MUTTER_DEBUG_NUM_DUMMY_MONITORS=2
 | 
			
		||||
   * MUTTER_DEBUG_DUMMY_MONITOR_SCALES=1,2
 | 
			
		||||
   */
 | 
			
		||||
  num_monitors_str = getenv ("MUTTER_DEBUG_NUM_DUMMY_MONITORS");
 | 
			
		||||
  if (num_monitors_str)
 | 
			
		||||
    {
 | 
			
		||||
      num_monitors = g_ascii_strtoll (num_monitors_str, NULL, 10);
 | 
			
		||||
      if (num_monitors <= 0)
 | 
			
		||||
        {
 | 
			
		||||
          meta_warning ("Invalid number of dummy monitors");
 | 
			
		||||
          num_monitors = 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  monitor_scales = g_newa (int, num_monitors);
 | 
			
		||||
  for (i = 0; i < num_monitors; i++)
 | 
			
		||||
    monitor_scales[i] = 1;
 | 
			
		||||
 | 
			
		||||
  monitor_scales_str = getenv ("MUTTER_DEBUG_DUMMY_MONITOR_SCALES");
 | 
			
		||||
  if (monitor_scales_str)
 | 
			
		||||
    {
 | 
			
		||||
      gchar **scales_str_list;
 | 
			
		||||
 | 
			
		||||
      scales_str_list = g_strsplit (monitor_scales_str, ",", -1);
 | 
			
		||||
      if (g_strv_length (scales_str_list) != num_monitors)
 | 
			
		||||
        meta_warning ("Number of specified monitor scales differ from number "
 | 
			
		||||
                      "of monitors (defaults to 1).\n");
 | 
			
		||||
      for (i = 0; i < num_monitors && scales_str_list[i]; i++)
 | 
			
		||||
        {
 | 
			
		||||
          int scale = g_ascii_strtoll (scales_str_list[i], NULL, 10);
 | 
			
		||||
          if (scale == 1 || scale == 2)
 | 
			
		||||
            monitor_scales[i] = scale;
 | 
			
		||||
          else
 | 
			
		||||
            meta_warning ("Invalid dummy monitor scale");
 | 
			
		||||
        }
 | 
			
		||||
      g_strfreev (scales_str_list);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  manager->max_screen_width = 65535;
 | 
			
		||||
  manager->max_screen_height = 65535;
 | 
			
		||||
  manager->screen_width = 1024;
 | 
			
		||||
  manager->screen_width = 1024 * num_monitors;
 | 
			
		||||
  manager->screen_height = 768;
 | 
			
		||||
 | 
			
		||||
  manager->modes = g_new0 (MetaMonitorMode, 1);
 | 
			
		||||
@@ -57,46 +121,52 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
 | 
			
		||||
  manager->modes[0].height = 768;
 | 
			
		||||
  manager->modes[0].refresh_rate = 60.0;
 | 
			
		||||
 | 
			
		||||
  manager->crtcs = g_new0 (MetaCRTC, 1);
 | 
			
		||||
  manager->n_crtcs = 1;
 | 
			
		||||
  manager->crtcs = g_new0 (MetaCRTC, num_monitors);
 | 
			
		||||
  manager->n_crtcs = num_monitors;
 | 
			
		||||
  manager->outputs = g_new0 (MetaOutput, num_monitors);
 | 
			
		||||
  manager->n_outputs = num_monitors;
 | 
			
		||||
 | 
			
		||||
  manager->crtcs[0].crtc_id = 1;
 | 
			
		||||
  manager->crtcs[0].rect.x = 0;
 | 
			
		||||
  manager->crtcs[0].rect.y = 0;
 | 
			
		||||
  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].is_dirty = FALSE;
 | 
			
		||||
  manager->crtcs[0].logical_monitor = NULL;
 | 
			
		||||
  for (i = 0; i < num_monitors; i++)
 | 
			
		||||
    {
 | 
			
		||||
      manager->crtcs[i].crtc_id = i + 1;
 | 
			
		||||
      manager->crtcs[i].rect.x = current_x;
 | 
			
		||||
      manager->crtcs[i].rect.y = 0;
 | 
			
		||||
      manager->crtcs[i].rect.width = manager->modes[0].width;
 | 
			
		||||
      manager->crtcs[i].rect.height = manager->modes[0].height;
 | 
			
		||||
      manager->crtcs[i].current_mode = &manager->modes[0];
 | 
			
		||||
      manager->crtcs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
 | 
			
		||||
      manager->crtcs[i].all_transforms = ALL_TRANSFORMS;
 | 
			
		||||
      manager->crtcs[i].is_dirty = FALSE;
 | 
			
		||||
      manager->crtcs[i].logical_monitor = NULL;
 | 
			
		||||
 | 
			
		||||
  manager->outputs = g_new0 (MetaOutput, 1);
 | 
			
		||||
  manager->n_outputs = 1;
 | 
			
		||||
      current_x += manager->crtcs[i].rect.width;
 | 
			
		||||
 | 
			
		||||
  manager->outputs[0].crtc = &manager->crtcs[0];
 | 
			
		||||
  manager->outputs[0].winsys_id = 1;
 | 
			
		||||
  manager->outputs[0].name = g_strdup ("LVDS");
 | 
			
		||||
  manager->outputs[0].vendor = g_strdup ("MetaProducts Inc.");
 | 
			
		||||
  manager->outputs[0].product = g_strdup ("unknown");
 | 
			
		||||
  manager->outputs[0].serial = g_strdup ("0xC0FFEE");
 | 
			
		||||
  manager->outputs[0].width_mm = 222;
 | 
			
		||||
  manager->outputs[0].height_mm = 125;
 | 
			
		||||
  manager->outputs[0].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
 | 
			
		||||
  manager->outputs[0].preferred_mode = &manager->modes[0];
 | 
			
		||||
  manager->outputs[0].n_modes = 1;
 | 
			
		||||
  manager->outputs[0].modes = g_new0 (MetaMonitorMode *, 1);
 | 
			
		||||
  manager->outputs[0].modes[0] = &manager->modes[0];
 | 
			
		||||
  manager->outputs[0].n_possible_crtcs = 1;
 | 
			
		||||
  manager->outputs[0].possible_crtcs = g_new0 (MetaCRTC *, 1);
 | 
			
		||||
  manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0];
 | 
			
		||||
  manager->outputs[0].n_possible_clones = 0;
 | 
			
		||||
  manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0);
 | 
			
		||||
  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;
 | 
			
		||||
      manager->outputs[i].crtc = &manager->crtcs[i];
 | 
			
		||||
      manager->outputs[i].winsys_id = i + 1;
 | 
			
		||||
      manager->outputs[i].name = g_strdup_printf ("LVDS%d", i + 1);
 | 
			
		||||
      manager->outputs[i].vendor = g_strdup ("MetaProducts Inc.");
 | 
			
		||||
      manager->outputs[i].product = g_strdup ("unknown");
 | 
			
		||||
      manager->outputs[i].serial = g_strdup ("0xC0FFEE");
 | 
			
		||||
      manager->outputs[i].suggested_x = -1;
 | 
			
		||||
      manager->outputs[i].suggested_y = -1;
 | 
			
		||||
      manager->outputs[i].width_mm = 222;
 | 
			
		||||
      manager->outputs[i].height_mm = 125;
 | 
			
		||||
      manager->outputs[i].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
 | 
			
		||||
      manager->outputs[i].preferred_mode = &manager->modes[0];
 | 
			
		||||
      manager->outputs[i].n_modes = 1;
 | 
			
		||||
      manager->outputs[i].modes = g_new0 (MetaMonitorMode *, 1);
 | 
			
		||||
      manager->outputs[i].modes[0] = &manager->modes[0];
 | 
			
		||||
      manager->outputs[i].n_possible_crtcs = 1;
 | 
			
		||||
      manager->outputs[i].possible_crtcs = g_new0 (MetaCRTC *, 1);
 | 
			
		||||
      manager->outputs[i].possible_crtcs[0] = &manager->crtcs[i];
 | 
			
		||||
      manager->outputs[i].n_possible_clones = 0;
 | 
			
		||||
      manager->outputs[i].possible_clones = g_new0 (MetaOutput *, 0);
 | 
			
		||||
      manager->outputs[i].backlight = -1;
 | 
			
		||||
      manager->outputs[i].backlight_min = 0;
 | 
			
		||||
      manager->outputs[i].backlight_max = 0;
 | 
			
		||||
      manager->outputs[i].connector_type = META_CONNECTOR_TYPE_LVDS;
 | 
			
		||||
      manager->outputs[i].scale = monitor_scales[i];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -56,6 +56,7 @@ typedef struct _MetaMonitorMode MetaMonitorMode;
 | 
			
		||||
typedef struct _MetaMonitorInfo MetaMonitorInfo;
 | 
			
		||||
typedef struct _MetaCRTCInfo MetaCRTCInfo;
 | 
			
		||||
typedef struct _MetaOutputInfo MetaOutputInfo;
 | 
			
		||||
typedef struct _MetaTileInfo MetaTileInfo;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  META_MONITOR_TRANSFORM_NORMAL,
 | 
			
		||||
@@ -89,6 +90,17 @@ typedef enum {
 | 
			
		||||
  META_CONNECTOR_TYPE_DSI = 16,
 | 
			
		||||
} MetaConnectorType;
 | 
			
		||||
 | 
			
		||||
struct _MetaTileInfo {
 | 
			
		||||
  guint32 group_id;
 | 
			
		||||
  guint32 flags;
 | 
			
		||||
  guint32 max_h_tiles;
 | 
			
		||||
  guint32 max_v_tiles;
 | 
			
		||||
  guint32 loc_h_tile;
 | 
			
		||||
  guint32 loc_v_tile;
 | 
			
		||||
  guint32 tile_w;
 | 
			
		||||
  guint32 tile_h;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaOutput
 | 
			
		||||
{
 | 
			
		||||
  /* The CRTC driving this output, NULL if the output is not enabled */
 | 
			
		||||
@@ -133,6 +145,7 @@ struct _MetaOutput
 | 
			
		||||
  gboolean is_primary;
 | 
			
		||||
  gboolean is_presentation;
 | 
			
		||||
  gboolean is_underscanning;
 | 
			
		||||
  gboolean supports_underscanning;
 | 
			
		||||
 | 
			
		||||
  gpointer driver_private;
 | 
			
		||||
  GDestroyNotify driver_notify;
 | 
			
		||||
@@ -141,6 +154,8 @@ struct _MetaOutput
 | 
			
		||||
  gboolean hotplug_mode_update;
 | 
			
		||||
  gint suggested_x;
 | 
			
		||||
  gint suggested_y;
 | 
			
		||||
 | 
			
		||||
  MetaTileInfo tile_info;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaCRTC
 | 
			
		||||
@@ -179,6 +194,7 @@ struct _MetaMonitorMode
 | 
			
		||||
  GDestroyNotify driver_notify;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define META_MAX_OUTPUTS_PER_MONITOR 4
 | 
			
		||||
/**
 | 
			
		||||
 * MetaMonitorInfo:
 | 
			
		||||
 *
 | 
			
		||||
@@ -194,9 +210,14 @@ struct _MetaMonitorInfo
 | 
			
		||||
  int number;
 | 
			
		||||
  int xinerama_index;
 | 
			
		||||
  MetaRectangle rect;
 | 
			
		||||
  /* for tiled monitors these are calculated, from untiled just copied */
 | 
			
		||||
  float refresh_rate;
 | 
			
		||||
  int width_mm;
 | 
			
		||||
  int height_mm;
 | 
			
		||||
  gboolean is_primary;
 | 
			
		||||
  gboolean is_presentation; /* XXX: not yet used */
 | 
			
		||||
  gboolean in_fullscreen;
 | 
			
		||||
  int scale;
 | 
			
		||||
 | 
			
		||||
  /* 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.
 | 
			
		||||
@@ -207,6 +228,12 @@ struct _MetaMonitorInfo
 | 
			
		||||
     the primary one).
 | 
			
		||||
  */
 | 
			
		||||
  glong winsys_id;
 | 
			
		||||
 | 
			
		||||
  guint32 tile_group_id;
 | 
			
		||||
 | 
			
		||||
  int monitor_winsys_xid;
 | 
			
		||||
  int n_outputs;
 | 
			
		||||
  MetaOutput *outputs[META_MAX_OUTPUTS_PER_MONITOR];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -324,6 +351,13 @@ struct _MetaMonitorManagerClass
 | 
			
		||||
                          unsigned short     *,
 | 
			
		||||
                          unsigned short     *,
 | 
			
		||||
                          unsigned short     *);
 | 
			
		||||
 | 
			
		||||
  void (*add_monitor) (MetaMonitorManager *,
 | 
			
		||||
                       MetaMonitorInfo *);
 | 
			
		||||
 | 
			
		||||
  void (*delete_monitor) (MetaMonitorManager *,
 | 
			
		||||
                          int monitor_winsys_xid);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void                meta_monitor_manager_rebuild_derived   (MetaMonitorManager *manager);
 | 
			
		||||
 
 | 
			
		||||
@@ -71,6 +71,98 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * rules for constructing a tiled monitor
 | 
			
		||||
 * 1. find a tile_group_id
 | 
			
		||||
 * 2. iterate over all outputs for that tile group id
 | 
			
		||||
 * 3. see if output has a crtc and if it is configured for the tile size
 | 
			
		||||
 * 4. calculate the total tile size
 | 
			
		||||
 * 5. set tile finished size
 | 
			
		||||
 * 6. check for more tile_group_id
 | 
			
		||||
*/
 | 
			
		||||
static void
 | 
			
		||||
construct_tile_monitor (MetaMonitorManager *manager,
 | 
			
		||||
                        GArray *monitor_infos,
 | 
			
		||||
                        guint32 tile_group_id)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorInfo info;
 | 
			
		||||
  unsigned i;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < monitor_infos->len; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaMonitorInfo *pinfo = &g_array_index (monitor_infos, MetaMonitorInfo, i);
 | 
			
		||||
 | 
			
		||||
      if (pinfo->tile_group_id == tile_group_id)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* didn't find it */
 | 
			
		||||
  info.number = monitor_infos->len;
 | 
			
		||||
  info.tile_group_id = tile_group_id;
 | 
			
		||||
  info.is_presentation = FALSE;
 | 
			
		||||
  info.refresh_rate = 0.0;
 | 
			
		||||
  info.width_mm = 0;
 | 
			
		||||
  info.height_mm = 0;
 | 
			
		||||
  info.is_primary = FALSE;
 | 
			
		||||
  info.rect.x = INT_MAX;
 | 
			
		||||
  info.rect.y = INT_MAX;
 | 
			
		||||
  info.rect.width = 0;
 | 
			
		||||
  info.rect.height = 0;
 | 
			
		||||
  info.winsys_id = 0;
 | 
			
		||||
  info.n_outputs = 0;
 | 
			
		||||
  info.monitor_winsys_xid = 0;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < manager->n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaOutput *output = &manager->outputs[i];
 | 
			
		||||
 | 
			
		||||
      if (!output->tile_info.group_id)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (output->tile_info.group_id != tile_group_id)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (!output->crtc)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (output->crtc->rect.width != (int)output->tile_info.tile_w ||
 | 
			
		||||
          output->crtc->rect.height != (int)output->tile_info.tile_h)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (output->tile_info.loc_h_tile == 0 && output->tile_info.loc_v_tile == 0)
 | 
			
		||||
        {
 | 
			
		||||
          info.refresh_rate = output->crtc->current_mode->refresh_rate;
 | 
			
		||||
          info.width_mm = output->width_mm;
 | 
			
		||||
          info.height_mm = output->height_mm;
 | 
			
		||||
          info.winsys_id = output->winsys_id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* hack */
 | 
			
		||||
      if (output->crtc->rect.x < info.rect.x)
 | 
			
		||||
        info.rect.x = output->crtc->rect.x;
 | 
			
		||||
      if (output->crtc->rect.y < info.rect.y)
 | 
			
		||||
        info.rect.y = output->crtc->rect.y;
 | 
			
		||||
 | 
			
		||||
      if (output->tile_info.loc_h_tile == 0)
 | 
			
		||||
        info.rect.height += output->tile_info.tile_h;
 | 
			
		||||
 | 
			
		||||
      if (output->tile_info.loc_v_tile == 0)
 | 
			
		||||
        info.rect.width += output->tile_info.tile_w;
 | 
			
		||||
 | 
			
		||||
      if (info.n_outputs > META_MAX_OUTPUTS_PER_MONITOR)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      info.outputs[info.n_outputs++] = output;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* if we don't have a winsys id, i.e. we haven't found tile 0,0
 | 
			
		||||
     don't try and add this to the monitor infos */
 | 
			
		||||
  if (!info.winsys_id)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_array_append_val (monitor_infos, info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * make_logical_config:
 | 
			
		||||
 *
 | 
			
		||||
@@ -81,6 +173,7 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
 | 
			
		||||
static void
 | 
			
		||||
make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (manager);
 | 
			
		||||
  GArray *monitor_infos;
 | 
			
		||||
  unsigned int i, j;
 | 
			
		||||
 | 
			
		||||
@@ -91,6 +184,15 @@ make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
     for each of them, unless they reference a rectangle that
 | 
			
		||||
     is already there.
 | 
			
		||||
  */
 | 
			
		||||
  /* for tiling we need to work out how many tiled outputs there are */
 | 
			
		||||
  for (i = 0; i < manager->n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaOutput *output = &manager->outputs[i];
 | 
			
		||||
 | 
			
		||||
      if (output->tile_info.group_id)
 | 
			
		||||
        construct_tile_monitor (manager, monitor_infos, output->tile_info.group_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < manager->n_crtcs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaCRTC *crtc = &manager->crtcs[i];
 | 
			
		||||
@@ -102,8 +204,8 @@ make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
      for (j = 0; j < monitor_infos->len; j++)
 | 
			
		||||
        {
 | 
			
		||||
          MetaMonitorInfo *info = &g_array_index (monitor_infos, MetaMonitorInfo, j);
 | 
			
		||||
          if (meta_rectangle_equal (&crtc->rect,
 | 
			
		||||
                                    &info->rect))
 | 
			
		||||
          if (meta_rectangle_contains_rect (&info->rect,
 | 
			
		||||
                                            &crtc->rect))
 | 
			
		||||
            {
 | 
			
		||||
              crtc->logical_monitor = info;
 | 
			
		||||
              break;
 | 
			
		||||
@@ -115,7 +217,10 @@ make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
          MetaMonitorInfo info;
 | 
			
		||||
 | 
			
		||||
          info.number = monitor_infos->len;
 | 
			
		||||
          info.tile_group_id = 0;
 | 
			
		||||
          info.rect = crtc->rect;
 | 
			
		||||
          info.refresh_rate = crtc->current_mode->refresh_rate;
 | 
			
		||||
          info.scale = 1;
 | 
			
		||||
          info.is_primary = FALSE;
 | 
			
		||||
          /* This starts true because we want
 | 
			
		||||
             is_presentation only if all outputs are
 | 
			
		||||
@@ -125,7 +230,8 @@ make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
          info.is_presentation = TRUE;
 | 
			
		||||
          info.in_fullscreen = -1;
 | 
			
		||||
          info.winsys_id = 0;
 | 
			
		||||
 | 
			
		||||
          info.n_outputs = 0;
 | 
			
		||||
          info.monitor_winsys_xid = 0;
 | 
			
		||||
          g_array_append_val (monitor_infos, info);
 | 
			
		||||
 | 
			
		||||
          crtc->logical_monitor = &g_array_index (monitor_infos, MetaMonitorInfo,
 | 
			
		||||
@@ -147,6 +253,9 @@ make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
      if (output->crtc == NULL)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (output->tile_info.group_id)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      /* We must have a logical monitor on every CRTC at this point */
 | 
			
		||||
      g_assert (output->crtc->logical_monitor != NULL);
 | 
			
		||||
 | 
			
		||||
@@ -155,8 +264,17 @@ make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
      info->is_primary = info->is_primary || output->is_primary;
 | 
			
		||||
      info->is_presentation = info->is_presentation && output->is_presentation;
 | 
			
		||||
 | 
			
		||||
      info->width_mm = output->width_mm;
 | 
			
		||||
      info->height_mm = output->height_mm;
 | 
			
		||||
 | 
			
		||||
      info->outputs[0] = output;
 | 
			
		||||
      info->n_outputs = 1;
 | 
			
		||||
 | 
			
		||||
      if (output->is_primary || info->winsys_id == 0)
 | 
			
		||||
        info->winsys_id = output->winsys_id;
 | 
			
		||||
        {
 | 
			
		||||
          info->scale = output->scale;
 | 
			
		||||
          info->winsys_id = output->winsys_id;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (info->is_primary)
 | 
			
		||||
        manager->primary_monitor_index = info->number;
 | 
			
		||||
@@ -164,6 +282,10 @@ make_logical_config (MetaMonitorManager *manager)
 | 
			
		||||
 | 
			
		||||
  manager->n_monitor_infos = monitor_infos->len;
 | 
			
		||||
  manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE);
 | 
			
		||||
 | 
			
		||||
  if (manager_class->add_monitor)
 | 
			
		||||
    for (i = 0; i < manager->n_monitor_infos; i++)
 | 
			
		||||
      manager_class->add_monitor (manager, &manager->monitor_infos[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -368,16 +490,14 @@ static char *
 | 
			
		||||
make_display_name (MetaMonitorManager *manager,
 | 
			
		||||
                   MetaOutput         *output)
 | 
			
		||||
{
 | 
			
		||||
  char *inches = NULL;
 | 
			
		||||
  char *vendor_name = NULL;
 | 
			
		||||
  char *ret;
 | 
			
		||||
  g_autofree char *inches = NULL;
 | 
			
		||||
  g_autofree char *vendor_name = NULL;
 | 
			
		||||
 | 
			
		||||
  switch (output->connector_type)
 | 
			
		||||
    {
 | 
			
		||||
    case META_CONNECTOR_TYPE_LVDS:
 | 
			
		||||
    case META_CONNECTOR_TYPE_eDP:
 | 
			
		||||
      ret = g_strdup (_("Built-in display"));
 | 
			
		||||
      goto out;
 | 
			
		||||
      return g_strdup (_("Built-in display"));
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
@@ -413,18 +533,12 @@ make_display_name (MetaMonitorManager *manager,
 | 
			
		||||
      /* TRANSLATORS: this is a monitor vendor name, followed by a
 | 
			
		||||
       * size in inches, like 'Dell 15"'
 | 
			
		||||
       */
 | 
			
		||||
      ret = g_strdup_printf (_("%s %s"), vendor_name, inches);
 | 
			
		||||
      return g_strdup_printf (_("%s %s"), vendor_name, inches);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      ret = g_strdup (vendor_name);
 | 
			
		||||
      return g_strdup (vendor_name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  g_free (inches);
 | 
			
		||||
  g_free (vendor_name);
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
@@ -537,6 +651,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
 | 
			
		||||
                             g_variant_new_string (get_connector_type_name (output->connector_type)));
 | 
			
		||||
      g_variant_builder_add (&properties, "{sv}", "underscanning",
 | 
			
		||||
                             g_variant_new_boolean (output->is_underscanning));
 | 
			
		||||
      g_variant_builder_add (&properties, "{sv}", "supports-underscanning",
 | 
			
		||||
                             g_variant_new_boolean (output->supports_underscanning));
 | 
			
		||||
 | 
			
		||||
      edid_file = manager_class->get_edid_file (manager, output);
 | 
			
		||||
      if (edid_file)
 | 
			
		||||
@@ -557,6 +673,20 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (output->tile_info.group_id)
 | 
			
		||||
        {
 | 
			
		||||
          g_variant_builder_add (&properties, "{sv}", "tile",
 | 
			
		||||
                                 g_variant_new ("(uuuuuuuu)",
 | 
			
		||||
                                                output->tile_info.group_id,
 | 
			
		||||
                                                output->tile_info.flags,
 | 
			
		||||
                                                output->tile_info.max_h_tiles,
 | 
			
		||||
                                                output->tile_info.max_v_tiles,
 | 
			
		||||
                                                output->tile_info.loc_h_tile,
 | 
			
		||||
                                                output->tile_info.loc_v_tile,
 | 
			
		||||
                                                output->tile_info.tile_w,
 | 
			
		||||
                                                output->tile_info.tile_h));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
 | 
			
		||||
                             i, /* ID */
 | 
			
		||||
                             (gint64)output->winsys_id,
 | 
			
		||||
@@ -1237,15 +1367,35 @@ meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
 | 
			
		||||
void
 | 
			
		||||
meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_GET_CLASS (manager);
 | 
			
		||||
  MetaMonitorInfo *old_monitor_infos;
 | 
			
		||||
 | 
			
		||||
  unsigned old_n_monitor_infos;
 | 
			
		||||
  unsigned i, j;
 | 
			
		||||
  old_monitor_infos = manager->monitor_infos;
 | 
			
		||||
  old_n_monitor_infos = manager->n_monitor_infos;
 | 
			
		||||
 | 
			
		||||
  if (manager->in_init)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  make_logical_config (manager);
 | 
			
		||||
 | 
			
		||||
  if (manager_class->delete_monitor)
 | 
			
		||||
    {
 | 
			
		||||
      for (i = 0; i < old_n_monitor_infos; i++)
 | 
			
		||||
        {
 | 
			
		||||
          gboolean delete_mon = TRUE;
 | 
			
		||||
          for (j = 0; j < manager->n_monitor_infos; j++)
 | 
			
		||||
            {
 | 
			
		||||
              if (manager->monitor_infos[j].monitor_winsys_xid == old_monitor_infos[i].monitor_winsys_xid)
 | 
			
		||||
                {
 | 
			
		||||
                  delete_mon = FALSE;
 | 
			
		||||
                  break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
          if (delete_mon)
 | 
			
		||||
            manager_class->delete_monitor (manager, old_monitor_infos[i].monitor_winsys_xid);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  g_signal_emit_by_name (manager, "monitors-changed");
 | 
			
		||||
 | 
			
		||||
  g_free (old_monitor_infos);
 | 
			
		||||
@@ -1266,25 +1416,35 @@ meta_output_parse_edid (MetaOutput *meta_output,
 | 
			
		||||
  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);
 | 
			
		||||
      if (!g_utf8_validate (meta_output->vendor, -1, NULL))
 | 
			
		||||
        g_clear_pointer (&meta_output->vendor, g_free);
 | 
			
		||||
 | 
			
		||||
      meta_output->product = g_strndup (parsed_edid->dsc_product_name, 14);
 | 
			
		||||
      if (!g_utf8_validate (meta_output->product, -1, NULL) ||
 | 
			
		||||
          meta_output->product[0] == '\0')
 | 
			
		||||
        {
 | 
			
		||||
          g_clear_pointer (&meta_output->product, g_free);
 | 
			
		||||
          meta_output->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      meta_output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
 | 
			
		||||
      if (!g_utf8_validate (meta_output->serial, -1, NULL) ||
 | 
			
		||||
          meta_output->serial[0] == '\0')
 | 
			
		||||
        {
 | 
			
		||||
          g_clear_pointer (&meta_output->serial, g_free);
 | 
			
		||||
          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");
 | 
			
		||||
    }
 | 
			
		||||
    meta_output->vendor = g_strdup ("unknown");
 | 
			
		||||
  if (!meta_output->product)
 | 
			
		||||
    meta_output->product = g_strdup ("unknown");
 | 
			
		||||
  if (!meta_output->serial)
 | 
			
		||||
    meta_output->serial = g_strdup ("unknown");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@
 | 
			
		||||
 | 
			
		||||
#include <meta/main.h>
 | 
			
		||||
#include <clutter/evdev/clutter-evdev.h>
 | 
			
		||||
#include <libupower-glib/upower.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-barrier-native.h"
 | 
			
		||||
#include "meta-idle-monitor-native.h"
 | 
			
		||||
@@ -39,10 +40,11 @@
 | 
			
		||||
struct _MetaBackendNativePrivate
 | 
			
		||||
{
 | 
			
		||||
  MetaLauncher *launcher;
 | 
			
		||||
 | 
			
		||||
  MetaBarrierManagerNative *barrier_manager;
 | 
			
		||||
 | 
			
		||||
  GSettings *keyboard_settings;
 | 
			
		||||
  UpClient *up_client;
 | 
			
		||||
  guint sleep_signal_id;
 | 
			
		||||
  GCancellable *cancellable;
 | 
			
		||||
  GDBusConnection *system_bus;
 | 
			
		||||
};
 | 
			
		||||
typedef struct _MetaBackendNativePrivate MetaBackendNativePrivate;
 | 
			
		||||
 | 
			
		||||
@@ -56,9 +58,69 @@ meta_backend_native_finalize (GObject *object)
 | 
			
		||||
 | 
			
		||||
  meta_launcher_free (priv->launcher);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (priv->up_client);
 | 
			
		||||
  if (priv->sleep_signal_id)
 | 
			
		||||
    g_dbus_connection_signal_unsubscribe (priv->system_bus, priv->sleep_signal_id);
 | 
			
		||||
  g_cancellable_cancel (priv->cancellable);
 | 
			
		||||
  g_clear_object (&priv->cancellable);
 | 
			
		||||
  g_clear_object (&priv->system_bus);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
prepare_for_sleep_cb (GDBusConnection *connection,
 | 
			
		||||
                      const gchar     *sender_name,
 | 
			
		||||
                      const gchar     *object_path,
 | 
			
		||||
                      const gchar     *interface_name,
 | 
			
		||||
                      const gchar     *signal_name,
 | 
			
		||||
                      GVariant        *parameters,
 | 
			
		||||
                      gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
  gboolean suspending;
 | 
			
		||||
  g_variant_get (parameters, "(b)", &suspending);
 | 
			
		||||
  if (suspending)
 | 
			
		||||
    return;
 | 
			
		||||
  meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
system_bus_gotten_cb (GObject      *object,
 | 
			
		||||
                      GAsyncResult *res,
 | 
			
		||||
                      gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendNativePrivate *priv;
 | 
			
		||||
  GDBusConnection *bus;
 | 
			
		||||
 | 
			
		||||
  bus = g_bus_get_finish (res, NULL);
 | 
			
		||||
  if (!bus)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  priv = meta_backend_native_get_instance_private (META_BACKEND_NATIVE (user_data));
 | 
			
		||||
  priv->system_bus = bus;
 | 
			
		||||
  priv->sleep_signal_id = g_dbus_connection_signal_subscribe (priv->system_bus,
 | 
			
		||||
                                                              "org.freedesktop.login1",
 | 
			
		||||
                                                              "org.freedesktop.login1.Manager",
 | 
			
		||||
                                                              "PrepareForSleep",
 | 
			
		||||
                                                              "/org/freedesktop/login1",
 | 
			
		||||
                                                              NULL,
 | 
			
		||||
                                                              G_DBUS_SIGNAL_FLAGS_NONE,
 | 
			
		||||
                                                              prepare_for_sleep_cb,
 | 
			
		||||
                                                              NULL,
 | 
			
		||||
                                                              NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
lid_is_closed_changed_cb (UpClient   *client,
 | 
			
		||||
                          GParamSpec *pspec,
 | 
			
		||||
                          gpointer    user_data)
 | 
			
		||||
{
 | 
			
		||||
  if (up_client_get_lid_is_closed (client))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
constrain_to_barriers (ClutterInputDevice *device,
 | 
			
		||||
                       guint32             time,
 | 
			
		||||
@@ -270,6 +332,16 @@ meta_backend_native_init (MetaBackendNative *native)
 | 
			
		||||
  priv->launcher = meta_launcher_new ();
 | 
			
		||||
 | 
			
		||||
  priv->barrier_manager = meta_barrier_manager_native_new ();
 | 
			
		||||
 | 
			
		||||
  priv->up_client = up_client_new ();
 | 
			
		||||
  g_signal_connect (priv->up_client, "notify::lid-is-closed",
 | 
			
		||||
                    G_CALLBACK (lid_is_closed_changed_cb), NULL);
 | 
			
		||||
 | 
			
		||||
  priv->cancellable = g_cancellable_new ();
 | 
			
		||||
  g_bus_get (G_BUS_TYPE_SYSTEM,
 | 
			
		||||
             priv->cancellable,
 | 
			
		||||
             system_bus_gotten_cb,
 | 
			
		||||
             native);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,9 @@ struct _MetaCursorRendererNativePrivate
 | 
			
		||||
{
 | 
			
		||||
  gboolean has_hw_cursor;
 | 
			
		||||
 | 
			
		||||
  MetaCursorReference *last_cursor;
 | 
			
		||||
  guint animation_timeout_id;
 | 
			
		||||
 | 
			
		||||
  int drm_fd;
 | 
			
		||||
  struct gbm_device *gbm;
 | 
			
		||||
 | 
			
		||||
@@ -59,6 +62,9 @@ meta_cursor_renderer_native_finalize (GObject *object)
 | 
			
		||||
  MetaCursorRendererNative *renderer = META_CURSOR_RENDERER_NATIVE (object);
 | 
			
		||||
  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (renderer);
 | 
			
		||||
 | 
			
		||||
  if (priv->animation_timeout_id)
 | 
			
		||||
    g_source_remove (priv->animation_timeout_id);
 | 
			
		||||
 | 
			
		||||
  if (priv->gbm)
 | 
			
		||||
    gbm_device_destroy (priv->gbm);
 | 
			
		||||
 | 
			
		||||
@@ -147,12 +153,66 @@ should_have_hw_cursor (MetaCursorRenderer *renderer)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
 | 
			
		||||
  MetaCursorReference *cursor;
 | 
			
		||||
 | 
			
		||||
  priv->animation_timeout_id = 0;
 | 
			
		||||
  cursor = meta_cursor_renderer_get_cursor (META_CURSOR_RENDERER (native));
 | 
			
		||||
  meta_cursor_reference_tick_frame (cursor);
 | 
			
		||||
  meta_cursor_renderer_force_update (META_CURSOR_RENDERER (native));
 | 
			
		||||
  meta_cursor_renderer_native_force_update (native);
 | 
			
		||||
 | 
			
		||||
  return G_SOURCE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
 | 
			
		||||
  MetaCursorReference *cursor;
 | 
			
		||||
  gboolean cursor_change;
 | 
			
		||||
  guint delay;
 | 
			
		||||
 | 
			
		||||
  cursor = meta_cursor_renderer_get_cursor (META_CURSOR_RENDERER (native));
 | 
			
		||||
  cursor_change = cursor != priv->last_cursor;
 | 
			
		||||
  priv->last_cursor = cursor;
 | 
			
		||||
 | 
			
		||||
  if (!cursor_change && priv->animation_timeout_id)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (priv->animation_timeout_id)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_remove (priv->animation_timeout_id);
 | 
			
		||||
      priv->animation_timeout_id = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (cursor && meta_cursor_reference_is_animated (cursor))
 | 
			
		||||
    {
 | 
			
		||||
      delay = meta_cursor_reference_get_current_frame_time (cursor);
 | 
			
		||||
 | 
			
		||||
      if (delay == 0)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      priv->animation_timeout_id =
 | 
			
		||||
        g_timeout_add (delay,
 | 
			
		||||
                       (GSourceFunc) meta_cursor_renderer_native_update_animation,
 | 
			
		||||
                       native);
 | 
			
		||||
      g_source_set_name_by_id (priv->animation_timeout_id,
 | 
			
		||||
                               "[mutter] meta_cursor_renderer_native_update_animation");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
 | 
			
		||||
{
 | 
			
		||||
  MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
 | 
			
		||||
  MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
 | 
			
		||||
 | 
			
		||||
  meta_cursor_renderer_native_trigger_frame (native);
 | 
			
		||||
 | 
			
		||||
  priv->has_hw_cursor = should_have_hw_cursor (renderer);
 | 
			
		||||
  update_hw_cursor (native, FALSE);
 | 
			
		||||
  return priv->has_hw_cursor;
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,7 @@
 | 
			
		||||
 | 
			
		||||
#include "backends/meta-backend-private.h"
 | 
			
		||||
#include "meta-cursor-renderer-native.h"
 | 
			
		||||
#include "meta-idle-monitor-native.h"
 | 
			
		||||
 | 
			
		||||
struct _MetaLauncher
 | 
			
		||||
{
 | 
			
		||||
@@ -110,6 +111,7 @@ session_unpause (void)
 | 
			
		||||
 | 
			
		||||
    clutter_actor_queue_redraw (stage);
 | 
			
		||||
    meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer));
 | 
			
		||||
    meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -128,9 +130,8 @@ take_device (Login1Session *session_proxy,
 | 
			
		||||
             GCancellable  *cancellable,
 | 
			
		||||
             GError       **error)
 | 
			
		||||
{
 | 
			
		||||
  gboolean ret = FALSE;
 | 
			
		||||
  GVariant *fd_variant = NULL;
 | 
			
		||||
  GUnixFDList *fd_list = NULL;
 | 
			
		||||
  g_autoptr (GVariant) fd_variant = NULL;
 | 
			
		||||
  g_autoptr (GUnixFDList) fd_list = NULL;
 | 
			
		||||
  int fd = -1;
 | 
			
		||||
 | 
			
		||||
  if (!login1_session_call_take_device_sync (session_proxy,
 | 
			
		||||
@@ -142,21 +143,14 @@ take_device (Login1Session *session_proxy,
 | 
			
		||||
                                             &fd_list,
 | 
			
		||||
                                             cancellable,
 | 
			
		||||
                                             error))
 | 
			
		||||
    goto out;
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), error);
 | 
			
		||||
  if (fd == -1)
 | 
			
		||||
    goto out;
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *out_fd = fd;
 | 
			
		||||
  ret = TRUE;
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  if (fd_variant)
 | 
			
		||||
    g_variant_unref (fd_variant);
 | 
			
		||||
  if (fd_list)
 | 
			
		||||
    g_object_unref (fd_list);
 | 
			
		||||
  return ret;
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
@@ -164,22 +158,16 @@ get_device_info_from_path (const char *path,
 | 
			
		||||
                           int        *out_major,
 | 
			
		||||
                           int        *out_minor)
 | 
			
		||||
{
 | 
			
		||||
  gboolean ret = FALSE;
 | 
			
		||||
  int r;
 | 
			
		||||
  struct stat st;
 | 
			
		||||
 | 
			
		||||
  r = stat (path, &st);
 | 
			
		||||
  if (r < 0)
 | 
			
		||||
    goto out;
 | 
			
		||||
  if (!S_ISCHR (st.st_mode))
 | 
			
		||||
    goto out;
 | 
			
		||||
  if (r < 0 || !S_ISCHR (st.st_mode))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *out_major = major (st.st_rdev);
 | 
			
		||||
  *out_minor = minor (st.st_rdev);
 | 
			
		||||
  ret = TRUE;
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  return ret;
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
@@ -187,22 +175,16 @@ get_device_info_from_fd (int  fd,
 | 
			
		||||
                         int *out_major,
 | 
			
		||||
                         int *out_minor)
 | 
			
		||||
{
 | 
			
		||||
  gboolean ret = FALSE;
 | 
			
		||||
  int r;
 | 
			
		||||
  struct stat st;
 | 
			
		||||
 | 
			
		||||
  r = fstat (fd, &st);
 | 
			
		||||
  if (r < 0)
 | 
			
		||||
    goto out;
 | 
			
		||||
  if (!S_ISCHR (st.st_mode))
 | 
			
		||||
    goto out;
 | 
			
		||||
  if (r < 0 || !S_ISCHR (st.st_mode))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *out_major = major (st.st_rdev);
 | 
			
		||||
  *out_minor = minor (st.st_rdev);
 | 
			
		||||
  ret = TRUE;
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  return ret;
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
 
 | 
			
		||||
@@ -55,6 +55,11 @@ typedef struct {
 | 
			
		||||
 | 
			
		||||
  uint32_t dpms_prop_id;
 | 
			
		||||
  uint32_t edid_blob_id;
 | 
			
		||||
  uint32_t tile_blob_id;
 | 
			
		||||
 | 
			
		||||
  int suggested_x;
 | 
			
		||||
  int suggested_y;
 | 
			
		||||
  uint32_t hotplug_mode_update;
 | 
			
		||||
} MetaOutputKms;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
@@ -110,7 +115,7 @@ make_output_name (drmModeConnector *connector)
 | 
			
		||||
  static const char * const connector_type_names[] = {
 | 
			
		||||
    "unknown", "VGA", "DVII", "DVID", "DVID", "Composite",
 | 
			
		||||
    "SVIDEO", "LVDS", "Component", "9PinDIN", "DisplayPort",
 | 
			
		||||
    "HDMIA", "HDMIB", "TV", "eDP"
 | 
			
		||||
    "HDMIA", "HDMIB", "TV", "eDP", "Virtual", "DSI"
 | 
			
		||||
  };
 | 
			
		||||
  const char *connector_type_name;
 | 
			
		||||
 | 
			
		||||
@@ -198,6 +203,9 @@ find_connector_properties (MetaMonitorManagerKms *manager_kms,
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  output_kms->hotplug_mode_update = 0;
 | 
			
		||||
  output_kms->suggested_x = -1;
 | 
			
		||||
  output_kms->suggested_y = -1;
 | 
			
		||||
  for (i = 0; i < output_kms->connector->count_props; i++)
 | 
			
		||||
    {
 | 
			
		||||
      drmModePropertyPtr prop = drmModeGetProperty (manager_kms->fd, output_kms->connector->props[i]);
 | 
			
		||||
@@ -208,7 +216,19 @@ find_connector_properties (MetaMonitorManagerKms *manager_kms,
 | 
			
		||||
        output_kms->dpms_prop_id = prop->prop_id;
 | 
			
		||||
      else if ((prop->flags & DRM_MODE_PROP_BLOB) && strcmp (prop->name, "EDID") == 0)
 | 
			
		||||
        output_kms->edid_blob_id = output_kms->connector->prop_values[i];
 | 
			
		||||
 | 
			
		||||
      else if ((prop->flags & DRM_MODE_PROP_BLOB) &&
 | 
			
		||||
               strcmp (prop->name, "TILE") == 0)
 | 
			
		||||
        output_kms->tile_blob_id = output_kms->connector->prop_values[i];
 | 
			
		||||
      else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
 | 
			
		||||
               strcmp (prop->name, "suggested X") == 0)
 | 
			
		||||
        output_kms->suggested_x = output_kms->connector->prop_values[i];
 | 
			
		||||
      else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
 | 
			
		||||
               strcmp (prop->name, "suggested Y") == 0)
 | 
			
		||||
        output_kms->suggested_y = output_kms->connector->prop_values[i];
 | 
			
		||||
      else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
 | 
			
		||||
               strcmp (prop->name, "hotplug_mode_update") == 0)
 | 
			
		||||
        output_kms->hotplug_mode_update = output_kms->connector->prop_values[i];
 | 
			
		||||
      
 | 
			
		||||
      drmModeFreeProperty (prop);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -273,6 +293,47 @@ read_output_edid (MetaMonitorManagerKms *manager_kms,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
output_get_tile_info (MetaMonitorManagerKms *manager_kms,
 | 
			
		||||
                      MetaOutput            *output)
 | 
			
		||||
{
 | 
			
		||||
  MetaOutputKms *output_kms = output->driver_private;
 | 
			
		||||
  drmModePropertyBlobPtr tile_blob = NULL;
 | 
			
		||||
  int ret;
 | 
			
		||||
 | 
			
		||||
  if (output_kms->tile_blob_id == 0)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  tile_blob = drmModeGetPropertyBlob (manager_kms->fd, output_kms->tile_blob_id);
 | 
			
		||||
  if (!tile_blob)
 | 
			
		||||
    {
 | 
			
		||||
      meta_warning ("Failed to read TILE of output %s: %s\n", output->name, strerror(errno));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (tile_blob->length > 0)
 | 
			
		||||
    {
 | 
			
		||||
      ret = sscanf ((char *)tile_blob->data, "%d:%d:%d:%d:%d:%d:%d:%d",
 | 
			
		||||
                    &output->tile_info.group_id,
 | 
			
		||||
                    &output->tile_info.flags,
 | 
			
		||||
                    &output->tile_info.max_h_tiles,
 | 
			
		||||
                    &output->tile_info.max_v_tiles,
 | 
			
		||||
                    &output->tile_info.loc_h_tile,
 | 
			
		||||
                    &output->tile_info.loc_v_tile,
 | 
			
		||||
                    &output->tile_info.tile_w,
 | 
			
		||||
                    &output->tile_info.tile_h);
 | 
			
		||||
 | 
			
		||||
      if (ret != 8)
 | 
			
		||||
        return FALSE;
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      drmModeFreePropertyBlob (tile_blob);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaMonitorMode *
 | 
			
		||||
find_meta_mode (MetaMonitorManager    *manager,
 | 
			
		||||
                const drmModeModeInfo *drm_mode)
 | 
			
		||||
@@ -516,8 +577,6 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
 | 
			
		||||
	  meta_output->name = make_output_name (connector);
 | 
			
		||||
	  meta_output->width_mm = connector->mmWidth;
 | 
			
		||||
	  meta_output->height_mm = connector->mmHeight;
 | 
			
		||||
	  meta_output->suggested_x = -1;
 | 
			
		||||
	  meta_output->suggested_y = -1;
 | 
			
		||||
 | 
			
		||||
          switch (connector->subpixel)
 | 
			
		||||
            {
 | 
			
		||||
@@ -542,11 +601,17 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
	  meta_output->preferred_mode = NULL;
 | 
			
		||||
	  meta_output->n_modes = connector->count_modes;
 | 
			
		||||
	  meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
 | 
			
		||||
	  for (j = 0; j < meta_output->n_modes; j++)
 | 
			
		||||
	  for (j = 0; j < meta_output->n_modes; j++) {
 | 
			
		||||
            meta_output->modes[j] = find_meta_mode (manager, &connector->modes[j]);
 | 
			
		||||
	  meta_output->preferred_mode = meta_output->modes[0];
 | 
			
		||||
            if (connector->modes[j].type & DRM_MODE_TYPE_PREFERRED)
 | 
			
		||||
              meta_output->preferred_mode = meta_output->modes[j];
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (!meta_output->preferred_mode)
 | 
			
		||||
            meta_output->preferred_mode = meta_output->modes[0];
 | 
			
		||||
 | 
			
		||||
          output_kms->connector = connector;
 | 
			
		||||
          output_kms->n_encoders = connector->count_encoders;
 | 
			
		||||
@@ -612,7 +677,10 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          find_connector_properties (manager_kms, output_kms);
 | 
			
		||||
 | 
			
		||||
          meta_output->suggested_x = output_kms->suggested_x;
 | 
			
		||||
          meta_output->suggested_y = output_kms->suggested_y;
 | 
			
		||||
          meta_output->hotplug_mode_update = output_kms->hotplug_mode_update;
 | 
			
		||||
          
 | 
			
		||||
          edid = read_output_edid (manager_kms, meta_output);
 | 
			
		||||
          meta_output_parse_edid (meta_output, edid);
 | 
			
		||||
          g_bytes_unref (edid);
 | 
			
		||||
@@ -622,6 +690,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
 | 
			
		||||
 | 
			
		||||
          meta_output->scale = get_output_scale (manager, meta_output);
 | 
			
		||||
 | 
			
		||||
          output_get_tile_info (manager_kms, meta_output);
 | 
			
		||||
 | 
			
		||||
          /* FIXME: backlight is a very driver specific thing unfortunately,
 | 
			
		||||
             every DDX does its own thing, and the dumb KMS API does not include it.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -46,6 +46,14 @@
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
#include "compositor/compositor-private.h"
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  /* We're a traditional CM running under the host. */
 | 
			
		||||
  META_BACKEND_X11_MODE_COMPOSITOR,
 | 
			
		||||
 | 
			
		||||
  /* We're a nested X11 client */
 | 
			
		||||
  META_BACKEND_X11_MODE_NESTED,
 | 
			
		||||
} MetaBackendX11Mode;
 | 
			
		||||
 | 
			
		||||
struct _MetaBackendX11Private
 | 
			
		||||
{
 | 
			
		||||
  /* The host X11 display */
 | 
			
		||||
@@ -53,6 +61,8 @@ struct _MetaBackendX11Private
 | 
			
		||||
  xcb_connection_t *xcb;
 | 
			
		||||
  GSource *source;
 | 
			
		||||
 | 
			
		||||
  MetaBackendX11Mode mode;
 | 
			
		||||
 | 
			
		||||
  int xsync_event_base;
 | 
			
		||||
  int xsync_error_base;
 | 
			
		||||
 | 
			
		||||
@@ -102,7 +112,7 @@ translate_device_event (MetaBackendX11 *x11,
 | 
			
		||||
      /* This codepath should only ever trigger as an X11 compositor,
 | 
			
		||||
       * and never under nested, as under nested all backend events
 | 
			
		||||
       * should be reported with respect to the stage window. */
 | 
			
		||||
      g_assert (!meta_is_wayland_compositor ());
 | 
			
		||||
      g_assert (priv->mode == META_BACKEND_X11_MODE_COMPOSITOR);
 | 
			
		||||
 | 
			
		||||
      device_event->event = stage_window;
 | 
			
		||||
 | 
			
		||||
@@ -133,6 +143,8 @@ static void
 | 
			
		||||
translate_crossing_event (MetaBackendX11 *x11,
 | 
			
		||||
                          XIEnterEvent   *enter_event)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
 | 
			
		||||
 | 
			
		||||
  /* Throw out weird events generated by grabs. */
 | 
			
		||||
  if (enter_event->mode == XINotifyGrab ||
 | 
			
		||||
      enter_event->mode == XINotifyUngrab)
 | 
			
		||||
@@ -141,7 +153,15 @@ translate_crossing_event (MetaBackendX11 *x11,
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  enter_event->event = meta_backend_x11_get_xwindow (x11);
 | 
			
		||||
  Window stage_window = meta_backend_x11_get_xwindow (x11);
 | 
			
		||||
  if (enter_event->event != stage_window)
 | 
			
		||||
    {
 | 
			
		||||
      /* See above for the rationale for this... */
 | 
			
		||||
      g_assert (priv->mode == META_BACKEND_X11_MODE_COMPOSITOR);
 | 
			
		||||
      enter_event->event = meta_backend_x11_get_xwindow (x11);
 | 
			
		||||
      enter_event->event_x = enter_event->root_x;
 | 
			
		||||
      enter_event->event_y = enter_event->root_y;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -430,7 +450,9 @@ meta_backend_x11_post_init (MetaBackend *backend)
 | 
			
		||||
      meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  take_touch_grab (backend);
 | 
			
		||||
  /* We only take the passive touch grab if we are a X11 compositor */
 | 
			
		||||
  if (priv->mode == META_BACKEND_X11_MODE_COMPOSITOR)
 | 
			
		||||
    take_touch_grab (backend);
 | 
			
		||||
 | 
			
		||||
  priv->xcb = XGetXCBConnection (priv->xdisplay);
 | 
			
		||||
  if (!xkb_x11_setup_xkb_extension (priv->xcb,
 | 
			
		||||
@@ -461,13 +483,18 @@ meta_backend_x11_create_idle_monitor (MetaBackend *backend,
 | 
			
		||||
static MetaMonitorManager *
 | 
			
		||||
meta_backend_x11_create_monitor_manager (MetaBackend *backend)
 | 
			
		||||
{
 | 
			
		||||
  /* 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 g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
 | 
			
		||||
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
 | 
			
		||||
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
 | 
			
		||||
 | 
			
		||||
  return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
 | 
			
		||||
  switch (priv->mode)
 | 
			
		||||
    {
 | 
			
		||||
    case META_BACKEND_X11_MODE_COMPOSITOR:
 | 
			
		||||
      return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
 | 
			
		||||
    case META_BACKEND_X11_MODE_NESTED:
 | 
			
		||||
      return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
 | 
			
		||||
    default:
 | 
			
		||||
      g_assert_not_reached ();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaCursorRenderer *
 | 
			
		||||
@@ -721,7 +748,10 @@ static void
 | 
			
		||||
meta_backend_x11_update_screen_size (MetaBackend *backend,
 | 
			
		||||
                                     int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
 | 
			
		||||
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
 | 
			
		||||
 | 
			
		||||
  if (priv->mode == META_BACKEND_X11_MODE_NESTED)
 | 
			
		||||
    {
 | 
			
		||||
      /* For a nested wayland session, we want to go through Clutter to update the
 | 
			
		||||
       * toplevel window size, rather than doing it directly.
 | 
			
		||||
@@ -755,9 +785,21 @@ meta_backend_x11_select_stage_events (MetaBackend *backend)
 | 
			
		||||
  XISetMask (mask.mask, XI_FocusIn);
 | 
			
		||||
  XISetMask (mask.mask, XI_FocusOut);
 | 
			
		||||
  XISetMask (mask.mask, XI_Motion);
 | 
			
		||||
  XIClearMask (mask.mask, XI_TouchBegin);
 | 
			
		||||
  XIClearMask (mask.mask, XI_TouchEnd);
 | 
			
		||||
  XIClearMask (mask.mask, XI_TouchUpdate);
 | 
			
		||||
 | 
			
		||||
  if (priv->mode == META_BACKEND_X11_MODE_NESTED)
 | 
			
		||||
    {
 | 
			
		||||
      /* When we're an X11 compositor, we can't take these events or else
 | 
			
		||||
       * replaying events from our passive root window grab will cause
 | 
			
		||||
       * them to come back to us.
 | 
			
		||||
       *
 | 
			
		||||
       * When we're a nested application, we want to behave like any other
 | 
			
		||||
       * application, so select these events like normal apps do.
 | 
			
		||||
       */
 | 
			
		||||
      XISetMask (mask.mask, XI_TouchBegin);
 | 
			
		||||
      XISetMask (mask.mask, XI_TouchEnd);
 | 
			
		||||
      XISetMask (mask.mask, XI_TouchUpdate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  XISelectEvents (priv->xdisplay, xwin, &mask, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -783,8 +825,15 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
 | 
			
		||||
static void
 | 
			
		||||
meta_backend_x11_init (MetaBackendX11 *x11)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
 | 
			
		||||
 | 
			
		||||
  /* We do X11 event retrieval ourselves */
 | 
			
		||||
  clutter_x11_disable_event_retrieval ();
 | 
			
		||||
 | 
			
		||||
  if (meta_is_wayland_compositor ())
 | 
			
		||||
    priv->mode = META_BACKEND_X11_MODE_NESTED;
 | 
			
		||||
  else
 | 
			
		||||
    priv->mode = META_BACKEND_X11_MODE_COMPOSITOR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Display *
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@
 | 
			
		||||
#include "meta-backend-x11.h"
 | 
			
		||||
#include "meta-input-settings-x11.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gdk/gdkx.h>
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
#include <X11/extensions/XInput2.h>
 | 
			
		||||
@@ -35,6 +36,41 @@
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaInputSettingsX11, meta_input_settings_x11, META_TYPE_INPUT_SETTINGS)
 | 
			
		||||
 | 
			
		||||
static void *
 | 
			
		||||
get_property (ClutterInputDevice *device,
 | 
			
		||||
              const gchar        *property,
 | 
			
		||||
              Atom                type,
 | 
			
		||||
              int                 format,
 | 
			
		||||
              gulong              nitems)
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
  Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
 | 
			
		||||
  gulong nitems_ret, bytes_after_ret;
 | 
			
		||||
  int rc, device_id, format_ret;
 | 
			
		||||
  Atom property_atom, type_ret;
 | 
			
		||||
  guchar *data_ret = NULL;
 | 
			
		||||
 | 
			
		||||
  property_atom = XInternAtom (xdisplay, property, True);
 | 
			
		||||
  if (!property_atom)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  device_id = clutter_input_device_get_device_id (device);
 | 
			
		||||
 | 
			
		||||
  rc = XIGetProperty (xdisplay, device_id, property_atom,
 | 
			
		||||
                      0, 10, False, type, &type_ret, &format_ret,
 | 
			
		||||
                      &nitems_ret, &bytes_after_ret, &data_ret);
 | 
			
		||||
  if (rc == Success && type_ret == type && format_ret == format && nitems_ret >= nitems)
 | 
			
		||||
    {
 | 
			
		||||
      if (nitems_ret > nitems)
 | 
			
		||||
        g_warning ("Property '%s' for device '%s' returned %lu items, expected %lu",
 | 
			
		||||
                   property, clutter_input_device_get_device_name (device), nitems_ret, nitems);
 | 
			
		||||
      return data_ret;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_XFree (data_ret);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
change_property (ClutterInputDevice *device,
 | 
			
		||||
                 const gchar        *property,
 | 
			
		||||
@@ -45,23 +81,23 @@ change_property (ClutterInputDevice *device,
 | 
			
		||||
{
 | 
			
		||||
  MetaBackend *backend = meta_get_backend ();
 | 
			
		||||
  Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
 | 
			
		||||
  gulong nitems_ret, bytes_after_ret;
 | 
			
		||||
  int rc, device_id, format_ret;
 | 
			
		||||
  Atom property_atom, type_ret;
 | 
			
		||||
  int device_id;
 | 
			
		||||
  Atom property_atom;
 | 
			
		||||
  guchar *data_ret;
 | 
			
		||||
 | 
			
		||||
  property_atom = XInternAtom (xdisplay, property, False);
 | 
			
		||||
  property_atom = XInternAtom (xdisplay, property, True);
 | 
			
		||||
  if (!property_atom)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  device_id = clutter_input_device_get_device_id (device);
 | 
			
		||||
 | 
			
		||||
  rc = XIGetProperty (xdisplay, device_id, property_atom,
 | 
			
		||||
                      0, 0, False, type, &type_ret, &format_ret,
 | 
			
		||||
                      &nitems_ret, &bytes_after_ret, &data_ret);
 | 
			
		||||
  data_ret = get_property (device, property, type, format, nitems);
 | 
			
		||||
  if (!data_ret)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  XIChangeProperty (xdisplay, device_id, property_atom, type,
 | 
			
		||||
                    format, XIPropModeReplace, data, nitems);
 | 
			
		||||
  meta_XFree (data_ret);
 | 
			
		||||
 | 
			
		||||
  if (rc == Success && type_ret == type && format_ret == format)
 | 
			
		||||
    XIChangeProperty (xdisplay, device_id, property_atom, type,
 | 
			
		||||
                      format, XIPropModeReplace, data, nitems);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -70,6 +106,12 @@ meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
 | 
			
		||||
                                         GDesktopDeviceSendEvents  mode)
 | 
			
		||||
{
 | 
			
		||||
  guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */
 | 
			
		||||
  guchar *available;
 | 
			
		||||
 | 
			
		||||
  available = get_property (device, "libinput Send Events Modes Available",
 | 
			
		||||
                            XA_INTEGER, 8, 2);
 | 
			
		||||
  if (!available)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  switch (mode)
 | 
			
		||||
    {
 | 
			
		||||
@@ -83,8 +125,14 @@ meta_input_settings_x11_set_send_events (MetaInputSettings        *settings,
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  change_property (device, "libinput Send Events Mode Enabled",
 | 
			
		||||
                   XA_INTEGER, 8, &values, 2);
 | 
			
		||||
  if ((values[0] && !available[0]) || (values[1] && !available[1]))
 | 
			
		||||
    g_warning ("Device '%s' does not support sendevents mode %d\n",
 | 
			
		||||
               clutter_input_device_get_device_name (device), mode);
 | 
			
		||||
  else
 | 
			
		||||
    change_property (device, "libinput Send Events Mode Enabled",
 | 
			
		||||
                     XA_INTEGER, 8, &values, 2);
 | 
			
		||||
 | 
			
		||||
  meta_XFree (available);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -156,6 +204,12 @@ meta_input_settings_x11_set_scroll_method (MetaInputSettings            *setting
 | 
			
		||||
                                           GDesktopTouchpadScrollMethod  mode)
 | 
			
		||||
{
 | 
			
		||||
  guchar values[3] = { 0 }; /* 2fg, edge, button. The last value is unused */
 | 
			
		||||
  guchar *available;
 | 
			
		||||
 | 
			
		||||
  available = get_property (device, "libinput Scroll Methods Available",
 | 
			
		||||
                            XA_INTEGER, 8, 3);
 | 
			
		||||
  if (!available)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  switch (mode)
 | 
			
		||||
    {
 | 
			
		||||
@@ -171,8 +225,14 @@ meta_input_settings_x11_set_scroll_method (MetaInputSettings            *setting
 | 
			
		||||
      g_assert_not_reached ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  change_property (device, "libinput Scroll Method Enabled",
 | 
			
		||||
                   XA_INTEGER, 8, &values, 3);
 | 
			
		||||
  if ((values[0] && !available[0]) || (values[1] && !available[1]))
 | 
			
		||||
    g_warning ("Device '%s' does not support scroll mode %d\n",
 | 
			
		||||
               clutter_input_device_get_device_name (device), mode);
 | 
			
		||||
  else
 | 
			
		||||
    change_property (device, "libinput Scroll Method Enabled",
 | 
			
		||||
                     XA_INTEGER, 8, &values, 3);
 | 
			
		||||
 | 
			
		||||
  meta_XFree (available);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -190,16 +250,28 @@ meta_input_settings_x11_set_click_method (MetaInputSettings           *settings,
 | 
			
		||||
                                          GDesktopTouchpadClickMethod  mode)
 | 
			
		||||
{
 | 
			
		||||
  guchar values[2] = { 0 }; /* buttonareas, clickfinger */
 | 
			
		||||
  guchar *defaults, *available;
 | 
			
		||||
 | 
			
		||||
  available = get_property (device, "libinput Click Methods Available",
 | 
			
		||||
                            XA_INTEGER, 8, 2);
 | 
			
		||||
  if (!available)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  switch (mode)
 | 
			
		||||
    {
 | 
			
		||||
    case G_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT:
 | 
			
		||||
      defaults = get_property (device, "libinput Click Method Enabled Default",
 | 
			
		||||
                               XA_INTEGER, 8, 2);
 | 
			
		||||
      if (!defaults)
 | 
			
		||||
        break;
 | 
			
		||||
      memcpy (values, defaults, 2);
 | 
			
		||||
      meta_XFree (defaults);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE:
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS:
 | 
			
		||||
      values[0] = 1;
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT:
 | 
			
		||||
      /* XXX: We can't be much smarter yet, x11 doesn't expose default settings */
 | 
			
		||||
    case G_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS:
 | 
			
		||||
      values[1] = 1;
 | 
			
		||||
      break;
 | 
			
		||||
@@ -208,8 +280,14 @@ meta_input_settings_x11_set_click_method (MetaInputSettings           *settings,
 | 
			
		||||
      return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  change_property (device, "libinput Click Method Enabled",
 | 
			
		||||
                   XA_INTEGER, 8, &values, 2);
 | 
			
		||||
  if ((values[0] && !available[0]) || (values[1] && !available[1]))
 | 
			
		||||
    g_warning ("Device '%s' does not support click method %d\n",
 | 
			
		||||
               clutter_input_device_get_device_name (device), mode);
 | 
			
		||||
  else
 | 
			
		||||
    change_property (device, "libinput Click Method Enabled",
 | 
			
		||||
                     XA_INTEGER, 8, &values, 2);
 | 
			
		||||
 | 
			
		||||
  meta_XFree(available);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -58,6 +58,7 @@ struct _MetaMonitorManagerXrandr
 | 
			
		||||
  XRRScreenResources *resources;
 | 
			
		||||
  int rr_event_base;
 | 
			
		||||
  int rr_error_base;
 | 
			
		||||
  gboolean has_randr15;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaMonitorManagerXrandrClass
 | 
			
		||||
@@ -194,11 +195,10 @@ static gboolean
 | 
			
		||||
output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
                             MetaOutput *output, const char *propname)
 | 
			
		||||
{
 | 
			
		||||
  gboolean value = FALSE;
 | 
			
		||||
  Atom atom, actual_type;
 | 
			
		||||
  int actual_format;
 | 
			
		||||
  unsigned long nitems, bytes_after;
 | 
			
		||||
  unsigned char *buffer;
 | 
			
		||||
  g_autofree unsigned char *buffer = NULL;
 | 
			
		||||
 | 
			
		||||
  atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
 | 
			
		||||
  XRRGetOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
@@ -209,13 +209,9 @@ output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
                        &nitems, &bytes_after, &buffer);
 | 
			
		||||
 | 
			
		||||
  if (actual_type != XA_CARDINAL || actual_format != 32 || nitems < 1)
 | 
			
		||||
    goto out;
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  value = ((int*)buffer)[0];
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  XFree (buffer);
 | 
			
		||||
  return value;
 | 
			
		||||
  return ((int*)buffer)[0];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
@@ -229,12 +225,11 @@ static gboolean
 | 
			
		||||
output_get_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
                                 MetaOutput               *output)
 | 
			
		||||
{
 | 
			
		||||
  gboolean value = FALSE;
 | 
			
		||||
  Atom atom, actual_type;
 | 
			
		||||
  int actual_format;
 | 
			
		||||
  unsigned long nitems, bytes_after;
 | 
			
		||||
  unsigned char *buffer;
 | 
			
		||||
  char *str;
 | 
			
		||||
  g_autofree unsigned char *buffer = NULL;
 | 
			
		||||
  g_autofree char *str = NULL;
 | 
			
		||||
 | 
			
		||||
  atom = XInternAtom (manager_xrandr->xdisplay, "underscan", False);
 | 
			
		||||
  XRRGetOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
@@ -244,17 +239,56 @@ output_get_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
                        &actual_type, &actual_format,
 | 
			
		||||
                        &nitems, &bytes_after, &buffer);
 | 
			
		||||
 | 
			
		||||
  if (actual_type != XA_ATOM || actual_format != 32 ||
 | 
			
		||||
      nitems < 1)
 | 
			
		||||
    goto out;
 | 
			
		||||
  if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  str = XGetAtomName (manager_xrandr->xdisplay, *(Atom *)buffer);
 | 
			
		||||
  value = !strcmp(str, "on");
 | 
			
		||||
  XFree (str);
 | 
			
		||||
  return (strcmp (str, "on") == 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
  XFree (buffer);
 | 
			
		||||
  return value;
 | 
			
		||||
static gboolean
 | 
			
		||||
output_get_supports_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
                                          MetaOutput               *output)
 | 
			
		||||
{
 | 
			
		||||
  Atom atom, actual_type;
 | 
			
		||||
  int actual_format, i;
 | 
			
		||||
  unsigned long nitems, bytes_after;
 | 
			
		||||
  g_autofree unsigned char *buffer = NULL;
 | 
			
		||||
  XRRPropertyInfo *property_info;
 | 
			
		||||
  Atom *values;
 | 
			
		||||
  gboolean supports_underscanning = FALSE;
 | 
			
		||||
 | 
			
		||||
  atom = XInternAtom (manager_xrandr->xdisplay, "underscan", False);
 | 
			
		||||
  XRRGetOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
                        (XID)output->winsys_id,
 | 
			
		||||
                        atom,
 | 
			
		||||
                        0, G_MAXLONG, False, False, XA_ATOM,
 | 
			
		||||
                        &actual_type, &actual_format,
 | 
			
		||||
                        &nitems, &bytes_after, &buffer);
 | 
			
		||||
 | 
			
		||||
  if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  property_info = XRRQueryOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
                                          (XID) output->winsys_id,
 | 
			
		||||
                                          atom);
 | 
			
		||||
  values = (Atom *) property_info->values;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < property_info->num_values; i++)
 | 
			
		||||
    {
 | 
			
		||||
      /* The output supports underscanning if "on" is a valid value
 | 
			
		||||
       * for the underscan property.
 | 
			
		||||
       */
 | 
			
		||||
      char *name = XGetAtomName (manager_xrandr->xdisplay, values[i]);
 | 
			
		||||
      if (strcmp (name, "on") == 0)
 | 
			
		||||
        supports_underscanning = TRUE;
 | 
			
		||||
 | 
			
		||||
      XFree (name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  XFree (property_info);
 | 
			
		||||
 | 
			
		||||
  return supports_underscanning;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
@@ -273,7 +307,7 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
  Atom atom, actual_type;
 | 
			
		||||
  int actual_format;
 | 
			
		||||
  unsigned long nitems, bytes_after;
 | 
			
		||||
  unsigned char *buffer;
 | 
			
		||||
  g_autofree unsigned char *buffer = NULL;
 | 
			
		||||
 | 
			
		||||
  atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
 | 
			
		||||
  XRRGetOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
@@ -284,12 +318,9 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
                        &nitems, &bytes_after, &buffer);
 | 
			
		||||
 | 
			
		||||
  if (actual_type != XA_INTEGER || actual_format != 32 || nitems < 1)
 | 
			
		||||
    goto out;
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  value = ((int*)buffer)[0];
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  XFree (buffer);
 | 
			
		||||
  if (value > 0)
 | 
			
		||||
    return normalize_backlight (output, value);
 | 
			
		||||
  else
 | 
			
		||||
@@ -302,7 +333,7 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
{
 | 
			
		||||
  Atom atom;
 | 
			
		||||
  xcb_connection_t *xcb_conn;
 | 
			
		||||
  xcb_randr_query_output_property_reply_t *reply;
 | 
			
		||||
  g_autofree xcb_randr_query_output_property_reply_t *reply;
 | 
			
		||||
 | 
			
		||||
  atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
 | 
			
		||||
 | 
			
		||||
@@ -320,15 +351,12 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
  if (!reply->range || reply->length != 2)
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("backlight %s was not range\n", output->name);
 | 
			
		||||
      goto out;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  int32_t *values = xcb_randr_query_output_property_valid_values (reply);
 | 
			
		||||
  output->backlight_min = values[0];
 | 
			
		||||
  output->backlight_max = values[1];
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
  free (reply);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
@@ -408,6 +436,42 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
output_get_tile_info (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
                      MetaOutput *output)
 | 
			
		||||
{
 | 
			
		||||
  Atom tile_atom;
 | 
			
		||||
  unsigned char *prop;
 | 
			
		||||
  unsigned long nitems, bytes_after;
 | 
			
		||||
  int actual_format;
 | 
			
		||||
  Atom actual_type;
 | 
			
		||||
 | 
			
		||||
  if (manager_xrandr->has_randr15 == FALSE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  tile_atom = XInternAtom (manager_xrandr->xdisplay, "TILE", FALSE);
 | 
			
		||||
  XRRGetOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
                        output->winsys_id,
 | 
			
		||||
                        tile_atom, 0, 100, False,
 | 
			
		||||
                        False, AnyPropertyType,
 | 
			
		||||
                        &actual_type, &actual_format,
 | 
			
		||||
                        &nitems, &bytes_after, &prop);
 | 
			
		||||
 | 
			
		||||
  if (actual_type == XA_INTEGER && actual_format == 32 && nitems == 8)
 | 
			
		||||
    {
 | 
			
		||||
      long *values = (long *)prop;
 | 
			
		||||
      output->tile_info.group_id = values[0];
 | 
			
		||||
      output->tile_info.flags = values[1];
 | 
			
		||||
      output->tile_info.max_h_tiles = values[2];
 | 
			
		||||
      output->tile_info.max_v_tiles = values[3];
 | 
			
		||||
      output->tile_info.loc_h_tile = values[4];
 | 
			
		||||
      output->tile_info.loc_v_tile = values[5];
 | 
			
		||||
      output->tile_info.tile_w = values[6];
 | 
			
		||||
      output->tile_info.tile_h = values[7];
 | 
			
		||||
    }
 | 
			
		||||
  XFree (prop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
                                MetaOutput               *output)
 | 
			
		||||
@@ -479,11 +543,10 @@ static MetaConnectorType
 | 
			
		||||
output_get_connector_type_from_prop (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
                                     MetaOutput               *output)
 | 
			
		||||
{
 | 
			
		||||
  MetaConnectorType ret = META_CONNECTOR_TYPE_Unknown;
 | 
			
		||||
  Atom atom, actual_type, connector_type_atom;
 | 
			
		||||
  int actual_format;
 | 
			
		||||
  unsigned long nitems, bytes_after;
 | 
			
		||||
  unsigned char *buffer;
 | 
			
		||||
  g_autofree unsigned char *buffer = NULL;
 | 
			
		||||
 | 
			
		||||
  atom = XInternAtom (manager_xrandr->xdisplay, "ConnectorType", False);
 | 
			
		||||
  XRRGetOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
@@ -494,14 +557,10 @@ output_get_connector_type_from_prop (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
                        &nitems, &bytes_after, &buffer);
 | 
			
		||||
 | 
			
		||||
  if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1)
 | 
			
		||||
    goto out;
 | 
			
		||||
    return META_CONNECTOR_TYPE_Unknown;
 | 
			
		||||
 | 
			
		||||
  connector_type_atom = ((Atom *) buffer)[0];
 | 
			
		||||
  ret = connector_type_from_atom (manager_xrandr, connector_type_atom);
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  meta_XFree (buffer);
 | 
			
		||||
  return ret;
 | 
			
		||||
  return connector_type_from_atom (manager_xrandr, connector_type_atom);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaConnectorType
 | 
			
		||||
@@ -538,7 +597,7 @@ output_get_connector_type_from_name (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
  if (g_str_has_prefix (name, "Virtual"))
 | 
			
		||||
    return META_CONNECTOR_TYPE_VIRTUAL;
 | 
			
		||||
  if (g_str_has_prefix (name, "Composite"))
 | 
			
		||||
    return META_CONNECTOR_TYPE_VGA;
 | 
			
		||||
    return META_CONNECTOR_TYPE_Composite;
 | 
			
		||||
  if (g_str_has_prefix (name, "S-video"))
 | 
			
		||||
    return META_CONNECTOR_TYPE_SVIDEO;
 | 
			
		||||
  if (g_str_has_prefix (name, "TV"))
 | 
			
		||||
@@ -736,6 +795,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
 | 
			
		||||
	  meta_output->suggested_y = output_get_suggested_y (manager_xrandr, meta_output);
 | 
			
		||||
          meta_output->connector_type = output_get_connector_type (manager_xrandr, meta_output);
 | 
			
		||||
 | 
			
		||||
	  output_get_tile_info (manager_xrandr, meta_output);
 | 
			
		||||
	  meta_output->n_modes = output->nmode;
 | 
			
		||||
	  meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
 | 
			
		||||
	  for (j = 0; j < meta_output->n_modes; j++)
 | 
			
		||||
@@ -789,6 +849,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
 | 
			
		||||
	  meta_output->is_primary = ((XID)meta_output->winsys_id == primary_output);
 | 
			
		||||
	  meta_output->is_presentation = output_get_presentation_xrandr (manager_xrandr, meta_output);
 | 
			
		||||
	  meta_output->is_underscanning = output_get_underscanning_xrandr (manager_xrandr, meta_output);
 | 
			
		||||
          meta_output->supports_underscanning = output_get_supports_underscanning_xrandr (manager_xrandr, meta_output);
 | 
			
		||||
	  output_get_backlight_limits_xrandr (manager_xrandr, meta_output);
 | 
			
		||||
 | 
			
		||||
	  if (!(meta_output->backlight_min == 0 && meta_output->backlight_max == 0))
 | 
			
		||||
@@ -902,11 +963,12 @@ output_set_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
  int value = presentation;
 | 
			
		||||
 | 
			
		||||
  atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False);
 | 
			
		||||
  XRRChangeOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
                           (XID)output->winsys_id,
 | 
			
		||||
                           atom,
 | 
			
		||||
                           XA_CARDINAL, 32, PropModeReplace,
 | 
			
		||||
                           (unsigned char*) &value, 1);
 | 
			
		||||
 | 
			
		||||
  xcb_randr_change_output_property (XGetXCBConnection (manager_xrandr->xdisplay),
 | 
			
		||||
                                    (XID)output->winsys_id,
 | 
			
		||||
                                    atom, XCB_ATOM_CARDINAL, 32,
 | 
			
		||||
                                    XCB_PROP_MODE_REPLACE,
 | 
			
		||||
                                    1, &value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -921,11 +983,12 @@ output_set_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
 | 
			
		||||
  value = underscanning ? "on" : "off";
 | 
			
		||||
  valueatom = XInternAtom (manager_xrandr->xdisplay, value, False);
 | 
			
		||||
  XRRChangeOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
                           (XID)output->winsys_id,
 | 
			
		||||
                           prop,
 | 
			
		||||
                           XA_ATOM, 32, PropModeReplace,
 | 
			
		||||
                           (unsigned char*) &valueatom, 1);
 | 
			
		||||
 | 
			
		||||
  xcb_randr_change_output_property (XGetXCBConnection (manager_xrandr->xdisplay),
 | 
			
		||||
                                    (XID)output->winsys_id,
 | 
			
		||||
                                    prop, XCB_ATOM_ATOM, 32,
 | 
			
		||||
                                    XCB_PROP_MODE_REPLACE,
 | 
			
		||||
                                    1, &valueatom);
 | 
			
		||||
 | 
			
		||||
  /* Configure the border at the same time. Currently, we use a
 | 
			
		||||
   * 5% of the width/height of the mode. In the future, we should
 | 
			
		||||
@@ -936,19 +999,21 @@ output_set_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
 | 
			
		||||
 | 
			
		||||
      prop = XInternAtom (manager_xrandr->xdisplay, "underscan hborder", False);
 | 
			
		||||
      border_value = output->crtc->current_mode->width * 0.05;
 | 
			
		||||
      XRRChangeOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
                               (XID)output->winsys_id,
 | 
			
		||||
                               prop,
 | 
			
		||||
                               XA_INTEGER, 32, PropModeReplace,
 | 
			
		||||
                               (unsigned char *) &border_value, 1);
 | 
			
		||||
 | 
			
		||||
      xcb_randr_change_output_property (XGetXCBConnection (manager_xrandr->xdisplay),
 | 
			
		||||
                                        (XID)output->winsys_id,
 | 
			
		||||
                                        prop, XCB_ATOM_INTEGER, 32,
 | 
			
		||||
                                        XCB_PROP_MODE_REPLACE,
 | 
			
		||||
                                        1, &border_value);
 | 
			
		||||
 | 
			
		||||
      prop = XInternAtom (manager_xrandr->xdisplay, "underscan vborder", False);
 | 
			
		||||
      border_value = output->crtc->current_mode->height * 0.05;
 | 
			
		||||
      XRRChangeOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
                               (XID)output->winsys_id,
 | 
			
		||||
                               prop,
 | 
			
		||||
                               XA_INTEGER, 32, PropModeReplace,
 | 
			
		||||
                               (unsigned char *) &border_value, 1);
 | 
			
		||||
 | 
			
		||||
      xcb_randr_change_output_property (XGetXCBConnection (manager_xrandr->xdisplay),
 | 
			
		||||
                                        (XID)output->winsys_id,
 | 
			
		||||
                                        prop, XCB_ATOM_INTEGER, 32,
 | 
			
		||||
                                        XCB_PROP_MODE_REPLACE,
 | 
			
		||||
                                        1, &border_value);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1068,7 +1133,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
 | 
			
		||||
      if (crtc_info->mode != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          MetaMonitorMode *mode;
 | 
			
		||||
          XID *outputs;
 | 
			
		||||
          g_autofree XID *outputs = NULL;
 | 
			
		||||
          unsigned int j, n_outputs;
 | 
			
		||||
          int width, height;
 | 
			
		||||
          Status ok;
 | 
			
		||||
@@ -1105,7 +1170,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
 | 
			
		||||
                            (unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id),
 | 
			
		||||
                            mode->width, mode->height, (float)mode->refresh_rate,
 | 
			
		||||
                            crtc_info->x, crtc_info->y, crtc_info->transform);
 | 
			
		||||
              goto next;
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          if (meta_monitor_transform_is_rotated (crtc_info->transform))
 | 
			
		||||
@@ -1125,9 +1190,6 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
 | 
			
		||||
          crtc->rect.height = height;
 | 
			
		||||
          crtc->current_mode = mode;
 | 
			
		||||
          crtc->transform = crtc_info->transform;
 | 
			
		||||
 | 
			
		||||
        next:
 | 
			
		||||
          g_free (outputs);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1147,9 +1209,10 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
 | 
			
		||||
                                      output_info->output,
 | 
			
		||||
                                      output_info->is_presentation);
 | 
			
		||||
 | 
			
		||||
      output_set_underscanning_xrandr (manager_xrandr,
 | 
			
		||||
                                       output_info->output,
 | 
			
		||||
                                       output_info->is_underscanning);
 | 
			
		||||
      if (output_get_supports_underscanning_xrandr (manager_xrandr, output_info->output))
 | 
			
		||||
        output_set_underscanning_xrandr (manager_xrandr,
 | 
			
		||||
                                         output_info->output,
 | 
			
		||||
                                         output_info->is_underscanning);
 | 
			
		||||
 | 
			
		||||
      output->is_primary = output_info->is_primary;
 | 
			
		||||
      output->is_presentation = output_info->is_presentation;
 | 
			
		||||
@@ -1187,11 +1250,12 @@ meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager,
 | 
			
		||||
  hw_value = round ((double)value / 100.0 * output->backlight_max + output->backlight_min);
 | 
			
		||||
 | 
			
		||||
  atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
 | 
			
		||||
  XRRChangeOutputProperty (manager_xrandr->xdisplay,
 | 
			
		||||
                           (XID)output->winsys_id,
 | 
			
		||||
                           atom,
 | 
			
		||||
                           XA_INTEGER, 32, PropModeReplace,
 | 
			
		||||
                           (unsigned char *) &hw_value, 1);
 | 
			
		||||
 | 
			
		||||
  xcb_randr_change_output_property (XGetXCBConnection (manager_xrandr->xdisplay),
 | 
			
		||||
                                    (XID)output->winsys_id,
 | 
			
		||||
                                    atom, XCB_ATOM_INTEGER, 32,
 | 
			
		||||
                                    XCB_PROP_MODE_REPLACE,
 | 
			
		||||
                                    1, &hw_value);
 | 
			
		||||
 | 
			
		||||
  /* We're not selecting for property notifies, so update the value immediately */
 | 
			
		||||
  output->backlight = normalize_backlight (output, hw_value);
 | 
			
		||||
@@ -1239,6 +1303,88 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager,
 | 
			
		||||
  XRRFreeGamma (gamma);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_XRANDR15
 | 
			
		||||
static void
 | 
			
		||||
meta_monitor_manager_xrandr_add_monitor(MetaMonitorManager *manager,
 | 
			
		||||
                                        MetaMonitorInfo *monitor)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
 | 
			
		||||
  XRRMonitorInfo *m;
 | 
			
		||||
  int o;
 | 
			
		||||
  Atom name;
 | 
			
		||||
  char name_buf[40];
 | 
			
		||||
 | 
			
		||||
  if (manager_xrandr->has_randr15 == FALSE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (monitor->n_outputs <= 1)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (monitor->outputs[0]->product)
 | 
			
		||||
    snprintf (name_buf, 40, "%s-%d", monitor->outputs[0]->product, monitor->outputs[0]->tile_info.group_id);
 | 
			
		||||
  else
 | 
			
		||||
    snprintf (name_buf, 40, "Tiled-%d", monitor->outputs[0]->tile_info.group_id);
 | 
			
		||||
 | 
			
		||||
  name = XInternAtom (manager_xrandr->xdisplay, name_buf, False);
 | 
			
		||||
  monitor->monitor_winsys_xid = name;
 | 
			
		||||
  m = XRRAllocateMonitor (manager_xrandr->xdisplay, monitor->n_outputs);
 | 
			
		||||
  if (!m)
 | 
			
		||||
    return;
 | 
			
		||||
  m->name = name;
 | 
			
		||||
  m->primary = monitor->is_primary;
 | 
			
		||||
  m->automatic = True;
 | 
			
		||||
 | 
			
		||||
  for (o = 0; o < monitor->n_outputs; o++) {
 | 
			
		||||
    MetaOutput *output = monitor->outputs[o];
 | 
			
		||||
    m->outputs[o] = output->winsys_id;
 | 
			
		||||
  }
 | 
			
		||||
  XRRSetMonitor (manager_xrandr->xdisplay,
 | 
			
		||||
                 DefaultRootWindow (manager_xrandr->xdisplay),
 | 
			
		||||
                 m);
 | 
			
		||||
  XRRFreeMonitors (m);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_monitor_manager_xrandr_delete_monitor(MetaMonitorManager *manager,
 | 
			
		||||
                                           int monitor_winsys_xid)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
 | 
			
		||||
 | 
			
		||||
  if (manager_xrandr->has_randr15 == FALSE)
 | 
			
		||||
    return;
 | 
			
		||||
  XRRDeleteMonitor (manager_xrandr->xdisplay,
 | 
			
		||||
                    DefaultRootWindow (manager_xrandr->xdisplay),
 | 
			
		||||
                    monitor_winsys_xid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_monitor_manager_xrandr_init_monitors(MetaMonitorManagerXrandr *manager_xrandr)
 | 
			
		||||
{
 | 
			
		||||
  XRRMonitorInfo *m;
 | 
			
		||||
  int n, i;
 | 
			
		||||
 | 
			
		||||
  if (manager_xrandr->has_randr15 == FALSE)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* delete any tiled monitors setup, as mutter will want to recreate
 | 
			
		||||
     things in its image */
 | 
			
		||||
  m = XRRGetMonitors (manager_xrandr->xdisplay,
 | 
			
		||||
                      DefaultRootWindow (manager_xrandr->xdisplay),
 | 
			
		||||
                      FALSE, &n);
 | 
			
		||||
  if (n == -1)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (m[i].noutput > 1)
 | 
			
		||||
        XRRDeleteMonitor (manager_xrandr->xdisplay,
 | 
			
		||||
                          DefaultRootWindow (manager_xrandr->xdisplay),
 | 
			
		||||
                          m[i].name);
 | 
			
		||||
    }
 | 
			
		||||
  XRRFreeMonitors (m);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
 | 
			
		||||
{
 | 
			
		||||
@@ -1254,6 +1400,7 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      int major_version, minor_version;
 | 
			
		||||
      /* We only use ScreenChangeNotify, but GDK uses the others,
 | 
			
		||||
	 and we don't want to step on its toes */
 | 
			
		||||
      XRRSelectInput (manager_xrandr->xdisplay,
 | 
			
		||||
@@ -1261,6 +1408,17 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
 | 
			
		||||
		      RRScreenChangeNotifyMask
 | 
			
		||||
		      | RRCrtcChangeNotifyMask
 | 
			
		||||
		      | RROutputPropertyNotifyMask);
 | 
			
		||||
 | 
			
		||||
      manager_xrandr->has_randr15 = FALSE;
 | 
			
		||||
      XRRQueryVersion (manager_xrandr->xdisplay, &major_version,
 | 
			
		||||
                       &minor_version);
 | 
			
		||||
#ifdef HAVE_XRANDR15
 | 
			
		||||
      if (major_version > 1 ||
 | 
			
		||||
          (major_version == 1 &&
 | 
			
		||||
           minor_version >= 5))
 | 
			
		||||
        manager_xrandr->has_randr15 = TRUE;
 | 
			
		||||
      meta_monitor_manager_xrandr_init_monitors (manager_xrandr);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1291,6 +1449,10 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
 | 
			
		||||
  manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight;
 | 
			
		||||
  manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma;
 | 
			
		||||
  manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma;
 | 
			
		||||
#ifdef HAVE_XRANDR15
 | 
			
		||||
  manager_class->add_monitor = meta_monitor_manager_xrandr_add_monitor;
 | 
			
		||||
  manager_class->delete_monitor = meta_monitor_manager_xrandr_delete_monitor;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
 
 | 
			
		||||
@@ -37,11 +37,6 @@
 | 
			
		||||
 * compositor needs to delay hiding the windows until the switch
 | 
			
		||||
 * workspace animation completes.
 | 
			
		||||
 *
 | 
			
		||||
 * meta_compositor_maximize_window() and meta_compositor_unmaximize_window()
 | 
			
		||||
 * are transitions within the visible state. The window is resized __before__
 | 
			
		||||
 * the call, so it may be necessary to readjust the display based on the
 | 
			
		||||
 * old_rect to start the animation.
 | 
			
		||||
 *
 | 
			
		||||
 * # Containers #
 | 
			
		||||
 *
 | 
			
		||||
 * There's two containers in the stage that are used to place window actors, here
 | 
			
		||||
@@ -769,23 +764,14 @@ meta_compositor_hide_window (MetaCompositor *compositor,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_maximize_window (MetaCompositor    *compositor,
 | 
			
		||||
                                 MetaWindow        *window,
 | 
			
		||||
				 MetaRectangle	   *old_rect,
 | 
			
		||||
				 MetaRectangle	   *new_rect)
 | 
			
		||||
meta_compositor_size_change_window (MetaCompositor    *compositor,
 | 
			
		||||
                                    MetaWindow        *window,
 | 
			
		||||
                                    MetaSizeChange     which_change,
 | 
			
		||||
                                    MetaRectangle     *old_frame_rect,
 | 
			
		||||
                                    MetaRectangle     *old_buffer_rect)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
 | 
			
		||||
  meta_window_actor_maximize (window_actor, old_rect, new_rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_compositor_unmaximize_window (MetaCompositor    *compositor,
 | 
			
		||||
                                   MetaWindow        *window,
 | 
			
		||||
				   MetaRectangle     *old_rect,
 | 
			
		||||
				   MetaRectangle     *new_rect)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
 | 
			
		||||
  meta_window_actor_unmaximize (window_actor, old_rect, new_rect);
 | 
			
		||||
  meta_window_actor_size_change (window_actor, META_SIZE_CHANGE_MAXIMIZE, old_frame_rect, old_buffer_rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -187,7 +187,7 @@ meta_feedback_actor_set_anchor (MetaFeedbackActor *self,
 | 
			
		||||
  if (priv->anchor_x == anchor_x && priv->anchor_y == anchor_y)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (priv->anchor_x != anchor_y)
 | 
			
		||||
  if (priv->anchor_x != anchor_x)
 | 
			
		||||
    {
 | 
			
		||||
      priv->anchor_x = anchor_x;
 | 
			
		||||
      g_object_notify (G_OBJECT (self), "anchor-x");
 | 
			
		||||
 
 | 
			
		||||
@@ -149,7 +149,7 @@ meta_plugin_manager_kill_switch_workspace (MetaPluginManager *plugin_mgr)
 | 
			
		||||
gboolean
 | 
			
		||||
meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
 | 
			
		||||
                                  MetaWindowActor   *actor,
 | 
			
		||||
                                  unsigned long      event)
 | 
			
		||||
                                  MetaPluginEffect   event)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin *plugin = plugin_mgr->plugin;
 | 
			
		||||
  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
@@ -196,67 +196,32 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      g_warning ("Incorrect handler called for event %lu", event);
 | 
			
		||||
      g_warning ("Incorrect handler called for event %d", event);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return retval;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The public method that the compositor hooks into for maximize and unmaximize
 | 
			
		||||
 * events.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns TRUE if the plugin handled the event type (i.e.,
 | 
			
		||||
 * if the return value is FALSE, there will be no subsequent call to the
 | 
			
		||||
 * manager completed() callback, and the compositor must ensure that any
 | 
			
		||||
 * appropriate post-effect cleanup is carried out.
 | 
			
		||||
 */
 | 
			
		||||
gboolean
 | 
			
		||||
meta_plugin_manager_event_maximize (MetaPluginManager *plugin_mgr,
 | 
			
		||||
                                    MetaWindowActor   *actor,
 | 
			
		||||
                                    unsigned long      event,
 | 
			
		||||
                                    gint               target_x,
 | 
			
		||||
                                    gint               target_y,
 | 
			
		||||
                                    gint               target_width,
 | 
			
		||||
                                    gint               target_height)
 | 
			
		||||
meta_plugin_manager_event_size_change (MetaPluginManager *plugin_mgr,
 | 
			
		||||
                                       MetaWindowActor   *actor,
 | 
			
		||||
                                       MetaSizeChange     which_change,
 | 
			
		||||
                                       MetaRectangle     *old_frame_rect,
 | 
			
		||||
                                       MetaRectangle     *old_buffer_rect)
 | 
			
		||||
{
 | 
			
		||||
  MetaPlugin *plugin = plugin_mgr->plugin;
 | 
			
		||||
  MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
 | 
			
		||||
  MetaDisplay *display = plugin_mgr->compositor->display;
 | 
			
		||||
  gboolean retval = FALSE;
 | 
			
		||||
 | 
			
		||||
  if (display->display_opening)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  switch (event)
 | 
			
		||||
    {
 | 
			
		||||
    case META_PLUGIN_MAXIMIZE:
 | 
			
		||||
      if (klass->maximize)
 | 
			
		||||
        {
 | 
			
		||||
          retval = TRUE;
 | 
			
		||||
          meta_plugin_manager_kill_window_effects (plugin_mgr,
 | 
			
		||||
                                                   actor);
 | 
			
		||||
          klass->maximize (plugin, actor,
 | 
			
		||||
                           target_x, target_y,
 | 
			
		||||
                           target_width, target_height);
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PLUGIN_UNMAXIMIZE:
 | 
			
		||||
      if (klass->unmaximize)
 | 
			
		||||
        {
 | 
			
		||||
          retval = TRUE;
 | 
			
		||||
          meta_plugin_manager_kill_window_effects (plugin_mgr,
 | 
			
		||||
                                                   actor);
 | 
			
		||||
          klass->unmaximize (plugin, actor,
 | 
			
		||||
                             target_x, target_y,
 | 
			
		||||
                             target_width, target_height);
 | 
			
		||||
        }
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      g_warning ("Incorrect handler called for event %lu", event);
 | 
			
		||||
    }
 | 
			
		||||
  if (!klass->size_change)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return retval;
 | 
			
		||||
  meta_plugin_manager_kill_window_effects (plugin_mgr, actor);
 | 
			
		||||
  klass->size_change (plugin, actor, which_change, old_frame_rect, old_buffer_rect);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -24,20 +24,17 @@
 | 
			
		||||
 | 
			
		||||
#include <meta/types.h>
 | 
			
		||||
#include <meta/screen.h>
 | 
			
		||||
 | 
			
		||||
#define  META_PLUGIN_FROM_MANAGER_
 | 
			
		||||
#include <meta/meta-plugin.h>
 | 
			
		||||
#undef   META_PLUGIN_FROM_MANAGER_
 | 
			
		||||
 | 
			
		||||
#define META_PLUGIN_MINIMIZE         (1<<0)
 | 
			
		||||
#define META_PLUGIN_MAXIMIZE         (1<<1)
 | 
			
		||||
#define META_PLUGIN_UNMAXIMIZE       (1<<2)
 | 
			
		||||
#define META_PLUGIN_MAP              (1<<3)
 | 
			
		||||
#define META_PLUGIN_DESTROY          (1<<4)
 | 
			
		||||
#define META_PLUGIN_SWITCH_WORKSPACE (1<<5)
 | 
			
		||||
#define META_PLUGIN_UNMINIMIZE       (1<<6)
 | 
			
		||||
 | 
			
		||||
#define META_PLUGIN_ALL_EFFECTS      (~0)
 | 
			
		||||
typedef enum {
 | 
			
		||||
  META_PLUGIN_NONE,
 | 
			
		||||
  META_PLUGIN_MINIMIZE,
 | 
			
		||||
  META_PLUGIN_MAP,
 | 
			
		||||
  META_PLUGIN_DESTROY,
 | 
			
		||||
  META_PLUGIN_SWITCH_WORKSPACE,
 | 
			
		||||
  META_PLUGIN_UNMINIMIZE,
 | 
			
		||||
  META_PLUGIN_SIZE_CHANGE,
 | 
			
		||||
} MetaPluginEffect;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MetaPluginManager: (skip)
 | 
			
		||||
@@ -51,15 +48,13 @@ void     meta_plugin_manager_load         (const gchar       *plugin_name);
 | 
			
		||||
 | 
			
		||||
gboolean meta_plugin_manager_event_simple (MetaPluginManager *mgr,
 | 
			
		||||
                                           MetaWindowActor   *actor,
 | 
			
		||||
                                           unsigned long      event);
 | 
			
		||||
                                           MetaPluginEffect   event);
 | 
			
		||||
 | 
			
		||||
gboolean meta_plugin_manager_event_maximize    (MetaPluginManager *mgr,
 | 
			
		||||
                                                MetaWindowActor   *actor,
 | 
			
		||||
                                                unsigned long      event,
 | 
			
		||||
                                                gint               target_x,
 | 
			
		||||
                                                gint               target_y,
 | 
			
		||||
                                                gint               target_width,
 | 
			
		||||
                                                gint               target_height);
 | 
			
		||||
gboolean meta_plugin_manager_event_size_change    (MetaPluginManager *mgr,
 | 
			
		||||
                                                   MetaWindowActor   *actor,
 | 
			
		||||
                                                   MetaSizeChange     which_change,
 | 
			
		||||
                                                   MetaRectangle     *old_frame_rect,
 | 
			
		||||
                                                   MetaRectangle     *old_buffer_rect);
 | 
			
		||||
 | 
			
		||||
gboolean meta_plugin_manager_switch_workspace (MetaPluginManager   *mgr,
 | 
			
		||||
                                               gint                 from,
 | 
			
		||||
 
 | 
			
		||||
@@ -118,17 +118,10 @@ meta_plugin_unminimize_completed (MetaPlugin      *plugin,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_maximize_completed (MetaPlugin      *plugin,
 | 
			
		||||
                                MetaWindowActor *actor)
 | 
			
		||||
meta_plugin_size_change_completed (MetaPlugin      *plugin,
 | 
			
		||||
                                   MetaWindowActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MAXIMIZE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_unmaximize_completed (MetaPlugin      *plugin,
 | 
			
		||||
                                  MetaWindowActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_UNMAXIMIZE);
 | 
			
		||||
  meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_SIZE_CHANGE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -1,66 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
/*
 | 
			
		||||
 * MetaShadowFactory:
 | 
			
		||||
 *
 | 
			
		||||
 * Create and cache shadow textures for arbitrary window shapes
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 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/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __META_SHADOW_FACTORY_PRIVATE_H__
 | 
			
		||||
#define __META_SHADOW_FACTORY_PRIVATE_H__
 | 
			
		||||
 | 
			
		||||
#include <cairo.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include "meta-window-shape.h"
 | 
			
		||||
#include <meta/meta-shadow-factory.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MetaShadow:
 | 
			
		||||
 * #MetaShadow holds a shadow texture along with information about how to
 | 
			
		||||
 * apply that texture to draw a window texture. (E.g., it knows how big the
 | 
			
		||||
 * unscaled borders are on each side of the shadow texture.)
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _MetaShadow MetaShadow;
 | 
			
		||||
 | 
			
		||||
MetaShadow *meta_shadow_ref         (MetaShadow            *shadow);
 | 
			
		||||
void        meta_shadow_unref       (MetaShadow            *shadow);
 | 
			
		||||
CoglTexture*meta_shadow_get_texture (MetaShadow            *shadow);
 | 
			
		||||
void        meta_shadow_paint       (MetaShadow            *shadow,
 | 
			
		||||
                                     int                    window_x,
 | 
			
		||||
                                     int                    window_y,
 | 
			
		||||
                                     int                    window_width,
 | 
			
		||||
                                     int                    window_height,
 | 
			
		||||
                                     guint8                 opacity,
 | 
			
		||||
                                     cairo_region_t        *clip,
 | 
			
		||||
                                     gboolean               clip_strictly);
 | 
			
		||||
void        meta_shadow_get_bounds  (MetaShadow            *shadow,
 | 
			
		||||
                                     int                    window_x,
 | 
			
		||||
                                     int                    window_y,
 | 
			
		||||
                                     int                    window_width,
 | 
			
		||||
                                     int                    window_height,
 | 
			
		||||
                                     cairo_rectangle_int_t *bounds);
 | 
			
		||||
 | 
			
		||||
MetaShadowFactory *meta_shadow_factory_new (void);
 | 
			
		||||
 | 
			
		||||
MetaShadow *meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
 | 
			
		||||
                                            MetaWindowShape   *shape,
 | 
			
		||||
                                            int                width,
 | 
			
		||||
                                            int                height,
 | 
			
		||||
                                            const char        *class_name,
 | 
			
		||||
                                            gboolean           focused);
 | 
			
		||||
 | 
			
		||||
#endif /* __META_SHADOW_FACTORY_PRIVATE_H__ */
 | 
			
		||||
@@ -26,8 +26,9 @@
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-shadow-factory.h>
 | 
			
		||||
 | 
			
		||||
#include "cogl-utils.h"
 | 
			
		||||
#include "meta-shadow-factory-private.h"
 | 
			
		||||
#include "region-utils.h"
 | 
			
		||||
 | 
			
		||||
/* This file implements blurring the shape of a window to produce a
 | 
			
		||||
@@ -1048,3 +1049,6 @@ meta_shadow_factory_get_params (MetaShadowFactory *factory,
 | 
			
		||||
  if (params)
 | 
			
		||||
    *params = *stored_params;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_DEFINE_BOXED_TYPE (MetaShadow, meta_shadow,
 | 
			
		||||
                     meta_shadow_ref, meta_shadow_unref)
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,9 @@
 | 
			
		||||
ClutterActor *meta_shaped_texture_new (void);
 | 
			
		||||
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
 | 
			
		||||
                                      CoglTexture       *texture);
 | 
			
		||||
void meta_shaped_texture_set_fallback_size (MetaShapedTexture *stex,
 | 
			
		||||
                                            guint              fallback_width,
 | 
			
		||||
                                            guint              fallback_height);
 | 
			
		||||
gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -86,6 +86,7 @@ struct _MetaShapedTexturePrivate
 | 
			
		||||
  cairo_region_t *unobscured_region;
 | 
			
		||||
 | 
			
		||||
  guint tex_width, tex_height;
 | 
			
		||||
  guint fallback_width, fallback_height;
 | 
			
		||||
 | 
			
		||||
  guint create_mipmaps : 1;
 | 
			
		||||
};
 | 
			
		||||
@@ -136,7 +137,20 @@ set_unobscured_region (MetaShapedTexture *self,
 | 
			
		||||
  g_clear_pointer (&priv->unobscured_region, (GDestroyNotify) cairo_region_destroy);
 | 
			
		||||
  if (unobscured_region)
 | 
			
		||||
    {
 | 
			
		||||
      cairo_rectangle_int_t bounds = { 0, 0, priv->tex_width, priv->tex_height };
 | 
			
		||||
      guint width, height;
 | 
			
		||||
 | 
			
		||||
      if (priv->texture)
 | 
			
		||||
        {
 | 
			
		||||
          width = priv->tex_width;
 | 
			
		||||
          height = priv->tex_height;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          width = priv->fallback_width;
 | 
			
		||||
          height = priv->fallback_height;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      cairo_rectangle_int_t bounds = { 0, 0, width, height };
 | 
			
		||||
      priv->unobscured_region = cairo_region_copy (unobscured_region);
 | 
			
		||||
      cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
 | 
			
		||||
    }
 | 
			
		||||
@@ -173,10 +187,25 @@ meta_shaped_texture_dispose (GObject *object)
 | 
			
		||||
  G_OBJECT_CLASS (meta_shaped_texture_parent_class)->dispose (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CoglPipeline *
 | 
			
		||||
get_base_pipeline (CoglContext *ctx)
 | 
			
		||||
{
 | 
			
		||||
  static CoglPipeline *template = NULL;
 | 
			
		||||
  if (G_UNLIKELY (template == NULL))
 | 
			
		||||
    {
 | 
			
		||||
      template = cogl_pipeline_new (ctx);
 | 
			
		||||
      cogl_pipeline_set_layer_wrap_mode_s (template, 0, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
 | 
			
		||||
      cogl_pipeline_set_layer_wrap_mode_t (template, 0, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
 | 
			
		||||
      cogl_pipeline_set_layer_wrap_mode_s (template, 1, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
 | 
			
		||||
      cogl_pipeline_set_layer_wrap_mode_t (template, 1, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);
 | 
			
		||||
    }
 | 
			
		||||
  return template;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CoglPipeline *
 | 
			
		||||
get_unmasked_pipeline (CoglContext *ctx)
 | 
			
		||||
{
 | 
			
		||||
  return cogl_pipeline_new (ctx);
 | 
			
		||||
  return get_base_pipeline (ctx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CoglPipeline *
 | 
			
		||||
@@ -185,13 +214,13 @@ get_masked_pipeline (CoglContext *ctx)
 | 
			
		||||
  static CoglPipeline *template = NULL;
 | 
			
		||||
  if (G_UNLIKELY (template == NULL))
 | 
			
		||||
    {
 | 
			
		||||
      template = cogl_pipeline_new (ctx);
 | 
			
		||||
      template = cogl_pipeline_copy (get_base_pipeline (ctx));
 | 
			
		||||
      cogl_pipeline_set_layer_combine (template, 1,
 | 
			
		||||
                                       "RGBA = MODULATE (PREVIOUS, TEXTURE[A])",
 | 
			
		||||
                                       NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return cogl_pipeline_copy (template);
 | 
			
		||||
  return template;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CoglPipeline *
 | 
			
		||||
@@ -201,7 +230,7 @@ get_unblended_pipeline (CoglContext *ctx)
 | 
			
		||||
  if (G_UNLIKELY (template == NULL))
 | 
			
		||||
    {
 | 
			
		||||
      CoglColor color;
 | 
			
		||||
      template = cogl_pipeline_new (ctx);
 | 
			
		||||
      template = cogl_pipeline_copy (get_base_pipeline (ctx));
 | 
			
		||||
      cogl_color_init_from_4ub (&color, 255, 255, 255, 255);
 | 
			
		||||
      cogl_pipeline_set_blend (template,
 | 
			
		||||
                               "RGBA = ADD (SRC_COLOR, 0)",
 | 
			
		||||
@@ -209,7 +238,7 @@ get_unblended_pipeline (CoglContext *ctx)
 | 
			
		||||
      cogl_pipeline_set_color (template, &color);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return cogl_pipeline_copy (template);
 | 
			
		||||
  return template;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -420,8 +449,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
              cairo_region_get_rectangle (region, i, &rect);
 | 
			
		||||
              paint_clipped_rectangle (fb, opaque_pipeline, &rect, &alloc);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          cogl_object_unref (opaque_pipeline);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      cairo_region_destroy (region);
 | 
			
		||||
@@ -484,8 +511,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
 | 
			
		||||
                                           alloc.x2 - alloc.x1,
 | 
			
		||||
                                           alloc.y2 - alloc.y1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      cogl_object_unref (blended_pipeline);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (blended_region != NULL)
 | 
			
		||||
@@ -498,17 +523,18 @@ meta_shaped_texture_get_preferred_width (ClutterActor *self,
 | 
			
		||||
                                         gfloat       *min_width_p,
 | 
			
		||||
                                         gfloat       *natural_width_p)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
  MetaShapedTexturePrivate *priv = META_SHAPED_TEXTURE (self)->priv;
 | 
			
		||||
  guint width;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_SHAPED_TEXTURE (self));
 | 
			
		||||
 | 
			
		||||
  priv = META_SHAPED_TEXTURE (self)->priv;
 | 
			
		||||
  if (priv->texture)
 | 
			
		||||
    width = priv->tex_width;
 | 
			
		||||
  else
 | 
			
		||||
    width = priv->fallback_width;
 | 
			
		||||
 | 
			
		||||
  if (min_width_p)
 | 
			
		||||
    *min_width_p = priv->tex_width;
 | 
			
		||||
 | 
			
		||||
    *min_width_p = width;
 | 
			
		||||
  if (natural_width_p)
 | 
			
		||||
    *natural_width_p = priv->tex_width;
 | 
			
		||||
    *natural_width_p = width;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -517,17 +543,18 @@ meta_shaped_texture_get_preferred_height (ClutterActor *self,
 | 
			
		||||
                                          gfloat       *min_height_p,
 | 
			
		||||
                                          gfloat       *natural_height_p)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv;
 | 
			
		||||
  MetaShapedTexturePrivate *priv = META_SHAPED_TEXTURE (self)->priv;
 | 
			
		||||
  guint height;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_SHAPED_TEXTURE (self));
 | 
			
		||||
 | 
			
		||||
  priv = META_SHAPED_TEXTURE (self)->priv;
 | 
			
		||||
  if (priv->texture)
 | 
			
		||||
    height = priv->tex_height;
 | 
			
		||||
  else
 | 
			
		||||
    height = priv->fallback_height;
 | 
			
		||||
 | 
			
		||||
  if (min_height_p)
 | 
			
		||||
    *min_height_p = priv->tex_height;
 | 
			
		||||
 | 
			
		||||
    *min_height_p = height;
 | 
			
		||||
  if (natural_height_p)
 | 
			
		||||
    *natural_height_p = priv->tex_height;
 | 
			
		||||
    *natural_height_p = height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static cairo_region_t *
 | 
			
		||||
@@ -860,6 +887,17 @@ meta_shaped_texture_get_image (MetaShapedTexture     *stex,
 | 
			
		||||
  return surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_shaped_texture_set_fallback_size (MetaShapedTexture *self,
 | 
			
		||||
                                       guint              fallback_width,
 | 
			
		||||
                                       guint              fallback_height)
 | 
			
		||||
{
 | 
			
		||||
  MetaShapedTexturePrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  priv->fallback_width = fallback_width;
 | 
			
		||||
  priv->fallback_height = fallback_height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_shaped_texture_cull_out (MetaCullable   *cullable,
 | 
			
		||||
                              cairo_region_t *unobscured_region,
 | 
			
		||||
 
 | 
			
		||||
@@ -26,10 +26,13 @@
 | 
			
		||||
 | 
			
		||||
#include "meta-surface-actor-wayland.h"
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
#include <cogl/cogl-wayland-server.h>
 | 
			
		||||
#include "meta-shaped-texture-private.h"
 | 
			
		||||
 | 
			
		||||
#include "wayland/meta-wayland-buffer.h"
 | 
			
		||||
#include "wayland/meta-wayland-private.h"
 | 
			
		||||
#include "wayland/meta-window-wayland.h"
 | 
			
		||||
 | 
			
		||||
#include "compositor/region-utils.h"
 | 
			
		||||
 | 
			
		||||
@@ -80,53 +83,89 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
get_output_scale (int winsys_id)
 | 
			
		||||
{
 | 
			
		||||
  MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
 | 
			
		||||
  MetaOutput *outputs;
 | 
			
		||||
  guint n_outputs, i;
 | 
			
		||||
  int output_scale = 1;
 | 
			
		||||
 | 
			
		||||
  outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (outputs[i].winsys_id == winsys_id)
 | 
			
		||||
        {
 | 
			
		||||
          output_scale = outputs[i].scale;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return output_scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double
 | 
			
		||||
meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor)
 | 
			
		||||
{
 | 
			
		||||
   MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (actor);
 | 
			
		||||
   MetaWaylandSurface *surface = priv->surface;
 | 
			
		||||
   MetaWindow *window = surface->window;
 | 
			
		||||
   MetaWindow *window;
 | 
			
		||||
   int output_scale = 1;
 | 
			
		||||
 | 
			
		||||
   while (surface)
 | 
			
		||||
    {
 | 
			
		||||
      if (surface->window)
 | 
			
		||||
        {
 | 
			
		||||
          window = surface->window;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      surface = surface->sub.parent;
 | 
			
		||||
    }
 | 
			
		||||
   if (!surface)
 | 
			
		||||
     return 1;
 | 
			
		||||
 | 
			
		||||
   window = meta_wayland_surface_get_toplevel_window (surface);
 | 
			
		||||
 | 
			
		||||
   /* XXX: We do not handle x11 clients yet */
 | 
			
		||||
   if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
 | 
			
		||||
     output_scale = get_output_scale (window->monitor->winsys_id);
 | 
			
		||||
     output_scale = meta_window_wayland_get_main_monitor_scale (window);
 | 
			
		||||
 | 
			
		||||
   return (double)output_scale / (double)priv->surface->scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
logical_to_actor_position (MetaSurfaceActorWayland *self,
 | 
			
		||||
                           int                     *x,
 | 
			
		||||
                           int                     *y)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
 | 
			
		||||
  MetaWindow *toplevel_window;
 | 
			
		||||
  int monitor_scale = 1;
 | 
			
		||||
 | 
			
		||||
  toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
 | 
			
		||||
  if (toplevel_window)
 | 
			
		||||
    monitor_scale = meta_window_wayland_get_main_monitor_scale (toplevel_window);
 | 
			
		||||
 | 
			
		||||
  *x = *x * monitor_scale;
 | 
			
		||||
  *y = *y * monitor_scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Convert the current actor state to the corresponding subsurface rectangle
 | 
			
		||||
 * in logical pixel coordinate space. */
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self,
 | 
			
		||||
                                                MetaRectangle           *rect)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
 | 
			
		||||
  CoglTexture *texture = surface->buffer->texture;
 | 
			
		||||
  MetaWindow *toplevel_window;
 | 
			
		||||
  int monitor_scale;
 | 
			
		||||
  float x, y;
 | 
			
		||||
 | 
			
		||||
  toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
 | 
			
		||||
  monitor_scale = meta_window_wayland_get_main_monitor_scale (toplevel_window);
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_position (CLUTTER_ACTOR (self), &x, &y);
 | 
			
		||||
  *rect = (MetaRectangle) {
 | 
			
		||||
    .x = x / monitor_scale,
 | 
			
		||||
    .y = y / monitor_scale,
 | 
			
		||||
    .width = cogl_texture_get_width (texture) / surface->scale,
 | 
			
		||||
    .height = cogl_texture_get_height (texture) / surface->scale,
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
 | 
			
		||||
  MetaWindow *window;
 | 
			
		||||
  int x = surface->offset_x + surface->sub.x;
 | 
			
		||||
  int y = surface->offset_y + surface->sub.y;
 | 
			
		||||
 | 
			
		||||
  window = meta_wayland_surface_get_toplevel_window (surface);
 | 
			
		||||
  if (window && window->client_type == META_WINDOW_CLIENT_TYPE_X11)
 | 
			
		||||
    {
 | 
			
		||||
      /* Bail directly if this is part of a Xwayland window and warn
 | 
			
		||||
       * if there happen to be offsets anyway since that is not supposed
 | 
			
		||||
       * to happen. */
 | 
			
		||||
      g_warn_if_fail (x == 0 && y == 0);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  logical_to_actor_position (self, &x, &y);
 | 
			
		||||
  clutter_actor_set_position (CLUTTER_ACTOR (self), x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
 | 
			
		||||
{
 | 
			
		||||
@@ -173,25 +212,65 @@ meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
 | 
			
		||||
                                            scaled_opaque_region);
 | 
			
		||||
      cairo_region_destroy (scaled_opaque_region);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_surface_actor_wayland_sync_subsurface_state (self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
 | 
			
		||||
  MetaWindow *window = meta_wayland_surface_get_toplevel_window (surface);
 | 
			
		||||
  GList *iter;
 | 
			
		||||
 | 
			
		||||
  meta_surface_actor_wayland_sync_state (self);
 | 
			
		||||
 | 
			
		||||
  for (iter = surface->subsurfaces; iter != NULL; iter = iter->next)
 | 
			
		||||
  if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWaylandSurface *subsurf = iter->data;
 | 
			
		||||
      for (iter = surface->subsurfaces; iter != NULL; iter = iter->next)
 | 
			
		||||
        {
 | 
			
		||||
          MetaWaylandSurface *subsurf = iter->data;
 | 
			
		||||
 | 
			
		||||
      meta_surface_actor_wayland_sync_state_recursive (
 | 
			
		||||
        META_SURFACE_ACTOR_WAYLAND (subsurf->surface_actor));
 | 
			
		||||
          meta_surface_actor_wayland_sync_state_recursive (
 | 
			
		||||
            META_SURFACE_ACTOR_WAYLAND (subsurf->surface_actor));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
 | 
			
		||||
                                          MetaMonitorInfo         *monitor)
 | 
			
		||||
{
 | 
			
		||||
  float x, y, width, height;
 | 
			
		||||
  cairo_rectangle_int_t actor_rect;
 | 
			
		||||
  cairo_region_t *region;
 | 
			
		||||
  gboolean is_on_monitor;
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_transformed_position (CLUTTER_ACTOR (self), &x, &y);
 | 
			
		||||
  clutter_actor_get_transformed_size (CLUTTER_ACTOR (self), &width, &height);
 | 
			
		||||
 | 
			
		||||
  actor_rect.x = (int)roundf (x);
 | 
			
		||||
  actor_rect.y = (int)roundf (y);
 | 
			
		||||
  actor_rect.width = (int)roundf (x + width) - actor_rect.x;
 | 
			
		||||
  actor_rect.height = (int)roundf (y + height) - actor_rect.y;
 | 
			
		||||
 | 
			
		||||
  /* Calculate the scaled surface actor region. */
 | 
			
		||||
  region = cairo_region_create_rectangle (&actor_rect);
 | 
			
		||||
 | 
			
		||||
  cairo_region_intersect_rectangle (region,
 | 
			
		||||
				    &((cairo_rectangle_int_t) {
 | 
			
		||||
				      .x = monitor->rect.x,
 | 
			
		||||
				      .y = monitor->rect.y,
 | 
			
		||||
				      .width = monitor->rect.width,
 | 
			
		||||
				      .height = monitor->rect.height,
 | 
			
		||||
				    }));
 | 
			
		||||
 | 
			
		||||
  is_on_monitor = !cairo_region_is_empty (region);
 | 
			
		||||
  cairo_region_destroy (region);
 | 
			
		||||
 | 
			
		||||
  return is_on_monitor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaWindow *
 | 
			
		||||
meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
 | 
			
		||||
{
 | 
			
		||||
@@ -236,6 +315,19 @@ meta_surface_actor_wayland_get_preferred_height  (ClutterActor *self,
 | 
			
		||||
    *natural_height_p *= scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_surface_actor_wayland_paint (ClutterActor *actor)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
 | 
			
		||||
  MetaSurfaceActorWaylandPrivate *priv =
 | 
			
		||||
    meta_surface_actor_wayland_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  if (priv->surface)
 | 
			
		||||
    meta_wayland_surface_update_outputs (priv->surface);
 | 
			
		||||
 | 
			
		||||
  CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_surface_actor_wayland_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
@@ -255,6 +347,7 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
 | 
			
		||||
 | 
			
		||||
  actor_class->get_preferred_width = meta_surface_actor_wayland_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height = meta_surface_actor_wayland_get_preferred_height;
 | 
			
		||||
  actor_class->paint = meta_surface_actor_wayland_paint;
 | 
			
		||||
 | 
			
		||||
  surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
 | 
			
		||||
  surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
 | 
			
		||||
@@ -301,3 +394,12 @@ meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self)
 | 
			
		||||
  MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
 | 
			
		||||
  return priv->surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_surface_actor_wayland_surface_destroyed (MetaSurfaceActorWayland *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorWaylandPrivate *priv =
 | 
			
		||||
    meta_surface_actor_wayland_get_instance_private (self);
 | 
			
		||||
 | 
			
		||||
  priv->surface = NULL;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,8 @@
 | 
			
		||||
 | 
			
		||||
#include "wayland/meta-wayland.h"
 | 
			
		||||
 | 
			
		||||
#include "backends/meta-monitor-manager-private.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_SURFACE_ACTOR_WAYLAND            (meta_surface_actor_wayland_get_type ())
 | 
			
		||||
@@ -57,16 +59,25 @@ GType meta_surface_actor_wayland_get_type (void);
 | 
			
		||||
 | 
			
		||||
MetaSurfaceActor * meta_surface_actor_wayland_new (MetaWaylandSurface *surface);
 | 
			
		||||
MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWayland *self);
 | 
			
		||||
void meta_surface_actor_wayland_surface_destroyed (MetaSurfaceActorWayland *self);
 | 
			
		||||
 | 
			
		||||
void meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
 | 
			
		||||
                                             CoglTexture *texture);
 | 
			
		||||
 | 
			
		||||
double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
 | 
			
		||||
 | 
			
		||||
void meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self,
 | 
			
		||||
                                                     MetaRectangle           *rect);
 | 
			
		||||
 | 
			
		||||
void meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self);
 | 
			
		||||
 | 
			
		||||
void meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self);
 | 
			
		||||
 | 
			
		||||
void meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *self);
 | 
			
		||||
 | 
			
		||||
gboolean meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
 | 
			
		||||
                                                   MetaMonitorInfo         *monitor);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -416,6 +416,7 @@ meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
 | 
			
		||||
                                 int width, int height)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
 | 
			
		||||
  MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
 | 
			
		||||
 | 
			
		||||
  if (priv->last_width == width &&
 | 
			
		||||
      priv->last_height == height)
 | 
			
		||||
@@ -424,4 +425,5 @@ meta_surface_actor_x11_set_size (MetaSurfaceActorX11 *self,
 | 
			
		||||
  priv->size_changed = TRUE;
 | 
			
		||||
  priv->last_width = width;
 | 
			
		||||
  priv->last_height = height;
 | 
			
		||||
  meta_shaped_texture_set_fallback_size (stex, width, height);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@
 | 
			
		||||
#include <X11/extensions/Xdamage.h>
 | 
			
		||||
#include <meta/compositor-mutter.h>
 | 
			
		||||
#include "meta-surface-actor.h"
 | 
			
		||||
#include "meta-plugin-manager.h"
 | 
			
		||||
 | 
			
		||||
MetaWindowActor *meta_window_actor_new (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
@@ -18,12 +19,10 @@ void meta_window_actor_show (MetaWindowActor *self,
 | 
			
		||||
void meta_window_actor_hide (MetaWindowActor *self,
 | 
			
		||||
                             MetaCompEffect   effect);
 | 
			
		||||
 | 
			
		||||
void meta_window_actor_maximize   (MetaWindowActor *self,
 | 
			
		||||
                                   MetaRectangle   *old_rect,
 | 
			
		||||
                                   MetaRectangle   *new_rect);
 | 
			
		||||
void meta_window_actor_unmaximize (MetaWindowActor *self,
 | 
			
		||||
                                   MetaRectangle   *old_rect,
 | 
			
		||||
                                   MetaRectangle   *new_rect);
 | 
			
		||||
void meta_window_actor_size_change   (MetaWindowActor *self,
 | 
			
		||||
                                      MetaSizeChange   which_change,
 | 
			
		||||
                                      MetaRectangle   *old_frame_rect,
 | 
			
		||||
                                      MetaRectangle   *old_buffer_rect);
 | 
			
		||||
 | 
			
		||||
void meta_window_actor_process_x11_damage (MetaWindowActor    *self,
 | 
			
		||||
                                           XDamageNotifyEvent *event);
 | 
			
		||||
@@ -55,8 +54,8 @@ void     meta_window_actor_sync_updates_frozen (MetaWindowActor *self);
 | 
			
		||||
void     meta_window_actor_queue_frame_drawn   (MetaWindowActor *self,
 | 
			
		||||
                                                gboolean         no_delay_frame);
 | 
			
		||||
 | 
			
		||||
void meta_window_actor_effect_completed (MetaWindowActor *actor,
 | 
			
		||||
                                         gulong           event);
 | 
			
		||||
void meta_window_actor_effect_completed (MetaWindowActor  *actor,
 | 
			
		||||
                                         MetaPluginEffect  event);
 | 
			
		||||
 | 
			
		||||
MetaSurfaceActor *meta_window_actor_get_surface (MetaWindowActor *self);
 | 
			
		||||
void meta_window_actor_update_surface (MetaWindowActor *self);
 | 
			
		||||
 
 | 
			
		||||
@@ -20,10 +20,11 @@
 | 
			
		||||
#include "frame.h"
 | 
			
		||||
#include <meta/window.h>
 | 
			
		||||
#include <meta/meta-shaped-texture.h>
 | 
			
		||||
#include <meta/meta-enum-types.h>
 | 
			
		||||
#include <meta/meta-shadow-factory.h>
 | 
			
		||||
 | 
			
		||||
#include "compositor-private.h"
 | 
			
		||||
#include "meta-shaped-texture-private.h"
 | 
			
		||||
#include "meta-shadow-factory-private.h"
 | 
			
		||||
#include "meta-window-actor-private.h"
 | 
			
		||||
#include "meta-texture-rectangle.h"
 | 
			
		||||
#include "region-utils.h"
 | 
			
		||||
@@ -74,6 +75,8 @@ struct _MetaWindowActorPrivate
 | 
			
		||||
  MetaWindowShape  *shadow_shape;
 | 
			
		||||
  char *            shadow_class;
 | 
			
		||||
 | 
			
		||||
  MetaShadowMode    shadow_mode;
 | 
			
		||||
 | 
			
		||||
  guint             send_frame_messages_timer;
 | 
			
		||||
  gint64            frame_drawn_time;
 | 
			
		||||
 | 
			
		||||
@@ -87,8 +90,7 @@ struct _MetaWindowActorPrivate
 | 
			
		||||
   */
 | 
			
		||||
  gint              minimize_in_progress;
 | 
			
		||||
  gint              unminimize_in_progress;
 | 
			
		||||
  gint              maximize_in_progress;
 | 
			
		||||
  gint              unmaximize_in_progress;
 | 
			
		||||
  gint              size_change_in_progress;
 | 
			
		||||
  gint              map_in_progress;
 | 
			
		||||
  gint              destroy_in_progress;
 | 
			
		||||
 | 
			
		||||
@@ -110,8 +112,6 @@ struct _MetaWindowActorPrivate
 | 
			
		||||
 | 
			
		||||
  guint		    needs_destroy	   : 1;
 | 
			
		||||
 | 
			
		||||
  guint             no_shadow              : 1;
 | 
			
		||||
 | 
			
		||||
  guint             updates_frozen         : 1;
 | 
			
		||||
  guint             first_frame_state      : 2; /* FirstFrameState */
 | 
			
		||||
};
 | 
			
		||||
@@ -147,7 +147,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_META_WINDOW = 1,
 | 
			
		||||
  PROP_NO_SHADOW,
 | 
			
		||||
  PROP_SHADOW_MODE,
 | 
			
		||||
  PROP_SHADOW_CLASS
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -245,14 +245,15 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
 | 
			
		||||
                                   PROP_META_WINDOW,
 | 
			
		||||
                                   pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_boolean ("no-shadow",
 | 
			
		||||
                                "No shadow",
 | 
			
		||||
                                "Do not add shaddow to this window",
 | 
			
		||||
                                FALSE,
 | 
			
		||||
                                G_PARAM_READWRITE);
 | 
			
		||||
  pspec = g_param_spec_enum ("shadow-mode",
 | 
			
		||||
                             "Shadow mode",
 | 
			
		||||
                             "Decides when to paint shadows",
 | 
			
		||||
                             META_TYPE_SHADOW_MODE,
 | 
			
		||||
                             META_SHADOW_MODE_AUTO,
 | 
			
		||||
                             G_PARAM_READWRITE);
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_NO_SHADOW,
 | 
			
		||||
                                   PROP_SHADOW_MODE,
 | 
			
		||||
                                   pspec);
 | 
			
		||||
 | 
			
		||||
  pspec = g_param_spec_string ("shadow-class",
 | 
			
		||||
@@ -510,14 +511,14 @@ meta_window_actor_set_property (GObject      *object,
 | 
			
		||||
      g_signal_connect_object (priv->window, "notify::appears-focused",
 | 
			
		||||
                               G_CALLBACK (window_appears_focused_notify), self, 0);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_NO_SHADOW:
 | 
			
		||||
    case PROP_SHADOW_MODE:
 | 
			
		||||
      {
 | 
			
		||||
        gboolean newv = g_value_get_boolean (value);
 | 
			
		||||
        MetaShadowMode newv = g_value_get_enum (value);
 | 
			
		||||
 | 
			
		||||
        if (newv == priv->no_shadow)
 | 
			
		||||
        if (newv == priv->shadow_mode)
 | 
			
		||||
          return;
 | 
			
		||||
 | 
			
		||||
        priv->no_shadow = newv;
 | 
			
		||||
        priv->shadow_mode = newv;
 | 
			
		||||
 | 
			
		||||
        meta_window_actor_invalidate_shadow (self);
 | 
			
		||||
      }
 | 
			
		||||
@@ -554,8 +555,8 @@ meta_window_actor_get_property (GObject      *object,
 | 
			
		||||
    case PROP_META_WINDOW:
 | 
			
		||||
      g_value_set_object (value, priv->window);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_NO_SHADOW:
 | 
			
		||||
      g_value_set_boolean (value, priv->no_shadow);
 | 
			
		||||
    case PROP_SHADOW_MODE:
 | 
			
		||||
      g_value_set_enum (value, priv->shadow_mode);
 | 
			
		||||
      break;
 | 
			
		||||
    case PROP_SHADOW_CLASS:
 | 
			
		||||
      g_value_set_string (value, priv->shadow_class);
 | 
			
		||||
@@ -615,8 +616,10 @@ meta_window_actor_get_shape_bounds (MetaWindowActor       *self,
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
  if (META_IS_SURFACE_ACTOR_WAYLAND (priv->surface))
 | 
			
		||||
    {
 | 
			
		||||
      double scale = priv->surface ?
 | 
			
		||||
                     meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (priv->surface)) : 1.;
 | 
			
		||||
      MetaSurfaceActorWayland *surface_actor =
 | 
			
		||||
        META_SURFACE_ACTOR_WAYLAND (priv->surface);
 | 
			
		||||
      double scale = meta_surface_actor_wayland_get_scale (surface_actor);
 | 
			
		||||
 | 
			
		||||
      bounds->x *= scale;
 | 
			
		||||
      bounds->y *= scale;
 | 
			
		||||
      bounds->width *= scale;
 | 
			
		||||
@@ -802,8 +805,10 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
 | 
			
		||||
  if (priv->no_shadow)
 | 
			
		||||
  if (priv->shadow_mode == META_SHADOW_MODE_FORCED_OFF)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  if (priv->shadow_mode == META_SHADOW_MODE_FORCED_ON)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  /* Leaving out shadows for maximized and fullscreen windows is an effeciency
 | 
			
		||||
   * win and also prevents the unsightly effect of the shadow of maximized
 | 
			
		||||
@@ -1036,20 +1041,18 @@ gboolean
 | 
			
		||||
meta_window_actor_effect_in_progress (MetaWindowActor *self)
 | 
			
		||||
{
 | 
			
		||||
  return (self->priv->minimize_in_progress ||
 | 
			
		||||
	  self->priv->maximize_in_progress ||
 | 
			
		||||
	  self->priv->unmaximize_in_progress ||
 | 
			
		||||
	  self->priv->size_change_in_progress ||
 | 
			
		||||
	  self->priv->map_in_progress ||
 | 
			
		||||
	  self->priv->destroy_in_progress);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_freeze_thaw_effect (gulong event)
 | 
			
		||||
is_freeze_thaw_effect (MetaPluginEffect event)
 | 
			
		||||
{
 | 
			
		||||
  switch (event)
 | 
			
		||||
  {
 | 
			
		||||
  case META_PLUGIN_DESTROY:
 | 
			
		||||
  case META_PLUGIN_MAXIMIZE:
 | 
			
		||||
  case META_PLUGIN_UNMAXIMIZE:
 | 
			
		||||
  case META_PLUGIN_SIZE_CHANGE:
 | 
			
		||||
    return TRUE;
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
@@ -1058,8 +1061,8 @@ is_freeze_thaw_effect (gulong event)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
start_simple_effect (MetaWindowActor *self,
 | 
			
		||||
                     gulong        event)
 | 
			
		||||
start_simple_effect (MetaWindowActor  *self,
 | 
			
		||||
                     MetaPluginEffect  event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  MetaCompositor *compositor = priv->compositor;
 | 
			
		||||
@@ -1068,6 +1071,8 @@ start_simple_effect (MetaWindowActor *self,
 | 
			
		||||
 | 
			
		||||
  switch (event)
 | 
			
		||||
  {
 | 
			
		||||
  case META_PLUGIN_NONE:
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  case META_PLUGIN_MINIMIZE:
 | 
			
		||||
    counter = &priv->minimize_in_progress;
 | 
			
		||||
    break;
 | 
			
		||||
@@ -1080,8 +1085,7 @@ start_simple_effect (MetaWindowActor *self,
 | 
			
		||||
  case META_PLUGIN_DESTROY:
 | 
			
		||||
    counter = &priv->destroy_in_progress;
 | 
			
		||||
    break;
 | 
			
		||||
  case META_PLUGIN_UNMAXIMIZE:
 | 
			
		||||
  case META_PLUGIN_MAXIMIZE:
 | 
			
		||||
  case META_PLUGIN_SIZE_CHANGE:
 | 
			
		||||
  case META_PLUGIN_SWITCH_WORKSPACE:
 | 
			
		||||
    g_assert_not_reached ();
 | 
			
		||||
    break;
 | 
			
		||||
@@ -1123,8 +1127,8 @@ meta_window_actor_after_effects (MetaWindowActor *self)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_actor_effect_completed (MetaWindowActor *self,
 | 
			
		||||
                                    gulong           event)
 | 
			
		||||
meta_window_actor_effect_completed (MetaWindowActor  *self,
 | 
			
		||||
                                    MetaPluginEffect  event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv   = self->priv;
 | 
			
		||||
 | 
			
		||||
@@ -1134,6 +1138,8 @@ meta_window_actor_effect_completed (MetaWindowActor *self,
 | 
			
		||||
 | 
			
		||||
  switch (event)
 | 
			
		||||
  {
 | 
			
		||||
  case META_PLUGIN_NONE:
 | 
			
		||||
    break;
 | 
			
		||||
  case META_PLUGIN_MINIMIZE:
 | 
			
		||||
    {
 | 
			
		||||
      priv->minimize_in_progress--;
 | 
			
		||||
@@ -1176,20 +1182,12 @@ meta_window_actor_effect_completed (MetaWindowActor *self,
 | 
			
		||||
	priv->destroy_in_progress = 0;
 | 
			
		||||
      }
 | 
			
		||||
    break;
 | 
			
		||||
  case META_PLUGIN_UNMAXIMIZE:
 | 
			
		||||
    priv->unmaximize_in_progress--;
 | 
			
		||||
    if (priv->unmaximize_in_progress < 0)
 | 
			
		||||
  case META_PLUGIN_SIZE_CHANGE:
 | 
			
		||||
    priv->size_change_in_progress--;
 | 
			
		||||
    if (priv->size_change_in_progress < 0)
 | 
			
		||||
      {
 | 
			
		||||
	g_warning ("Error in unmaximize accounting.");
 | 
			
		||||
	priv->unmaximize_in_progress = 0;
 | 
			
		||||
      }
 | 
			
		||||
    break;
 | 
			
		||||
  case META_PLUGIN_MAXIMIZE:
 | 
			
		||||
    priv->maximize_in_progress--;
 | 
			
		||||
    if (priv->maximize_in_progress < 0)
 | 
			
		||||
      {
 | 
			
		||||
	g_warning ("Error in maximize accounting.");
 | 
			
		||||
	priv->maximize_in_progress = 0;
 | 
			
		||||
	g_warning ("Error in size change accounting.");
 | 
			
		||||
	priv->size_change_in_progress = 0;
 | 
			
		||||
      }
 | 
			
		||||
    break;
 | 
			
		||||
  case META_PLUGIN_SWITCH_WORKSPACE:
 | 
			
		||||
@@ -1300,7 +1298,7 @@ meta_window_actor_show (MetaWindowActor   *self,
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  MetaCompositor *compositor = priv->compositor;
 | 
			
		||||
  gulong event = 0;
 | 
			
		||||
  MetaPluginEffect event;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (!priv->visible);
 | 
			
		||||
 | 
			
		||||
@@ -1315,14 +1313,13 @@ meta_window_actor_show (MetaWindowActor   *self,
 | 
			
		||||
      event = META_PLUGIN_UNMINIMIZE;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_COMP_EFFECT_NONE:
 | 
			
		||||
      event = META_PLUGIN_NONE;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_COMP_EFFECT_DESTROY:
 | 
			
		||||
    case META_COMP_EFFECT_MINIMIZE:
 | 
			
		||||
    default:
 | 
			
		||||
      g_assert_not_reached();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (compositor->switch_workspace_in_progress ||
 | 
			
		||||
      event == 0 ||
 | 
			
		||||
      !start_simple_effect (self, event))
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_show (CLUTTER_ACTOR (self));
 | 
			
		||||
@@ -1335,7 +1332,7 @@ meta_window_actor_hide (MetaWindowActor *self,
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  MetaCompositor *compositor = priv->compositor;
 | 
			
		||||
  gulong event = 0;
 | 
			
		||||
  MetaPluginEffect event;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (priv->visible);
 | 
			
		||||
 | 
			
		||||
@@ -1357,70 +1354,32 @@ meta_window_actor_hide (MetaWindowActor *self,
 | 
			
		||||
      event = META_PLUGIN_MINIMIZE;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_COMP_EFFECT_NONE:
 | 
			
		||||
      event = META_PLUGIN_NONE;
 | 
			
		||||
      break;
 | 
			
		||||
    case META_COMP_EFFECT_UNMINIMIZE:
 | 
			
		||||
    case META_COMP_EFFECT_CREATE:
 | 
			
		||||
    default:
 | 
			
		||||
      g_assert_not_reached();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (event == 0 ||
 | 
			
		||||
      !start_simple_effect (self, event))
 | 
			
		||||
  if (!start_simple_effect (self, event))
 | 
			
		||||
    clutter_actor_hide (CLUTTER_ACTOR (self));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_actor_maximize (MetaWindowActor    *self,
 | 
			
		||||
                            MetaRectangle      *old_rect,
 | 
			
		||||
                            MetaRectangle      *new_rect)
 | 
			
		||||
meta_window_actor_size_change (MetaWindowActor    *self,
 | 
			
		||||
                               MetaSizeChange      which_change,
 | 
			
		||||
                               MetaRectangle      *old_frame_rect,
 | 
			
		||||
                               MetaRectangle      *old_buffer_rect)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  MetaCompositor *compositor = priv->compositor;
 | 
			
		||||
 | 
			
		||||
  /* The window has already been resized (in order to compute new_rect),
 | 
			
		||||
   * which by side effect caused the actor to be resized. Restore it to the
 | 
			
		||||
   * old size and position */
 | 
			
		||||
  clutter_actor_set_position (CLUTTER_ACTOR (self), old_rect->x, old_rect->y);
 | 
			
		||||
  clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height);
 | 
			
		||||
 | 
			
		||||
  self->priv->maximize_in_progress++;
 | 
			
		||||
  self->priv->size_change_in_progress++;
 | 
			
		||||
  meta_window_actor_freeze (self);
 | 
			
		||||
 | 
			
		||||
  if (!meta_plugin_manager_event_maximize (compositor->plugin_mgr,
 | 
			
		||||
                                           self,
 | 
			
		||||
                                           META_PLUGIN_MAXIMIZE,
 | 
			
		||||
                                           new_rect->x, new_rect->y,
 | 
			
		||||
                                           new_rect->width, new_rect->height))
 | 
			
		||||
 | 
			
		||||
  if (!meta_plugin_manager_event_size_change (compositor->plugin_mgr, self,
 | 
			
		||||
                                              which_change, old_frame_rect, old_buffer_rect))
 | 
			
		||||
    {
 | 
			
		||||
      self->priv->maximize_in_progress--;
 | 
			
		||||
      meta_window_actor_thaw (self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_actor_unmaximize (MetaWindowActor   *self,
 | 
			
		||||
                              MetaRectangle     *old_rect,
 | 
			
		||||
                              MetaRectangle     *new_rect)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowActorPrivate *priv = self->priv;
 | 
			
		||||
  MetaCompositor *compositor = priv->compositor;
 | 
			
		||||
 | 
			
		||||
  /* The window has already been resized (in order to compute new_rect),
 | 
			
		||||
   * which by side effect caused the actor to be resized. Restore it to the
 | 
			
		||||
   * old size and position */
 | 
			
		||||
  clutter_actor_set_position (CLUTTER_ACTOR (self), old_rect->x, old_rect->y);
 | 
			
		||||
  clutter_actor_set_size (CLUTTER_ACTOR (self), old_rect->width, old_rect->height);
 | 
			
		||||
 | 
			
		||||
  self->priv->unmaximize_in_progress++;
 | 
			
		||||
  meta_window_actor_freeze (self);
 | 
			
		||||
 | 
			
		||||
  if (!meta_plugin_manager_event_maximize (compositor->plugin_mgr,
 | 
			
		||||
                                           self,
 | 
			
		||||
                                           META_PLUGIN_UNMAXIMIZE,
 | 
			
		||||
                                           new_rect->x, new_rect->y,
 | 
			
		||||
                                           new_rect->width, new_rect->height))
 | 
			
		||||
    {
 | 
			
		||||
      self->priv->unmaximize_in_progress--;
 | 
			
		||||
      self->priv->size_change_in_progress--;
 | 
			
		||||
      meta_window_actor_thaw (self);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -58,9 +58,7 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
  cairo_region_t *clip_region;
 | 
			
		||||
  cairo_region_t *unobscured_region;
 | 
			
		||||
  cairo_rectangle_int_t visible_rect, clip_rect;
 | 
			
		||||
  int paint_x_offset, paint_y_offset;
 | 
			
		||||
  int paint_x_origin, paint_y_origin;
 | 
			
		||||
  int actor_x_origin, actor_y_origin;
 | 
			
		||||
  int screen_width, screen_height;
 | 
			
		||||
 | 
			
		||||
  MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
 | 
			
		||||
@@ -82,7 +80,7 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
   * on the stage.
 | 
			
		||||
   */
 | 
			
		||||
  if (!meta_actor_painting_untransformed (screen_width, screen_height, &paint_x_origin, &paint_y_origin) ||
 | 
			
		||||
      !meta_actor_is_untransformed (actor, &actor_x_origin, &actor_y_origin))
 | 
			
		||||
      !meta_actor_is_untransformed (actor, NULL, NULL))
 | 
			
		||||
    {
 | 
			
		||||
      CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
 | 
			
		||||
      return;
 | 
			
		||||
@@ -105,9 +103,7 @@ meta_window_group_paint (ClutterActor *actor)
 | 
			
		||||
 | 
			
		||||
  clip_region = cairo_region_create_rectangle (&clip_rect);
 | 
			
		||||
 | 
			
		||||
  paint_x_offset = paint_x_origin - actor_x_origin;
 | 
			
		||||
  paint_y_offset = paint_y_origin - actor_y_origin;
 | 
			
		||||
  cairo_region_translate (clip_region, -paint_x_offset, -paint_y_offset);
 | 
			
		||||
  cairo_region_translate (clip_region, -paint_x_origin, -paint_y_origin);
 | 
			
		||||
 | 
			
		||||
  meta_cullable_cull_out (META_CULLABLE (window_group), unobscured_region, clip_region);
 | 
			
		||||
 | 
			
		||||
@@ -145,6 +141,36 @@ meta_window_group_get_paint_volume (ClutterActor       *self,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This is a workaround for Clutter's awful allocation tracking.
 | 
			
		||||
 * Without this, any time the window group changed size, which is
 | 
			
		||||
 * any time windows are dragged around, we'll do a full repaint
 | 
			
		||||
 * of the window group, which includes the background actor, meaning
 | 
			
		||||
 * a full-stage repaint.
 | 
			
		||||
 *
 | 
			
		||||
 * Since actors are allowed to paint outside their allocation, and
 | 
			
		||||
 * since child actors are allowed to be outside their parents, this
 | 
			
		||||
 * doesn't affect anything, but it means that we'll get much more
 | 
			
		||||
 * sane and consistent clipped repaints from Clutter. */
 | 
			
		||||
static void
 | 
			
		||||
meta_window_group_get_preferred_width (ClutterActor *actor,
 | 
			
		||||
                                       gfloat        for_height,
 | 
			
		||||
                                       gfloat       *min_width,
 | 
			
		||||
                                       gfloat       *nat_width)
 | 
			
		||||
{
 | 
			
		||||
  *min_width = 0;
 | 
			
		||||
  *nat_width = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_group_get_preferred_height (ClutterActor *actor,
 | 
			
		||||
                                        gfloat        for_width,
 | 
			
		||||
                                        gfloat       *min_height,
 | 
			
		||||
                                        gfloat       *nat_height)
 | 
			
		||||
{
 | 
			
		||||
  *min_height = 0;
 | 
			
		||||
  *nat_height = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_group_class_init (MetaWindowGroupClass *klass)
 | 
			
		||||
{
 | 
			
		||||
@@ -152,6 +178,8 @@ meta_window_group_class_init (MetaWindowGroupClass *klass)
 | 
			
		||||
 | 
			
		||||
  actor_class->paint = meta_window_group_paint;
 | 
			
		||||
  actor_class->get_paint_volume = meta_window_group_get_paint_volume;
 | 
			
		||||
  actor_class->get_preferred_width = meta_window_group_get_preferred_width;
 | 
			
		||||
  actor_class->get_preferred_height = meta_window_group_get_preferred_height;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * MetaWindowShape
 | 
			
		||||
 *
 | 
			
		||||
@@ -19,9 +20,12 @@
 | 
			
		||||
 * 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 <string.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-window-shape.h"
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <meta/meta-window-shape.h>
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "region-utils.h"
 | 
			
		||||
 | 
			
		||||
struct _MetaWindowShape
 | 
			
		||||
@@ -250,3 +254,5 @@ meta_window_shape_to_region (MetaWindowShape *shape,
 | 
			
		||||
  return region;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_DEFINE_BOXED_TYPE (MetaWindowShape, meta_window_shape,
 | 
			
		||||
                     meta_window_shape_ref, meta_window_shape_unref)
 | 
			
		||||
 
 | 
			
		||||
@@ -689,7 +689,7 @@ show_tile_preview (MetaPlugin    *plugin,
 | 
			
		||||
  ScreenTilePreview *preview = get_screen_tile_preview (screen);
 | 
			
		||||
  ClutterActor *window_actor;
 | 
			
		||||
 | 
			
		||||
  if (CLUTTER_ACTOR_IS_VISIBLE (preview->actor)
 | 
			
		||||
  if (clutter_actor_is_visible (preview->actor)
 | 
			
		||||
      && preview->tile_rect.x == tile_rect->x
 | 
			
		||||
      && preview->tile_rect.y == tile_rect->y
 | 
			
		||||
      && preview->tile_rect.width == tile_rect->width
 | 
			
		||||
 
 | 
			
		||||
@@ -172,18 +172,6 @@ meta_core_toggle_maximize (Display *xdisplay,
 | 
			
		||||
    meta_window_maximize (window, META_MAXIMIZE_BOTH);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_core_change_workspace (Display *xdisplay,
 | 
			
		||||
                            Window   frame_xwindow,
 | 
			
		||||
                            int      new_workspace)
 | 
			
		||||
{
 | 
			
		||||
  MetaWindow *window = get_window (xdisplay, frame_xwindow);
 | 
			
		||||
 | 
			
		||||
  meta_window_change_workspace (window,
 | 
			
		||||
                                meta_screen_get_workspace_by_index (window->screen,
 | 
			
		||||
                                                                    new_workspace));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_core_show_window_menu (Display            *xdisplay,
 | 
			
		||||
                            Window              frame_xwindow,
 | 
			
		||||
 
 | 
			
		||||
@@ -41,12 +41,6 @@ void meta_core_toggle_maximize_horizontally  (Display *xdisplay,
 | 
			
		||||
                                              Window   frame_xwindow);
 | 
			
		||||
void meta_core_toggle_maximize_vertically    (Display *xdisplay,
 | 
			
		||||
                                              Window   frame_xwindow);
 | 
			
		||||
void meta_core_change_workspace (Display *xdisplay,
 | 
			
		||||
                                 Window   frame_xwindow,
 | 
			
		||||
                                 int      new_workspace);
 | 
			
		||||
 | 
			
		||||
int meta_core_get_frame_workspace (Display *xdisplay,
 | 
			
		||||
                                   Window frame_xwindow);
 | 
			
		||||
 | 
			
		||||
void meta_core_show_window_menu (Display            *xdisplay,
 | 
			
		||||
                                 Window              frame_xwindow,
 | 
			
		||||
 
 | 
			
		||||
@@ -160,12 +160,7 @@ void
 | 
			
		||||
meta_window_set_alive (MetaWindow *window,
 | 
			
		||||
                       gboolean    is_alive)
 | 
			
		||||
{
 | 
			
		||||
  if (window->is_alive == is_alive)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  window->is_alive = is_alive;
 | 
			
		||||
 | 
			
		||||
  if (window->is_alive)
 | 
			
		||||
  if (is_alive)
 | 
			
		||||
    kill_delete_dialog (window);
 | 
			
		||||
  else
 | 
			
		||||
    show_delete_dialog (window, CurrentTime);
 | 
			
		||||
@@ -185,34 +180,6 @@ meta_window_delete (MetaWindow  *window,
 | 
			
		||||
  META_WINDOW_GET_CLASS (window)->delete (window, timestamp);
 | 
			
		||||
 | 
			
		||||
  meta_window_check_alive (window, timestamp);
 | 
			
		||||
 | 
			
		||||
  if (window->has_focus)
 | 
			
		||||
    {
 | 
			
		||||
      /* FIXME Clean this up someday
 | 
			
		||||
       * http://bugzilla.gnome.org/show_bug.cgi?id=108706
 | 
			
		||||
       */
 | 
			
		||||
#if 0
 | 
			
		||||
      /* This is unfortunately going to result in weirdness
 | 
			
		||||
       * if the window doesn't respond to the delete event.
 | 
			
		||||
       * I don't know how to avoid that though.
 | 
			
		||||
       */
 | 
			
		||||
      meta_topic (META_DEBUG_FOCUS,
 | 
			
		||||
                  "Focusing default window because focus window %s was deleted/killed\n",
 | 
			
		||||
                  window->desc);
 | 
			
		||||
      meta_workspace_focus_default_window (window->screen->active_workspace,
 | 
			
		||||
                                           window);
 | 
			
		||||
#else
 | 
			
		||||
      meta_topic (META_DEBUG_FOCUS,
 | 
			
		||||
                  "Not unfocusing %s on delete/kill\n",
 | 
			
		||||
                  window->desc);
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      meta_topic (META_DEBUG_FOCUS,
 | 
			
		||||
                  "Window %s was deleted/killed but didn't have focus\n",
 | 
			
		||||
                  window->desc);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
 
 | 
			
		||||
@@ -217,9 +217,6 @@ struct _MetaDisplay
 | 
			
		||||
  guint       grab_have_pointer : 1;
 | 
			
		||||
  guint       grab_have_keyboard : 1;
 | 
			
		||||
  guint       grab_frame_action : 1;
 | 
			
		||||
  /* During a resize operation, the directions in which we've broken
 | 
			
		||||
   * out of the initial maximization state */
 | 
			
		||||
  guint       grab_resize_unmaximize : 2; /* MetaMaximizeFlags */
 | 
			
		||||
  MetaRectangle grab_initial_window_pos;
 | 
			
		||||
  int         grab_initial_x, grab_initial_y;  /* These are only relevant for */
 | 
			
		||||
  gboolean    grab_threshold_movement_reached; /* raise_on_click == FALSE.    */
 | 
			
		||||
 
 | 
			
		||||
@@ -46,7 +46,7 @@
 | 
			
		||||
#include <meta/compositor.h>
 | 
			
		||||
#include <meta/compositor-mutter.h>
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
#include "mutter-enum-types.h"
 | 
			
		||||
#include <meta/meta-enum-types.h>
 | 
			
		||||
#include "meta-idle-monitor-dbus.h"
 | 
			
		||||
#include "meta-cursor-tracker-private.h"
 | 
			
		||||
#include <meta/meta-backend.h>
 | 
			
		||||
@@ -1922,7 +1922,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
 | 
			
		||||
  display->grab_last_moveresize_time.tv_usec = 0;
 | 
			
		||||
  display->grab_last_user_action_was_snap = FALSE;
 | 
			
		||||
  display->grab_frame_action = frame_action;
 | 
			
		||||
  display->grab_resize_unmaximize = 0;
 | 
			
		||||
 | 
			
		||||
  meta_display_update_cursor (display);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,13 @@
 | 
			
		||||
#endif
 | 
			
		||||
#include "meta-surface-actor.h"
 | 
			
		||||
 | 
			
		||||
#define IS_GESTURE_EVENT(e) ((e)->type == CLUTTER_TOUCHPAD_SWIPE || \
 | 
			
		||||
                             (e)->type == CLUTTER_TOUCHPAD_PINCH || \
 | 
			
		||||
                             (e)->type == CLUTTER_TOUCH_BEGIN || \
 | 
			
		||||
                             (e)->type == CLUTTER_TOUCH_UPDATE || \
 | 
			
		||||
                             (e)->type == CLUTTER_TOUCH_END || \
 | 
			
		||||
                             (e)->type == CLUTTER_TOUCH_CANCEL)
 | 
			
		||||
 | 
			
		||||
static MetaWindow *
 | 
			
		||||
get_window_for_event (MetaDisplay        *display,
 | 
			
		||||
                      const ClutterEvent *event)
 | 
			
		||||
@@ -265,15 +272,18 @@ meta_display_handle_event (MetaDisplay        *display,
 | 
			
		||||
 | 
			
		||||
  if (window)
 | 
			
		||||
    {
 | 
			
		||||
      if (!clutter_event_get_event_sequence (event))
 | 
			
		||||
        {
 | 
			
		||||
          /* Swallow all non-touch events on windows that come our way.
 | 
			
		||||
           * Touch events that reach here aren't yet in an accepted state,
 | 
			
		||||
           * so Clutter must see them to maybe trigger gestures into
 | 
			
		||||
           * recognition.
 | 
			
		||||
           */
 | 
			
		||||
          bypass_clutter = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
      /* Events that are likely to trigger compositor gestures should
 | 
			
		||||
       * be known to clutter so they can propagate along the hierarchy.
 | 
			
		||||
       * Gesture-wise, there's two groups of events we should be getting
 | 
			
		||||
       * here:
 | 
			
		||||
       * - CLUTTER_TOUCH_* with a touch sequence that's not yet accepted
 | 
			
		||||
       *   by the gesture tracker, these might trigger gesture actions
 | 
			
		||||
       *   into recognition. Already accepted touch sequences are handled
 | 
			
		||||
       *   directly by meta_gesture_tracker_handle_event().
 | 
			
		||||
       * - CLUTTER_TOUCHPAD_* events over windows. These can likewise
 | 
			
		||||
       *   trigger ::captured-event handlers along the way.
 | 
			
		||||
       */
 | 
			
		||||
      bypass_clutter = !IS_GESTURE_EVENT (event);
 | 
			
		||||
 | 
			
		||||
      meta_window_handle_ungrabbed_event (window, event);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,7 @@
 | 
			
		||||
#include <gio/gio.h>
 | 
			
		||||
#include <meta/keybindings.h>
 | 
			
		||||
#include <xkbcommon/xkbcommon.h>
 | 
			
		||||
#include "meta-accel-parse.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaKeyHandler MetaKeyHandler;
 | 
			
		||||
struct _MetaKeyHandler
 | 
			
		||||
@@ -53,7 +54,6 @@ typedef struct _MetaResolvedKeyCombo {
 | 
			
		||||
 * @keycode: keycode
 | 
			
		||||
 * @modifiers: modifiers
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _MetaKeyCombo MetaKeyCombo;
 | 
			
		||||
struct _MetaKeyCombo
 | 
			
		||||
{
 | 
			
		||||
  unsigned int keysym;
 | 
			
		||||
 
 | 
			
		||||
@@ -3186,7 +3186,7 @@ handle_move_to_monitor (MetaDisplay    *display,
 | 
			
		||||
  gint which = binding->handler->data;
 | 
			
		||||
  const MetaMonitorInfo *current, *new;
 | 
			
		||||
 | 
			
		||||
  current = meta_screen_get_monitor_for_window (screen, window);
 | 
			
		||||
  current = window->monitor;
 | 
			
		||||
  new = meta_screen_get_monitor_neighbor (screen, current->number, which);
 | 
			
		||||
 | 
			
		||||
  if (new == NULL)
 | 
			
		||||
 
 | 
			
		||||
@@ -176,7 +176,6 @@ static gboolean
 | 
			
		||||
accelerator_parse (const gchar         *accelerator,
 | 
			
		||||
                   MetaKeyCombo        *combo)
 | 
			
		||||
{
 | 
			
		||||
  gboolean error = FALSE;
 | 
			
		||||
  guint keyval, keycode;
 | 
			
		||||
  MetaVirtualModifier mods;
 | 
			
		||||
  gint len;
 | 
			
		||||
@@ -186,10 +185,7 @@ accelerator_parse (const gchar         *accelerator,
 | 
			
		||||
  combo->modifiers = 0;
 | 
			
		||||
 | 
			
		||||
  if (accelerator == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      error = TRUE;
 | 
			
		||||
      goto out;
 | 
			
		||||
    }
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  keyval = 0;
 | 
			
		||||
  keycode = 0;
 | 
			
		||||
@@ -310,10 +306,7 @@ accelerator_parse (const gchar         *accelerator,
 | 
			
		||||
                  g_free (with_xf86);
 | 
			
		||||
 | 
			
		||||
                  if (keyval == XKB_KEY_NoSymbol)
 | 
			
		||||
                    {
 | 
			
		||||
                      error = TRUE;
 | 
			
		||||
                      goto out;
 | 
			
		||||
                    }
 | 
			
		||||
                    return FALSE;
 | 
			
		||||
                }
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
@@ -322,14 +315,10 @@ accelerator_parse (const gchar         *accelerator,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
  if (error)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
 out:
 | 
			
		||||
  combo->keysym = keyval;
 | 
			
		||||
  combo->keycode = keycode;
 | 
			
		||||
  combo->modifiers = mods;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -149,8 +149,8 @@ const MetaMonitorInfo* meta_screen_get_current_monitor_info_for_pos   (MetaScree
 | 
			
		||||
                                                                       int y);
 | 
			
		||||
const MetaMonitorInfo* meta_screen_get_monitor_for_rect   (MetaScreen    *screen,
 | 
			
		||||
                                                           MetaRectangle *rect);
 | 
			
		||||
const MetaMonitorInfo* meta_screen_get_monitor_for_window (MetaScreen    *screen,
 | 
			
		||||
                                                           MetaWindow    *window);
 | 
			
		||||
const MetaMonitorInfo* meta_screen_calculate_monitor_for_window (MetaScreen    *screen,
 | 
			
		||||
                                                                 MetaWindow    *window);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const MetaMonitorInfo* meta_screen_get_monitor_neighbor (MetaScreen *screen,
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@
 | 
			
		||||
#include "keybindings-private.h"
 | 
			
		||||
#include "stack.h"
 | 
			
		||||
#include <meta/compositor.h>
 | 
			
		||||
#include "mutter-enum-types.h"
 | 
			
		||||
#include <meta/meta-enum-types.h>
 | 
			
		||||
#include "core.h"
 | 
			
		||||
#include "meta-cursor-tracker-private.h"
 | 
			
		||||
 | 
			
		||||
@@ -750,7 +750,7 @@ void
 | 
			
		||||
meta_screen_init_workspaces (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  MetaWorkspace *current_workspace;
 | 
			
		||||
  gulong current_workspace_index = 0;
 | 
			
		||||
  uint32_t current_workspace_index = 0;
 | 
			
		||||
  guint32 timestamp;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (META_IS_SCREEN (screen));
 | 
			
		||||
@@ -1166,7 +1166,7 @@ update_num_workspaces (MetaScreen *screen,
 | 
			
		||||
  if (meta_prefs_get_dynamic_workspaces ())
 | 
			
		||||
    {
 | 
			
		||||
      int n_items;
 | 
			
		||||
      gulong *list;
 | 
			
		||||
      uint32_t *list;
 | 
			
		||||
 | 
			
		||||
      n_items = 0;
 | 
			
		||||
      list = NULL;
 | 
			
		||||
@@ -1439,8 +1439,8 @@ meta_screen_get_monitor_for_rect (MetaScreen    *screen,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const MetaMonitorInfo*
 | 
			
		||||
meta_screen_get_monitor_for_window (MetaScreen *screen,
 | 
			
		||||
                                    MetaWindow *window)
 | 
			
		||||
meta_screen_calculate_monitor_for_window (MetaScreen *screen,
 | 
			
		||||
                                          MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaRectangle window_rect;
 | 
			
		||||
 | 
			
		||||
@@ -1755,7 +1755,7 @@ meta_screen_get_monitor_geometry (MetaScreen    *screen,
 | 
			
		||||
void
 | 
			
		||||
meta_screen_update_workspace_layout (MetaScreen *screen)
 | 
			
		||||
{
 | 
			
		||||
  gulong *list;
 | 
			
		||||
  uint32_t *list;
 | 
			
		||||
  int n_items;
 | 
			
		||||
 | 
			
		||||
  if (screen->workspace_layout_overridden)
 | 
			
		||||
@@ -2388,12 +2388,12 @@ on_monitors_changed (MetaMonitorManager *manager,
 | 
			
		||||
                       &changes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Queue a resize on all the windows */
 | 
			
		||||
  meta_screen_foreach_window (screen, META_LIST_DEFAULT, meta_screen_resize_func, 0);
 | 
			
		||||
 | 
			
		||||
  /* Fix up monitor for all windows on this screen */
 | 
			
		||||
  meta_screen_foreach_window (screen, META_LIST_INCLUDE_OVERRIDE_REDIRECT, (MetaScreenWindowFunc) meta_window_update_for_monitors_changed, 0);
 | 
			
		||||
 | 
			
		||||
  /* Queue a resize on all the windows */
 | 
			
		||||
  meta_screen_foreach_window (screen, META_LIST_DEFAULT, meta_screen_resize_func, 0);
 | 
			
		||||
 | 
			
		||||
  meta_screen_queue_check_fullscreen (screen);
 | 
			
		||||
 | 
			
		||||
  g_signal_emit (screen, screen_signals[MONITORS_CHANGED], 0);
 | 
			
		||||
 
 | 
			
		||||
@@ -288,8 +288,7 @@ windows_on_different_monitor (MetaWindow *a,
 | 
			
		||||
  if (a->screen != b->screen)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  return meta_screen_get_monitor_for_window (a->screen, a) !=
 | 
			
		||||
    meta_screen_get_monitor_for_window (b->screen, b);
 | 
			
		||||
  return a->monitor != b->monitor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get layer ignoring any transient or group relationships */
 | 
			
		||||
@@ -1239,24 +1238,10 @@ get_default_focus_window (MetaStack     *stack,
 | 
			
		||||
{
 | 
			
		||||
  /* Find the topmost, focusable, mapped, window.
 | 
			
		||||
   * not_this_one is being unfocused or going away, so exclude it.
 | 
			
		||||
   * Also, prefer to focus transient parent of not_this_one,
 | 
			
		||||
   * or top window in same group as not_this_one.
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  MetaWindow *transient_parent;
 | 
			
		||||
  MetaWindow *topmost_in_group;
 | 
			
		||||
  MetaWindow *topmost_overall;
 | 
			
		||||
  MetaGroup *not_this_one_group;
 | 
			
		||||
  GList *l;
 | 
			
		||||
 | 
			
		||||
  transient_parent = NULL;
 | 
			
		||||
  topmost_in_group = NULL;
 | 
			
		||||
  topmost_overall = NULL;
 | 
			
		||||
  if (not_this_one)
 | 
			
		||||
    not_this_one_group = meta_window_get_group (not_this_one);
 | 
			
		||||
  else
 | 
			
		||||
    not_this_one_group = NULL;
 | 
			
		||||
 | 
			
		||||
  stack_ensure_sorted (stack);
 | 
			
		||||
 | 
			
		||||
  /* top of this layer is at the front of the list */
 | 
			
		||||
@@ -1273,49 +1258,25 @@ get_default_focus_window (MetaStack     *stack,
 | 
			
		||||
      if (window->unmaps_pending > 0)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (window->minimized)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (window->unmanaging)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (!(window->input || window->take_focus))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (workspace != NULL && !meta_window_located_on_workspace (window, workspace))
 | 
			
		||||
      if (!meta_window_should_be_showing (window))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (must_be_at_point && !window_contains_point (window, root_x, root_y))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      if (not_this_one != NULL)
 | 
			
		||||
        {
 | 
			
		||||
          if (transient_parent == NULL &&
 | 
			
		||||
              meta_window_get_transient_for (not_this_one) == window)
 | 
			
		||||
            transient_parent = window;
 | 
			
		||||
      if (window->type == META_WINDOW_DOCK)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
          if (topmost_in_group == NULL &&
 | 
			
		||||
              not_this_one_group != NULL &&
 | 
			
		||||
              not_this_one_group == meta_window_get_group (window))
 | 
			
		||||
            topmost_in_group = window;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (topmost_overall == NULL && window->type != META_WINDOW_DOCK)
 | 
			
		||||
        topmost_overall = window;
 | 
			
		||||
 | 
			
		||||
      /* We could try to bail out early here for efficiency in
 | 
			
		||||
       * some cases, but it's just not worth the code.
 | 
			
		||||
       */
 | 
			
		||||
      return window;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (transient_parent)
 | 
			
		||||
    return transient_parent;
 | 
			
		||||
  else if (topmost_in_group)
 | 
			
		||||
    return topmost_in_group;
 | 
			
		||||
  else if (topmost_overall)
 | 
			
		||||
    return topmost_overall;
 | 
			
		||||
  else
 | 
			
		||||
    return NULL;
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaWindow*
 | 
			
		||||
 
 | 
			
		||||
@@ -78,6 +78,7 @@ typedef enum
 | 
			
		||||
  META_MOVE_RESIZE_RESIZE_ACTION     = 1 << 3,
 | 
			
		||||
  META_MOVE_RESIZE_WAYLAND_RESIZE    = 1 << 4,
 | 
			
		||||
  META_MOVE_RESIZE_STATE_CHANGED     = 1 << 5,
 | 
			
		||||
  META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR = 1 << 6,
 | 
			
		||||
} MetaMoveResizeFlags;
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
@@ -434,7 +435,6 @@ struct _MetaWindow
 | 
			
		||||
 | 
			
		||||
  /* Managed by delete.c */
 | 
			
		||||
  int dialog_pid;
 | 
			
		||||
  guint is_alive : 1;
 | 
			
		||||
 | 
			
		||||
  /* maintained by group.c */
 | 
			
		||||
  MetaGroup *group;
 | 
			
		||||
@@ -482,6 +482,7 @@ struct _MetaWindowClass
 | 
			
		||||
  gboolean (*update_icon)        (MetaWindow       *window,
 | 
			
		||||
                                  cairo_surface_t **icon,
 | 
			
		||||
                                  cairo_surface_t **mini_icon);
 | 
			
		||||
  void (*update_main_monitor)    (MetaWindow *window);
 | 
			
		||||
  void (*main_monitor_changed)   (MetaWindow *window,
 | 
			
		||||
                                  const MetaMonitorInfo *old);
 | 
			
		||||
};
 | 
			
		||||
@@ -695,4 +696,6 @@ void meta_window_set_alive (MetaWindow *window, gboolean is_alive);
 | 
			
		||||
 | 
			
		||||
gboolean meta_window_has_pointer (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
void meta_window_emit_size_changed (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,7 @@
 | 
			
		||||
#include <meta/prefs.h>
 | 
			
		||||
#include <meta/group.h>
 | 
			
		||||
#include "constraints.h"
 | 
			
		||||
#include "mutter-enum-types.h"
 | 
			
		||||
#include <meta/meta-enum-types.h>
 | 
			
		||||
#include "core.h"
 | 
			
		||||
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
@@ -58,6 +58,7 @@
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
#include "wayland/meta-window-wayland.h"
 | 
			
		||||
#include "wayland/meta-wayland-surface.h"
 | 
			
		||||
#include "wayland/meta-wayland-private.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -723,6 +724,12 @@ meta_window_should_attach_to_parent (MetaWindow *window)
 | 
			
		||||
static gboolean
 | 
			
		||||
client_window_should_be_mapped (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
  if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND &&
 | 
			
		||||
      !window->surface->buffer)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return !window->shaded;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -974,7 +981,8 @@ _meta_window_shared_new (MetaDisplay         *display,
 | 
			
		||||
 | 
			
		||||
  window->compositor_private = NULL;
 | 
			
		||||
 | 
			
		||||
  window->monitor = meta_screen_get_monitor_for_window (window->screen, window);
 | 
			
		||||
  window->monitor = meta_screen_calculate_monitor_for_window (window->screen,
 | 
			
		||||
                                                              window);
 | 
			
		||||
  window->preferred_output_winsys_id = window->monitor->winsys_id;
 | 
			
		||||
 | 
			
		||||
  window->tile_match = NULL;
 | 
			
		||||
@@ -1533,6 +1541,12 @@ meta_window_showing_on_its_workspace (MetaWindow *window)
 | 
			
		||||
gboolean
 | 
			
		||||
meta_window_should_be_showing (MetaWindow  *window)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
  if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND &&
 | 
			
		||||
      !window->surface->buffer)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /* Windows should be showing if they're located on the
 | 
			
		||||
   * active workspace and they're showing on their own workspace. */
 | 
			
		||||
  return (meta_window_located_on_workspace (window, window->screen->active_workspace) &&
 | 
			
		||||
@@ -2651,8 +2665,6 @@ meta_window_maximize (MetaWindow        *window,
 | 
			
		||||
{
 | 
			
		||||
  MetaRectangle *saved_rect = NULL;
 | 
			
		||||
  gboolean maximize_horizontally, maximize_vertically;
 | 
			
		||||
  MetaRectangle old_rect;
 | 
			
		||||
  MetaRectangle new_rect;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (!window->override_redirect);
 | 
			
		||||
 | 
			
		||||
@@ -2702,18 +2714,23 @@ meta_window_maximize (MetaWindow        *window,
 | 
			
		||||
                                     directions,
 | 
			
		||||
                                     saved_rect);
 | 
			
		||||
 | 
			
		||||
      meta_window_get_frame_rect (window, &old_rect);
 | 
			
		||||
      MetaRectangle old_frame_rect, old_buffer_rect, new_rect;
 | 
			
		||||
 | 
			
		||||
      meta_window_get_frame_rect (window, &old_frame_rect);
 | 
			
		||||
      meta_window_get_buffer_rect (window, &old_buffer_rect);
 | 
			
		||||
 | 
			
		||||
      meta_window_move_resize_internal (window,
 | 
			
		||||
                                        META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
 | 
			
		||||
                                        (META_MOVE_RESIZE_MOVE_ACTION |
 | 
			
		||||
                                         META_MOVE_RESIZE_RESIZE_ACTION |
 | 
			
		||||
                                         META_MOVE_RESIZE_STATE_CHANGED |
 | 
			
		||||
                                         META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR),
 | 
			
		||||
                                        NorthWestGravity,
 | 
			
		||||
                                        window->unconstrained_rect);
 | 
			
		||||
 | 
			
		||||
      meta_window_get_frame_rect (window, &new_rect);
 | 
			
		||||
      meta_compositor_maximize_window (window->display->compositor,
 | 
			
		||||
                                       window,
 | 
			
		||||
                                       &old_rect,
 | 
			
		||||
                                       &new_rect);
 | 
			
		||||
 | 
			
		||||
      meta_compositor_size_change_window (window->display->compositor, window,
 | 
			
		||||
                                          META_SIZE_CHANGE_MAXIMIZE,
 | 
			
		||||
                                          &old_frame_rect, &old_buffer_rect);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2873,8 +2890,6 @@ void
 | 
			
		||||
meta_window_tile (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  MetaMaximizeFlags directions;
 | 
			
		||||
  MetaRectangle old_rect;
 | 
			
		||||
  MetaRectangle new_rect;
 | 
			
		||||
 | 
			
		||||
  /* Don't do anything if no tiling is requested */
 | 
			
		||||
  if (window->tile_mode == META_TILE_NONE)
 | 
			
		||||
@@ -2888,16 +2903,8 @@ meta_window_tile (MetaWindow *window)
 | 
			
		||||
  meta_window_maximize_internal (window, directions, NULL);
 | 
			
		||||
  meta_screen_update_tile_preview (window->screen, FALSE);
 | 
			
		||||
 | 
			
		||||
  meta_window_get_frame_rect (window, &old_rect);
 | 
			
		||||
 | 
			
		||||
  meta_window_move_resize_now (window);
 | 
			
		||||
 | 
			
		||||
  meta_window_get_frame_rect (window, &new_rect);
 | 
			
		||||
  meta_compositor_maximize_window (window->display->compositor,
 | 
			
		||||
                                   window,
 | 
			
		||||
                                   &old_rect,
 | 
			
		||||
                                   &new_rect);
 | 
			
		||||
 | 
			
		||||
  if (window->frame)
 | 
			
		||||
    meta_frame_queue_draw (window->frame);
 | 
			
		||||
}
 | 
			
		||||
@@ -2965,11 +2972,9 @@ unmaximize_window_before_freeing (MetaWindow        *window)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_unmaximize_internal (MetaWindow        *window,
 | 
			
		||||
                                 MetaMaximizeFlags  directions,
 | 
			
		||||
                                 MetaRectangle     *desired_rect,
 | 
			
		||||
                                 int                gravity)
 | 
			
		||||
void
 | 
			
		||||
meta_window_unmaximize (MetaWindow        *window,
 | 
			
		||||
                        MetaMaximizeFlags  directions)
 | 
			
		||||
{
 | 
			
		||||
  gboolean unmaximize_horizontally, unmaximize_vertically;
 | 
			
		||||
  MetaRectangle new_rect;
 | 
			
		||||
@@ -2990,12 +2995,14 @@ meta_window_unmaximize_internal (MetaWindow        *window,
 | 
			
		||||
  if ((unmaximize_horizontally && window->maximized_horizontally) ||
 | 
			
		||||
      (unmaximize_vertically   && window->maximized_vertically))
 | 
			
		||||
    {
 | 
			
		||||
      MetaRectangle *desired_rect;
 | 
			
		||||
      MetaRectangle target_rect;
 | 
			
		||||
      MetaRectangle work_area;
 | 
			
		||||
      MetaRectangle old_rect;
 | 
			
		||||
      MetaRectangle old_frame_rect, old_buffer_rect;
 | 
			
		||||
 | 
			
		||||
      meta_window_get_work_area_for_monitor (window, window->monitor->number, &work_area);
 | 
			
		||||
      meta_window_get_frame_rect (window, &old_rect);
 | 
			
		||||
      meta_window_get_frame_rect (window, &old_frame_rect);
 | 
			
		||||
      meta_window_get_buffer_rect (window, &old_buffer_rect);
 | 
			
		||||
 | 
			
		||||
      meta_topic (META_DEBUG_WINDOW_OPS,
 | 
			
		||||
                  "Unmaximizing %s%s\n",
 | 
			
		||||
@@ -3015,10 +3022,12 @@ meta_window_unmaximize_internal (MetaWindow        *window,
 | 
			
		||||
       */
 | 
			
		||||
      meta_window_frame_size_changed (window);
 | 
			
		||||
 | 
			
		||||
      desired_rect = &window->saved_rect;
 | 
			
		||||
 | 
			
		||||
      /* Unmaximize to the saved_rect position in the direction(s)
 | 
			
		||||
       * being unmaximized.
 | 
			
		||||
       */
 | 
			
		||||
      target_rect = old_rect;
 | 
			
		||||
      target_rect = old_frame_rect;
 | 
			
		||||
 | 
			
		||||
      /* Avoid unmaximizing to "almost maximized" size when the previous size
 | 
			
		||||
       * is greater then 80% of the work area use MAX_UNMAXIMIZED_WINDOW_AREA of the work area as upper limit
 | 
			
		||||
@@ -3060,15 +3069,17 @@ meta_window_unmaximize_internal (MetaWindow        *window,
 | 
			
		||||
      meta_window_client_rect_to_frame_rect (window, &target_rect, &target_rect);
 | 
			
		||||
 | 
			
		||||
      meta_window_move_resize_internal (window,
 | 
			
		||||
                                        META_MOVE_RESIZE_MOVE_ACTION | META_MOVE_RESIZE_RESIZE_ACTION | META_MOVE_RESIZE_STATE_CHANGED,
 | 
			
		||||
                                        gravity,
 | 
			
		||||
                                        (META_MOVE_RESIZE_MOVE_ACTION |
 | 
			
		||||
                                         META_MOVE_RESIZE_RESIZE_ACTION |
 | 
			
		||||
                                         META_MOVE_RESIZE_STATE_CHANGED |
 | 
			
		||||
                                         META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR),
 | 
			
		||||
                                        NorthWestGravity,
 | 
			
		||||
                                        target_rect);
 | 
			
		||||
 | 
			
		||||
      meta_window_get_frame_rect (window, &new_rect);
 | 
			
		||||
      meta_compositor_unmaximize_window (window->display->compositor,
 | 
			
		||||
                                         window,
 | 
			
		||||
                                         &old_rect,
 | 
			
		||||
                                         &new_rect);
 | 
			
		||||
      meta_compositor_size_change_window (window->display->compositor, window,
 | 
			
		||||
                                          META_SIZE_CHANGE_UNMAXIMIZE,
 | 
			
		||||
                                          &old_frame_rect, &old_buffer_rect);
 | 
			
		||||
 | 
			
		||||
      /* When we unmaximize, if we're doing a mouse move also we could
 | 
			
		||||
       * get the window suddenly jumping to the upper left corner of
 | 
			
		||||
@@ -3095,37 +3106,6 @@ meta_window_unmaximize_internal (MetaWindow        *window,
 | 
			
		||||
  g_object_thaw_notify (G_OBJECT (window));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_unmaximize (MetaWindow        *window,
 | 
			
		||||
                        MetaMaximizeFlags  directions)
 | 
			
		||||
{
 | 
			
		||||
  meta_window_unmaximize_internal (window, directions, &window->saved_rect,
 | 
			
		||||
                                   NorthWestGravity);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Like meta_window_unmaximize(), but instead of unmaximizing to the
 | 
			
		||||
 * saved position, we give the new desired size, and the gravity that
 | 
			
		||||
 * determines the positioning relationship between the area occupied
 | 
			
		||||
 * maximized and the new are. The arguments are similar to
 | 
			
		||||
 * meta_window_resize_with_gravity().
 | 
			
		||||
 * Unlike meta_window_unmaximize(), tiling is not restored for windows
 | 
			
		||||
 * with a tile mode other than META_TILE_NONE.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
meta_window_unmaximize_with_gravity (MetaWindow        *window,
 | 
			
		||||
                                     MetaMaximizeFlags  directions,
 | 
			
		||||
                                     int                new_width,
 | 
			
		||||
                                     int                new_height,
 | 
			
		||||
                                     int                gravity)
 | 
			
		||||
{
 | 
			
		||||
  MetaRectangle desired_rect;
 | 
			
		||||
 | 
			
		||||
  desired_rect.width = new_width;
 | 
			
		||||
  desired_rect.height = new_height;
 | 
			
		||||
 | 
			
		||||
  meta_window_unmaximize_internal (window, directions, &desired_rect, gravity);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_make_above (MetaWindow  *window)
 | 
			
		||||
{
 | 
			
		||||
@@ -3228,6 +3208,8 @@ meta_window_unmake_fullscreen (MetaWindow  *window)
 | 
			
		||||
      window->fullscreen = FALSE;
 | 
			
		||||
      target_rect = window->saved_rect;
 | 
			
		||||
 | 
			
		||||
      meta_window_frame_size_changed (window);
 | 
			
		||||
 | 
			
		||||
      /* Window's size hints may have changed while maximized, making
 | 
			
		||||
       * saved_rect invalid.  #329152
 | 
			
		||||
       */
 | 
			
		||||
@@ -3565,7 +3547,7 @@ meta_window_update_monitor (MetaWindow *window,
 | 
			
		||||
  const MetaMonitorInfo *old;
 | 
			
		||||
 | 
			
		||||
  old = window->monitor;
 | 
			
		||||
  window->monitor = meta_screen_get_monitor_for_window (window->screen, window);
 | 
			
		||||
  META_WINDOW_GET_CLASS (window)->update_main_monitor (window);
 | 
			
		||||
  if (old != window->monitor)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_on_all_workspaces_changed (window);
 | 
			
		||||
@@ -3706,7 +3688,7 @@ meta_window_move_resize_internal (MetaWindow          *window,
 | 
			
		||||
    {
 | 
			
		||||
      window->unconstrained_rect = unconstrained_rect;
 | 
			
		||||
 | 
			
		||||
      if (window->known_to_compositor)
 | 
			
		||||
      if (window->known_to_compositor && !(flags & META_MOVE_RESIZE_DONT_SYNC_COMPOSITOR))
 | 
			
		||||
        meta_compositor_sync_window_geometry (window->display->compositor,
 | 
			
		||||
                                              window,
 | 
			
		||||
                                              did_placement);
 | 
			
		||||
@@ -4038,9 +4020,8 @@ meta_window_get_buffer_rect (const MetaWindow *window,
 | 
			
		||||
 * @client_rect: client rectangle in root coordinates
 | 
			
		||||
 * @frame_rect: (out): location to store the computed corresponding frame bounds.
 | 
			
		||||
 *
 | 
			
		||||
 * Converts a desired bounds of the client window - what is passed to meta_window_move_resize() -
 | 
			
		||||
 * into the corresponding bounds of the window frame (excluding invisible borders
 | 
			
		||||
 * and client side shadows.)
 | 
			
		||||
 * Converts a desired bounds of the client window into the corresponding bounds
 | 
			
		||||
 * of the window frame (excluding invisible borders and client side shadows.)
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_window_client_rect_to_frame_rect (MetaWindow    *window,
 | 
			
		||||
@@ -4087,7 +4068,7 @@ meta_window_client_rect_to_frame_rect (MetaWindow    *window,
 | 
			
		||||
 * @client_rect: (out): location to store the computed corresponding client rectangle.
 | 
			
		||||
 *
 | 
			
		||||
 * Converts a desired frame bounds for a window into the bounds of the client
 | 
			
		||||
 * window - what is passed to meta_window_move_resize().
 | 
			
		||||
 * window.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
meta_window_frame_rect_to_client_rect (MetaWindow    *window,
 | 
			
		||||
@@ -4634,12 +4615,7 @@ meta_window_change_workspace_by_index (MetaWindow *window,
 | 
			
		||||
    workspace = meta_screen_append_new_workspace (screen, FALSE, CurrentTime);
 | 
			
		||||
 | 
			
		||||
  if (workspace)
 | 
			
		||||
    {
 | 
			
		||||
      if (window->on_all_workspaces_requested)
 | 
			
		||||
        meta_window_unstick (window);
 | 
			
		||||
 | 
			
		||||
      meta_window_change_workspace (window, workspace);
 | 
			
		||||
    }
 | 
			
		||||
    meta_window_change_workspace (window, workspace);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -5658,7 +5634,7 @@ update_move (MetaWindow  *window,
 | 
			
		||||
      int monitor;
 | 
			
		||||
 | 
			
		||||
      window->tile_mode = META_TILE_NONE;
 | 
			
		||||
      wmonitor = meta_screen_get_monitor_for_window (window->screen, window);
 | 
			
		||||
      wmonitor = window->monitor;
 | 
			
		||||
 | 
			
		||||
      for (monitor = 0; monitor < window->screen->n_monitor_infos; monitor++)
 | 
			
		||||
        {
 | 
			
		||||
@@ -5728,81 +5704,6 @@ update_move (MetaWindow  *window,
 | 
			
		||||
  meta_window_move_frame (window, TRUE, new_x, new_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* When resizing a maximized window by using alt-middle-drag (resizing
 | 
			
		||||
 * with the grips or the menu for a maximized window is not enabled),
 | 
			
		||||
 * the user can "break" out of the maximized state. This checks for
 | 
			
		||||
 * that possibility. During such a break-out resize the user can also
 | 
			
		||||
 * return to the previous maximization state by resizing back to near
 | 
			
		||||
 * the original size.
 | 
			
		||||
 */
 | 
			
		||||
static MetaMaximizeFlags
 | 
			
		||||
check_resize_unmaximize(MetaWindow *window,
 | 
			
		||||
                        int         dx,
 | 
			
		||||
                        int         dy)
 | 
			
		||||
{
 | 
			
		||||
  int threshold;
 | 
			
		||||
  MetaMaximizeFlags new_unmaximize;
 | 
			
		||||
 | 
			
		||||
#define DRAG_THRESHOLD_TO_RESIZE_THRESHOLD_FACTOR 3
 | 
			
		||||
 | 
			
		||||
  threshold = meta_prefs_get_drag_threshold () *
 | 
			
		||||
    DRAG_THRESHOLD_TO_RESIZE_THRESHOLD_FACTOR;
 | 
			
		||||
  new_unmaximize = 0;
 | 
			
		||||
 | 
			
		||||
  if (window->maximized_horizontally ||
 | 
			
		||||
      window->tile_mode != META_TILE_NONE ||
 | 
			
		||||
      (window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0)
 | 
			
		||||
    {
 | 
			
		||||
      int x_amount;
 | 
			
		||||
 | 
			
		||||
      /* We allow breaking out of maximization in either direction, to make
 | 
			
		||||
       * the window larger than the monitor as well as smaller than the
 | 
			
		||||
       * monitor. If we wanted to only allow resizing smaller than the
 | 
			
		||||
       * monitor, we'd use - dx for NE/E/SE and dx for SW/W/NW.
 | 
			
		||||
       */
 | 
			
		||||
      if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_WEST | META_GRAB_OP_WINDOW_DIR_EAST)) != 0)
 | 
			
		||||
        x_amount = dx < 0 ? - dx : dx;
 | 
			
		||||
      else
 | 
			
		||||
        x_amount = 0;
 | 
			
		||||
 | 
			
		||||
      if (x_amount > threshold)
 | 
			
		||||
        new_unmaximize |= META_MAXIMIZE_HORIZONTAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (window->maximized_vertically ||
 | 
			
		||||
      (window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0)
 | 
			
		||||
    {
 | 
			
		||||
      int y_amount;
 | 
			
		||||
 | 
			
		||||
      if ((window->display->grab_op & (META_GRAB_OP_WINDOW_DIR_NORTH | META_GRAB_OP_WINDOW_DIR_SOUTH)) != 0)
 | 
			
		||||
        y_amount = dy < 0 ? - dy : dy;
 | 
			
		||||
      else
 | 
			
		||||
        y_amount = 0;
 | 
			
		||||
 | 
			
		||||
      if (y_amount > threshold)
 | 
			
		||||
        new_unmaximize |= META_MAXIMIZE_VERTICAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Metacity doesn't have a full user interface for only horizontally or
 | 
			
		||||
   * vertically maximized, so while only unmaximizing in the direction drags
 | 
			
		||||
   * has some advantages, it will also confuse the user. So, we always
 | 
			
		||||
   * unmaximize both ways if possible.
 | 
			
		||||
   */
 | 
			
		||||
  if (new_unmaximize != 0)
 | 
			
		||||
    {
 | 
			
		||||
      new_unmaximize = 0;
 | 
			
		||||
 | 
			
		||||
      if (window->maximized_horizontally ||
 | 
			
		||||
          (window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0)
 | 
			
		||||
        new_unmaximize |= META_MAXIMIZE_HORIZONTAL;
 | 
			
		||||
      if (window->maximized_vertically ||
 | 
			
		||||
          (window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0)
 | 
			
		||||
        new_unmaximize |= META_MAXIMIZE_VERTICAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return new_unmaximize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
update_resize_timeout (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
@@ -5827,7 +5728,6 @@ update_resize (MetaWindow *window,
 | 
			
		||||
  int gravity;
 | 
			
		||||
  MetaRectangle old;
 | 
			
		||||
  double remaining = 0;
 | 
			
		||||
  MetaMaximizeFlags new_unmaximize;
 | 
			
		||||
 | 
			
		||||
  window->display->grab_latest_motion_x = x;
 | 
			
		||||
  window->display->grab_latest_motion_y = y;
 | 
			
		||||
@@ -5874,8 +5774,6 @@ update_resize (MetaWindow *window,
 | 
			
		||||
      meta_window_update_keyboard_resize (window, TRUE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  new_unmaximize = check_resize_unmaximize (window, dx, dy);
 | 
			
		||||
 | 
			
		||||
  if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_EAST)
 | 
			
		||||
    new_w += dx;
 | 
			
		||||
  else if (window->display->grab_op & META_GRAB_OP_WINDOW_DIR_WEST)
 | 
			
		||||
@@ -5944,29 +5842,7 @@ update_resize (MetaWindow *window,
 | 
			
		||||
                                          snap,
 | 
			
		||||
                                          FALSE);
 | 
			
		||||
 | 
			
		||||
  if (new_unmaximize == window->display->grab_resize_unmaximize)
 | 
			
		||||
    {
 | 
			
		||||
      meta_window_resize_frame_with_gravity (window, TRUE, new_w, new_h, gravity);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      if ((new_unmaximize & ~window->display->grab_resize_unmaximize) != 0)
 | 
			
		||||
        {
 | 
			
		||||
          meta_window_unmaximize_with_gravity (window,
 | 
			
		||||
                                               (new_unmaximize & ~window->display->grab_resize_unmaximize),
 | 
			
		||||
                                               new_w, new_h, gravity);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if ((window->display->grab_resize_unmaximize & ~new_unmaximize))
 | 
			
		||||
        {
 | 
			
		||||
          MetaRectangle saved_rect = window->saved_rect;
 | 
			
		||||
          meta_window_maximize (window,
 | 
			
		||||
                                (window->display->grab_resize_unmaximize & ~new_unmaximize));
 | 
			
		||||
          window->saved_rect = saved_rect;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  window->display->grab_resize_unmaximize = new_unmaximize;
 | 
			
		||||
  meta_window_resize_frame_with_gravity (window, TRUE, new_w, new_h, gravity);
 | 
			
		||||
 | 
			
		||||
  /* Store the latest resize time, if we actually resized. */
 | 
			
		||||
  if (window->rect.width != old.width || window->rect.height != old.height)
 | 
			
		||||
@@ -6167,12 +6043,8 @@ void
 | 
			
		||||
meta_window_get_work_area_current_monitor (MetaWindow    *window,
 | 
			
		||||
                                           MetaRectangle *area)
 | 
			
		||||
{
 | 
			
		||||
  const MetaMonitorInfo *monitor = NULL;
 | 
			
		||||
  monitor = meta_screen_get_monitor_for_window (window->screen,
 | 
			
		||||
                                                window);
 | 
			
		||||
 | 
			
		||||
  meta_window_get_work_area_for_monitor (window,
 | 
			
		||||
                                         monitor->number,
 | 
			
		||||
                                         window->monitor->number,
 | 
			
		||||
                                         area);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -7977,3 +7849,9 @@ meta_window_grab_op_ended (MetaWindow *window,
 | 
			
		||||
{
 | 
			
		||||
  META_WINDOW_GET_CLASS (window)->grab_op_ended (window, op);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_emit_size_changed (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  g_signal_emit (window, window_signals[SIZE_CHANGED], 0);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*** BEGIN file-header ***/
 | 
			
		||||
#include "mutter-enum-types.h"
 | 
			
		||||
#include <meta/meta-enum-types.h>
 | 
			
		||||
/*** END file-header ***/
 | 
			
		||||
 | 
			
		||||
/*** BEGIN file-production ***/
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*** BEGIN file-header ***/
 | 
			
		||||
#ifndef __MUTTER_ENUM_TYPES_H__
 | 
			
		||||
#define __MUTTER_ENUM_TYPES_H__
 | 
			
		||||
#ifndef __META_ENUM_TYPES_H__
 | 
			
		||||
#define __META_ENUM_TYPES_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
@@ -54,6 +54,11 @@ typedef enum
 | 
			
		||||
  META_COMP_EFFECT_NONE
 | 
			
		||||
} MetaCompEffect;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  META_SIZE_CHANGE_MAXIMIZE,
 | 
			
		||||
  META_SIZE_CHANGE_UNMAXIMIZE,
 | 
			
		||||
} MetaSizeChange;
 | 
			
		||||
 | 
			
		||||
MetaCompositor *meta_compositor_new     (MetaDisplay    *display);
 | 
			
		||||
void            meta_compositor_destroy (MetaCompositor *compositor);
 | 
			
		||||
 | 
			
		||||
@@ -89,14 +94,11 @@ void meta_compositor_switch_workspace  (MetaCompositor      *compositor,
 | 
			
		||||
                                        MetaWorkspace       *to,
 | 
			
		||||
                                        MetaMotionDirection  direction);
 | 
			
		||||
 | 
			
		||||
void meta_compositor_maximize_window   (MetaCompositor      *compositor,
 | 
			
		||||
                                        MetaWindow          *window,
 | 
			
		||||
                                        MetaRectangle       *old_rect,
 | 
			
		||||
                                        MetaRectangle       *new_rect);
 | 
			
		||||
void meta_compositor_unmaximize_window (MetaCompositor      *compositor,
 | 
			
		||||
                                        MetaWindow          *window,
 | 
			
		||||
                                        MetaRectangle       *old_rect,
 | 
			
		||||
                                        MetaRectangle       *new_rect);
 | 
			
		||||
void meta_compositor_size_change_window (MetaCompositor      *compositor,
 | 
			
		||||
                                         MetaWindow          *window,
 | 
			
		||||
                                         MetaSizeChange       which_change,
 | 
			
		||||
                                         MetaRectangle       *old_frame_rect,
 | 
			
		||||
                                         MetaRectangle       *old_buffer_rect);
 | 
			
		||||
 | 
			
		||||
void meta_compositor_sync_window_geometry (MetaCompositor *compositor,
 | 
			
		||||
                                           MetaWindow     *window,
 | 
			
		||||
 
 | 
			
		||||
@@ -55,8 +55,7 @@ struct _MetaPlugin
 | 
			
		||||
 * MetaPluginClass:
 | 
			
		||||
 * @start: virtual function called when the compositor starts managing a screen
 | 
			
		||||
 * @minimize: virtual function called when a window is minimized
 | 
			
		||||
 * @maximize: virtual function called when a window is maximized
 | 
			
		||||
 * @unmaximize: virtual function called when a window is unmaximized
 | 
			
		||||
 * @size_change: virtual function called when a window changes size to/from constraints
 | 
			
		||||
 * @map: virtual function called when a window is mapped
 | 
			
		||||
 * @destroy: virtual function called when a window is destroyed
 | 
			
		||||
 * @switch_workspace: virtual function called when the user switches to another
 | 
			
		||||
@@ -103,39 +102,11 @@ struct _MetaPluginClass
 | 
			
		||||
  void (*unminimize)       (MetaPlugin         *plugin,
 | 
			
		||||
                            MetaWindowActor    *actor);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * MetaPluginClass::maximize:
 | 
			
		||||
   * @actor: a #MetaWindowActor
 | 
			
		||||
   * @x: target X coordinate
 | 
			
		||||
   * @y: target Y coordinate
 | 
			
		||||
   * @width: target width
 | 
			
		||||
   * @height: target height
 | 
			
		||||
   *
 | 
			
		||||
   * Virtual function called when the window represented by @actor is maximized.
 | 
			
		||||
   */
 | 
			
		||||
  void (*maximize)         (MetaPlugin         *plugin,
 | 
			
		||||
  void (*size_change)      (MetaPlugin         *plugin,
 | 
			
		||||
                            MetaWindowActor    *actor,
 | 
			
		||||
                            gint                x,
 | 
			
		||||
                            gint                y,
 | 
			
		||||
                            gint                width,
 | 
			
		||||
                            gint                height);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * MetaPluginClass::unmaximize:
 | 
			
		||||
   * @actor: a #MetaWindowActor
 | 
			
		||||
   * @x: target X coordinate
 | 
			
		||||
   * @y: target Y coordinate
 | 
			
		||||
   * @width: target width
 | 
			
		||||
   * @height: target height
 | 
			
		||||
   *
 | 
			
		||||
   * Virtual function called when the window represented by @actor is unmaximized.
 | 
			
		||||
   */
 | 
			
		||||
  void (*unmaximize)       (MetaPlugin         *plugin,
 | 
			
		||||
                            MetaWindowActor    *actor,
 | 
			
		||||
                            gint                x,
 | 
			
		||||
                            gint                y,
 | 
			
		||||
                            gint                width,
 | 
			
		||||
                            gint                height);
 | 
			
		||||
                            MetaSizeChange      which_change,
 | 
			
		||||
                            MetaRectangle      *old_frame_rect,
 | 
			
		||||
                            MetaRectangle      *old_buffer_rect);
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * MetaPluginClass::map:
 | 
			
		||||
@@ -386,12 +357,8 @@ meta_plugin_unminimize_completed (MetaPlugin      *plugin,
 | 
			
		||||
                                  MetaWindowActor *actor);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_maximize_completed (MetaPlugin      *plugin,
 | 
			
		||||
                                MetaWindowActor *actor);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_unmaximize_completed (MetaPlugin      *plugin,
 | 
			
		||||
                                  MetaWindowActor *actor);
 | 
			
		||||
meta_plugin_size_change_completed (MetaPlugin      *plugin,
 | 
			
		||||
                                   MetaWindowActor *actor);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_plugin_map_completed (MetaPlugin      *plugin,
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,11 @@
 | 
			
		||||
#ifndef __META_SHADOW_FACTORY_H__
 | 
			
		||||
#define __META_SHADOW_FACTORY_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <cairo.h>
 | 
			
		||||
#include <clutter/clutter.h>
 | 
			
		||||
#include <meta/meta-window-shape.h>
 | 
			
		||||
 | 
			
		||||
GType meta_shadow_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MetaShadowParams:
 | 
			
		||||
@@ -81,4 +85,38 @@ void meta_shadow_factory_get_params (MetaShadowFactory *factory,
 | 
			
		||||
                                     gboolean           focused,
 | 
			
		||||
                                     MetaShadowParams  *params);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MetaShadow:
 | 
			
		||||
 * #MetaShadow holds a shadow texture along with information about how to
 | 
			
		||||
 * apply that texture to draw a window texture. (E.g., it knows how big the
 | 
			
		||||
 * unscaled borders are on each side of the shadow texture.)
 | 
			
		||||
 */
 | 
			
		||||
typedef struct _MetaShadow MetaShadow;
 | 
			
		||||
 | 
			
		||||
MetaShadow *meta_shadow_ref         (MetaShadow            *shadow);
 | 
			
		||||
void        meta_shadow_unref       (MetaShadow            *shadow);
 | 
			
		||||
void        meta_shadow_paint       (MetaShadow            *shadow,
 | 
			
		||||
                                     int                    window_x,
 | 
			
		||||
                                     int                    window_y,
 | 
			
		||||
                                     int                    window_width,
 | 
			
		||||
                                     int                    window_height,
 | 
			
		||||
                                     guint8                 opacity,
 | 
			
		||||
                                     cairo_region_t        *clip,
 | 
			
		||||
                                     gboolean               clip_strictly);
 | 
			
		||||
void        meta_shadow_get_bounds  (MetaShadow            *shadow,
 | 
			
		||||
                                     int                    window_x,
 | 
			
		||||
                                     int                    window_y,
 | 
			
		||||
                                     int                    window_width,
 | 
			
		||||
                                     int                    window_height,
 | 
			
		||||
                                     cairo_rectangle_int_t *bounds);
 | 
			
		||||
 | 
			
		||||
MetaShadowFactory *meta_shadow_factory_new (void);
 | 
			
		||||
 | 
			
		||||
MetaShadow *meta_shadow_factory_get_shadow (MetaShadowFactory *factory,
 | 
			
		||||
                                            MetaWindowShape   *shape,
 | 
			
		||||
                                            int                width,
 | 
			
		||||
                                            int                height,
 | 
			
		||||
                                            const char        *class_name,
 | 
			
		||||
                                            gboolean           focused);
 | 
			
		||||
 | 
			
		||||
#endif /* __META_SHADOW_FACTORY_H__ */
 | 
			
		||||
 
 | 
			
		||||
@@ -62,4 +62,10 @@ MetaWindow *       meta_window_actor_get_meta_window      (MetaWindowActor *self
 | 
			
		||||
ClutterActor *     meta_window_actor_get_texture          (MetaWindowActor *self);
 | 
			
		||||
gboolean       meta_window_actor_is_destroyed (MetaWindowActor *self);
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  META_SHADOW_MODE_AUTO,
 | 
			
		||||
  META_SHADOW_MODE_FORCED_OFF,
 | 
			
		||||
  META_SHADOW_MODE_FORCED_ON,
 | 
			
		||||
} MetaShadowMode;
 | 
			
		||||
 | 
			
		||||
#endif /* META_WINDOW_ACTOR_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,9 @@
 | 
			
		||||
#define __META_WINDOW_SHAPE_H__
 | 
			
		||||
 | 
			
		||||
#include <cairo.h>
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
GType meta_window_shape_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MetaWindowShape:
 | 
			
		||||
							
								
								
									
										1
									
								
								src/stamp-mutter-enum-types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/stamp-mutter-enum-types.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
timestamp
 | 
			
		||||
@@ -1053,6 +1053,11 @@ meta_frame_left_click_event (MetaUIFrame *frame,
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    case META_FRAME_CONTROL_NONE:
 | 
			
		||||
      /* We can get this for example when trying to resize window
 | 
			
		||||
       * that cannot be resized (e. g. it is maximized and the theme
 | 
			
		||||
       * currently used has borders for maximized windows), see #751884 */
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    default:
 | 
			
		||||
      g_assert_not_reached ();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@
 | 
			
		||||
#include <meta/common.h>
 | 
			
		||||
#include <meta/types.h>
 | 
			
		||||
#include "theme-private.h"
 | 
			
		||||
#include "ui.h"
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
@@ -69,8 +70,6 @@ typedef enum
 | 
			
		||||
typedef struct _MetaFrames        MetaFrames;
 | 
			
		||||
typedef struct _MetaFramesClass   MetaFramesClass;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaUIFrame         MetaUIFrame;
 | 
			
		||||
 | 
			
		||||
struct _MetaUIFrame
 | 
			
		||||
{
 | 
			
		||||
  MetaFrames *frames;
 | 
			
		||||
 
 | 
			
		||||
@@ -115,7 +115,7 @@ struct _MetaFrameGeometry
 | 
			
		||||
 | 
			
		||||
  /* used for a memset hack */
 | 
			
		||||
#define ADDRESS_OF_BUTTON_RECTS(fgeom) (((char*)(fgeom)) + G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
 | 
			
		||||
#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, unstick_rect) + sizeof (GdkRectangle) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
 | 
			
		||||
#define LENGTH_OF_BUTTON_RECTS (G_STRUCT_OFFSET (MetaFrameGeometry, unstick_rect) + sizeof (MetaButtonSpace) - G_STRUCT_OFFSET (MetaFrameGeometry, close_rect))
 | 
			
		||||
 | 
			
		||||
  /* The button rects (if changed adjust memset hack) */
 | 
			
		||||
  MetaButtonSpace close_rect;
 | 
			
		||||
 
 | 
			
		||||
@@ -121,7 +121,7 @@ meta_frame_layout_get_borders (const MetaFrameLayout *layout,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
meta_theme_get_window_scaling_factor ()
 | 
			
		||||
meta_theme_get_window_scaling_factor (void)
 | 
			
		||||
{
 | 
			
		||||
  GdkScreen *screen;
 | 
			
		||||
  GValue value = G_VALUE_INIT;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								src/wayland/meta-wayland-data-device-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/wayland/meta-wayland-data-device-private.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 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:
 | 
			
		||||
 *     Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_WAYLAND_DATA_DEVICE_PRIVATE_H
 | 
			
		||||
#define META_WAYLAND_DATA_DEVICE_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_WAYLAND_DATA_SOURCE_WAYLAND (meta_wayland_data_source_wayland_get_type ())
 | 
			
		||||
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourceWayland,
 | 
			
		||||
                      meta_wayland_data_source_wayland,
 | 
			
		||||
                      META, WAYLAND_DATA_SOURCE_WAYLAND,
 | 
			
		||||
                      MetaWaylandDataSource);
 | 
			
		||||
 | 
			
		||||
#endif /* META_WAYLAND_DATA_DEVICE_PRIVATE_H */
 | 
			
		||||
@@ -31,24 +31,44 @@
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-wayland-data-device.h"
 | 
			
		||||
#include "meta-wayland-data-device-private.h"
 | 
			
		||||
#include "meta-wayland-seat.h"
 | 
			
		||||
#include "meta-wayland-pointer.h"
 | 
			
		||||
#include "meta-wayland-private.h"
 | 
			
		||||
#include "meta-dnd-actor-private.h"
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
struct _MetaWaylandDataOffer
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  MetaWaylandDataSource *source;
 | 
			
		||||
  struct wl_listener source_destroy_listener;
 | 
			
		||||
} MetaWaylandDataOffer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandDataSource
 | 
			
		||||
typedef struct _MetaWaylandDataSourcePrivate
 | 
			
		||||
{
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  struct wl_array mime_types;
 | 
			
		||||
  gboolean has_target;
 | 
			
		||||
};
 | 
			
		||||
} MetaWaylandDataSourcePrivate;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandDataSourceWayland
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSource parent;
 | 
			
		||||
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
} MetaWaylandDataSourceWayland;
 | 
			
		||||
 | 
			
		||||
GType meta_wayland_data_source_wayland_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandDataSource, meta_wayland_data_source,
 | 
			
		||||
                            G_TYPE_OBJECT);
 | 
			
		||||
G_DEFINE_TYPE (MetaWaylandDataSourceWayland, meta_wayland_data_source_wayland,
 | 
			
		||||
               META_TYPE_WAYLAND_DATA_SOURCE);
 | 
			
		||||
 | 
			
		||||
static MetaWaylandDataSource *
 | 
			
		||||
meta_wayland_data_source_wayland_new (struct wl_resource *resource);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
unbind_resource (struct wl_resource *resource)
 | 
			
		||||
@@ -56,6 +76,55 @@ unbind_resource (struct wl_resource *resource)
 | 
			
		||||
  wl_list_remove (wl_resource_get_link (resource));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_target (MetaWaylandDataSource *source,
 | 
			
		||||
                                 const char *mime_type)
 | 
			
		||||
{
 | 
			
		||||
  META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->target (source, mime_type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_data_source_send (MetaWaylandDataSource *source,
 | 
			
		||||
                               const char *mime_type,
 | 
			
		||||
                               int fd)
 | 
			
		||||
{
 | 
			
		||||
  META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->send (source, mime_type, fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_wayland_data_source_has_target (MetaWaylandDataSource *source)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourcePrivate *priv =
 | 
			
		||||
    meta_wayland_data_source_get_instance_private (source);
 | 
			
		||||
 | 
			
		||||
  return priv->has_target;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
 | 
			
		||||
                                         gboolean has_target)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourcePrivate *priv =
 | 
			
		||||
    meta_wayland_data_source_get_instance_private (source);
 | 
			
		||||
 | 
			
		||||
  priv->has_target = has_target;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct wl_array *
 | 
			
		||||
meta_wayland_data_source_get_mime_types (const MetaWaylandDataSource *source)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourcePrivate *priv =
 | 
			
		||||
    meta_wayland_data_source_get_instance_private (source);
 | 
			
		||||
 | 
			
		||||
  return &priv->mime_types;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_cancel (MetaWaylandDataSource *source)
 | 
			
		||||
{
 | 
			
		||||
  META_WAYLAND_DATA_SOURCE_GET_CLASS (source)->cancel (source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
data_offer_accept (struct wl_client *client,
 | 
			
		||||
                   struct wl_resource *resource,
 | 
			
		||||
@@ -70,8 +139,9 @@ data_offer_accept (struct wl_client *client,
 | 
			
		||||
 | 
			
		||||
  if (offer->source)
 | 
			
		||||
    {
 | 
			
		||||
      wl_data_source_send_target (offer->source->resource, mime_type);
 | 
			
		||||
      offer->source->has_target = mime_type != NULL;
 | 
			
		||||
      meta_wayland_data_source_target (offer->source, mime_type);
 | 
			
		||||
      meta_wayland_data_source_set_has_target (offer->source,
 | 
			
		||||
                                               mime_type != NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -82,9 +152,9 @@ data_offer_receive (struct wl_client *client, struct wl_resource *resource,
 | 
			
		||||
  MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
 | 
			
		||||
 | 
			
		||||
  if (offer->source)
 | 
			
		||||
    wl_data_source_send_send (offer->source->resource, mime_type, fd);
 | 
			
		||||
 | 
			
		||||
  close (fd);
 | 
			
		||||
    meta_wayland_data_source_send (offer->source, mime_type, fd);
 | 
			
		||||
  else
 | 
			
		||||
    close (fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -105,38 +175,34 @@ destroy_data_offer (struct wl_resource *resource)
 | 
			
		||||
  MetaWaylandDataOffer *offer = wl_resource_get_user_data (resource);
 | 
			
		||||
 | 
			
		||||
  if (offer->source)
 | 
			
		||||
    wl_list_remove (&offer->source_destroy_listener.link);
 | 
			
		||||
    g_object_remove_weak_pointer (G_OBJECT (offer->source),
 | 
			
		||||
                                  (gpointer *)&offer->source);
 | 
			
		||||
 | 
			
		||||
  g_slice_free (MetaWaylandDataOffer, offer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_offer_data_source (struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataOffer *offer;
 | 
			
		||||
 | 
			
		||||
  offer = wl_container_of (listener, offer, source_destroy_listener);
 | 
			
		||||
 | 
			
		||||
  offer->source = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct wl_resource *
 | 
			
		||||
meta_wayland_data_source_send_offer (MetaWaylandDataSource *source,
 | 
			
		||||
                                     struct wl_resource *target)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourcePrivate *priv =
 | 
			
		||||
    meta_wayland_data_source_get_instance_private (source);
 | 
			
		||||
  MetaWaylandDataOffer *offer = g_slice_new0 (MetaWaylandDataOffer);
 | 
			
		||||
  char **p;
 | 
			
		||||
 | 
			
		||||
  offer->source = source;
 | 
			
		||||
  offer->source_destroy_listener.notify = destroy_offer_data_source;
 | 
			
		||||
 | 
			
		||||
  offer->resource = wl_resource_create (wl_resource_get_client (target), &wl_data_offer_interface, wl_resource_get_version (target), 0);
 | 
			
		||||
  wl_resource_set_implementation (offer->resource, &data_offer_interface, offer, destroy_data_offer);
 | 
			
		||||
  wl_resource_add_destroy_listener (source->resource, &offer->source_destroy_listener);
 | 
			
		||||
  g_object_add_weak_pointer (G_OBJECT (source), (gpointer *)&offer->source);
 | 
			
		||||
  offer->resource = wl_resource_create (wl_resource_get_client (target),
 | 
			
		||||
                                        &wl_data_offer_interface,
 | 
			
		||||
                                        wl_resource_get_version (target), 0);
 | 
			
		||||
  wl_resource_set_implementation (offer->resource,
 | 
			
		||||
                                  &data_offer_interface,
 | 
			
		||||
                                  offer,
 | 
			
		||||
                                  destroy_data_offer);
 | 
			
		||||
 | 
			
		||||
  wl_data_device_send_data_offer (target, offer->resource);
 | 
			
		||||
 | 
			
		||||
  wl_array_for_each (p, &source->mime_types)
 | 
			
		||||
  wl_array_for_each (p, &priv->mime_types)
 | 
			
		||||
    wl_data_offer_send_offer (offer->resource, *p);
 | 
			
		||||
 | 
			
		||||
  return offer->resource;
 | 
			
		||||
@@ -147,12 +213,8 @@ data_source_offer (struct wl_client *client,
 | 
			
		||||
                   struct wl_resource *resource, const char *type)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
 | 
			
		||||
  char **p;
 | 
			
		||||
 | 
			
		||||
  p = wl_array_add (&source->mime_types, sizeof *p);
 | 
			
		||||
  if (p)
 | 
			
		||||
    *p = strdup (type);
 | 
			
		||||
  if (!p || !*p)
 | 
			
		||||
  if (!meta_wayland_data_source_add_mime_type (source, type))
 | 
			
		||||
    wl_resource_post_no_memory (resource);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -181,7 +243,6 @@ struct _MetaWaylandDragGrab {
 | 
			
		||||
  struct wl_listener      drag_icon_listener;
 | 
			
		||||
 | 
			
		||||
  MetaWaylandDataSource  *drag_data_source;
 | 
			
		||||
  struct wl_listener      drag_data_source_listener;
 | 
			
		||||
 | 
			
		||||
  ClutterActor           *feedback_actor;
 | 
			
		||||
 | 
			
		||||
@@ -199,26 +260,20 @@ destroy_drag_focus (struct wl_listener *listener, void *data)
 | 
			
		||||
  grab->drag_focus_data_device = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drag_grab_focus (MetaWaylandPointerGrab *grab,
 | 
			
		||||
                 MetaWaylandSurface     *surface)
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_drag_grab_set_focus (MetaWaylandDragGrab *drag_grab,
 | 
			
		||||
                                  MetaWaylandSurface  *surface)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
 | 
			
		||||
  MetaWaylandSeat *seat = drag_grab->seat;
 | 
			
		||||
  struct wl_client *client;
 | 
			
		||||
  struct wl_resource *data_device_resource, *offer = NULL;
 | 
			
		||||
  struct wl_display *display;
 | 
			
		||||
  guint32 serial;
 | 
			
		||||
  wl_fixed_t sx, sy;
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_focus == surface)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_focus_data_device)
 | 
			
		||||
  if (drag_grab->drag_focus)
 | 
			
		||||
    {
 | 
			
		||||
      wl_data_device_send_leave (drag_grab->drag_focus_data_device);
 | 
			
		||||
      wl_list_remove (&drag_grab->drag_focus_listener.link);
 | 
			
		||||
      drag_grab->drag_focus_data_device = NULL;
 | 
			
		||||
      meta_wayland_surface_drag_dest_focus_out (drag_grab->drag_focus);
 | 
			
		||||
      drag_grab->drag_focus = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -232,25 +287,31 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
 | 
			
		||||
  client = wl_resource_get_client (surface->resource);
 | 
			
		||||
 | 
			
		||||
  data_device_resource = wl_resource_find_for_client (&seat->data_device.resource_list, client);
 | 
			
		||||
  if (!data_device_resource)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  display = wl_client_get_display (client);
 | 
			
		||||
  serial = wl_display_next_serial (display);
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_data_source)
 | 
			
		||||
  if (drag_grab->drag_data_source && data_device_resource)
 | 
			
		||||
    offer = meta_wayland_data_source_send_offer (drag_grab->drag_data_source,
 | 
			
		||||
                                                 data_device_resource);
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_get_relative_coordinates (grab->pointer, surface, &sx, &sy);
 | 
			
		||||
  wl_data_device_send_enter (data_device_resource, serial, surface->resource,
 | 
			
		||||
                             sx, sy, offer);
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_focus = surface;
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_focus_data_device = data_device_resource;
 | 
			
		||||
  drag_grab->drag_focus_listener.notify = destroy_drag_focus;
 | 
			
		||||
  wl_resource_add_destroy_listener (data_device_resource, &drag_grab->drag_focus_listener);
 | 
			
		||||
 | 
			
		||||
  meta_wayland_surface_drag_dest_focus_in (drag_grab->drag_focus,
 | 
			
		||||
                                           offer ? wl_resource_get_user_data (offer) : NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaWaylandSurface *
 | 
			
		||||
meta_wayland_drag_grab_get_focus (MetaWaylandDragGrab *drag_grab)
 | 
			
		||||
{
 | 
			
		||||
  return drag_grab->drag_focus;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
drag_grab_focus (MetaWaylandPointerGrab *grab,
 | 
			
		||||
                 MetaWaylandSurface     *surface)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
 | 
			
		||||
 | 
			
		||||
  meta_wayland_drag_grab_set_focus (drag_grab, surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -258,17 +319,9 @@ drag_grab_motion (MetaWaylandPointerGrab *grab,
 | 
			
		||||
		  const ClutterEvent     *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
 | 
			
		||||
  wl_fixed_t sx, sy;
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_focus_data_device)
 | 
			
		||||
    {
 | 
			
		||||
      meta_wayland_pointer_get_relative_coordinates (grab->pointer,
 | 
			
		||||
						     drag_grab->drag_focus,
 | 
			
		||||
						     &sx, &sy);
 | 
			
		||||
      wl_data_device_send_motion (drag_grab->drag_focus_data_device,
 | 
			
		||||
				  clutter_event_get_time (event),
 | 
			
		||||
				  sx, sy);
 | 
			
		||||
    }
 | 
			
		||||
  if (drag_grab->drag_focus)
 | 
			
		||||
    meta_wayland_surface_drag_dest_motion (drag_grab->drag_focus, event);
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_surface)
 | 
			
		||||
    meta_feedback_actor_update (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
 | 
			
		||||
@@ -278,6 +331,8 @@ drag_grab_motion (MetaWaylandPointerGrab *grab,
 | 
			
		||||
static void
 | 
			
		||||
data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
 | 
			
		||||
{
 | 
			
		||||
  meta_wayland_drag_grab_set_focus (drag_grab, NULL);
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_origin)
 | 
			
		||||
    {
 | 
			
		||||
      drag_grab->drag_origin = NULL;
 | 
			
		||||
@@ -291,10 +346,9 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->drag_data_source)
 | 
			
		||||
    {
 | 
			
		||||
      drag_grab->drag_data_source->has_target = FALSE;
 | 
			
		||||
      wl_list_remove (&drag_grab->drag_data_source_listener.link);
 | 
			
		||||
    }
 | 
			
		||||
    g_object_weak_unref (G_OBJECT (drag_grab->drag_data_source),
 | 
			
		||||
                         drag_grab_data_source_destroyed,
 | 
			
		||||
                         drag_grab);
 | 
			
		||||
 | 
			
		||||
  if (drag_grab->feedback_actor)
 | 
			
		||||
    {
 | 
			
		||||
@@ -304,8 +358,6 @@ data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
 | 
			
		||||
 | 
			
		||||
  drag_grab->seat->data_device.current_grab = NULL;
 | 
			
		||||
 | 
			
		||||
  drag_grab_focus (&drag_grab->generic, NULL);
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
 | 
			
		||||
  g_slice_free (MetaWaylandDragGrab, drag_grab);
 | 
			
		||||
}
 | 
			
		||||
@@ -323,10 +375,9 @@ drag_grab_button (MetaWaylandPointerGrab *grab,
 | 
			
		||||
    {
 | 
			
		||||
      gboolean success = FALSE;
 | 
			
		||||
 | 
			
		||||
      if (drag_grab->drag_focus_data_device &&
 | 
			
		||||
          drag_grab->drag_data_source->has_target)
 | 
			
		||||
      if (meta_wayland_data_source_has_target (drag_grab->drag_data_source))
 | 
			
		||||
        {
 | 
			
		||||
          wl_data_device_send_drop (drag_grab->drag_focus_data_device);
 | 
			
		||||
          meta_wayland_surface_drag_dest_drop (drag_grab->drag_focus);
 | 
			
		||||
          success = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -355,23 +406,24 @@ destroy_data_device_origin (struct wl_listener *listener, void *data)
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_origin = NULL;
 | 
			
		||||
  data_device_end_drag_grab (drag_grab);
 | 
			
		||||
  meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_data_device_source (struct wl_listener *listener, void *data)
 | 
			
		||||
drag_grab_data_source_destroyed (gpointer data, GObject *where_the_object_was)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab =
 | 
			
		||||
    wl_container_of (listener, drag_grab, drag_data_source_listener);
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab = data;
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_data_source = NULL;
 | 
			
		||||
  data_device_end_drag_grab (drag_grab);
 | 
			
		||||
  meta_wayland_data_device_set_dnd_source (&drag_grab->seat->data_device, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_data_device_icon (struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab =
 | 
			
		||||
    wl_container_of (listener, drag_grab, drag_data_source_listener);
 | 
			
		||||
    wl_container_of (listener, drag_grab, drag_icon_listener);
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_surface = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -379,6 +431,76 @@ destroy_data_device_icon (struct wl_listener *listener, void *data)
 | 
			
		||||
    clutter_actor_remove_all_children (drag_grab->feedback_actor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_data_device_start_drag (MetaWaylandDataDevice                 *data_device,
 | 
			
		||||
                                     struct wl_client                      *client,
 | 
			
		||||
                                     const MetaWaylandPointerGrabInterface *funcs,
 | 
			
		||||
                                     MetaWaylandSurface                    *surface,
 | 
			
		||||
                                     MetaWaylandDataSource                 *source,
 | 
			
		||||
                                     MetaWaylandSurface                    *icon_surface)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab;
 | 
			
		||||
  ClutterPoint pos, stage_pos;
 | 
			
		||||
 | 
			
		||||
  data_device->current_grab = drag_grab = g_slice_new0 (MetaWaylandDragGrab);
 | 
			
		||||
 | 
			
		||||
  drag_grab->generic.interface = funcs;
 | 
			
		||||
  drag_grab->generic.pointer = &seat->pointer;
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_client = client;
 | 
			
		||||
  drag_grab->seat = seat;
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_origin = surface;
 | 
			
		||||
  drag_grab->drag_origin_listener.notify = destroy_data_device_origin;
 | 
			
		||||
  wl_resource_add_destroy_listener (surface->resource,
 | 
			
		||||
                                    &drag_grab->drag_origin_listener);
 | 
			
		||||
 | 
			
		||||
  clutter_input_device_get_coords (seat->pointer.device, NULL, &pos);
 | 
			
		||||
  clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)),
 | 
			
		||||
                                       pos.x, pos.y, &stage_pos.x, &stage_pos.y);
 | 
			
		||||
  drag_grab->drag_start_x = stage_pos.x;
 | 
			
		||||
  drag_grab->drag_start_y = stage_pos.y;
 | 
			
		||||
 | 
			
		||||
  g_object_weak_ref (G_OBJECT (source),
 | 
			
		||||
                     drag_grab_data_source_destroyed,
 | 
			
		||||
                     drag_grab);
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_data_source = source;
 | 
			
		||||
  meta_wayland_data_device_set_dnd_source (data_device,
 | 
			
		||||
                                           drag_grab->drag_data_source);
 | 
			
		||||
 | 
			
		||||
  if (icon_surface)
 | 
			
		||||
    {
 | 
			
		||||
      drag_grab->drag_surface = icon_surface;
 | 
			
		||||
 | 
			
		||||
      drag_grab->drag_icon_listener.notify = destroy_data_device_icon;
 | 
			
		||||
      wl_resource_add_destroy_listener (icon_surface->resource,
 | 
			
		||||
                                        &drag_grab->drag_icon_listener);
 | 
			
		||||
 | 
			
		||||
      drag_grab->feedback_actor = meta_dnd_actor_new (CLUTTER_ACTOR (drag_grab->drag_origin->surface_actor),
 | 
			
		||||
                                                      drag_grab->drag_start_x,
 | 
			
		||||
                                                      drag_grab->drag_start_y);
 | 
			
		||||
      meta_feedback_actor_set_anchor (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
 | 
			
		||||
                                      -drag_grab->drag_surface->offset_x,
 | 
			
		||||
                                      -drag_grab->drag_surface->offset_y);
 | 
			
		||||
      clutter_actor_add_child (drag_grab->feedback_actor,
 | 
			
		||||
                               CLUTTER_ACTOR (drag_grab->drag_surface->surface_actor));
 | 
			
		||||
 | 
			
		||||
      meta_feedback_actor_set_position (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
 | 
			
		||||
                                        pos.x, pos.y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_start_grab (&seat->pointer, (MetaWaylandPointerGrab*) drag_grab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_data_device_end_drag (MetaWaylandDataDevice *data_device)
 | 
			
		||||
{
 | 
			
		||||
  if (data_device->current_grab)
 | 
			
		||||
    data_device_end_drag_grab (data_device->current_grab);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
data_device_start_drag (struct wl_client *client,
 | 
			
		||||
                        struct wl_resource *resource,
 | 
			
		||||
@@ -388,9 +510,8 @@ data_device_start_drag (struct wl_client *client,
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
 | 
			
		||||
  MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
 | 
			
		||||
  MetaWaylandSurface *surface = NULL;
 | 
			
		||||
  MetaWaylandDragGrab *drag_grab;
 | 
			
		||||
  ClutterPoint pos;
 | 
			
		||||
  MetaWaylandSurface *surface = NULL, *icon_surface = NULL;
 | 
			
		||||
  MetaWaylandDataSource *drag_source = NULL;
 | 
			
		||||
 | 
			
		||||
  if (origin_resource)
 | 
			
		||||
    surface = wl_resource_get_user_data (origin_resource);
 | 
			
		||||
@@ -410,69 +531,28 @@ data_device_start_drag (struct wl_client *client,
 | 
			
		||||
      seat->pointer.grab != &seat->pointer.default_grab)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (icon_resource)
 | 
			
		||||
    icon_surface = wl_resource_get_user_data (icon_resource);
 | 
			
		||||
  if (source_resource)
 | 
			
		||||
    drag_source = wl_resource_get_user_data (source_resource);
 | 
			
		||||
 | 
			
		||||
  if (icon_resource &&
 | 
			
		||||
      meta_wayland_surface_set_role (wl_resource_get_user_data (icon_resource),
 | 
			
		||||
      meta_wayland_surface_set_role (icon_surface,
 | 
			
		||||
                                     META_WAYLAND_SURFACE_ROLE_DND,
 | 
			
		||||
                                     resource,
 | 
			
		||||
                                     WL_DATA_DEVICE_ERROR_ROLE) != 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  data_device->current_grab = drag_grab = g_slice_new0 (MetaWaylandDragGrab);
 | 
			
		||||
 | 
			
		||||
  drag_grab->generic.interface = &drag_grab_interface;
 | 
			
		||||
  drag_grab->generic.pointer = &seat->pointer;
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_client = client;
 | 
			
		||||
  drag_grab->seat = seat;
 | 
			
		||||
 | 
			
		||||
  drag_grab->drag_origin = surface;
 | 
			
		||||
  drag_grab->drag_origin_listener.notify = destroy_data_device_origin;
 | 
			
		||||
  wl_resource_add_destroy_listener (origin_resource,
 | 
			
		||||
                                    &drag_grab->drag_origin_listener);
 | 
			
		||||
 | 
			
		||||
  clutter_input_device_get_coords (seat->pointer.device, NULL, &pos);
 | 
			
		||||
  clutter_actor_transform_stage_point (CLUTTER_ACTOR (meta_surface_actor_get_texture (surface->surface_actor)),
 | 
			
		||||
                                       pos.x, pos.y, &pos.x, &pos.y);
 | 
			
		||||
  drag_grab->drag_start_x = pos.x;
 | 
			
		||||
  drag_grab->drag_start_y = pos.y;
 | 
			
		||||
 | 
			
		||||
  if (source_resource)
 | 
			
		||||
    {
 | 
			
		||||
      drag_grab->drag_data_source = wl_resource_get_user_data (source_resource);
 | 
			
		||||
      drag_grab->drag_data_source_listener.notify = destroy_data_device_source;
 | 
			
		||||
      wl_resource_add_destroy_listener (source_resource,
 | 
			
		||||
                                        &drag_grab->drag_data_source_listener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (icon_resource)
 | 
			
		||||
    {
 | 
			
		||||
      drag_grab->drag_surface = wl_resource_get_user_data (icon_resource);
 | 
			
		||||
      drag_grab->drag_icon_listener.notify = destroy_data_device_icon;
 | 
			
		||||
      wl_resource_add_destroy_listener (icon_resource,
 | 
			
		||||
                                        &drag_grab->drag_icon_listener);
 | 
			
		||||
 | 
			
		||||
      drag_grab->feedback_actor = meta_dnd_actor_new (CLUTTER_ACTOR (drag_grab->drag_origin->surface_actor),
 | 
			
		||||
                                                      drag_grab->drag_start_x,
 | 
			
		||||
                                                      drag_grab->drag_start_y);
 | 
			
		||||
      meta_feedback_actor_set_anchor (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
 | 
			
		||||
                                      -drag_grab->drag_surface->offset_x,
 | 
			
		||||
                                      -drag_grab->drag_surface->offset_y);
 | 
			
		||||
      clutter_actor_add_child (drag_grab->feedback_actor,
 | 
			
		||||
                               CLUTTER_ACTOR (drag_grab->drag_surface->surface_actor));
 | 
			
		||||
 | 
			
		||||
      clutter_input_device_get_coords (seat->pointer.device, NULL, &pos);
 | 
			
		||||
      meta_feedback_actor_set_position (META_FEEDBACK_ACTOR (drag_grab->feedback_actor),
 | 
			
		||||
                                        pos.x, pos.y);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_set_focus (&seat->pointer, NULL);
 | 
			
		||||
  meta_wayland_pointer_start_grab (&seat->pointer, (MetaWaylandPointerGrab*)drag_grab);
 | 
			
		||||
  meta_wayland_data_device_start_drag (data_device, client,
 | 
			
		||||
                                       &drag_grab_interface,
 | 
			
		||||
                                       surface, drag_source, icon_surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_selection_data_source (struct wl_listener *listener, void *data)
 | 
			
		||||
selection_data_source_destroyed (gpointer data, GObject *object_was_here)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataDevice *data_device = wl_container_of (listener, data_device, selection_data_source_listener);
 | 
			
		||||
  MetaWaylandDataDevice *data_device = data;
 | 
			
		||||
  MetaWaylandSeat *seat = wl_container_of (data_device, seat, data_device);
 | 
			
		||||
  struct wl_resource *data_device_resource;
 | 
			
		||||
  struct wl_client *focus_client = NULL;
 | 
			
		||||
@@ -489,6 +569,190 @@ destroy_selection_data_source (struct wl_listener *listener, void *data)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_source_send (MetaWaylandDataSource *source,
 | 
			
		||||
                          const gchar           *mime_type,
 | 
			
		||||
                          gint                   fd)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourceWayland *source_wayland =
 | 
			
		||||
    META_WAYLAND_DATA_SOURCE_WAYLAND (source);
 | 
			
		||||
 | 
			
		||||
  wl_data_source_send_send (source_wayland->resource, mime_type, fd);
 | 
			
		||||
  close (fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_source_target (MetaWaylandDataSource *source,
 | 
			
		||||
                            const gchar           *mime_type)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourceWayland *source_wayland =
 | 
			
		||||
    META_WAYLAND_DATA_SOURCE_WAYLAND (source);
 | 
			
		||||
 | 
			
		||||
  wl_data_source_send_target (source_wayland->resource, mime_type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_source_cancel (MetaWaylandDataSource *source)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourceWayland *source_wayland =
 | 
			
		||||
    META_WAYLAND_DATA_SOURCE_WAYLAND (source);
 | 
			
		||||
 | 
			
		||||
  wl_data_source_send_cancelled (source_wayland->resource);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_source_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  G_OBJECT_CLASS (meta_wayland_data_source_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_wayland_init (MetaWaylandDataSourceWayland *source_wayland)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_wayland_class_init (MetaWaylandDataSourceWaylandClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  MetaWaylandDataSourceClass *data_source_class =
 | 
			
		||||
    META_WAYLAND_DATA_SOURCE_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = meta_wayland_source_finalize;
 | 
			
		||||
 | 
			
		||||
  data_source_class->send = meta_wayland_source_send;
 | 
			
		||||
  data_source_class->target = meta_wayland_source_target;
 | 
			
		||||
  data_source_class->cancel = meta_wayland_source_cancel;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSource *source = META_WAYLAND_DATA_SOURCE (object);
 | 
			
		||||
  MetaWaylandDataSourcePrivate *priv =
 | 
			
		||||
    meta_wayland_data_source_get_instance_private (source);
 | 
			
		||||
  char **pos;
 | 
			
		||||
 | 
			
		||||
  wl_array_for_each (pos, &priv->mime_types)
 | 
			
		||||
    g_free (*pos);
 | 
			
		||||
  wl_array_release (&priv->mime_types);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_wayland_data_source_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_init (MetaWaylandDataSource *source)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourcePrivate *priv =
 | 
			
		||||
    meta_wayland_data_source_get_instance_private (source);
 | 
			
		||||
 | 
			
		||||
  wl_array_init (&priv->mime_types);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_data_source_class_init (MetaWaylandDataSourceClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = meta_wayland_data_source_finalize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_drag_dest_focus_in (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                 MetaWaylandSurface    *surface,
 | 
			
		||||
                                 MetaWaylandDataOffer  *offer)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDragGrab *grab = data_device->current_grab;
 | 
			
		||||
  struct wl_display *display;
 | 
			
		||||
  struct wl_client *client;
 | 
			
		||||
  wl_fixed_t sx, sy;
 | 
			
		||||
 | 
			
		||||
  if (!grab->drag_focus_data_device)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  client = wl_resource_get_client (surface->resource);
 | 
			
		||||
  display = wl_client_get_display (client);
 | 
			
		||||
 | 
			
		||||
  grab->drag_focus_listener.notify = destroy_drag_focus;
 | 
			
		||||
  wl_resource_add_destroy_listener (grab->drag_focus_data_device,
 | 
			
		||||
                                    &grab->drag_focus_listener);
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_get_relative_coordinates (grab->generic.pointer,
 | 
			
		||||
                                                 surface, &sx, &sy);
 | 
			
		||||
  wl_data_device_send_enter (grab->drag_focus_data_device,
 | 
			
		||||
                             wl_display_next_serial (display),
 | 
			
		||||
                             surface->resource, sx, sy, offer->resource);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_drag_dest_focus_out (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                  MetaWaylandSurface    *surface)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDragGrab *grab = data_device->current_grab;
 | 
			
		||||
 | 
			
		||||
  if (grab->drag_focus_data_device)
 | 
			
		||||
    wl_data_device_send_leave (grab->drag_focus_data_device);
 | 
			
		||||
 | 
			
		||||
  wl_list_remove (&grab->drag_focus_listener.link);
 | 
			
		||||
  grab->drag_focus_data_device = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_drag_dest_motion (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                               MetaWaylandSurface    *surface,
 | 
			
		||||
                               const ClutterEvent    *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDragGrab *grab = data_device->current_grab;
 | 
			
		||||
  wl_fixed_t sx, sy;
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_get_relative_coordinates (grab->generic.pointer,
 | 
			
		||||
                                                 grab->drag_focus,
 | 
			
		||||
                                                 &sx, &sy);
 | 
			
		||||
  wl_data_device_send_motion (grab->drag_focus_data_device,
 | 
			
		||||
                              clutter_event_get_time (event),
 | 
			
		||||
                              sx, sy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_drag_dest_drop (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                             MetaWaylandSurface    *surface)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDragGrab *grab = data_device->current_grab;
 | 
			
		||||
 | 
			
		||||
  wl_data_device_send_drop (grab->drag_focus_data_device);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const MetaWaylandDragDestFuncs meta_wayland_drag_dest_funcs = {
 | 
			
		||||
  meta_wayland_drag_dest_focus_in,
 | 
			
		||||
  meta_wayland_drag_dest_focus_out,
 | 
			
		||||
  meta_wayland_drag_dest_motion,
 | 
			
		||||
  meta_wayland_drag_dest_drop
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const MetaWaylandDragDestFuncs *
 | 
			
		||||
meta_wayland_data_device_get_drag_dest_funcs (void)
 | 
			
		||||
{
 | 
			
		||||
  return &meta_wayland_drag_dest_funcs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_data_device_set_dnd_source (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                         MetaWaylandDataSource *source)
 | 
			
		||||
{
 | 
			
		||||
  if (data_device->dnd_data_source == source)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (data_device->dnd_data_source)
 | 
			
		||||
    g_object_remove_weak_pointer (G_OBJECT (source),
 | 
			
		||||
                                  (gpointer *)&data_device->dnd_data_source);
 | 
			
		||||
 | 
			
		||||
  data_device->dnd_data_source = source;
 | 
			
		||||
  g_object_add_weak_pointer (G_OBJECT (source),
 | 
			
		||||
                             (gpointer *)&data_device->dnd_data_source);
 | 
			
		||||
 | 
			
		||||
  wl_signal_emit (&data_device->dnd_ownership_signal, source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                        MetaWaylandDataSource *source,
 | 
			
		||||
                                        guint32 serial)
 | 
			
		||||
@@ -503,8 +767,10 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
 | 
			
		||||
 | 
			
		||||
  if (data_device->selection_data_source)
 | 
			
		||||
    {
 | 
			
		||||
      wl_data_source_send_cancelled (data_device->selection_data_source->resource);
 | 
			
		||||
      wl_list_remove (&data_device->selection_data_source_listener.link);
 | 
			
		||||
      meta_wayland_data_source_cancel (data_device->selection_data_source);
 | 
			
		||||
      g_object_weak_unref (G_OBJECT (data_device->selection_data_source),
 | 
			
		||||
                           selection_data_source_destroyed,
 | 
			
		||||
                           data_device);
 | 
			
		||||
      data_device->selection_data_source = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -531,9 +797,12 @@ meta_wayland_data_device_set_selection (MetaWaylandDataDevice *data_device,
 | 
			
		||||
 | 
			
		||||
  if (source)
 | 
			
		||||
    {
 | 
			
		||||
      data_device->selection_data_source_listener.notify = destroy_selection_data_source;
 | 
			
		||||
      wl_resource_add_destroy_listener (source->resource, &data_device->selection_data_source_listener);
 | 
			
		||||
      g_object_weak_ref (G_OBJECT (source),
 | 
			
		||||
                         selection_data_source_destroyed,
 | 
			
		||||
                         data_device);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  wl_signal_emit (&data_device->selection_ownership_signal, source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -545,10 +814,10 @@ data_device_set_selection (struct wl_client *client,
 | 
			
		||||
  MetaWaylandDataDevice *data_device = wl_resource_get_user_data (resource);
 | 
			
		||||
  MetaWaylandDataSource *source;
 | 
			
		||||
 | 
			
		||||
  if (!source_resource)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  source = wl_resource_get_user_data (source_resource);
 | 
			
		||||
  if (source_resource)
 | 
			
		||||
    source = wl_resource_get_user_data (source_resource);
 | 
			
		||||
  else
 | 
			
		||||
    source = NULL;
 | 
			
		||||
 | 
			
		||||
  /* FIXME: Store serial and check against incoming serial here. */
 | 
			
		||||
  meta_wayland_data_device_set_selection (data_device, source, serial);
 | 
			
		||||
@@ -569,26 +838,21 @@ static const struct wl_data_device_interface data_device_interface = {
 | 
			
		||||
static void
 | 
			
		||||
destroy_data_source (struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSource *source = wl_resource_get_user_data (resource);
 | 
			
		||||
  char **p;
 | 
			
		||||
  MetaWaylandDataSourceWayland *source = wl_resource_get_user_data (resource);
 | 
			
		||||
 | 
			
		||||
  wl_array_for_each (p, &source->mime_types) free (*p);
 | 
			
		||||
 | 
			
		||||
  wl_array_release (&source->mime_types);
 | 
			
		||||
 | 
			
		||||
  g_slice_free (MetaWaylandDataSource, source);
 | 
			
		||||
  source->resource = NULL;
 | 
			
		||||
  g_object_unref (source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
create_data_source (struct wl_client *client,
 | 
			
		||||
                    struct wl_resource *resource, guint32 id)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSource *source = g_slice_new0 (MetaWaylandDataSource);
 | 
			
		||||
  struct wl_resource *source_resource;
 | 
			
		||||
 | 
			
		||||
  source->resource = wl_resource_create (client, &wl_data_source_interface, wl_resource_get_version (resource), id);
 | 
			
		||||
  wl_resource_set_implementation (source->resource, &data_source_interface, source, destroy_data_source);
 | 
			
		||||
 | 
			
		||||
  wl_array_init (&source->mime_types);
 | 
			
		||||
  source_resource = wl_resource_create (client, &wl_data_source_interface,
 | 
			
		||||
                                        wl_resource_get_version (resource), id);
 | 
			
		||||
  meta_wayland_data_source_wayland_new (source_resource);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -632,6 +896,8 @@ void
 | 
			
		||||
meta_wayland_data_device_init (MetaWaylandDataDevice *data_device)
 | 
			
		||||
{
 | 
			
		||||
  wl_list_init (&data_device->resource_list);
 | 
			
		||||
  wl_signal_init (&data_device->selection_ownership_signal);
 | 
			
		||||
  wl_signal_init (&data_device->dnd_ownership_signal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -656,6 +922,8 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandDataDevice *data_device)
 | 
			
		||||
      offer = meta_wayland_data_source_send_offer (source, data_device_resource);
 | 
			
		||||
      wl_data_device_send_selection (data_device_resource, offer);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    wl_data_device_send_selection (data_device_resource, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
@@ -683,3 +951,52 @@ meta_wayland_data_device_update_dnd_surface (MetaWaylandDataDevice *data_device)
 | 
			
		||||
                                  -drag_grab->drag_surface->offset_x,
 | 
			
		||||
                                  -drag_grab->drag_surface->offset_y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_wayland_data_source_has_mime_type (const MetaWaylandDataSource *source,
 | 
			
		||||
                                        const gchar                 *mime_type)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourcePrivate *priv =
 | 
			
		||||
    meta_wayland_data_source_get_instance_private (source);
 | 
			
		||||
  gchar **p;
 | 
			
		||||
 | 
			
		||||
  wl_array_for_each (p, &priv->mime_types)
 | 
			
		||||
    {
 | 
			
		||||
      if (g_strcmp0 (mime_type, *p) == 0)
 | 
			
		||||
        return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaWaylandDataSource *
 | 
			
		||||
meta_wayland_data_source_wayland_new (struct wl_resource *resource)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourceWayland *source_wayland =
 | 
			
		||||
   g_object_new (META_TYPE_WAYLAND_DATA_SOURCE_WAYLAND, NULL);
 | 
			
		||||
 | 
			
		||||
  source_wayland->resource = resource;
 | 
			
		||||
  wl_resource_set_implementation (resource, &data_source_interface,
 | 
			
		||||
                                  source_wayland, destroy_data_source);
 | 
			
		||||
 | 
			
		||||
  return META_WAYLAND_DATA_SOURCE (source_wayland);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_wayland_data_source_add_mime_type (MetaWaylandDataSource *source,
 | 
			
		||||
                                        const gchar           *mime_type)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandDataSourcePrivate *priv =
 | 
			
		||||
    meta_wayland_data_source_get_instance_private (source);
 | 
			
		||||
  gchar **pos;
 | 
			
		||||
 | 
			
		||||
  pos = wl_array_add (&priv->mime_types, sizeof (*pos));
 | 
			
		||||
 | 
			
		||||
  if (pos)
 | 
			
		||||
    {
 | 
			
		||||
      *pos = g_strdup (mime_type);
 | 
			
		||||
      return *pos != NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,20 +24,44 @@
 | 
			
		||||
#define META_WAYLAND_DATA_DEVICE_H
 | 
			
		||||
 | 
			
		||||
#include <wayland-server.h>
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
#include "meta-wayland-types.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandDragGrab MetaWaylandDragGrab;
 | 
			
		||||
typedef struct _MetaWaylandDataSourceFuncs MetaWaylandDataSourceFuncs;
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_WAYLAND_DATA_SOURCE (meta_wayland_data_source_get_type ())
 | 
			
		||||
G_DECLARE_DERIVABLE_TYPE (MetaWaylandDataSource, meta_wayland_data_source,
 | 
			
		||||
                          META, WAYLAND_DATA_SOURCE, GObject);
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandDataSourceClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  void (* send)    (MetaWaylandDataSource *source,
 | 
			
		||||
                    const gchar           *mime_type,
 | 
			
		||||
                    gint                   fd);
 | 
			
		||||
  void (* target)  (MetaWaylandDataSource *source,
 | 
			
		||||
                    const gchar           *mime_type);
 | 
			
		||||
  void (* cancel)  (MetaWaylandDataSource *source);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandDataDevice
 | 
			
		||||
{
 | 
			
		||||
  uint32_t selection_serial;
 | 
			
		||||
  MetaWaylandDataSource *selection_data_source;
 | 
			
		||||
  MetaWaylandDataSource *dnd_data_source;
 | 
			
		||||
  struct wl_listener selection_data_source_listener;
 | 
			
		||||
  struct wl_list resource_list;
 | 
			
		||||
  MetaWaylandDragGrab *current_grab;
 | 
			
		||||
 | 
			
		||||
  struct wl_signal selection_ownership_signal;
 | 
			
		||||
  struct wl_signal dnd_ownership_signal;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType meta_wayland_data_source_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void meta_wayland_data_device_manager_init (MetaWaylandCompositor *compositor);
 | 
			
		||||
 | 
			
		||||
void meta_wayland_data_device_init (MetaWaylandDataDevice *data_device);
 | 
			
		||||
@@ -48,4 +72,45 @@ gboolean meta_wayland_data_device_is_dnd_surface (MetaWaylandDataDevice *data_de
 | 
			
		||||
                                                  MetaWaylandSurface    *surface);
 | 
			
		||||
void meta_wayland_data_device_update_dnd_surface (MetaWaylandDataDevice *data_device);
 | 
			
		||||
 | 
			
		||||
void meta_wayland_data_device_set_dnd_source     (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                                  MetaWaylandDataSource *source);
 | 
			
		||||
void meta_wayland_data_device_set_selection      (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                                                  MetaWaylandDataSource *source,
 | 
			
		||||
                                                  guint32 serial);
 | 
			
		||||
 | 
			
		||||
gboolean meta_wayland_data_source_add_mime_type  (MetaWaylandDataSource *source,
 | 
			
		||||
                                                  const gchar           *mime_type);
 | 
			
		||||
 | 
			
		||||
gboolean meta_wayland_data_source_has_mime_type  (const MetaWaylandDataSource *source,
 | 
			
		||||
                                                  const gchar                 *mime_type);
 | 
			
		||||
 | 
			
		||||
struct wl_array *
 | 
			
		||||
         meta_wayland_data_source_get_mime_types (const MetaWaylandDataSource *source);
 | 
			
		||||
 | 
			
		||||
gboolean meta_wayland_data_source_has_target     (MetaWaylandDataSource *source);
 | 
			
		||||
 | 
			
		||||
void     meta_wayland_data_source_set_has_target (MetaWaylandDataSource *source,
 | 
			
		||||
                                                  gboolean               has_target);
 | 
			
		||||
 | 
			
		||||
void     meta_wayland_data_source_send           (MetaWaylandDataSource *source,
 | 
			
		||||
                                                  const gchar           *mime_type,
 | 
			
		||||
                                                  gint                   fd);
 | 
			
		||||
 | 
			
		||||
const MetaWaylandDragDestFuncs *
 | 
			
		||||
         meta_wayland_data_device_get_drag_dest_funcs (void);
 | 
			
		||||
 | 
			
		||||
void     meta_wayland_data_device_start_drag     (MetaWaylandDataDevice                 *data_device,
 | 
			
		||||
                                                  struct wl_client                      *client,
 | 
			
		||||
                                                  const MetaWaylandPointerGrabInterface *funcs,
 | 
			
		||||
                                                  MetaWaylandSurface                    *surface,
 | 
			
		||||
                                                  MetaWaylandDataSource                 *source,
 | 
			
		||||
                                                  MetaWaylandSurface                    *icon_surface);
 | 
			
		||||
 | 
			
		||||
void     meta_wayland_data_device_end_drag       (MetaWaylandDataDevice                 *data_device);
 | 
			
		||||
 | 
			
		||||
void     meta_wayland_drag_grab_set_focus        (MetaWaylandDragGrab             *drag_grab,
 | 
			
		||||
                                                  MetaWaylandSurface              *surface);
 | 
			
		||||
MetaWaylandSurface *
 | 
			
		||||
         meta_wayland_drag_grab_get_focus        (MetaWaylandDragGrab             *drag_grab);
 | 
			
		||||
 | 
			
		||||
#endif /* META_WAYLAND_DATA_DEVICE_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -31,14 +31,15 @@
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  MetaOutput               *output;
 | 
			
		||||
  struct wl_global         *global;
 | 
			
		||||
  int                       x, y;
 | 
			
		||||
  enum wl_output_transform  transform;
 | 
			
		||||
enum {
 | 
			
		||||
  OUTPUT_DESTROYED,
 | 
			
		||||
 | 
			
		||||
  GList                    *resources;
 | 
			
		||||
} MetaWaylandOutput;
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL];
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (MetaWaylandOutput, meta_wayland_output, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
output_resource_destroy (struct wl_resource *res)
 | 
			
		||||
@@ -46,6 +47,9 @@ output_resource_destroy (struct wl_resource *res)
 | 
			
		||||
  MetaWaylandOutput *wayland_output;
 | 
			
		||||
 | 
			
		||||
  wayland_output = wl_resource_get_user_data (res);
 | 
			
		||||
  if (!wayland_output)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  wayland_output->resources = g_list_remove (wayland_output->resources, res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -56,9 +60,10 @@ bind_output (struct wl_client *client,
 | 
			
		||||
             guint32 id)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandOutput *wayland_output = data;
 | 
			
		||||
  MetaOutput *output = wayland_output->output;
 | 
			
		||||
  MetaMonitorInfo *monitor_info = wayland_output->monitor_info;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
  guint mode_flags;
 | 
			
		||||
  MetaOutput *output = monitor_info->outputs[0];
 | 
			
		||||
 | 
			
		||||
  resource = wl_resource_create (client, &wl_output_interface, version, id);
 | 
			
		||||
  wayland_output->resources = g_list_prepend (wayland_output->resources, resource);
 | 
			
		||||
@@ -66,17 +71,17 @@ bind_output (struct wl_client *client,
 | 
			
		||||
  wl_resource_set_user_data (resource, wayland_output);
 | 
			
		||||
  wl_resource_set_destructor (resource, output_resource_destroy);
 | 
			
		||||
 | 
			
		||||
  meta_verbose ("Binding output %p/%s (%u, %u, %u, %u) x %f\n",
 | 
			
		||||
                output, output->name,
 | 
			
		||||
                output->crtc->rect.x, output->crtc->rect.y,
 | 
			
		||||
                output->crtc->rect.width, output->crtc->rect.height,
 | 
			
		||||
                output->crtc->current_mode->refresh_rate);
 | 
			
		||||
  meta_verbose ("Binding monitor %p/%s (%u, %u, %u, %u) x %f\n",
 | 
			
		||||
                monitor_info, output->name,
 | 
			
		||||
                monitor_info->rect.x, monitor_info->rect.y,
 | 
			
		||||
                monitor_info->rect.width, monitor_info->rect.height,
 | 
			
		||||
                monitor_info->refresh_rate);
 | 
			
		||||
 | 
			
		||||
  wl_output_send_geometry (resource,
 | 
			
		||||
                           (int)output->crtc->rect.x,
 | 
			
		||||
                           (int)output->crtc->rect.y,
 | 
			
		||||
                           output->width_mm,
 | 
			
		||||
                           output->height_mm,
 | 
			
		||||
                           (int)monitor_info->rect.x,
 | 
			
		||||
                           (int)monitor_info->rect.y,
 | 
			
		||||
                           monitor_info->width_mm,
 | 
			
		||||
                           monitor_info->height_mm,
 | 
			
		||||
                           /* Cogl values reflect XRandR values,
 | 
			
		||||
                              and so does wayland */
 | 
			
		||||
                           output->subpixel_order,
 | 
			
		||||
@@ -92,9 +97,9 @@ bind_output (struct wl_client *client,
 | 
			
		||||
 | 
			
		||||
  wl_output_send_mode (resource,
 | 
			
		||||
                       mode_flags,
 | 
			
		||||
                       (int)output->crtc->current_mode->width,
 | 
			
		||||
                       (int)output->crtc->current_mode->height,
 | 
			
		||||
                       (int)output->crtc->current_mode->refresh_rate);
 | 
			
		||||
                       (int)monitor_info->rect.width,
 | 
			
		||||
                       (int)monitor_info->rect.height,
 | 
			
		||||
                       (int)monitor_info->refresh_rate);
 | 
			
		||||
 | 
			
		||||
  if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
 | 
			
		||||
    wl_output_send_scale (resource, output->scale);
 | 
			
		||||
@@ -107,16 +112,9 @@ static void
 | 
			
		||||
wayland_output_destroy_notify (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandOutput *wayland_output = data;
 | 
			
		||||
  GList *resources;
 | 
			
		||||
 | 
			
		||||
  /* Make sure the destructors don't mess with the list */
 | 
			
		||||
  resources = wayland_output->resources;
 | 
			
		||||
  wayland_output->resources = NULL;
 | 
			
		||||
 | 
			
		||||
  wl_global_destroy (wayland_output->global);
 | 
			
		||||
  g_list_free (resources);
 | 
			
		||||
 | 
			
		||||
  g_slice_free (MetaWaylandOutput, wayland_output);
 | 
			
		||||
  g_signal_emit (wayland_output, signals[OUTPUT_DESTROYED], 0);
 | 
			
		||||
  g_object_unref (wayland_output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline enum wl_output_transform
 | 
			
		||||
@@ -128,14 +126,13 @@ wl_output_transform_from_meta_monitor_transform (MetaMonitorTransform transform)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
 | 
			
		||||
                                  MetaOutput        *output)
 | 
			
		||||
                                  MetaMonitorInfo *monitor_info)
 | 
			
		||||
{
 | 
			
		||||
  GList *iter;
 | 
			
		||||
  guint mode_flags;
 | 
			
		||||
  MetaOutput *output = monitor_info->outputs[0];
 | 
			
		||||
  enum wl_output_transform wl_transform = wl_output_transform_from_meta_monitor_transform (output->crtc->transform);
 | 
			
		||||
 | 
			
		||||
  g_assert (output->crtc->current_mode != NULL);
 | 
			
		||||
 | 
			
		||||
  mode_flags = WL_OUTPUT_MODE_CURRENT;
 | 
			
		||||
  if (output->crtc->current_mode == output->preferred_mode)
 | 
			
		||||
    mode_flags |= WL_OUTPUT_MODE_PREFERRED;
 | 
			
		||||
@@ -144,15 +141,15 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
 | 
			
		||||
    {
 | 
			
		||||
      struct wl_resource *resource = iter->data;
 | 
			
		||||
 | 
			
		||||
      if (wayland_output->x != output->crtc->rect.x ||
 | 
			
		||||
          wayland_output->y != output->crtc->rect.y ||
 | 
			
		||||
      if (wayland_output->x != monitor_info->rect.x ||
 | 
			
		||||
          wayland_output->y != monitor_info->rect.y ||
 | 
			
		||||
          wayland_output->transform != wl_transform)
 | 
			
		||||
        {
 | 
			
		||||
          wl_output_send_geometry (resource,
 | 
			
		||||
                                   (int)output->crtc->rect.x,
 | 
			
		||||
                                   (int)output->crtc->rect.y,
 | 
			
		||||
                                   output->width_mm,
 | 
			
		||||
                                   output->height_mm,
 | 
			
		||||
                                   (int)monitor_info->rect.x,
 | 
			
		||||
                                   (int)monitor_info->rect.y,
 | 
			
		||||
                                   monitor_info->width_mm,
 | 
			
		||||
                                   monitor_info->height_mm,
 | 
			
		||||
                                   output->subpixel_order,
 | 
			
		||||
                                   output->vendor,
 | 
			
		||||
                                   output->product,
 | 
			
		||||
@@ -161,59 +158,63 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
 | 
			
		||||
 | 
			
		||||
      wl_output_send_mode (resource,
 | 
			
		||||
                           mode_flags,
 | 
			
		||||
                           (int)output->crtc->current_mode->width,
 | 
			
		||||
                           (int)output->crtc->current_mode->height,
 | 
			
		||||
                           (int)output->crtc->current_mode->refresh_rate);
 | 
			
		||||
                           (int)monitor_info->rect.width,
 | 
			
		||||
                           (int)monitor_info->rect.height,
 | 
			
		||||
                           (int)monitor_info->refresh_rate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* It's very important that we change the output pointer here, as
 | 
			
		||||
     the old structure is about to be freed by MetaMonitorManager */
 | 
			
		||||
  wayland_output->output = output;
 | 
			
		||||
  wayland_output->x = output->crtc->rect.x;
 | 
			
		||||
  wayland_output->y = output->crtc->rect.y;
 | 
			
		||||
  wayland_output->monitor_info = monitor_info;
 | 
			
		||||
  wayland_output->x = monitor_info->rect.x;
 | 
			
		||||
  wayland_output->y = monitor_info->rect.y;
 | 
			
		||||
  wayland_output->transform = wl_transform;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MetaWaylandOutput *
 | 
			
		||||
meta_wayland_output_new (MetaWaylandCompositor *compositor)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandOutput *wayland_output;
 | 
			
		||||
 | 
			
		||||
  wayland_output = g_object_new (META_TYPE_WAYLAND_OUTPUT, NULL);
 | 
			
		||||
  wayland_output->global = wl_global_create (compositor->wayland_display,
 | 
			
		||||
                                             &wl_output_interface,
 | 
			
		||||
                                             META_WL_OUTPUT_VERSION,
 | 
			
		||||
                                             wayland_output, bind_output);
 | 
			
		||||
 | 
			
		||||
  return wayland_output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GHashTable *
 | 
			
		||||
meta_wayland_compositor_update_outputs (MetaWaylandCompositor *compositor,
 | 
			
		||||
                                        MetaMonitorManager    *monitors)
 | 
			
		||||
{
 | 
			
		||||
  MetaOutput *outputs;
 | 
			
		||||
  unsigned int i, n_outputs;
 | 
			
		||||
  unsigned int i;
 | 
			
		||||
  GHashTable *new_table;
 | 
			
		||||
  MetaMonitorInfo *monitor_infos;
 | 
			
		||||
  unsigned int n_monitor_infos;
 | 
			
		||||
 | 
			
		||||
  outputs = meta_monitor_manager_get_outputs (monitors, &n_outputs);
 | 
			
		||||
  monitor_infos = meta_monitor_manager_get_monitor_infos (monitors, &n_monitor_infos);
 | 
			
		||||
  new_table = g_hash_table_new_full (NULL, NULL, NULL, wayland_output_destroy_notify);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_outputs; i++)
 | 
			
		||||
  for (i = 0; i < n_monitor_infos; i++)
 | 
			
		||||
    {
 | 
			
		||||
      MetaOutput *output = &outputs[i];
 | 
			
		||||
      MetaMonitorInfo *info = &monitor_infos[i];
 | 
			
		||||
      MetaWaylandOutput *wayland_output;
 | 
			
		||||
 | 
			
		||||
      /* wayland does not expose disabled outputs */
 | 
			
		||||
      if (output->crtc == NULL)
 | 
			
		||||
        {
 | 
			
		||||
          g_hash_table_remove (compositor->outputs, GSIZE_TO_POINTER (output->winsys_id));
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      wayland_output = g_hash_table_lookup (compositor->outputs, GSIZE_TO_POINTER (output->winsys_id));
 | 
			
		||||
      if (info->winsys_id == 0)
 | 
			
		||||
        continue;
 | 
			
		||||
      wayland_output = g_hash_table_lookup (compositor->outputs, GSIZE_TO_POINTER (info->winsys_id));
 | 
			
		||||
 | 
			
		||||
      if (wayland_output)
 | 
			
		||||
        {
 | 
			
		||||
          g_hash_table_steal (compositor->outputs, GSIZE_TO_POINTER (output->winsys_id));
 | 
			
		||||
          g_hash_table_steal (compositor->outputs, GSIZE_TO_POINTER (info->winsys_id));
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          wayland_output = g_slice_new0 (MetaWaylandOutput);
 | 
			
		||||
          wayland_output->global = wl_global_create (compositor->wayland_display,
 | 
			
		||||
                                                     &wl_output_interface,
 | 
			
		||||
						     META_WL_OUTPUT_VERSION,
 | 
			
		||||
                                                     wayland_output, bind_output);
 | 
			
		||||
        }
 | 
			
		||||
        wayland_output = meta_wayland_output_new (compositor);
 | 
			
		||||
 | 
			
		||||
      wayland_output_update_for_output (wayland_output, output);
 | 
			
		||||
      g_hash_table_insert (new_table, GSIZE_TO_POINTER (output->winsys_id), wayland_output);
 | 
			
		||||
      wayland_output_update_for_output (wayland_output, info);
 | 
			
		||||
      g_hash_table_insert (new_table, GSIZE_TO_POINTER (info->winsys_id), wayland_output);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_hash_table_destroy (compositor->outputs);
 | 
			
		||||
@@ -227,6 +228,49 @@ on_monitors_changed (MetaMonitorManager    *monitors,
 | 
			
		||||
  compositor->outputs = meta_wayland_compositor_update_outputs (compositor, monitors);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_output_init (MetaWaylandOutput *wayland_output)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_output_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandOutput *wayland_output = META_WAYLAND_OUTPUT (object);
 | 
			
		||||
  GList *l;
 | 
			
		||||
 | 
			
		||||
  wl_global_destroy (wayland_output->global);
 | 
			
		||||
 | 
			
		||||
  /* Make sure the wl_output destructor doesn't try to access MetaWaylandOutput
 | 
			
		||||
   * after we have freed it.
 | 
			
		||||
   */
 | 
			
		||||
  for (l = wayland_output->resources; l; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      struct wl_resource *output_resource = l->data;
 | 
			
		||||
 | 
			
		||||
      wl_resource_set_user_data (output_resource, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_list_free (wayland_output->resources);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (meta_wayland_output_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_wayland_output_class_init (MetaWaylandOutputClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize = meta_wayland_output_finalize;
 | 
			
		||||
 | 
			
		||||
  signals[OUTPUT_DESTROYED] = g_signal_new ("output-destroyed",
 | 
			
		||||
                                            G_TYPE_FROM_CLASS (object_class),
 | 
			
		||||
                                            G_SIGNAL_RUN_LAST,
 | 
			
		||||
                                            0,
 | 
			
		||||
                                            NULL, NULL, NULL,
 | 
			
		||||
                                            G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_outputs_init (MetaWaylandCompositor *compositor)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -25,8 +25,37 @@
 | 
			
		||||
#ifndef META_WAYLAND_OUTPUTS_H
 | 
			
		||||
#define META_WAYLAND_OUTPUTS_H
 | 
			
		||||
 | 
			
		||||
#include "backends/meta-monitor-manager-private.h"
 | 
			
		||||
#include "meta-wayland-private.h"
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_WAYLAND_OUTPUT            (meta_wayland_output_get_type ())
 | 
			
		||||
#define META_WAYLAND_OUTPUT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_WAYLAND_OUTPUT, MetaWaylandOutput))
 | 
			
		||||
#define META_WAYLAND_OUTPUT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass),  META_TYPE_WAYLAND_OUTPUT, MetaWaylandOutputClass))
 | 
			
		||||
#define META_IS_WAYLAND_OUTPUT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_WAYLAND_OUTPUT))
 | 
			
		||||
#define META_IS_WAYLAND_OUTPUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  META_TYPE_WAYLAND_OUTPUT))
 | 
			
		||||
#define META_WAYLAND_OUTPUT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  META_TYPE_WAYLAND_OUTPUT, MetaWaylandOutputClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandOutputClass  MetaWaylandOutputClass;
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandOutput
 | 
			
		||||
{
 | 
			
		||||
  GObject                   parent;
 | 
			
		||||
 | 
			
		||||
  MetaMonitorInfo          *monitor_info;
 | 
			
		||||
  struct wl_global         *global;
 | 
			
		||||
  int                       x, y;
 | 
			
		||||
  enum wl_output_transform  transform;
 | 
			
		||||
 | 
			
		||||
  GList                    *resources;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandOutputClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType meta_wayland_output_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
void meta_wayland_outputs_init (MetaWaylandCompositor *compositor);
 | 
			
		||||
 | 
			
		||||
#endif /* META_WAYLAND_OUTPUTS_H */
 | 
			
		||||
 
 | 
			
		||||
@@ -339,8 +339,6 @@ handle_button_event (MetaWaylandPointer *pointer,
 | 
			
		||||
{
 | 
			
		||||
  gboolean implicit_grab;
 | 
			
		||||
 | 
			
		||||
  notify_motion (pointer, event);
 | 
			
		||||
 | 
			
		||||
  implicit_grab = (event->type == CLUTTER_BUTTON_PRESS) && (pointer->button_count == 1);
 | 
			
		||||
  if (implicit_grab)
 | 
			
		||||
    {
 | 
			
		||||
@@ -363,8 +361,6 @@ handle_scroll_event (MetaWaylandPointer *pointer,
 | 
			
		||||
  struct wl_list *l;
 | 
			
		||||
  wl_fixed_t x_value = 0, y_value = 0;
 | 
			
		||||
 | 
			
		||||
  notify_motion (pointer, event);
 | 
			
		||||
 | 
			
		||||
  if (clutter_event_is_pointer_emulated (event))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,8 @@
 | 
			
		||||
#include "meta-wayland-surface.h"
 | 
			
		||||
#include "meta-wayland-seat.h"
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaXWaylandSelection MetaXWaylandSelection;
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  struct wl_list link;
 | 
			
		||||
@@ -52,6 +54,8 @@ typedef struct
 | 
			
		||||
  char *display_name;
 | 
			
		||||
 | 
			
		||||
  GMainLoop *init_loop;
 | 
			
		||||
 | 
			
		||||
  MetaXWaylandSelection *selection_data;
 | 
			
		||||
} MetaXWaylandManager;
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandCompositor
 | 
			
		||||
 
 | 
			
		||||
@@ -42,6 +42,7 @@
 | 
			
		||||
#include "meta-wayland-pointer.h"
 | 
			
		||||
#include "meta-wayland-popup.h"
 | 
			
		||||
#include "meta-wayland-data-device.h"
 | 
			
		||||
#include "meta-wayland-outputs.h"
 | 
			
		||||
 | 
			
		||||
#include "meta-cursor-tracker-private.h"
 | 
			
		||||
#include "display-private.h"
 | 
			
		||||
@@ -52,6 +53,7 @@
 | 
			
		||||
 | 
			
		||||
#include "meta-surface-actor.h"
 | 
			
		||||
#include "meta-surface-actor-wayland.h"
 | 
			
		||||
#include "meta-xwayland-private.h"
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
@@ -186,32 +188,35 @@ calculate_surface_window_geometry (MetaWaylandSurface *surface,
 | 
			
		||||
                                   float               parent_x,
 | 
			
		||||
                                   float               parent_y)
 | 
			
		||||
{
 | 
			
		||||
  ClutterActor *surface_actor = CLUTTER_ACTOR (surface->surface_actor);
 | 
			
		||||
  MetaSurfaceActorWayland *surface_actor =
 | 
			
		||||
    META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
 | 
			
		||||
  MetaRectangle subsurface_rect;
 | 
			
		||||
  MetaRectangle geom;
 | 
			
		||||
  float x, y;
 | 
			
		||||
  GList *l;
 | 
			
		||||
 | 
			
		||||
  /* Unmapped surfaces don't count. */
 | 
			
		||||
  if (!CLUTTER_ACTOR_IS_VISIBLE (surface_actor))
 | 
			
		||||
  if (!CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (surface_actor)))
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if (!surface->buffer)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* XXX: Is there a better way to do this using Clutter APIs? */
 | 
			
		||||
  clutter_actor_get_position (surface_actor, &x, &y);
 | 
			
		||||
  meta_surface_actor_wayland_get_subsurface_rect (surface_actor,
 | 
			
		||||
                                                  &subsurface_rect);
 | 
			
		||||
 | 
			
		||||
  geom.x = parent_x + x;
 | 
			
		||||
  geom.y = parent_x + y;
 | 
			
		||||
  geom.width = cogl_texture_get_width (surface->buffer->texture);
 | 
			
		||||
  geom.height = cogl_texture_get_height (surface->buffer->texture);
 | 
			
		||||
  geom.x = parent_x + subsurface_rect.x;
 | 
			
		||||
  geom.y = parent_x + subsurface_rect.y;
 | 
			
		||||
  geom.width = subsurface_rect.width;
 | 
			
		||||
  geom.height = subsurface_rect.height;
 | 
			
		||||
 | 
			
		||||
  meta_rectangle_union (total_geometry, &geom, total_geometry);
 | 
			
		||||
 | 
			
		||||
  for (l = surface->subsurfaces; l != NULL; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      MetaWaylandSurface *subsurface = l->data;
 | 
			
		||||
      calculate_surface_window_geometry (subsurface, total_geometry, x, y);
 | 
			
		||||
      calculate_surface_window_geometry (subsurface, total_geometry,
 | 
			
		||||
                                         subsurface_rect.x,
 | 
			
		||||
                                         subsurface_rect.y);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -380,18 +385,13 @@ static void
 | 
			
		||||
subsurface_surface_commit (MetaWaylandSurface      *surface,
 | 
			
		||||
                           MetaWaylandPendingState *pending)
 | 
			
		||||
{
 | 
			
		||||
  MetaSurfaceActor *surface_actor = surface->surface_actor;
 | 
			
		||||
  float x, y;
 | 
			
		||||
  MetaSurfaceActorWayland *surface_actor =
 | 
			
		||||
    META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
 | 
			
		||||
 | 
			
		||||
  if (surface->buffer != NULL)
 | 
			
		||||
    clutter_actor_show (CLUTTER_ACTOR (surface_actor));
 | 
			
		||||
  else
 | 
			
		||||
    clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
 | 
			
		||||
 | 
			
		||||
  clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
 | 
			
		||||
  x += pending->dx;
 | 
			
		||||
  y += pending->dy;
 | 
			
		||||
  clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* A non-subsurface is always desynchronized.
 | 
			
		||||
@@ -425,20 +425,23 @@ parent_surface_state_applied (gpointer data, gpointer user_data)
 | 
			
		||||
 | 
			
		||||
  if (surface->sub.pending_pos)
 | 
			
		||||
    {
 | 
			
		||||
      clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor),
 | 
			
		||||
                                  surface->sub.pending_x,
 | 
			
		||||
                                  surface->sub.pending_y);
 | 
			
		||||
      surface->sub.x = surface->sub.pending_x;
 | 
			
		||||
      surface->sub.y = surface->sub.pending_y;
 | 
			
		||||
      surface->sub.pending_pos = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (surface->sub.pending_placement_ops)
 | 
			
		||||
    {
 | 
			
		||||
      GSList *it;
 | 
			
		||||
      MetaWaylandSurface *parent = surface->sub.parent;
 | 
			
		||||
      ClutterActor *parent_actor =
 | 
			
		||||
        clutter_actor_get_parent (CLUTTER_ACTOR (parent->surface_actor));
 | 
			
		||||
      ClutterActor *surface_actor =
 | 
			
		||||
        surface_actor = CLUTTER_ACTOR (surface->surface_actor);
 | 
			
		||||
 | 
			
		||||
      for (it = surface->sub.pending_placement_ops; it; it = it->next)
 | 
			
		||||
        {
 | 
			
		||||
          MetaWaylandSubsurfacePlacementOp *op = it->data;
 | 
			
		||||
          ClutterActor *surface_actor;
 | 
			
		||||
          ClutterActor *parent_actor;
 | 
			
		||||
          ClutterActor *sibling_actor;
 | 
			
		||||
 | 
			
		||||
          if (!op->sibling)
 | 
			
		||||
@@ -447,8 +450,6 @@ parent_surface_state_applied (gpointer data, gpointer user_data)
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          surface_actor = CLUTTER_ACTOR (surface->surface_actor);
 | 
			
		||||
          parent_actor = clutter_actor_get_parent (CLUTTER_ACTOR (surface->sub.parent));
 | 
			
		||||
          sibling_actor = CLUTTER_ACTOR (op->sibling->surface_actor);
 | 
			
		||||
 | 
			
		||||
          switch (op->placement)
 | 
			
		||||
@@ -475,6 +476,9 @@ parent_surface_state_applied (gpointer data, gpointer user_data)
 | 
			
		||||
 | 
			
		||||
  if (is_surface_effectively_synchronized (surface))
 | 
			
		||||
    apply_pending_state (surface, &surface->sub.pending);
 | 
			
		||||
 | 
			
		||||
  meta_surface_actor_wayland_sync_subsurface_state (
 | 
			
		||||
    META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -485,6 +489,9 @@ apply_pending_state (MetaWaylandSurface      *surface,
 | 
			
		||||
 | 
			
		||||
  if (pending->newly_attached)
 | 
			
		||||
    {
 | 
			
		||||
      if (!surface->buffer && surface->window)
 | 
			
		||||
        meta_window_queue (surface->window, META_QUEUE_CALC_SHOWING);
 | 
			
		||||
 | 
			
		||||
      surface_set_buffer (surface, pending->buffer);
 | 
			
		||||
 | 
			
		||||
      if (pending->buffer)
 | 
			
		||||
@@ -517,21 +524,32 @@ apply_pending_state (MetaWaylandSurface      *surface,
 | 
			
		||||
      surface->input_region = cairo_region_reference (pending->input_region);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_surface_actor_wayland_sync_state (
 | 
			
		||||
    META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
 | 
			
		||||
 | 
			
		||||
  /* wl_surface.frame */
 | 
			
		||||
  wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list);
 | 
			
		||||
  wl_list_init (&pending->frame_callback_list);
 | 
			
		||||
 | 
			
		||||
  if (surface == compositor->seat->pointer.cursor_surface)
 | 
			
		||||
    cursor_surface_commit (surface, pending);
 | 
			
		||||
  else if (meta_wayland_data_device_is_dnd_surface (&compositor->seat->data_device, surface))
 | 
			
		||||
    dnd_surface_commit (surface, pending);
 | 
			
		||||
  else if (surface->window)
 | 
			
		||||
    toplevel_surface_commit (surface, pending);
 | 
			
		||||
  else if (surface->wl_subsurface)
 | 
			
		||||
    subsurface_surface_commit (surface, pending);
 | 
			
		||||
  switch (surface->role)
 | 
			
		||||
    {
 | 
			
		||||
    case META_WAYLAND_SURFACE_ROLE_NONE:
 | 
			
		||||
      break;
 | 
			
		||||
    case META_WAYLAND_SURFACE_ROLE_CURSOR:
 | 
			
		||||
      cursor_surface_commit (surface, pending);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_WAYLAND_SURFACE_ROLE_DND:
 | 
			
		||||
      dnd_surface_commit (surface, pending);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_WAYLAND_SURFACE_ROLE_XDG_SURFACE:
 | 
			
		||||
    case META_WAYLAND_SURFACE_ROLE_XDG_POPUP:
 | 
			
		||||
    case META_WAYLAND_SURFACE_ROLE_WL_SHELL_SURFACE:
 | 
			
		||||
      toplevel_surface_commit (surface, pending);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_WAYLAND_SURFACE_ROLE_SUBSURFACE:
 | 
			
		||||
      subsurface_surface_commit (surface, pending);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_surface_actor_wayland_sync_state (
 | 
			
		||||
    META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
 | 
			
		||||
 | 
			
		||||
  pending_state_reset (pending);
 | 
			
		||||
 | 
			
		||||
@@ -748,12 +766,131 @@ sync_reactive (MetaWaylandSurface *surface)
 | 
			
		||||
                              surface_should_be_reactive (surface));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
sync_drag_dest_funcs (MetaWaylandSurface *surface)
 | 
			
		||||
{
 | 
			
		||||
  if (surface->window &&
 | 
			
		||||
      surface->window->client_type == META_WINDOW_CLIENT_TYPE_X11)
 | 
			
		||||
    surface->dnd.funcs = meta_xwayland_selection_get_drag_dest_funcs ();
 | 
			
		||||
  else
 | 
			
		||||
    surface->dnd.funcs = meta_wayland_data_device_get_drag_dest_funcs ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
surface_entered_output (MetaWaylandSurface *surface,
 | 
			
		||||
                        MetaWaylandOutput *wayland_output)
 | 
			
		||||
{
 | 
			
		||||
  GList *iter;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
 | 
			
		||||
  for (iter = wayland_output->resources; iter != NULL; iter = iter->next)
 | 
			
		||||
    {
 | 
			
		||||
      resource = iter->data;
 | 
			
		||||
 | 
			
		||||
      if (wl_resource_get_client (resource) !=
 | 
			
		||||
          wl_resource_get_client (surface->resource))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      wl_surface_send_enter (surface->resource, resource);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
surface_left_output (MetaWaylandSurface *surface,
 | 
			
		||||
                     MetaWaylandOutput *wayland_output)
 | 
			
		||||
{
 | 
			
		||||
  GList *iter;
 | 
			
		||||
  struct wl_resource *resource;
 | 
			
		||||
 | 
			
		||||
  for (iter = wayland_output->resources; iter != NULL; iter = iter->next)
 | 
			
		||||
    {
 | 
			
		||||
      resource = iter->data;
 | 
			
		||||
 | 
			
		||||
      if (wl_resource_get_client (resource) !=
 | 
			
		||||
          wl_resource_get_client (surface->resource))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      wl_surface_send_leave (surface->resource, resource);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_surface_is_on_output (MetaWaylandSurface *surface,
 | 
			
		||||
                          MetaWaylandOutput *wayland_output,
 | 
			
		||||
                          gboolean is_on_output);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
surface_handle_output_destroy (MetaWaylandOutput *wayland_output,
 | 
			
		||||
                               GParamSpec *pspec,
 | 
			
		||||
                               MetaWaylandSurface *surface)
 | 
			
		||||
{
 | 
			
		||||
  set_surface_is_on_output (surface, wayland_output, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_surface_is_on_output (MetaWaylandSurface *surface,
 | 
			
		||||
                          MetaWaylandOutput *wayland_output,
 | 
			
		||||
                          gboolean is_on_output)
 | 
			
		||||
{
 | 
			
		||||
  gboolean was_on_output = g_hash_table_contains (surface->outputs,
 | 
			
		||||
                                                  wayland_output);
 | 
			
		||||
 | 
			
		||||
  if (!was_on_output && is_on_output)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_connect (wayland_output, "output-destroyed",
 | 
			
		||||
                        G_CALLBACK (surface_handle_output_destroy),
 | 
			
		||||
                        surface);
 | 
			
		||||
      g_hash_table_add (surface->outputs, wayland_output);
 | 
			
		||||
      surface_entered_output (surface, wayland_output);
 | 
			
		||||
    }
 | 
			
		||||
  else if (was_on_output && !is_on_output)
 | 
			
		||||
    {
 | 
			
		||||
      g_hash_table_remove (surface->outputs, wayland_output);
 | 
			
		||||
      g_signal_handlers_disconnect_by_func  (
 | 
			
		||||
        wayland_output, (gpointer)surface_handle_output_destroy, surface);
 | 
			
		||||
      surface_left_output (surface, wayland_output);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_surface_output_state (gpointer key, gpointer value, gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandOutput *wayland_output = value;
 | 
			
		||||
  MetaWaylandSurface *surface = user_data;
 | 
			
		||||
  MetaSurfaceActorWayland *actor =
 | 
			
		||||
    META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
 | 
			
		||||
  MetaMonitorInfo *monitor;
 | 
			
		||||
  gboolean is_on_output;
 | 
			
		||||
 | 
			
		||||
  monitor = wayland_output->monitor_info;
 | 
			
		||||
  if (!monitor)
 | 
			
		||||
    {
 | 
			
		||||
      set_surface_is_on_output (surface, wayland_output, FALSE);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  is_on_output = meta_surface_actor_wayland_is_on_monitor (actor, monitor);
 | 
			
		||||
  set_surface_is_on_output (surface, wayland_output, is_on_output);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_surface_update_outputs (MetaWaylandSurface *surface)
 | 
			
		||||
{
 | 
			
		||||
  if (!surface->compositor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_hash_table_foreach (surface->compositor->outputs,
 | 
			
		||||
                        update_surface_output_state,
 | 
			
		||||
                        surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_surface_set_window (MetaWaylandSurface *surface,
 | 
			
		||||
                                 MetaWindow         *window)
 | 
			
		||||
{
 | 
			
		||||
  surface->window = window;
 | 
			
		||||
  sync_reactive (surface);
 | 
			
		||||
  sync_drag_dest_funcs (surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -776,10 +913,15 @@ wl_surface_destructor (struct wl_resource *resource)
 | 
			
		||||
  if (surface->input_region)
 | 
			
		||||
    cairo_region_destroy (surface->input_region);
 | 
			
		||||
 | 
			
		||||
  meta_surface_actor_wayland_surface_destroyed (
 | 
			
		||||
    META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
 | 
			
		||||
 | 
			
		||||
  g_object_unref (surface->surface_actor);
 | 
			
		||||
 | 
			
		||||
  meta_wayland_compositor_destroy_frame_callbacks (compositor, surface);
 | 
			
		||||
 | 
			
		||||
  g_hash_table_unref (surface->outputs);
 | 
			
		||||
 | 
			
		||||
  if (surface->resource)
 | 
			
		||||
    wl_resource_set_user_data (surface->resource, NULL);
 | 
			
		||||
 | 
			
		||||
@@ -816,6 +958,10 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
 | 
			
		||||
  surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy;
 | 
			
		||||
  surface->surface_actor = g_object_ref_sink (meta_surface_actor_wayland_new (surface));
 | 
			
		||||
 | 
			
		||||
  sync_drag_dest_funcs (surface);
 | 
			
		||||
 | 
			
		||||
  surface->outputs = g_hash_table_new (NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  pending_state_init (&surface->pending);
 | 
			
		||||
  return surface;
 | 
			
		||||
}
 | 
			
		||||
@@ -1258,11 +1404,8 @@ xdg_shell_get_xdg_popup (struct wl_client *client,
 | 
			
		||||
                                    &surface->popup.parent_destroy_listener);
 | 
			
		||||
 | 
			
		||||
  window = meta_window_wayland_new (display, surface);
 | 
			
		||||
  meta_window_move_frame (window, FALSE,
 | 
			
		||||
                          parent_surf->window->rect.x + x,
 | 
			
		||||
                          parent_surf->window->rect.y + y);
 | 
			
		||||
  meta_window_wayland_place_relative_to (window, parent_surf->window, x, y);
 | 
			
		||||
  window->showing_for_first_time = FALSE;
 | 
			
		||||
  window->placed = TRUE;
 | 
			
		||||
 | 
			
		||||
  meta_wayland_surface_set_window (surface, window);
 | 
			
		||||
 | 
			
		||||
@@ -1426,10 +1569,9 @@ wl_shell_surface_set_transient (struct wl_client *client,
 | 
			
		||||
  wl_shell_surface_set_state (surface, SURFACE_STATE_TOPLEVEL);
 | 
			
		||||
 | 
			
		||||
  meta_window_set_transient_for (surface->window, parent_surf->window);
 | 
			
		||||
  meta_window_move_frame (surface->window, FALSE,
 | 
			
		||||
                          parent_surf->window->rect.x + x,
 | 
			
		||||
                          parent_surf->window->rect.y + y);
 | 
			
		||||
  surface->window->placed = TRUE;
 | 
			
		||||
  meta_window_wayland_place_relative_to (surface->window,
 | 
			
		||||
                                         parent_surf->window,
 | 
			
		||||
                                         x, y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -1444,6 +1586,17 @@ wl_shell_surface_set_fullscreen (struct wl_client *client,
 | 
			
		||||
  wl_shell_surface_set_state (surface, SURFACE_STATE_FULLSCREEN);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
handle_wl_shell_popup_parent_destroyed (struct wl_listener *listener,
 | 
			
		||||
                                        void *data)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSurface *surface =
 | 
			
		||||
    wl_container_of (listener, surface, popup.parent_destroy_listener);
 | 
			
		||||
 | 
			
		||||
  wl_list_remove (&surface->popup.parent_destroy_listener.link);
 | 
			
		||||
  surface->popup.parent = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
wl_shell_surface_set_popup (struct wl_client *client,
 | 
			
		||||
                            struct wl_resource *resource,
 | 
			
		||||
@@ -1467,10 +1620,18 @@ wl_shell_surface_set_popup (struct wl_client *client,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_window_set_transient_for (surface->window, parent_surf->window);
 | 
			
		||||
  meta_window_move_frame (surface->window, FALSE,
 | 
			
		||||
                          parent_surf->window->rect.x + x,
 | 
			
		||||
                          parent_surf->window->rect.y + y);
 | 
			
		||||
  surface->window->placed = TRUE;
 | 
			
		||||
  meta_window_wayland_place_relative_to (surface->window,
 | 
			
		||||
                                         parent_surf->window,
 | 
			
		||||
                                         x, y);
 | 
			
		||||
 | 
			
		||||
  if (!surface->popup.parent)
 | 
			
		||||
    {
 | 
			
		||||
      surface->popup.parent = parent_surf;
 | 
			
		||||
      surface->popup.parent_destroy_listener.notify =
 | 
			
		||||
        handle_wl_shell_popup_parent_destroyed;
 | 
			
		||||
      wl_resource_add_destroy_listener (parent_surf->resource,
 | 
			
		||||
                                        &surface->popup.parent_destroy_listener);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_wayland_pointer_start_popup_grab (&seat->pointer, surface);
 | 
			
		||||
}
 | 
			
		||||
@@ -1525,6 +1686,7 @@ wl_shell_get_shell_surface (struct wl_client *client,
 | 
			
		||||
                            struct wl_resource *surface_resource)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
 | 
			
		||||
  MetaWindow *window;
 | 
			
		||||
 | 
			
		||||
  if (surface->wl_shell_surface != NULL)
 | 
			
		||||
    {
 | 
			
		||||
@@ -1542,6 +1704,9 @@ wl_shell_get_shell_surface (struct wl_client *client,
 | 
			
		||||
 | 
			
		||||
  surface->wl_shell_surface = wl_resource_create (client, &wl_shell_surface_interface, wl_resource_get_version (resource), id);
 | 
			
		||||
  wl_resource_set_implementation (surface->wl_shell_surface, &meta_wayland_wl_shell_surface_interface, surface, wl_shell_surface_destructor);
 | 
			
		||||
 | 
			
		||||
  window = meta_window_wayland_new (meta_get_display (), surface);
 | 
			
		||||
  meta_wayland_surface_set_window (surface, window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct wl_shell_interface meta_wayland_wl_shell_interface = {
 | 
			
		||||
@@ -1990,12 +2155,6 @@ meta_wayland_surface_configure_notify (MetaWaylandSurface *surface,
 | 
			
		||||
      wl_array_init (&states);
 | 
			
		||||
      fill_states (&states, surface->window);
 | 
			
		||||
 | 
			
		||||
      /* new_width and new_height comes from window->rect, which is based on
 | 
			
		||||
       * the buffer size, not the surface size. The configure event requires
 | 
			
		||||
       * surface size. */
 | 
			
		||||
      new_width /= surface->scale;
 | 
			
		||||
      new_height /= surface->scale;
 | 
			
		||||
 | 
			
		||||
      xdg_surface_send_configure (surface->xdg_surface, new_width, new_height, &states, serial);
 | 
			
		||||
 | 
			
		||||
      wl_array_release (&states);
 | 
			
		||||
@@ -2043,3 +2202,60 @@ meta_wayland_surface_popup_done (MetaWaylandSurface *surface)
 | 
			
		||||
  else if (surface->wl_shell_surface)
 | 
			
		||||
    wl_shell_surface_send_popup_done (surface->wl_shell_surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_surface_drag_dest_focus_in (MetaWaylandSurface   *surface,
 | 
			
		||||
                                         MetaWaylandDataOffer *offer)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
 | 
			
		||||
  MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
 | 
			
		||||
 | 
			
		||||
  surface->dnd.funcs->focus_in (data_device, surface, offer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_surface_drag_dest_motion (MetaWaylandSurface *surface,
 | 
			
		||||
                                       const ClutterEvent *event)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
 | 
			
		||||
  MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
 | 
			
		||||
 | 
			
		||||
  surface->dnd.funcs->motion (data_device, surface, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_surface_drag_dest_focus_out (MetaWaylandSurface *surface)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
 | 
			
		||||
  MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
 | 
			
		||||
 | 
			
		||||
  surface->dnd.funcs->focus_out (data_device, surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_wayland_surface_drag_dest_drop (MetaWaylandSurface *surface)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
 | 
			
		||||
  MetaWaylandDataDevice *data_device = &compositor->seat->data_device;
 | 
			
		||||
 | 
			
		||||
  surface->dnd.funcs->drop (data_device, surface);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MetaWindow *
 | 
			
		||||
meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface)
 | 
			
		||||
{
 | 
			
		||||
  while (surface)
 | 
			
		||||
    {
 | 
			
		||||
      if (surface->window)
 | 
			
		||||
        {
 | 
			
		||||
          if (surface->popup.parent)
 | 
			
		||||
            surface = surface->popup.parent;
 | 
			
		||||
          else
 | 
			
		||||
            return surface->window;
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        surface = surface->sub.parent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -71,6 +71,20 @@ typedef struct
 | 
			
		||||
  gboolean has_new_geometry;
 | 
			
		||||
} MetaWaylandPendingState;
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandDragDestFuncs
 | 
			
		||||
{
 | 
			
		||||
  void (* focus_in)  (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                      MetaWaylandSurface    *surface,
 | 
			
		||||
                      MetaWaylandDataOffer  *offer);
 | 
			
		||||
  void (* focus_out) (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                      MetaWaylandSurface    *surface);
 | 
			
		||||
  void (* motion)    (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                      MetaWaylandSurface    *surface,
 | 
			
		||||
                      const ClutterEvent    *event);
 | 
			
		||||
  void (* drop)      (MetaWaylandDataDevice *data_device,
 | 
			
		||||
                      MetaWaylandSurface    *surface);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _MetaWaylandSurface
 | 
			
		||||
{
 | 
			
		||||
  /* Generic stuff */
 | 
			
		||||
@@ -86,6 +100,11 @@ struct _MetaWaylandSurface
 | 
			
		||||
  int scale;
 | 
			
		||||
  int32_t offset_x, offset_y;
 | 
			
		||||
  GList *subsurfaces;
 | 
			
		||||
  GHashTable *outputs;
 | 
			
		||||
 | 
			
		||||
  struct {
 | 
			
		||||
    const MetaWaylandDragDestFuncs *funcs;
 | 
			
		||||
  } dnd;
 | 
			
		||||
 | 
			
		||||
  /* All the pending state that wl_surface.commit will apply. */
 | 
			
		||||
  MetaWaylandPendingState pending;
 | 
			
		||||
@@ -117,6 +136,9 @@ struct _MetaWaylandSurface
 | 
			
		||||
    MetaWaylandSurface *parent;
 | 
			
		||||
    struct wl_listener parent_destroy_listener;
 | 
			
		||||
 | 
			
		||||
    int x;
 | 
			
		||||
    int y;
 | 
			
		||||
 | 
			
		||||
    /* When the surface is synchronous, its state will be applied
 | 
			
		||||
     * when the parent is committed. This is done by moving the
 | 
			
		||||
     * "real" pending state below to here when this surface is
 | 
			
		||||
@@ -161,4 +183,16 @@ void                meta_wayland_surface_delete (MetaWaylandSurface *surface);
 | 
			
		||||
 | 
			
		||||
void                meta_wayland_surface_popup_done (MetaWaylandSurface *surface);
 | 
			
		||||
 | 
			
		||||
/* Drag dest functions */
 | 
			
		||||
void                meta_wayland_surface_drag_dest_focus_in  (MetaWaylandSurface   *surface,
 | 
			
		||||
                                                              MetaWaylandDataOffer *offer);
 | 
			
		||||
void                meta_wayland_surface_drag_dest_motion    (MetaWaylandSurface   *surface,
 | 
			
		||||
                                                              const ClutterEvent   *event);
 | 
			
		||||
void                meta_wayland_surface_drag_dest_focus_out (MetaWaylandSurface   *surface);
 | 
			
		||||
void                meta_wayland_surface_drag_dest_drop      (MetaWaylandSurface   *surface);
 | 
			
		||||
 | 
			
		||||
void                meta_wayland_surface_update_outputs (MetaWaylandSurface *surface);
 | 
			
		||||
 | 
			
		||||
MetaWindow *        meta_wayland_surface_get_toplevel_window (MetaWaylandSurface *surface);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,8 @@ typedef struct _MetaWaylandPopupGrab MetaWaylandPopupGrab;
 | 
			
		||||
typedef struct _MetaWaylandPopup MetaWaylandPopup;
 | 
			
		||||
typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard;
 | 
			
		||||
typedef struct _MetaWaylandTouch MetaWaylandTouch;
 | 
			
		||||
typedef struct _MetaWaylandDataSource MetaWaylandDataSource;
 | 
			
		||||
typedef struct _MetaWaylandDragDestFuncs MetaWaylandDragDestFuncs;
 | 
			
		||||
typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer;
 | 
			
		||||
typedef struct _MetaWaylandDataDevice MetaWaylandDataDevice;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandBuffer MetaWaylandBuffer;
 | 
			
		||||
@@ -38,6 +39,8 @@ typedef struct _MetaWaylandRegion MetaWaylandRegion;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandSurface MetaWaylandSurface;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandOutput MetaWaylandOutput;
 | 
			
		||||
 | 
			
		||||
typedef struct _MetaWaylandSerial MetaWaylandSerial;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -166,9 +166,20 @@ meta_window_wayland_move_resize_internal (MetaWindow                *window,
 | 
			
		||||
{
 | 
			
		||||
  MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
 | 
			
		||||
  gboolean can_move_now;
 | 
			
		||||
  int configured_width;
 | 
			
		||||
  int configured_height;
 | 
			
		||||
  int monitor_scale;
 | 
			
		||||
 | 
			
		||||
  g_assert (window->frame == NULL);
 | 
			
		||||
 | 
			
		||||
  /* The scale the window is drawn in might change depending on what monitor it
 | 
			
		||||
   * is mainly on. Scale the configured rectangle to be in logical pixel
 | 
			
		||||
   * coordinate space so that we can have a scale independent size to pass
 | 
			
		||||
   * to the Wayland surface. */
 | 
			
		||||
  monitor_scale = meta_window_wayland_get_main_monitor_scale (window);
 | 
			
		||||
  configured_width = constrained_rect.width / monitor_scale;
 | 
			
		||||
  configured_height = constrained_rect.height / monitor_scale;
 | 
			
		||||
 | 
			
		||||
  /* For wayland clients, the size is completely determined by the client,
 | 
			
		||||
   * and while this allows to avoid some trickery with frames and the resulting
 | 
			
		||||
   * lagging, we also need to insist a bit when the constraints would apply
 | 
			
		||||
@@ -223,8 +234,8 @@ meta_window_wayland_move_resize_internal (MetaWindow                *window,
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
          meta_wayland_surface_configure_notify (window->surface,
 | 
			
		||||
                                                 constrained_rect.width,
 | 
			
		||||
                                                 constrained_rect.height,
 | 
			
		||||
                                                 configured_width,
 | 
			
		||||
                                                 configured_height,
 | 
			
		||||
                                                 &wl_window->pending_configure_serial);
 | 
			
		||||
 | 
			
		||||
          /* We need to wait until the resize completes before we can move */
 | 
			
		||||
@@ -238,8 +249,8 @@ meta_window_wayland_move_resize_internal (MetaWindow                *window,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  wl_window->last_sent_width = constrained_rect.width;
 | 
			
		||||
  wl_window->last_sent_height = constrained_rect.height;
 | 
			
		||||
  wl_window->last_sent_width = configured_width;
 | 
			
		||||
  wl_window->last_sent_height = configured_height;
 | 
			
		||||
 | 
			
		||||
  if (can_move_now)
 | 
			
		||||
    {
 | 
			
		||||
@@ -277,12 +288,101 @@ meta_window_wayland_move_resize_internal (MetaWindow                *window,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
scale_rect_size (MetaRectangle *rect, float scale)
 | 
			
		||||
{
 | 
			
		||||
  rect->width = (int)(rect->width * scale);
 | 
			
		||||
  rect->height = (int)(rect->height * scale);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_wayland_update_main_monitor (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  const MetaMonitorInfo *from;
 | 
			
		||||
  const MetaMonitorInfo *to;
 | 
			
		||||
  const MetaMonitorInfo *scaled_new;
 | 
			
		||||
  float scale;
 | 
			
		||||
  MetaRectangle rect;
 | 
			
		||||
 | 
			
		||||
  /* Require both the current and the new monitor would be the new main monitor,
 | 
			
		||||
   * even given the resulting scale the window would end up having. This is
 | 
			
		||||
   * needed to avoid jumping back and forth between the new and the old, since
 | 
			
		||||
   * changing main monitor may cause the window to be resized so that it no
 | 
			
		||||
   * longer have that same new main monitor. */
 | 
			
		||||
  from = window->monitor;
 | 
			
		||||
  to = meta_screen_calculate_monitor_for_window (window->screen, window);
 | 
			
		||||
 | 
			
		||||
  if (from == to)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* If we are setting the first output, unsetting the output, or the new has
 | 
			
		||||
   * the same scale as the old no need to do any further checking. */
 | 
			
		||||
  if (from == NULL || to == NULL || from->scale == to->scale)
 | 
			
		||||
    {
 | 
			
		||||
      window->monitor = to;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* To avoid a window alternating between two main monitors because scaling
 | 
			
		||||
   * changes the main monitor, wait until both the current and the new scale
 | 
			
		||||
   * will result in the same main monitor. */
 | 
			
		||||
  scale = (float)to->scale / from->scale;
 | 
			
		||||
  rect = window->rect;
 | 
			
		||||
  scale_rect_size (&rect, scale);
 | 
			
		||||
  scaled_new = meta_screen_get_monitor_for_rect (window->screen, &rect);
 | 
			
		||||
  if (to != scaled_new)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  window->monitor = to;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_wayland_main_monitor_changed (MetaWindow *window,
 | 
			
		||||
                                          const MetaMonitorInfo *old)
 | 
			
		||||
{
 | 
			
		||||
  MetaWaylandSurface *surface = window->surface;
 | 
			
		||||
  float scale_factor;
 | 
			
		||||
  MetaWaylandSurface *surface;
 | 
			
		||||
 | 
			
		||||
  /* This function makes sure that window geometry, window actor geometry and
 | 
			
		||||
   * surface actor geometry gets set according the old and current main monitor
 | 
			
		||||
   * scale. If there either is no past or current main monitor, or if the scale
 | 
			
		||||
   * didn't change, there is nothing to do. */
 | 
			
		||||
  if (old == NULL ||
 | 
			
		||||
      window->monitor == NULL ||
 | 
			
		||||
      old->scale == window->monitor->scale)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* MetaWindow keeps its rectangles in the physical pixel coordinate space.
 | 
			
		||||
   * When the main monitor of a window changes, it can cause the corresponding
 | 
			
		||||
   * window surfaces to be scaled given the monitor scale, so we need to scale
 | 
			
		||||
   * the rectangles in MetaWindow accordingly. */
 | 
			
		||||
 | 
			
		||||
  scale_factor = (float)window->monitor->scale / old->scale;
 | 
			
		||||
 | 
			
		||||
  /* Window size. */
 | 
			
		||||
  scale_rect_size (&window->rect, scale_factor);
 | 
			
		||||
 | 
			
		||||
  /* Window geometry offset (XXX: Need a better place, see
 | 
			
		||||
   * meta_window_wayland_move_resize). */
 | 
			
		||||
  window->custom_frame_extents.left =
 | 
			
		||||
    (int)(scale_factor * window->custom_frame_extents.left);
 | 
			
		||||
  window->custom_frame_extents.top =
 | 
			
		||||
    (int)(scale_factor * window->custom_frame_extents.top);
 | 
			
		||||
 | 
			
		||||
  /* Buffer rect. */
 | 
			
		||||
  scale_rect_size (&window->buffer_rect, scale_factor);
 | 
			
		||||
  window->buffer_rect.x =
 | 
			
		||||
    window->rect.x - window->custom_frame_extents.left;
 | 
			
		||||
  window->buffer_rect.y =
 | 
			
		||||
    window->rect.y - window->custom_frame_extents.top;
 | 
			
		||||
 | 
			
		||||
  meta_compositor_sync_window_geometry (window->display->compositor,
 | 
			
		||||
                                        window,
 | 
			
		||||
                                        TRUE);
 | 
			
		||||
 | 
			
		||||
  /* The surface actor needs to update the scale recursively for itself and all
 | 
			
		||||
   * its subsurfaces */
 | 
			
		||||
  surface = window->surface;
 | 
			
		||||
  if (surface)
 | 
			
		||||
    {
 | 
			
		||||
      MetaSurfaceActorWayland *actor =
 | 
			
		||||
@@ -290,6 +390,8 @@ meta_window_wayland_main_monitor_changed (MetaWindow *window,
 | 
			
		||||
 | 
			
		||||
      meta_surface_actor_wayland_sync_state_recursive (actor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  meta_window_emit_size_changed (window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -330,6 +432,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass)
 | 
			
		||||
  window_class->grab_op_began = meta_window_wayland_grab_op_began;
 | 
			
		||||
  window_class->grab_op_ended = meta_window_wayland_grab_op_ended;
 | 
			
		||||
  window_class->move_resize_internal = meta_window_wayland_move_resize_internal;
 | 
			
		||||
  window_class->update_main_monitor = meta_window_wayland_update_main_monitor;
 | 
			
		||||
  window_class->main_monitor_changed = meta_window_wayland_main_monitor_changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -412,6 +515,12 @@ should_do_pending_move (MetaWindowWayland *wl_window,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
meta_window_wayland_get_main_monitor_scale (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  return window->monitor->scale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * meta_window_move_resize_wayland:
 | 
			
		||||
 *
 | 
			
		||||
@@ -428,6 +537,22 @@ meta_window_wayland_move_resize (MetaWindow        *window,
 | 
			
		||||
  int gravity;
 | 
			
		||||
  MetaRectangle rect;
 | 
			
		||||
  MetaMoveResizeFlags flags;
 | 
			
		||||
  int monitor_scale;
 | 
			
		||||
 | 
			
		||||
  /* new_geom is in the logical pixel coordinate space, but MetaWindow wants its
 | 
			
		||||
   * rects to represent what in turn will end up on the stage, i.e. we need to
 | 
			
		||||
   * scale new_geom to physical pixels given what buffer scale and texture scale
 | 
			
		||||
   * is in use. */
 | 
			
		||||
  monitor_scale = meta_window_wayland_get_main_monitor_scale (window);
 | 
			
		||||
  new_geom.x *= monitor_scale;
 | 
			
		||||
  new_geom.y *= monitor_scale;
 | 
			
		||||
  new_geom.width *= monitor_scale;
 | 
			
		||||
  new_geom.height *= monitor_scale;
 | 
			
		||||
 | 
			
		||||
  /* The (dx, dy) offset is also in logical pixel coordinate space and needs
 | 
			
		||||
   * to be scaled in the same way as new_geom. */
 | 
			
		||||
  dx *= monitor_scale;
 | 
			
		||||
  dy *= monitor_scale;
 | 
			
		||||
 | 
			
		||||
  /* XXX: Find a better place to store the window geometry offsets. */
 | 
			
		||||
  window->custom_frame_extents.left = new_geom.x;
 | 
			
		||||
@@ -470,3 +595,24 @@ meta_window_wayland_move_resize (MetaWindow        *window,
 | 
			
		||||
  gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
 | 
			
		||||
  meta_window_move_resize_internal (window, flags, gravity, rect);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_window_wayland_place_relative_to (MetaWindow *window,
 | 
			
		||||
                                       MetaWindow *other,
 | 
			
		||||
                                       int         x,
 | 
			
		||||
                                       int         y)
 | 
			
		||||
{
 | 
			
		||||
  int monitor_scale;
 | 
			
		||||
 | 
			
		||||
  /* If there is no monitor, we can't position the window reliably. */
 | 
			
		||||
  if (!other->monitor)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  /* Scale the relative coordinate (x, y) from logical pixels to physical
 | 
			
		||||
   * pixels. */
 | 
			
		||||
  monitor_scale = other->monitor->scale;
 | 
			
		||||
  meta_window_move_frame (window, FALSE,
 | 
			
		||||
                          other->buffer_rect.x + (x * monitor_scale),
 | 
			
		||||
                          other->buffer_rect.y + (y * monitor_scale));
 | 
			
		||||
  window->placed = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -50,5 +50,11 @@ void meta_window_wayland_move_resize (MetaWindow        *window,
 | 
			
		||||
                                      MetaRectangle      new_geom,
 | 
			
		||||
                                      int                dx,
 | 
			
		||||
                                      int                dy);
 | 
			
		||||
int meta_window_wayland_get_main_monitor_scale (MetaWindow *window);
 | 
			
		||||
 | 
			
		||||
void meta_window_wayland_place_relative_to (MetaWindow *window,
 | 
			
		||||
                                            MetaWindow *other,
 | 
			
		||||
                                            int         x,
 | 
			
		||||
                                            int         y);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -34,4 +34,11 @@ meta_xwayland_complete_init (void);
 | 
			
		||||
void
 | 
			
		||||
meta_xwayland_stop (MetaXWaylandManager *manager);
 | 
			
		||||
 | 
			
		||||
/* wl_data_device/X11 selection interoperation */
 | 
			
		||||
void     meta_xwayland_init_selection         (void);
 | 
			
		||||
void     meta_xwayland_shutdown_selection     (void);
 | 
			
		||||
gboolean meta_xwayland_selection_handle_event (XEvent *xevent);
 | 
			
		||||
 | 
			
		||||
const MetaWaylandDragDestFuncs * meta_xwayland_selection_get_drag_dest_funcs (void);
 | 
			
		||||
 | 
			
		||||
#endif /* META_XWAYLAND_PRIVATE_H */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								src/wayland/meta-xwayland-selection-private.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/wayland/meta-xwayland-selection-private.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 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:
 | 
			
		||||
 *     Jonas Ådahl <jadahl@gmail.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef META_XWAYLAND_SELECTION_PRIVATE_H
 | 
			
		||||
#define META_XWAYLAND_SELECTION_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
#define META_TYPE_WAYLAND_DATA_SOURCE_XWAYLAND (meta_wayland_data_source_xwayland_get_type ())
 | 
			
		||||
G_DECLARE_FINAL_TYPE (MetaWaylandDataSourceXWayland,
 | 
			
		||||
                      meta_wayland_data_source_xwayland,
 | 
			
		||||
                      META, WAYLAND_DATA_SOURCE_XWAYLAND,
 | 
			
		||||
                      MetaWaylandDataSource);
 | 
			
		||||
 | 
			
		||||
#endif /* META_XWAYLAND_SELECTION_PRIVATE_H */
 | 
			
		||||
							
								
								
									
										1577
									
								
								src/wayland/meta-xwayland-selection.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1577
									
								
								src/wayland/meta-xwayland-selection.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -522,6 +522,8 @@ meta_xwayland_complete_init (void)
 | 
			
		||||
     we won't reset the tty).
 | 
			
		||||
  */
 | 
			
		||||
  XSetIOErrorHandler (x_io_error);
 | 
			
		||||
 | 
			
		||||
  meta_xwayland_init_selection ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -529,6 +531,8 @@ meta_xwayland_stop (MetaXWaylandManager *manager)
 | 
			
		||||
{
 | 
			
		||||
  char path[256];
 | 
			
		||||
 | 
			
		||||
  meta_xwayland_shutdown_selection ();
 | 
			
		||||
 | 
			
		||||
  snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index);
 | 
			
		||||
  unlink (path);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,680 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Asynchronous X property getting hack */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2002 Havoc Pennington
 | 
			
		||||
 * Copyright (C) 1986, 1998  The Open Group
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, distribute, and sell this software
 | 
			
		||||
 * and its documentation for any purpose is hereby granted without
 | 
			
		||||
 * fee, provided that the above copyright notice appear in all copies
 | 
			
		||||
 * and that both that copyright notice and this permission notice
 | 
			
		||||
 * appear in supporting documentation.
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be
 | 
			
		||||
 * included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
 | 
			
		||||
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 | 
			
		||||
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | 
			
		||||
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of The Open Group shall not be
 | 
			
		||||
 * used in advertising or otherwise to promote the sale, use or other dealings
 | 
			
		||||
 * in this Software without prior written authorization from The Open Group.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#undef DEBUG_SPEW
 | 
			
		||||
#ifdef DEBUG_SPEW
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "async-getprop.h"
 | 
			
		||||
 | 
			
		||||
#define NEED_REPLIES
 | 
			
		||||
#include <X11/Xlibint.h>
 | 
			
		||||
 | 
			
		||||
#ifndef NULL
 | 
			
		||||
#define NULL ((void*)0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct _ListNode ListNode;
 | 
			
		||||
typedef struct _AgPerDisplayData AgPerDisplayData;
 | 
			
		||||
 | 
			
		||||
struct _ListNode
 | 
			
		||||
{
 | 
			
		||||
  ListNode *next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _AgGetPropertyTask
 | 
			
		||||
{
 | 
			
		||||
  ListNode node;
 | 
			
		||||
 | 
			
		||||
  AgPerDisplayData *dd;
 | 
			
		||||
  Window window;
 | 
			
		||||
  Atom property;
 | 
			
		||||
 | 
			
		||||
  unsigned long request_seq;
 | 
			
		||||
  int error;
 | 
			
		||||
 | 
			
		||||
  Atom actual_type;
 | 
			
		||||
  int  actual_format;
 | 
			
		||||
 | 
			
		||||
  unsigned long  n_items;
 | 
			
		||||
  unsigned long  bytes_after;
 | 
			
		||||
  char          *data;
 | 
			
		||||
 | 
			
		||||
  Bool have_reply;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _AgPerDisplayData
 | 
			
		||||
{
 | 
			
		||||
  ListNode node;
 | 
			
		||||
  _XAsyncHandler async;
 | 
			
		||||
 | 
			
		||||
  Display *display;
 | 
			
		||||
  ListNode *pending_tasks;
 | 
			
		||||
  ListNode *pending_tasks_tail;
 | 
			
		||||
  ListNode *completed_tasks;
 | 
			
		||||
  ListNode *completed_tasks_tail;
 | 
			
		||||
  int n_tasks_pending;
 | 
			
		||||
  int n_tasks_completed;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static ListNode *display_datas = NULL;
 | 
			
		||||
static ListNode *display_datas_tail = NULL;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
append_to_list (ListNode **head,
 | 
			
		||||
                ListNode **tail,
 | 
			
		||||
                ListNode  *task)
 | 
			
		||||
{
 | 
			
		||||
  task->next = NULL;
 | 
			
		||||
 | 
			
		||||
  if (*tail == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      assert (*head == NULL);
 | 
			
		||||
      *head = task;
 | 
			
		||||
      *tail = task;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      (*tail)->next = task;
 | 
			
		||||
      *tail = task;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
remove_from_list (ListNode **head,
 | 
			
		||||
                  ListNode **tail,
 | 
			
		||||
                  ListNode  *task)
 | 
			
		||||
{
 | 
			
		||||
  ListNode *prev;
 | 
			
		||||
  ListNode *node;
 | 
			
		||||
 | 
			
		||||
  prev = NULL;
 | 
			
		||||
  node = *head;
 | 
			
		||||
  while (node != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (node == task)
 | 
			
		||||
        {
 | 
			
		||||
          if (prev)
 | 
			
		||||
            prev->next = node->next;
 | 
			
		||||
          else
 | 
			
		||||
            *head = node->next;
 | 
			
		||||
 | 
			
		||||
          if (node == *tail)
 | 
			
		||||
            *tail = prev;
 | 
			
		||||
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      prev = node;
 | 
			
		||||
      node = node->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* can't remove what's not there */
 | 
			
		||||
  assert (node != NULL);
 | 
			
		||||
 | 
			
		||||
  node->next = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
move_to_completed (AgPerDisplayData  *dd,
 | 
			
		||||
                   AgGetPropertyTask *task)
 | 
			
		||||
{
 | 
			
		||||
  remove_from_list (&dd->pending_tasks,
 | 
			
		||||
                    &dd->pending_tasks_tail,
 | 
			
		||||
                    &task->node);
 | 
			
		||||
 | 
			
		||||
  append_to_list (&dd->completed_tasks,
 | 
			
		||||
                  &dd->completed_tasks_tail,
 | 
			
		||||
                  &task->node);
 | 
			
		||||
 | 
			
		||||
  dd->n_tasks_pending -= 1;
 | 
			
		||||
  dd->n_tasks_completed += 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static AgGetPropertyTask*
 | 
			
		||||
find_pending_by_request_sequence (AgPerDisplayData *dd,
 | 
			
		||||
                                  unsigned long     request_seq)
 | 
			
		||||
{
 | 
			
		||||
  ListNode *node;
 | 
			
		||||
 | 
			
		||||
  /* if the sequence is after our last pending task, we
 | 
			
		||||
   * aren't going to find a match
 | 
			
		||||
   */
 | 
			
		||||
  {
 | 
			
		||||
    AgGetPropertyTask *task = (AgGetPropertyTask*) dd->pending_tasks_tail;
 | 
			
		||||
    if (task != NULL)
 | 
			
		||||
      {
 | 
			
		||||
        if (task->request_seq < request_seq)
 | 
			
		||||
          return NULL;
 | 
			
		||||
        else if (task->request_seq == request_seq)
 | 
			
		||||
          return task; /* why not check this */
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Generally we should get replies in the order we sent
 | 
			
		||||
   * requests, so we should usually be using the task
 | 
			
		||||
   * at the head of the list, if we use any task at all.
 | 
			
		||||
   * I'm not sure this is 100% guaranteed, if it is,
 | 
			
		||||
   * it would be a big speedup.
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  node = dd->pending_tasks;
 | 
			
		||||
  while (node != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      AgGetPropertyTask *task = (AgGetPropertyTask*) node;
 | 
			
		||||
 | 
			
		||||
      if (task->request_seq == request_seq)
 | 
			
		||||
        return task;
 | 
			
		||||
 | 
			
		||||
      node = node->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
async_get_property_handler (Display *dpy,
 | 
			
		||||
                            xReply  *rep,
 | 
			
		||||
                            char    *buf,
 | 
			
		||||
                            int      len,
 | 
			
		||||
                            XPointer data)
 | 
			
		||||
{
 | 
			
		||||
  xGetPropertyReply  replbuf;
 | 
			
		||||
  xGetPropertyReply *reply;
 | 
			
		||||
  AgGetPropertyTask *task;
 | 
			
		||||
  AgPerDisplayData *dd;
 | 
			
		||||
  int bytes_read;
 | 
			
		||||
 | 
			
		||||
  dd = (AgPerDisplayData*) data;
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
  printf ("%s: seeing request seq %ld buflen %d\n", __FUNCTION__,
 | 
			
		||||
          dpy->last_request_read, len);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  task = find_pending_by_request_sequence (dd, dpy->last_request_read);
 | 
			
		||||
 | 
			
		||||
  if (task == NULL)
 | 
			
		||||
    return False;
 | 
			
		||||
 | 
			
		||||
  assert (dpy->last_request_read == task->request_seq);
 | 
			
		||||
 | 
			
		||||
  task->have_reply = True;
 | 
			
		||||
  move_to_completed (dd, task);
 | 
			
		||||
 | 
			
		||||
  /* read bytes so far */
 | 
			
		||||
  bytes_read = SIZEOF (xReply);
 | 
			
		||||
 | 
			
		||||
  if (rep->generic.type == X_Error)
 | 
			
		||||
    {
 | 
			
		||||
      xError errbuf;
 | 
			
		||||
 | 
			
		||||
      task->error = rep->error.errorCode;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_SPEW
 | 
			
		||||
      printf ("%s: error code = %d (ignoring error, eating %d bytes, generic.length = %ld)\n",
 | 
			
		||||
              __FUNCTION__, task->error, (SIZEOF (xError) - bytes_read),
 | 
			
		||||
              rep->generic.length);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
      /* We return True (meaning we consumed the reply)
 | 
			
		||||
       * because otherwise it would invoke the X error handler,
 | 
			
		||||
       * and an async API is useless if you have to synchronously
 | 
			
		||||
       * trap X errors. Also GetProperty can always fail, pretty
 | 
			
		||||
       * much, so trapping errors is always what you want.
 | 
			
		||||
       *
 | 
			
		||||
       * We have to eat all the error reply data here.
 | 
			
		||||
       * (kind of a charade as we know sizeof(xError) == sizeof(xReply))
 | 
			
		||||
       *
 | 
			
		||||
       * Passing discard = True seems to break things; I don't understand
 | 
			
		||||
       * why, because there should be no extra data in an error reply,
 | 
			
		||||
       * right?
 | 
			
		||||
       */
 | 
			
		||||
      _XGetAsyncReply (dpy, (char *)&errbuf, rep, buf, len,
 | 
			
		||||
                       (SIZEOF (xError) - bytes_read) >> 2, /* in 32-bit words */
 | 
			
		||||
                       False); /* really seems like it should be True */
 | 
			
		||||
 | 
			
		||||
      return True;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_SPEW
 | 
			
		||||
  printf ("%s: already read %d bytes reading %d more for total of %d; generic.length = %ld\n",
 | 
			
		||||
          __FUNCTION__, bytes_read, (SIZEOF (xGetPropertyReply) - bytes_read) >> 2,
 | 
			
		||||
          SIZEOF (xGetPropertyReply), rep->generic.length);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /* (kind of a silly as we know sizeof(xGetPropertyReply) == sizeof(xReply)) */
 | 
			
		||||
  reply = (xGetPropertyReply *)
 | 
			
		||||
    _XGetAsyncReply (dpy, (char *)&replbuf, rep, buf, len,
 | 
			
		||||
                     (SIZEOF (xGetPropertyReply) - bytes_read) >> 2, /* in 32-bit words */
 | 
			
		||||
                     False); /* False means expecting more data to follow,
 | 
			
		||||
                              * don't eat the rest of the reply
 | 
			
		||||
                              */
 | 
			
		||||
 | 
			
		||||
  bytes_read = SIZEOF (xGetPropertyReply);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_SPEW
 | 
			
		||||
  printf ("%s: have reply propertyType = %ld format = %d n_items = %ld\n",
 | 
			
		||||
          __FUNCTION__, reply->propertyType, reply->format, reply->nItems);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  assert (task->data == NULL);
 | 
			
		||||
 | 
			
		||||
  /* This is all copied from XGetWindowProperty().  Not sure we should
 | 
			
		||||
   * LockDisplay(). Not sure I'm passing the right args to
 | 
			
		||||
   * XGetAsyncData(). Not sure about a lot of things.
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  /* LockDisplay (dpy); */
 | 
			
		||||
 | 
			
		||||
  if (reply->propertyType != None)
 | 
			
		||||
    {
 | 
			
		||||
      long nbytes, netbytes;
 | 
			
		||||
 | 
			
		||||
      /* this alignment macro from orbit2 */
 | 
			
		||||
#define ALIGN_VALUE(this, boundary) \
 | 
			
		||||
  (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
 | 
			
		||||
 | 
			
		||||
      switch (reply->format)
 | 
			
		||||
        {
 | 
			
		||||
          /*
 | 
			
		||||
           * One extra byte is malloced than is needed to contain the property
 | 
			
		||||
           * data, but this last byte is null terminated and convenient for
 | 
			
		||||
           * returning string properties, so the client doesn't then have to
 | 
			
		||||
           * recopy the string to make it null terminated.
 | 
			
		||||
           */
 | 
			
		||||
        case 8:
 | 
			
		||||
          nbytes = reply->nItems;
 | 
			
		||||
          /* there's padding to word boundary */
 | 
			
		||||
          netbytes = ALIGN_VALUE (nbytes, 4);
 | 
			
		||||
          if (nbytes + 1 > 0 &&
 | 
			
		||||
              (task->data = (char *) Xmalloc ((unsigned)nbytes + 1)))
 | 
			
		||||
            {
 | 
			
		||||
#ifdef DEBUG_SPEW
 | 
			
		||||
              printf ("%s: already read %d bytes using %ld, more eating %ld more\n",
 | 
			
		||||
                      __FUNCTION__, bytes_read, nbytes, netbytes);
 | 
			
		||||
#endif
 | 
			
		||||
              /* _XReadPad (dpy, (char *) task->data, netbytes); */
 | 
			
		||||
              _XGetAsyncData (dpy, task->data, buf, len,
 | 
			
		||||
                              bytes_read, nbytes,
 | 
			
		||||
                              netbytes);
 | 
			
		||||
            }
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case 16:
 | 
			
		||||
          nbytes = reply->nItems * sizeof (short);
 | 
			
		||||
          netbytes = reply->nItems << 1;
 | 
			
		||||
          netbytes = ALIGN_VALUE (netbytes, 4); /* align to word boundary */
 | 
			
		||||
          if (nbytes + 1 > 0 &&
 | 
			
		||||
              (task->data = (char *) Xmalloc ((unsigned)nbytes + 1)))
 | 
			
		||||
            {
 | 
			
		||||
#ifdef DEBUG_SPEW
 | 
			
		||||
              printf ("%s: already read %d bytes using %ld more, eating %ld more\n",
 | 
			
		||||
                      __FUNCTION__, bytes_read, nbytes, netbytes);
 | 
			
		||||
#endif
 | 
			
		||||
              /* _XRead16Pad (dpy, (short *) task->data, netbytes); */
 | 
			
		||||
              _XGetAsyncData (dpy, task->data, buf, len,
 | 
			
		||||
                              bytes_read, nbytes, netbytes);
 | 
			
		||||
            }
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case 32:
 | 
			
		||||
          /* NOTE buffer is in longs to match XGetWindowProperty() */
 | 
			
		||||
          nbytes = reply->nItems * sizeof (long);
 | 
			
		||||
          netbytes = reply->nItems << 2; /* wire size is always 32 bits though */
 | 
			
		||||
          if (nbytes + 1 > 0 &&
 | 
			
		||||
              (task->data = (char *) Xmalloc ((unsigned)nbytes + 1)))
 | 
			
		||||
            {
 | 
			
		||||
#ifdef DEBUG_SPEW
 | 
			
		||||
              printf ("%s: already read %d bytes using %ld more, eating %ld more\n",
 | 
			
		||||
                      __FUNCTION__, bytes_read, nbytes, netbytes);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
              /* We have to copy the XGetWindowProperty() crackrock
 | 
			
		||||
               * and get format 32 as long even on 64-bit platforms.
 | 
			
		||||
               */
 | 
			
		||||
              if (sizeof (long) == 8)
 | 
			
		||||
                {
 | 
			
		||||
                  char *netdata;
 | 
			
		||||
                  char *lptr;
 | 
			
		||||
                  char *end_lptr;
 | 
			
		||||
 | 
			
		||||
                  /* Store the 32-bit values in the end of the array */
 | 
			
		||||
                  netdata = task->data + nbytes / 2;
 | 
			
		||||
 | 
			
		||||
                  _XGetAsyncData (dpy, netdata, buf, len,
 | 
			
		||||
                                  bytes_read, netbytes,
 | 
			
		||||
                                  netbytes);
 | 
			
		||||
 | 
			
		||||
                  /* Now move the 32-bit values to the front */
 | 
			
		||||
 | 
			
		||||
                  lptr = task->data;
 | 
			
		||||
                  end_lptr = task->data + nbytes;
 | 
			
		||||
                  while (lptr != end_lptr)
 | 
			
		||||
                    {
 | 
			
		||||
                      *(long*) lptr = *(CARD32*) netdata;
 | 
			
		||||
                      lptr += sizeof (long);
 | 
			
		||||
                      netdata += sizeof (CARD32);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
              else
 | 
			
		||||
                {
 | 
			
		||||
                  /* Here the wire format matches our actual format */
 | 
			
		||||
                  _XGetAsyncData (dpy, task->data, buf, len,
 | 
			
		||||
                                  bytes_read, netbytes,
 | 
			
		||||
                                  netbytes);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          /*
 | 
			
		||||
           * This part of the code should never be reached.  If it is,
 | 
			
		||||
           * the server sent back a property with an invalid format.
 | 
			
		||||
           * This is a BadImplementation error.
 | 
			
		||||
           *
 | 
			
		||||
           * However this async GetProperty API doesn't report errors
 | 
			
		||||
           * via the standard X mechanism, so don't do anything about
 | 
			
		||||
           * it, other than store it in task->error.
 | 
			
		||||
           */
 | 
			
		||||
          {
 | 
			
		||||
#if 0
 | 
			
		||||
            xError error;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
            task->error = BadImplementation;
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
            error.sequenceNumber = task->request_seq;
 | 
			
		||||
            error.type = X_Error;
 | 
			
		||||
            error.majorCode = X_GetProperty;
 | 
			
		||||
            error.minorCode = 0;
 | 
			
		||||
            error.errorCode = BadImplementation;
 | 
			
		||||
 | 
			
		||||
            _XError (dpy, &error);
 | 
			
		||||
#endif
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          nbytes = netbytes = 0L;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (task->data == NULL)
 | 
			
		||||
        {
 | 
			
		||||
          task->error = BadAlloc;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_SPEW
 | 
			
		||||
          printf ("%s: already read %d bytes eating %ld\n",
 | 
			
		||||
                  __FUNCTION__, bytes_read, netbytes);
 | 
			
		||||
#endif
 | 
			
		||||
          /* _XEatData (dpy, (unsigned long) netbytes); */
 | 
			
		||||
          _XGetAsyncData (dpy, NULL, buf, len,
 | 
			
		||||
                          bytes_read, 0, netbytes);
 | 
			
		||||
 | 
			
		||||
          /* UnlockDisplay (dpy); */
 | 
			
		||||
          return BadAlloc; /* not Success */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      (task->data)[nbytes] = '\0';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_SPEW
 | 
			
		||||
  printf ("%s: have data\n", __FUNCTION__);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  task->actual_type = reply->propertyType;
 | 
			
		||||
  task->actual_format = reply->format;
 | 
			
		||||
  task->n_items = reply->nItems;
 | 
			
		||||
  task->bytes_after = reply->bytesAfter;
 | 
			
		||||
 | 
			
		||||
  /* UnlockDisplay (dpy); */
 | 
			
		||||
 | 
			
		||||
  return True;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static AgPerDisplayData*
 | 
			
		||||
get_display_data (Display *display,
 | 
			
		||||
                  Bool     create)
 | 
			
		||||
{
 | 
			
		||||
  ListNode *node;
 | 
			
		||||
  AgPerDisplayData *dd;
 | 
			
		||||
 | 
			
		||||
  node = display_datas;
 | 
			
		||||
  while (node != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      dd = (AgPerDisplayData*) node;
 | 
			
		||||
 | 
			
		||||
      if (dd->display == display)
 | 
			
		||||
        return dd;
 | 
			
		||||
 | 
			
		||||
      node = node->next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!create)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  dd = Xcalloc (1, sizeof (AgPerDisplayData));
 | 
			
		||||
  if (dd == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  dd->display = display;
 | 
			
		||||
  dd->async.next = display->async_handlers;
 | 
			
		||||
  dd->async.handler = async_get_property_handler;
 | 
			
		||||
  dd->async.data = (XPointer) dd;
 | 
			
		||||
  dd->display->async_handlers = &dd->async;
 | 
			
		||||
 | 
			
		||||
  append_to_list (&display_datas,
 | 
			
		||||
                  &display_datas_tail,
 | 
			
		||||
                  &dd->node);
 | 
			
		||||
 | 
			
		||||
  return dd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
maybe_free_display_data (AgPerDisplayData *dd)
 | 
			
		||||
{
 | 
			
		||||
  if (dd->pending_tasks == NULL &&
 | 
			
		||||
      dd->completed_tasks == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      DeqAsyncHandler (dd->display, &dd->async);
 | 
			
		||||
      remove_from_list (&display_datas, &display_datas_tail,
 | 
			
		||||
                        &dd->node);
 | 
			
		||||
      XFree (dd);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AgGetPropertyTask*
 | 
			
		||||
ag_task_create (Display *dpy,
 | 
			
		||||
                Window   window,
 | 
			
		||||
                Atom     property,
 | 
			
		||||
                long     offset,
 | 
			
		||||
                long     length,
 | 
			
		||||
                Bool     delete,
 | 
			
		||||
                Atom     req_type)
 | 
			
		||||
{
 | 
			
		||||
  AgGetPropertyTask *task;
 | 
			
		||||
  xGetPropertyReq *req;
 | 
			
		||||
  AgPerDisplayData *dd;
 | 
			
		||||
 | 
			
		||||
  /* Fire up our request */
 | 
			
		||||
  LockDisplay (dpy);
 | 
			
		||||
 | 
			
		||||
  dd = get_display_data (dpy, True);
 | 
			
		||||
  if (dd == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      UnlockDisplay (dpy);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  GetReq (GetProperty, req);
 | 
			
		||||
  req->window = window;
 | 
			
		||||
  req->property = property;
 | 
			
		||||
  req->type = req_type;
 | 
			
		||||
  req->delete = delete;
 | 
			
		||||
  req->longOffset = offset;
 | 
			
		||||
  req->longLength = length;
 | 
			
		||||
 | 
			
		||||
  /* Queue up our async task */
 | 
			
		||||
  task = Xcalloc (1, sizeof (AgGetPropertyTask));
 | 
			
		||||
  if (task == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      UnlockDisplay (dpy);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  task->dd = dd;
 | 
			
		||||
  task->window = window;
 | 
			
		||||
  task->property = property;
 | 
			
		||||
  task->request_seq = dpy->request;
 | 
			
		||||
 | 
			
		||||
  append_to_list (&dd->pending_tasks,
 | 
			
		||||
                  &dd->pending_tasks_tail,
 | 
			
		||||
                  &task->node);
 | 
			
		||||
  dd->n_tasks_pending += 1;
 | 
			
		||||
 | 
			
		||||
  UnlockDisplay (dpy);
 | 
			
		||||
 | 
			
		||||
  SyncHandle ();
 | 
			
		||||
 | 
			
		||||
  return task;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
free_task (AgGetPropertyTask *task)
 | 
			
		||||
{
 | 
			
		||||
  remove_from_list (&task->dd->completed_tasks,
 | 
			
		||||
                    &task->dd->completed_tasks_tail,
 | 
			
		||||
                    &task->node);
 | 
			
		||||
  task->dd->n_tasks_completed -= 1;
 | 
			
		||||
  maybe_free_display_data (task->dd);
 | 
			
		||||
  XFree (task);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Status
 | 
			
		||||
ag_task_get_reply_and_free (AgGetPropertyTask  *task,
 | 
			
		||||
                            Atom               *actual_type,
 | 
			
		||||
                            int                *actual_format,
 | 
			
		||||
                            unsigned long      *nitems,
 | 
			
		||||
                            unsigned long      *bytesafter,
 | 
			
		||||
                            unsigned char     **prop)
 | 
			
		||||
{
 | 
			
		||||
  Display *dpy;
 | 
			
		||||
 | 
			
		||||
  *prop = NULL;
 | 
			
		||||
 | 
			
		||||
  dpy = task->dd->display; /* Xlib macros require a variable named "dpy" */
 | 
			
		||||
 | 
			
		||||
  if (task->error != Success)
 | 
			
		||||
    {
 | 
			
		||||
      Status s = task->error;
 | 
			
		||||
 | 
			
		||||
      free_task (task);
 | 
			
		||||
 | 
			
		||||
      return s;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (!task->have_reply)
 | 
			
		||||
    {
 | 
			
		||||
      free_task (task);
 | 
			
		||||
 | 
			
		||||
      return BadAlloc; /* not Success */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  *actual_type = task->actual_type;
 | 
			
		||||
  *actual_format = task->actual_format;
 | 
			
		||||
  *nitems = task->n_items;
 | 
			
		||||
  *bytesafter = task->bytes_after;
 | 
			
		||||
 | 
			
		||||
  *prop = (unsigned char*) task->data; /* pass out ownership of task->data */
 | 
			
		||||
 | 
			
		||||
  SyncHandle ();
 | 
			
		||||
 | 
			
		||||
  free_task (task);
 | 
			
		||||
 | 
			
		||||
  return Success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Bool
 | 
			
		||||
ag_task_have_reply (AgGetPropertyTask *task)
 | 
			
		||||
{
 | 
			
		||||
  return task->have_reply;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Atom
 | 
			
		||||
ag_task_get_property (AgGetPropertyTask *task)
 | 
			
		||||
{
 | 
			
		||||
  return task->property;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Window
 | 
			
		||||
ag_task_get_window (AgGetPropertyTask *task)
 | 
			
		||||
{
 | 
			
		||||
  return task->window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Display*
 | 
			
		||||
ag_task_get_display (AgGetPropertyTask *task)
 | 
			
		||||
{
 | 
			
		||||
  return task->dd->display;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AgGetPropertyTask*
 | 
			
		||||
ag_get_next_completed_task (Display *display)
 | 
			
		||||
{
 | 
			
		||||
  AgPerDisplayData *dd;
 | 
			
		||||
 | 
			
		||||
  dd = get_display_data (display, False);
 | 
			
		||||
 | 
			
		||||
  if (dd == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_SPEW
 | 
			
		||||
  printf ("%d pending %d completed\n",
 | 
			
		||||
          dd->n_tasks_pending,
 | 
			
		||||
          dd->n_tasks_completed);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return (AgGetPropertyTask*) dd->completed_tasks;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
ag_Xmalloc (unsigned long bytes)
 | 
			
		||||
{
 | 
			
		||||
  return (void*) Xmalloc (bytes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void*
 | 
			
		||||
ag_Xmalloc0 (unsigned long bytes)
 | 
			
		||||
{
 | 
			
		||||
  return (void*) Xcalloc (bytes, 1);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,67 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/* Asynchronous X property getting hack */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2002 Havoc Pennington
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, distribute, and sell this software
 | 
			
		||||
 * and its documentation for any purpose is hereby granted without
 | 
			
		||||
 * fee, provided that the above copyright notice appear in all copies
 | 
			
		||||
 * and that both that copyright notice and this permission notice
 | 
			
		||||
 * appear in supporting documentation.
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be
 | 
			
		||||
 * included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
 | 
			
		||||
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 | 
			
		||||
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | 
			
		||||
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of The Open Group shall not be
 | 
			
		||||
 * used in advertising or otherwise to promote the sale, use or other dealings
 | 
			
		||||
 * in this Software without prior written authorization from The Open Group.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ASYNC_GETPROP_H
 | 
			
		||||
#define ASYNC_GETPROP_H
 | 
			
		||||
 | 
			
		||||
#include <X11/Xlib.h>
 | 
			
		||||
#include <X11/Xutil.h>
 | 
			
		||||
 | 
			
		||||
typedef struct _AgGetPropertyTask AgGetPropertyTask;
 | 
			
		||||
 | 
			
		||||
AgGetPropertyTask* ag_task_create             (Display            *display,
 | 
			
		||||
                                               Window              window,
 | 
			
		||||
                                               Atom                property,
 | 
			
		||||
                                               long                offset,
 | 
			
		||||
                                               long                length,
 | 
			
		||||
                                               Bool                delete,
 | 
			
		||||
                                               Atom                req_type);
 | 
			
		||||
Status             ag_task_get_reply_and_free (AgGetPropertyTask  *task,
 | 
			
		||||
                                               Atom               *actual_type,
 | 
			
		||||
                                               int                *actual_format,
 | 
			
		||||
                                               unsigned long      *nitems,
 | 
			
		||||
                                               unsigned long      *bytesafter,
 | 
			
		||||
                                               unsigned char     **prop);
 | 
			
		||||
 | 
			
		||||
Bool     ag_task_have_reply   (AgGetPropertyTask *task);
 | 
			
		||||
Atom     ag_task_get_property (AgGetPropertyTask *task);
 | 
			
		||||
Window   ag_task_get_window   (AgGetPropertyTask *task);
 | 
			
		||||
Display* ag_task_get_display  (AgGetPropertyTask *task);
 | 
			
		||||
 | 
			
		||||
AgGetPropertyTask* ag_get_next_completed_task (Display *display);
 | 
			
		||||
 | 
			
		||||
/* so other headers don't have to include internal Xlib goo */
 | 
			
		||||
void*    ag_Xmalloc  (unsigned long bytes);
 | 
			
		||||
void*    ag_Xmalloc0 (unsigned long bytes);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -39,6 +39,7 @@
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
#include "wayland/meta-xwayland.h"
 | 
			
		||||
#include "wayland/meta-wayland-private.h"
 | 
			
		||||
#include "wayland/meta-xwayland-private.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static XIEvent *
 | 
			
		||||
@@ -1676,6 +1677,15 @@ meta_display_handle_xevent (MetaDisplay *display,
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_WAYLAND
 | 
			
		||||
  if (meta_is_wayland_compositor () &&
 | 
			
		||||
      meta_xwayland_selection_handle_event (event))
 | 
			
		||||
    {
 | 
			
		||||
      bypass_gtk = bypass_compositor = TRUE;
 | 
			
		||||
      goto out;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  display->current_time = event_get_time (display, event);
 | 
			
		||||
  display->monitor_cache_invalidated = TRUE;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,11 @@ meta_group_new (MetaDisplay *display,
 | 
			
		||||
  group->group_leader = group_leader;
 | 
			
		||||
  group->refcount = 1; /* owned by caller, hash table has only weak ref */
 | 
			
		||||
 | 
			
		||||
  XWindowAttributes attrs;
 | 
			
		||||
  XGetWindowAttributes (display->xdisplay, group_leader, &attrs);
 | 
			
		||||
  XSelectInput (display->xdisplay, group_leader,
 | 
			
		||||
                attrs.your_event_mask | PropertyChangeMask);
 | 
			
		||||
 | 
			
		||||
  if (display->groups_by_leader == NULL)
 | 
			
		||||
    display->groups_by_leader = g_hash_table_new (meta_unsigned_long_hash,
 | 
			
		||||
                                                  meta_unsigned_long_equal);
 | 
			
		||||
 
 | 
			
		||||
@@ -60,10 +60,10 @@ SOFTWARE.
 | 
			
		||||
#ifndef _XATOMTYPE_H_
 | 
			
		||||
#define _XATOMTYPE_H_
 | 
			
		||||
 | 
			
		||||
#define BOOL long
 | 
			
		||||
#define SIGNEDINT long
 | 
			
		||||
#define UNSIGNEDINT unsigned long
 | 
			
		||||
#define RESOURCEID unsigned long
 | 
			
		||||
#define BOOL int32_t
 | 
			
		||||
#define SIGNEDINT int32_t
 | 
			
		||||
#define UNSIGNEDINT uint32_t
 | 
			
		||||
#define RESOURCEID uint32_t
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* this structure may be extended, but do not change the order */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,496 +0,0 @@
 | 
			
		||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2002 Havoc Pennington
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, distribute, and sell this software
 | 
			
		||||
 * and its documentation for any purpose is hereby granted without
 | 
			
		||||
 * fee, provided that the above copyright notice appear in all copies
 | 
			
		||||
 * and that both that copyright notice and this permission notice
 | 
			
		||||
 * appear in supporting documentation.
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be
 | 
			
		||||
 * included in all copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR
 | 
			
		||||
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 | 
			
		||||
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | 
			
		||||
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * Except as contained in this notice, the name of The Open Group shall not be
 | 
			
		||||
 * used in advertising or otherwise to promote the sale, use or other dealings
 | 
			
		||||
 * in this Software without prior written authorization from The Open Group.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "async-getprop.h"
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#ifndef TRUE
 | 
			
		||||
#define TRUE 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef FALSE
 | 
			
		||||
#define FALSE 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef NULL
 | 
			
		||||
#define NULL ((void*) 0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_BACKTRACE
 | 
			
		||||
#include <execinfo.h>
 | 
			
		||||
static void
 | 
			
		||||
print_backtrace (void)
 | 
			
		||||
{
 | 
			
		||||
  void *bt[500];
 | 
			
		||||
  int bt_size;
 | 
			
		||||
  int i;
 | 
			
		||||
  char **syms;
 | 
			
		||||
 | 
			
		||||
  bt_size = backtrace (bt, 500);
 | 
			
		||||
 | 
			
		||||
  syms = backtrace_symbols (bt, bt_size);
 | 
			
		||||
 | 
			
		||||
  i = 0;
 | 
			
		||||
  while (i < bt_size)
 | 
			
		||||
    {
 | 
			
		||||
      fprintf (stderr, "  %s\n", syms[i]);
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  free (syms);
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
static void
 | 
			
		||||
print_backtrace (void)
 | 
			
		||||
{
 | 
			
		||||
  fprintf (stderr, "Not compiled with backtrace support\n");
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int error_trap_depth = 0;
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
x_error_handler (Display     *xdisplay,
 | 
			
		||||
                 XErrorEvent *error)
 | 
			
		||||
{
 | 
			
		||||
  char buf[64];
 | 
			
		||||
 | 
			
		||||
  XGetErrorText (xdisplay, error->error_code, buf, 63);
 | 
			
		||||
 | 
			
		||||
  if (error_trap_depth == 0)
 | 
			
		||||
    {
 | 
			
		||||
      print_backtrace ();
 | 
			
		||||
 | 
			
		||||
      fprintf (stderr, "Unexpected X error: %s serial %ld error_code %d request_code %d minor_code %d)\n",
 | 
			
		||||
               buf,
 | 
			
		||||
               error->serial,
 | 
			
		||||
               error->error_code,
 | 
			
		||||
               error->request_code,
 | 
			
		||||
               error->minor_code);
 | 
			
		||||
 | 
			
		||||
      exit (1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return 1; /* return value is meaningless */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
error_trap_push (Display   *xdisplay)
 | 
			
		||||
{
 | 
			
		||||
  ++error_trap_depth;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
error_trap_pop (Display   *xdisplay)
 | 
			
		||||
{
 | 
			
		||||
  if (error_trap_depth == 0)
 | 
			
		||||
    {
 | 
			
		||||
      fprintf (stderr, "Error trap underflow!\n");
 | 
			
		||||
      exit (1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  XSync (xdisplay, False); /* get all errors out of the queue */
 | 
			
		||||
  --error_trap_depth;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char*
 | 
			
		||||
my_strdup (const char *str)
 | 
			
		||||
{
 | 
			
		||||
  char *s;
 | 
			
		||||
 | 
			
		||||
  s = malloc (strlen (str) + 1);
 | 
			
		||||
  if (s == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      fprintf (stderr, "malloc failed\n");
 | 
			
		||||
      exit (1);
 | 
			
		||||
    }
 | 
			
		||||
  strcpy (s, str);
 | 
			
		||||
 | 
			
		||||
  return s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char*
 | 
			
		||||
atom_name (Display *display,
 | 
			
		||||
           Atom     atom)
 | 
			
		||||
{
 | 
			
		||||
  if (atom == None)
 | 
			
		||||
    {
 | 
			
		||||
      return my_strdup ("None");
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      char *xname;
 | 
			
		||||
      char *ret;
 | 
			
		||||
 | 
			
		||||
      error_trap_push (display);
 | 
			
		||||
      xname = XGetAtomName (display, atom);
 | 
			
		||||
      error_trap_pop (display);
 | 
			
		||||
      if (xname == NULL)
 | 
			
		||||
        return my_strdup ("[unknown atom]");
 | 
			
		||||
 | 
			
		||||
      ret = my_strdup (xname);
 | 
			
		||||
      XFree (xname);
 | 
			
		||||
 | 
			
		||||
      return ret;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ELAPSED(start_time, current_time) \
 | 
			
		||||
    (((((double)current_time.tv_sec - start_time.tv_sec) * 1000000 + \
 | 
			
		||||
       (current_time.tv_usec - start_time.tv_usec))) / 1000.0)
 | 
			
		||||
 | 
			
		||||
static struct timeval program_start_time;
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
try_get_reply (Display           *xdisplay,
 | 
			
		||||
               AgGetPropertyTask *task)
 | 
			
		||||
{
 | 
			
		||||
  if (ag_task_have_reply (task))
 | 
			
		||||
    {
 | 
			
		||||
      int result;
 | 
			
		||||
      Atom actual_type;
 | 
			
		||||
      int actual_format;
 | 
			
		||||
      unsigned long n_items;
 | 
			
		||||
      unsigned long bytes_after;
 | 
			
		||||
      unsigned char *data;
 | 
			
		||||
      char *name;
 | 
			
		||||
      struct timeval current_time;
 | 
			
		||||
 | 
			
		||||
      gettimeofday (¤t_time, NULL);
 | 
			
		||||
 | 
			
		||||
      printf (" %gms (we have a reply for property %ld)\n",
 | 
			
		||||
              ELAPSED (program_start_time, current_time),
 | 
			
		||||
              ag_task_get_property (task));
 | 
			
		||||
 | 
			
		||||
      data = NULL;
 | 
			
		||||
 | 
			
		||||
      name = atom_name (xdisplay,
 | 
			
		||||
                        ag_task_get_property (task));
 | 
			
		||||
      printf (" %s on 0x%lx:\n", name,
 | 
			
		||||
              ag_task_get_window (task));
 | 
			
		||||
      free (name);
 | 
			
		||||
 | 
			
		||||
      result = ag_task_get_reply_and_free (task,
 | 
			
		||||
                                           &actual_type,
 | 
			
		||||
                                           &actual_format,
 | 
			
		||||
                                           &n_items,
 | 
			
		||||
                                           &bytes_after,
 | 
			
		||||
                                           &data);
 | 
			
		||||
      task = NULL;
 | 
			
		||||
 | 
			
		||||
      if (result != Success)
 | 
			
		||||
        {
 | 
			
		||||
          fprintf (stderr, "  error code %d getting reply\n", result);
 | 
			
		||||
        }
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          name = atom_name (xdisplay, actual_type);
 | 
			
		||||
          printf ("  actual_type = %s\n", name);
 | 
			
		||||
          free (name);
 | 
			
		||||
 | 
			
		||||
          printf ("  actual_format = %d\n", actual_format);
 | 
			
		||||
 | 
			
		||||
          printf ("  n_items = %lu\n", n_items);
 | 
			
		||||
          printf ("  bytes_after = %lu\n", bytes_after);
 | 
			
		||||
 | 
			
		||||
          printf ("  data = \"%s\"\n", data ? (char*) data : "NULL");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      return True;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return False;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void run_speed_comparison (Display *xdisplay,
 | 
			
		||||
                                  Window   window);
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
main (int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
  Display *xdisplay;
 | 
			
		||||
  int i;
 | 
			
		||||
  int n_left;
 | 
			
		||||
  int n_props;
 | 
			
		||||
  Window window;
 | 
			
		||||
  const char *window_str;
 | 
			
		||||
  char *end;
 | 
			
		||||
  Atom *props;
 | 
			
		||||
  struct timeval current_time;
 | 
			
		||||
 | 
			
		||||
  if (argc < 2)
 | 
			
		||||
    {
 | 
			
		||||
      fprintf (stderr, "specify window ID\n");
 | 
			
		||||
      return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  window_str = argv[1];
 | 
			
		||||
 | 
			
		||||
  end = NULL;
 | 
			
		||||
  window = strtoul (window_str, &end, 0);
 | 
			
		||||
  if (end == NULL || *end != '\0')
 | 
			
		||||
    {
 | 
			
		||||
      fprintf (stderr, "\"%s\" does not parse as a window ID\n", window_str);
 | 
			
		||||
      return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  xdisplay = XOpenDisplay (NULL);
 | 
			
		||||
  if (xdisplay == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      fprintf (stderr, "Could not open display\n");
 | 
			
		||||
      return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (getenv ("MUTTER_SYNC") != NULL)
 | 
			
		||||
    XSynchronize (xdisplay, True);
 | 
			
		||||
 | 
			
		||||
  XSetErrorHandler (x_error_handler);
 | 
			
		||||
 | 
			
		||||
  n_props = 0;
 | 
			
		||||
  props = XListProperties (xdisplay, window, &n_props);
 | 
			
		||||
  if (n_props == 0 || props == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      fprintf (stderr, "Window has no properties\n");
 | 
			
		||||
      return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  gettimeofday (&program_start_time, NULL);
 | 
			
		||||
 | 
			
		||||
  i = 0;
 | 
			
		||||
  while (i < n_props)
 | 
			
		||||
    {
 | 
			
		||||
      gettimeofday (¤t_time, NULL);
 | 
			
		||||
      printf (" %gms (sending request for property %ld)\n",
 | 
			
		||||
              ELAPSED (program_start_time, current_time),
 | 
			
		||||
              props[i]);
 | 
			
		||||
      if (ag_task_create (xdisplay,
 | 
			
		||||
                          window, props[i],
 | 
			
		||||
                          0, 0xffffffff,
 | 
			
		||||
                          False,
 | 
			
		||||
                          AnyPropertyType) == NULL)
 | 
			
		||||
        {
 | 
			
		||||
          fprintf (stderr, "Failed to send request\n");
 | 
			
		||||
          return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  XFree (props);
 | 
			
		||||
  props = NULL;
 | 
			
		||||
 | 
			
		||||
  n_left = n_props;
 | 
			
		||||
 | 
			
		||||
  while (TRUE)
 | 
			
		||||
    {
 | 
			
		||||
      XEvent xevent;
 | 
			
		||||
      int connection;
 | 
			
		||||
      fd_set set;
 | 
			
		||||
      AgGetPropertyTask *task;
 | 
			
		||||
 | 
			
		||||
      /* Mop up event queue */
 | 
			
		||||
      while (XPending (xdisplay) > 0)
 | 
			
		||||
        {
 | 
			
		||||
          XNextEvent (xdisplay, &xevent);
 | 
			
		||||
          gettimeofday (¤t_time, NULL);
 | 
			
		||||
          printf (" %gms (processing event type %d)\n",
 | 
			
		||||
                  ELAPSED (program_start_time, current_time),
 | 
			
		||||
                  xevent.xany.type);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      while ((task = ag_get_next_completed_task (xdisplay)))
 | 
			
		||||
        {
 | 
			
		||||
          try_get_reply (xdisplay, task);
 | 
			
		||||
          n_left -= 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (n_left == 0)
 | 
			
		||||
        {
 | 
			
		||||
          printf ("All %d replies received.\n", n_props);
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      /* Wake up if we may have a reply */
 | 
			
		||||
      connection = ConnectionNumber (xdisplay);
 | 
			
		||||
 | 
			
		||||
      FD_ZERO (&set);
 | 
			
		||||
      FD_SET (connection, &set);
 | 
			
		||||
 | 
			
		||||
      gettimeofday (¤t_time, NULL);
 | 
			
		||||
      printf (" %gms (blocking for data %d left)\n",
 | 
			
		||||
              ELAPSED (program_start_time, current_time), n_left);
 | 
			
		||||
      select (connection + 1, &set, NULL, NULL, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  run_speed_comparison (xdisplay, window);
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function doesn't have all the printf's
 | 
			
		||||
 * and other noise, it just compares async to sync
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
run_speed_comparison (Display *xdisplay,
 | 
			
		||||
                      Window   window)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  int n_props;
 | 
			
		||||
  struct timeval start, end;
 | 
			
		||||
  int n_left;
 | 
			
		||||
 | 
			
		||||
  /* We just use atom values (0 to n_props) % 200, many are probably
 | 
			
		||||
   * BadAtom, that's fine, but the %200 keeps most of them valid. The
 | 
			
		||||
   * async case is about twice as advantageous when using valid atoms
 | 
			
		||||
   * (or the issue may be that it's more advantageous when the
 | 
			
		||||
   * properties are present and data is transmitted).
 | 
			
		||||
   */
 | 
			
		||||
  n_props = 4000;
 | 
			
		||||
  printf ("Timing with %d property requests\n", n_props);
 | 
			
		||||
 | 
			
		||||
  gettimeofday (&start, NULL);
 | 
			
		||||
 | 
			
		||||
  i = 0;
 | 
			
		||||
  while (i < n_props)
 | 
			
		||||
    {
 | 
			
		||||
      if (ag_task_create (xdisplay,
 | 
			
		||||
                          window, (Atom) i % 200,
 | 
			
		||||
                          0, 0xffffffff,
 | 
			
		||||
                          False,
 | 
			
		||||
                          AnyPropertyType) == NULL)
 | 
			
		||||
        {
 | 
			
		||||
          fprintf (stderr, "Failed to send request\n");
 | 
			
		||||
          exit (1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  n_left = n_props;
 | 
			
		||||
 | 
			
		||||
  while (TRUE)
 | 
			
		||||
    {
 | 
			
		||||
      int connection;
 | 
			
		||||
      fd_set set;
 | 
			
		||||
      XEvent xevent;
 | 
			
		||||
      AgGetPropertyTask *task;
 | 
			
		||||
 | 
			
		||||
      /* Mop up event queue */
 | 
			
		||||
      while (XPending (xdisplay) > 0)
 | 
			
		||||
        XNextEvent (xdisplay, &xevent);
 | 
			
		||||
 | 
			
		||||
      while ((task = ag_get_next_completed_task (xdisplay)))
 | 
			
		||||
        {
 | 
			
		||||
          Atom actual_type;
 | 
			
		||||
          int actual_format;
 | 
			
		||||
          unsigned long n_items;
 | 
			
		||||
          unsigned long bytes_after;
 | 
			
		||||
          unsigned char *data;
 | 
			
		||||
 | 
			
		||||
          assert (ag_task_have_reply (task));
 | 
			
		||||
 | 
			
		||||
          data = NULL;
 | 
			
		||||
          ag_task_get_reply_and_free (task,
 | 
			
		||||
                                      &actual_type,
 | 
			
		||||
                                      &actual_format,
 | 
			
		||||
                                      &n_items,
 | 
			
		||||
                                      &bytes_after,
 | 
			
		||||
                                      &data);
 | 
			
		||||
 | 
			
		||||
          if (data)
 | 
			
		||||
            XFree (data);
 | 
			
		||||
 | 
			
		||||
          n_left -= 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (n_left == 0)
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
      /* Wake up if we may have a reply */
 | 
			
		||||
      connection = ConnectionNumber (xdisplay);
 | 
			
		||||
 | 
			
		||||
      FD_ZERO (&set);
 | 
			
		||||
      FD_SET (connection, &set);
 | 
			
		||||
 | 
			
		||||
      select (connection + 1, &set, NULL, NULL, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  gettimeofday (&end, NULL);
 | 
			
		||||
 | 
			
		||||
  printf ("Async time: %gms\n",
 | 
			
		||||
          ELAPSED (start, end));
 | 
			
		||||
 | 
			
		||||
  gettimeofday (&start, NULL);
 | 
			
		||||
 | 
			
		||||
  error_trap_push (xdisplay);
 | 
			
		||||
 | 
			
		||||
  i = 0;
 | 
			
		||||
  while (i < n_props)
 | 
			
		||||
    {
 | 
			
		||||
      Atom actual_type;
 | 
			
		||||
      int actual_format;
 | 
			
		||||
      unsigned long n_items;
 | 
			
		||||
      unsigned long bytes_after;
 | 
			
		||||
      unsigned char *data;
 | 
			
		||||
 | 
			
		||||
      data = NULL;
 | 
			
		||||
      if (XGetWindowProperty (xdisplay, window,
 | 
			
		||||
                              (Atom) i % 200,
 | 
			
		||||
                              0, 0xffffffff,
 | 
			
		||||
                              False,
 | 
			
		||||
                              AnyPropertyType,
 | 
			
		||||
                              &actual_type,
 | 
			
		||||
                              &actual_format,
 | 
			
		||||
                              &n_items,
 | 
			
		||||
                              &bytes_after,
 | 
			
		||||
                              &data) == Success)
 | 
			
		||||
        {
 | 
			
		||||
          if (data)
 | 
			
		||||
            XFree (data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  error_trap_pop (xdisplay);
 | 
			
		||||
 | 
			
		||||
  gettimeofday (&end, NULL);
 | 
			
		||||
 | 
			
		||||
  printf ("Sync time:  %gms\n",
 | 
			
		||||
          ELAPSED (start, end));
 | 
			
		||||
}
 | 
			
		||||
@@ -428,10 +428,10 @@ reload_net_wm_pid (MetaWindow    *window,
 | 
			
		||||
{
 | 
			
		||||
  if (value->type != META_PROP_VALUE_INVALID)
 | 
			
		||||
    {
 | 
			
		||||
      gulong cardinal = (int) value->v.cardinal;
 | 
			
		||||
      uint32_t cardinal = (int) value->v.cardinal;
 | 
			
		||||
 | 
			
		||||
      if (cardinal <= 0)
 | 
			
		||||
        meta_warning ("Application set a bogus _NET_WM_PID %lu\n",
 | 
			
		||||
        meta_warning ("Application set a bogus _NET_WM_PID %u\n",
 | 
			
		||||
                      cardinal);
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
@@ -449,7 +449,7 @@ reload_net_wm_user_time (MetaWindow    *window,
 | 
			
		||||
{
 | 
			
		||||
  if (value->type != META_PROP_VALUE_INVALID)
 | 
			
		||||
    {
 | 
			
		||||
      gulong cardinal = value->v.cardinal;
 | 
			
		||||
      uint32_t cardinal = value->v.cardinal;
 | 
			
		||||
      meta_window_set_user_time (window, cardinal);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -670,7 +670,7 @@ reload_opaque_region (MetaWindow    *window,
 | 
			
		||||
 | 
			
		||||
  if (value->type != META_PROP_VALUE_INVALID)
 | 
			
		||||
    {
 | 
			
		||||
      gulong *region = value->v.cardinal_list.cardinals;
 | 
			
		||||
      uint32_t *region = value->v.cardinal_list.cardinals;
 | 
			
		||||
      int nitems = value->v.cardinal_list.n_cardinals;
 | 
			
		||||
 | 
			
		||||
      cairo_rectangle_int_t *rects;
 | 
			
		||||
@@ -862,7 +862,7 @@ reload_mwm_hints (MetaWindow    *window,
 | 
			
		||||
 | 
			
		||||
  if (hints->flags & MWM_HINTS_DECORATIONS)
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("Window %s sets MWM_HINTS_DECORATIONS 0x%lx\n",
 | 
			
		||||
      meta_verbose ("Window %s sets MWM_HINTS_DECORATIONS 0x%x\n",
 | 
			
		||||
          window->desc, hints->decorations);
 | 
			
		||||
 | 
			
		||||
      if (hints->decorations == 0)
 | 
			
		||||
@@ -878,7 +878,7 @@ reload_mwm_hints (MetaWindow    *window,
 | 
			
		||||
    {
 | 
			
		||||
      gboolean toggle_value;
 | 
			
		||||
 | 
			
		||||
      meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%lx\n",
 | 
			
		||||
      meta_verbose ("Window %s sets MWM_HINTS_FUNCTIONS 0x%x\n",
 | 
			
		||||
                    window->desc, hints->functions);
 | 
			
		||||
 | 
			
		||||
      /* If _ALL is specified, then other flags indicate what to turn off;
 | 
			
		||||
 
 | 
			
		||||
@@ -1283,7 +1283,7 @@ meta_window_x11_update_struts (MetaWindow *window)
 | 
			
		||||
  GSList *old_struts;
 | 
			
		||||
  GSList *new_struts;
 | 
			
		||||
  GSList *old_iter, *new_iter;
 | 
			
		||||
  gulong *struts = NULL;
 | 
			
		||||
  uint32_t *struts = NULL;
 | 
			
		||||
  int nitems;
 | 
			
		||||
  gboolean changed;
 | 
			
		||||
 | 
			
		||||
@@ -1346,7 +1346,7 @@ meta_window_x11_update_struts (MetaWindow *window)
 | 
			
		||||
              new_struts = g_slist_prepend (new_struts, temp);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          meta_verbose ("_NET_WM_STRUT_PARTIAL struts %lu %lu %lu %lu for "
 | 
			
		||||
          meta_verbose ("_NET_WM_STRUT_PARTIAL struts %u %u %u %u for "
 | 
			
		||||
                        "window %s\n",
 | 
			
		||||
                        struts[0], struts[1], struts[2], struts[3],
 | 
			
		||||
                        window->desc);
 | 
			
		||||
@@ -1405,7 +1405,7 @@ meta_window_x11_update_struts (MetaWindow *window)
 | 
			
		||||
              new_struts = g_slist_prepend (new_struts, temp);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
          meta_verbose ("_NET_WM_STRUT struts %lu %lu %lu %lu for window %s\n",
 | 
			
		||||
          meta_verbose ("_NET_WM_STRUT struts %u %u %u %u for window %s\n",
 | 
			
		||||
                        struts[0], struts[1], struts[2], struts[3],
 | 
			
		||||
                        window->desc);
 | 
			
		||||
        }
 | 
			
		||||
@@ -1471,6 +1471,13 @@ meta_window_x11_update_icon (MetaWindow       *window,
 | 
			
		||||
                          META_MINI_ICON_WIDTH, META_MINI_ICON_HEIGHT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_x11_update_main_monitor (MetaWindow *window)
 | 
			
		||||
{
 | 
			
		||||
  window->monitor = meta_screen_calculate_monitor_for_window (window->screen,
 | 
			
		||||
                                                              window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
meta_window_x11_main_monitor_changed (MetaWindow *window,
 | 
			
		||||
                                      const MetaMonitorInfo *old)
 | 
			
		||||
@@ -1495,6 +1502,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass)
 | 
			
		||||
  window_class->update_struts = meta_window_x11_update_struts;
 | 
			
		||||
  window_class->get_default_skip_hints = meta_window_x11_get_default_skip_hints;
 | 
			
		||||
  window_class->update_icon = meta_window_x11_update_icon;
 | 
			
		||||
  window_class->update_main_monitor = meta_window_x11_update_main_monitor;
 | 
			
		||||
  window_class->main_monitor_changed = meta_window_x11_main_monitor_changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2239,19 +2247,11 @@ meta_window_x11_client_message (MetaWindow *window,
 | 
			
		||||
                                            space);
 | 
			
		||||
 | 
			
		||||
      if (workspace)
 | 
			
		||||
        {
 | 
			
		||||
          if (window->on_all_workspaces_requested)
 | 
			
		||||
            meta_window_unstick (window);
 | 
			
		||||
          meta_window_change_workspace (window, workspace);
 | 
			
		||||
        }
 | 
			
		||||
        meta_window_change_workspace (window, workspace);
 | 
			
		||||
      else if (space == (int) 0xFFFFFFFF)
 | 
			
		||||
        {
 | 
			
		||||
          meta_window_stick (window);
 | 
			
		||||
        }
 | 
			
		||||
        meta_window_stick (window);
 | 
			
		||||
      else
 | 
			
		||||
        {
 | 
			
		||||
          meta_verbose ("No such workspace %d for screen\n", space);
 | 
			
		||||
        }
 | 
			
		||||
        meta_verbose ("No such workspace %d for screen\n", space);
 | 
			
		||||
 | 
			
		||||
      meta_verbose ("Window %s now on_all_workspaces = %d\n",
 | 
			
		||||
                    window->desc, window->on_all_workspaces);
 | 
			
		||||
@@ -2774,7 +2774,7 @@ maybe_filter_xwindow (MetaDisplay       *display,
 | 
			
		||||
       */
 | 
			
		||||
      if (!must_be_viewable || attrs->map_state == IsViewable)
 | 
			
		||||
        {
 | 
			
		||||
          gulong old_state;
 | 
			
		||||
          uint32_t old_state;
 | 
			
		||||
 | 
			
		||||
          if (!meta_prop_get_cardinal_with_atom_type (display, xwindow,
 | 
			
		||||
                                                      display->atom_WM_STATE,
 | 
			
		||||
@@ -2910,7 +2910,7 @@ meta_window_x11_new (MetaDisplay       *display,
 | 
			
		||||
  if (must_be_viewable && attrs.map_state != IsViewable)
 | 
			
		||||
    {
 | 
			
		||||
      /* Only manage if WM_STATE is IconicState or NormalState */
 | 
			
		||||
      gulong state;
 | 
			
		||||
      uint32_t state;
 | 
			
		||||
 | 
			
		||||
      /* WM_STATE isn't a cardinal, it's type WM_STATE, but is an int */
 | 
			
		||||
      if (!(meta_prop_get_cardinal_with_atom_type (display, xwindow,
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										507
									
								
								src/x11/xprops.c
									
									
									
									
									
								
							
							
						
						
									
										507
									
								
								src/x11/xprops.c
									
									
									
									
									
								
							@@ -78,17 +78,21 @@ from The Open Group.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "xprops.h"
 | 
			
		||||
#include <meta/errors.h>
 | 
			
		||||
#include "util-private.h"
 | 
			
		||||
#include "async-getprop.h"
 | 
			
		||||
#include "ui.h"
 | 
			
		||||
#include "mutter-Xatomtype.h"
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "window-private.h"
 | 
			
		||||
 | 
			
		||||
#include <X11/Xatom.h>
 | 
			
		||||
#include <X11/Xlib-xcb.h>
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
  MetaDisplay   *display;
 | 
			
		||||
@@ -168,13 +172,50 @@ validate_or_free_results (GetPropertyResults *results,
 | 
			
		||||
 | 
			
		||||
  if (results->prop)
 | 
			
		||||
    {
 | 
			
		||||
      XFree (results->prop);
 | 
			
		||||
      g_free (results->prop);
 | 
			
		||||
      results->prop = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xcb_get_property_cookie_t
 | 
			
		||||
async_get_property (xcb_connection_t *xcb_conn, Window xwindow,
 | 
			
		||||
                    Atom xatom, Atom required_type)
 | 
			
		||||
{
 | 
			
		||||
  return xcb_get_property (xcb_conn, False, xwindow,
 | 
			
		||||
                           xatom, required_type, 0, G_MAXUINT32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
async_get_property_finish (xcb_connection_t          *xcb_conn,
 | 
			
		||||
                           xcb_get_property_cookie_t  cookie,
 | 
			
		||||
                           GetPropertyResults        *results)
 | 
			
		||||
{
 | 
			
		||||
  xcb_get_property_reply_t *reply;
 | 
			
		||||
  xcb_generic_error_t *error;
 | 
			
		||||
 | 
			
		||||
  reply = xcb_get_property_reply (xcb_conn, cookie, &error);
 | 
			
		||||
  if (error)
 | 
			
		||||
    {
 | 
			
		||||
      free (error);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  results->n_items = reply->value_len;
 | 
			
		||||
  results->type = reply->type;
 | 
			
		||||
  results->bytes_after = reply->bytes_after;
 | 
			
		||||
  results->format = reply->format;
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
  if (results->type != None)
 | 
			
		||||
    results->prop = g_memdup (xcb_get_property_value (reply),
 | 
			
		||||
                              xcb_get_property_value_length (reply));
 | 
			
		||||
 | 
			
		||||
  free (reply);
 | 
			
		||||
  return (results->prop != NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
get_property (MetaDisplay        *display,
 | 
			
		||||
              Window              xwindow,
 | 
			
		||||
@@ -182,6 +223,9 @@ get_property (MetaDisplay        *display,
 | 
			
		||||
              Atom                req_type,
 | 
			
		||||
              GetPropertyResults *results)
 | 
			
		||||
{
 | 
			
		||||
  xcb_get_property_cookie_t cookie;
 | 
			
		||||
  xcb_connection_t *xcb_conn = XGetXCBConnection (display->xdisplay);
 | 
			
		||||
 | 
			
		||||
  results->display = display;
 | 
			
		||||
  results->xwindow = xwindow;
 | 
			
		||||
  results->xatom = xatom;
 | 
			
		||||
@@ -191,87 +235,37 @@ get_property (MetaDisplay        *display,
 | 
			
		||||
  results->bytes_after = 0;
 | 
			
		||||
  results->format = 0;
 | 
			
		||||
 | 
			
		||||
  meta_error_trap_push (display);
 | 
			
		||||
  if (XGetWindowProperty (display->xdisplay, xwindow, xatom,
 | 
			
		||||
                          0, G_MAXLONG,
 | 
			
		||||
                          False, req_type, &results->type, &results->format,
 | 
			
		||||
                          &results->n_items,
 | 
			
		||||
                          &results->bytes_after,
 | 
			
		||||
                          &results->prop) != Success ||
 | 
			
		||||
      results->type == None)
 | 
			
		||||
    {
 | 
			
		||||
      if (results->prop)
 | 
			
		||||
        XFree (results->prop);
 | 
			
		||||
      meta_error_trap_pop_with_return (display);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (meta_error_trap_pop_with_return (display) != Success)
 | 
			
		||||
    {
 | 
			
		||||
      if (results->prop)
 | 
			
		||||
        XFree (results->prop);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
  cookie = async_get_property (xcb_conn, xwindow, xatom, req_type);
 | 
			
		||||
  return async_get_property_finish (xcb_conn, cookie, results);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
atom_list_from_results (GetPropertyResults *results,
 | 
			
		||||
                        Atom              **atoms_p,
 | 
			
		||||
                        uint32_t          **atoms_p,
 | 
			
		||||
                        int                *n_atoms_p)
 | 
			
		||||
{
 | 
			
		||||
  if (!validate_or_free_results (results, 32, XA_ATOM, FALSE))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *atoms_p = (Atom*) results->prop;
 | 
			
		||||
  *atoms_p = (uint32_t*) results->prop;
 | 
			
		||||
  *n_atoms_p = results->n_items;
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_prop_get_atom_list (MetaDisplay *display,
 | 
			
		||||
                         Window       xwindow,
 | 
			
		||||
                         Atom         xatom,
 | 
			
		||||
                         Atom       **atoms_p,
 | 
			
		||||
                         int         *n_atoms_p)
 | 
			
		||||
{
 | 
			
		||||
  GetPropertyResults results;
 | 
			
		||||
 | 
			
		||||
  *atoms_p = NULL;
 | 
			
		||||
  *n_atoms_p = 0;
 | 
			
		||||
 | 
			
		||||
  if (!get_property (display, xwindow, xatom, XA_ATOM,
 | 
			
		||||
                     &results))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return atom_list_from_results (&results, atoms_p, n_atoms_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
cardinal_list_from_results (GetPropertyResults *results,
 | 
			
		||||
                            gulong            **cardinals_p,
 | 
			
		||||
                            uint32_t          **cardinals_p,
 | 
			
		||||
                            int                *n_cardinals_p)
 | 
			
		||||
{
 | 
			
		||||
  if (!validate_or_free_results (results, 32, XA_CARDINAL, FALSE))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *cardinals_p = (gulong*) results->prop;
 | 
			
		||||
  *cardinals_p = (uint32_t *) results->prop;
 | 
			
		||||
  *n_cardinals_p = results->n_items;
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
#if GLIB_SIZEOF_LONG == 8
 | 
			
		||||
  /* Xlib sign-extends format=32 items, but we want them unsigned */
 | 
			
		||||
  {
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < *n_cardinals_p; i++)
 | 
			
		||||
      (*cardinals_p)[i] = (*cardinals_p)[i] & 0xffffffff;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -279,7 +273,7 @@ gboolean
 | 
			
		||||
meta_prop_get_cardinal_list (MetaDisplay *display,
 | 
			
		||||
                             Window       xwindow,
 | 
			
		||||
                             Atom         xatom,
 | 
			
		||||
                             gulong     **cardinals_p,
 | 
			
		||||
                             uint32_t   **cardinals_p,
 | 
			
		||||
                             int         *n_cardinals_p)
 | 
			
		||||
{
 | 
			
		||||
  GetPropertyResults results;
 | 
			
		||||
@@ -298,19 +292,11 @@ static gboolean
 | 
			
		||||
motif_hints_from_results (GetPropertyResults *results,
 | 
			
		||||
                          MotifWmHints      **hints_p)
 | 
			
		||||
{
 | 
			
		||||
  int real_size, max_size;
 | 
			
		||||
#define MAX_ITEMS sizeof (MotifWmHints)/sizeof (gulong)
 | 
			
		||||
 | 
			
		||||
  *hints_p = NULL;
 | 
			
		||||
 | 
			
		||||
  if (results->type == None || results->n_items <= 0)
 | 
			
		||||
    {
 | 
			
		||||
      meta_verbose ("Motif hints had unexpected type or n_items\n");
 | 
			
		||||
      if (results->prop)
 | 
			
		||||
        {
 | 
			
		||||
          XFree (results->prop);
 | 
			
		||||
          results->prop = NULL;
 | 
			
		||||
        }
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -318,26 +304,12 @@ motif_hints_from_results (GetPropertyResults *results,
 | 
			
		||||
   * MotifWmHints than the one we expect, apparently.  I'm not sure of
 | 
			
		||||
   * the history behind it. See bug #89841 for example.
 | 
			
		||||
   */
 | 
			
		||||
  *hints_p = ag_Xmalloc (sizeof (MotifWmHints));
 | 
			
		||||
  *hints_p = calloc (1, sizeof (MotifWmHints));
 | 
			
		||||
  if (*hints_p == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (results->prop)
 | 
			
		||||
        {
 | 
			
		||||
          XFree (results->prop);
 | 
			
		||||
          results->prop = NULL;
 | 
			
		||||
        }
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  real_size = results->n_items * sizeof (gulong);
 | 
			
		||||
  max_size = MAX_ITEMS * sizeof (gulong);
 | 
			
		||||
  memcpy (*hints_p, results->prop, MIN (real_size, max_size));
 | 
			
		||||
 | 
			
		||||
  if (results->prop)
 | 
			
		||||
    {
 | 
			
		||||
      XFree (results->prop);
 | 
			
		||||
      results->prop = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  memcpy(*hints_p, results->prop, MIN (sizeof (MotifWmHints),
 | 
			
		||||
                                       results->n_items * sizeof (uint32_t)));
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -367,8 +339,7 @@ latin1_string_from_results (GetPropertyResults *results,
 | 
			
		||||
  if (!validate_or_free_results (results, 8, XA_STRING, FALSE))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *str_p = (char*) results->prop;
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
  *str_p = g_strndup ((char *) results->prop, results->n_items);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
@@ -409,36 +380,17 @@ utf8_string_from_results (GetPropertyResults *results,
 | 
			
		||||
      meta_warning ("Property %s on window 0x%lx contained invalid UTF-8\n",
 | 
			
		||||
                    name, results->xwindow);
 | 
			
		||||
      meta_XFree (name);
 | 
			
		||||
      XFree (results->prop);
 | 
			
		||||
      g_free (results->prop);
 | 
			
		||||
      results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  *str_p = (char*) results->prop;
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
  *str_p = g_strndup ((char *) results->prop, results->n_items);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_prop_get_utf8_string (MetaDisplay *display,
 | 
			
		||||
                           Window       xwindow,
 | 
			
		||||
                           Atom         xatom,
 | 
			
		||||
                           char       **str_p)
 | 
			
		||||
{
 | 
			
		||||
  GetPropertyResults results;
 | 
			
		||||
 | 
			
		||||
  *str_p = NULL;
 | 
			
		||||
 | 
			
		||||
  if (!get_property (display, xwindow, xatom,
 | 
			
		||||
                     display->atom_UTF8_STRING,
 | 
			
		||||
                     &results))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return utf8_string_from_results (&results, str_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* this one freakishly returns g_malloc memory */
 | 
			
		||||
static gboolean
 | 
			
		||||
utf8_list_from_results (GetPropertyResults *results,
 | 
			
		||||
@@ -492,7 +444,7 @@ utf8_list_from_results (GetPropertyResults *results,
 | 
			
		||||
          meta_warning ("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n",
 | 
			
		||||
                        name, results->xwindow, i);
 | 
			
		||||
          meta_XFree (name);
 | 
			
		||||
          meta_XFree (results->prop);
 | 
			
		||||
          g_free (results->prop);
 | 
			
		||||
          results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
          g_strfreev (retval);
 | 
			
		||||
@@ -508,7 +460,7 @@ utf8_list_from_results (GetPropertyResults *results,
 | 
			
		||||
  *str_p = retval;
 | 
			
		||||
  *n_str_p = i;
 | 
			
		||||
 | 
			
		||||
  meta_XFree (results->prop);
 | 
			
		||||
  g_free (results->prop);
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
@@ -534,81 +486,6 @@ meta_prop_get_utf8_list (MetaDisplay   *display,
 | 
			
		||||
  return utf8_list_from_results (&results, str_p, n_str_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* this one freakishly returns g_malloc memory */
 | 
			
		||||
static gboolean
 | 
			
		||||
latin1_list_from_results (GetPropertyResults *results,
 | 
			
		||||
                        char             ***str_p,
 | 
			
		||||
                        int                *n_str_p)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  int n_strings;
 | 
			
		||||
  char **retval;
 | 
			
		||||
  const char *p;
 | 
			
		||||
 | 
			
		||||
  *str_p = NULL;
 | 
			
		||||
  *n_str_p = 0;
 | 
			
		||||
 | 
			
		||||
  if (!validate_or_free_results (results, 8, XA_STRING, FALSE))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  /* I'm not sure this is right, but I'm guessing the
 | 
			
		||||
   * property is nul-separated
 | 
			
		||||
   */
 | 
			
		||||
  i = 0;
 | 
			
		||||
  n_strings = 0;
 | 
			
		||||
  while (i < (int) results->n_items)
 | 
			
		||||
    {
 | 
			
		||||
      if (results->prop[i] == '\0')
 | 
			
		||||
        ++n_strings;
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (results->prop[results->n_items - 1] != '\0')
 | 
			
		||||
    ++n_strings;
 | 
			
		||||
 | 
			
		||||
  /* we're guaranteed that results->prop has a nul on the end
 | 
			
		||||
   * by XGetWindowProperty
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
  retval = g_new0 (char*, n_strings + 1);
 | 
			
		||||
 | 
			
		||||
  p = (char *)results->prop;
 | 
			
		||||
  i = 0;
 | 
			
		||||
  while (i < n_strings)
 | 
			
		||||
    {
 | 
			
		||||
      retval[i] = g_strdup (p);
 | 
			
		||||
 | 
			
		||||
      p = p + strlen (p) + 1;
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  *str_p = retval;
 | 
			
		||||
  *n_str_p = i;
 | 
			
		||||
 | 
			
		||||
  meta_XFree (results->prop);
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_prop_get_latin1_list (MetaDisplay   *display,
 | 
			
		||||
                           Window         xwindow,
 | 
			
		||||
                           Atom           xatom,
 | 
			
		||||
                           char        ***str_p,
 | 
			
		||||
                           int           *n_str_p)
 | 
			
		||||
{
 | 
			
		||||
  GetPropertyResults results;
 | 
			
		||||
 | 
			
		||||
  *str_p = NULL;
 | 
			
		||||
 | 
			
		||||
  if (!get_property (display, xwindow, xatom,
 | 
			
		||||
                     XA_STRING, &results))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return latin1_list_from_results (&results, str_p, n_str_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
meta_prop_set_utf8_string_hint (MetaDisplay *display,
 | 
			
		||||
                                Window xwindow,
 | 
			
		||||
@@ -631,7 +508,7 @@ window_from_results (GetPropertyResults *results,
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *window_p = *(Window*) results->prop;
 | 
			
		||||
  XFree (results->prop);
 | 
			
		||||
  g_free (results->prop);
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
@@ -647,7 +524,7 @@ counter_from_results (GetPropertyResults *results,
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *counter_p = *(XSyncCounter*) results->prop;
 | 
			
		||||
  XFree (results->prop);
 | 
			
		||||
  g_free (results->prop);
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
@@ -655,7 +532,7 @@ counter_from_results (GetPropertyResults *results,
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
counter_list_from_results (GetPropertyResults *results,
 | 
			
		||||
                           XSyncCounter      **counters_p,
 | 
			
		||||
                           uint32_t          **counters_p,
 | 
			
		||||
                           int                *n_counters_p)
 | 
			
		||||
{
 | 
			
		||||
  if (!validate_or_free_results (results, 32,
 | 
			
		||||
@@ -663,7 +540,7 @@ counter_list_from_results (GetPropertyResults *results,
 | 
			
		||||
                                 FALSE))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *counters_p = (XSyncCounter*) results->prop;
 | 
			
		||||
  *counters_p = (uint32_t *) results->prop;
 | 
			
		||||
  *n_counters_p = results->n_items;
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -691,7 +568,7 @@ gboolean
 | 
			
		||||
meta_prop_get_cardinal (MetaDisplay   *display,
 | 
			
		||||
                        Window         xwindow,
 | 
			
		||||
                        Atom           xatom,
 | 
			
		||||
                        gulong        *cardinal_p)
 | 
			
		||||
                        uint32_t      *cardinal_p)
 | 
			
		||||
{
 | 
			
		||||
  return meta_prop_get_cardinal_with_atom_type (display, xwindow, xatom,
 | 
			
		||||
                                                XA_CARDINAL, cardinal_p);
 | 
			
		||||
@@ -700,17 +577,13 @@ meta_prop_get_cardinal (MetaDisplay   *display,
 | 
			
		||||
static gboolean
 | 
			
		||||
cardinal_with_atom_type_from_results (GetPropertyResults *results,
 | 
			
		||||
                                      Atom                prop_type,
 | 
			
		||||
                                      gulong             *cardinal_p)
 | 
			
		||||
                                      uint32_t           *cardinal_p)
 | 
			
		||||
{
 | 
			
		||||
  if (!validate_or_free_results (results, 32, prop_type, TRUE))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  *cardinal_p = *(gulong*) results->prop;
 | 
			
		||||
#if GLIB_SIZEOF_LONG == 8
 | 
			
		||||
  /* Xlib sign-extends format=32 items, but we want them unsigned */
 | 
			
		||||
  *cardinal_p &= 0xffffffff;
 | 
			
		||||
#endif
 | 
			
		||||
  XFree (results->prop);
 | 
			
		||||
  *cardinal_p = *((uint32_t *) results->prop);
 | 
			
		||||
  g_free (results->prop);
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
@@ -721,7 +594,7 @@ meta_prop_get_cardinal_with_atom_type (MetaDisplay   *display,
 | 
			
		||||
                                       Window         xwindow,
 | 
			
		||||
                                       Atom           xatom,
 | 
			
		||||
                                       Atom           prop_type,
 | 
			
		||||
                                       gulong        *cardinal_p)
 | 
			
		||||
                                       uint32_t      *cardinal_p)
 | 
			
		||||
{
 | 
			
		||||
  GetPropertyResults results;
 | 
			
		||||
 | 
			
		||||
@@ -779,46 +652,6 @@ text_property_from_results (GetPropertyResults *results,
 | 
			
		||||
  return *utf8_str_p != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_prop_get_text_property (MetaDisplay   *display,
 | 
			
		||||
                             Window         xwindow,
 | 
			
		||||
                             Atom           xatom,
 | 
			
		||||
                             char         **utf8_str_p)
 | 
			
		||||
{
 | 
			
		||||
  GetPropertyResults results;
 | 
			
		||||
 | 
			
		||||
  if (!get_property (display, xwindow, xatom, AnyPropertyType,
 | 
			
		||||
                     &results))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return text_property_from_results (&results, utf8_str_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* From Xmd.h */
 | 
			
		||||
#ifndef cvtINT32toInt
 | 
			
		||||
#if SIZEOF_VOID_P == 8
 | 
			
		||||
#define cvtINT8toInt(val)   ((((unsigned int)val) & 0x00000080) ? (((unsigned int)val) | 0xffffffffffffff00) : ((unsigned int)val))
 | 
			
		||||
#define cvtINT16toInt(val)  ((((unsigned int)val) & 0x00008000) ? (((unsigned int)val) | 0xffffffffffff0000) : ((unsigned int)val))
 | 
			
		||||
#define cvtINT32toInt(val)  ((((unsigned int)val) & 0x80000000) ? (((unsigned int)val) | 0xffffffff00000000) : ((unsigned int)val))
 | 
			
		||||
#define cvtINT8toShort(val)  cvtINT8toInt(val)
 | 
			
		||||
#define cvtINT16toShort(val) cvtINT16toInt(val)
 | 
			
		||||
#define cvtINT32toShort(val) cvtINT32toInt(val)
 | 
			
		||||
#define cvtINT8toLong(val)  cvtINT8toInt(val)
 | 
			
		||||
#define cvtINT16toLong(val) cvtINT16toInt(val)
 | 
			
		||||
#define cvtINT32toLong(val) cvtINT32toInt(val)
 | 
			
		||||
#else
 | 
			
		||||
#define cvtINT8toInt(val) (val)
 | 
			
		||||
#define cvtINT16toInt(val) (val)
 | 
			
		||||
#define cvtINT32toInt(val) (val)
 | 
			
		||||
#define cvtINT8toShort(val) (val)
 | 
			
		||||
#define cvtINT16toShort(val) (val)
 | 
			
		||||
#define cvtINT32toShort(val) (val)
 | 
			
		||||
#define cvtINT8toLong(val) (val)
 | 
			
		||||
#define cvtINT16toLong(val) (val)
 | 
			
		||||
#define cvtINT32toLong(val) (val)
 | 
			
		||||
#endif /* SIZEOF_VOID_P == 8 */
 | 
			
		||||
#endif /* cvtINT32toInt() */
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
wm_hints_from_results (GetPropertyResults *results,
 | 
			
		||||
                       XWMHints          **hints_p)
 | 
			
		||||
@@ -838,23 +671,23 @@ wm_hints_from_results (GetPropertyResults *results,
 | 
			
		||||
                    (int) results->n_items, NumPropWMHintsElements - 1);
 | 
			
		||||
      if (results->prop)
 | 
			
		||||
        {
 | 
			
		||||
          XFree (results->prop);
 | 
			
		||||
          g_free (results->prop);
 | 
			
		||||
          results->prop = NULL;
 | 
			
		||||
        }
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  hints = ag_Xmalloc0 (sizeof (XWMHints));
 | 
			
		||||
  hints = calloc (1, sizeof (XWMHints));
 | 
			
		||||
 | 
			
		||||
  raw = (xPropWMHints*) results->prop;
 | 
			
		||||
 | 
			
		||||
  hints->flags = raw->flags;
 | 
			
		||||
  hints->input = (raw->input ? True : False);
 | 
			
		||||
  hints->initial_state = cvtINT32toInt (raw->initialState);
 | 
			
		||||
  hints->initial_state = raw->initialState;
 | 
			
		||||
  hints->icon_pixmap = raw->iconPixmap;
 | 
			
		||||
  hints->icon_window = raw->iconWindow;
 | 
			
		||||
  hints->icon_x = cvtINT32toInt (raw->iconX);
 | 
			
		||||
  hints->icon_y = cvtINT32toInt (raw->iconY);
 | 
			
		||||
  hints->icon_x = raw->iconX;
 | 
			
		||||
  hints->icon_y = raw->iconY;
 | 
			
		||||
  hints->icon_mask = raw->iconMask;
 | 
			
		||||
  if (results->n_items >= NumPropWMHintsElements)
 | 
			
		||||
    hints->window_group = raw->windowGroup;
 | 
			
		||||
@@ -863,7 +696,7 @@ wm_hints_from_results (GetPropertyResults *results,
 | 
			
		||||
 | 
			
		||||
  if (results->prop)
 | 
			
		||||
    {
 | 
			
		||||
      XFree (results->prop);
 | 
			
		||||
      g_free (results->prop);
 | 
			
		||||
      results->prop = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -872,23 +705,6 @@ wm_hints_from_results (GetPropertyResults *results,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_prop_get_wm_hints (MetaDisplay   *display,
 | 
			
		||||
                        Window         xwindow,
 | 
			
		||||
                        Atom           xatom,
 | 
			
		||||
                        XWMHints     **hints_p)
 | 
			
		||||
{
 | 
			
		||||
  GetPropertyResults results;
 | 
			
		||||
 | 
			
		||||
  *hints_p = NULL;
 | 
			
		||||
 | 
			
		||||
  if (!get_property (display, xwindow, xatom, XA_WM_HINTS,
 | 
			
		||||
                     &results))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return wm_hints_from_results (&results, hints_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
class_hint_from_results (GetPropertyResults *results,
 | 
			
		||||
                         XClassHint         *class_hint)
 | 
			
		||||
@@ -902,9 +718,9 @@ class_hint_from_results (GetPropertyResults *results,
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  len_name = strlen ((char *) results->prop);
 | 
			
		||||
  if (! (class_hint->res_name = ag_Xmalloc (len_name+1)))
 | 
			
		||||
  if (! (class_hint->res_name = malloc (len_name+1)))
 | 
			
		||||
    {
 | 
			
		||||
      XFree (results->prop);
 | 
			
		||||
      g_free (results->prop);
 | 
			
		||||
      results->prop = NULL;
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
@@ -916,41 +732,23 @@ class_hint_from_results (GetPropertyResults *results,
 | 
			
		||||
 | 
			
		||||
  len_class = strlen ((char *)results->prop + len_name + 1);
 | 
			
		||||
 | 
			
		||||
  if (! (class_hint->res_class = ag_Xmalloc(len_class+1)))
 | 
			
		||||
  if (! (class_hint->res_class = malloc(len_class+1)))
 | 
			
		||||
    {
 | 
			
		||||
      XFree(class_hint->res_name);
 | 
			
		||||
      class_hint->res_name = NULL;
 | 
			
		||||
      XFree (results->prop);
 | 
			
		||||
      g_free (results->prop);
 | 
			
		||||
      results->prop = NULL;
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  strcpy (class_hint->res_class, (char *)results->prop + len_name + 1);
 | 
			
		||||
 | 
			
		||||
  XFree (results->prop);
 | 
			
		||||
  g_free (results->prop);
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_prop_get_class_hint (MetaDisplay   *display,
 | 
			
		||||
                          Window         xwindow,
 | 
			
		||||
                          Atom           xatom,
 | 
			
		||||
                          XClassHint    *class_hint)
 | 
			
		||||
{
 | 
			
		||||
  GetPropertyResults results;
 | 
			
		||||
 | 
			
		||||
  class_hint->res_class = NULL;
 | 
			
		||||
  class_hint->res_name = NULL;
 | 
			
		||||
 | 
			
		||||
  if (!get_property (display, xwindow, xatom, XA_STRING,
 | 
			
		||||
                     &results))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return class_hint_from_results (&results, class_hint);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
size_hints_from_results (GetPropertyResults *results,
 | 
			
		||||
                         XSizeHints        **hints_p,
 | 
			
		||||
@@ -970,37 +768,36 @@ size_hints_from_results (GetPropertyResults *results,
 | 
			
		||||
 | 
			
		||||
  raw = (xPropSizeHints*) results->prop;
 | 
			
		||||
 | 
			
		||||
  hints = ag_Xmalloc (sizeof (XSizeHints));
 | 
			
		||||
  hints = malloc (sizeof (XSizeHints));
 | 
			
		||||
 | 
			
		||||
  /* XSizeHints misdeclares these as int instead of long */
 | 
			
		||||
  hints->flags = raw->flags;
 | 
			
		||||
  hints->x = cvtINT32toInt (raw->x);
 | 
			
		||||
  hints->y = cvtINT32toInt (raw->y);
 | 
			
		||||
  hints->width = cvtINT32toInt (raw->width);
 | 
			
		||||
  hints->height = cvtINT32toInt (raw->height);
 | 
			
		||||
  hints->min_width  = cvtINT32toInt (raw->minWidth);
 | 
			
		||||
  hints->min_height = cvtINT32toInt (raw->minHeight);
 | 
			
		||||
  hints->max_width  = cvtINT32toInt (raw->maxWidth);
 | 
			
		||||
  hints->max_height = cvtINT32toInt (raw->maxHeight);
 | 
			
		||||
  hints->width_inc  = cvtINT32toInt (raw->widthInc);
 | 
			
		||||
  hints->height_inc = cvtINT32toInt (raw->heightInc);
 | 
			
		||||
  hints->min_aspect.x = cvtINT32toInt (raw->minAspectX);
 | 
			
		||||
  hints->min_aspect.y = cvtINT32toInt (raw->minAspectY);
 | 
			
		||||
  hints->max_aspect.x = cvtINT32toInt (raw->maxAspectX);
 | 
			
		||||
  hints->max_aspect.y = cvtINT32toInt (raw->maxAspectY);
 | 
			
		||||
  hints->x = raw->x;
 | 
			
		||||
  hints->y = raw->y;
 | 
			
		||||
  hints->width = raw->width;
 | 
			
		||||
  hints->height = raw->height;
 | 
			
		||||
  hints->min_width  = raw->minWidth;
 | 
			
		||||
  hints->min_height = raw->minHeight;
 | 
			
		||||
  hints->max_width  = raw->maxWidth;
 | 
			
		||||
  hints->max_height = raw->maxHeight;
 | 
			
		||||
  hints->width_inc  = raw->widthInc;
 | 
			
		||||
  hints->height_inc = raw->heightInc;
 | 
			
		||||
  hints->min_aspect.x = raw->minAspectX;
 | 
			
		||||
  hints->min_aspect.y = raw->minAspectY;
 | 
			
		||||
  hints->max_aspect.x = raw->maxAspectX;
 | 
			
		||||
  hints->max_aspect.y = raw->maxAspectY;
 | 
			
		||||
 | 
			
		||||
  *flags_p = (USPosition | USSize | PAllHints);
 | 
			
		||||
  if (results->n_items >= NumPropSizeElements)
 | 
			
		||||
    {
 | 
			
		||||
      hints->base_width= cvtINT32toInt (raw->baseWidth);
 | 
			
		||||
      hints->base_height= cvtINT32toInt (raw->baseHeight);
 | 
			
		||||
      hints->win_gravity= cvtINT32toInt (raw->winGravity);
 | 
			
		||||
      hints->base_width = raw->baseWidth;
 | 
			
		||||
      hints->base_height = raw->baseHeight;
 | 
			
		||||
      hints->win_gravity = raw->winGravity;
 | 
			
		||||
      *flags_p |= (PBaseSize | PWinGravity);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  hints->flags &= (*flags_p);	/* get rid of unwanted bits */
 | 
			
		||||
 | 
			
		||||
  XFree (results->prop);
 | 
			
		||||
  g_free (results->prop);
 | 
			
		||||
  results->prop = NULL;
 | 
			
		||||
 | 
			
		||||
  *hints_p = hints;
 | 
			
		||||
@@ -1008,37 +805,6 @@ size_hints_from_results (GetPropertyResults *results,
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
meta_prop_get_size_hints (MetaDisplay   *display,
 | 
			
		||||
                          Window         xwindow,
 | 
			
		||||
                          Atom           xatom,
 | 
			
		||||
                          XSizeHints   **hints_p,
 | 
			
		||||
                          gulong        *flags_p)
 | 
			
		||||
{
 | 
			
		||||
  GetPropertyResults results;
 | 
			
		||||
 | 
			
		||||
  *hints_p = NULL;
 | 
			
		||||
  *flags_p = 0;
 | 
			
		||||
 | 
			
		||||
  if (!get_property (display, xwindow, xatom, XA_WM_SIZE_HINTS,
 | 
			
		||||
                     &results))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return size_hints_from_results (&results, hints_p, flags_p);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static AgGetPropertyTask*
 | 
			
		||||
get_task (MetaDisplay        *display,
 | 
			
		||||
          Window              xwindow,
 | 
			
		||||
          Atom                xatom,
 | 
			
		||||
          Atom                req_type)
 | 
			
		||||
{
 | 
			
		||||
  return ag_task_create (display->xdisplay,
 | 
			
		||||
                         xwindow,
 | 
			
		||||
                         xatom, 0, G_MAXLONG,
 | 
			
		||||
                         False, req_type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char*
 | 
			
		||||
latin1_to_utf8 (const char *text)
 | 
			
		||||
{
 | 
			
		||||
@@ -1064,7 +830,8 @@ meta_prop_get_values (MetaDisplay   *display,
 | 
			
		||||
                      int            n_values)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  AgGetPropertyTask **tasks;
 | 
			
		||||
  xcb_get_property_cookie_t *tasks;
 | 
			
		||||
  xcb_connection_t *xcb_conn = XGetXCBConnection (display->xdisplay);
 | 
			
		||||
 | 
			
		||||
  meta_verbose ("Requesting %d properties of 0x%lx at once\n",
 | 
			
		||||
                n_values, xwindow);
 | 
			
		||||
@@ -1072,7 +839,7 @@ meta_prop_get_values (MetaDisplay   *display,
 | 
			
		||||
  if (n_values == 0)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  tasks = g_new0 (AgGetPropertyTask*, n_values);
 | 
			
		||||
  tasks = g_new0 (xcb_get_property_cookie_t, n_values);
 | 
			
		||||
 | 
			
		||||
  /* Start up tasks. The "values" array can have values
 | 
			
		||||
   * with atom == None, which means to ignore that element.
 | 
			
		||||
@@ -1132,9 +899,7 @@ meta_prop_get_values (MetaDisplay   *display,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      if (values[i].atom != None)
 | 
			
		||||
        tasks[i] = get_task (display, xwindow,
 | 
			
		||||
                             values[i].atom, values[i].required_type);
 | 
			
		||||
 | 
			
		||||
        tasks[i] = async_get_property (xcb_conn, xwindow, values[i].atom, values[i].required_type);
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1147,10 +912,11 @@ meta_prop_get_values (MetaDisplay   *display,
 | 
			
		||||
  i = 0;
 | 
			
		||||
  while (i < n_values)
 | 
			
		||||
    {
 | 
			
		||||
      AgGetPropertyTask *task;
 | 
			
		||||
      GetPropertyResults results;
 | 
			
		||||
 | 
			
		||||
      if (tasks[i] == NULL)
 | 
			
		||||
      /* We're relying on the fact that sequence numbers can never be zero
 | 
			
		||||
       * in Xorg. This is a bit disgusting... */
 | 
			
		||||
      if (tasks[i].sequence == 0)
 | 
			
		||||
        {
 | 
			
		||||
          /* Probably values[i].type was None, or ag_task_create()
 | 
			
		||||
           * returned NULL.
 | 
			
		||||
@@ -1159,10 +925,6 @@ meta_prop_get_values (MetaDisplay   *display,
 | 
			
		||||
          goto next;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
      task = ag_get_next_completed_task (display->xdisplay);
 | 
			
		||||
      g_assert (task != NULL);
 | 
			
		||||
      g_assert (ag_task_have_reply (task));
 | 
			
		||||
 | 
			
		||||
      results.display = display;
 | 
			
		||||
      results.xwindow = xwindow;
 | 
			
		||||
      results.xatom = values[i].atom;
 | 
			
		||||
@@ -1172,19 +934,9 @@ meta_prop_get_values (MetaDisplay   *display,
 | 
			
		||||
      results.bytes_after = 0;
 | 
			
		||||
      results.format = 0;
 | 
			
		||||
 | 
			
		||||
      if (ag_task_get_reply_and_free (task,
 | 
			
		||||
                                      &results.type, &results.format,
 | 
			
		||||
                                      &results.n_items,
 | 
			
		||||
                                      &results.bytes_after,
 | 
			
		||||
                                      &results.prop) != Success ||
 | 
			
		||||
          results.type == None)
 | 
			
		||||
      if (!async_get_property_finish (xcb_conn, tasks[i], &results))
 | 
			
		||||
        {
 | 
			
		||||
          values[i].type = META_PROP_VALUE_INVALID;
 | 
			
		||||
          if (results.prop)
 | 
			
		||||
            {
 | 
			
		||||
              XFree (results.prop);
 | 
			
		||||
              results.prop = NULL;
 | 
			
		||||
            }
 | 
			
		||||
          goto next;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1216,18 +968,9 @@ meta_prop_get_values (MetaDisplay   *display,
 | 
			
		||||
          else
 | 
			
		||||
            {
 | 
			
		||||
              char *new_str;
 | 
			
		||||
              char *xmalloc_new_str;
 | 
			
		||||
 | 
			
		||||
              new_str = latin1_to_utf8 (values[i].v.str);
 | 
			
		||||
              xmalloc_new_str = ag_Xmalloc (strlen (new_str) + 1);
 | 
			
		||||
              if (xmalloc_new_str != NULL)
 | 
			
		||||
                {
 | 
			
		||||
                  strcpy (xmalloc_new_str, new_str);
 | 
			
		||||
                  meta_XFree (values[i].v.str);
 | 
			
		||||
                  values[i].v.str = xmalloc_new_str;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
              g_free (new_str);
 | 
			
		||||
              free (values[i].v.str);
 | 
			
		||||
              values[i].v.str = new_str;
 | 
			
		||||
            }
 | 
			
		||||
          break;
 | 
			
		||||
        case META_PROP_VALUE_MOTIF_HINTS:
 | 
			
		||||
@@ -1305,42 +1048,44 @@ free_value (MetaPropValue *value)
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_UTF8:
 | 
			
		||||
    case META_PROP_VALUE_STRING:
 | 
			
		||||
      free (value->v.str);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_STRING_AS_UTF8:
 | 
			
		||||
      meta_XFree (value->v.str);
 | 
			
		||||
      g_free (value->v.str);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_MOTIF_HINTS:
 | 
			
		||||
      meta_XFree (value->v.motif_hints);
 | 
			
		||||
      free (value->v.motif_hints);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_CARDINAL:
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_WINDOW:
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_ATOM_LIST:
 | 
			
		||||
      meta_XFree (value->v.atom_list.atoms);
 | 
			
		||||
      free (value->v.atom_list.atoms);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_TEXT_PROPERTY:
 | 
			
		||||
      meta_XFree (value->v.str);
 | 
			
		||||
      free (value->v.str);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_WM_HINTS:
 | 
			
		||||
      meta_XFree (value->v.wm_hints);
 | 
			
		||||
      free (value->v.wm_hints);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_CLASS_HINT:
 | 
			
		||||
      meta_XFree (value->v.class_hint.res_class);
 | 
			
		||||
      meta_XFree (value->v.class_hint.res_name);
 | 
			
		||||
      free (value->v.class_hint.res_class);
 | 
			
		||||
      free (value->v.class_hint.res_name);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_SIZE_HINTS:
 | 
			
		||||
      meta_XFree (value->v.size_hints.hints);
 | 
			
		||||
      free (value->v.size_hints.hints);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_UTF8_LIST:
 | 
			
		||||
      g_strfreev (value->v.string_list.strings);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_CARDINAL_LIST:
 | 
			
		||||
      meta_XFree (value->v.cardinal_list.cardinals);
 | 
			
		||||
      free (value->v.cardinal_list.cardinals);
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_SYNC_COUNTER:
 | 
			
		||||
      break;
 | 
			
		||||
    case META_PROP_VALUE_SYNC_COUNTER_LIST:
 | 
			
		||||
      meta_XFree (value->v.xcounter_list.counters);
 | 
			
		||||
      free (value->v.xcounter_list.counters);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -33,11 +33,11 @@
 | 
			
		||||
 * found in some Motif reference guides online.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    unsigned long flags;
 | 
			
		||||
    unsigned long functions;
 | 
			
		||||
    unsigned long decorations;
 | 
			
		||||
    long input_mode;
 | 
			
		||||
    unsigned long status;
 | 
			
		||||
    uint32_t flags;
 | 
			
		||||
    uint32_t functions;
 | 
			
		||||
    uint32_t decorations;
 | 
			
		||||
    uint32_t input_mode;
 | 
			
		||||
    uint32_t status;
 | 
			
		||||
} MotifWmHints, MwmHints;
 | 
			
		||||
 | 
			
		||||
#define MWM_HINTS_FUNCTIONS     (1L << 0)
 | 
			
		||||
@@ -71,11 +71,6 @@ typedef struct {
 | 
			
		||||
/* These all return the memory from Xlib, so require an XFree()
 | 
			
		||||
 * when they return TRUE. They return TRUE on success.
 | 
			
		||||
 */
 | 
			
		||||
gboolean meta_prop_get_atom_list     (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      Atom         **atoms_p,
 | 
			
		||||
                                      int           *n_atoms_p);
 | 
			
		||||
gboolean meta_prop_get_motif_hints   (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
@@ -83,26 +78,17 @@ gboolean meta_prop_get_motif_hints   (MetaDisplay   *display,
 | 
			
		||||
gboolean meta_prop_get_cardinal_list (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      gulong       **cardinals_p,
 | 
			
		||||
                                      uint32_t     **cardinals_p,
 | 
			
		||||
                                      int           *n_cardinals_p);
 | 
			
		||||
gboolean meta_prop_get_latin1_string (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      char         **str_p);
 | 
			
		||||
gboolean meta_prop_get_utf8_string   (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      char         **str_p);
 | 
			
		||||
gboolean meta_prop_get_utf8_list     (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      char        ***str_p,
 | 
			
		||||
                                      int           *n_str_p);
 | 
			
		||||
gboolean meta_prop_get_latin1_list   (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      char        ***str_p,
 | 
			
		||||
                                      int           *n_str_p);
 | 
			
		||||
void     meta_prop_set_utf8_string_hint
 | 
			
		||||
                                     (MetaDisplay *display,
 | 
			
		||||
                                      Window xwindow,
 | 
			
		||||
@@ -115,32 +101,12 @@ gboolean meta_prop_get_window        (MetaDisplay   *display,
 | 
			
		||||
gboolean meta_prop_get_cardinal      (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      gulong        *cardinal_p);
 | 
			
		||||
                                      uint32_t      *cardinal_p);
 | 
			
		||||
gboolean meta_prop_get_cardinal_with_atom_type (MetaDisplay   *display,
 | 
			
		||||
                                                Window         xwindow,
 | 
			
		||||
                                                Atom           xatom,
 | 
			
		||||
                                                Atom           prop_type,
 | 
			
		||||
                                                gulong        *cardinal_p);
 | 
			
		||||
gboolean meta_prop_get_text_property (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      char         **utf8_str_p);
 | 
			
		||||
 | 
			
		||||
gboolean meta_prop_get_wm_hints      (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      XWMHints     **hints_p);
 | 
			
		||||
 | 
			
		||||
gboolean meta_prop_get_class_hint    (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      XClassHint    *class_hint);
 | 
			
		||||
 | 
			
		||||
gboolean meta_prop_get_size_hints    (MetaDisplay   *display,
 | 
			
		||||
                                      Window         xwindow,
 | 
			
		||||
                                      Atom           xatom,
 | 
			
		||||
                                      XSizeHints   **hints_p,
 | 
			
		||||
                                      gulong        *flags_p);
 | 
			
		||||
                                                uint32_t      *cardinal_p);
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
@@ -174,14 +140,14 @@ typedef struct
 | 
			
		||||
    char *str;
 | 
			
		||||
    MotifWmHints *motif_hints;
 | 
			
		||||
    Window xwindow;
 | 
			
		||||
    gulong cardinal;
 | 
			
		||||
    uint32_t cardinal;
 | 
			
		||||
    XWMHints *wm_hints;
 | 
			
		||||
    XClassHint class_hint;
 | 
			
		||||
    XSyncCounter xcounter;
 | 
			
		||||
    struct
 | 
			
		||||
    {
 | 
			
		||||
      gulong *counters;
 | 
			
		||||
      int     n_counters;
 | 
			
		||||
      uint32_t *counters;
 | 
			
		||||
      int       n_counters;
 | 
			
		||||
    } xcounter_list;
 | 
			
		||||
 | 
			
		||||
    struct
 | 
			
		||||
@@ -192,8 +158,8 @@ typedef struct
 | 
			
		||||
 | 
			
		||||
    struct
 | 
			
		||||
    {
 | 
			
		||||
      gulong *cardinals;
 | 
			
		||||
      int     n_cardinals;
 | 
			
		||||
      uint32_t *cardinals;
 | 
			
		||||
      int       n_cardinals;
 | 
			
		||||
    } cardinal_list;
 | 
			
		||||
 | 
			
		||||
    struct
 | 
			
		||||
@@ -204,8 +170,8 @@ typedef struct
 | 
			
		||||
 | 
			
		||||
    struct
 | 
			
		||||
    {
 | 
			
		||||
      Atom *atoms;
 | 
			
		||||
      int   n_atoms;
 | 
			
		||||
      uint32_t *atoms;
 | 
			
		||||
      int       n_atoms;
 | 
			
		||||
    } atom_list;
 | 
			
		||||
 | 
			
		||||
  } v;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user