Compare commits
246 Commits
3.16.1.1
...
wip/fullsc
Author | SHA1 | Date | |
---|---|---|---|
88e466f8a8 | |||
377ecdb864 | |||
d7f544f42e | |||
1ab8b854df | |||
ae7aabd5de | |||
b975676c5d | |||
86d8c3954f | |||
54557f062e | |||
130807a308 | |||
e84f694668 | |||
b18542f2b6 | |||
da0aac665f | |||
8b0b0cf028 | |||
6f64d6b0aa | |||
ebeca983c7 | |||
cf88675807 | |||
405f1ce3d0 | |||
6190ae3873 | |||
69c267b142 | |||
9abc071283 | |||
a9df4bb81a | |||
bc9e63d3db | |||
5b5ceede2b | |||
4e63c95c02 | |||
67d3a7a2d7 | |||
bc00f118f3 | |||
5801b5518f | |||
25a796afc6 | |||
27b37407d0 | |||
e23e697043 | |||
35729e8659 | |||
dc7e665de9 | |||
2e3bfd1a11 | |||
b7aca07844 | |||
dc780d2c44 | |||
c49b284643 | |||
0373b854c1 | |||
5d837a5c85 | |||
79c86ae890 | |||
7c7cf91c32 | |||
e407f5bbae | |||
8900bd2f5c | |||
83c17134f1 | |||
8e5fb03611 | |||
dece49b53d | |||
443d579d40 | |||
5066eaf691 | |||
6ea7fa9973 | |||
79f755bf0f | |||
1845bfe1b6 | |||
8e22bf5bc9 | |||
c13ddafdb8 | |||
94513726de | |||
0aa4c4d43e | |||
e3db4ab16a | |||
614d6bd0f8 | |||
1d56d50fcd | |||
0ffd4254d9 | |||
36eee04a21 | |||
d3fdaa3232 | |||
165050f8f9 | |||
68279e8a08 | |||
cd1ce2cb0a | |||
b01f95cfdd | |||
4b667d1e09 | |||
fe8454d13f | |||
53a6d16891 | |||
e76c3ecb00 | |||
637be80c86 | |||
975feb9202 | |||
a5417ebee1 | |||
b64b159109 | |||
804ab7894f | |||
299ed424d3 | |||
55692b4019 | |||
2fafa24305 | |||
51a2f28723 | |||
e11feb229b | |||
1ee387bb31 | |||
cba2ab445e | |||
038f828ab1 | |||
4dc5882777 | |||
b0b08d5010 | |||
070cd27786 | |||
9df6cda3e3 | |||
39763d4add | |||
352cac3850 | |||
9c745105f8 | |||
ab9dabe725 | |||
7ce06928e2 | |||
ac79988939 | |||
a43a2af18b | |||
07f533f617 | |||
10504b0fdc | |||
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 | |||
cff5ef0ec2 | |||
d478d8f143 | |||
7eca43cec9 | |||
9060190555 | |||
0de3869656 | |||
9f13033f15 | |||
48bf807430 | |||
c68e43a97f | |||
cc53d48fa8 | |||
ca6e799b97 | |||
0f8e387dc0 | |||
d62c595e51 | |||
dd3cf94744 | |||
eb56e0a3d7 | |||
8937c32cd5 | |||
a8a5da768a | |||
33bfcf56ce | |||
40cccb58a5 | |||
eb6c70137b | |||
df3b412a25 | |||
cfba0a5dfc | |||
3561b46fc6 | |||
8dfb88b669 | |||
2e3086e2aa |
8
.gitignore
vendored
8
.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]
|
||||
@ -68,6 +66,8 @@ src/gtk-shell-protocol.c
|
||||
src/gtk-shell-server-protocol.h
|
||||
src/xdg-shell-protocol.c
|
||||
src/xdg-shell-server-protocol.h
|
||||
src/pointer-gestures-protocol.c
|
||||
src/pointer-gestures-server-protocol.h
|
||||
src/xserver-protocol.c
|
||||
src/xserver-server-protocol.h
|
||||
src/meta/meta-version.h
|
||||
|
@ -9,5 +9,3 @@ DISTCLEANFILES = \
|
||||
intltool-update \
|
||||
po/stamp-it \
|
||||
po/.intltool-merge-cache
|
||||
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
||||
|
101
NEWS
101
NEWS
@ -1,3 +1,104 @@
|
||||
3.18.0
|
||||
======
|
||||
* Misc. fixes [Florian, Jonas; #753434]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Florian Müllner
|
||||
|
||||
Translations:
|
||||
Rūdolfs Mazurs [lv]
|
||||
|
||||
3.17.92
|
||||
=======
|
||||
* Don't omit the background color for backgrounds that don't fill the screen
|
||||
[Ray; #754476]
|
||||
* Fix up key state on FocusIn when running nested [Owen; #753948]
|
||||
* Find the right DRM device instead of hardcoding card0 [Marek; #753434]
|
||||
* Scale cursor on HiDPI screens [Jonas; #744932]
|
||||
* Misc. fixes and cleanups [Lan, Jonas, Javier, Olivier; #754545, #754215,
|
||||
#754621, #754715]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Marek Chalupa, Olivier Fourdan, Javier Jardón, Ting-Wei Lan,
|
||||
Ray Strode, Owen W. Taylor
|
||||
|
||||
3.17.91
|
||||
=======
|
||||
* Send error on pointer-gesture protocol version mismatch [Jonas; #753855]
|
||||
* Misc. cleanups [Jonas; #744932]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl
|
||||
|
||||
Translations:
|
||||
Chao-Hsiung Liao [zh_TW], Piotr Drąg [pl]
|
||||
|
||||
3.17.90
|
||||
=======
|
||||
* Fix glitch with some fullscreen apps [Rui; #753020]
|
||||
* Fix screen update issue with NVidia driver [Aaron, Rui; #728464]
|
||||
* Only call frame callbacks for surfaces that get drawn [Adel; #739163]
|
||||
* Misc. bug fixes and cleanups [Jonas, Rui, Ting-Wei; #753222, #752753, #753237,
|
||||
#753380, #744104, #744932]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Adel Gadllah, Carlos Garnacho, Ting-Wei Lan, Rui Matos,
|
||||
Florian Müllner, Aaron Plattner, Jasper St. Pierre
|
||||
|
||||
Translations:
|
||||
Akom Chotiphantawanon [th]
|
||||
|
||||
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]
|
||||
* Apply the right settings to the right input devices [Carlos; #747886]
|
||||
* Fix scroll button setting [Ondrej; #747967]
|
||||
* Add support for modal hint on wayland [Jonas; #745720]
|
||||
* Don't reset idle time for non-hardware events [Rui; #748541]
|
||||
* Misc. bug fixes [Ray, Rui; #748380, #748478]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Carlos Garnacho, Ondrej Holy, Rui Matos, Florian Müllner,
|
||||
Jasper St. Pierre, Ray Strode, Tomeu Vizoso
|
||||
|
||||
3.16.1
|
||||
======
|
||||
* Add function to refresh all background instances [Rui; #739178]
|
||||
|
28
configure.ac
28
configure.ac
@ -1,8 +1,8 @@
|
||||
AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [16])
|
||||
m4_define([mutter_micro_version], [1])
|
||||
m4_define([mutter_minor_version], [18])
|
||||
m4_define([mutter_micro_version], [0])
|
||||
|
||||
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
|
||||
|
||||
@ -76,7 +63,7 @@ MUTTER_PC_MODULES="
|
||||
pango >= 1.2.0
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.15.92
|
||||
$CLUTTER_PACKAGE >= 1.21.3
|
||||
$CLUTTER_PACKAGE >= 1.23.4
|
||||
cogl-1.0 >= 1.17.1
|
||||
upower-glib >= 0.99.0
|
||||
gnome-desktop-3.0
|
||||
@ -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,7 +319,10 @@ if test "x$enable_debug" = "xyes"; then
|
||||
CFLAGS="$CFLAGS -g -O"
|
||||
fi
|
||||
|
||||
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
|
||||
AC_CHECK_DECL([GL_EXT_x11_sync_object],
|
||||
[],
|
||||
[AC_MSG_ERROR([GL_EXT_x11_sync_object definition not found, please update your GL headers])],
|
||||
[#include <GL/glx.h>])
|
||||
|
||||
#### Warnings (last since -Werror can disturb other tests)
|
||||
|
||||
@ -403,8 +395,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"
|
||||
|
51
po/pl.po
51
po/pl.po
@ -15,8 +15,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-03-05 00:23+0100\n"
|
||||
"PO-Revision-Date: 2015-03-05 00:24+0100\n"
|
||||
"POT-Creation-Date: 2015-08-26 18:49+0200\n"
|
||||
"PO-Revision-Date: 2015-08-26 18:50+0200\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Polish <gnomepl@aviary.pl>\n"
|
||||
"Language: pl\n"
|
||||
@ -285,9 +285,9 @@ msgid ""
|
||||
"\"Windows key\" on PC hardware. It's expected that this binding either the "
|
||||
"default or set to the empty string."
|
||||
msgstr ""
|
||||
"Ten klawisz inicjuje tryb \"overlay\", który jest połączeniem podglądu okien "
|
||||
"i systemu uruchamiania programów. Domyślnie jest przeznaczony do powiązania "
|
||||
"z klawiszem \"Windows\" na komputerach typu PC. Ustawienie tego powiązania "
|
||||
"Ten klawisz inicjuje tryb „overlay”, który jest połączeniem podglądu okien i "
|
||||
"systemu uruchamiania programów. Domyślnie jest przeznaczony do powiązania z "
|
||||
"klawiszem „Windows” na komputerach typu PC. Ustawienie tego powiązania "
|
||||
"powinno być domyślne lub puste."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:3
|
||||
@ -300,9 +300,9 @@ msgid ""
|
||||
"attached to the titlebar of the parent window and are moved together with "
|
||||
"the parent window."
|
||||
msgstr ""
|
||||
"Jeśli wynosi \"true\", to modalne okna dialogowe pojawiają się dołączone do "
|
||||
"paska tytułowego okna nadrzędnego zamiast posiadać oddzielne paski tytułowe "
|
||||
"i są przenoszone razem z nim."
|
||||
"Jeśli wynosi wartość „true”, to modalne okna dialogowe pojawiają się "
|
||||
"dołączone do paska tytułowego okna nadrzędnego zamiast posiadać oddzielne "
|
||||
"paski tytułowe i są przenoszone razem z nim."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:5
|
||||
msgid "Enable edge tiling when dropping windows on screen edges"
|
||||
@ -332,7 +332,7 @@ msgid ""
|
||||
"gnome.desktop.wm.preferences)."
|
||||
msgstr ""
|
||||
"Określa, czy obszary robocze są zarządzane dynamicznie, czy istnieje "
|
||||
"statyczna liczba obszarów (określona przez klucz \"num-workspaces\" w org."
|
||||
"statyczna liczba obszarów (określona przez klucz „num-workspaces” w org."
|
||||
"gnome.desktop.wm.preferences)."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
|
||||
@ -369,9 +369,9 @@ msgid ""
|
||||
"the focus will not be changed immediately when entering a window, but only "
|
||||
"after the pointer stops moving."
|
||||
msgstr ""
|
||||
"Jeśli jest ustawione na wartość \"true\", a tryb aktywności to \"sloppy\" "
|
||||
"lub \"mouse\", to aktywność nie będzie zmieniana od razu po przejściu do "
|
||||
"okna, ale dopiero po zatrzymaniu ruchu kursora."
|
||||
"Jeśli jest ustawione na wartość „true”, a tryb aktywności to „sloppy” lub "
|
||||
"„mouse”, to aktywność nie będzie zmieniana od razu po przejściu do okna, ale "
|
||||
"dopiero po zatrzymaniu ruchu kursora."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
|
||||
msgid "Draggable border width"
|
||||
@ -409,7 +409,7 @@ msgid ""
|
||||
"When true, the new windows will always be put in the center of the active "
|
||||
"screen of the monitor."
|
||||
msgstr ""
|
||||
"Jeśli wynosi \"true\", to nowe okna będą zawsze umieszczane na środku "
|
||||
"Jeśli wynosi wartość „true”, to nowe okna będą zawsze umieszczane na środku "
|
||||
"aktywnego ekranu monitora."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
|
||||
@ -468,22 +468,22 @@ msgstr "Przełączenie na 11. konsolę wirtualną"
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "Przełączenie na 12. konsolę wirtualną"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:364
|
||||
#: ../src/backends/meta-monitor-manager.c:500
|
||||
msgid "Built-in display"
|
||||
msgstr "Wbudowany ekran"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:391
|
||||
#: ../src/backends/meta-monitor-manager.c:526
|
||||
msgid "Unknown"
|
||||
msgstr "Nieznany"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:393
|
||||
#: ../src/backends/meta-monitor-manager.c:528
|
||||
msgid "Unknown Display"
|
||||
msgstr "Nieznany ekran"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:401
|
||||
#: ../src/backends/meta-monitor-manager.c:536
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
@ -496,7 +496,7 @@ msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
"\"."
|
||||
msgstr ""
|
||||
"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu \"%s\"."
|
||||
"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu „%s”."
|
||||
|
||||
#: ../src/core/bell.c:185
|
||||
msgid "Bell event"
|
||||
@ -505,7 +505,7 @@ msgstr "Zdarzenie sygnału dźwiękowego"
|
||||
#: ../src/core/delete.c:127
|
||||
#, c-format
|
||||
msgid "“%s” is not responding."
|
||||
msgstr "Okno \"%s\" nie odpowiada."
|
||||
msgstr "Okno „%s” nie odpowiada."
|
||||
|
||||
#: ../src/core/delete.c:129
|
||||
msgid "Application is not responding."
|
||||
@ -525,11 +525,10 @@ msgstr "_Czekaj"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Zakończ"
|
||||
|
||||
#: ../src/core/display.c:562
|
||||
#: ../src/core/display.c:563
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr ""
|
||||
"Otwarcie połączenia z ekranem \"%s\" systemu X Window się nie powiodło\n"
|
||||
msgstr "Otwarcie połączenia z ekranem „%s” systemu X Window się nie powiodło\n"
|
||||
|
||||
#: ../src/core/main.c:176
|
||||
msgid "Disable connection to session manager"
|
||||
@ -573,7 +572,7 @@ msgid ""
|
||||
"PARTICULAR PURPOSE.\n"
|
||||
msgstr ""
|
||||
"mutter %s\n"
|
||||
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., oraz inni\n"
|
||||
"Copyright (C) 2001—%d Havoc Pennington, Red Hat, Inc., oraz inni\n"
|
||||
"Niniejszy program jest wolnym oprogramowaniem, aby poznać warunki, pod\n"
|
||||
"jakimi dopuszczalne jest kopiowanie programu, zajrzyj do jego źródeł.\n"
|
||||
"Na program nie udziela się ŻADNYCH GWARANCJI, nawet domyślnej gwarancji\n"
|
||||
@ -598,13 +597,13 @@ msgid ""
|
||||
"Display \"%s\" already has a window manager; try using the --replace option "
|
||||
"to replace the current window manager."
|
||||
msgstr ""
|
||||
"Na ekranie \"%s\" działa już menedżer okien. Aby zastąpić działającego "
|
||||
"Na ekranie „%s” działa już menedżer okien. Aby zastąpić działającego "
|
||||
"menedżera okien, proszę spróbować użyć opcji --replace."
|
||||
|
||||
#: ../src/core/screen.c:607
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Podekran %d ekranu \"%s\" jest nieprawidłowy\n"
|
||||
msgstr "Podekran %d ekranu „%s” jest nieprawidłowy\n"
|
||||
|
||||
#: ../src/core/util.c:118
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
@ -616,7 +615,7 @@ msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
"be restarted manually next time you log in."
|
||||
msgstr ""
|
||||
"Te okna nie obsługują opcji zapisu obecnego stanu (\"save current setup\"), "
|
||||
"Te okna nie obsługują opcji zapisu obecnego stanu („save current setup”), "
|
||||
"więc przy następnym zalogowaniu będą musiały zostać uruchomione ręcznie."
|
||||
|
||||
#: ../src/x11/window-props.c:549
|
||||
|
20
po/zh_TW.po
20
po/zh_TW.po
@ -10,7 +10,7 @@ msgstr ""
|
||||
"Project-Id-Version: metacity 3.3.4\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2015-02-20 23:22+0000\n"
|
||||
"POT-Creation-Date: 2015-07-21 10:52+0000\n"
|
||||
"PO-Revision-Date: 2015-02-21 16:33+0800\n"
|
||||
"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n"
|
||||
"Language-Team: Chinese (Taiwan) <zh-l10n@lists.linux.org.tw>\n"
|
||||
@ -439,22 +439,22 @@ msgstr "切換至 VT 11"
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "切換至 VT 12"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:364
|
||||
#: ../src/backends/meta-monitor-manager.c:500
|
||||
msgid "Built-in display"
|
||||
msgstr "內建顯示"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:391
|
||||
#: ../src/backends/meta-monitor-manager.c:526
|
||||
msgid "Unknown"
|
||||
msgstr "不明"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:393
|
||||
#: ../src/backends/meta-monitor-manager.c:528
|
||||
msgid "Unknown Display"
|
||||
msgstr "不明的顯示器"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:401
|
||||
#: ../src/backends/meta-monitor-manager.c:536
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
@ -462,7 +462,7 @@ msgstr "%s %s"
|
||||
# FIXME: I'm still unclear about the meaning of XGetSelectionOwner -- Abel
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:456
|
||||
#: ../src/compositor/compositor.c:451
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@ -496,14 +496,14 @@ msgstr "等待(_W)"
|
||||
msgid "_Force Quit"
|
||||
msgstr "強制結束(_F)"
|
||||
|
||||
#: ../src/core/display.c:562
|
||||
#: ../src/core/display.c:563
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "無法開啟 X Window 畫面‘%s’\n"
|
||||
|
||||
#: ../src/core/main.c:176
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "停用到作業階段管理程式的連線"
|
||||
msgstr "停用到作業階段管理員的連線"
|
||||
|
||||
#: ../src/core/main.c:182
|
||||
msgid "Replace the running window manager"
|
||||
@ -1053,9 +1053,9 @@ msgstr "%s(在 %s)"
|
||||
#~ msgid ""
|
||||
#~ "\"%s\" found in configuration database is not a valid value for mouse "
|
||||
#~ "button modifier\n"
|
||||
#~ msgstr "組態資料庫中的“%s”設定值不是有效的滑鼠按鈕修改功能鍵\n"
|
||||
#~ msgstr "設定資料庫中的“%s”設定值不是有效的滑鼠按鈕修改功能鍵\n"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\"%s\" found in configuration database is not a valid value for "
|
||||
#~ "keybinding \"%s\"\n"
|
||||
#~ msgstr "組態資料庫中的“%s”不是按鍵組合“%s”的有效設定值\n"
|
||||
#~ msgstr "設定資料庫中的“%s”不是按鍵組合“%s”的有效設定值\n"
|
||||
|
@ -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,12 +39,14 @@ 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
|
||||
mutter_built_sources += \
|
||||
pointer-gestures-protocol.c \
|
||||
pointer-gestures-server-protocol.h \
|
||||
gtk-shell-protocol.c \
|
||||
gtk-shell-server-protocol.h \
|
||||
xdg-shell-protocol.c \
|
||||
@ -53,6 +55,7 @@ mutter_built_sources += \
|
||||
endif
|
||||
|
||||
wayland_protocols = \
|
||||
wayland/protocol/pointer-gestures.xml \
|
||||
wayland/protocol/gtk-shell.xml \
|
||||
wayland/protocol/xdg-shell.xml \
|
||||
$(NULL)
|
||||
@ -65,7 +68,6 @@ libmutter_la_SOURCES = \
|
||||
backends/meta-barrier-private.h \
|
||||
backends/meta-cursor.c \
|
||||
backends/meta-cursor.h \
|
||||
backends/meta-cursor-private.h \
|
||||
backends/meta-cursor-tracker.c \
|
||||
backends/meta-cursor-tracker-private.h \
|
||||
backends/meta-cursor-renderer.c \
|
||||
@ -94,6 +96,8 @@ libmutter_la_SOURCES = \
|
||||
backends/x11/meta-barrier-x11.h \
|
||||
backends/x11/meta-cursor-renderer-x11.c \
|
||||
backends/x11/meta-cursor-renderer-x11.h \
|
||||
backends/x11/nested/meta-cursor-renderer-x11-nested.c \
|
||||
backends/x11/nested/meta-cursor-renderer-x11-nested.h \
|
||||
backends/x11/meta-idle-monitor-xsync.c \
|
||||
backends/x11/meta-idle-monitor-xsync.h \
|
||||
backends/x11/meta-input-settings-x11.c \
|
||||
@ -132,13 +136,14 @@ 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 \
|
||||
compositor/meta-surface-actor.h \
|
||||
compositor/meta-surface-actor-x11.c \
|
||||
compositor/meta-surface-actor-x11.h \
|
||||
compositor/meta-sync-ring.c \
|
||||
compositor/meta-sync-ring.h \
|
||||
compositor/meta-texture-rectangle.c \
|
||||
compositor/meta-texture-rectangle.h \
|
||||
compositor/meta-texture-tower.c \
|
||||
@ -148,7 +153,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 +163,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,10 +215,7 @@ libmutter_la_SOURCES = \
|
||||
meta/theme.h \
|
||||
ui/theme-private.h \
|
||||
ui/ui.c \
|
||||
x11/iconcache.c \
|
||||
x11/iconcache.h \
|
||||
x11/async-getprop.c \
|
||||
x11/async-getprop.h \
|
||||
x11/atomnames.h \
|
||||
x11/events.c \
|
||||
x11/events.h \
|
||||
x11/group-private.h \
|
||||
@ -221,6 +223,8 @@ libmutter_la_SOURCES = \
|
||||
x11/group-props.h \
|
||||
x11/group.c \
|
||||
meta/group.h \
|
||||
x11/iconcache.c \
|
||||
x11/iconcache.h \
|
||||
x11/session.c \
|
||||
x11/session.h \
|
||||
x11/window-props.c \
|
||||
@ -242,6 +246,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 \
|
||||
@ -249,6 +255,13 @@ 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-pointer-gestures.c \
|
||||
wayland/meta-wayland-pointer-gestures.h \
|
||||
wayland/meta-wayland-pointer-gesture-swipe.c \
|
||||
wayland/meta-wayland-pointer-gesture-swipe.h \
|
||||
wayland/meta-wayland-pointer-gesture-pinch.c \
|
||||
wayland/meta-wayland-pointer-gesture-pinch.h \
|
||||
wayland/meta-wayland-keyboard.c \
|
||||
wayland/meta-wayland-keyboard.h \
|
||||
wayland/meta-wayland-pointer.c \
|
||||
@ -265,8 +278,8 @@ libmutter_la_SOURCES += \
|
||||
wayland/meta-wayland-versions.h \
|
||||
wayland/meta-wayland-outputs.c \
|
||||
wayland/meta-wayland-outputs.h \
|
||||
wayland/window-wayland.c \
|
||||
wayland/window-wayland.h \
|
||||
wayland/meta-window-wayland.c \
|
||||
wayland/meta-window-wayland.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
@ -322,6 +335,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 \
|
||||
@ -332,22 +346,18 @@ 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) \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
# Excluded from scanning for introspection but installed
|
||||
# atomnames.h: macros cause problems for scanning process
|
||||
libmutterinclude_extra_headers = \
|
||||
meta/atomnames.h
|
||||
|
||||
libmutterincludedir = $(includedir)/mutter/meta
|
||||
|
||||
libmutterinclude_HEADERS = \
|
||||
$(libmutterinclude_headers) \
|
||||
$(libmutterinclude_extra_headers)
|
||||
$(libmutterinclude_headers)
|
||||
|
||||
nodist_libmutterinclude_HEADERS = \
|
||||
$(libmutterinclude_built_headers)
|
||||
@ -390,7 +400,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
|
||||
@ -413,8 +422,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 \
|
||||
@ -424,26 +433,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)
|
||||
|
@ -1,59 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2013 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Giovanni Campagna <gcampagn@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef META_CURSOR_PRIVATE_H
|
||||
#define META_CURSOR_PRIVATE_H
|
||||
|
||||
#include "meta-cursor.h"
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include <gbm.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
CoglTexture2D *texture;
|
||||
int hot_x, hot_y;
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_bo *bo;
|
||||
#endif
|
||||
} MetaCursorImage;
|
||||
|
||||
struct _MetaCursorReference {
|
||||
int ref_count;
|
||||
|
||||
MetaCursor cursor;
|
||||
MetaCursorImage image;
|
||||
};
|
||||
|
||||
CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y);
|
||||
#endif
|
||||
|
||||
#endif /* META_CURSOR_PRIVATE_H */
|
@ -25,7 +25,6 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-cursor-renderer.h"
|
||||
#include "meta-cursor-private.h"
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/util.h>
|
||||
@ -38,9 +37,8 @@
|
||||
struct _MetaCursorRendererPrivate
|
||||
{
|
||||
int current_x, current_y;
|
||||
MetaRectangle current_rect;
|
||||
|
||||
MetaCursorReference *displayed_cursor;
|
||||
MetaCursorSprite *displayed_cursor;
|
||||
gboolean handled_by_backend;
|
||||
};
|
||||
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
|
||||
@ -48,27 +46,33 @@ typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT);
|
||||
|
||||
static void
|
||||
queue_redraw (MetaCursorRenderer *renderer)
|
||||
queue_redraw (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
CoglTexture *texture;
|
||||
MetaRectangle rect = { 0 };
|
||||
|
||||
if (cursor_sprite)
|
||||
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
|
||||
|
||||
/* During early initialization, we can have no stage */
|
||||
if (!stage)
|
||||
return;
|
||||
|
||||
if (priv->displayed_cursor && !priv->handled_by_backend)
|
||||
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, NULL, NULL);
|
||||
if (cursor_sprite && !priv->handled_by_backend)
|
||||
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
else
|
||||
texture = NULL;
|
||||
|
||||
meta_stage_set_cursor (META_STAGE (stage), texture, &priv->current_rect);
|
||||
meta_stage_set_cursor (META_STAGE (stage), texture, &rect);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer)
|
||||
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@ -84,34 +88,50 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
|
||||
{
|
||||
}
|
||||
|
||||
MetaRectangle
|
||||
meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
CoglTexture *texture;
|
||||
int hot_x, hot_y;
|
||||
int width, height;
|
||||
float texture_scale;
|
||||
|
||||
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
if (!texture)
|
||||
return (MetaRectangle) { 0 };
|
||||
|
||||
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
|
||||
texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
|
||||
width = cogl_texture_get_width (texture);
|
||||
height = cogl_texture_get_height (texture);
|
||||
|
||||
return (MetaRectangle) {
|
||||
.x = (int)roundf (priv->current_x - (hot_x * texture_scale)),
|
||||
.y = (int)roundf (priv->current_y - (hot_y * texture_scale)),
|
||||
.width = (int)roundf (width * texture_scale),
|
||||
.height = (int)roundf (height * texture_scale),
|
||||
};
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor (MetaCursorRenderer *renderer)
|
||||
update_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
gboolean handled_by_backend;
|
||||
gboolean should_redraw = FALSE;
|
||||
|
||||
if (priv->displayed_cursor)
|
||||
{
|
||||
CoglTexture *texture;
|
||||
int hot_x, hot_y;
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_prepare_at (cursor_sprite,
|
||||
priv->current_x,
|
||||
priv->current_y);
|
||||
|
||||
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
|
||||
|
||||
priv->current_rect.x = priv->current_x - hot_x;
|
||||
priv->current_rect.y = priv->current_y - hot_y;
|
||||
priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
|
||||
priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->current_rect.x = 0;
|
||||
priv->current_rect.y = 0;
|
||||
priv->current_rect.width = 0;
|
||||
priv->current_rect.height = 0;
|
||||
}
|
||||
|
||||
handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
|
||||
handled_by_backend =
|
||||
META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer,
|
||||
cursor_sprite);
|
||||
if (handled_by_backend != priv->handled_by_backend)
|
||||
{
|
||||
priv->handled_by_backend = handled_by_backend;
|
||||
@ -122,7 +142,7 @@ update_cursor (MetaCursorRenderer *renderer)
|
||||
should_redraw = TRUE;
|
||||
|
||||
if (should_redraw)
|
||||
queue_redraw (renderer);
|
||||
queue_redraw (renderer, cursor_sprite);
|
||||
}
|
||||
|
||||
MetaCursorRenderer *
|
||||
@ -132,16 +152,25 @@ meta_cursor_renderer_new (void)
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorReference *cursor)
|
||||
meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
if (priv->displayed_cursor == cursor)
|
||||
if (priv->displayed_cursor == cursor_sprite)
|
||||
return;
|
||||
priv->displayed_cursor = cursor_sprite;
|
||||
|
||||
priv->displayed_cursor = cursor;
|
||||
update_cursor (renderer);
|
||||
update_cursor (renderer, cursor_sprite);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv =
|
||||
meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
update_cursor (renderer, priv->displayed_cursor);
|
||||
}
|
||||
|
||||
void
|
||||
@ -155,10 +184,10 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
|
||||
priv->current_x = x;
|
||||
priv->current_y = y;
|
||||
|
||||
update_cursor (renderer);
|
||||
update_cursor (renderer, priv->displayed_cursor);
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
MetaCursorSprite *
|
||||
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
@ -166,10 +195,27 @@ meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
|
||||
return priv->displayed_cursor;
|
||||
}
|
||||
|
||||
const MetaRectangle *
|
||||
meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer)
|
||||
#ifdef HAVE_WAYLAND
|
||||
void
|
||||
meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
struct wl_resource *buffer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
|
||||
return &priv->current_rect;
|
||||
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
|
||||
|
||||
if (renderer_class->realize_cursor_from_wl_buffer)
|
||||
renderer_class->realize_cursor_from_wl_buffer (renderer, cursor_sprite, buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
XcursorImage *xc_image)
|
||||
{
|
||||
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_GET_CLASS (renderer);
|
||||
|
||||
if (renderer_class->realize_cursor_from_xcursor)
|
||||
renderer_class->realize_cursor_from_xcursor (renderer, cursor_sprite, xc_image);
|
||||
}
|
||||
|
@ -26,43 +26,56 @@
|
||||
#define META_CURSOR_RENDERER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include <wayland-server.h>
|
||||
#endif
|
||||
|
||||
#include <meta/screen.h>
|
||||
#include "meta-cursor.h"
|
||||
|
||||
#define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ())
|
||||
#define META_CURSOR_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER, MetaCursorRenderer))
|
||||
#define META_CURSOR_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass))
|
||||
#define META_IS_CURSOR_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER))
|
||||
#define META_IS_CURSOR_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_CURSOR_RENDERER))
|
||||
#define META_CURSOR_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass))
|
||||
|
||||
typedef struct _MetaCursorRenderer MetaCursorRenderer;
|
||||
typedef struct _MetaCursorRendererClass MetaCursorRendererClass;
|
||||
|
||||
struct _MetaCursorRenderer
|
||||
{
|
||||
GObject parent;
|
||||
};
|
||||
#define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ())
|
||||
G_DECLARE_DERIVABLE_TYPE (MetaCursorRenderer, meta_cursor_renderer,
|
||||
META, CURSOR_RENDERER, GObject);
|
||||
|
||||
struct _MetaCursorRendererClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (* update_cursor) (MetaCursorRenderer *renderer);
|
||||
gboolean (* update_cursor) (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
#ifdef HAVE_WAYLAND
|
||||
void (* realize_cursor_from_wl_buffer) (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
struct wl_resource *buffer);
|
||||
#endif
|
||||
void (* realize_cursor_from_xcursor) (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
XcursorImage *xc_image);
|
||||
};
|
||||
|
||||
GType meta_cursor_renderer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaCursorRenderer * meta_cursor_renderer_new (void);
|
||||
|
||||
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorReference *cursor);
|
||||
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
|
||||
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);
|
||||
MetaCursorSprite * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
|
||||
|
||||
MetaRectangle meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
void meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
struct wl_resource *buffer);
|
||||
#endif
|
||||
|
||||
void meta_cursor_renderer_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
XcursorImage *xc_image);
|
||||
|
||||
#endif /* META_CURSOR_RENDERER_H */
|
||||
|
@ -34,7 +34,7 @@ struct _MetaCursorTracker {
|
||||
|
||||
gboolean is_showing;
|
||||
|
||||
MetaCursorReference *displayed_cursor;
|
||||
MetaCursorSprite *displayed_cursor;
|
||||
|
||||
/* Wayland clients can set a NULL buffer as their cursor
|
||||
* explicitly, which means that we shouldn't display anything.
|
||||
@ -42,12 +42,12 @@ struct _MetaCursorTracker {
|
||||
* determine an unset window cursor; we need an extra boolean.
|
||||
*/
|
||||
gboolean has_window_cursor;
|
||||
MetaCursorReference *window_cursor;
|
||||
MetaCursorSprite *window_cursor;
|
||||
|
||||
MetaCursorReference *root_cursor;
|
||||
MetaCursorSprite *root_cursor;
|
||||
|
||||
/* The cursor from the X11 server. */
|
||||
MetaCursorReference *xfixes_cursor;
|
||||
MetaCursorSprite *xfixes_cursor;
|
||||
};
|
||||
|
||||
struct _MetaCursorTrackerClass {
|
||||
@ -57,16 +57,16 @@ struct _MetaCursorTrackerClass {
|
||||
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
XEvent *xevent);
|
||||
|
||||
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor);
|
||||
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
|
||||
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor);
|
||||
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
|
||||
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorSprite *cursor_sprite);
|
||||
|
||||
void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
||||
int new_x,
|
||||
int new_y);
|
||||
|
||||
MetaCursorReference * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
|
||||
MetaCursorSprite * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
|
||||
|
||||
#endif
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
|
||||
#include "meta-backend-private.h"
|
||||
#include "meta-cursor-private.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
|
||||
|
||||
@ -54,7 +53,7 @@ enum {
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static MetaCursorReference *
|
||||
static MetaCursorSprite *
|
||||
get_displayed_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
@ -80,14 +79,14 @@ update_displayed_cursor (MetaCursorTracker *tracker)
|
||||
static void
|
||||
sync_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker);
|
||||
MetaCursorSprite *displayed_cursor = get_displayed_cursor (tracker);
|
||||
|
||||
if (tracker->displayed_cursor == displayed_cursor)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref);
|
||||
g_clear_object (&tracker->displayed_cursor);
|
||||
if (displayed_cursor)
|
||||
tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor);
|
||||
tracker->displayed_cursor = g_object_ref (displayed_cursor);
|
||||
|
||||
update_displayed_cursor (tracker);
|
||||
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
|
||||
@ -108,9 +107,9 @@ meta_cursor_tracker_finalize (GObject *object)
|
||||
MetaCursorTracker *self = META_CURSOR_TRACKER (object);
|
||||
|
||||
if (self->displayed_cursor)
|
||||
meta_cursor_reference_unref (self->displayed_cursor);
|
||||
g_object_unref (self->displayed_cursor);
|
||||
if (self->root_cursor)
|
||||
meta_cursor_reference_unref (self->root_cursor);
|
||||
g_object_unref (self->root_cursor);
|
||||
|
||||
G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->finalize (object);
|
||||
}
|
||||
@ -156,13 +155,13 @@ meta_cursor_tracker_get_for_screen (MetaScreen *screen)
|
||||
}
|
||||
|
||||
static void
|
||||
set_window_cursor (MetaCursorTracker *tracker,
|
||||
gboolean has_cursor,
|
||||
MetaCursorReference *cursor)
|
||||
set_window_cursor (MetaCursorTracker *tracker,
|
||||
gboolean has_cursor,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
g_clear_pointer (&tracker->window_cursor, meta_cursor_reference_unref);
|
||||
if (cursor)
|
||||
tracker->window_cursor = meta_cursor_reference_ref (cursor);
|
||||
g_clear_object (&tracker->window_cursor);
|
||||
if (cursor_sprite)
|
||||
tracker->window_cursor = g_object_ref (cursor_sprite);
|
||||
tracker->has_window_cursor = has_cursor;
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
@ -184,28 +183,12 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
if (notify_event->subtype != XFixesDisplayCursorNotify)
|
||||
return FALSE;
|
||||
|
||||
g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref);
|
||||
g_clear_object (&tracker->xfixes_cursor);
|
||||
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static MetaCursorReference *
|
||||
meta_cursor_reference_take_texture (CoglTexture2D *texture,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
MetaCursorReference *self;
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
self->image.texture = texture;
|
||||
self->image.hot_x = hot_x;
|
||||
self->image.hot_y = hot_y;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
@ -263,10 +246,13 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
|
||||
if (sprite != NULL)
|
||||
{
|
||||
MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite,
|
||||
cursor_image->xhot,
|
||||
cursor_image->yhot);
|
||||
tracker->xfixes_cursor = cursor;
|
||||
MetaCursorSprite *cursor_sprite = meta_cursor_sprite_new ();
|
||||
meta_cursor_sprite_set_texture (cursor_sprite,
|
||||
sprite,
|
||||
cursor_image->xhot,
|
||||
cursor_image->yhot);
|
||||
cogl_object_unref (sprite);
|
||||
tracker->xfixes_cursor = cursor_sprite;
|
||||
}
|
||||
XFree (cursor_image);
|
||||
}
|
||||
@ -279,22 +265,22 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
CoglTexture *
|
||||
meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
MetaCursorSprite *cursor_sprite;
|
||||
|
||||
g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
cursor = tracker->displayed_cursor;
|
||||
cursor_sprite = tracker->displayed_cursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_xfixes_cursor (tracker);
|
||||
cursor = tracker->xfixes_cursor;
|
||||
cursor_sprite = tracker->xfixes_cursor;
|
||||
}
|
||||
|
||||
if (cursor)
|
||||
return meta_cursor_reference_get_cogl_texture (cursor, NULL, NULL);
|
||||
if (cursor_sprite)
|
||||
return meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@ -311,22 +297,22 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
MetaCursorSprite *cursor_sprite;
|
||||
|
||||
g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
cursor = tracker->displayed_cursor;
|
||||
cursor_sprite = tracker->displayed_cursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_xfixes_cursor (tracker);
|
||||
cursor = tracker->xfixes_cursor;
|
||||
cursor_sprite = tracker->xfixes_cursor;
|
||||
}
|
||||
|
||||
if (cursor)
|
||||
meta_cursor_reference_get_cogl_texture (cursor, x, y);
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_get_hotspot (cursor_sprite, x, y);
|
||||
else
|
||||
{
|
||||
if (x)
|
||||
@ -337,10 +323,10 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor)
|
||||
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
set_window_cursor (tracker, TRUE, cursor);
|
||||
set_window_cursor (tracker, TRUE, cursor_sprite);
|
||||
}
|
||||
|
||||
void
|
||||
@ -350,12 +336,12 @@ meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker)
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor)
|
||||
meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref);
|
||||
if (cursor)
|
||||
tracker->root_cursor = meta_cursor_reference_ref (cursor);
|
||||
g_clear_object (&tracker->root_cursor);
|
||||
if (cursor_sprite)
|
||||
tracker->root_cursor = g_object_ref (cursor_sprite);
|
||||
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
@ -438,7 +424,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
MetaCursorSprite *
|
||||
meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
return tracker->displayed_cursor;
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-cursor.h"
|
||||
|
||||
#include <meta/errors.h>
|
||||
|
||||
@ -29,56 +29,38 @@
|
||||
#include "screen-private.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-cursor-renderer-native.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#endif
|
||||
enum {
|
||||
PREPARE_AT,
|
||||
|
||||
MetaCursorReference *
|
||||
meta_cursor_reference_ref (MetaCursorReference *self)
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
struct _MetaCursorSprite
|
||||
{
|
||||
g_assert (self->ref_count > 0);
|
||||
self->ref_count++;
|
||||
GObject parent;
|
||||
|
||||
return self;
|
||||
}
|
||||
MetaCursor cursor;
|
||||
|
||||
static void
|
||||
meta_cursor_image_free (MetaCursorImage *image)
|
||||
{
|
||||
if (image->texture)
|
||||
cogl_object_unref (image->texture);
|
||||
CoglTexture2D *texture;
|
||||
float texture_scale;
|
||||
int hot_x, hot_y;
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
if (image->bo)
|
||||
gbm_bo_destroy (image->bo);
|
||||
#endif
|
||||
}
|
||||
int current_frame;
|
||||
XcursorImages *xcursor_images;
|
||||
|
||||
static void
|
||||
meta_cursor_reference_free (MetaCursorReference *self)
|
||||
{
|
||||
meta_cursor_image_free (&self->image);
|
||||
g_slice_free (MetaCursorReference, self);
|
||||
}
|
||||
int theme_scale;
|
||||
gboolean theme_dirty;
|
||||
};
|
||||
|
||||
void
|
||||
meta_cursor_reference_unref (MetaCursorReference *self)
|
||||
{
|
||||
self->ref_count--;
|
||||
|
||||
if (self->ref_count == 0)
|
||||
meta_cursor_reference_free (self);
|
||||
}
|
||||
G_DEFINE_TYPE (MetaCursorSprite, meta_cursor_sprite, G_TYPE_OBJECT)
|
||||
|
||||
static const char *
|
||||
translate_meta_cursor (MetaCursor cursor)
|
||||
@ -135,93 +117,27 @@ meta_cursor_create_x_cursor (Display *xdisplay,
|
||||
return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
|
||||
}
|
||||
|
||||
static XcursorImage *
|
||||
load_cursor_on_client (MetaCursor cursor)
|
||||
static XcursorImages *
|
||||
load_cursor_on_client (MetaCursor cursor, int scale)
|
||||
{
|
||||
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 () * scale);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static void
|
||||
get_hardware_cursor_size (uint64_t *cursor_width, uint64_t *cursor_height)
|
||||
meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *self,
|
||||
XcursorImage *xc_image)
|
||||
{
|
||||
MetaBackend *meta_backend = meta_get_backend ();
|
||||
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
|
||||
|
||||
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
|
||||
{
|
||||
meta_cursor_renderer_native_get_cursor_size (META_CURSOR_RENDERER_NATIVE (renderer), cursor_width, cursor_height);
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static void
|
||||
meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
|
||||
MetaCursorImage *image,
|
||||
uint8_t *pixels,
|
||||
uint width,
|
||||
uint height,
|
||||
int rowstride,
|
||||
uint32_t gbm_format)
|
||||
{
|
||||
uint64_t cursor_width, cursor_height;
|
||||
get_hardware_cursor_size (&cursor_width, &cursor_height);
|
||||
|
||||
if (width > cursor_width || height > cursor_height)
|
||||
{
|
||||
meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
|
||||
(unsigned int)cursor_width, (unsigned int)cursor_height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gbm_device_is_format_supported (gbm, gbm_format,
|
||||
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
|
||||
{
|
||||
uint8_t buf[4 * cursor_width * cursor_height];
|
||||
uint i;
|
||||
|
||||
image->bo = gbm_bo_create (gbm, cursor_width, cursor_height,
|
||||
gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
||||
|
||||
memset (buf, 0, sizeof(buf));
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
|
||||
|
||||
gbm_bo_write (image->bo, buf, cursor_width * cursor_height * 4);
|
||||
}
|
||||
else
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static struct gbm_device *
|
||||
get_gbm_device (void)
|
||||
{
|
||||
MetaBackend *meta_backend = meta_get_backend ();
|
||||
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
|
||||
|
||||
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
|
||||
return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
|
||||
XcursorImage *xc_image)
|
||||
{
|
||||
uint width, height, rowstride;
|
||||
CoglPixelFormat cogl_format;
|
||||
ClutterBackend *clutter_backend;
|
||||
CoglContext *cogl_context;
|
||||
CoglTexture *texture;
|
||||
|
||||
g_assert (self->texture == NULL);
|
||||
|
||||
width = xc_image->width;
|
||||
height = xc_image->height;
|
||||
@ -233,196 +149,210 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
|
||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||
#endif
|
||||
|
||||
image->hot_x = xc_image->xhot;
|
||||
image->hot_y = xc_image->yhot;
|
||||
|
||||
clutter_backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
image->texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
rowstride,
|
||||
(uint8_t *) xc_image->pixels,
|
||||
NULL);
|
||||
texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
rowstride,
|
||||
(uint8_t *) xc_image->pixels,
|
||||
NULL);
|
||||
meta_cursor_sprite_set_texture (self, texture,
|
||||
xc_image->xhot, xc_image->yhot);
|
||||
cogl_object_unref (texture);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_device *gbm = get_gbm_device ();
|
||||
if (gbm)
|
||||
meta_cursor_image_load_gbm_buffer (gbm,
|
||||
image,
|
||||
(uint8_t *) xc_image->pixels,
|
||||
width, height, rowstride,
|
||||
GBM_FORMAT_ARGB8888);
|
||||
#endif
|
||||
meta_cursor_renderer_realize_cursor_from_xcursor (renderer, self, xc_image);
|
||||
}
|
||||
|
||||
static void
|
||||
load_cursor_image (MetaCursorReference *cursor)
|
||||
static XcursorImage *
|
||||
meta_cursor_sprite_get_current_frame_image (MetaCursorSprite *self)
|
||||
{
|
||||
return self->xcursor_images->images[self->current_frame];
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_tick_frame (MetaCursorSprite *self)
|
||||
{
|
||||
XcursorImage *image;
|
||||
|
||||
/* Either cursors are loaded from X cursors or buffers. Since
|
||||
* buffers are converted over immediately, we can make sure to
|
||||
* load this directly. */
|
||||
g_assert (cursor->cursor != META_CURSOR_NONE);
|
||||
|
||||
image = load_cursor_on_client (cursor->cursor);
|
||||
if (!image)
|
||||
if (!meta_cursor_sprite_is_animated (self))
|
||||
return;
|
||||
|
||||
meta_cursor_image_load_from_xcursor_image (&cursor->image, image);
|
||||
XcursorImageDestroy (image);
|
||||
self->current_frame++;
|
||||
|
||||
if (self->current_frame >= self->xcursor_images->nimage)
|
||||
self->current_frame = 0;
|
||||
|
||||
image = meta_cursor_sprite_get_current_frame_image (self);
|
||||
|
||||
g_clear_pointer (&self->texture, cogl_object_unref);
|
||||
meta_cursor_sprite_load_from_xcursor_image (self, image);
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
meta_cursor_reference_from_theme (MetaCursor cursor)
|
||||
guint
|
||||
meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *self)
|
||||
{
|
||||
MetaCursorReference *self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
self->cursor = cursor;
|
||||
return self;
|
||||
if (!meta_cursor_sprite_is_animated (self))
|
||||
return 0;
|
||||
|
||||
return self->xcursor_images->images[self->current_frame]->delay;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_cursor_sprite_is_animated (MetaCursorSprite *self)
|
||||
{
|
||||
return (self->xcursor_images &&
|
||||
self->xcursor_images->nimage > 1);
|
||||
}
|
||||
|
||||
MetaCursorSprite *
|
||||
meta_cursor_sprite_new (void)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_SPRITE, NULL);
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
static void
|
||||
meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
||||
struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
meta_cursor_sprite_load_from_theme (MetaCursorSprite *self)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
XcursorImage *image;
|
||||
|
||||
image->hot_x = hot_x;
|
||||
image->hot_y = hot_y;
|
||||
g_assert (self->cursor != META_CURSOR_NONE);
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_device *gbm = get_gbm_device ();
|
||||
if (gbm)
|
||||
/* We might be reloading with a different scale. If so clear the old data. */
|
||||
if (self->xcursor_images)
|
||||
{
|
||||
uint32_t gbm_format;
|
||||
uint64_t cursor_width, cursor_height;
|
||||
uint width, height;
|
||||
|
||||
width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
|
||||
height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
|
||||
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
|
||||
if (shm_buffer)
|
||||
{
|
||||
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
|
||||
|
||||
wl_shm_buffer_begin_access (shm_buffer);
|
||||
|
||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
||||
{
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#else
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
}
|
||||
|
||||
meta_cursor_image_load_gbm_buffer (gbm,
|
||||
image,
|
||||
(uint8_t *) wl_shm_buffer_get_data (shm_buffer),
|
||||
width, height, rowstride,
|
||||
gbm_format);
|
||||
|
||||
wl_shm_buffer_end_access (shm_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HW cursors have a predefined size (at least 64x64), which usually is bigger than cursor theme
|
||||
size, so themed cursors must be padded with transparent pixels to fill the
|
||||
overlay. This is trivial if we have CPU access to the data, but it's not
|
||||
possible if the buffer is in GPU memory (and possibly tiled too), so if we
|
||||
don't get the right size, we fallback to GL.
|
||||
*/
|
||||
get_hardware_cursor_size (&cursor_width, &cursor_height);
|
||||
|
||||
if (width != cursor_width || height != cursor_height)
|
||||
{
|
||||
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
|
||||
return;
|
||||
}
|
||||
|
||||
image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER, buffer, GBM_BO_USE_CURSOR);
|
||||
if (!image->bo)
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
}
|
||||
g_clear_pointer (&self->texture, cogl_object_unref);
|
||||
XcursorImagesDestroy (self->xcursor_images);
|
||||
}
|
||||
#endif
|
||||
|
||||
self->current_frame = 0;
|
||||
self->xcursor_images = load_cursor_on_client (self->cursor,
|
||||
self->theme_scale);
|
||||
if (!self->xcursor_images)
|
||||
meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
|
||||
|
||||
image = meta_cursor_sprite_get_current_frame_image (self);
|
||||
meta_cursor_sprite_load_from_xcursor_image (self, image);
|
||||
|
||||
self->theme_dirty = FALSE;
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
meta_cursor_reference_from_buffer (struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
MetaCursorSprite *
|
||||
meta_cursor_sprite_from_theme (MetaCursor cursor)
|
||||
{
|
||||
MetaCursorReference *self;
|
||||
MetaCursorSprite *self;
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
meta_cursor_image_load_from_buffer (&self->image, buffer, hot_x, hot_y);
|
||||
self = meta_cursor_sprite_new ();
|
||||
|
||||
self->cursor = cursor;
|
||||
self->theme_dirty = TRUE;
|
||||
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
meta_cursor_sprite_set_texture (MetaCursorSprite *self,
|
||||
CoglTexture *texture,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
g_clear_pointer (&self->texture, cogl_object_unref);
|
||||
if (texture)
|
||||
self->texture = cogl_object_ref (texture);
|
||||
self->hot_x = hot_x;
|
||||
self->hot_y = hot_y;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self,
|
||||
float scale)
|
||||
{
|
||||
self->texture_scale = scale;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_set_theme_scale (MetaCursorSprite *self,
|
||||
int theme_scale)
|
||||
{
|
||||
if (self->theme_scale != theme_scale)
|
||||
self->theme_dirty = TRUE;
|
||||
self->theme_scale = theme_scale;
|
||||
}
|
||||
|
||||
CoglTexture *
|
||||
meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self)
|
||||
{
|
||||
if (!cursor->image.texture)
|
||||
load_cursor_image (cursor);
|
||||
|
||||
if (hot_x)
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->image.hot_y;
|
||||
|
||||
return COGL_TEXTURE (cursor->image.texture);
|
||||
return COGL_TEXTURE (self->texture);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_bo *
|
||||
meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
{
|
||||
if (!cursor->image.bo)
|
||||
load_cursor_image (cursor);
|
||||
|
||||
if (hot_x)
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->image.hot_y;
|
||||
return cursor->image.bo;
|
||||
}
|
||||
#endif
|
||||
|
||||
MetaCursor
|
||||
meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor)
|
||||
meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self)
|
||||
{
|
||||
return cursor->cursor;
|
||||
return self->cursor;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_get_hotspot (MetaCursorSprite *self,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
{
|
||||
*hot_x = self->hot_x;
|
||||
*hot_y = self->hot_y;
|
||||
}
|
||||
|
||||
float
|
||||
meta_cursor_sprite_get_texture_scale (MetaCursorSprite *self)
|
||||
{
|
||||
return self->texture_scale;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_prepare_at (MetaCursorSprite *self,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
g_signal_emit (self, signals[PREPARE_AT], 0, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_sprite_realize_texture (MetaCursorSprite *self)
|
||||
{
|
||||
if (self->theme_dirty)
|
||||
meta_cursor_sprite_load_from_theme (self);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_sprite_init (MetaCursorSprite *self)
|
||||
{
|
||||
self->texture_scale = 1.0f;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_sprite_finalize (GObject *object)
|
||||
{
|
||||
MetaCursorSprite *self = META_CURSOR_SPRITE (object);
|
||||
|
||||
if (self->xcursor_images)
|
||||
XcursorImagesDestroy (self->xcursor_images);
|
||||
|
||||
g_clear_pointer (&self->texture, cogl_object_unref);
|
||||
|
||||
G_OBJECT_CLASS (meta_cursor_sprite_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_sprite_class_init (MetaCursorSpriteClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_cursor_sprite_finalize;
|
||||
|
||||
signals[PREPARE_AT] = g_signal_new ("prepare-at",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_INT);
|
||||
}
|
||||
|
@ -22,25 +22,54 @@
|
||||
#ifndef META_CURSOR_H
|
||||
#define META_CURSOR_H
|
||||
|
||||
typedef struct _MetaCursorReference MetaCursorReference;
|
||||
|
||||
MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor);
|
||||
void meta_cursor_reference_unref (MetaCursorReference *cursor);
|
||||
|
||||
#include <meta/common.h>
|
||||
#include <meta/boxes.h>
|
||||
|
||||
MetaCursorReference * meta_cursor_reference_from_theme (MetaCursor cursor);
|
||||
typedef struct _MetaCursorSprite MetaCursorSprite;
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include <wayland-server.h>
|
||||
MetaCursorReference * meta_cursor_reference_from_buffer (struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
#endif
|
||||
#define META_TYPE_CURSOR_SPRITE (meta_cursor_sprite_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaCursorSprite,
|
||||
meta_cursor_sprite,
|
||||
META, CURSOR_SPRITE,
|
||||
GObject);
|
||||
|
||||
MetaCursor meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor);
|
||||
MetaCursorSprite * meta_cursor_sprite_new (void);
|
||||
|
||||
MetaCursorSprite * meta_cursor_sprite_from_theme (MetaCursor cursor);
|
||||
|
||||
|
||||
void meta_cursor_sprite_set_theme_scale (MetaCursorSprite *self,
|
||||
int scale);
|
||||
|
||||
MetaCursor meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self);
|
||||
|
||||
Cursor meta_cursor_create_x_cursor (Display *xdisplay,
|
||||
MetaCursor cursor);
|
||||
|
||||
void meta_cursor_sprite_prepare_at (MetaCursorSprite *self,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void meta_cursor_sprite_realize_texture (MetaCursorSprite *self);
|
||||
|
||||
void meta_cursor_sprite_set_texture (MetaCursorSprite *self,
|
||||
CoglTexture *texture,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
|
||||
void meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self,
|
||||
float scale);
|
||||
|
||||
CoglTexture *meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self);
|
||||
|
||||
void meta_cursor_sprite_get_hotspot (MetaCursorSprite *self,
|
||||
int *hot_x,
|
||||
int *hot_y);
|
||||
|
||||
float meta_cursor_sprite_get_texture_scale (MetaCursorSprite *self);
|
||||
|
||||
gboolean meta_cursor_sprite_is_animated (MetaCursorSprite *self);
|
||||
void meta_cursor_sprite_tick_frame (MetaCursorSprite *self);
|
||||
guint meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *self);
|
||||
|
||||
#endif /* META_CURSOR_H */
|
||||
|
@ -209,6 +209,10 @@ update_touchpad_left_handed (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled = FALSE;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
handedness = g_settings_get_enum (priv->touchpad_settings, "left-handed");
|
||||
@ -230,7 +234,6 @@ update_touchpad_left_handed (MetaInputSettings *input_settings,
|
||||
|
||||
if (device)
|
||||
{
|
||||
g_assert (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHPAD_DEVICE);
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
@ -251,13 +254,16 @@ update_mouse_left_handed (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_POINTER_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
|
||||
|
||||
if (device)
|
||||
{
|
||||
g_assert (clutter_input_device_get_device_type (device) == CLUTTER_POINTER_DEVICE);
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
@ -366,6 +372,10 @@ update_touchpad_tap_enabled (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
|
||||
@ -392,6 +402,10 @@ update_touchpad_scroll_method (MetaInputSettings *input_settings,
|
||||
GDesktopTouchpadScrollMethod method;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
method = g_settings_get_enum (priv->touchpad_settings, "scroll-method");
|
||||
@ -418,6 +432,10 @@ update_touchpad_click_method (MetaInputSettings *input_settings,
|
||||
GDesktopTouchpadScrollMethod method;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
method = g_settings_get_enum (priv->touchpad_settings, "click-method");
|
||||
@ -444,6 +462,10 @@ update_touchpad_send_events (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
GDesktopDeviceSendEvents mode;
|
||||
|
||||
if (device &&
|
||||
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
mode = g_settings_get_enum (priv->touchpad_settings, "send-events");
|
||||
@ -486,27 +508,28 @@ update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
MetaInputSettingsPrivate *priv;
|
||||
guint button;
|
||||
|
||||
if (device && !device_is_trackball (device))
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
/* This key is 'i' in the schema but it also specifies a minimum
|
||||
* range of 0 so the cast here is safe. */
|
||||
button = (guint) g_settings_get_int (priv->trackball_settings, "scroll-wheel-emulation-button");
|
||||
|
||||
if (device && device_is_trackball (device))
|
||||
if (device)
|
||||
{
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
}
|
||||
else if (!device)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
const GSList *devices;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
||||
|
||||
while (devices)
|
||||
{
|
||||
ClutterInputDevice *device = devices->data;
|
||||
device = devices->data;
|
||||
|
||||
if (device_is_trackball (device))
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
|
@ -65,6 +65,7 @@ typedef struct {
|
||||
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
gboolean is_underscanning;
|
||||
} MetaOutputConfig;
|
||||
|
||||
typedef struct {
|
||||
@ -82,7 +83,8 @@ struct _MetaMonitorConfig {
|
||||
gboolean current_is_for_laptop_lid;
|
||||
MetaConfiguration *previous;
|
||||
|
||||
GFile *file;
|
||||
GFile *user_file;
|
||||
GFile *system_file;
|
||||
GCancellable *save_cancellable;
|
||||
|
||||
UpClient *up_client;
|
||||
@ -238,6 +240,7 @@ meta_monitor_config_init (MetaMonitorConfig *self)
|
||||
{
|
||||
const char *filename;
|
||||
char *path;
|
||||
const char * const *system_dirs;
|
||||
|
||||
self->configs = g_hash_table_new_full (config_hash, config_equal, NULL, (GDestroyNotify) config_unref);
|
||||
|
||||
@ -246,9 +249,17 @@ meta_monitor_config_init (MetaMonitorConfig *self)
|
||||
filename = "monitors.xml";
|
||||
|
||||
path = g_build_filename (g_get_user_config_dir (), filename, NULL);
|
||||
self->file = g_file_new_for_path (path);
|
||||
self->user_file = g_file_new_for_path (path);
|
||||
g_free (path);
|
||||
|
||||
for (system_dirs = g_get_system_config_dirs (); !self->system_file && *system_dirs; system_dirs++)
|
||||
{
|
||||
path = g_build_filename (*system_dirs, filename, NULL);
|
||||
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||
self->system_file = g_file_new_for_path (path);
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
self->up_client = up_client_new ();
|
||||
self->lid_is_closed = up_client_get_lid_is_closed (self->up_client);
|
||||
|
||||
@ -393,7 +404,8 @@ handle_start_element (GMarkupParseContext *context,
|
||||
strcmp (element_name, "reflect_x") == 0 ||
|
||||
strcmp (element_name, "reflect_y") == 0 ||
|
||||
strcmp (element_name, "primary") == 0 ||
|
||||
strcmp (element_name, "presentation") == 0) && parser->unknown_count == 0)
|
||||
strcmp (element_name, "presentation") == 0 ||
|
||||
strcmp (element_name, "underscanning") == 0) && parser->unknown_count == 0)
|
||||
{
|
||||
parser->state = STATE_OUTPUT_FIELD;
|
||||
|
||||
@ -477,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;
|
||||
@ -700,6 +712,8 @@ handle_text (GMarkupParseContext *context,
|
||||
parser->output.is_primary = read_bool (text, text_len, error);
|
||||
else if (strcmp (parser->output_field, "presentation") == 0)
|
||||
parser->output.is_presentation = read_bool (text, text_len, error);
|
||||
else if (strcmp (parser->output_field, "underscanning") == 0)
|
||||
parser->output.is_underscanning = read_bool (text, text_len, error);
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
@ -717,8 +731,8 @@ static const GMarkupParser config_parser = {
|
||||
.text = handle_text,
|
||||
};
|
||||
|
||||
static void
|
||||
meta_monitor_config_load (MetaMonitorConfig *self)
|
||||
static gboolean
|
||||
load_config_file (MetaMonitorConfig *self, GFile *file)
|
||||
{
|
||||
char *contents;
|
||||
gsize size;
|
||||
@ -736,14 +750,12 @@ meta_monitor_config_load (MetaMonitorConfig *self)
|
||||
*/
|
||||
|
||||
error = NULL;
|
||||
ok = g_file_load_contents (self->file, NULL, &contents, &size, NULL, &error);
|
||||
ok = g_file_load_contents (file, NULL, &contents, &size, NULL, &error);
|
||||
if (!ok)
|
||||
{
|
||||
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
meta_warning ("Failed to load stored monitor configuration: %s\n", error->message);
|
||||
|
||||
g_error_free (error);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset (&parser, 0, sizeof (ConfigParser));
|
||||
@ -772,6 +784,17 @@ meta_monitor_config_load (MetaMonitorConfig *self)
|
||||
|
||||
g_markup_parse_context_free (context);
|
||||
g_free (contents);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_config_load (MetaMonitorConfig *self)
|
||||
{
|
||||
if (self->user_file && load_config_file (self, self->user_file))
|
||||
return;
|
||||
if (self->system_file && load_config_file (self, self->system_file))
|
||||
return;
|
||||
}
|
||||
|
||||
MetaMonitorConfig *
|
||||
@ -863,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,
|
||||
@ -882,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
|
||||
@ -1056,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);
|
||||
@ -1069,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;
|
||||
}
|
||||
@ -1123,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);
|
||||
@ -1131,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;
|
||||
@ -1158,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,
|
||||
@ -1166,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1314,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 */
|
||||
@ -1332,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)
|
||||
{
|
||||
@ -1408,6 +1511,7 @@ init_config_from_output (MetaOutputConfig *config,
|
||||
config->transform = output->crtc->transform;
|
||||
config->is_primary = output->is_primary;
|
||||
config->is_presentation = output->is_presentation;
|
||||
config->is_underscanning = output->is_underscanning;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1598,7 +1702,8 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
||||
" <reflect_x>%s</reflect_x>\n"
|
||||
" <reflect_y>no</reflect_y>\n"
|
||||
" <primary>%s</primary>\n"
|
||||
" <presentation>%s</presentation>\n",
|
||||
" <presentation>%s</presentation>\n"
|
||||
" <underscanning>%s</underscanning>\n",
|
||||
output->rect.width,
|
||||
output->rect.height,
|
||||
refresh_rate,
|
||||
@ -1607,7 +1712,8 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
||||
rotation_map[output->transform & 0x3],
|
||||
output->transform >= META_MONITOR_TRANSFORM_FLIPPED ? "yes" : "no",
|
||||
output->is_primary ? "yes" : "no",
|
||||
output->is_presentation ? "yes" : "no");
|
||||
output->is_presentation ? "yes" : "no",
|
||||
output->is_underscanning ? "yes" : "no");
|
||||
}
|
||||
|
||||
g_string_append (buffer, " </output>\n");
|
||||
@ -1622,7 +1728,7 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
||||
closure->config = g_object_ref (self);
|
||||
closure->buffer = buffer;
|
||||
|
||||
g_file_replace_contents_async (self->file,
|
||||
g_file_replace_contents_async (self->user_file,
|
||||
buffer->str, buffer->len,
|
||||
NULL, /* etag */
|
||||
TRUE,
|
||||
@ -1740,7 +1846,7 @@ crtc_assignment_assign (CrtcAssignment *assign,
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaCRTCInfo *info = g_slice_new0 (MetaCRTCInfo);
|
||||
info = g_slice_new0 (MetaCRTCInfo);
|
||||
|
||||
info->crtc = crtc;
|
||||
info->mode = mode;
|
||||
@ -1814,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;
|
||||
@ -1831,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];
|
||||
@ -1879,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);
|
||||
}
|
||||
@ -1891,8 +1991,7 @@ real_assign_crtcs (CrtcAssignment *assignment,
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return success;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1941,6 +2040,7 @@ meta_monitor_config_assign_crtcs (MetaConfiguration *config,
|
||||
&config->keys[i]);
|
||||
output_info->is_primary = output_config->is_primary;
|
||||
output_info->is_presentation = output_config->is_presentation;
|
||||
output_info->is_underscanning = output_config->is_underscanning;
|
||||
|
||||
g_ptr_array_add (outputs, output_info);
|
||||
}
|
||||
|
@ -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
|
||||
@ -127,7 +197,7 @@ meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
|
||||
{
|
||||
MetaMonitorMode *mode;
|
||||
MetaOutput *output;
|
||||
int i, n_outputs;
|
||||
unsigned int j;
|
||||
int width, height;
|
||||
|
||||
mode = crtc_info->mode;
|
||||
@ -153,10 +223,9 @@ meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
|
||||
screen_width = MAX (screen_width, crtc_info->x + width);
|
||||
screen_height = MAX (screen_height, crtc_info->y + height);
|
||||
|
||||
n_outputs = crtc_info->outputs->len;
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
for (j = 0; j < crtc_info->outputs->len; j++)
|
||||
{
|
||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[i];
|
||||
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
|
@ -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 */
|
||||
@ -132,6 +144,8 @@ struct _MetaOutput
|
||||
*/
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
gboolean is_underscanning;
|
||||
gboolean supports_underscanning;
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
@ -140,6 +154,8 @@ struct _MetaOutput
|
||||
gboolean hotplug_mode_update;
|
||||
gint suggested_x;
|
||||
gint suggested_y;
|
||||
|
||||
MetaTileInfo tile_info;
|
||||
};
|
||||
|
||||
struct _MetaCRTC
|
||||
@ -158,7 +174,11 @@ struct _MetaCRTC
|
||||
/* Used when changing configuration */
|
||||
gboolean is_dirty;
|
||||
|
||||
MetaCursorReference *cursor;
|
||||
/* Used by cursor renderer backend */
|
||||
void *cursor_renderer_private;
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
};
|
||||
|
||||
struct _MetaMonitorMode
|
||||
@ -175,6 +195,7 @@ struct _MetaMonitorMode
|
||||
GDestroyNotify driver_notify;
|
||||
};
|
||||
|
||||
#define META_MAX_OUTPUTS_PER_MONITOR 4
|
||||
/**
|
||||
* MetaMonitorInfo:
|
||||
*
|
||||
@ -190,9 +211,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.
|
||||
@ -203,6 +229,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];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -230,6 +262,7 @@ struct _MetaOutputInfo {
|
||||
MetaOutput *output;
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
gboolean is_underscanning;
|
||||
};
|
||||
|
||||
#define META_TYPE_MONITOR_MANAGER (meta_monitor_manager_get_type ())
|
||||
@ -319,6 +352,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
|
||||
@ -264,6 +386,21 @@ meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
|
||||
g_free (old_modes);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_free_crtc_array (MetaCRTC *old_crtcs,
|
||||
int n_old_crtcs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_old_crtcs; i++)
|
||||
{
|
||||
if (old_crtcs[i].driver_notify)
|
||||
old_crtcs[i].driver_notify (&old_crtcs[i]);
|
||||
}
|
||||
|
||||
g_free (old_crtcs);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_finalize (GObject *object)
|
||||
{
|
||||
@ -271,8 +408,8 @@ meta_monitor_manager_finalize (GObject *object)
|
||||
|
||||
meta_monitor_manager_free_output_array (manager->outputs, manager->n_outputs);
|
||||
meta_monitor_manager_free_mode_array (manager->modes, manager->n_modes);
|
||||
meta_monitor_manager_free_crtc_array (manager->crtcs, manager->n_crtcs);
|
||||
g_free (manager->monitor_infos);
|
||||
g_free (manager->crtcs);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->finalize (object);
|
||||
}
|
||||
@ -353,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;
|
||||
}
|
||||
@ -398,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 *
|
||||
@ -520,6 +649,10 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
g_variant_new_boolean (output->is_presentation));
|
||||
g_variant_builder_add (&properties, "{sv}", "connector-type",
|
||||
g_variant_new_string (get_connector_type_name (output->connector_type)));
|
||||
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)
|
||||
@ -540,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,
|
||||
@ -737,8 +884,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
crtc_info->y = 0;
|
||||
}
|
||||
|
||||
if (transform < META_MONITOR_TRANSFORM_NORMAL ||
|
||||
transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
|
||||
if (transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
|
||||
((crtc->all_transforms & (1 << transform)) == 0))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@ -808,7 +954,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_index, &properties))
|
||||
{
|
||||
MetaOutputInfo *output_info;
|
||||
gboolean primary, presentation;
|
||||
gboolean primary, presentation, underscanning;
|
||||
|
||||
if (output_index >= manager->n_outputs)
|
||||
{
|
||||
@ -827,6 +973,9 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
if (g_variant_lookup (properties, "presentation", "b", &presentation))
|
||||
output_info->is_presentation = presentation;
|
||||
|
||||
if (g_variant_lookup (properties, "underscanning", "b", &underscanning))
|
||||
output_info->is_underscanning = underscanning;
|
||||
|
||||
g_ptr_array_add (output_infos, output_info);
|
||||
}
|
||||
|
||||
@ -1194,37 +1343,58 @@ meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
|
||||
MetaOutput *old_outputs;
|
||||
MetaCRTC *old_crtcs;
|
||||
MetaMonitorMode *old_modes;
|
||||
unsigned int n_old_outputs, n_old_modes;
|
||||
unsigned int n_old_outputs, n_old_crtcs, n_old_modes;
|
||||
|
||||
/* Some implementations of read_current use the existing information
|
||||
* we have available, so don't free the old configuration until after
|
||||
* read_current finishes. */
|
||||
old_outputs = manager->outputs;
|
||||
n_old_outputs = manager->n_outputs;
|
||||
old_crtcs = manager->crtcs;
|
||||
n_old_crtcs = manager->n_crtcs;
|
||||
old_modes = manager->modes;
|
||||
n_old_modes = manager->n_modes;
|
||||
old_crtcs = manager->crtcs;
|
||||
|
||||
manager->serial++;
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
|
||||
|
||||
meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
|
||||
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
|
||||
g_free (old_crtcs);
|
||||
meta_monitor_manager_free_crtc_array (old_crtcs, n_old_crtcs);
|
||||
}
|
||||
|
||||
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);
|
||||
@ -1245,25 +1415,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
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include "meta-stage.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
|
@ -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,
|
||||
@ -266,10 +328,18 @@ meta_backend_native_init (MetaBackendNative *native)
|
||||
{
|
||||
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
|
||||
|
||||
/* We're a display server, so start talking to weston-launch. */
|
||||
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
|
||||
|
@ -26,11 +26,16 @@
|
||||
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <gbm.h>
|
||||
#include <xf86drm.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <meta/util.h>
|
||||
#include <meta/meta-backend.h>
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
#include "meta/boxes.h"
|
||||
|
||||
#ifndef DRM_CAP_CURSOR_WIDTH
|
||||
#define DRM_CAP_CURSOR_WIDTH 0x8
|
||||
@ -39,10 +44,28 @@
|
||||
#define DRM_CAP_CURSOR_HEIGHT 0x9
|
||||
#endif
|
||||
|
||||
/* When animating a cursor, we usually call drmModeSetCursor2 once per frame.
|
||||
* Though, testing shows that we need to triple buffer the cursor buffer in
|
||||
* order to avoid glitches when animating the cursor, at least when running on
|
||||
* Intel. The reason for this might be (but is not confirmed to be) due to
|
||||
* the user space gbm_bo cache, making us reuse and overwrite the kernel side
|
||||
* buffer content before it was scanned out. To avoid this, we keep a user space
|
||||
* reference to each buffer we set until at least one frame after it was drawn.
|
||||
* In effect, this means we three active cursor gbm_bo's: one that that just has
|
||||
* been set, one that was previously set and may or may not have been scanned
|
||||
* out, and one pending that will be replaced if the cursor sprite changes.
|
||||
*/
|
||||
#define HW_CURSOR_BUFFER_COUNT 3
|
||||
|
||||
static GQuark quark_cursor_sprite = 0;
|
||||
|
||||
struct _MetaCursorRendererNativePrivate
|
||||
{
|
||||
gboolean has_hw_cursor;
|
||||
|
||||
MetaCursorSprite *last_cursor;
|
||||
guint animation_timeout_id;
|
||||
|
||||
int drm_fd;
|
||||
struct gbm_device *gbm;
|
||||
|
||||
@ -51,77 +74,170 @@ struct _MetaCursorRendererNativePrivate
|
||||
};
|
||||
typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate;
|
||||
|
||||
typedef enum _MetaCursorGbmBoState
|
||||
{
|
||||
META_CURSOR_GBM_BO_STATE_NONE,
|
||||
META_CURSOR_GBM_BO_STATE_SET,
|
||||
META_CURSOR_GBM_BO_STATE_INVALIDATED,
|
||||
} MetaCursorGbmBoState;
|
||||
|
||||
typedef struct _MetaCursorNativePrivate
|
||||
{
|
||||
guint active_bo;
|
||||
MetaCursorGbmBoState pending_bo_state;
|
||||
struct gbm_bo *bos[HW_CURSOR_BUFFER_COUNT];
|
||||
} MetaCursorNativePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native, META_TYPE_CURSOR_RENDERER);
|
||||
|
||||
static MetaCursorNativePrivate *
|
||||
ensure_cursor_priv (MetaCursorSprite *cursor_sprite);
|
||||
|
||||
static void
|
||||
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);
|
||||
|
||||
G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static guint
|
||||
get_pending_cursor_sprite_gbm_bo_index (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
|
||||
return (cursor_priv->active_bo + 1) % HW_CURSOR_BUFFER_COUNT;
|
||||
}
|
||||
|
||||
static struct gbm_bo *
|
||||
get_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
guint pending_bo;
|
||||
|
||||
if (!cursor_priv)
|
||||
return NULL;
|
||||
|
||||
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
|
||||
return cursor_priv->bos[pending_bo];
|
||||
}
|
||||
|
||||
static struct gbm_bo *
|
||||
get_active_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
|
||||
if (!cursor_priv)
|
||||
return NULL;
|
||||
|
||||
return cursor_priv->bos[cursor_priv->active_bo];
|
||||
}
|
||||
|
||||
static void
|
||||
set_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite,
|
||||
struct gbm_bo *bo)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv;
|
||||
guint pending_bo;
|
||||
|
||||
cursor_priv = ensure_cursor_priv (cursor_sprite);
|
||||
|
||||
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
|
||||
cursor_priv->bos[pending_bo] = bo;
|
||||
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_SET;
|
||||
}
|
||||
|
||||
static void
|
||||
set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
MetaCRTC *crtc,
|
||||
MetaCursorReference *cursor,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
gboolean force)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
|
||||
if (crtc->cursor == cursor && !force)
|
||||
return;
|
||||
|
||||
crtc->cursor = cursor;
|
||||
|
||||
if (cursor)
|
||||
if (cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
struct gbm_bo *bo;
|
||||
union gbm_bo_handle handle;
|
||||
int hot_x, hot_y;
|
||||
|
||||
bo = meta_cursor_reference_get_gbm_bo (cursor, &hot_x, &hot_y);
|
||||
if (cursor_priv->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
|
||||
bo = get_pending_cursor_sprite_gbm_bo (cursor_sprite);
|
||||
else
|
||||
bo = get_active_cursor_sprite_gbm_bo (cursor_sprite);
|
||||
|
||||
if (!force && bo == crtc->cursor_renderer_private)
|
||||
return;
|
||||
|
||||
crtc->cursor_renderer_private = bo;
|
||||
|
||||
handle = gbm_bo_get_handle (bo);
|
||||
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
|
||||
|
||||
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
|
||||
priv->cursor_width, priv->cursor_height, hot_x, hot_y);
|
||||
|
||||
if (cursor_priv->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
|
||||
{
|
||||
cursor_priv->active_bo =
|
||||
(cursor_priv->active_bo + 1) % HW_CURSOR_BUFFER_COUNT;
|
||||
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
|
||||
if (force || crtc->cursor_renderer_private != NULL)
|
||||
{
|
||||
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
|
||||
crtc->cursor_renderer_private = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_hw_cursor (MetaCursorRendererNative *native,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
gboolean force)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
|
||||
const MetaRectangle *cursor_rect = meta_cursor_renderer_get_rect (renderer);
|
||||
MetaCursorReference *cursor = meta_cursor_renderer_get_cursor (renderer);
|
||||
MetaMonitorManager *monitors;
|
||||
MetaCRTC *crtcs;
|
||||
unsigned int i, n_crtcs;
|
||||
MetaRectangle rect;
|
||||
|
||||
monitors = meta_monitor_manager_get ();
|
||||
meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
|
||||
|
||||
if (cursor_sprite)
|
||||
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
|
||||
else
|
||||
rect = (MetaRectangle) { 0 };
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
gboolean crtc_should_have_cursor;
|
||||
MetaCursorReference *crtc_cursor;
|
||||
gboolean crtc_should_use_cursor;
|
||||
MetaCursorSprite *crtc_cursor;
|
||||
MetaRectangle *crtc_rect;
|
||||
|
||||
crtc_rect = &crtcs[i].rect;
|
||||
|
||||
crtc_should_have_cursor = (priv->has_hw_cursor && meta_rectangle_overlap (cursor_rect, crtc_rect));
|
||||
if (crtc_should_have_cursor)
|
||||
crtc_cursor = cursor;
|
||||
crtc_should_use_cursor = (priv->has_hw_cursor &&
|
||||
meta_rectangle_overlap (&rect, crtc_rect));
|
||||
if (crtc_should_use_cursor)
|
||||
crtc_cursor = cursor_sprite;
|
||||
else
|
||||
crtc_cursor = NULL;
|
||||
|
||||
@ -130,34 +246,350 @@ update_hw_cursor (MetaCursorRendererNative *native,
|
||||
if (crtc_cursor)
|
||||
{
|
||||
drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
|
||||
cursor_rect->x - crtc_rect->x,
|
||||
cursor_rect->y - crtc_rect->y);
|
||||
rect.x - crtc_rect->x,
|
||||
rect.y - crtc_rect->y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
should_have_hw_cursor (MetaCursorRenderer *renderer)
|
||||
has_valid_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorReference *cursor = meta_cursor_renderer_get_cursor (renderer);
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
|
||||
if (cursor)
|
||||
return (meta_cursor_reference_get_gbm_bo (cursor, NULL, NULL) != NULL);
|
||||
else
|
||||
return FALSE;
|
||||
switch (cursor_priv->pending_bo_state)
|
||||
{
|
||||
case META_CURSOR_GBM_BO_STATE_NONE:
|
||||
return get_active_cursor_sprite_gbm_bo (cursor_sprite) != NULL;
|
||||
case META_CURSOR_GBM_BO_STATE_SET:
|
||||
return TRUE;
|
||||
case META_CURSOR_GBM_BO_STATE_INVALIDATED:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
|
||||
should_have_hw_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
CoglTexture *texture;
|
||||
|
||||
if (!cursor_sprite)
|
||||
return FALSE;
|
||||
|
||||
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
if (!texture)
|
||||
return FALSE;
|
||||
|
||||
if (meta_cursor_sprite_get_texture_scale (cursor_sprite) != 1)
|
||||
return FALSE;
|
||||
|
||||
if (!has_valid_cursor_sprite_gbm_bo (cursor_sprite))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_native_update_animation (MetaCursorRendererNative *native)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
|
||||
MetaCursorSprite *cursor_sprite = meta_cursor_renderer_get_cursor (renderer);
|
||||
|
||||
priv->animation_timeout_id = 0;
|
||||
meta_cursor_sprite_tick_frame (cursor_sprite);
|
||||
meta_cursor_renderer_force_update (renderer);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_native_trigger_frame (MetaCursorRendererNative *native,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
gboolean cursor_change;
|
||||
guint delay;
|
||||
|
||||
cursor_change = cursor_sprite != priv->last_cursor;
|
||||
priv->last_cursor = cursor_sprite;
|
||||
|
||||
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_sprite && meta_cursor_sprite_is_animated (cursor_sprite))
|
||||
{
|
||||
delay = meta_cursor_sprite_get_current_frame_time (cursor_sprite);
|
||||
|
||||
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,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
|
||||
priv->has_hw_cursor = should_have_hw_cursor (renderer);
|
||||
update_hw_cursor (native, FALSE);
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_realize_texture (cursor_sprite);
|
||||
|
||||
meta_cursor_renderer_native_trigger_frame (native, cursor_sprite);
|
||||
|
||||
priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite);
|
||||
update_hw_cursor (native, cursor_sprite, FALSE);
|
||||
return priv->has_hw_cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
get_hardware_cursor_size (MetaCursorRendererNative *native,
|
||||
uint64_t *width, uint64_t *height)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (native);
|
||||
|
||||
*width = priv->cursor_width;
|
||||
*height = priv->cursor_height;
|
||||
}
|
||||
|
||||
static void
|
||||
cursor_priv_free (gpointer data)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv = data;
|
||||
guint i;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
for (i = 0; i < HW_CURSOR_BUFFER_COUNT; i++)
|
||||
g_clear_pointer (&cursor_priv->bos[0], (GDestroyNotify) gbm_bo_destroy);
|
||||
g_slice_free (MetaCursorNativePrivate, cursor_priv);
|
||||
}
|
||||
|
||||
static MetaCursorNativePrivate *
|
||||
ensure_cursor_priv (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
|
||||
if (!cursor_priv)
|
||||
{
|
||||
cursor_priv = g_slice_new0 (MetaCursorNativePrivate);
|
||||
g_object_set_qdata_full (G_OBJECT (cursor_sprite),
|
||||
quark_cursor_sprite,
|
||||
cursor_priv,
|
||||
cursor_priv_free);
|
||||
}
|
||||
|
||||
return cursor_priv;
|
||||
}
|
||||
|
||||
static void
|
||||
load_cursor_sprite_gbm_buffer (MetaCursorRendererNative *native,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
uint8_t *pixels,
|
||||
uint width,
|
||||
uint height,
|
||||
int rowstride,
|
||||
uint32_t gbm_format)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (native);
|
||||
uint64_t cursor_width, cursor_height;
|
||||
|
||||
get_hardware_cursor_size (native, &cursor_width, &cursor_height);
|
||||
|
||||
if (width > cursor_width || height > cursor_height)
|
||||
{
|
||||
meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
|
||||
(unsigned int)cursor_width, (unsigned int)cursor_height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gbm_device_is_format_supported (priv->gbm, gbm_format,
|
||||
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
|
||||
{
|
||||
struct gbm_bo *bo;
|
||||
uint8_t buf[4 * cursor_width * cursor_height];
|
||||
uint i;
|
||||
|
||||
bo = gbm_bo_create (priv->gbm, cursor_width, cursor_height,
|
||||
gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
||||
if (!bo)
|
||||
{
|
||||
meta_warning ("Failed to allocate HW cursor buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset (buf, 0, sizeof(buf));
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
|
||||
if (gbm_bo_write (bo, buf, cursor_width * cursor_height * 4) != 0)
|
||||
{
|
||||
meta_warning ("Failed to write cursors buffer data: %s",
|
||||
g_strerror (errno));
|
||||
gbm_bo_destroy (bo);
|
||||
return;
|
||||
}
|
||||
|
||||
set_pending_cursor_sprite_gbm_bo (cursor_sprite, bo);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
invalidate_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorNativePrivate *cursor_priv =
|
||||
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
|
||||
guint pending_bo;
|
||||
|
||||
if (!cursor_priv)
|
||||
return;
|
||||
|
||||
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
|
||||
g_clear_pointer (&cursor_priv->bos[pending_bo],
|
||||
(GDestroyNotify) gbm_bo_destroy);
|
||||
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_INVALIDATED;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
static void
|
||||
meta_cursor_renderer_native_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
struct wl_resource *buffer)
|
||||
{
|
||||
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (native);
|
||||
uint32_t gbm_format;
|
||||
uint64_t cursor_width, cursor_height;
|
||||
CoglTexture *texture;
|
||||
uint width, height;
|
||||
|
||||
/* Destroy any previous pending cursor buffer; we'll always either fail (which
|
||||
* should unset, or succeed, which will set new buffer.
|
||||
*/
|
||||
invalidate_pending_cursor_sprite_gbm_bo (cursor_sprite);
|
||||
|
||||
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
|
||||
width = cogl_texture_get_width (texture);
|
||||
height = cogl_texture_get_height (texture);
|
||||
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
|
||||
if (shm_buffer)
|
||||
{
|
||||
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
|
||||
uint8_t *buffer_data;
|
||||
|
||||
wl_shm_buffer_begin_access (shm_buffer);
|
||||
|
||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
||||
{
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#else
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
}
|
||||
|
||||
buffer_data = wl_shm_buffer_get_data (shm_buffer);
|
||||
load_cursor_sprite_gbm_buffer (native,
|
||||
cursor_sprite,
|
||||
buffer_data,
|
||||
width, height, rowstride,
|
||||
gbm_format);
|
||||
|
||||
wl_shm_buffer_end_access (shm_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct gbm_bo *bo;
|
||||
|
||||
/* HW cursors have a predefined size (at least 64x64), which usually is
|
||||
* bigger than cursor theme size, so themed cursors must be padded with
|
||||
* transparent pixels to fill the overlay. This is trivial if we have CPU
|
||||
* access to the data, but it's not possible if the buffer is in GPU
|
||||
* memory (and possibly tiled too), so if we don't get the right size, we
|
||||
* fallback to GL. */
|
||||
get_hardware_cursor_size (native, &cursor_width, &cursor_height);
|
||||
|
||||
if (width != cursor_width || height != cursor_height)
|
||||
{
|
||||
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bo = gbm_bo_import (priv->gbm,
|
||||
GBM_BO_IMPORT_WL_BUFFER,
|
||||
buffer,
|
||||
GBM_BO_USE_CURSOR);
|
||||
if (!bo)
|
||||
{
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
set_pending_cursor_sprite_gbm_bo (cursor_sprite, bo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_native_realize_cursor_from_xcursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite,
|
||||
XcursorImage *xc_image)
|
||||
{
|
||||
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
|
||||
|
||||
invalidate_pending_cursor_sprite_gbm_bo (cursor_sprite);
|
||||
|
||||
load_cursor_sprite_gbm_buffer (native,
|
||||
cursor_sprite,
|
||||
(uint8_t *) xc_image->pixels,
|
||||
xc_image->width,
|
||||
xc_image->height,
|
||||
xc_image->width * 4,
|
||||
GBM_FORMAT_ARGB8888);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
|
||||
{
|
||||
@ -166,6 +598,22 @@ meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
|
||||
|
||||
object_class->finalize = meta_cursor_renderer_native_finalize;
|
||||
renderer_class->update_cursor = meta_cursor_renderer_native_update_cursor;
|
||||
#ifdef HAVE_WAYLAND
|
||||
renderer_class->realize_cursor_from_wl_buffer =
|
||||
meta_cursor_renderer_native_realize_cursor_from_wl_buffer;
|
||||
#endif
|
||||
renderer_class->realize_cursor_from_xcursor =
|
||||
meta_cursor_renderer_native_realize_cursor_from_xcursor;
|
||||
|
||||
quark_cursor_sprite = g_quark_from_static_string ("-meta-cursor-native");
|
||||
}
|
||||
|
||||
static void
|
||||
force_update_hw_cursor (MetaCursorRendererNative *native)
|
||||
{
|
||||
MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
|
||||
|
||||
update_hw_cursor (native, meta_cursor_renderer_get_cursor (renderer), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -173,7 +621,7 @@ on_monitors_changed (MetaMonitorManager *monitors,
|
||||
MetaCursorRendererNative *native)
|
||||
{
|
||||
/* Our tracking is all messed up, so force an update. */
|
||||
update_hw_cursor (native, TRUE);
|
||||
force_update_hw_cursor (native);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -218,18 +666,8 @@ meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *native)
|
||||
return priv->gbm;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_native_get_cursor_size (MetaCursorRendererNative *native,
|
||||
uint64_t *width, uint64_t *height)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
|
||||
*width = priv->cursor_width;
|
||||
*height = priv->cursor_height;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
|
||||
{
|
||||
update_hw_cursor (native, TRUE);
|
||||
force_update_hw_cursor (native);
|
||||
}
|
||||
|
@ -37,12 +37,14 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <systemd/sd-login.h>
|
||||
#include <gudev/gudev.h>
|
||||
|
||||
#include "dbus-utils.h"
|
||||
#include "meta-dbus-login1.h"
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
#include "meta-idle-monitor-native.h"
|
||||
|
||||
struct _MetaLauncher
|
||||
{
|
||||
@ -52,12 +54,27 @@ struct _MetaLauncher
|
||||
gboolean session_active;
|
||||
};
|
||||
|
||||
static void
|
||||
report_error_and_die (const char *prefix,
|
||||
GError *error)
|
||||
{
|
||||
/* if a function returns due to g_return_val_if_fail,
|
||||
* then the error may not be set */
|
||||
if (error)
|
||||
g_error ("%s: %s", prefix, error->message);
|
||||
else
|
||||
g_error ("%s", prefix);
|
||||
|
||||
/* the error is not freed, but it is ok as g_error aborts the process */
|
||||
}
|
||||
|
||||
static Login1Session *
|
||||
get_session_proxy (GCancellable *cancellable)
|
||||
{
|
||||
char *proxy_path;
|
||||
char *session_id;
|
||||
Login1Session *session_proxy;
|
||||
GError *error = NULL;
|
||||
|
||||
if (sd_pid_get_session (getpid (), &session_id) < 0)
|
||||
return NULL;
|
||||
@ -68,7 +85,10 @@ get_session_proxy (GCancellable *cancellable)
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
proxy_path,
|
||||
cancellable, NULL);
|
||||
cancellable, &error);
|
||||
if (!session_proxy)
|
||||
report_error_and_die ("Failed getting session proxy", error);
|
||||
|
||||
free (proxy_path);
|
||||
|
||||
return session_proxy;
|
||||
@ -77,22 +97,27 @@ get_session_proxy (GCancellable *cancellable)
|
||||
static Login1Seat *
|
||||
get_seat_proxy (GCancellable *cancellable)
|
||||
{
|
||||
return login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1/seat/self",
|
||||
cancellable, NULL);
|
||||
GError *error = NULL;
|
||||
Login1Seat *seat = login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1/seat/self",
|
||||
cancellable, &error);
|
||||
if (!seat)
|
||||
report_error_and_die ("Could not get seat proxy", error);
|
||||
|
||||
return seat;
|
||||
}
|
||||
|
||||
static void
|
||||
session_unpause (void)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
ClutterBackend *clutter_backend;
|
||||
CoglContext *cogl_context;
|
||||
CoglDisplay *cogl_display;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
clutter_backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
cogl_display = cogl_context_get_display (cogl_context);
|
||||
cogl_kms_display_queue_modes_reset (cogl_display);
|
||||
|
||||
@ -110,6 +135,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 +154,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 +167,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 +182,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 +199,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
|
||||
@ -241,7 +247,7 @@ on_evdev_device_close (int fd,
|
||||
if (!get_device_info_from_fd (fd, &major, &minor))
|
||||
{
|
||||
g_warning ("Could not get device info for fd %d: %m", fd);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!login1_session_call_release_device_sync (self->session_proxy,
|
||||
@ -250,6 +256,9 @@ on_evdev_device_close (int fd,
|
||||
{
|
||||
g_warning ("Could not release device %d,%d: %s", major, minor, error->message);
|
||||
}
|
||||
|
||||
out:
|
||||
close (fd);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -277,31 +286,115 @@ on_active_changed (Login1Session *session,
|
||||
sync_active (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static gchar *
|
||||
get_primary_gpu_path (const gchar *seat_name)
|
||||
{
|
||||
const gchar *subsystems[] = {"drm", NULL};
|
||||
gchar *path = NULL;
|
||||
GList *devices, *tmp;
|
||||
|
||||
GUdevClient *gudev_client = g_udev_client_new (subsystems);
|
||||
GUdevEnumerator *enumerator = g_udev_enumerator_new (gudev_client);
|
||||
|
||||
g_udev_enumerator_add_match_name (enumerator, "card*");
|
||||
g_udev_enumerator_add_match_tag (enumerator, "seat");
|
||||
|
||||
devices = g_udev_enumerator_execute (enumerator);
|
||||
if (!devices)
|
||||
goto out;
|
||||
|
||||
for (tmp = devices; tmp != NULL; tmp = tmp->next)
|
||||
{
|
||||
GUdevDevice *pci_device;
|
||||
GUdevDevice *dev = tmp->data;
|
||||
gint boot_vga;
|
||||
const gchar *device_seat;
|
||||
|
||||
/* filter out devices that are not character device, like card0-VGA-1 */
|
||||
if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
|
||||
continue;
|
||||
|
||||
device_seat = g_udev_device_get_property (dev, "ID_SEAT");
|
||||
if (!device_seat)
|
||||
{
|
||||
/* when ID_SEAT is not set, it means seat0 */
|
||||
device_seat = "seat0";
|
||||
}
|
||||
else if (g_strcmp0 (device_seat, "seat0") != 0)
|
||||
{
|
||||
/* if the device has been explicitly assigned other seat
|
||||
* than seat0, it is probably the right device to use */
|
||||
path = g_strdup (g_udev_device_get_device_file (dev));
|
||||
break;
|
||||
}
|
||||
|
||||
/* skip devices that do not belong to our seat */
|
||||
if (g_strcmp0 (seat_name, device_seat))
|
||||
continue;
|
||||
|
||||
pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
|
||||
if (!pci_device)
|
||||
continue;
|
||||
|
||||
/* get value of boot_vga attribute or 0 if the device has no boot_vga */
|
||||
boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
|
||||
g_object_unref (pci_device);
|
||||
|
||||
if (boot_vga == 1)
|
||||
{
|
||||
/* found the boot_vga device */
|
||||
path = g_strdup (g_udev_device_get_device_file (dev));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free_full (devices, g_object_unref);
|
||||
|
||||
out:
|
||||
g_object_unref (enumerator);
|
||||
g_object_unref (gudev_client);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
static void
|
||||
get_kms_fd (Login1Session *session_proxy,
|
||||
const gchar *seat_id,
|
||||
int *fd_out)
|
||||
{
|
||||
int major, minor;
|
||||
int fd;
|
||||
gchar *path;
|
||||
GError *error = NULL;
|
||||
|
||||
/* XXX -- use udev to find the DRM master device */
|
||||
if (!get_device_info_from_path ("/dev/dri/card0", &major, &minor))
|
||||
{
|
||||
g_warning ("Could not stat /dev/dri/card0: %m");
|
||||
return FALSE;
|
||||
}
|
||||
path = get_primary_gpu_path (seat_id);
|
||||
if (!path)
|
||||
g_error ("could not find drm kms device");
|
||||
|
||||
if (!get_device_info_from_path (path, &major, &minor))
|
||||
g_error ("Could not stat %s: %m", path);
|
||||
|
||||
g_free (path);
|
||||
|
||||
if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
|
||||
{
|
||||
g_warning ("Could not open DRM device: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
report_error_and_die ("Could not open DRM device", error);
|
||||
|
||||
*fd_out = fd;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
static gchar *
|
||||
get_seat_id (void)
|
||||
{
|
||||
char *session_id, *seat_id = NULL;
|
||||
|
||||
if (sd_pid_get_session (0, &session_id) < 0)
|
||||
return NULL;
|
||||
|
||||
/* on error the seat_id will remain NULL */
|
||||
sd_session_get_seat (session_id, &seat_id);
|
||||
free (session_id);
|
||||
|
||||
return seat_id;
|
||||
}
|
||||
|
||||
MetaLauncher *
|
||||
@ -309,22 +402,23 @@ meta_launcher_new (void)
|
||||
{
|
||||
MetaLauncher *self = NULL;
|
||||
Login1Session *session_proxy;
|
||||
char *seat_id;
|
||||
GError *error = NULL;
|
||||
int kms_fd;
|
||||
|
||||
session_proxy = get_session_proxy (NULL);
|
||||
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error))
|
||||
{
|
||||
g_warning ("Could not take control: %s", error->message);
|
||||
g_error_free (error);
|
||||
goto out;
|
||||
}
|
||||
report_error_and_die ("Could not take control", error);
|
||||
|
||||
if (!get_kms_fd (session_proxy, &kms_fd))
|
||||
goto out;
|
||||
seat_id = get_seat_id ();
|
||||
if (!seat_id)
|
||||
g_error ("Failed getting seat id");
|
||||
|
||||
get_kms_fd (session_proxy, seat_id, &kms_fd);
|
||||
free (seat_id);
|
||||
|
||||
self = g_slice_new0 (MetaLauncher);
|
||||
self->session_proxy = g_object_ref (session_proxy);
|
||||
self->session_proxy = session_proxy;
|
||||
self->seat_proxy = get_seat_proxy (NULL);
|
||||
|
||||
self->session_active = TRUE;
|
||||
@ -336,9 +430,6 @@ meta_launcher_new (void)
|
||||
|
||||
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
||||
|
||||
out:
|
||||
g_object_unref (session_proxy);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -55,8 +55,19 @@ 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 {
|
||||
uint32_t underscan_prop_id;
|
||||
uint32_t underscan_hborder_prop_id;
|
||||
uint32_t underscan_vborder_prop_id;
|
||||
} MetaCRTCKms;
|
||||
|
||||
struct _MetaMonitorManagerKms
|
||||
{
|
||||
MetaMonitorManager parent_instance;
|
||||
@ -104,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;
|
||||
|
||||
@ -137,6 +148,12 @@ meta_monitor_mode_destroy_notify (MetaMonitorMode *output)
|
||||
g_slice_free (drmModeModeInfo, output->driver_private);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_crtc_destroy_notify (MetaCRTC *crtc)
|
||||
{
|
||||
g_free (crtc->driver_private);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drm_mode_equal (gconstpointer one,
|
||||
gconstpointer two)
|
||||
@ -181,24 +198,67 @@ drm_mode_hash (gconstpointer ptr)
|
||||
}
|
||||
|
||||
static void
|
||||
find_properties (MetaMonitorManagerKms *manager_kms,
|
||||
MetaOutputKms *output_kms)
|
||||
find_connector_properties (MetaMonitorManagerKms *manager_kms,
|
||||
MetaOutputKms *output_kms)
|
||||
{
|
||||
drmModePropertyPtr prop;
|
||||
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++)
|
||||
{
|
||||
prop = drmModeGetProperty (manager_kms->fd, output_kms->connector->props[i]);
|
||||
drmModePropertyPtr prop = drmModeGetProperty (manager_kms->fd, output_kms->connector->props[i]);
|
||||
if (!prop)
|
||||
continue;
|
||||
|
||||
if ((prop->flags & DRM_MODE_PROP_ENUM) &&
|
||||
strcmp(prop->name, "DPMS") == 0)
|
||||
if ((prop->flags & DRM_MODE_PROP_ENUM) && strcmp (prop->name, "DPMS") == 0)
|
||||
output_kms->dpms_prop_id = prop->prop_id;
|
||||
else if ((prop->flags & DRM_MODE_PROP_BLOB) &&
|
||||
strcmp (prop->name, "EDID") == 0)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
find_crtc_properties (MetaMonitorManagerKms *manager_kms,
|
||||
MetaCRTC *meta_crtc)
|
||||
{
|
||||
MetaCRTCKms *crtc_kms;
|
||||
drmModeObjectPropertiesPtr props;
|
||||
size_t i;
|
||||
|
||||
crtc_kms = meta_crtc->driver_private;
|
||||
|
||||
props = drmModeObjectGetProperties (manager_kms->fd, meta_crtc->crtc_id, DRM_MODE_OBJECT_CRTC);
|
||||
if (!props)
|
||||
return;
|
||||
|
||||
for (i = 0; i < props->count_props; i++)
|
||||
{
|
||||
drmModePropertyPtr prop = drmModeGetProperty (manager_kms->fd, props->props[i]);
|
||||
if (!prop)
|
||||
continue;
|
||||
|
||||
if ((prop->flags & DRM_MODE_PROP_ENUM) && strcmp (prop->name, "underscan") == 0)
|
||||
crtc_kms->underscan_prop_id = prop->prop_id;
|
||||
else if ((prop->flags & DRM_MODE_PROP_RANGE) && strcmp (prop->name, "underscan hborder") == 0)
|
||||
crtc_kms->underscan_hborder_prop_id = prop->prop_id;
|
||||
else if ((prop->flags & DRM_MODE_PROP_RANGE) && strcmp (prop->name, "underscan vborder") == 0)
|
||||
crtc_kms->underscan_vborder_prop_id = prop->prop_id;
|
||||
|
||||
drmModeFreeProperty (prop);
|
||||
}
|
||||
@ -233,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)
|
||||
@ -442,6 +543,10 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
height = MAX (height, meta_crtc->rect.y + meta_crtc->rect.height);
|
||||
}
|
||||
|
||||
meta_crtc->driver_private = g_new0 (MetaCRTCKms, 1);
|
||||
meta_crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
|
||||
find_crtc_properties (manager_kms, meta_crtc);
|
||||
|
||||
drmModeFreeCrtc (crtc);
|
||||
}
|
||||
|
||||
@ -472,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)
|
||||
{
|
||||
@ -498,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;
|
||||
@ -567,8 +676,11 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_output->is_presentation = FALSE;
|
||||
}
|
||||
|
||||
find_properties (manager_kms, output_kms);
|
||||
|
||||
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);
|
||||
@ -578,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.
|
||||
|
||||
@ -723,8 +837,9 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
|
||||
if (output_kms->dpms_prop_id != 0)
|
||||
{
|
||||
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->winsys_id,
|
||||
output_kms->dpms_prop_id, state);
|
||||
int ok = drmModeObjectSetProperty (manager_kms->fd, meta_output->winsys_id,
|
||||
DRM_MODE_OBJECT_CONNECTOR,
|
||||
output_kms->dpms_prop_id, state);
|
||||
|
||||
if (ok < 0)
|
||||
meta_warning ("Failed to set power save mode for output %s: %s\n",
|
||||
@ -748,6 +863,48 @@ crtc_free (CoglKmsCrtc *crtc)
|
||||
g_slice_free (CoglKmsCrtc, crtc);
|
||||
}
|
||||
|
||||
static void
|
||||
set_underscan (MetaMonitorManagerKms *manager_kms,
|
||||
MetaOutput *output)
|
||||
{
|
||||
if (!output->crtc)
|
||||
return;
|
||||
|
||||
MetaCRTC *crtc = output->crtc;
|
||||
MetaCRTCKms *crtc_kms = crtc->driver_private;
|
||||
if (!crtc_kms->underscan_prop_id)
|
||||
return;
|
||||
|
||||
if (output->is_underscanning)
|
||||
{
|
||||
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC,
|
||||
crtc_kms->underscan_prop_id, (uint64_t) 1);
|
||||
|
||||
if (crtc_kms->underscan_hborder_prop_id)
|
||||
{
|
||||
uint64_t value = crtc->current_mode->width * 0.05;
|
||||
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC,
|
||||
crtc_kms->underscan_hborder_prop_id, value);
|
||||
}
|
||||
if (crtc_kms->underscan_vborder_prop_id)
|
||||
{
|
||||
uint64_t value = crtc->current_mode->height * 0.05;
|
||||
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC,
|
||||
crtc_kms->underscan_vborder_prop_id, value);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
|
||||
DRM_MODE_OBJECT_CRTC,
|
||||
crtc_kms->underscan_prop_id, (uint64_t) 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaCRTCInfo **crtcs,
|
||||
@ -755,6 +912,7 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
CoglDisplay *cogl_display;
|
||||
@ -900,6 +1058,9 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
|
||||
output->is_primary = output_info->is_primary;
|
||||
output->is_presentation = output_info->is_presentation;
|
||||
output->is_underscanning = output_info->is_underscanning;
|
||||
|
||||
set_underscan (manager_kms, output);
|
||||
}
|
||||
|
||||
/* Disable outputs not mentioned in the list */
|
||||
|
@ -40,12 +40,24 @@
|
||||
#include "meta-idle-monitor-xsync.h"
|
||||
#include "meta-monitor-manager-xrandr.h"
|
||||
#include "backends/meta-monitor-manager-dummy.h"
|
||||
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
|
||||
#include "meta-cursor-renderer-x11.h"
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "wayland/meta-wayland.h"
|
||||
#endif
|
||||
|
||||
#include <meta/util.h>
|
||||
#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 +65,8 @@ struct _MetaBackendX11Private
|
||||
xcb_connection_t *xcb;
|
||||
GSource *source;
|
||||
|
||||
MetaBackendX11Mode mode;
|
||||
|
||||
int xsync_event_base;
|
||||
int xsync_error_base;
|
||||
|
||||
@ -102,7 +116,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 +147,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 +157,14 @@ 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 &&
|
||||
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
|
||||
@ -250,6 +273,25 @@ handle_host_xevent (MetaBackend *backend,
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->mode == META_BACKEND_X11_MODE_NESTED && event->type == FocusIn)
|
||||
{
|
||||
#ifdef HAVE_WAYLAND
|
||||
Window xwin = meta_backend_x11_get_xwindow(x11);
|
||||
XEvent xev;
|
||||
|
||||
if (event->xfocus.window == xwin)
|
||||
{
|
||||
/* Since we've selected for KeymapStateMask, every FocusIn is followed immediately
|
||||
* by a KeymapNotify event */
|
||||
XMaskEvent(priv->xdisplay, KeymapStateMask, &xev);
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
meta_wayland_compositor_update_key_state (compositor, xev.xkeymap.key_vector, 32, 8);
|
||||
}
|
||||
#else
|
||||
g_assert_not_reached ();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
|
||||
handle_alarm_notify (backend, event);
|
||||
|
||||
@ -399,6 +441,7 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
int major, minor;
|
||||
gboolean has_xi = FALSE;
|
||||
|
||||
priv->xdisplay = clutter_x11_get_default_display ();
|
||||
|
||||
@ -408,29 +451,27 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
||||
!XSyncInitialize (priv->xdisplay, &major, &minor))
|
||||
meta_fatal ("Could not initialize XSync");
|
||||
|
||||
{
|
||||
int major = 2, minor = 3;
|
||||
gboolean has_xi = FALSE;
|
||||
if (XQueryExtension (priv->xdisplay,
|
||||
"XInputExtension",
|
||||
&priv->xinput_opcode,
|
||||
&priv->xinput_error_base,
|
||||
&priv->xinput_event_base))
|
||||
{
|
||||
major = 2; minor = 3;
|
||||
if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
|
||||
{
|
||||
int version = (major * 10) + minor;
|
||||
if (version >= 22)
|
||||
has_xi = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (XQueryExtension (priv->xdisplay,
|
||||
"XInputExtension",
|
||||
&priv->xinput_opcode,
|
||||
&priv->xinput_error_base,
|
||||
&priv->xinput_event_base))
|
||||
{
|
||||
if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
|
||||
{
|
||||
int version = (major * 10) + minor;
|
||||
if (version >= 22)
|
||||
has_xi = TRUE;
|
||||
}
|
||||
}
|
||||
if (!has_xi)
|
||||
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
|
||||
|
||||
if (!has_xi)
|
||||
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,19 +502,37 @@ 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 *
|
||||
meta_backend_x11_create_cursor_renderer (MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
switch (priv->mode)
|
||||
{
|
||||
case META_BACKEND_X11_MODE_COMPOSITOR:
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
|
||||
break;
|
||||
case META_BACKEND_X11_MODE_NESTED:
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, NULL);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -701,6 +760,9 @@ meta_backend_x11_get_keymap (MetaBackend *backend)
|
||||
priv->xcb,
|
||||
xkb_x11_get_core_keyboard_device_id (priv->xcb),
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
if (priv->keymap == NULL)
|
||||
priv->keymap = xkb_keymap_new_from_names (context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
|
||||
xkb_context_unref (context);
|
||||
}
|
||||
|
||||
@ -721,7 +783,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.
|
||||
@ -730,8 +795,6 @@ meta_backend_x11_update_screen_size (MetaBackend *backend,
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
Window xwin = meta_backend_x11_get_xwindow (x11);
|
||||
XResizeWindow (priv->xdisplay, xwin, width, height);
|
||||
}
|
||||
@ -755,10 +818,36 @@ 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);
|
||||
|
||||
if (priv->mode == META_BACKEND_X11_MODE_NESTED)
|
||||
{
|
||||
/* We have no way of tracking key changes when the stage doesn't have
|
||||
* focus, so we select for KeymapStateMask so that we get a complete
|
||||
* dump of the keyboard state in a KeymapNotify event that immediately
|
||||
* follows each FocusIn (and EnterNotify, but we ignore that.)
|
||||
*/
|
||||
XWindowAttributes xwa;
|
||||
|
||||
XGetWindowAttributes(priv->xdisplay, xwin, &xwa);
|
||||
XSelectInput(priv->xdisplay, xwin,
|
||||
xwa.your_event_mask | FocusChangeMask | KeymapStateMask);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -783,8 +872,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 *
|
||||
|
@ -40,25 +40,29 @@ typedef struct _MetaCursorRendererX11Private MetaCursorRendererX11Private;
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER);
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer)
|
||||
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer);
|
||||
MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11);
|
||||
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Window xwindow = meta_backend_x11_get_xwindow (backend);
|
||||
|
||||
if (xwindow == None)
|
||||
return FALSE;
|
||||
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
|
||||
MetaCursorReference *cursor_ref = meta_cursor_renderer_get_cursor (renderer);
|
||||
if (xwindow == None)
|
||||
{
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_realize_texture (cursor_sprite);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean has_server_cursor = FALSE;
|
||||
|
||||
if (cursor_ref)
|
||||
if (cursor_sprite)
|
||||
{
|
||||
MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref);
|
||||
MetaCursor cursor = meta_cursor_sprite_get_meta_cursor (cursor_sprite);
|
||||
|
||||
if (cursor != META_CURSOR_NONE)
|
||||
{
|
||||
Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor);
|
||||
@ -80,6 +84,9 @@ meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer)
|
||||
priv->server_cursor_visible = has_server_cursor;
|
||||
}
|
||||
|
||||
if (!priv->server_cursor_visible && cursor_sprite)
|
||||
meta_cursor_sprite_realize_texture (cursor_sprite);
|
||||
|
||||
return priv->server_cursor_visible;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -180,7 +240,7 @@ meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
guint button)
|
||||
{
|
||||
change_property (device, "libinput Scroll Method Enabled",
|
||||
change_property (device, "libinput Button Scrolling Button",
|
||||
XA_INTEGER, 32, &button, 1);
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -225,6 +221,76 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
return output_get_boolean_property (manager_xrandr, output, "_MUTTER_PRESENTATION_OUTPUT");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
Atom atom, actual_type;
|
||||
int actual_format;
|
||||
unsigned long nitems, bytes_after;
|
||||
g_autofree unsigned char *buffer = NULL;
|
||||
g_autofree char *str = NULL;
|
||||
|
||||
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;
|
||||
|
||||
str = XGetAtomName (manager_xrandr->xdisplay, *(Atom *)buffer);
|
||||
return (strcmp (str, "on") == 0);
|
||||
}
|
||||
|
||||
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
|
||||
normalize_backlight (MetaOutput *output,
|
||||
int hw_value)
|
||||
@ -241,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,
|
||||
@ -252,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
|
||||
@ -270,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);
|
||||
|
||||
@ -288,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
|
||||
@ -376,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)
|
||||
@ -447,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,
|
||||
@ -462,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
|
||||
@ -506,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"))
|
||||
@ -704,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++)
|
||||
@ -756,6 +848,8 @@ 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))
|
||||
@ -869,11 +963,58 @@ 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
|
||||
output_set_underscanning_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output,
|
||||
gboolean underscanning)
|
||||
{
|
||||
Atom prop, valueatom;
|
||||
const char *value;
|
||||
|
||||
prop = XInternAtom (manager_xrandr->xdisplay, "underscan", False);
|
||||
|
||||
value = underscanning ? "on" : "off";
|
||||
valueatom = XInternAtom (manager_xrandr->xdisplay, value, False);
|
||||
|
||||
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
|
||||
* make the border configurable. */
|
||||
if (underscanning)
|
||||
{
|
||||
uint32_t border_value;
|
||||
|
||||
prop = XInternAtom (manager_xrandr->xdisplay, "underscan hborder", False);
|
||||
border_value = output->crtc->current_mode->width * 0.05;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -992,17 +1133,16 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
if (crtc_info->mode != NULL)
|
||||
{
|
||||
MetaMonitorMode *mode;
|
||||
XID *outputs;
|
||||
unsigned int j, n_outputs;
|
||||
int width, height;
|
||||
g_autofree XID *output_ids = NULL;
|
||||
unsigned int j, n_output_ids;
|
||||
Status ok;
|
||||
|
||||
mode = crtc_info->mode;
|
||||
|
||||
n_outputs = crtc_info->outputs->len;
|
||||
outputs = g_new (XID, n_outputs);
|
||||
n_output_ids = crtc_info->outputs->len;
|
||||
output_ids = g_new (XID, n_output_ids);
|
||||
|
||||
for (j = 0; j < n_outputs; j++)
|
||||
for (j = 0; j < n_output_ids; j++)
|
||||
{
|
||||
MetaOutput *output;
|
||||
|
||||
@ -1011,7 +1151,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
|
||||
outputs[j] = output->winsys_id;
|
||||
output_ids[j] = output->winsys_id;
|
||||
}
|
||||
|
||||
ok = XRRSetCrtcConfig (manager_xrandr->xdisplay,
|
||||
@ -1021,7 +1161,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
crtc_info->x, crtc_info->y,
|
||||
(XID)mode->mode_id,
|
||||
meta_monitor_transform_to_xrandr (crtc_info->transform),
|
||||
outputs, n_outputs);
|
||||
output_ids, n_output_ids);
|
||||
|
||||
if (ok != Success)
|
||||
{
|
||||
@ -1029,7 +1169,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))
|
||||
@ -1049,9 +1189,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1071,8 +1208,14 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
output_info->output,
|
||||
output_info->is_presentation);
|
||||
|
||||
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;
|
||||
output->is_underscanning = output_info->is_underscanning;
|
||||
}
|
||||
|
||||
/* Disable outputs not mentioned in the list */
|
||||
@ -1106,11 +1249,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);
|
||||
@ -1158,6 +1302,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)
|
||||
{
|
||||
@ -1173,6 +1399,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,
|
||||
@ -1180,6 +1407,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
|
||||
}
|
||||
}
|
||||
|
||||
@ -1210,6 +1448,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
|
||||
|
89
src/backends/x11/nested/meta-cursor-renderer-x11-nested.c
Normal file
89
src/backends/x11/nested/meta-cursor-renderer-x11-nested.c
Normal file
@ -0,0 +1,89 @@
|
||||
/* -*- 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>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
|
||||
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
struct _MetaCursorRendererX11Nested
|
||||
{
|
||||
MetaCursorRenderer parent;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaCursorRendererX11Nested, meta_cursor_renderer_x11_nested,
|
||||
META_TYPE_CURSOR_RENDERER);
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_x11_nested_update_cursor (MetaCursorRenderer *renderer,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
if (cursor_sprite)
|
||||
meta_cursor_sprite_realize_texture (cursor_sprite);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static Cursor
|
||||
create_empty_cursor (Display *xdisplay)
|
||||
{
|
||||
XcursorImage *image;
|
||||
XcursorPixel *pixels;
|
||||
Cursor xcursor;
|
||||
|
||||
image = XcursorImageCreate (1, 1);
|
||||
if (image == NULL)
|
||||
return None;
|
||||
|
||||
image->xhot = 0;
|
||||
image->yhot = 0;
|
||||
|
||||
pixels = image->pixels;
|
||||
pixels[0] = 0;
|
||||
|
||||
xcursor = XcursorImageLoadCursor (xdisplay, image);
|
||||
XcursorImageDestroy (image);
|
||||
|
||||
return xcursor;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_x11_nested_init (MetaCursorRendererX11Nested *x11_nested)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Window xwindow = meta_backend_x11_get_xwindow (backend);
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
|
||||
Cursor empty_xcursor = create_empty_cursor (xdisplay);
|
||||
XDefineCursor (xdisplay, xwindow, empty_xcursor);
|
||||
XFreeCursor (xdisplay, empty_xcursor);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_x11_nested_class_init (MetaCursorRendererX11NestedClass *klass)
|
||||
{
|
||||
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass);
|
||||
|
||||
renderer_class->update_cursor = meta_cursor_renderer_x11_nested_update_cursor;
|
||||
}
|
38
src/backends/x11/nested/meta-cursor-renderer-x11-nested.h
Normal file
38
src/backends/x11/nested/meta-cursor-renderer-x11-nested.h
Normal file
@ -0,0 +1,38 @@
|
||||
/* -*- 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_CURSOR_RENDERER_X11_NESTED_NESTED_H
|
||||
#define META_CURSOR_RENDERER_X11_NESTED_NESTED_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "backends/meta-cursor-renderer.h"
|
||||
|
||||
#define META_TYPE_CURSOR_RENDERER_X11_NESTED (meta_cursor_renderer_x11_nested_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaCursorRendererX11Nested,
|
||||
meta_cursor_renderer_x11_nested,
|
||||
META, CURSOR_RENDERER_X11_NESTED,
|
||||
MetaCursorRenderer);
|
||||
|
||||
#endif /* META_CURSOR_RENDERER_X11_NESTED_NESTED_H */
|
@ -15,7 +15,8 @@ struct _MetaCompositor
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
guint repaint_func_id;
|
||||
guint pre_paint_func_id;
|
||||
guint post_paint_func_id;
|
||||
|
||||
gint64 server_time_query_time;
|
||||
gint64 server_time_offset;
|
||||
@ -40,6 +41,7 @@ struct _MetaCompositor
|
||||
MetaPluginManager *plugin_mgr;
|
||||
|
||||
gboolean frame_has_updated_xsurfaces;
|
||||
gboolean have_x11_sync_object;
|
||||
};
|
||||
|
||||
/* Wait 2ms after vblank before starting to draw next frame */
|
||||
|
@ -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
|
||||
@ -79,6 +74,7 @@
|
||||
#include "frame.h"
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#include "meta-sync-ring.h"
|
||||
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
@ -125,7 +121,11 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
|
||||
void
|
||||
meta_compositor_destroy (MetaCompositor *compositor)
|
||||
{
|
||||
clutter_threads_remove_repaint_func (compositor->repaint_func_id);
|
||||
clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
|
||||
clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
|
||||
|
||||
if (compositor->have_x11_sync_object)
|
||||
meta_sync_ring_destroy ();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -468,13 +468,11 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
MetaDisplay *display = compositor->display;
|
||||
Display *xdisplay = display->xdisplay;
|
||||
MetaScreen *screen = display->screen;
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
meta_screen_set_cm_selection (display->screen);
|
||||
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
compositor->stage = meta_backend_get_stage (backend);
|
||||
}
|
||||
compositor->stage = meta_backend_get_stage (backend);
|
||||
|
||||
/* We use connect_after() here to accomodate code in GNOME Shell that,
|
||||
* when benchmarking drawing performance, connects to ::after-paint
|
||||
@ -510,7 +508,7 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
|
||||
compositor->output = screen->composite_overlay_window;
|
||||
|
||||
xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (meta_get_backend ()));
|
||||
xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (backend));
|
||||
|
||||
XReparentWindow (xdisplay, xwin, compositor->output, 0, 0);
|
||||
|
||||
@ -530,6 +528,8 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
* contents until we show the stage.
|
||||
*/
|
||||
XMapWindow (xdisplay, compositor->output);
|
||||
|
||||
compositor->have_x11_sync_object = meta_sync_ring_init (xdisplay);
|
||||
}
|
||||
|
||||
redirect_windows (display->screen);
|
||||
@ -731,6 +731,9 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
process_damage (compositor, (XDamageNotifyEvent *) event, window);
|
||||
}
|
||||
|
||||
if (compositor->have_x11_sync_object)
|
||||
meta_sync_ring_handle_event (event);
|
||||
|
||||
/* Clutter needs to know about MapNotify events otherwise it will
|
||||
think the stage is invisible */
|
||||
if (!meta_is_wayland_compositor () && event->type == MapNotify)
|
||||
@ -769,23 +772,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, which_change, old_frame_rect, old_buffer_rect);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1044,11 +1038,12 @@ frame_callback (CoglOnscreen *onscreen,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pre_paint_windows (MetaCompositor *compositor)
|
||||
static gboolean
|
||||
meta_pre_paint_func (gpointer data)
|
||||
{
|
||||
GList *l;
|
||||
MetaWindowActor *top_window;
|
||||
MetaCompositor *compositor = data;
|
||||
|
||||
if (compositor->onscreen == NULL)
|
||||
{
|
||||
@ -1060,7 +1055,7 @@ pre_paint_windows (MetaCompositor *compositor)
|
||||
}
|
||||
|
||||
if (compositor->windows == NULL)
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
top_window = g_list_last (compositor->windows)->data;
|
||||
|
||||
@ -1077,10 +1072,12 @@ pre_paint_windows (MetaCompositor *compositor)
|
||||
{
|
||||
/* We need to make sure that any X drawing that happens before
|
||||
* the XDamageSubtract() for each window above is visible to
|
||||
* subsequent GL rendering; the only standardized way to do this
|
||||
* is EXT_x11_sync_object, which isn't yet widely available. For
|
||||
* now, we count on details of Xorg and the open source drivers,
|
||||
* and hope for the best otherwise.
|
||||
* subsequent GL rendering; the standardized way to do this is
|
||||
* GL_EXT_X11_sync_object. Since this isn't implemented yet in
|
||||
* mesa, we also have a path that relies on the implementation
|
||||
* of the open source drivers.
|
||||
*
|
||||
* Anything else, we just hope for the best.
|
||||
*
|
||||
* Xorg and open source driver specifics:
|
||||
*
|
||||
@ -1095,17 +1092,28 @@ pre_paint_windows (MetaCompositor *compositor)
|
||||
* round trip request at this point is sufficient to flush the
|
||||
* GLX buffers.
|
||||
*/
|
||||
XSync (compositor->display->xdisplay, False);
|
||||
|
||||
compositor->frame_has_updated_xsurfaces = FALSE;
|
||||
if (compositor->have_x11_sync_object)
|
||||
compositor->have_x11_sync_object = meta_sync_ring_insert_wait ();
|
||||
else
|
||||
XSync (compositor->display->xdisplay, False);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_repaint_func (gpointer data)
|
||||
meta_post_paint_func (gpointer data)
|
||||
{
|
||||
MetaCompositor *compositor = data;
|
||||
pre_paint_windows (compositor);
|
||||
|
||||
if (compositor->frame_has_updated_xsurfaces)
|
||||
{
|
||||
if (compositor->have_x11_sync_object)
|
||||
compositor->have_x11_sync_object = meta_sync_ring_after_frame ();
|
||||
|
||||
compositor->frame_has_updated_xsurfaces = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1140,10 +1148,16 @@ meta_compositor_new (MetaDisplay *display)
|
||||
G_CALLBACK (on_shadow_factory_changed),
|
||||
compositor);
|
||||
|
||||
compositor->repaint_func_id = clutter_threads_add_repaint_func (meta_repaint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
|
||||
compositor->pre_paint_func_id =
|
||||
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_PRE_PAINT,
|
||||
meta_pre_paint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
compositor->post_paint_func_id =
|
||||
clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
|
||||
meta_post_paint_func,
|
||||
compositor,
|
||||
NULL);
|
||||
return compositor;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "meta-background-private.h"
|
||||
#include "cogl-utils.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
enum
|
||||
{
|
||||
CHANGED,
|
||||
@ -71,6 +73,8 @@ enum
|
||||
|
||||
G_DEFINE_TYPE (MetaBackground, meta_background, G_TYPE_OBJECT)
|
||||
|
||||
static gboolean texture_has_alpha (CoglTexture *texture);
|
||||
|
||||
static GSList *all_backgrounds = NULL;
|
||||
|
||||
static void
|
||||
@ -474,7 +478,7 @@ get_texture_area (MetaBackground *self,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
draw_texture (MetaBackground *self,
|
||||
CoglFramebuffer *framebuffer,
|
||||
CoglPipeline *pipeline,
|
||||
@ -483,6 +487,7 @@ draw_texture (MetaBackground *self,
|
||||
{
|
||||
MetaBackgroundPrivate *priv = self->priv;
|
||||
cairo_rectangle_int_t texture_area;
|
||||
gboolean bare_region_visible;
|
||||
|
||||
get_texture_area (self, monitor_area, texture, &texture_area);
|
||||
|
||||
@ -503,6 +508,9 @@ draw_texture (MetaBackground *self,
|
||||
- texture_area.y / (float)texture_area.height,
|
||||
(monitor_area->width - texture_area.x) / (float)texture_area.width,
|
||||
(monitor_area->height - texture_area.y) / (float)texture_area.height);
|
||||
|
||||
bare_region_visible = texture_has_alpha (texture);
|
||||
|
||||
/* Draw just the texture */
|
||||
break;
|
||||
case G_DESKTOP_BACKGROUND_STYLE_CENTERED:
|
||||
@ -513,11 +521,16 @@ draw_texture (MetaBackground *self,
|
||||
texture_area.x + texture_area.width,
|
||||
texture_area.y + texture_area.height,
|
||||
0, 0, 1.0, 1.0);
|
||||
bare_region_visible = texture_has_alpha (texture) || memcmp (&texture_area, monitor_area, sizeof (cairo_rectangle_int_t)) != 0;
|
||||
break;
|
||||
case G_DESKTOP_BACKGROUND_STYLE_NONE:
|
||||
bare_region_visible = TRUE;
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached();
|
||||
g_return_val_if_reached(FALSE);
|
||||
}
|
||||
|
||||
return bare_region_visible;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -748,6 +761,7 @@ meta_background_get_texture (MetaBackground *self,
|
||||
if (monitor->dirty)
|
||||
{
|
||||
CoglError *catch_error = NULL;
|
||||
gboolean bare_region_visible = FALSE;
|
||||
|
||||
if (monitor->texture == NULL)
|
||||
{
|
||||
@ -783,9 +797,9 @@ meta_background_get_texture (MetaBackground *self,
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, texture2);
|
||||
cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (priv->style));
|
||||
|
||||
draw_texture (self,
|
||||
monitor->fbo, pipeline,
|
||||
texture2, &monitor_area);
|
||||
bare_region_visible = draw_texture (self,
|
||||
monitor->fbo, pipeline,
|
||||
texture2, &monitor_area);
|
||||
|
||||
cogl_object_unref (pipeline);
|
||||
}
|
||||
@ -796,8 +810,7 @@ meta_background_get_texture (MetaBackground *self,
|
||||
0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
if (texture1 != NULL &&
|
||||
!(texture2 != NULL && priv->blend_factor == 1.0 && !texture_has_alpha (texture2)))
|
||||
if (texture1 != NULL && priv->blend_factor != 1.0)
|
||||
{
|
||||
CoglPipeline *pipeline = create_pipeline (PIPELINE_ADD);
|
||||
cogl_pipeline_set_color4f (pipeline,
|
||||
@ -808,15 +821,14 @@ meta_background_get_texture (MetaBackground *self,
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, texture1);
|
||||
cogl_pipeline_set_layer_wrap_mode (pipeline, 0, get_wrap_mode (priv->style));
|
||||
|
||||
draw_texture (self,
|
||||
monitor->fbo, pipeline,
|
||||
texture1, &monitor_area);
|
||||
bare_region_visible = bare_region_visible || draw_texture (self,
|
||||
monitor->fbo, pipeline,
|
||||
texture1, &monitor_area);
|
||||
|
||||
cogl_object_unref (pipeline);
|
||||
}
|
||||
|
||||
if (!((texture2 != NULL && priv->blend_factor == 1.0 && !texture_has_alpha (texture2)) ||
|
||||
(texture1 != NULL && !texture_has_alpha (texture1))))
|
||||
if (bare_region_visible)
|
||||
{
|
||||
CoglPipeline *pipeline = create_pipeline (PIPELINE_OVER_REVERSE);
|
||||
|
||||
|
@ -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,16 +26,20 @@
|
||||
|
||||
#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"
|
||||
|
||||
struct _MetaSurfaceActorWaylandPrivate
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
struct wl_list frame_callback_list;
|
||||
};
|
||||
typedef struct _MetaSurfaceActorWaylandPrivate MetaSurfaceActorWaylandPrivate;
|
||||
|
||||
@ -80,53 +84,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)
|
||||
{
|
||||
@ -158,6 +198,10 @@ meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
|
||||
scaled_input_region);
|
||||
cairo_region_destroy (scaled_input_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_surface_actor_set_input_region (META_SURFACE_ACTOR (self), NULL);
|
||||
}
|
||||
|
||||
/* Opaque region */
|
||||
if (surface->opaque_region)
|
||||
@ -173,31 +217,88 @@ meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
|
||||
scaled_opaque_region);
|
||||
cairo_region_destroy (scaled_opaque_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_surface_actor_set_opaque_region (META_SURFACE_ACTOR (self), NULL);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
|
||||
struct wl_list *frame_callbacks)
|
||||
{
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (self);
|
||||
|
||||
wl_list_insert_list (&priv->frame_callback_list, frame_callbacks);
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
|
||||
{
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (META_SURFACE_ACTOR_WAYLAND (actor));
|
||||
MetaWaylandSurface *surface = priv->surface;
|
||||
|
||||
return priv->surface->window;
|
||||
if (!surface)
|
||||
return NULL;
|
||||
|
||||
return surface->window;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -236,6 +337,25 @@ 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)
|
||||
{
|
||||
MetaWaylandCompositor *compositor = priv->surface->compositor;
|
||||
meta_wayland_surface_update_outputs (priv->surface);
|
||||
|
||||
wl_list_insert_list (&compositor->frame_callbacks, &priv->frame_callback_list);
|
||||
wl_list_init (&priv->frame_callback_list);
|
||||
}
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_surface_actor_wayland_parent_class)->paint (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_dispose (GObject *object)
|
||||
{
|
||||
@ -255,6 +375,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;
|
||||
@ -282,6 +403,7 @@ meta_surface_actor_wayland_new (MetaWaylandSurface *surface)
|
||||
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
wl_list_init (&priv->frame_callback_list);
|
||||
priv->surface = surface;
|
||||
|
||||
return META_SURFACE_ACTOR (self);
|
||||
@ -301,3 +423,18 @@ 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)
|
||||
{
|
||||
MetaWaylandFrameCallback *callback, *next;
|
||||
MetaSurfaceActorWaylandPrivate *priv =
|
||||
meta_surface_actor_wayland_get_instance_private (self);
|
||||
|
||||
wl_list_for_each_safe (callback, next, &priv->frame_callback_list, link)
|
||||
{
|
||||
wl_resource_destroy (callback->resource);
|
||||
}
|
||||
|
||||
priv->surface = NULL;
|
||||
}
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include "meta-surface-actor.h"
|
||||
|
||||
#include "wayland/meta-wayland.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -57,16 +60,28 @@ 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);
|
||||
|
||||
void meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
|
||||
struct wl_list *frame_callbacks);
|
||||
|
||||
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);
|
||||
}
|
||||
|
592
src/compositor/meta-sync-ring.c
Normal file
592
src/compositor/meta-sync-ring.c
Normal file
@ -0,0 +1,592 @@
|
||||
/*
|
||||
* This is based on an original C++ implementation for compiz that
|
||||
* carries the following copyright notice:
|
||||
*
|
||||
*
|
||||
* Copyright © 2011 NVIDIA Corporation
|
||||
*
|
||||
* 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, and that the name of NVIDIA
|
||||
* Corporation not be used in advertising or publicity pertaining to
|
||||
* distribution of the software without specific, written prior
|
||||
* permission. NVIDIA Corporation makes no representations about the
|
||||
* suitability of this software for any purpose. It is provided "as
|
||||
* is" without express or implied warranty.
|
||||
*
|
||||
* NVIDIA CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Authors: James Jones <jajones@nvidia.com>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glx.h>
|
||||
#include <X11/extensions/sync.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <meta/util.h>
|
||||
|
||||
#include "meta-sync-ring.h"
|
||||
|
||||
/* Theory of operation:
|
||||
*
|
||||
* We use a ring of NUM_SYNCS fence objects. On each frame we advance
|
||||
* to the next fence in the ring. For each fence we do:
|
||||
*
|
||||
* 1. fence is XSyncTriggerFence()'d and glWaitSync()'d
|
||||
* 2. NUM_SYNCS / 2 frames later, fence should be triggered
|
||||
* 3. fence is XSyncResetFence()'d
|
||||
* 4. NUM_SYNCS / 2 frames later, fence should be reset
|
||||
* 5. go back to 1 and re-use fence
|
||||
*
|
||||
* glClientWaitSync() and XAlarms are used in steps 2 and 4,
|
||||
* respectively, to double-check the expectections.
|
||||
*/
|
||||
|
||||
#define NUM_SYNCS 10
|
||||
#define MAX_SYNC_WAIT_TIME (1 * 1000 * 1000 * 1000) /* one sec */
|
||||
#define MAX_REBOOT_ATTEMPTS 2
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_SYNC_STATE_READY,
|
||||
META_SYNC_STATE_WAITING,
|
||||
META_SYNC_STATE_DONE,
|
||||
META_SYNC_STATE_RESET_PENDING,
|
||||
} MetaSyncState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Display *xdisplay;
|
||||
|
||||
XSyncFence xfence;
|
||||
GLsync gl_x11_sync;
|
||||
GLsync gpu_fence;
|
||||
|
||||
XSyncCounter xcounter;
|
||||
XSyncAlarm xalarm;
|
||||
XSyncValue next_counter_value;
|
||||
|
||||
MetaSyncState state;
|
||||
} MetaSync;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Display *xdisplay;
|
||||
int xsync_event_base;
|
||||
int xsync_error_base;
|
||||
|
||||
GHashTable *alarm_to_sync;
|
||||
|
||||
MetaSync *syncs_array[NUM_SYNCS];
|
||||
guint current_sync_idx;
|
||||
MetaSync *current_sync;
|
||||
guint warmup_syncs;
|
||||
|
||||
guint reboots;
|
||||
} MetaSyncRing;
|
||||
|
||||
static MetaSyncRing meta_sync_ring = { 0 };
|
||||
|
||||
static XSyncValue SYNC_VALUE_ZERO;
|
||||
static XSyncValue SYNC_VALUE_ONE;
|
||||
|
||||
static const char* (*meta_gl_get_string) (GLenum name);
|
||||
static void (*meta_gl_get_integerv) (GLenum pname,
|
||||
GLint *params);
|
||||
static const char* (*meta_gl_get_stringi) (GLenum name,
|
||||
GLuint index);
|
||||
static void (*meta_gl_delete_sync) (GLsync sync);
|
||||
static GLenum (*meta_gl_client_wait_sync) (GLsync sync,
|
||||
GLbitfield flags,
|
||||
GLuint64 timeout);
|
||||
static void (*meta_gl_wait_sync) (GLsync sync,
|
||||
GLbitfield flags,
|
||||
GLuint64 timeout);
|
||||
static GLsync (*meta_gl_import_sync) (GLenum external_sync_type,
|
||||
GLintptr external_sync,
|
||||
GLbitfield flags);
|
||||
static GLsync (*meta_gl_fence_sync) (GLenum condition,
|
||||
GLbitfield flags);
|
||||
|
||||
static MetaSyncRing *
|
||||
meta_sync_ring_get (void)
|
||||
{
|
||||
if (meta_sync_ring.reboots > MAX_REBOOT_ATTEMPTS)
|
||||
return NULL;
|
||||
|
||||
return &meta_sync_ring;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_gl_symbol (const char *name,
|
||||
void **func)
|
||||
{
|
||||
*func = cogl_get_proc_address (name);
|
||||
if (!*func)
|
||||
{
|
||||
meta_verbose ("MetaSyncRing: failed to resolve required GL symbol \"%s\"\n", name);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_gl_extensions (void)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
CoglDisplay *cogl_display;
|
||||
CoglRenderer *cogl_renderer;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
cogl_display = cogl_context_get_display (cogl_context);
|
||||
cogl_renderer = cogl_display_get_renderer (cogl_display);
|
||||
|
||||
switch (cogl_renderer_get_driver (cogl_renderer))
|
||||
{
|
||||
case COGL_DRIVER_GL3:
|
||||
{
|
||||
int num_extensions, i;
|
||||
gboolean arb_sync = FALSE;
|
||||
gboolean x11_sync_object = FALSE;
|
||||
|
||||
meta_gl_get_integerv (GL_NUM_EXTENSIONS, &num_extensions);
|
||||
|
||||
for (i = 0; i < num_extensions; ++i)
|
||||
{
|
||||
const char *ext = meta_gl_get_stringi (GL_EXTENSIONS, i);
|
||||
|
||||
if (g_strcmp0 ("GL_ARB_sync", ext) == 0)
|
||||
arb_sync = TRUE;
|
||||
else if (g_strcmp0 ("GL_EXT_x11_sync_object", ext) == 0)
|
||||
x11_sync_object = TRUE;
|
||||
}
|
||||
|
||||
return arb_sync && x11_sync_object;
|
||||
}
|
||||
case COGL_DRIVER_GL:
|
||||
{
|
||||
const char *extensions = meta_gl_get_string (GL_EXTENSIONS);
|
||||
return (extensions != NULL &&
|
||||
strstr (extensions, "GL_ARB_sync") != NULL &&
|
||||
strstr (extensions, "GL_EXT_x11_sync_object") != NULL);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_required_symbols (void)
|
||||
{
|
||||
static gboolean success = FALSE;
|
||||
|
||||
if (success)
|
||||
return TRUE;
|
||||
|
||||
/* We don't link against libGL directly because cogl may want to
|
||||
* use something else. This assumes that cogl has been initialized
|
||||
* and dynamically loaded libGL at this point.
|
||||
*/
|
||||
|
||||
if (!load_gl_symbol ("glGetString", (void **) &meta_gl_get_string))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glGetIntegerv", (void **) &meta_gl_get_integerv))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glGetStringi", (void **) &meta_gl_get_stringi))
|
||||
goto out;
|
||||
|
||||
if (!check_gl_extensions ())
|
||||
{
|
||||
meta_verbose ("MetaSyncRing: couldn't find required GL extensions\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!load_gl_symbol ("glDeleteSync", (void **) &meta_gl_delete_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glClientWaitSync", (void **) &meta_gl_client_wait_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glWaitSync", (void **) &meta_gl_wait_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glImportSyncEXT", (void **) &meta_gl_import_sync))
|
||||
goto out;
|
||||
if (!load_gl_symbol ("glFenceSync", (void **) &meta_gl_fence_sync))
|
||||
goto out;
|
||||
|
||||
success = TRUE;
|
||||
out:
|
||||
return success;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_insert (MetaSync *self)
|
||||
{
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_READY);
|
||||
|
||||
XSyncTriggerFence (self->xdisplay, self->xfence);
|
||||
XFlush (self->xdisplay);
|
||||
|
||||
meta_gl_wait_sync (self->gl_x11_sync, 0, GL_TIMEOUT_IGNORED);
|
||||
self->gpu_fence = meta_gl_fence_sync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
|
||||
self->state = META_SYNC_STATE_WAITING;
|
||||
}
|
||||
|
||||
static GLenum
|
||||
meta_sync_check_update_finished (MetaSync *self,
|
||||
GLuint64 timeout)
|
||||
{
|
||||
GLenum status = GL_WAIT_FAILED;
|
||||
|
||||
switch (self->state)
|
||||
{
|
||||
case META_SYNC_STATE_DONE:
|
||||
status = GL_ALREADY_SIGNALED;
|
||||
break;
|
||||
case META_SYNC_STATE_WAITING:
|
||||
status = meta_gl_client_wait_sync (self->gpu_fence, 0, timeout);
|
||||
if (status == GL_ALREADY_SIGNALED || status == GL_CONDITION_SATISFIED)
|
||||
{
|
||||
self->state = META_SYNC_STATE_DONE;
|
||||
meta_gl_delete_sync (self->gpu_fence);
|
||||
self->gpu_fence = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
g_warn_if_fail (status != GL_WAIT_FAILED);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_reset (MetaSync *self)
|
||||
{
|
||||
XSyncAlarmAttributes attrs;
|
||||
int overflow;
|
||||
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_DONE);
|
||||
|
||||
XSyncResetFence (self->xdisplay, self->xfence);
|
||||
|
||||
attrs.trigger.wait_value = self->next_counter_value;
|
||||
|
||||
XSyncChangeAlarm (self->xdisplay, self->xalarm, XSyncCAValue, &attrs);
|
||||
XSyncSetCounter (self->xdisplay, self->xcounter, self->next_counter_value);
|
||||
|
||||
XSyncValueAdd (&self->next_counter_value,
|
||||
self->next_counter_value,
|
||||
SYNC_VALUE_ONE,
|
||||
&overflow);
|
||||
|
||||
self->state = META_SYNC_STATE_RESET_PENDING;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_handle_event (MetaSync *self,
|
||||
XSyncAlarmNotifyEvent *event)
|
||||
{
|
||||
g_return_if_fail (event->alarm == self->xalarm);
|
||||
g_return_if_fail (self->state == META_SYNC_STATE_RESET_PENDING);
|
||||
|
||||
self->state = META_SYNC_STATE_READY;
|
||||
}
|
||||
|
||||
static MetaSync *
|
||||
meta_sync_new (Display *xdisplay)
|
||||
{
|
||||
MetaSync *self;
|
||||
XSyncAlarmAttributes attrs;
|
||||
|
||||
self = g_malloc0 (sizeof (MetaSync));
|
||||
|
||||
self->xdisplay = xdisplay;
|
||||
|
||||
self->xfence = XSyncCreateFence (xdisplay, DefaultRootWindow (xdisplay), FALSE);
|
||||
self->gl_x11_sync = 0;
|
||||
self->gpu_fence = 0;
|
||||
|
||||
self->xcounter = XSyncCreateCounter (xdisplay, SYNC_VALUE_ZERO);
|
||||
|
||||
attrs.trigger.counter = self->xcounter;
|
||||
attrs.trigger.value_type = XSyncAbsolute;
|
||||
attrs.trigger.wait_value = SYNC_VALUE_ONE;
|
||||
attrs.trigger.test_type = XSyncPositiveTransition;
|
||||
attrs.events = TRUE;
|
||||
self->xalarm = XSyncCreateAlarm (xdisplay,
|
||||
XSyncCACounter |
|
||||
XSyncCAValueType |
|
||||
XSyncCAValue |
|
||||
XSyncCATestType |
|
||||
XSyncCAEvents,
|
||||
&attrs);
|
||||
|
||||
XSyncIntToValue (&self->next_counter_value, 1);
|
||||
|
||||
self->state = META_SYNC_STATE_READY;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_import (MetaSync *self)
|
||||
{
|
||||
g_return_if_fail (self->gl_x11_sync == 0);
|
||||
self->gl_x11_sync = meta_gl_import_sync (GL_SYNC_X11_FENCE_EXT, self->xfence, 0);
|
||||
}
|
||||
|
||||
static Bool
|
||||
alarm_event_predicate (Display *dpy,
|
||||
XEvent *event,
|
||||
XPointer data)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return False;
|
||||
|
||||
if (event->type == ring->xsync_event_base + XSyncAlarmNotify)
|
||||
{
|
||||
if (((MetaSync *) data)->xalarm == ((XSyncAlarmNotifyEvent *) event)->alarm)
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_sync_free (MetaSync *self)
|
||||
{
|
||||
/* When our assumptions don't hold, something has gone wrong but we
|
||||
* don't know what, so we reboot the ring. While doing that, we
|
||||
* trigger fences before deleting them to try to get ourselves out
|
||||
* of a potentially stuck GPU state.
|
||||
*/
|
||||
switch (self->state)
|
||||
{
|
||||
case META_SYNC_STATE_WAITING:
|
||||
meta_gl_delete_sync (self->gpu_fence);
|
||||
break;
|
||||
case META_SYNC_STATE_DONE:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case META_SYNC_STATE_RESET_PENDING:
|
||||
{
|
||||
XEvent event;
|
||||
XIfEvent (self->xdisplay, &event, alarm_event_predicate, (XPointer) self);
|
||||
meta_sync_handle_event (self, (XSyncAlarmNotifyEvent *) &event);
|
||||
}
|
||||
/* fall through */
|
||||
case META_SYNC_STATE_READY:
|
||||
XSyncTriggerFence (self->xdisplay, self->xfence);
|
||||
XFlush (self->xdisplay);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
meta_gl_delete_sync (self->gl_x11_sync);
|
||||
XSyncDestroyFence (self->xdisplay, self->xfence);
|
||||
XSyncDestroyCounter (self->xdisplay, self->xcounter);
|
||||
XSyncDestroyAlarm (self->xdisplay, self->xalarm);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_init (Display *xdisplay)
|
||||
{
|
||||
gint major, minor;
|
||||
guint i;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (xdisplay != NULL, FALSE);
|
||||
g_return_val_if_fail (ring->xdisplay == NULL, FALSE);
|
||||
|
||||
if (!load_required_symbols ())
|
||||
return FALSE;
|
||||
|
||||
if (!XSyncQueryExtension (xdisplay, &ring->xsync_event_base, &ring->xsync_error_base) ||
|
||||
!XSyncInitialize (xdisplay, &major, &minor))
|
||||
return FALSE;
|
||||
|
||||
XSyncIntToValue (&SYNC_VALUE_ZERO, 0);
|
||||
XSyncIntToValue (&SYNC_VALUE_ONE, 1);
|
||||
|
||||
ring->xdisplay = xdisplay;
|
||||
|
||||
ring->alarm_to_sync = g_hash_table_new (NULL, NULL);
|
||||
|
||||
for (i = 0; i < NUM_SYNCS; ++i)
|
||||
{
|
||||
MetaSync *sync = meta_sync_new (ring->xdisplay);
|
||||
ring->syncs_array[i] = sync;
|
||||
g_hash_table_replace (ring->alarm_to_sync, (gpointer) sync->xalarm, sync);
|
||||
}
|
||||
/* Since the connection we create the X fences on isn't the same as
|
||||
* the one used for the GLX context, we need to XSync() here to
|
||||
* ensure glImportSync() succeeds. */
|
||||
XSync (xdisplay, False);
|
||||
for (i = 0; i < NUM_SYNCS; ++i)
|
||||
meta_sync_import (ring->syncs_array[i]);
|
||||
|
||||
ring->current_sync_idx = 0;
|
||||
ring->current_sync = ring->syncs_array[0];
|
||||
ring->warmup_syncs = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_sync_ring_destroy (void)
|
||||
{
|
||||
guint i;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
g_return_if_fail (ring->xdisplay != NULL);
|
||||
|
||||
ring->current_sync_idx = 0;
|
||||
ring->current_sync = NULL;
|
||||
ring->warmup_syncs = 0;
|
||||
|
||||
for (i = 0; i < NUM_SYNCS; ++i)
|
||||
meta_sync_free (ring->syncs_array[i]);
|
||||
|
||||
g_hash_table_destroy (ring->alarm_to_sync);
|
||||
|
||||
ring->xsync_event_base = 0;
|
||||
ring->xsync_error_base = 0;
|
||||
ring->xdisplay = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_sync_ring_reboot (Display *xdisplay)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
meta_sync_ring_destroy ();
|
||||
|
||||
ring->reboots += 1;
|
||||
|
||||
if (!meta_sync_ring_get ())
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Too many reboots -- disabling\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return meta_sync_ring_init (xdisplay);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_after_frame (void)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
|
||||
|
||||
if (ring->warmup_syncs >= NUM_SYNCS / 2)
|
||||
{
|
||||
guint reset_sync_idx = (ring->current_sync_idx + NUM_SYNCS - (NUM_SYNCS / 2)) % NUM_SYNCS;
|
||||
MetaSync *sync_to_reset = ring->syncs_array[reset_sync_idx];
|
||||
|
||||
GLenum status = meta_sync_check_update_finished (sync_to_reset, 0);
|
||||
if (status == GL_TIMEOUT_EXPIRED)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: We should never wait for a sync -- add more syncs?\n");
|
||||
status = meta_sync_check_update_finished (sync_to_reset, MAX_SYNC_WAIT_TIME);
|
||||
}
|
||||
|
||||
if (status != GL_ALREADY_SIGNALED && status != GL_CONDITION_SATISFIED)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Timed out waiting for sync object.\n");
|
||||
return meta_sync_ring_reboot (ring->xdisplay);
|
||||
}
|
||||
|
||||
meta_sync_reset (sync_to_reset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ring->warmup_syncs += 1;
|
||||
}
|
||||
|
||||
ring->current_sync_idx += 1;
|
||||
ring->current_sync_idx %= NUM_SYNCS;
|
||||
|
||||
ring->current_sync = ring->syncs_array[ring->current_sync_idx];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_sync_ring_insert_wait (void)
|
||||
{
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return FALSE;
|
||||
|
||||
g_return_val_if_fail (ring->xdisplay != NULL, FALSE);
|
||||
|
||||
if (ring->current_sync->state != META_SYNC_STATE_READY)
|
||||
{
|
||||
meta_warning ("MetaSyncRing: Sync object is not ready -- were events handled properly?\n");
|
||||
if (!meta_sync_ring_reboot (ring->xdisplay))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
meta_sync_insert (ring->current_sync);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_sync_ring_handle_event (XEvent *xevent)
|
||||
{
|
||||
XSyncAlarmNotifyEvent *event;
|
||||
MetaSync *sync;
|
||||
MetaSyncRing *ring = meta_sync_ring_get ();
|
||||
|
||||
if (!ring)
|
||||
return;
|
||||
|
||||
g_return_if_fail (ring->xdisplay != NULL);
|
||||
|
||||
if (xevent->type != (ring->xsync_event_base + XSyncAlarmNotify))
|
||||
return;
|
||||
|
||||
event = (XSyncAlarmNotifyEvent *) xevent;
|
||||
|
||||
sync = g_hash_table_lookup (ring->alarm_to_sync, (gpointer) event->alarm);
|
||||
if (sync)
|
||||
meta_sync_handle_event (sync, event);
|
||||
}
|
14
src/compositor/meta-sync-ring.h
Normal file
14
src/compositor/meta-sync-ring.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef _META_SYNC_RING_H_
|
||||
#define _META_SYNC_RING_H_
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
gboolean meta_sync_ring_init (Display *dpy);
|
||||
void meta_sync_ring_destroy (void);
|
||||
gboolean meta_sync_ring_after_frame (void);
|
||||
gboolean meta_sync_ring_insert_wait (void);
|
||||
void meta_sync_ring_handle_event (XEvent *event);
|
||||
|
||||
#endif /* _META_SYNC_RING_H_ */
|
@ -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
|
||||
@ -827,21 +832,23 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
||||
return TRUE;
|
||||
|
||||
/*
|
||||
* Do not add shadows to non-opaque windows; eventually we should generate
|
||||
* a shadow from the input shape for such windows.
|
||||
* Do not add shadows to non-opaque (ARGB32) windows, as we can't easily
|
||||
* generate shadows for them.
|
||||
*/
|
||||
if (is_non_opaque (self))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Add shadows to override redirect windows on X11 unless the toolkit
|
||||
* indicates that it is handling shadows itself (e.g., Gtk menus).
|
||||
* If a window specifies that it has custom frame extents, that likely
|
||||
* means that it is drawing a shadow itself. Don't draw our own.
|
||||
*/
|
||||
if (priv->window->override_redirect &&
|
||||
!priv->window->has_custom_frame_extents)
|
||||
return TRUE;
|
||||
if (priv->window->has_custom_frame_extents)
|
||||
return FALSE;
|
||||
|
||||
return FALSE;
|
||||
/*
|
||||
* Generate shadows for all other windows.
|
||||
*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1036,20 +1043,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 +1063,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 +1073,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 +1087,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 +1129,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 +1140,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 +1184,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 +1300,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 +1315,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 +1334,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 +1356,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
|
||||
|
@ -493,11 +493,10 @@ place_window_if_needed(MetaWindow *window,
|
||||
if (window->placed || did_placement)
|
||||
{
|
||||
if (window->maximize_horizontally_after_placement ||
|
||||
window->maximize_vertically_after_placement ||
|
||||
window->fullscreen_after_placement)
|
||||
window->maximize_vertically_after_placement)
|
||||
{
|
||||
/* define a sane saved_rect so that the user can unmaximize or
|
||||
* make unfullscreen to something reasonable.
|
||||
/* define a sane saved_rect so that the user can unmaximize to
|
||||
* something reasonable.
|
||||
*/
|
||||
if (info->current.width >= info->work_area_monitor.width)
|
||||
{
|
||||
@ -525,15 +524,6 @@ place_window_if_needed(MetaWindow *window,
|
||||
(window->maximize_vertically_after_placement ?
|
||||
META_MAXIMIZE_VERTICAL : 0), &info->current);
|
||||
|
||||
if (window->fullscreen_after_placement)
|
||||
{
|
||||
window->saved_rect = info->current;
|
||||
window->fullscreen = TRUE;
|
||||
window->fullscreen_after_placement = FALSE;
|
||||
|
||||
g_object_notify (G_OBJECT (window), "fullscreen");
|
||||
}
|
||||
|
||||
window->maximize_horizontally_after_placement = FALSE;
|
||||
window->maximize_vertically_after_placement = FALSE;
|
||||
}
|
||||
|
@ -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,
|
||||
@ -217,19 +205,6 @@ meta_core_show_window_menu_for_rect (Display *xdisplay,
|
||||
meta_window_show_menu_for_rect (window, menu, rect);
|
||||
}
|
||||
|
||||
const char*
|
||||
meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||
Window xroot,
|
||||
int index)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWorkspace *workspace;
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
workspace = meta_screen_get_workspace_by_index (display->screen, index);
|
||||
return workspace ? meta_workspace_get_name (workspace) : NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_core_begin_grab_op (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
|
@ -41,15 +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);
|
||||
const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||
Window xroot,
|
||||
int index);
|
||||
|
||||
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
|
||||
|
@ -121,7 +121,7 @@ struct _MetaDisplay
|
||||
* class is constructed.
|
||||
*/
|
||||
#define item(x) Atom atom_##x;
|
||||
#include <meta/atomnames.h>
|
||||
#include <x11/atomnames.h>
|
||||
#undef item
|
||||
|
||||
/* The window and serial of the most recent FocusIn event. */
|
||||
@ -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>
|
||||
@ -547,9 +547,9 @@ meta_display_open (void)
|
||||
guint32 timestamp;
|
||||
|
||||
/* A list of all atom names, so that we can intern them in one go. */
|
||||
char *atom_names[] = {
|
||||
const char *atom_names[] = {
|
||||
#define item(x) #x,
|
||||
#include <meta/atomnames.h>
|
||||
#include <x11/atomnames.h>
|
||||
#undef item
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
@ -605,14 +605,13 @@ meta_display_open (void)
|
||||
meta_prefs_add_listener (prefs_changed_callback, display);
|
||||
|
||||
meta_verbose ("Creating %d atoms\n", (int) G_N_ELEMENTS (atom_names));
|
||||
XInternAtoms (display->xdisplay, atom_names, G_N_ELEMENTS (atom_names),
|
||||
XInternAtoms (display->xdisplay, (char **)atom_names, G_N_ELEMENTS (atom_names),
|
||||
False, atoms);
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
i = 0;
|
||||
#define item(x) display->atom_##x = atoms[i++];
|
||||
#include <meta/atomnames.h>
|
||||
#include <x11/atomnames.h>
|
||||
#undef item
|
||||
}
|
||||
|
||||
display->prop_hooks = NULL;
|
||||
meta_display_init_window_prop_hooks (display);
|
||||
@ -1922,7 +1921,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);
|
||||
|
||||
@ -1965,9 +1963,12 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Ending grab op %u at time %u\n", grab_op, timestamp);
|
||||
|
||||
if (display->event_route == META_EVENT_ROUTE_NORMAL)
|
||||
if (display->event_route == META_EVENT_ROUTE_NORMAL ||
|
||||
display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB)
|
||||
return;
|
||||
|
||||
g_assert (grab_window != NULL);
|
||||
|
||||
g_signal_emit (display, display_signals[GRAB_OP_END], 0,
|
||||
display->screen, grab_window, grab_op);
|
||||
|
||||
|
@ -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)
|
||||
@ -93,6 +100,15 @@ handle_idletime_for_event (const ClutterEvent *event)
|
||||
if (device == NULL)
|
||||
return;
|
||||
|
||||
if (event->any.flags & CLUTTER_EVENT_FLAG_SYNTHETIC ||
|
||||
event->type == CLUTTER_ENTER ||
|
||||
event->type == CLUTTER_LEAVE ||
|
||||
event->type == CLUTTER_STAGE_STATE ||
|
||||
event->type == CLUTTER_DESTROY_NOTIFY ||
|
||||
event->type == CLUTTER_CLIENT_MESSAGE ||
|
||||
event->type == CLUTTER_DELETE)
|
||||
return;
|
||||
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
core_monitor = meta_idle_monitor_get_core ();
|
||||
@ -190,8 +206,9 @@ meta_display_handle_event (MetaDisplay *display,
|
||||
|
||||
if (meta_is_wayland_compositor () && event->type == CLUTTER_MOTION)
|
||||
{
|
||||
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
meta_cursor_tracker_update_position (tracker, event->motion.x, event->motion.y);
|
||||
meta_cursor_tracker_update_position (meta_cursor_tracker_get_for_screen (NULL),
|
||||
event->motion.x, event->motion.y);
|
||||
display->monitor_cache_invalidated = TRUE;
|
||||
}
|
||||
|
||||
handle_idletime_for_event (event);
|
||||
@ -255,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;
|
||||
|
@ -188,7 +188,7 @@ reload_modmap (MetaKeyBindingManager *keys)
|
||||
|
||||
/* Modifiers to find. */
|
||||
struct {
|
||||
char *name;
|
||||
const char *name;
|
||||
xkb_mod_mask_t *mask_p;
|
||||
} mods[] = {
|
||||
{ "ScrollLock", &scroll_lock_mask },
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ print_version (const gchar *option_name,
|
||||
exit (0);
|
||||
}
|
||||
|
||||
static gchar *plugin = "default";
|
||||
static const char *plugin = "default";
|
||||
|
||||
GOptionEntry mutter_options[] = {
|
||||
{
|
||||
|
@ -96,6 +96,10 @@ static gboolean bell_is_audible = TRUE;
|
||||
static gboolean gnome_accessibility = FALSE;
|
||||
static gboolean gnome_animations = TRUE;
|
||||
static char *cursor_theme = NULL;
|
||||
/* cursor_size will, when running as an X11 compositing window manager, be the
|
||||
* actual cursor size, multiplied with the global window scaling factor. On
|
||||
* Wayland, it will be the actual cursor size retrieved from gsettings.
|
||||
*/
|
||||
static int cursor_size = 24;
|
||||
static int draggable_border_width = 10;
|
||||
static int drag_threshold;
|
||||
@ -123,6 +127,9 @@ static gboolean update_binding (MetaKeyPref *binding,
|
||||
static gboolean update_key_binding (const char *key,
|
||||
gchar **strokes);
|
||||
|
||||
static void wayland_settings_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
gpointer data);
|
||||
static void settings_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
gpointer data);
|
||||
@ -134,9 +141,10 @@ static void shell_shows_app_menu_changed (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data);
|
||||
|
||||
static void update_cursor_size (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data);
|
||||
static void update_cursor_size_from_gtk (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data);
|
||||
static void update_cursor_size (void);
|
||||
|
||||
static void queue_changed (MetaPreference pref);
|
||||
|
||||
@ -161,8 +169,8 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *key;
|
||||
char *schema;
|
||||
const char *key;
|
||||
const char *schema;
|
||||
MetaPreference pref;
|
||||
} MetaBasePreference;
|
||||
|
||||
@ -963,14 +971,18 @@ meta_prefs_init (void)
|
||||
G_CALLBACK (settings_changed), NULL);
|
||||
g_signal_connect (settings, "changed::" KEY_GNOME_CURSOR_THEME,
|
||||
G_CALLBACK (settings_changed), NULL);
|
||||
if (meta_is_wayland_compositor ())
|
||||
g_signal_connect (settings, "changed::cursor-size",
|
||||
G_CALLBACK (wayland_settings_changed), NULL);
|
||||
g_hash_table_insert (settings_schemas, g_strdup (SCHEMA_INTERFACE), settings);
|
||||
|
||||
g_signal_connect (gtk_settings_get_default (),
|
||||
"notify::gtk-shell-shows-app-menu",
|
||||
G_CALLBACK (shell_shows_app_menu_changed), NULL);
|
||||
|
||||
g_signal_connect (gtk_settings_get_default (), "notify::gtk-cursor-theme-size",
|
||||
G_CALLBACK (update_cursor_size), NULL);
|
||||
if (!meta_is_wayland_compositor ())
|
||||
g_signal_connect (gtk_settings_get_default (), "notify::gtk-cursor-theme-size",
|
||||
G_CALLBACK (update_cursor_size_from_gtk), NULL);
|
||||
|
||||
settings = g_settings_new (SCHEMA_INPUT_SOURCES);
|
||||
g_signal_connect (settings, "changed::" KEY_XKB_OPTIONS,
|
||||
@ -992,7 +1004,7 @@ meta_prefs_init (void)
|
||||
handle_preference_init_string_array ();
|
||||
handle_preference_init_int ();
|
||||
|
||||
update_cursor_size (gtk_settings_get_default (), NULL, NULL);
|
||||
update_cursor_size ();
|
||||
shell_shows_app_menu_changed (gtk_settings_get_default (), NULL, NULL);
|
||||
|
||||
init_bindings ();
|
||||
@ -1133,6 +1145,20 @@ meta_prefs_override_preference_schema (const char *key, const char *schema)
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
static void
|
||||
wayland_settings_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
gpointer data)
|
||||
{
|
||||
GVariant *value = g_settings_get_value (settings, key);
|
||||
const GVariantType *type = g_variant_get_type (value);
|
||||
|
||||
g_return_if_fail (g_variant_type_equal (type, G_VARIANT_TYPE_INT32));
|
||||
g_return_if_fail (g_str_equal (key, "cursor-size"));
|
||||
|
||||
update_cursor_size ();
|
||||
}
|
||||
|
||||
static void
|
||||
settings_changed (GSettings *settings,
|
||||
gchar *key,
|
||||
@ -1216,9 +1242,29 @@ shell_shows_app_menu_changed (GtkSettings *settings,
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor_size (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
update_cursor_size (void)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
/* When running as a Wayland compositor, since we size of the cursor
|
||||
* depends on what output it is on, we cannot use the GTK+
|
||||
* "gtk-cursor-theme-size" setting because it has already been multiplied
|
||||
* by the primary monitor scale. So, instead get the non-premultiplied
|
||||
* cursor size value directly from gsettings instead.
|
||||
*/
|
||||
cursor_size =
|
||||
g_settings_get_int (SETTINGS (SCHEMA_INTERFACE), "cursor-size");
|
||||
}
|
||||
else
|
||||
{
|
||||
update_cursor_size_from_gtk (gtk_settings_get_default (), NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_cursor_size_from_gtk (GtkSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
gpointer data)
|
||||
{
|
||||
GdkScreen *screen = gdk_screen_get_default ();
|
||||
GValue value = G_VALUE_INIT;
|
||||
|
@ -41,14 +41,6 @@
|
||||
typedef void (* MetaScreenWindowFunc) (MetaWindow *window,
|
||||
gpointer user_data);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_SCREEN_UP,
|
||||
META_SCREEN_DOWN,
|
||||
META_SCREEN_LEFT,
|
||||
META_SCREEN_RIGHT
|
||||
} MetaScreenDirection;
|
||||
|
||||
#define META_WIREFRAME_XOR_LINE_WIDTH 2
|
||||
|
||||
struct _MetaScreen
|
||||
@ -157,8 +149,12 @@ 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_for_point (MetaScreen *screen,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
|
||||
const MetaMonitorInfo* meta_screen_get_monitor_neighbor (MetaScreen *screen,
|
||||
|
@ -40,9 +40,10 @@
|
||||
#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"
|
||||
#include "boxes-private.h"
|
||||
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
@ -294,7 +295,7 @@ set_supported_hint (MetaScreen *screen)
|
||||
Atom atoms[] = {
|
||||
#define EWMH_ATOMS_ONLY
|
||||
#define item(x) screen->display->atom_##x,
|
||||
#include <meta/atomnames.h>
|
||||
#include <x11/atomnames.h>
|
||||
#undef item
|
||||
#undef EWMH_ATOMS_ONLY
|
||||
|
||||
@ -750,7 +751,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 +1167,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;
|
||||
@ -1255,21 +1256,47 @@ update_num_workspaces (MetaScreen *screen,
|
||||
g_object_notify (G_OBJECT (screen), "n-workspaces");
|
||||
}
|
||||
|
||||
static void
|
||||
root_cursor_prepare_at (MetaCursorSprite *cursor_sprite,
|
||||
int x,
|
||||
int y,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
const MetaMonitorInfo *monitor;
|
||||
|
||||
monitor = meta_screen_get_monitor_for_point (screen, x, y);
|
||||
|
||||
/* Reload the cursor texture if the scale has changed. */
|
||||
meta_cursor_sprite_set_theme_scale (cursor_sprite, monitor->scale);
|
||||
}
|
||||
|
||||
static void
|
||||
manage_root_cursor_sprite_scale (MetaScreen *screen,
|
||||
MetaCursorSprite *cursor_sprite)
|
||||
{
|
||||
g_signal_connect_object (cursor_sprite,
|
||||
"prepare-at",
|
||||
G_CALLBACK (root_cursor_prepare_at),
|
||||
screen,
|
||||
0);
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_update_cursor (MetaScreen *screen)
|
||||
{
|
||||
MetaDisplay *display = screen->display;
|
||||
MetaCursor cursor = screen->current_cursor;
|
||||
Cursor xcursor;
|
||||
MetaCursorReference *cursor_ref;
|
||||
MetaCursorSprite *cursor_sprite;
|
||||
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (screen);
|
||||
|
||||
cursor_ref = meta_cursor_reference_from_theme (cursor);
|
||||
if (cursor_ref == NULL)
|
||||
meta_fatal ("Could not find cursor. Perhaps set XCURSOR_PATH?");
|
||||
cursor_sprite = meta_cursor_sprite_from_theme (cursor);
|
||||
|
||||
meta_cursor_tracker_set_root_cursor (tracker, cursor_ref);
|
||||
meta_cursor_reference_unref (cursor_ref);
|
||||
if (meta_is_wayland_compositor ())
|
||||
manage_root_cursor_sprite_scale (screen, cursor_sprite);
|
||||
|
||||
meta_cursor_tracker_set_root_cursor (tracker, cursor_sprite);
|
||||
g_object_unref (cursor_sprite);
|
||||
|
||||
/* Set a cursor for X11 applications that don't specify their own */
|
||||
xcursor = meta_display_create_x_cursor (display, cursor);
|
||||
@ -1439,8 +1466,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;
|
||||
|
||||
@ -1457,6 +1484,25 @@ meta_screen_get_monitor_index_for_rect (MetaScreen *screen,
|
||||
return monitor->number;
|
||||
}
|
||||
|
||||
const MetaMonitorInfo *
|
||||
meta_screen_get_monitor_for_point (MetaScreen *screen,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (screen->n_monitor_infos == 1)
|
||||
return &screen->monitor_infos[0];
|
||||
|
||||
for (i = 0; i < screen->n_monitor_infos; i++)
|
||||
{
|
||||
if (POINT_IN_RECT (x, y, screen->monitor_infos[i].rect))
|
||||
return &screen->monitor_infos[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const MetaMonitorInfo*
|
||||
meta_screen_get_monitor_neighbor (MetaScreen *screen,
|
||||
int which_monitor,
|
||||
@ -1490,6 +1536,16 @@ meta_screen_get_monitor_neighbor (MetaScreen *screen,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
meta_screen_get_monitor_neighbor_index (MetaScreen *screen,
|
||||
int which_monitor,
|
||||
MetaScreenDirection direction)
|
||||
{
|
||||
const MetaMonitorInfo *monitor;
|
||||
monitor = meta_screen_get_monitor_neighbor (screen, which_monitor, direction);
|
||||
return monitor ? monitor->number : -1;
|
||||
}
|
||||
|
||||
void
|
||||
meta_screen_get_natural_monitor_list (MetaScreen *screen,
|
||||
int** monitors_list,
|
||||
@ -1745,7 +1801,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)
|
||||
@ -2044,7 +2100,7 @@ meta_screen_queue_workarea_recalc (MetaScreen *screen)
|
||||
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
static char *
|
||||
static const char *
|
||||
meta_screen_corner_to_string (MetaScreenCorner corner)
|
||||
{
|
||||
switch (corner)
|
||||
@ -2378,12 +2434,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 */
|
||||
@ -1056,7 +1055,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
all_root_children_stacked = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||
x11_hidden_stack_ids = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||
|
||||
meta_topic (META_DEBUG_STACK, "Top to bottom: ");
|
||||
meta_topic (META_DEBUG_STACK, "Bottom to top: ");
|
||||
meta_push_no_msg_prefix ();
|
||||
|
||||
for (tmp = g_list_last(stack->sorted); tmp != NULL; tmp = tmp->prev)
|
||||
@ -1089,11 +1088,7 @@ stack_sync_to_xserver (MetaStack *stack)
|
||||
if (w->hidden)
|
||||
{
|
||||
if (w->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
guint64 stack_id = top_level_window;
|
||||
|
||||
g_array_append_val (x11_hidden_stack_ids, stack_id);
|
||||
}
|
||||
g_array_append_val (x11_hidden_stack_ids, top_level_window);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1239,24 +1234,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 +1254,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*
|
||||
|
@ -30,7 +30,7 @@
|
||||
#define NUM_RANDOM_RUNS 10000
|
||||
|
||||
static void
|
||||
init_random_ness ()
|
||||
init_random_ness (void)
|
||||
{
|
||||
srand(time(NULL));
|
||||
}
|
||||
@ -99,7 +99,7 @@ new_monitor_edge (int x, int y, int width, int height, int side_type)
|
||||
}
|
||||
|
||||
static void
|
||||
test_area ()
|
||||
test_area (void)
|
||||
{
|
||||
MetaRectangle temp;
|
||||
int i;
|
||||
@ -116,7 +116,7 @@ test_area ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_intersect ()
|
||||
test_intersect (void)
|
||||
{
|
||||
MetaRectangle a = {100, 200, 50, 40};
|
||||
MetaRectangle b = { 0, 50, 110, 152};
|
||||
@ -144,7 +144,7 @@ test_intersect ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_equal ()
|
||||
test_equal (void)
|
||||
{
|
||||
MetaRectangle a = {10, 12, 4, 18};
|
||||
MetaRectangle b = a;
|
||||
@ -163,7 +163,7 @@ test_equal ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_overlap_funcs ()
|
||||
test_overlap_funcs (void)
|
||||
{
|
||||
MetaRectangle temp1, temp2;
|
||||
int i;
|
||||
@ -186,7 +186,7 @@ test_overlap_funcs ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_basic_fitting ()
|
||||
test_basic_fitting (void)
|
||||
{
|
||||
MetaRectangle temp1, temp2, temp3;
|
||||
int i;
|
||||
@ -357,7 +357,7 @@ get_monitor_edges (int which_monitor_set, int which_strut_set)
|
||||
|
||||
#if 0
|
||||
static void
|
||||
test_merge_regions ()
|
||||
test_merge_regions (void)
|
||||
{
|
||||
/* logarithmically distributed random number of struts (range?)
|
||||
* logarithmically distributed random size of struts (up to screen size???)
|
||||
@ -579,7 +579,7 @@ verify_lists_are_equal (GList *code, GList *answer)
|
||||
}
|
||||
|
||||
static void
|
||||
test_regions_okay ()
|
||||
test_regions_okay (void)
|
||||
{
|
||||
GList* region;
|
||||
GList* tmp;
|
||||
@ -665,7 +665,7 @@ test_regions_okay ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_region_fitting ()
|
||||
test_region_fitting (void)
|
||||
{
|
||||
GList* region;
|
||||
MetaRectangle rect;
|
||||
@ -709,7 +709,7 @@ test_region_fitting ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_clamping_to_region ()
|
||||
test_clamping_to_region (void)
|
||||
{
|
||||
GList* region;
|
||||
MetaRectangle rect;
|
||||
@ -826,7 +826,7 @@ rect_overlaps_region (const GList *spanning_rects,
|
||||
gboolean time_to_print = FALSE;
|
||||
|
||||
static void
|
||||
test_clipping_to_region ()
|
||||
test_clipping_to_region (void)
|
||||
{
|
||||
GList* region;
|
||||
MetaRectangle rect, temp;
|
||||
@ -888,7 +888,7 @@ test_clipping_to_region ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_shoving_into_region ()
|
||||
test_shoving_into_region (void)
|
||||
{
|
||||
GList* region;
|
||||
MetaRectangle rect, temp;
|
||||
@ -1005,7 +1005,7 @@ verify_edge_lists_are_equal (GList *code, GList *answer)
|
||||
}
|
||||
|
||||
static void
|
||||
test_find_onscreen_edges ()
|
||||
test_find_onscreen_edges (void)
|
||||
{
|
||||
GList* edges;
|
||||
GList* tmp;
|
||||
@ -1138,7 +1138,7 @@ test_find_onscreen_edges ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_find_nonintersected_monitor_edges ()
|
||||
test_find_nonintersected_monitor_edges (void)
|
||||
{
|
||||
GList* edges;
|
||||
GList* tmp;
|
||||
@ -1227,7 +1227,7 @@ test_find_nonintersected_monitor_edges ()
|
||||
}
|
||||
|
||||
static void
|
||||
test_gravity_resize ()
|
||||
test_gravity_resize (void)
|
||||
{
|
||||
MetaRectangle oldrect, rect, temp;
|
||||
|
||||
@ -1329,7 +1329,7 @@ test_gravity_resize ()
|
||||
|
||||
#define EPSILON 0.000000001
|
||||
static void
|
||||
test_find_closest_point_to_line ()
|
||||
test_find_closest_point_to_line (void)
|
||||
{
|
||||
double x1, y1, x2, y2, px, py, rx, ry;
|
||||
double answer_x, answer_y;
|
||||
@ -1381,7 +1381,7 @@ test_find_closest_point_to_line ()
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
main(void)
|
||||
{
|
||||
init_random_ness ();
|
||||
test_area ();
|
||||
|
@ -46,7 +46,7 @@
|
||||
static void
|
||||
meta_topic_real_valist (MetaDebugTopic topic,
|
||||
const char *format,
|
||||
va_list args);
|
||||
va_list args) G_GNUC_PRINTF(2, 0);
|
||||
#endif
|
||||
|
||||
static gint verbose_topics = 0;
|
||||
|
@ -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
|
||||
@ -175,9 +176,6 @@ struct _MetaWindow
|
||||
/* Whether the window is marked as urgent */
|
||||
guint urgent : 1;
|
||||
|
||||
/* Whether we have to fullscreen after placement */
|
||||
guint fullscreen_after_placement : 1;
|
||||
|
||||
/* Area to cover when in fullscreen mode. If _NET_WM_FULLSCREEN_MONITORS has
|
||||
* been overridden (via a client message), the window will cover the union of
|
||||
* these monitors. If not, this is the single monitor which the window's
|
||||
@ -434,7 +432,6 @@ struct _MetaWindow
|
||||
|
||||
/* Managed by delete.c */
|
||||
int dialog_pid;
|
||||
guint is_alive : 1;
|
||||
|
||||
/* maintained by group.c */
|
||||
MetaGroup *group;
|
||||
@ -482,6 +479,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 +693,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>
|
||||
@ -57,7 +57,8 @@
|
||||
#include "x11/xprops.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "wayland/window-wayland.h"
|
||||
#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;
|
||||
}
|
||||
|
||||
@ -756,10 +763,22 @@ meta_window_update_desc (MetaWindow *window)
|
||||
{
|
||||
g_clear_pointer (&window->desc, g_free);
|
||||
|
||||
if (window->title)
|
||||
window->desc = g_strdup_printf ("0x%lx (%.10s)", window->xwindow, window->title);
|
||||
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
if (window->title)
|
||||
window->desc = g_strdup_printf ("0x%lx (%.10s)", window->xwindow, window->title);
|
||||
else
|
||||
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
|
||||
}
|
||||
else
|
||||
window->desc = g_strdup_printf ("0x%lx", window->xwindow);
|
||||
{
|
||||
guint64 small_stamp = window->stamp - G_GUINT64_CONSTANT(0x100000000);
|
||||
|
||||
if (window->title)
|
||||
window->desc = g_strdup_printf ("W%" G_GUINT64_FORMAT " (%.10s)", small_stamp, window->title);
|
||||
else
|
||||
window->desc = g_strdup_printf ("W%" G_GUINT64_FORMAT , small_stamp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -873,7 +892,6 @@ _meta_window_shared_new (MetaDisplay *display,
|
||||
window->maximize_vertically_after_placement = FALSE;
|
||||
window->minimize_after_placement = FALSE;
|
||||
window->fullscreen = FALSE;
|
||||
window->fullscreen_after_placement = FALSE;
|
||||
window->fullscreen_monitors[0] = -1;
|
||||
window->require_fully_onscreen = TRUE;
|
||||
window->require_on_single_monitor = TRUE;
|
||||
@ -974,7 +992,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 +1552,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 +2676,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 +2725,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 +2901,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 +2914,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 +2983,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 +3006,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 +3033,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 +3080,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 +3117,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)
|
||||
{
|
||||
@ -3204,12 +3195,23 @@ meta_window_make_fullscreen (MetaWindow *window)
|
||||
|
||||
if (!window->fullscreen)
|
||||
{
|
||||
meta_window_make_fullscreen_internal (window);
|
||||
MetaRectangle old_frame_rect, old_buffer_rect;
|
||||
|
||||
meta_window_get_frame_rect (window, &old_frame_rect);
|
||||
meta_window_get_buffer_rect (window, &old_buffer_rect);
|
||||
|
||||
meta_window_make_fullscreen_internal (window);
|
||||
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_compositor_size_change_window (window->display->compositor,
|
||||
window, META_SIZE_CHANGE_FULLSCREEN,
|
||||
&old_frame_rect, &old_buffer_rect);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3220,7 +3222,7 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
||||
|
||||
if (window->fullscreen)
|
||||
{
|
||||
MetaRectangle target_rect;
|
||||
MetaRectangle old_frame_rect, old_buffer_rect, target_rect;
|
||||
|
||||
meta_topic (META_DEBUG_WINDOW_OPS,
|
||||
"Unfullscreening %s\n", window->desc);
|
||||
@ -3228,6 +3230,10 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
||||
window->fullscreen = FALSE;
|
||||
target_rect = window->saved_rect;
|
||||
|
||||
meta_window_frame_size_changed (window);
|
||||
meta_window_get_frame_rect (window, &old_frame_rect);
|
||||
meta_window_get_buffer_rect (window, &old_buffer_rect);
|
||||
|
||||
/* Window's size hints may have changed while maximized, making
|
||||
* saved_rect invalid. #329152
|
||||
*/
|
||||
@ -3241,10 +3247,17 @@ meta_window_unmake_fullscreen (MetaWindow *window)
|
||||
set_net_wm_state (window);
|
||||
|
||||
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,
|
||||
target_rect);
|
||||
|
||||
meta_compositor_size_change_window (window->display->compositor,
|
||||
window, META_SIZE_CHANGE_UNFULLSCREEN,
|
||||
&old_frame_rect, &old_buffer_rect);
|
||||
|
||||
meta_window_update_layer (window);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_FULLSCREEN]);
|
||||
@ -3565,7 +3578,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 +3719,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 +4051,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 +4099,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,
|
||||
@ -4332,8 +4344,8 @@ set_workspace_state (MetaWindow *window,
|
||||
GList *l;
|
||||
for (l = window->screen->workspaces; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWorkspace *workspace = l->data;
|
||||
meta_workspace_remove_window (workspace, window);
|
||||
MetaWorkspace *ws = l->data;
|
||||
meta_workspace_remove_window (ws, window);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4347,8 +4359,8 @@ set_workspace_state (MetaWindow *window,
|
||||
GList *l;
|
||||
for (l = window->screen->workspaces; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWorkspace *workspace = l->data;
|
||||
meta_workspace_add_window (workspace, window);
|
||||
MetaWorkspace *ws = l->data;
|
||||
meta_workspace_add_window (ws, window);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4634,12 +4646,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 +5665,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 +5735,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 +5759,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 +5805,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 +5873,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 +6074,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);
|
||||
}
|
||||
|
||||
@ -6401,7 +6304,7 @@ find_ancestor_func (MetaWindow *window,
|
||||
* so by traversing the @transient's ancestors until it either locates @window
|
||||
* or reaches an ancestor that is not transient.
|
||||
*
|
||||
* Return Value: (transfer none): %TRUE if window is an ancestor of transient.
|
||||
* Return Value: %TRUE if window is an ancestor of transient.
|
||||
*/
|
||||
gboolean
|
||||
meta_window_is_ancestor_of_transient (MetaWindow *window,
|
||||
@ -7139,7 +7042,7 @@ meta_window_get_transient_for (MetaWindow *window)
|
||||
* Returns pid of the process that created this window, if known (obtained from
|
||||
* the _NET_WM_PID property).
|
||||
*
|
||||
* Return value: (transfer none): the pid, or -1 if not known.
|
||||
* Return value: the pid, or -1 if not known.
|
||||
*/
|
||||
int
|
||||
meta_window_get_pid (MetaWindow *window)
|
||||
@ -7977,3 +7880,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);
|
||||
}
|
||||
|
@ -1055,7 +1055,7 @@ meta_workspace_get_onmonitor_region (MetaWorkspace *workspace,
|
||||
}
|
||||
|
||||
#ifdef WITH_VERBOSE_MODE
|
||||
static char *
|
||||
static const char *
|
||||
meta_motion_direction_to_string (MetaMotionDirection direction)
|
||||
{
|
||||
switch (direction)
|
||||
|
@ -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,13 @@ typedef enum
|
||||
META_COMP_EFFECT_NONE
|
||||
} MetaCompEffect;
|
||||
|
||||
typedef enum {
|
||||
META_SIZE_CHANGE_MAXIMIZE,
|
||||
META_SIZE_CHANGE_UNMAXIMIZE,
|
||||
META_SIZE_CHANGE_FULLSCREEN,
|
||||
META_SIZE_CHANGE_UNFULLSCREEN
|
||||
} MetaSizeChange;
|
||||
|
||||
MetaCompositor *meta_compositor_new (MetaDisplay *display);
|
||||
void meta_compositor_destroy (MetaCompositor *compositor);
|
||||
|
||||
@ -89,14 +96,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,
|
||||
|
@ -49,7 +49,7 @@ typedef enum
|
||||
} MetaExitCode;
|
||||
|
||||
/* exit immediately */
|
||||
void meta_exit (MetaExitCode code);
|
||||
void meta_exit (MetaExitCode code) G_GNUC_NORETURN;
|
||||
|
||||
/* g_main_loop_quit() then fall out of main() */
|
||||
void meta_quit (MetaExitCode code);
|
||||
|
@ -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:
|
@ -66,6 +66,21 @@ int meta_screen_get_active_workspace_index (MetaScreen *screen);
|
||||
|
||||
MetaWorkspace * meta_screen_get_active_workspace (MetaScreen *screen);
|
||||
|
||||
/**
|
||||
* MetaScreenDirection:
|
||||
* @META_SCREEN_UP: up
|
||||
* @META_SCREEN_DOWN: down
|
||||
* @META_SCREEN_LEFT: left
|
||||
* @META_SCREEN_RIGHT: right
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
META_SCREEN_UP,
|
||||
META_SCREEN_DOWN,
|
||||
META_SCREEN_LEFT,
|
||||
META_SCREEN_RIGHT
|
||||
} MetaScreenDirection;
|
||||
|
||||
int meta_screen_get_n_monitors (MetaScreen *screen);
|
||||
int meta_screen_get_primary_monitor (MetaScreen *screen);
|
||||
int meta_screen_get_current_monitor (MetaScreen *screen);
|
||||
@ -82,6 +97,10 @@ gboolean meta_screen_get_monitor_in_fullscreen (MetaScreen *screen,
|
||||
int meta_screen_get_monitor_index_for_rect (MetaScreen *screen,
|
||||
MetaRectangle *rect);
|
||||
|
||||
int meta_screen_get_monitor_neighbor_index (MetaScreen *screen,
|
||||
int which_monitor,
|
||||
MetaScreenDirection dir);
|
||||
|
||||
void meta_screen_focus_default_window (MetaScreen *screen,
|
||||
guint32 timestamp);
|
||||
|
||||
|
1
src/stamp-mutter-enum-types.h
Normal file
1
src/stamp-mutter-enum-types.h
Normal file
@ -0,0 +1 @@
|
||||
timestamp
|
@ -25,7 +25,7 @@
|
||||
#include <string.h>
|
||||
#include <X11/extensions/sync.h>
|
||||
|
||||
char *client_id = "0";
|
||||
const char *client_id = "0";
|
||||
static gboolean wayland;
|
||||
GHashTable *windows;
|
||||
|
||||
|
@ -1094,7 +1094,6 @@ main (int argc, char **argv)
|
||||
if (all_tests)
|
||||
{
|
||||
GFile *test_dir = g_file_new_for_path (MUTTER_PKGDATADIR "/tests");
|
||||
GError *error = NULL;
|
||||
|
||||
if (!find_metatests_in_directory (test_dir, tests, &error))
|
||||
{
|
||||
@ -1120,7 +1119,7 @@ main (int argc, char **argv)
|
||||
|
||||
/* Then initalize mutter with a different set of arguments */
|
||||
|
||||
char *fake_args[] = { NULL, "--wayland" };
|
||||
char *fake_args[] = { NULL, (char *)"--wayland" };
|
||||
fake_args[0] = argv[0];
|
||||
char **fake_argv = fake_args;
|
||||
int fake_argc = 2;
|
||||
|
@ -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;
|
||||
@ -915,11 +915,9 @@ meta_theme_get_default (void)
|
||||
switch (frame_type)
|
||||
{
|
||||
case META_FRAME_TYPE_NORMAL:
|
||||
break;
|
||||
case META_FRAME_TYPE_DIALOG:
|
||||
case META_FRAME_TYPE_MODAL_DIALOG:
|
||||
case META_FRAME_TYPE_ATTACHED:
|
||||
layout->hide_buttons = TRUE;
|
||||
break;
|
||||
case META_FRAME_TYPE_MENU:
|
||||
case META_FRAME_TYPE_UTILITY:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user