Compare commits

..

4 Commits

Author SHA1 Message Date
7947bcb0b0 dnd 2 2014-09-01 14:34:33 -07:00
308cccc72c dnd 2014-09-01 14:34:33 -07:00
074946ac0b hot offs 2014-09-01 14:34:33 -07:00
9688a0d7bc wayland: Record the offset position
This is needed for DND surfaces. We should probably test to see if it's
used for cursor surfaces at all.
2014-09-01 14:34:33 -07:00
300 changed files with 96795 additions and 69053 deletions

24
.gitignore vendored
View File

@ -44,10 +44,6 @@ po/*.pot
libmutter.pc
mutter
mutter-restart-helper
mutter-test-client
mutter-test-runner
mutter-test-unit-tests
mutter-all.test
org.gnome.mutter.gschema.valid
org.gnome.mutter.gschema.xml
org.gnome.mutter.wayland.gschema.valid
@ -58,23 +54,19 @@ testgradient
m4/*
INSTALL
mkinstalldirs
meta-enum-types.[ch]
src/stamp-meta-enum-types.h
src/mutter-enum-types.[ch]
src/stamp-mutter-enum-types.h
src/mutter-marshal.[ch]
src/stamp-mutter-marshal.h
src/meta-dbus-display-config.[ch]
src/meta-dbus-idle-monitor.[ch]
src/meta-dbus-login1.[ch]
src/gtk-primary-selection-protocol.c
src/gtk-primary-selection-server-protocol.h
src/gtk-shell-protocol.c
src/gtk-shell-server-protocol.h
src/xdg-shell-unstable-v*-protocol.c
src/xdg-shell-unstable-v*-server-protocol.h
src/pointer-gestures-unstable-v*-protocol.c
src/pointer-gestures-unstable-v*-server-protocol.h
src/relative-pointer-unstable-v*-protocol.c
src/relative-pointer-unstable-v*-server-protocol.h
src/pointer-constraints-unstable-v*-protocol.c
src/pointer-constraints-unstable-v*-server-protocol.h
src/xdg-shell-protocol.c
src/xdg-shell-server-protocol.h
src/xserver-protocol.c
src/xserver-server-protocol.h
src/meta/meta-version.h
doc/reference/*.args
doc/reference/*.bak

View File

@ -9,3 +9,5 @@ DISTCLEANFILES = \
intltool-update \
po/stamp-it \
po/.intltool-merge-cache
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc

447
NEWS
View File

@ -1,450 +1,3 @@
3.20.0
======
* Fix crash when using visual bell [Jonas; #763858]
Contributors:
Jonas Ådahl, Jasper St. Pierre
Translations:
Milo Casagrande [it], Ask Hjorth Larsen [da]
3.19.92
=======
* Add system bell support on wayland [Jonas; #763284]
* Add gtk_surface.present to gtk-shell [Jonas; #763295]
* Handle DND drops on the root window [Carlos; #762104]
* Misc. bug fixes [Jonas, Carlos, Rui; #762828, #760745, #763125, #762763,
#762661, #762639, #763159]
Contributors:
Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner
Translations:
Rūdolfs Mazurs [lv], Balázs Úr [hu], Claude Paroz [fr], Matej Urbančič [sl],
Мирослав Николић [sr, sr@latin], Sebastian Rasmussen [sv], Changwoo Ryu [ko],
Gil Forcada [ca], Tom Tryfonidis [el]
3.19.91
=======
* Add --nested CLI argument to fix nested wayland session [Jonas; #758658]
* Fix stack - scene graph stacking synchronization issues [Jonas; #755605]
* Rate-limit last-device changes to fix freezes [Carlos; #753527]
* Implement primary selection protocol [Carlos; #762560]
* Misc. bug fixes [Carlos, Jonas; #762878, #762716]
Contributors:
Jonas Ådahl, Carlos Garnacho, Tim Lunn
Translations:
Piotr Drąg [pl], Artur de Aquino Morais [pt_BR], Marek Černocký [cs],
Cédric Valmary [oc], Mario Blättermann [de], Dušan Kazik [sk],
Fran Dieguez [gl], Aurimas Černius [lt], Daniel Mustieles [es],
Stas Solovey [ru], Yosef Or Boczko [he]
3.19.90
=======
* Release buffer after processing commit [Ray; #761312, #761613]
* Implement pointer motion, locks and confinement on wayland [Jonas; #744104]
* Add basic startup notification support on wayland [Carlos; #762268]
* Misc. bug fixes [Rui, Alberts, Florian; #760670, #761543, #752794, #761557]
Contributors:
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos,
Alberts Muktupāvels, Florian Müllner, Jasper St. Pierre, Ray Strode
3.19.4
======
* Fix updating stacking order when setting transient_for [Jonas; #755606]
* Support screen rotation when supported by the driver [Carlos; #745079]
* Protect against broken WM_CLASS property implementations [Sebastian; #759658]
* Handle wl_pointer v5 events on wayland [Carlos; #760637]
* Implement DND actions on wayland [Carlos; #760805]
* Misc. bug fixes [Jonas, Rui, Ray, Marek; #754711, #756789, #759297, #758613,
#760330, #760476, #759222, #760670]
Contributors:
Jonas Ådahl, Marek Chalupa, Carlos Garnacho, Sebastian Keller, Rui Matos,
Florian Müllner, Jasper St. Pierre, Ray Strode
Translations:
Aurimas Černius [lt]
3.19.3
======
* Correct refresh rate units on KMS/Wayland [Daniel; #758653]
* Fix crash when initial cursor position is not on a monitor [Marek; #756698]
* Fix crash when more CRTs are enabled than outputs connected [Rui; #751638]
* Fix touch pointer emulation on wayland [Carlos; #756754]
* Allow minimizing windows that don't advertise supporting it [Jasper; #758186]
* Force 2-finger scroll by default if available [Bastien; #759304]
* Fix crash during XWayland initialization [Marek; #751845]
* Ensure to send a ConfigureNotify to just mapped windows [Rui; #759492]
* Misc. bug fixes and cleanups [Carlos, Jonas, Lionel; #758239, #758633,
#755503, #759374]
Contributors:
Jonas Ådahl, Marek Chalupa, Carlos Garnacho, Lionel Landwerlin, Rui Matos,
Bastien Nocera, Daniel Stone, Jasper St. Pierre
3.19.2
======
* Fix crash on monitor unplug [Rui; #756796]
* Exit cleanly on initialization errors [Owen; #757311]
* Allow to determine backend setting from session type [Ray; #741666]
* Fix DRM device detection for non-PCI devices [Alban; #754911]
* Don't force placement of windows without buffer on wayland [Marek; #751887]
* Fix initialization of bypass compositor hint [Rui; #758544]
Contributors:
Alban Browaeys, Marek Chalupa, Rui Matos, Florian Müllner, Ray Strode,
Owen W. Taylor
3.19.1
======
* wayland: Allow to trigger popups through keyboard/touch [Carlos; #756296]
* Fix modifiers-only input source switching on Ubuntu [Alberts; #756543]
* Misc. bug fixes [Jonas, Rui, Giovanni, Florian; #756675, #756660, #746420,
#756548, #756796, #757101, #757148]
Contributors:
Jonas Ådahl, Giovanni Campagna, Carlos Garnacho, Rui Matos,
Alberts Muktupāvels, Florian Müllner
Translations:
Daniel Șerbănescu [ro]
3.18.1
======
* Misc. crash fixes [Jonas, Rui, Carlos, Owen, Florian; #755096, #754979,
#755490, #754357, #745785, #756642]
* Improve HiDPI support on wayland [Jonas; #755097]
* Fix doubly-scaled cursor on XWayland HiDPI [Jonas; #755099]
* Stop hiding titlebar buttons in dialogs [Florian; #641630]
* Add support for fullscreen/unfullscreen animations [Cosimo; #707248]
* Misc. bug fixes [Rui, Colin, Florian; #743339, #752047, #756074, #756649]
Contributors:
Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Florian Müllner,
Jasper St. Pierre, Colin Walters, Owen W. Taylor
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]
* Fix swapped scroll methods on wayland [Ondrej; #746870]
* Manually activate stage to fix accessibility on wayland [Ray, Rui; #746670]
* Center pointer on primary monitor on startup [Carlos; #746896]
* wayland: Reword synchronized state application semantics [Jonas; #743617]
* Ensure input settings are applied on startup [Rui; #747434]
* Misc. bug fixes [Jonas, Giovanni, Calvin, Ray, Rui; #744932, #746509, #746692,
#746510, #746545, #747263]
Contributors:
Jonas Ådahl, Giovanni Campagna, Carlos Garnacho, Ondrej Holy, Rui Matos,
Jasper St. Pierre, Ray Strode, Calvin Walton
Translations:
Khaled Hosny [ar], Marek Černocký [cs]
3.16.0
======
* wayland: Don't skip notifying about initial maximized state [Jonas; #745303]
Contributors:
Jonas Ådahl
Translations:
Kjartan Maraas [nb], Jiri Grönroos [fi], Andika Triwidada [id],
Inaki Larranaga Murgoitio [eu], Ask H. Larsen [da], Muhammet Kara [tr]
3.15.92
=======
* Ensure pointer visibility on monitor changes [Rui, Marek; #745121, #745752]
* Fix geometry of shaded windows [Florian; #746145]
* Take over cursor visibility handling from gsd [Carlos; #712775]
* Fix touch interaction on window decorations [Carlos; #745335]
* Add options for libinput_config_click_method [Carlos; #746290]
* Scale window decorations on HiDPI displays [Florian; #744354]
* Misc. bug fixes [Carlos, Ray, Rui; #745163, #746295, #746098, #745734]
Contributors:
Marek Chalupa, Carlos Garnacho, Rui Matos, Florian Müllner,
Jasper St. Pierre, Ray Strode
Translations:
Piotr Drąg [pl], Milo Casagrande [it], Changwoo Ryu [ko],
Daniel Korostil [uk], Baurzhan Muftakhidinov [kk], Trần Ngọc Quân [vi],
Alexander Shopov [bg], Jordi Mas [ca], Samir Ribic [bs], A S Alam [pa],
Matej Urbančič [sl]
3.15.91
=======
* wayland: Fix nested compositor mode [Jonas; #745401]
* wayland: Fix pointer constraining [Marek; #727337]
* wayland: Fix input region on HiDPI [Jonas; #744933]
* Allow themes to style buttons differently based on function [Horst; #745108]
* Misc. bug fixes and cleanups [Ray, Rui, Alban; #745141, #745118, #745476,
#745442]
Contributors:
Jonas Ådahl, Alban Browaeys, Marek Chalupa, Horst, Rui Matos,
Jasper St. Pierre, Ray Strode
Translations:
Chao-Hsiung Liao [zh_TW], Efstathios Iosifidis [el], Dušan Kazik [sk],
Balázs Úr [hu], Daniel Mustieles [es], Claude Paroz [fr], Stas Solovey [ru],
Yosef Or Boczko [he], Rafael Ferreira [pt_BR], Aurimas Černius [lt],
Fran Dieguez [gl], Anders Jonsson [sv], Мирослав Николић [sr, sr@latin]
3.15.90
=======
* Initialize MetaOutput even when we can't get the EDID [Rui; #743412]
* Expose MetaMonitorManager to introspection [Rui; #743745]
* Fix flash on unredirection [Chris; #743858]
* Update xdg-shell implementation to v5 [Jonas; #744452]
* Do not try to use seat devices that aren't (yet) present [Ray; #744640]
* Add keybindings for switching to VT8-VT12 [Ray; #744800]
* Misc bug fixes [Jonas, Cosimo; #743678, #744500]
Contributors:
Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Jasper St. Pierre,
Ray Strode, Chris Wilson
Translations:
Yosef Or Boczko [he], Yuri Myasoedov [ru], Kristjan SCHMIDT [eo],
Matej Urbančič [sl], Dušan Kazik [sk]
3.15.4
======
* Use GTK+ theme for window decorations instead of metacity [Florian; #741917]
* Export the same EDID information on X11 and wayland [Carlos; #742882]
* Apply input device configuration on wayland [Carlos; #739397]
* Implement pointer barriers on wayland [Jonas; #706655]
* Misc. bug fixes (Ting-Wei, Rui, Ikey, Florian, Marek, Jonas; #741829,
#738630, #737463, #698995, #727893, #742825, #742824, #742841, #743173,
#743189, #743217, #743254]
Contributors:
Jonas Ådahl, Giovanni Campagna, Marek Chalupa, Ikey Doherty, Adel Gadllah,
Carlos Garnacho, Ting-Wei Lan, Rui Matos, Florian Müllner, Jasper St. Pierre,
Rico Tzschichholz
Translations:
Matej Urbančič [sl], Balázs Úr [hu], Marek Černocký [cs],
Inaki Larranaga Murgoitio [eu], Rafael Ferreira [pt_BR],
Daniel Mustieles [es], Fran Dieguez [gl]
3.15.3
======
* Don't leave left-over frames queued [Owen; #738686]
* Set CRTC configuration even if it might be redundant [Rui; #740838]
Contributors:
Rui Matos, Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor
Translations:
Trần Ngọc Quân [vi], Muhammet Kara [tr]
3.15.2
======
* Don't enable hiDPI on monitors with broken EDID [Bastien; #734839]
* Prevent crash applying monitor config for a closed lid [Rui; #739450]
* Fix "flicker" during startup transition [Ray; #740377]
* Misc. bug fixes [Lan, Florian, Carlos; #731521, #740133, #738890]
Contributors:
Emmanuele Bassi, Carlos Garnacho, Jonathon Jongsma, Ting-Wei Lan, Rui Matos,
Florian Müllner, Bastien Nocera, Jasper St. Pierre, Ray Strode
Translations:
Kjartan Maraas [nb]
3.15.1
======
* Use GResources for theme loading [Cosimo; #736936]
* Fix headerbar drag getting stuck on xwayland [Carlos; #738411]
* Fix wayland hiDPI regressions [Adel; #739161]
* Misc bug fixes and cleanups [Jasper, Rui, Carlos; #662962, #738630, #738888,
#738890]
Contributors:
Cosimo Cecchi, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner,
Jasper St. Pierre
3.14.1
======
* Fix move-titlebar-onscreen function [Florian; #736915]
* Fix stacking of the guard window [Owen; #737233]
* Fix keycode lookup for non-default layouts [Rui; #737134]
* Fix workspaces-only-on-primary handling [Florian; #737178]
* Don't unstick sticky windows on workspace removal [Florian; #737625]
* Do not auto-minimize fullscreen windows [Jasper; #705177]
* Upload keymap to newly added keyboard devices [Rui; #737673]
* Apply keyboard repeat settings [Rui; #728055]
* Don't send pressed keys on enter [Rui; #727178]
* Fix build without wayland/native [Rico; #738225]
* Send modifiers after the key event [Rui; #738238]
* Fix unredirect heuristic [Adel; #738271]
* Do not show system chrome over fullscreen windows [Florian; #693991]
* Misc. bug fixes [Florian, Adel, Tom; #737135, #737581, #738146, #738384]
Contributors:
Tom Beckmann, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner,
Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor
Translations:
Krishnababu Krothapalli [te], Мирослав Николић [sr, sr@latin],
Alexander Shopov [bg], Saibal Ray [bn_IN], Milo Casagrande [it],
Rūdolfs Mazurs [lv]
3.14.0
======
* Fix placement of popup windows on wayland [Jasper; #736812]
* Only increment serial once per event [Jasper; #736840]
* Fix window positioning regression with non-GTK+ toolkits [Owen; #736719]
Contributors:
Jasper St. Pierre, Owen W. Taylor
Translations:
Saibal Ray [bn_IN], Dušan Kazik [sk], Manoj Kumar Giri [or],
Christian Kirbach [de], Ask H. Larsen [da], YunQiang Su [zh_CN],
Bernd Homuth [de], Shankar Prasad [kn], Petr Kovar [cs], Rajesh Ranjan [hi]
3.13.92
=======
* Rewrite background code [Owen; #735637, #736568]
* Fix size in nested mode [Owen; #736279]
* Fix destroy animation of background windows [Florian; #735927]
* Wire keymap changes up to the wayland frontend [Rui; #736433]
* Add a test framework and stacking tests [Owen; #736505]
* Simplify handling of the merged X and wayland stack [Owen; #736559]
* Fix cursor size on HiDPI [Adel; #729337]
* Misc. bug fixes [Owen; #735632, #736589, #736694]
Contributors:
Adel Gadllah, Rui Matos, Florian Müllner, Jasper St. Pierre, Owen W. Taylor
Translations:
Andika Triwidada [id], Piotr Drąg [pl], Changwoo Ryu [ko],
Kjartan Maraas [nb], Ville-Pekka Vainio [fi], Yuri Myasoedov [ru],
Aurimas Černius [lt], Balázs Úr [hu], Sweta Kothari [gu], A S Alam [pa],
Sandeep Sheshrao Shedmake [mr], Shantha kumar [ta], Gil Forcada [ca],
Carles Ferrando [ca@valencia], Mattias Eriksson [sv]
3.13.91
=======
* Misc. bug fixes [Carlos; #735452]
Contributors:
Adel Gadllah, Carlos Garnacho, Rui Matos, Jasper St. Pierre,
Rico Tzschichholz
Translations:
Chao-Hsiung Liao po/zh_HK, zh_TW.po, Enrico Nicoletto [pt_BR],
Kjartan Maraas [nb], Fran Diéguez [gl], Yosef Or Boczko [he],
Maria Mavridou [el], Claude Paroz [fr]
3.13.90
=======
* Only call XSync() once per frame [Rui; #728464]

View File

@ -4,6 +4,7 @@
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
PKG_NAME="mutter"
REQUIRED_AUTOMAKE_VERSION=1.11
(test -f $srcdir/configure.ac \
@ -18,4 +19,4 @@ which gnome-autogen.sh || {
echo "your distribution's package manager)."
exit 1
}
. gnome-autogen.sh
USE_GNOME2_MACROS=1 USE_COMMON_DOC_BUILD=yes . gnome-autogen.sh

View File

@ -1,8 +1,8 @@
AC_PREREQ(2.62)
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [20])
m4_define([mutter_micro_version], [0])
m4_define([mutter_minor_version], [13])
m4_define([mutter_micro_version], [90])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@ -46,26 +46,40 @@ IT_PROG_INTLTOOL([0.41])
AC_PROG_CC
AC_PROG_CC_C_O
AC_PROG_INSTALL
AC_PROG_SED
AC_HEADER_STDC
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
CLUTTER_PACKAGE=clutter-1.0
MUTTER_PC_MODULES="
gtk+-3.0 >= 3.19.8
gio-unix-2.0 >= 2.35.1
gtk+-3.0 >= 3.9.11
gio-unix-2.0 >= 2.25.10
pango >= 1.2.0
cairo >= 1.10.0
gsettings-desktop-schemas >= 3.19.3
$CLUTTER_PACKAGE >= 1.25.6
gsettings-desktop-schemas >= 3.7.3
$CLUTTER_PACKAGE >= 1.19.5
clutter-egl-1.0
cogl-1.0 >= 1.17.1
gbm
upower-glib >= 0.99.0
gnome-desktop-3.0
xcomposite >= 0.2
@ -78,7 +92,6 @@ MUTTER_PC_MODULES="
xkeyboard-config
xkbcommon >= 0.4.3
xkbcommon-x11
xrender
x11-xcb
xcb-randr
"
@ -114,12 +127,6 @@ AC_ARG_WITH([xwayland-path],
[XWAYLAND_PATH="$withval"],
[XWAYLAND_PATH="$bindir/Xwayland"])
AC_ARG_ENABLE(installed_tests,
AS_HELP_STRING([--enable-installed-tests],
[Install test programs (default: no)]),,
[enable_installed_tests=no])
AM_CONDITIONAL(BUILDOPT_INSTALL_TESTS, test x$enable_installed_tests = xyes)
## here we get the flags we'll actually use
# Unconditionally use this dir to avoid a circular dep with gnomecc
@ -189,43 +196,22 @@ AC_SUBST(XWAYLAND_PATH)
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
MUTTER_NATIVE_BACKEND_MODULES="clutter-egl-1.0 libdrm libsystemd libinput gudev-1.0 gbm >= 10.3"
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd libinput], [have_native_backend=yes], [have_native_backend=no])
if test $have_native_backend = yes; then
AC_DEFINE([HAVE_NATIVE_BACKEND],[1],[Define if you want to enable the native (KMS) backend based on systemd])
fi
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test $have_native_backend = yes])
AC_ARG_ENABLE(native-backend,
AS_HELP_STRING([--disable-native-backend], [disable mutter native (KMS) backend]),,
enable_native_backend=auto
)
AS_IF([test "$enable_native_backend" = "yes"], [have_native_backend=yes],
[test "$enable_native_backend" = "auto"], PKG_CHECK_EXISTS([$MUTTER_NATIVE_BACKEND_MODULES], [have_native_backend=yes]))
PKG_CHECK_MODULES(MUTTER_WAYLAND, [clutter-wayland-1.0 clutter-wayland-compositor-1.0 wayland-server >= 1.5.90], [have_wayland=yes], [have_wayland=no])
if test $have_wayland = yes; then
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
AS_IF([test $WAYLAND_SCANNER = "no"],
AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols]))
AC_SUBST([WAYLAND_SCANNER])
AS_IF([test "$have_native_backend" = "yes"], [
PKG_CHECK_MODULES([MUTTER_NATIVE_BACKEND], [$MUTTER_NATIVE_BACKEND_MODULES])
AC_DEFINE([HAVE_NATIVE_BACKEND],[1], [Define if you want to enable the native (KMS) backend based on systemd])
])
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test "$have_native_backend" = "yes"])
MUTTER_WAYLAND_MODULES="clutter-wayland-1.0 clutter-wayland-compositor-1.0 wayland-server >= 1.6.90"
AC_ARG_ENABLE(wayland,
AS_HELP_STRING([--disable-wayland], [disable mutter on wayland support]),,
enable_wayland=auto
)
AS_IF([test "$enable_wayland" = "yes"], [have_wayland=yes],
[test "$enable_wayland" = "auto"], PKG_CHECK_EXISTS([$MUTTER_WAYLAND_MODULES], [have_wayland=yes]))
AS_IF([test "$have_wayland" = "yes"], [
PKG_CHECK_MODULES([MUTTER_WAYLAND], [$MUTTER_WAYLAND_MODULES])
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
AS_IF([test $WAYLAND_SCANNER = "no"],
[AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])])
AC_SUBST([WAYLAND_SCANNER])
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
PKG_CHECK_MODULES(WAYLAND_PROTOCOLS, [wayland-protocols >= 1.1],
[ac_wayland_protocols_pkgdatadir=`$PKG_CONFIG --variable=pkgdatadir wayland-protocols`])
AC_SUBST(WAYLAND_PROTOCOLS_DATADIR, $ac_wayland_protocols_pkgdatadir)
])
AM_CONDITIONAL([HAVE_WAYLAND],[test "$have_wayland" = "yes"])
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
fi
AM_CONDITIONAL([HAVE_WAYLAND],[test $have_wayland = yes])
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))
@ -276,8 +262,6 @@ 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"
@ -324,10 +308,7 @@ if test "x$enable_debug" = "xyes"; then
CFLAGS="$CFLAGS -g -O"
fi
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>])
GTK_DOC_CHECK([1.15], [--flavour no-tmpl])
#### Warnings (last since -Werror can disturb other tests)
@ -400,6 +381,8 @@ 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
@ -429,8 +412,6 @@ mutter-$VERSION
libcanberra: ${have_libcanberra}
Introspection: ${found_introspection}
Session management: ${found_sm}
Wayland: ${have_wayland}
Native (KMS) backend: ${have_native_backend}
"

View File

@ -1,5 +1,6 @@
desktopfiles_in_files = \
mutter.desktop.in
mutter.desktop.in \
mutter-wayland.desktop.in
desktopfilesdir = $(datadir)/applications
desktopfiles_DATA = $(desktopfiles_in_files:.desktop.in=.desktop)

View File

@ -0,0 +1,17 @@
[Desktop Entry]
Type=Application
_Name=Mutter (wayland compositor)
Exec=mutter --wayland --display-server
NoDisplay=true
# name of loadable control center module
X-GNOME-WMSettingsModule=metacity
# name we put on the WM spec check window
X-GNOME-WMName=Mutter
# back compat only
X-GnomeWMSettingsLibrary=metacity
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=mutter
X-GNOME-Bugzilla-Component=general
X-GNOME-Autostart-Phase=WindowManager
X-GNOME-Provides=windowmanager
X-GNOME-Autostart-Notify=true

View File

@ -29,25 +29,5 @@
<default><![CDATA[['<Primary><Alt>F7']]]></default>
<_summary>Switch to VT 7</_summary>
</key>
<key name="switch-to-session-8" type="as">
<default><![CDATA[['<Primary><Alt>F8']]]></default>
<_summary>Switch to VT 8</_summary>
</key>
<key name="switch-to-session-9" type="as">
<default><![CDATA[['<Primary><Alt>F9']]]></default>
<_summary>Switch to VT 9</_summary>
</key>
<key name="switch-to-session-10" type="as">
<default><![CDATA[['<Primary><Alt>F10']]]></default>
<_summary>Switch to VT 10</_summary>
</key>
<key name="switch-to-session-11" type="as">
<default><![CDATA[['<Primary><Alt>F11']]]></default>
<_summary>Switch to VT 11</_summary>
</key>
<key name="switch-to-session-12" type="as">
<default><![CDATA[['<Primary><Alt>F12']]]></default>
<_summary>Switch to VT 12</_summary>
</key>
</schema>
</schemalist>

View File

@ -1,4 +1,4 @@
SUBDIRS = man
SUBDIRS = man reference
EXTRA_DIST = dialogs.txt code-overview.txt \
EXTRA_DIST=theme-format.txt dialogs.txt code-overview.txt \
how-to-get-focus-right.txt rationales.txt

164
doc/reference/Makefile.am Normal file
View File

@ -0,0 +1,164 @@
## 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-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)
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

View File

@ -0,0 +1,59 @@
<?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/gradient.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>

View File

@ -0,0 +1,684 @@
<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>gradient</FILE>
MetaGradientType
meta_gradient_create_simple
meta_gradient_create_multi
meta_gradient_create_interwoven
meta_gradient_add_alpha
</SECTION>
<SECTION>
<FILE>group</FILE>
MetaGroup
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_get_outer_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>

View File

@ -0,0 +1,15 @@
<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>

View File

@ -0,0 +1,100 @@
<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>

396
doc/theme-format.txt Normal file
View File

@ -0,0 +1,396 @@
Themes are in a simple XML-subset format. There are multiple versions
of the theme format, and a given theme can support more than one format.
Version 1: THEMEDIR/metacity-1/metacity-theme-1.xml
(original metacity format)
Version 2: THEMEDIR/metacity-1/metacity-theme-2.xml
Version 3: THEMEDIR/metacity-1/metacity-theme-3.xml
The subdirectory name is "metacity-1" in all versions.
As you might expect, older versions of metacity will not understand
newer theme formats. However, newer versions will use old themes.
Metacity will always use the newest theme format it understands that
the X server supports. Some format versions are only supported if you
have the right X server features.
Each format *requires* the corresponding filename. If you put version
2 format features in the metacity-1/metacity-theme-1.xml file, then
metacity will get angry.
This document has separate sections for each format version. You may
want to read the document in reverse order, since the base features
are discussed under version 1.
New Features in Theme Format Version 3.4
========================================
An additional color type is added to pick up custom colors defined
in the GTK+ theme's CSS:
gtk:custom(name,fallback)
where <name> refers to a custom color defined with @define-color in
the GTK+ theme, and <fallback> provides an alternative color definition
in case the color referenced by <name> is not found.
New Features in Theme Format Version 3.3
========================================
Add two additional button background functions - left_single_background and
right_single_background - for button groups with just a single button.
There are now additional frame states to style left/right tiled windows
differently ("tiled_left", "tiled_right", "tiled_left_and_shaded",
"tiled_right_and_shaded").
New Features in Theme Format Version 3.2
========================================
A new window type 'attached' is added for modal dialogs which are
attached to their parent window. (When the attach_modal_dialogs preference
is turned on.) If no style is defined for the 'attached' window type,
the 'border' window type will be used instead.
New Features in Theme Format Version 3.1
========================================
Additional predefined variables are added for positioning expressions:
frame_x_center: the X center of the entire frame, with respect to the
piece currently being drawn.
frame_y_center: the Y center of the entire frame, with respect to the
piece currently being drawn.
The <title/> element now supports an "ellipsize_width" attribute. When
specified, this gives a width at which to ellipsize the title. If not
specified, the title will simply be clipped to the title area.
New Features in Theme Format Version 3
======================================
Format version 3 has exactly one new feature; any element in the file
can now have a version attribute:
version="[<|<=|=>|>] MAJOR.MINOR"
(< and > should be to be entity escaped as &lt; and &gt;). If this
version check is not met, then the element and its children will be
ignored. This allows having alternate sections of the theme file for
older and newer version of the Metacity theme format.
When placed on the toplevel <metacity_theme> element, an unsatisfied
version check will not just cause the contents of the file to be
ignored, it will also cause the lookup of a theme file to proceed on
and look for an older format 2 or format 1 file. This allows making a
metacity-theme-3.xml file that is only used the format version 3.2 or
newer is supported, and using metacity-theme-1.xml for older window
managers.
New Features in Theme Format Version 2
======================================
The optional attributes rounded_top_left, rounded_top_right,
rounded_bottom_left and rounded_bottom_right on <frame_geometry>
should now be the radius of the corner in pixels. You may still use
the values "false" for 0 and "true" for 5, which means v1 values will
still work just fine.
<frame_geometry> has a new optional attribute, hide_buttons. If this
is true, no buttons will be displayed on the titlebar.
Anywhere you can use a positive integer, you can use an integer constant.
As well as constant integers and reals, you may define constant colours,
thus:
<constant name="RevoltingPink" value="#FF00FF"/>
<constant name="Background" value="gtk:bg[NORMAL]"/>
<frame_style> has two new optional attributes, background and alpha.
If you specify alpha, you must specify background. background is a
colour used for the background of the frame. alpha is the transparency
as a real between 0.0 and 1.0. If the current X server does not support
alpha channels, the value is ignored.
The filename attribute of <image> may begin with "theme:". If so, the
rest of the string is the name of a theme icon. The 64x64 version of the
icon is used, except for fallback mini_icons, which use the 16x16 version.
This does not affect ordinary resizing. For example:
<button function="close" state="normal">
<draw_ops>
<include name="active_button"/>
<image filename="theme:gnome-logout" x="2" y="2"
width="width-4" height="height-4"/>
<!-- Note: not "theme:gnome-logout.png" or similar. -->
</draw_ops>
</button>
<menu_icon>s are parsed but ignored.
Fallback icons can be specified using <fallback>. There are two
optional arguments, icon and mini_icon. The values of these arguments
are identical to that of the filename attribute of <image>. Fallback
icons are used when a window does not supply its own icon. If a fallback
icon is not specified with <fallback>, Metacity will use a built-in
icon, as in metacity-theme-1.
The <arc> element, as well as the original start_angle and end_angle
attributes, may be given from and to attributes. The values of these
attributes are given in degrees clockwise, with 0 being straight up.
For example:
<arc from="0.0" to="90.0" filled="true" color="#FF00FF"
x="0" y="5" width="15" height="15"/>
<frame state="shaded"> may now take an optional resize attribute, with
the same interpretation as the resize attribute on <frame state="normal">.
If this attribute is omitted for state="shaded", it defaults to "both".
(If it is omitted for state="normal", it remains an error.)
In addition to the four <button> functions which are required in
metacity-theme-1, there are six new functions in metacity-theme-2:
shade, unshade, above, unabove, stick and unstick.
Overview of Theme Format Version 1
==================================
<?xml version="1.0"?>
<metacity_theme>
<!-- Only one info section is allowed -->
<info>
<name>Foo</name>
<author>Foo P. Bar</author>
<copyright>whoever, 2002</copyright>
<date>Jan 31 2005</date>
<description>A sentence about the theme.</description>
</info>
<!-- define a frame geometry to be referenced later -->
<!-- frame_geometry has an optional has_title attribute which
determines whether the title text height is included in the
height calculation. if not specified, defaults to true.
It also has an optional text_size="medium" attribute
(same sizes as with Pango markup, xx-small thru medium thru
xx-large)
Finally it has optional args rounded_top_left=true,
rounded_top_right=true, rounded_bottom_left=true,
rounded_bottom_right=true.
-->
<frame_geometry name="normal" has_title="true" title_scale="medium">
<distance name="left_width" value="6"/>
<distance name="right_width" value="6"/>
<distance name="bottom_height" value="7"/>
<distance name="left_titlebar_edge" value="6"/>
<distance name="right_titlebar_edge" value="6"/>
<distance name="button_width" value="17"/>
<distance name="button_height" value="17"/>
<!-- alternative to button_width button_height distances -->
<aspect_ratio name="button" value="1.0"/>
<distance name="title_vertical_pad" value="4"/>
<border name="title_border" left="3" right="12" top="4" bottom="3"/>
<border name="button_border" left="0" right="0" top="1" bottom="1"/>
</frame_geometry>
<!-- inheritance is allowed; simply overwrites values from parent -->
<frame_geometry name="borderless" parent="normal">
<distance name="left_width" value="0"/>
<distance name="right_width" value="0"/>
<distance name="bottom_height" value="0"/>
<distance name="left_titlebar_edge" value="0"/>
<distance name="right_titlebar_edge" value="0"/>
</frame_geometry>
<!-- define a constant to use in positions/sizes of draw operations;
constant names must start with a capital letter.
-->
<constant name="LineOffset" value="3"/>
<!-- define drawing operations to be referenced later;
these draw-op lists can also be placed inline.
Positions/lengths are given as expressions.
Operators are: +,-,*,/,%,`max`,`min`
All operators are infix including `max` and `min`,
i.e. "2 `max` 5"
Some variables are predefined, and constants can also
be used. Variables are:
width - width of target area
height - height of target area
object_width - natural width of object being drawn
object_height - natural height of object being drawn
left_width - distance from left of frame to client window
right_width - distance from right of frame to client window
top_height - distance from top of frame to client window
bottom_height - distance from bottom of frame to client window
mini_icon_width - width of mini icon for window
mini_icon_height - height of mini icon
icon_width - width of large icon
icon_height - height of large icon
title_width - width of title text
title_height - height of title text
All these are always defined, except object_width/object_height
which only exists for <image> right now.
-->
<draw_ops name="demo_all_ops">
<line color="#00FF00" x1="LineOffset" y1="0" x2="0" y2="height"/>
<line color="gtk:fg[NORMAL]"
x1="width - 1" y1="0" x2="width - 1" y2="height"
width="3" dash_on_length="2" dash_off_length="3"/>
<rectangle color="blend/gtk:fg[NORMAL]/gtk:bg[NORMAL]/0.7"
x="0" y="0" width="width - 1" height="height - 1" filled="true"/>
<arc color="dark gray" x="0" y="0" width="width - 1" height="height - 1"
filled="false" start_angle="30" extent_angle="180"/>
<tint color="orange" alpha="0.5" x="0" y="0" width="width" height="height"/>
<!-- may be vertical, horizontal, diagonal -->
<gradient type="diagonal"
x="10" y="30" width="width / 3" height="height / 4">
<!-- any number of colors allowed here. A color can be
a color name like "blue" (look at gcolorsel), a hex color
as in HTML (#FFBB99), or a color from the gtk theme
given as "gtk:base[NORMAL]", "gtk:fg[ACTIVE]", etc.
-->
<color value="gtk:fg[SELECTED]"/>
<!-- color obtained by a 0.5 alpha composite of the second color onto the first -->
<color value="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.5"/>
</gradient>
<!-- image has an optional colorize="#color" attribute to give the
image a certain color -->
<image filename="foo.png" alpha="0.7"
x="10" y="30" width="width / 3" height="height / 4"/>
<gtk_arrow state="normal" shadow="in" arrow="up"
filled="true"
x="2" y="2" width="width - 4" height="height - 4"/>
<gtk_box state="normal" shadow="out"
x="2" y="2" width="width - 4" height="height - 4"/>
<gtk_vline state="normal" x="2" y1="0" y2="height"/>
<!-- window's icon -->
<icon alpha="0.7"
x="10" y="30" width="width / 3" height="height / 4"/>
<!-- window's title -->
<title color="gtk:text[NORMAL]" x="20" y="30"/>
<!-- include another draw ops list; has optional x/y/width/height attrs -->
<include name="some_other_draw_ops"/>
<!-- tile another draw ops list; has optional
x/y/width/height/tile_xoffset/tile_yoffset -->
<tile name="some_other_draw_ops" tile_width="10" tile_height="10"/>
</draw_ops>
<frame_style name="normal" geometry="normal">
<!-- How to draw each piece of the frame.
For each piece, a draw_ops can be given inline or referenced
by name. If a piece is omitted, then nothing will be drawn
for that piece.
For each piece, the "width" and "height" variables in
coordinate expressions refers to the dimensions of the piece,
the origin is at the top left of the piece.
So <rectangle x="0" y="0" width="width-1" height="height-1"/>
will outline a piece.
-->
<piece position="entire_background" draw_ops="demo_all_ops"/>
<piece position="left_titlebar_edge">
<draw_ops>
<line color="#00FF00" x1="0" y1="0" x2="0" y2="height"/>
</draw_ops>
</piece>
<!-- The complete list of frame pieces:
entire_background: whole frame
titlebar: entire area above the app's window
titlebar_middle: area of titlebar_background not considered
part of an edge
left_titlebar_edge: left side of titlebar background
right_titlebar_edge: right side of titlebar background
top_titlebar_edge: top side of titlebar background
bottom_titlebar_edge: bottom side of titlebar background
title: the title area (doesn't include buttons)
left_edge: left edge of the frame
right_edge: right edge of the frame
bottom_edge: bottom edge of the frame
overlay: same area as entire_background, but drawn after
drawing all sub-pieces instead of before
-->
<!-- For buttons, drawing methods have to be provided for
each of three states:
normal, pressed, prelight
and the button function or position must be provided:
close, maximize, minimize, menu,
left_left_background, left_middle_background,
left_right_background, right_left_background,
right_middle_background, right_right_background
So a working theme needs 3*4 = 12 button declarations
and a theme may have up to 3*10 = 30 button declarations
in order to handle button-rearrangement preferences.
(The name "function" for the attribute is from before the
background values existed.)
-->
<button function="close" state="normal" draw_ops="previously_named"/>
<button function="menu" state="normal">
<draw_ops>
<icon alpha="0.7"
x="0" y="0" width="object_width" height="object_height"/>
</draw_ops>
</button>
</frame_style>
<!-- styles can inherit from each other with the parent="" attribute.
In a subclass anything can be re-specified to override
the parent style. -->
<frame_style name="focused" parent="normal">
<piece position="title">
<draw_ops>
<rectangle color="gtk:bg[SELECTED]"
x="0" y="0" width="width-1" height="height-1"/>
<title color="gtk:fg[SELECTED]" x="(width - title_width) / 2"
y="(height - title_height) / 2"/>
</draw_ops>
</piece>
</frame_style>
<!-- Maps styles to states of frame.
Focus: yes (focused), no (not focused)
Window states: normal, maximized, shaded, maximized_and_shaded
Window resizability: none, vertical, horizontal, both
Everything unspecified just does the same as
unfocused/normal/both.
only state="normal" needs a resize="" attribute.
-->
<frame_style_set name="normal">
<frame focus="yes" state="normal" resize="both" style="focused"/>
<frame focus="no" state="normal" resize="both" style="normal"/>
</frame_style_set>
<!-- Each window type needs a style set
Types: normal, dialog, modal_dialog, menu, utility, border
-->
<window type="normal" style_set="normal"/>
<!-- For menu icons, drawing methods are needed for the same
four types as the buttons, and GTK states
(insensitive,prelight,normal,etc.)
-->
<menu_icon function="close" state="normal" draw_ops="previously_named"/>
</metacity_theme>

View File

@ -29,7 +29,6 @@ eu
fa
fi
fr
fur
ga
gl
gu

View File

@ -22,7 +22,9 @@ src/core/screen.c
src/core/util.c
src/core/window.c
src/ui/frames.c
src/ui/resizepopup.c
src/ui/theme.c
src/ui/theme-parser.c
src/x11/session.c
src/x11/window-props.c
src/x11/xprops.c

View File

@ -1,2 +1 @@
# List of source files that should NOT be translated.
# Please keep this file sorted alphabetically.
data/mutter-wayland.desktop.in

2298
po/ar.po

File diff suppressed because it is too large Load Diff

1903
po/bg.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

3797
po/bs.po

File diff suppressed because it is too large Load Diff

2210
po/ca.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2390
po/cs.po

File diff suppressed because it is too large Load Diff

2407
po/da.po

File diff suppressed because it is too large Load Diff

2415
po/de.po

File diff suppressed because it is too large Load Diff

1339
po/el.po

File diff suppressed because it is too large Load Diff

2425
po/eo.po

File diff suppressed because it is too large Load Diff

1319
po/es.po

File diff suppressed because it is too large Load Diff

1353
po/eu.po

File diff suppressed because it is too large Load Diff

1388
po/fi.po

File diff suppressed because it is too large Load Diff

840
po/fr.po
View File

@ -1,5 +1,5 @@
# French translation of mutter.
# Copyright (C) 2002-2016 Free Software Foundation, Inc.
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
# This file is distributed under the same license as the metacity package.
#
# Christophe Fergeau <teuf@users.sourceforge.net>, 2002.
@ -11,16 +11,17 @@
# Cyprien Le Pannérer <cyplp@free.fr>, 2006.
# Robert-André Mauchin <zebob.m@gmail.com>, 2007.
# Stéphane Raimbault <stephane.raimbault@gmail.com>, 2007.
# Claude Paroz <claude@2xlibre.net>, 2008-2016.
# Claude Paroz <claude@2xlibre.net>, 2008-2014.
# Bruno Brouard <annoa.b@gmail.com>, 2011-12.
#
msgid ""
msgstr ""
"Project-Id-Version: mutter master\n"
"Project-Id-Version: mutter masterReport-Msgid-Bugs-To: http://bugzilla.gnome."
"org/enter_bug.cgi?product=mutter&component=general\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2016-03-05 13:41+0000\n"
"PO-Revision-Date: 2016-03-05 17:57+0100\n"
"POT-Creation-Date: 2014-08-29 21:52+0000\n"
"PO-Revision-Date: 2014-08-30 11:59+0200\n"
"Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
"Language: fr\n"
@ -407,8 +408,8 @@ msgid ""
"When true, the new windows will always be put in the center of the active "
"screen of the monitor."
msgstr ""
"Si true (vrai), les nouvelles fenêtres seront toujours placées au centre de "
"l'écran actif du moniteur."
"Si true (vrai), les nouvelles fenêtres seront toujours placées au centre "
"de l'écran actif du moniteur."
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
msgid "Select window from tab popup"
@ -448,49 +449,29 @@ msgstr "Passer à l'émulateur de terminal 6"
msgid "Switch to VT 7"
msgstr "Passer à l'émulateur de terminal 7"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
msgid "Switch to VT 8"
msgstr "Passer à l'émulateur de terminal 8"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
msgid "Switch to VT 9"
msgstr "Passer à l'émulateur de terminal 9"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
msgid "Switch to VT 10"
msgstr "Passer à l'émulateur de terminal 10"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
msgid "Switch to VT 11"
msgstr "Passer à l'émulateur de terminal 11"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
msgid "Switch to VT 12"
msgstr "Passer à l'émulateur de terminal 12"
#: ../src/backends/meta-monitor-manager.c:518
#: ../src/backends/meta-monitor-manager.c:412
msgid "Built-in display"
msgstr "Affichage intégré"
#: ../src/backends/meta-monitor-manager.c:544
#: ../src/backends/meta-monitor-manager.c:437
msgid "Unknown"
msgstr "Inconnu"
#: ../src/backends/meta-monitor-manager.c:546
#: ../src/backends/meta-monitor-manager.c:439
msgid "Unknown Display"
msgstr "Affichage inconnu"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c:554
#: ../src/backends/meta-monitor-manager.c:447
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. 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:443
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
@ -499,6 +480,10 @@ msgstr ""
"Un autre gestionnaire de composition est déjà lancé sur l'écran %i de "
"l'affichage « %s »."
#: ../src/compositor/meta-background.c:1044
msgid "background texture could not be created from file"
msgstr "la texture d'arrière-plan n'a pas pu être créée depuis le fichier"
#: ../src/core/bell.c:185
msgid "Bell event"
msgstr "Évènement sonore"
@ -528,47 +513,56 @@ msgstr "_Attendre"
msgid "_Force Quit"
msgstr "_Forcer à quitter"
#: ../src/core/display.c:555
#: ../src/core/display.c:547
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Impossible d'ouvrir l'affichage « %s » du système X Window\n"
#: ../src/core/main.c:181
#: ../src/core/main.c:176
msgid "Disable connection to session manager"
msgstr "Désactiver la connexion au gestionnaire de sessions"
#: ../src/core/main.c:187
#: ../src/core/main.c:182
msgid "Replace the running window manager"
msgstr "Remplacer le gestionnaire de fenêtres en cours de fonctionnement"
#: ../src/core/main.c:193
#: ../src/core/main.c:188
msgid "Specify session management ID"
msgstr "Indiquer l'ID de gestion de sessions"
#: ../src/core/main.c:198
#: ../src/core/main.c:193
msgid "X Display to use"
msgstr "Affichage X à utiliser"
#: ../src/core/main.c:204
#: ../src/core/main.c:199
msgid "Initialize session from savefile"
msgstr "Initialiser la session depuis le fichier de sauvegarde"
#: ../src/core/main.c:210
#: ../src/core/main.c:205
msgid "Make X calls synchronous"
msgstr "Rendre synchrones les appels à X"
#: ../src/core/main.c:217
#: ../src/core/main.c:212
msgid "Run as a wayland compositor"
msgstr "Lancer comme un compositeur wayland"
#: ../src/core/main.c:223
msgid "Run as a nested compositor"
msgstr "Lancer comme un compositeur imbriqué"
#: ../src/core/main.c:231
#: ../src/core/main.c:220
msgid "Run as a full display server, rather than nested"
msgstr "Lancer comme un serveur d'affichage complet, plutôt qu'imbriqué"
#: ../src/core/main.c:459
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Le parcours du répertoire de thèmes a échoué : %s\n"
#: ../src/core/main.c:475
#, c-format
msgid ""
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
msgstr ""
"Impossible de trouver un thème ! Assurez-vous que %s existe et contient les "
"thèmes habituels.\n"
#: ../src/core/mutter.c:39
#, c-format
msgid ""
@ -593,29 +587,759 @@ msgstr "Afficher la version"
msgid "Mutter plugin to use"
msgstr "Greffon de Mutter à utiliser"
#: ../src/core/prefs.c:1997
#: ../src/core/prefs.c:2101
#, c-format
msgid "Workspace %d"
msgstr "Espace de travail %d"
#: ../src/core/screen.c:521
#, c-format
msgid ""
"Display \"%s\" already has a window manager; try using the --replace option "
"to replace the current window manager."
msgstr ""
"L'affichage « %s » a déjà un gestionnaire de fenêtres ; essayez d'utiliser "
"l'option --replace pour remplacer le gestionnaire de fenêtres actuel."
#: ../src/core/screen.c:603
#: ../src/core/screen.c:548
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "L'écran %d sur l'affichage « %s » n'est pas valide\n"
#: ../src/core/util.c:121
#: ../src/core/screen.c:564
#, c-format
msgid ""
"Screen %d on display \"%s\" already has a window manager; try using the --"
"replace option to replace the current window manager.\n"
msgstr ""
"L'écran %d sur l'affichage « %s » a déjà un gestionnaire de fenêtres ; "
"essayez d'utiliser l'option --replace pour remplacer le gestionnaire de "
"fenêtres actuel.\n"
#: ../src/core/screen.c:657
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "L'écran %d sur l'affichage « %s » a déjà un gestionnaire de fenêtres\n"
#: ../src/core/util.c:118
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter a été compilé sans la prise en charge du mode bavard\n"
#. Translators: This represents the size of a window. The first number is
#. * the width of the window and the second is the height.
#.
#: ../src/ui/resizepopup.c:134
#, c-format
msgid "%d x %d"
msgstr "%d x %d"
#: ../src/ui/theme.c:233
msgid "top"
msgstr "haut"
#: ../src/ui/theme.c:235
msgid "bottom"
msgstr "bas"
#: ../src/ui/theme.c:237
msgid "left"
msgstr "gauche"
#: ../src/ui/theme.c:239
msgid "right"
msgstr "droite"
#: ../src/ui/theme.c:267
#, c-format
msgid "frame geometry does not specify \"%s\" dimension"
msgstr "la géométrie du cadre n'indique pas la dimension « %s »"
#: ../src/ui/theme.c:286
#, c-format
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
msgstr ""
"la géométrie du cadre n'indique pas la dimension « %s » pour la bordure "
"« %s »"
#: ../src/ui/theme.c:323
#, c-format
msgid "Button aspect ratio %g is not reasonable"
msgstr "La proportion du bouton %g n'est pas raisonnable"
#: ../src/ui/theme.c:335
#, c-format
msgid "Frame geometry does not specify size of buttons"
msgstr "La géométrie du cadre n'indique pas la taille des boutons"
#: ../src/ui/theme.c:1061
#, c-format
msgid "Gradients should have at least two colors"
msgstr "Les dégradés doivent comporter au moins deux couleurs"
#: ../src/ui/theme.c:1211
#, c-format
msgid ""
"GTK custom color specification must have color name and fallback in "
"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
msgstr ""
"Une spécification de couleur personnalisée GTK doit comporter un nom de "
"couleur et un substitut entre parenthèses, par ex. gtk:custom(foo,bar) ; "
"impossible d'analyser « %s »"
#: ../src/ui/theme.c:1227
#, c-format
msgid ""
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
"_ are valid"
msgstr ""
"Caractère « %c » non valide dans le paramètre color_name de gtk:custom, "
"seuls A-Za-z0-9-_ sont acceptés"
#: ../src/ui/theme.c:1241
#, c-format
msgid ""
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
"fit the format"
msgstr ""
"Le format de gtk:custom est « gtk:custom(nom_couleur,substitut) », « %s » ne "
"correspond pas à ce format"
#: ../src/ui/theme.c:1286
#, c-format
msgid ""
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
"where NORMAL is the state; could not parse \"%s\""
msgstr ""
"La spécification de couleur GTK doit présenter l'état entre crochets, p. ex. "
"gtk:fg[NORMAL] où NORMAL est l'état ; impossible d'analyser « %s »"
#: ../src/ui/theme.c:1300
#, c-format
msgid ""
"GTK color specification must have a close bracket after the state, e.g. gtk:"
"fg[NORMAL] where NORMAL is the state; could not parse \"%s\""
msgstr ""
"La spécification de couleur GTK doit comporter un crochet de fermeture après "
"l'état, p. ex. gtk:fg[NORMAL] où NORMAL est l'état ; impossible d'analyser "
"« %s »"
#: ../src/ui/theme.c:1311
#, c-format
msgid "Did not understand state \"%s\" in color specification"
msgstr ""
"Impossible de comprendre l'état « %s » dans la spécification de couleur"
#: ../src/ui/theme.c:1324
#, c-format
msgid "Did not understand color component \"%s\" in color specification"
msgstr ""
"Impossible de comprendre le composant de couleur « %s » dans la "
"spécification de couleur"
#: ../src/ui/theme.c:1352
#, c-format
msgid ""
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
"format"
msgstr ""
"Le format de mélange est « blend/bg_color/fg_color/alpha », « %s » ne "
"correspond pas à ce format ."
#: ../src/ui/theme.c:1363
#, c-format
msgid "Could not parse alpha value \"%s\" in blended color"
msgstr "Impossible d'analyser la valeur alpha « %s » en couleur mélangée"
#: ../src/ui/theme.c:1373
#, c-format
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
msgstr ""
"La valeur alpha « %s » en couleur mélangée n'est pas comprise entre 0,0 et "
"1,0"
#: ../src/ui/theme.c:1419
#, c-format
msgid ""
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
msgstr ""
"Le format d'ombre est « shade/base_color/factor », « %s » ne correspond pas "
"au format"
#: ../src/ui/theme.c:1430
#, c-format
msgid "Could not parse shade factor \"%s\" in shaded color"
msgstr "Impossible d'analyser le facteur d'ombre « %s » en couleur ombrée"
#: ../src/ui/theme.c:1440
#, c-format
msgid "Shade factor \"%s\" in shaded color is negative"
msgstr "Le facteur d'ombre « %s » en couleur ombrée est négatif"
#: ../src/ui/theme.c:1469
#, c-format
msgid "Could not parse color \"%s\""
msgstr "Impossible d'analyser la couleur « %s »"
#: ../src/ui/theme.c:1778
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr ""
"L'expression de la coordonnée contient le caractère « %s » qui n'est pas "
"autorisé"
#: ../src/ui/theme.c:1805
#, c-format
msgid ""
"Coordinate expression contains floating point number '%s' which could not be "
"parsed"
msgstr ""
"L'expression de la coordonnée contient la valeur en virgule flottante « %s » "
"qui ne peut pas être analysée"
#: ../src/ui/theme.c:1819
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr ""
"L'expression de la coordonnée contient l'entier « %s » qui n'a pas pu être "
"analysé"
#: ../src/ui/theme.c:1940
#, c-format
msgid ""
"Coordinate expression contained unknown operator at the start of this text: "
"\"%s\""
msgstr ""
"L'expression de la coordonnée contenait un opérateur inconnu au début de ce "
"texte : « %s »"
#: ../src/ui/theme.c:1997
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr "L'expression de la coordonnée était vide ou incomprise"
#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154
#, c-format
msgid "Coordinate expression results in division by zero"
msgstr "L'expression de la coordonnée entraîne une division par zéro"
#: ../src/ui/theme.c:2162
#, c-format
msgid ""
"Coordinate expression tries to use mod operator on a floating-point number"
msgstr ""
"L'expression de la coordonnée tente d'utiliser l'opérateur mod sur une "
"valeur en virgule flottante"
#: ../src/ui/theme.c:2218
#, c-format
msgid ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
msgstr ""
"L'expression de la coordonnée a un opérateur « %s » là où un opérande était "
"attendu"
#: ../src/ui/theme.c:2227
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr ""
"L'expression de la coordonnée a un opérande là où un opérateur était attendu"
#: ../src/ui/theme.c:2235
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr ""
"L'expression de la coordonnée était terminée par un opérateur au lieu d'un "
"opérande"
#: ../src/ui/theme.c:2245
#, c-format
msgid ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
"operand in between"
msgstr ""
"L'expression de la coordonnée a un opérateur « %c » suivant l'opérateur "
"« %c » sans opérande entre eux"
#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr ""
"L'expression de la coordonnée possède une variable ou constante inconnue "
"« %s »"
#: ../src/ui/theme.c:2495
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr ""
"L'analyseur d'expression de coordonnées a dépassé la capacité de son tampon."
#: ../src/ui/theme.c:2524
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr ""
"L'expression de la coordonnée comporte une parenthèse de fermeture, mais pas "
"de parenthèse d'ouverture"
#: ../src/ui/theme.c:2588
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr ""
"L'expression de la coordonnée comporte une parenthèse d'ouverture, mais pas "
"de parenthèse de fermeture"
#: ../src/ui/theme.c:2599
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr ""
"L'expression de la coordonnée ne semble pas comprendre d'opérateur ni "
"d'opérande"
#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852
#, c-format
msgid "Theme contained an expression that resulted in an error: %s\n"
msgstr "Le thème contient une expression qui a entraîné une erreur : %s\n"
#: ../src/ui/theme.c:4455
#, c-format
msgid ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
"specified for this frame style"
msgstr ""
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> doit être "
"indiqué pour ce style de cadre"
#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995
#, c-format
msgid ""
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr ""
"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> manquant"
#: ../src/ui/theme.c:5041
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "Impossible de charger le thème « %s » : %s\n"
#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191
#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205
#, c-format
msgid "No <%s> set for theme \"%s\""
msgstr "Aucun <%s> défini pour le thème « %s »"
#: ../src/ui/theme.c:5213
#, c-format
msgid ""
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
"type=\"%s\" style_set=\"whatever\"/> element"
msgstr ""
"Aucun style de cadre défini pour le type de fenêtre « %s » dans le thème "
"« %s », ajoutez un élément <window type=\"%s\" style_set=\"whatever\"/>"
#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745
#, c-format
msgid ""
"User-defined constants must begin with a capital letter; \"%s\" does not"
msgstr ""
"Les constantes définies par l'utilisateur doivent commencer par une "
"majuscule ; « %s » commence par une minuscule"
#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753
#, c-format
msgid "Constant \"%s\" has already been defined"
msgstr "La constante « %s » a déjà été définie"
#. Translators: This means that an attribute which should have been found
#. * on an XML element was not in fact found.
#.
#: ../src/ui/theme-parser.c:234
#, c-format
msgid "No \"%s\" attribute on element <%s>"
msgstr "Aucun attribut « %s » sur l'élément <%s>"
#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281
#, c-format
msgid "Line %d character %d: %s"
msgstr "Ligne %d caractère %d: %s"
#: ../src/ui/theme-parser.c:481
#, c-format
msgid "Attribute \"%s\" repeated twice on the same <%s> element"
msgstr "Attribut « %s » répété deux fois sur le même élément <%s>"
#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554
#, c-format
msgid "Attribute \"%s\" is invalid on <%s> element in this context"
msgstr "Attribut « %s » non valide sur l'élément <%s> dans ce contexte"
#: ../src/ui/theme-parser.c:596
#, c-format
msgid "Could not parse \"%s\" as an integer"
msgstr "Impossible d'analyser « %s » en tant qu'entier"
#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660
#, c-format
msgid "Did not understand trailing characters \"%s\" in string \"%s\""
msgstr "Caractères de fin « %s » non compris dans la chaîne « %s »"
#: ../src/ui/theme-parser.c:615
#, c-format
msgid "Integer %ld must be positive"
msgstr "L'entier %ld doit être positif"
#: ../src/ui/theme-parser.c:623
#, c-format
msgid "Integer %ld is too large, current max is %d"
msgstr "L'entier %ld est trop élevé, le max. actuel est %d"
#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767
#, c-format
msgid "Could not parse \"%s\" as a floating point number"
msgstr "Impossible d'analyser « %s » en tant que valeur en virgule flottante"
#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710
#, c-format
msgid "Boolean values must be \"true\" or \"false\" not \"%s\""
msgstr ""
"Les valeurs booléennes doivent être « true » ou « false » et non « %s »"
#: ../src/ui/theme-parser.c:737
#, c-format
msgid "Angle must be between 0.0 and 360.0, was %g\n"
msgstr "L'angle doit être compris entre 0,0 et 360,0. Il était de %g\n"
#: ../src/ui/theme-parser.c:800
#, c-format
msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n"
msgstr ""
"La valeur alpha doit être comprise entre 0,0 (invisible) et 1,0 (entièrement "
"opaque). Elle était de %g\n"
#: ../src/ui/theme-parser.c:865
#, c-format
msgid ""
"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,"
"large,x-large,xx-large)\n"
msgstr ""
"Échelle de titre non valide « %s » (elle doit avoir l'une des valeurs "
"suivantes : xx-small, x-small, small, medium,large, x-large, xx-large)\n"
#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084
#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221
#, c-format
msgid "<%s> name \"%s\" used a second time"
msgstr "<%s> - nom « %s » utilisé une deuxième fois"
#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130
#: ../src/ui/theme-parser.c:1233
#, c-format
msgid "<%s> parent \"%s\" has not been defined"
msgstr "<%s> - parent « %s » non défini"
#: ../src/ui/theme-parser.c:1143
#, c-format
msgid "<%s> geometry \"%s\" has not been defined"
msgstr "<%s> - géométrie « %s » non définie"
#: ../src/ui/theme-parser.c:1156
#, c-format
msgid "<%s> must specify either a geometry or a parent that has a geometry"
msgstr "<%s> doit indiquer une géométrie ou un parent qui en possède une"
#: ../src/ui/theme-parser.c:1198
msgid "You must specify a background for an alpha value to be meaningful"
msgstr ""
"Vous devez indiquer un arrière-plan pour qu'une valeur alpha ait du sens."
#: ../src/ui/theme-parser.c:1266
#, c-format
msgid "Unknown type \"%s\" on <%s> element"
msgstr "Type inconnu « %s » sur l'élément <%s>"
#: ../src/ui/theme-parser.c:1277
#, c-format
msgid "Unknown style_set \"%s\" on <%s> element"
msgstr "style_set inconnu « %s » sur l'élément <%s>"
#: ../src/ui/theme-parser.c:1285
#, c-format
msgid "Window type \"%s\" has already been assigned a style set"
msgstr "Le type de fenêtre « %s » s'est déjà vu attribuer un jeu de styles"
#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379
#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840
#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036
#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310
#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386
#, c-format
msgid "Element <%s> is not allowed below <%s>"
msgstr "L'élément <%s> n'est pas autorisé sous <%s>"
#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443
#: ../src/ui/theme-parser.c:1488
msgid ""
"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" "
"for buttons"
msgstr ""
"Impossible d'indiquer à la fois « button_width » / "
 button_height » (largeur/hauteur) et « aspect_ratio » (proportion) pour "
"les boutons"
#: ../src/ui/theme-parser.c:1452
#, c-format
msgid "Distance \"%s\" is unknown"
msgstr "Distance « %s » inconnue"
#: ../src/ui/theme-parser.c:1497
#, c-format
msgid "Aspect ratio \"%s\" is unknown"
msgstr "Proportion « %s » inconnue"
#: ../src/ui/theme-parser.c:1559
#, c-format
msgid "Border \"%s\" is unknown"
msgstr "Bordure « %s » inconnue"
#: ../src/ui/theme-parser.c:1870
#, c-format
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
msgstr ""
"Aucun attribut « start_angle » (« début d'angle ») ou « from » (« depuis ») "
"sur l'élément <%s>"
#: ../src/ui/theme-parser.c:1877
#, c-format
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
msgstr ""
"Aucun attribut « extent_angle » (« extension d'angle ») ou « to » (« vers ») "
"sur l'élément <%s>"
#: ../src/ui/theme-parser.c:2117
#, c-format
msgid "Did not understand value \"%s\" for type of gradient"
msgstr "Impossible de comprendre la valeur « %s » pour le type de dégradé"
#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570
#, c-format
msgid "Did not understand fill type \"%s\" for <%s> element"
msgstr ""
"Impossible de comprendre le type de remplissage « %s » pour l'élément <%s>"
#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445
#: ../src/ui/theme-parser.c:2508
#, c-format
msgid "Did not understand state \"%s\" for <%s> element"
msgstr "Impossible de comprendre l'état « %s » pour l'élément <%s>"
#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455
#, c-format
msgid "Did not understand shadow \"%s\" for <%s> element"
msgstr "Impossible de comprendre l'ombre « %s » pour l'élément <%s>"
#: ../src/ui/theme-parser.c:2382
#, c-format
msgid "Did not understand arrow \"%s\" for <%s> element"
msgstr "Impossible de comprendre la flèche « %s » pour l'élément <%s>"
#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792
#, c-format
msgid "No <draw_ops> called \"%s\" has been defined"
msgstr "Aucun <draw_ops> appelé « %s » n'a été défini"
#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804
#, c-format
msgid "Including draw_ops \"%s\" here would create a circular reference"
msgstr "L'inclusion du draw_ops « %s » ici créerait une référence circulaire"
#: ../src/ui/theme-parser.c:2919
#, c-format
msgid "Unknown position \"%s\" for frame piece"
msgstr "Position inconnue « %s » de la pièce du cadre"
#: ../src/ui/theme-parser.c:2927
#, c-format
msgid "Frame style already has a piece at position %s"
msgstr "Le style de cadre a déjà une pièce à la position %s"
#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021
#, c-format
msgid "No <draw_ops> with the name \"%s\" has been defined"
msgstr "Aucun <draw_ops> avec le nom « %s » n'a été défini"
#: ../src/ui/theme-parser.c:2974
#, c-format
msgid "Unknown function \"%s\" for button"
msgstr "Fonction inconnue « %s » pour le bouton"
#: ../src/ui/theme-parser.c:2984
#, c-format
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
msgstr ""
"La fonction « %s » du bouton n'existe pas dans la version (%d, a besoin de "
"%d)"
#: ../src/ui/theme-parser.c:2996
#, c-format
msgid "Unknown state \"%s\" for button"
msgstr "État inconnu « %s » pour le bouton"
#: ../src/ui/theme-parser.c:3004
#, c-format
msgid "Frame style already has a button for function %s state %s"
msgstr "Le style de cadre a déjà un bouton pour la fonction %s, état %s"
#: ../src/ui/theme-parser.c:3075
#, c-format
msgid "\"%s\" is not a valid value for focus attribute"
msgstr "« %s » n'est pas une valeur valide pour l'attribut de focus"
#: ../src/ui/theme-parser.c:3084
#, c-format
msgid "\"%s\" is not a valid value for state attribute"
msgstr "« %s » n'est pas une valeur valide pour l'attribut d'état"
#: ../src/ui/theme-parser.c:3094
#, c-format
msgid "A style called \"%s\" has not been defined"
msgstr "Aucun style appelé « %s » n'a été défini"
#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138
#, c-format
msgid "\"%s\" is not a valid value for resize attribute"
msgstr ""
"« %s » n'est pas une valeur valide pour l'attribut de redimensionnement"
#: ../src/ui/theme-parser.c:3149
#, c-format
msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
"states"
msgstr ""
"L'attribut « resize » (« redimensionnement ») ne devrait pas figurer sur "
"l'élément <%s> pour les états maximisé/réduit dans la barre de titre"
#: ../src/ui/theme-parser.c:3163
#, c-format
msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized states"
msgstr ""
"L'attribut « resize » (« redimensionnement ») ne devrait pas figurer sur "
"l'élément <%s> pour l'état maximisé"
#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221
#, c-format
msgid "Style has already been specified for state %s resize %s focus %s"
msgstr ""
"Le style a déjà été indiqué pour l'état %s, redimensionnement %s, focus %s"
#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199
#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232
#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254
#, c-format
msgid "Style has already been specified for state %s focus %s"
msgstr "Le style a déjà été indiqué pour l'état %s, focus %s"
#: ../src/ui/theme-parser.c:3293
msgid ""
"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops "
"attribute and also a <draw_ops> element, or specified two elements)"
msgstr ""
"Impossible d'avoir deux attributs draw_ops pour un élément <piece> (le thème "
"indiquait un attribut draw_ops et un élément <draw_ops> ou deux éléments)"
#: ../src/ui/theme-parser.c:3331
msgid ""
"Can't have a two draw_ops for a <button> element (theme specified a draw_ops "
"attribute and also a <draw_ops> element, or specified two elements)"
msgstr ""
"Impossible d'avoir deux attributs draw_ops pour un élément <button> (le "
"thème indiquait un attribut draw_ops et un élément <draw_ops> ou deux "
"éléments)"
#: ../src/ui/theme-parser.c:3369
msgid ""
"Can't have a two draw_ops for a <menu_icon> element (theme specified a "
"draw_ops attribute and also a <draw_ops> element, or specified two elements)"
msgstr ""
"Impossible d'avoir deux attributs draw_ops pour un élément <menu_icon> (le "
"thème indiquait un attribut draw_ops et un élément <draw_ops> ou deux "
"éléments)"
#: ../src/ui/theme-parser.c:3433
#, c-format
msgid "Bad version specification '%s'"
msgstr "Mauvaise spécification de version « %s »"
#: ../src/ui/theme-parser.c:3506
msgid ""
"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
"theme-2.xml"
msgstr ""
"L'attribut « version » ne peut pas être utilisé dans metacity-theme-1.xml or "
"metacity-theme-2.xml"
#: ../src/ui/theme-parser.c:3529
#, c-format
msgid "Theme requires version %s but latest supported theme version is %d.%d"
msgstr ""
"Le thème nécessite la version %s mais la version de thème la plus récente "
"prise en charge est %d.%d"
#: ../src/ui/theme-parser.c:3561
#, c-format
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
msgstr ""
"L'élément le plus extérieur dans le thème doit être <metacity_theme> et non <"
"%s>"
#: ../src/ui/theme-parser.c:3581
#, c-format
msgid ""
"Element <%s> is not allowed inside a name/author/date/description element"
msgstr ""
"L'élément <%s> n'est pas autorisé dans un élément name/author/date/"
"description"
#: ../src/ui/theme-parser.c:3586
#, c-format
msgid "Element <%s> is not allowed inside a <constant> element"
msgstr "L'élément <%s> n'est pas autorisé dans un élément <constant>"
#: ../src/ui/theme-parser.c:3598
#, c-format
msgid ""
"Element <%s> is not allowed inside a distance/border/aspect_ratio element"
msgstr ""
"L'élément <%s> n'est pas autorisé dans un élément distance/border/"
"aspect_ratio"
#: ../src/ui/theme-parser.c:3620
#, c-format
msgid "Element <%s> is not allowed inside a draw operation element"
msgstr ""
"L'élément <%s> n'est pas autorisé dans un élément d'opération de dessin"
#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660
#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670
#, c-format
msgid "Element <%s> is not allowed inside a <%s> element"
msgstr "L'élément <%s> n'est pas autorisé dans un élément <%s>"
#: ../src/ui/theme-parser.c:3898
msgid "No draw_ops provided for frame piece"
msgstr "Aucun attribut draw_ops fourni pour la pièce du cadre"
#: ../src/ui/theme-parser.c:3913
msgid "No draw_ops provided for button"
msgstr "Aucun attribut draw_ops fourni pour le bouton"
#: ../src/ui/theme-parser.c:3967
#, c-format
msgid "No text is allowed inside element <%s>"
msgstr "Aucun texte autorisé dans l'élément <%s>"
#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037
#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061
#: ../src/ui/theme-parser.c:4073
#, c-format
msgid "<%s> specified twice for this theme"
msgstr "<%s> indiqué deux fois pour ce thème"
#: ../src/ui/theme-parser.c:4335
#, c-format
msgid "Failed to find a valid file for theme %s\n"
msgstr "Impossible de trouver un fichier valide pour le thème %s\n"
#: ../src/x11/session.c:1815
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
@ -625,7 +1349,7 @@ msgstr ""
"configuration actuelle » et devront être redémarrées manuellement à la "
"prochaine connexion."
#: ../src/x11/window-props.c:549
#: ../src/x11/window-props.c:515
#, c-format
msgid "%s (on %s)"
msgstr "%s (sur %s)"

583
po/fur.po
View File

@ -1,583 +0,0 @@
# Friulian translation for mutter.
# Copyright (C) 2016 mutter's COPYRIGHT HOLDER
# This file is distributed under the same license as the mutter package.
# Fabio Tomat <f.t.public@gmail.com>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: mutter master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
"product=mutter&keywords=I18N+L10N&component=general\n"
"POT-Creation-Date: 2016-03-25 01:58+0000\n"
"PO-Revision-Date: 2016-03-25 17:54+0100\n"
"Language-Team: Friulian <fur@li.org>\n"
"Language: fur\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
"X-Generator: Poedit 1.8.5\n"
#: ../data/50-mutter-navigation.xml.in.h:1
msgid "Navigation"
msgstr "Navigazion"
#: ../data/50-mutter-navigation.xml.in.h:2
msgid "Move window to workspace 1"
msgstr "Sposte barcon tal spazi di lavôr 1"
#: ../data/50-mutter-navigation.xml.in.h:3
msgid "Move window to workspace 2"
msgstr "Sposte barcon tal spazi di lavôr 2"
#: ../data/50-mutter-navigation.xml.in.h:4
msgid "Move window to workspace 3"
msgstr "Sposte barcon tal spazi di lavôr 3"
#: ../data/50-mutter-navigation.xml.in.h:5
msgid "Move window to workspace 4"
msgstr "Sposte barcon tal spazi di lavôr 4"
#: ../data/50-mutter-navigation.xml.in.h:6
msgid "Move window to last workspace"
msgstr "Sposte barcon tal ultin spazi di lavôr"
#: ../data/50-mutter-navigation.xml.in.h:7
msgid "Move window one workspace to the left"
msgstr "Sposte barcon tal spazi di lavôr a çampe"
#: ../data/50-mutter-navigation.xml.in.h:8
msgid "Move window one workspace to the right"
msgstr "Sposte barcon tal spazi di lavôr a drete"
#: ../data/50-mutter-navigation.xml.in.h:9
msgid "Move window one workspace up"
msgstr "Sposte barcon tal spazi di lavôr parsore"
#: ../data/50-mutter-navigation.xml.in.h:10
msgid "Move window one workspace down"
msgstr "Sposte barcon tal spazi di lavôr sot"
#: ../data/50-mutter-navigation.xml.in.h:11
msgid "Move window one monitor to the left"
msgstr "Sposte barcon tal visôr a çampe"
#: ../data/50-mutter-navigation.xml.in.h:12
msgid "Move window one monitor to the right"
msgstr "Sposte barcon tal visôr a drete"
#: ../data/50-mutter-navigation.xml.in.h:13
msgid "Move window one monitor up"
msgstr "Sposte barcon tal visôr parsore"
#: ../data/50-mutter-navigation.xml.in.h:14
msgid "Move window one monitor down"
msgstr "Sposte barcon tal visôr sot"
#: ../data/50-mutter-navigation.xml.in.h:15
msgid "Switch applications"
msgstr "Passâ di une aplicazion in chê altre"
#: ../data/50-mutter-navigation.xml.in.h:16
msgid "Switch to previous application"
msgstr "Passe ae aplicazion prime"
#: ../data/50-mutter-navigation.xml.in.h:17
msgid "Switch windows"
msgstr "Passâ di un barcon in chel altri"
#: ../data/50-mutter-navigation.xml.in.h:18
msgid "Switch to previous window"
msgstr "Passe al barcon prime"
#: ../data/50-mutter-navigation.xml.in.h:19
msgid "Switch windows of an application"
msgstr "Passâ di un barcon in chel altri di une aplicazion"
#: ../data/50-mutter-navigation.xml.in.h:20
msgid "Switch to previous window of an application"
msgstr "Passe al barcon prime di une aplicazion"
#: ../data/50-mutter-navigation.xml.in.h:21
msgid "Switch system controls"
msgstr "Passâ di un control di sisteme in chel altri"
#: ../data/50-mutter-navigation.xml.in.h:22
msgid "Switch to previous system control"
msgstr "Passe al control di sisteme precedent"
#: ../data/50-mutter-navigation.xml.in.h:23
msgid "Switch windows directly"
msgstr ""
#: ../data/50-mutter-navigation.xml.in.h:24
msgid "Switch directly to previous window"
msgstr ""
#: ../data/50-mutter-navigation.xml.in.h:25
msgid "Switch windows of an app directly"
msgstr ""
#: ../data/50-mutter-navigation.xml.in.h:26
msgid "Switch directly to previous window of an app"
msgstr ""
#: ../data/50-mutter-navigation.xml.in.h:27
msgid "Switch system controls directly"
msgstr ""
#: ../data/50-mutter-navigation.xml.in.h:28
msgid "Switch directly to previous system control"
msgstr ""
#: ../data/50-mutter-navigation.xml.in.h:29
msgid "Hide all normal windows"
msgstr "Plate ducj i barcons normâi"
#: ../data/50-mutter-navigation.xml.in.h:30
msgid "Switch to workspace 1"
msgstr "Passe al spazi di lavôr 1"
#: ../data/50-mutter-navigation.xml.in.h:31
msgid "Switch to workspace 2"
msgstr "Passe al spazi di lavôr 2"
#: ../data/50-mutter-navigation.xml.in.h:32
msgid "Switch to workspace 3"
msgstr "Passe al spazi di lavôr 3"
#: ../data/50-mutter-navigation.xml.in.h:33
msgid "Switch to workspace 4"
msgstr "Passe al spazi di lavôr 4"
#: ../data/50-mutter-navigation.xml.in.h:34
msgid "Switch to last workspace"
msgstr "Passe al ultin spazi di lavôr"
#: ../data/50-mutter-navigation.xml.in.h:35
msgid "Move to workspace left"
msgstr "Sposte il spazi di lavôr a çampe"
#: ../data/50-mutter-navigation.xml.in.h:36
msgid "Move to workspace right"
msgstr "Sposte il spazi di lavôr a drete"
#: ../data/50-mutter-navigation.xml.in.h:37
msgid "Move to workspace above"
msgstr "Sposte il spazi di lavôr parsore"
#: ../data/50-mutter-navigation.xml.in.h:38
msgid "Move to workspace below"
msgstr "Sposte il spazi di lavôr sot"
#: ../data/50-mutter-system.xml.in.h:1
msgid "System"
msgstr "Sisteme"
#: ../data/50-mutter-system.xml.in.h:2
msgid "Show the run command prompt"
msgstr ""
#: ../data/50-mutter-system.xml.in.h:3
msgid "Show the activities overview"
msgstr "Mostre la panoramiche ativitâts"
#: ../data/50-mutter-windows.xml.in.h:1
msgid "Windows"
msgstr "Barcons"
#: ../data/50-mutter-windows.xml.in.h:2
msgid "Activate the window menu"
msgstr "Ative il menù dal barcon"
#: ../data/50-mutter-windows.xml.in.h:3
msgid "Toggle fullscreen mode"
msgstr "Ative/Disative modalitât plen visôr"
#: ../data/50-mutter-windows.xml.in.h:4
msgid "Toggle maximization state"
msgstr "Ative/Disative il stât slargjât"
#: ../data/50-mutter-windows.xml.in.h:5
msgid "Maximize window"
msgstr "Slargje il barcon"
#: ../data/50-mutter-windows.xml.in.h:6
msgid "Restore window"
msgstr "Ripristine barcon"
#: ../data/50-mutter-windows.xml.in.h:7
msgid "Toggle shaded state"
msgstr "Ative/Disative stât inrodolât"
#: ../data/50-mutter-windows.xml.in.h:8
msgid "Close window"
msgstr "Siere il barcon"
#: ../data/50-mutter-windows.xml.in.h:9
msgid "Hide window"
msgstr "Plate il barcon"
#: ../data/50-mutter-windows.xml.in.h:10
msgid "Move window"
msgstr "Sposte il barcon"
#: ../data/50-mutter-windows.xml.in.h:11
msgid "Resize window"
msgstr "Ridimensione barcon"
#: ../data/50-mutter-windows.xml.in.h:12
msgid "Toggle window on all workspaces or one"
msgstr "Ative/Disative barcon su ducj i spazis di lavôr o nome un"
#: ../data/50-mutter-windows.xml.in.h:13
msgid "Raise window if covered, otherwise lower it"
msgstr "Tire sù il barcon se al è cuviert, se no sbassilu"
#: ../data/50-mutter-windows.xml.in.h:14
msgid "Raise window above other windows"
msgstr "Met il barcon parsore di chei altris"
#: ../data/50-mutter-windows.xml.in.h:15
msgid "Lower window below other windows"
msgstr "Bute il barcon sot di chei altris"
#: ../data/50-mutter-windows.xml.in.h:16
msgid "Maximize window vertically"
msgstr "Slargje il barcon par verticâl"
#: ../data/50-mutter-windows.xml.in.h:17
msgid "Maximize window horizontally"
msgstr "Slargje il barcon par orizontâl"
#: ../data/50-mutter-windows.xml.in.h:18
msgid "View split on left"
msgstr ""
#: ../data/50-mutter-windows.xml.in.h:19
msgid "View split on right"
msgstr ""
#: ../data/mutter.desktop.in.h:1
msgid "Mutter"
msgstr "Mutter"
#: ../data/org.gnome.mutter.gschema.xml.in.h:1
msgid "Modifier to use for extended window management operations"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:2
msgid ""
"This key will initiate the \"overlay\", which is a combination window "
"overview and application launching system. The default is intended to be the "
"\"Windows key\" on PC hardware. It's expected that this binding either the "
"default or set to the empty string."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:3
msgid "Attach modal dialogs"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:4
msgid ""
"When true, instead of having independent titlebars, modal dialogs appear "
"attached to the titlebar of the parent window and are moved together with "
"the parent window."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:5
msgid "Enable edge tiling when dropping windows on screen edges"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:6
msgid ""
"If enabled, dropping windows on vertical screen edges maximizes them "
"vertically and resizes them horizontally to cover half of the available "
"area. Dropping windows on the top screen edge maximizes them completely."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:7
msgid "Workspaces are managed dynamically"
msgstr "I spazis di vore a son ministrât in maniere dinamiche"
#: ../data/org.gnome.mutter.gschema.xml.in.h:8
msgid ""
"Determines whether workspaces are managed dynamically or whether there's a "
"static number of workspaces (determined by the num-workspaces key in org."
"gnome.desktop.wm.preferences)."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
msgid "Workspaces only on primary"
msgstr "Spazis di vore nome tal visôr primari"
#: ../data/org.gnome.mutter.gschema.xml.in.h:10
msgid ""
"Determines whether workspace switching should happen for windows on all "
"monitors or only for windows on the primary monitor."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:11
msgid "No tab popup"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:12
msgid ""
"Determines whether the use of popup and highlight frame should be disabled "
"for window cycling."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:13
msgid "Delay focus changes until the pointer stops moving"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:14
msgid ""
"If set to true, and the focus mode is either \"sloppy\" or \"mouse\" then "
"the focus will not be changed immediately when entering a window, but only "
"after the pointer stops moving."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
msgid "Draggable border width"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:16
msgid ""
"The amount of total draggable borders. If the theme's visible borders are "
"not enough, invisible borders will be added to meet this value."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:17
msgid "Auto maximize nearly monitor sized windows"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:18
msgid ""
"If enabled, new windows that are initially the size of the monitor "
"automatically get maximized."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:19
msgid "Place new windows in the center"
msgstr "Place i gnûfs barcons tal mieç"
#: ../data/org.gnome.mutter.gschema.xml.in.h:20
msgid ""
"When true, the new windows will always be put in the center of the active "
"screen of the monitor."
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
msgid "Select window from tab popup"
msgstr ""
#: ../data/org.gnome.mutter.gschema.xml.in.h:22
msgid "Cancel tab popup"
msgstr ""
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:1
msgid "Switch to VT 1"
msgstr "Passe al VT 1"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:2
msgid "Switch to VT 2"
msgstr "Passe al VT 2"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:3
msgid "Switch to VT 3"
msgstr "Passe al VT 3"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:4
msgid "Switch to VT 4"
msgstr "Passe al VT 4"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:5
msgid "Switch to VT 5"
msgstr "Passe al VT 5"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:6
msgid "Switch to VT 6"
msgstr "Passe al VT 6"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:7
msgid "Switch to VT 7"
msgstr "Passe al VT 7"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
msgid "Switch to VT 8"
msgstr "Passe al VT 8"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
msgid "Switch to VT 9"
msgstr "Passe al VT 9"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
msgid "Switch to VT 10"
msgstr "Passe al VT 10"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
msgid "Switch to VT 11"
msgstr "Passe al VT 11"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
msgid "Switch to VT 12"
msgstr "Passe al VT 12"
#: ../src/backends/meta-monitor-manager.c:518
msgid "Built-in display"
msgstr "Display integrât"
#: ../src/backends/meta-monitor-manager.c:544
msgid "Unknown"
msgstr "No cognossût"
#: ../src/backends/meta-monitor-manager.c:546
msgid "Unknown Display"
msgstr "Display no cognossût"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c:554
#, c-format
msgid "%s %s"
msgstr "%s %s"
#. 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
#, c-format
msgid ""
"Another compositing manager is already running on screen %i on display \"%s"
"\"."
msgstr ""
"Un altri compositing manager al è za in esecuzion sul schermi %i sul display "
"\"%s\"."
#: ../src/core/bell.c:194
msgid "Bell event"
msgstr "Event cjampane"
#: ../src/core/delete.c:127
#, c-format
msgid "“%s” is not responding."
msgstr "“%s” nol rispuint."
#: ../src/core/delete.c:129
msgid "Application is not responding."
msgstr "La aplicazion no rispuint."
#: ../src/core/delete.c:134
msgid ""
"You may choose to wait a short while for it to continue or force the "
"application to quit entirely."
msgstr ""
#: ../src/core/delete.c:141
msgid "_Wait"
msgstr "_Spiete"
#: ../src/core/delete.c:141
msgid "_Force Quit"
msgstr "Sfuarce _Jessude"
#: ../src/core/display.c:555
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Impussibil vierzi il display '%s' di X Window System\n"
#: ../src/core/main.c:181
msgid "Disable connection to session manager"
msgstr ""
#: ../src/core/main.c:187
msgid "Replace the running window manager"
msgstr "Rimplace il window manager in vore"
#: ../src/core/main.c:193
msgid "Specify session management ID"
msgstr ""
#: ../src/core/main.c:198
msgid "X Display to use"
msgstr "Display X di doprâ"
#: ../src/core/main.c:204
msgid "Initialize session from savefile"
msgstr "Inizialize session da file salvât"
#: ../src/core/main.c:210
msgid "Make X calls synchronous"
msgstr "Fâs lis clamadis X sincronis"
#: ../src/core/main.c:217
msgid "Run as a wayland compositor"
msgstr "Eseguìs come compositor wayland"
#: ../src/core/main.c:223
msgid "Run as a nested compositor"
msgstr "Eseguìs come compositor nidiât"
#: ../src/core/main.c:231
msgid "Run as a full display server, rather than nested"
msgstr "Eseguìs come servidôr display complet, invezit che nidiât"
#: ../src/core/mutter.c:39
#, c-format
msgid ""
"mutter %s\n"
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., and others\n"
"This is free software; see the source for copying conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A "
"PARTICULAR PURPOSE.\n"
msgstr ""
"mutter %s\n"
"Copyright (C) 2001-%d Havoc Pennington, Red Hat, Inc., e altris\n"
"Chest al è software libar; viodi i sorzints pes condizions di copie.\n"
"No je NISSUNE garanzie; nancje di COMERCIABILITÂT o IDONEITÂT A UNE "
"FINALITÂT PARTICOLÂR.\n"
#: ../src/core/mutter.c:53
msgid "Print version"
msgstr "Stampe version"
#: ../src/core/mutter.c:59
msgid "Mutter plugin to use"
msgstr "Plugin Mutter di doprâ"
#: ../src/core/prefs.c:1997
#, c-format
msgid "Workspace %d"
msgstr "Spazi di lavôr %d"
#: ../src/core/screen.c:521
#, c-format
msgid ""
"Display \"%s\" already has a window manager; try using the --replace option "
"to replace the current window manager."
msgstr ""
"Il display \"%s\" al à za un window manager; prove dopre la opzion --replace "
"par rimplaçâ chel atuâl."
#: ../src/core/screen.c:603
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Schermi %d su display '%s' no valit\n"
#: ../src/core/util.c:121
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter al è stât compilât cence supuart pe modalitât fetose\n"
#: ../src/x11/session.c:1815
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
"be restarted manually next time you log in."
msgstr ""
"Chescj barcons no supuartin la funzion &quot;salve impostazions atuâi&quot; "
"e si scugnarà tornâ a inviâlis a man tal prossim acès."
#: ../src/x11/window-props.c:549
#, c-format
msgid "%s (on %s)"
msgstr "%s (su %s)"

1292
po/gl.po

File diff suppressed because it is too large Load Diff

1759
po/gu.po

File diff suppressed because it is too large Load Diff

1247
po/he.po

File diff suppressed because it is too large Load Diff

1952
po/hi.po

File diff suppressed because it is too large Load Diff

2452
po/hu.po

File diff suppressed because it is too large Load Diff

1602
po/id.po

File diff suppressed because it is too large Load Diff

1774
po/it.po

File diff suppressed because it is too large Load Diff

1621
po/kk.po

File diff suppressed because it is too large Load Diff

1978
po/kn.po

File diff suppressed because it is too large Load Diff

2024
po/ko.po

File diff suppressed because it is too large Load Diff

1467
po/lt.po

File diff suppressed because it is too large Load Diff

2552
po/lv.po

File diff suppressed because it is too large Load Diff

1810
po/mr.po

File diff suppressed because it is too large Load Diff

1141
po/nb.po

File diff suppressed because it is too large Load Diff

2394
po/nl.po

File diff suppressed because it is too large Load Diff

3564
po/oc.po

File diff suppressed because it is too large Load Diff

1808
po/or.po

File diff suppressed because it is too large Load Diff

2376
po/pa.po

File diff suppressed because it is too large Load Diff

1784
po/pl.po

File diff suppressed because it is too large Load Diff

2516
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

3353
po/ro.po

File diff suppressed because it is too large Load Diff

1680
po/ru.po

File diff suppressed because it is too large Load Diff

2672
po/sk.po

File diff suppressed because it is too large Load Diff

1868
po/sl.po

File diff suppressed because it is too large Load Diff

2397
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2342
po/sv.po

File diff suppressed because it is too large Load Diff

1846
po/ta.po

File diff suppressed because it is too large Load Diff

1877
po/te.po

File diff suppressed because it is too large Load Diff

3900
po/th.po

File diff suppressed because it is too large Load Diff

2948
po/tr.po

File diff suppressed because it is too large Load Diff

2414
po/uk.po

File diff suppressed because it is too large Load Diff

4481
po/vi.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +0,0 @@
# A framework for running scripted tests
if HAVE_WAYLAND
if BUILDOPT_INSTALL_TESTS
stackingdir = $(pkgdatadir)/tests/stacking
dist_stacking_DATA = \
tests/stacking/basic-x11.metatest \
tests/stacking/basic-wayland.metatest \
tests/stacking/minimized.metatest \
tests/stacking/mixed-windows.metatest \
tests/stacking/set-parent.metatest \
tests/stacking/override-redirect.metatest
mutter-all.test: tests/mutter-all.test.in
$(AM_V_GEN) sed -e "s|@libexecdir[@]|$(libexecdir)|g" $< > $@.tmp && mv $@.tmp $@
installedtestsdir = $(datadir)/installed-tests/mutter
installedtests_DATA = mutter-all.test
installedtestsbindir = $(libexecdir)/installed-tests/mutter
installedtestsbin_PROGRAMS = mutter-test-client mutter-test-runner mutter-test-unit-tests
else
noinst_PROGRAMS += mutter-test-client mutter-test-runner mutter-test-unit-tests
endif
EXTRA_DIST += tests/mutter-all.test.in
mutter_test_client_SOURCES = tests/test-client.c
mutter_test_client_LDADD = $(MUTTER_LIBS) libmutter.la
mutter_test_runner_SOURCES = tests/test-runner.c
mutter_test_runner_LDADD = $(MUTTER_LIBS) libmutter.la
mutter_test_unit_tests_SOURCES = tests/unit-tests.c
mutter_test_unit_tests_LDADD = $(MUTTER_LIBS) libmutter.la
.PHONY: run-tests run-test-runner-tests run-unit-tests
run-test-runner-tests: mutter-test-client mutter-test-runner
./mutter-test-runner $(dist_stacking_DATA)
run-unit-tests: mutter-test-unit-tests
./mutter-test-unit-tests
run-tests: run-test-runner-tests run-unit-tests
endif
# Some random test programs for bits of the code
testboxes_SOURCES = core/testboxes.c
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
noinst_PROGRAMS += testboxes

View File

@ -5,9 +5,6 @@ lib_LTLIBRARIES = libmutter.la
SUBDIRS=compositor/plugins
EXTRA_DIST =
NULL =
AM_CPPFLAGS = \
-DCLUTTER_ENABLE_COMPOSITOR_API \
-DCLUTTER_ENABLE_EXPERIMENTAL_API \
@ -32,47 +29,34 @@ AM_CPPFLAGS = \
-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" \
-DMUTTER_PLUGIN_DIR=\"$(MUTTER_PLUGIN_DIR)\" \
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
-DXWAYLAND_PATH=\"$(XWAYLAND_PATH)\" \
$(NULL)
-DXWAYLAND_PATH=\"$(XWAYLAND_PATH)\"
mutter_built_sources = \
$(dbus_idle_built_sources) \
$(dbus_display_config_built_sources) \
$(dbus_login1_built_sources) \
meta/meta-enum-types.h \
meta-enum-types.c \
$(NULL)
mutter-enum-types.h \
mutter-enum-types.c
if HAVE_WAYLAND
mutter_built_sources += \
pointer-gestures-unstable-v1-protocol.c \
pointer-gestures-unstable-v1-server-protocol.h \
gtk-shell-protocol.c \
gtk-shell-server-protocol.h \
gtk-primary-selection-protocol.c \
gtk-primary-selection-server-protocol.h \
xdg-shell-unstable-v5-protocol.c \
xdg-shell-unstable-v5-server-protocol.h \
relative-pointer-unstable-v1-protocol.c \
relative-pointer-unstable-v1-server-protocol.h \
pointer-constraints-unstable-v1-protocol.c \
pointer-constraints-unstable-v1-server-protocol.h \
$(NULL)
xdg-shell-protocol.c \
xdg-shell-server-protocol.h
endif
wayland_protocols = \
wayland_protocols = \
wayland/protocol/gtk-shell.xml \
wayland/protocol/gtk-primary-selection.xml \
$(NULL)
wayland/protocol/xdg-shell.xml
libmutter_la_SOURCES = \
backends/meta-backend.c \
meta/meta-backend.h \
backends/meta-backend-private.h \
backends/meta-barrier.c \
backends/meta-barrier-private.h \
backends/meta-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 \
@ -82,45 +66,33 @@ libmutter_la_SOURCES = \
backends/meta-idle-monitor-private.h \
backends/meta-idle-monitor-dbus.c \
backends/meta-idle-monitor-dbus.h \
backends/meta-input-settings.c \
backends/meta-input-settings-private.h \
backends/meta-monitor-config.c \
backends/meta-monitor-config.h \
backends/meta-monitor-manager.c \
meta/meta-monitor-manager.h \
backends/meta-monitor-manager-private.h \
backends/meta-monitor-manager.h \
backends/meta-monitor-manager-dummy.c \
backends/meta-monitor-manager-dummy.h \
backends/meta-pointer-constraint.c \
backends/meta-pointer-constraint.h \
backends/meta-stage.h \
backends/meta-stage.c \
backends/edid-parse.c \
backends/edid.h \
backends/x11/meta-backend-x11.c \
backends/x11/meta-backend-x11.h \
backends/x11/meta-barrier-x11.c \
backends/x11/meta-barrier-x11.h \
backends/x11/meta-cursor-renderer-x11.c \
backends/x11/meta-cursor-renderer-x11.h \
backends/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 \
backends/x11/meta-input-settings-x11.h \
backends/x11/meta-monitor-manager-xrandr.c \
backends/x11/meta-monitor-manager-xrandr.h \
core/meta-accel-parse.c \
core/meta-accel-parse.h \
core/barrier.c \
meta/barrier.h \
core/bell.c \
core/bell.h \
core/boxes.c \
core/boxes-private.h \
meta/boxes.h \
core/meta-border.c \
core/meta-border.h \
compositor/clutter-utils.c \
compositor/clutter-utils.h \
compositor/cogl-utils.c \
@ -128,31 +100,24 @@ libmutter_la_SOURCES = \
compositor/compositor.c \
compositor/compositor-private.h \
compositor/meta-background.c \
compositor/meta-background-private.h \
compositor/meta-background-actor.c \
compositor/meta-background-actor-private.h \
compositor/meta-background-image.c \
compositor/meta-background-group.c \
compositor/meta-cullable.c \
compositor/meta-cullable.h \
compositor/meta-dnd-actor.c \
compositor/meta-dnd-actor-private.h \
compositor/meta-feedback-actor.c \
compositor/meta-feedback-actor-private.h \
compositor/meta-module.c \
compositor/meta-module.h \
compositor/meta-plugin.c \
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 \
@ -162,17 +127,16 @@ 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 \
meta/meta-background.h \
meta/meta-background-actor.h \
meta/meta-background-image.h \
meta/meta-background-group.h \
meta/meta-plugin.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \
meta/meta-window-shape.h \
meta/compositor-mutter.h \
core/constraints.c \
core/constraints.h \
@ -189,6 +153,8 @@ libmutter_la_SOURCES = \
meta/errors.h \
core/frame.c \
core/frame.h \
ui/gradient.c \
meta/gradient.h \
core/meta-gesture-tracker.c \
core/meta-gesture-tracker-private.h \
core/keybindings.c \
@ -201,8 +167,6 @@ libmutter_la_SOURCES = \
core/screen.c \
core/screen-private.h \
meta/screen.h \
core/startup-notification.c \
core/startup-notification-private.h \
meta/types.h \
core/restart.c \
core/stack.c \
@ -222,11 +186,17 @@ libmutter_la_SOURCES = \
ui/ui.h \
ui/frames.c \
ui/frames.h \
ui/resizepopup.c \
ui/resizepopup.h \
ui/theme-parser.c \
ui/theme.c \
meta/theme.h \
ui/theme-private.h \
ui/ui.c \
x11/atomnames.h \
x11/iconcache.c \
x11/iconcache.h \
x11/async-getprop.c \
x11/async-getprop.h \
x11/events.c \
x11/events.h \
x11/group-private.h \
@ -234,8 +204,6 @@ 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 \
@ -245,8 +213,7 @@ libmutter_la_SOURCES = \
x11/window-x11-private.h \
x11/xprops.c \
x11/xprops.h \
x11/mutter-Xatomtype.h \
$(NULL)
x11/mutter-Xatomtype.h
if HAVE_WAYLAND
libmutter_la_SOURCES += \
@ -257,34 +224,13 @@ 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 \
wayland/meta-wayland-region.c \
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 \
wayland/meta-wayland-pointer.h \
wayland/meta-wayland-pointer-constraints.c \
wayland/meta-wayland-pointer-constraints.h \
wayland/meta-pointer-lock-wayland.c \
wayland/meta-pointer-lock-wayland.h \
wayland/meta-pointer-confinement-wayland.c \
wayland/meta-pointer-confinement-wayland.h \
wayland/meta-wayland-popup.c \
wayland/meta-wayland-popup.h \
wayland/meta-wayland-seat.c \
wayland/meta-wayland-seat.h \
wayland/meta-wayland-touch.c \
@ -295,36 +241,30 @@ libmutter_la_SOURCES += \
wayland/meta-wayland-versions.h \
wayland/meta-wayland-outputs.c \
wayland/meta-wayland-outputs.h \
wayland/meta-window-wayland.c \
wayland/meta-window-wayland.h \
$(NULL)
wayland/window-wayland.c \
wayland/window-wayland.h
endif
if HAVE_NATIVE_BACKEND
libmutter_la_SOURCES += \
backends/native/meta-backend-native.c \
backends/native/meta-backend-native.h \
backends/native/meta-backend-native-private.h \
backends/native/meta-barrier-native.c \
backends/native/meta-barrier-native.h \
backends/native/meta-cursor-renderer-native.c \
backends/native/meta-cursor-renderer-native.h \
backends/native/meta-idle-monitor-native.c \
backends/native/meta-idle-monitor-native.h \
backends/native/meta-input-settings-native.c \
backends/native/meta-input-settings-native.h \
backends/native/meta-monitor-manager-kms.c \
backends/native/meta-monitor-manager-kms.h \
backends/native/meta-launcher.c \
backends/native/meta-launcher.h \
backends/native/dbus-utils.c \
backends/native/dbus-utils.h \
$(NULL)
backends/native/dbus-utils.h
endif
nodist_libmutter_la_SOURCES = $(mutter_built_sources)
nodist_libmutter_la_SOURCES = \
$(mutter_built_sources)
libmutter_la_LDFLAGS = -no-undefined -export-symbols-regex "^(meta|ag)_.*"
libmutter_la_LDFLAGS = -no-undefined
libmutter_la_LIBADD = $(MUTTER_LIBS) $(MUTTER_NATIVE_BACKEND_LIBS)
# Headers installed for plugins; introspected information will
@ -337,50 +277,50 @@ libmutterinclude_headers = \
meta/compositor.h \
meta/display.h \
meta/errors.h \
meta/gradient.h \
meta/group.h \
meta/keybindings.h \
meta/main.h \
meta/meta-backend.h \
meta/meta-background.h \
meta/meta-background-actor.h \
meta/meta-background-image.h \
meta/meta-background-group.h \
meta/meta-background.h \
meta/meta-cursor-tracker.h \
meta/meta-idle-monitor.h \
meta/meta-plugin.h \
meta/meta-monitor-manager.h \
meta/meta-shaped-texture.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \
meta/meta-window-shape.h \
meta/prefs.h \
meta/screen.h \
meta/theme.h \
meta/types.h \
meta/util.h \
meta/window.h \
meta/workspace.h \
$(NULL)
meta/workspace.h
libmutterinclude_built_headers = \
meta/meta-version.h \
meta/meta-enum-types.h \
$(NULL)
meta/meta-version.h
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_headers) \
$(libmutterinclude_extra_headers)
nodist_libmutterinclude_HEADERS = \
$(libmutterinclude_built_headers)
bin_PROGRAMS=mutter
noinst_PROGRAMS=
mutter_SOURCES = core/mutter.c
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
@ -389,8 +329,6 @@ libexec_PROGRAMS = mutter-restart-helper
mutter_restart_helper_SOURCES = core/restart-helper.c
mutter_restart_helper_LDADD = $(MUTTER_LIBS)
include Makefile-tests.am
if HAVE_INTROSPECTION
include $(INTROSPECTION_MAKEFILE)
@ -417,12 +355,23 @@ 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
endif
testboxes_SOURCES = core/testboxes.c
testgradient_SOURCES = ui/testgradient.c
testasyncgetprop_SOURCES = x11/testasyncgetprop.c
noinst_PROGRAMS=testboxes testgradient testasyncgetprop
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
CLEANFILES = \
@ -436,40 +385,39 @@ DISTCLEANFILES = \
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libmutter.pc
EXTRA_DIST += \
$(wayland_protocols) \
libmutter.pc.in \
meta-enum-types.h.in \
meta-enum-types.c.in \
org.freedesktop.login1.xml \
EXTRA_DIST = \
$(wayland_protocols) \
libmutter.pc.in \
mutter-enum-types.h.in \
mutter-enum-types.c.in \
org.freedesktop.login1.xml \
org.gnome.Mutter.DisplayConfig.xml \
org.gnome.Mutter.IdleMonitor.xml \
$(NULL)
org.gnome.Mutter.IdleMonitor.xml
BUILT_SOURCES = \
$(mutter_built_sources) \
$(libmutterinclude_built_headers)
MUTTER_STAMP_FILES = stamp-meta-enum-types.h
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
CLEANFILES += $(MUTTER_STAMP_FILES)
meta/meta-enum-types.h: stamp-meta-enum-types.h Makefile
mutter-enum-types.h: stamp-mutter-enum-types.h Makefile
@true
stamp-meta-enum-types.h: $(libmutterinclude_headers) meta-enum-types.h.in
stamp-mutter-enum-types.h: $(libmutterinclude_base_headers) mutter-enum-types.h.in
$(AM_V_GEN) ( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template meta-enum-types.h.in \
--template mutter-enum-types.h.in \
$(libmutterinclude_base_headers) ) >> xgen-teth && \
(cmp -s xgen-teth meta/meta-enum-types.h || cp xgen-teth meta/meta-enum-types.h) && \
(cmp -s xgen-teth mutter-enum-types.h || cp xgen-teth mutter-enum-types.h) && \
rm -f xgen-teth && \
echo timestamp > $(@F)
meta-enum-types.c: stamp-meta-enum-types.h meta-enum-types.c.in
mutter-enum-types.c: stamp-mutter-enum-types.h mutter-enum-types.c.in
$(AM_V_GEN) ( cd $(srcdir) && \
$(GLIB_MKENUMS) \
--template meta-enum-types.c.in \
--template mutter-enum-types.c.in \
$(libmutterinclude_base_headers) ) >> xgen-tetc && \
cp xgen-tetc meta-enum-types.c && \
cp xgen-tetc mutter-enum-types.c && \
rm -f xgen-tetc
dbus_display_config_built_sources = meta-dbus-display-config.c meta-dbus-display-config.h
@ -498,20 +446,6 @@ $(dbus_login1_built_sources) : Makefile.am org.freedesktop.login1.xml
--generate-c-code meta-dbus-login1 \
$(srcdir)/org.freedesktop.login1.xml
.SECONDEXPANSION:
define protostability
$(shell echo $1 | sed 's/.*\(\<unstable\>\|\<stable\>\).*/\1/')
endef
define protoname
$(shell echo $1 | sed 's/\([a-z\-]\+\)-[a-z]\+-v[0-9]\+/\1/')
endef
%-protocol.c : $(WAYLAND_PROTOCOLS_DATADIR)/$$(call protostability,$$*)/$$(call protoname,$$*)/$$*.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
%-server-protocol.h : $(WAYLAND_PROTOCOLS_DATADIR)/$$(call protostability,$$*)/$$(call protoname,$$*)/$$*.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) server-header < $< > $@
%-protocol.c : $(srcdir)/wayland/protocol/%.xml
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml

View File

@ -189,5 +189,7 @@ struct MonitorInfo
};
MonitorInfo *decode_edid (const uchar *data);
char *make_display_name (const MonitorInfo *info);
char *make_display_size_string (int width_mm, int height_mm);
#endif

View File

@ -33,8 +33,7 @@
#include <meta/meta-backend.h>
#include <meta/meta-idle-monitor.h>
#include "meta-cursor-renderer.h"
#include "meta-monitor-manager-private.h"
#include "backends/meta-pointer-constraint.h"
#include "meta-monitor-manager.h"
#define DEFAULT_XKB_RULES_FILE "evdev"
#define DEFAULT_XKB_MODEL "pc105+inet"
@ -50,10 +49,8 @@ struct _MetaBackend
{
GObject parent;
GHashTable *device_monitors;
gint current_device_id;
MetaPointerConstraint *client_pointer_constraint;
MetaIdleMonitor *device_monitors[256];
int device_id_max;
};
struct _MetaBackendClass
@ -90,13 +87,6 @@ struct _MetaBackendClass
void (* update_screen_size) (MetaBackend *backend, int width, int height);
void (* select_stage_events) (MetaBackend *backend);
gboolean (* get_relative_motion_deltas) (MetaBackend *backend,
const ClutterEvent *event,
double *dx,
double *dy,
double *dx_unaccel,
double *dy_unaccel);
};
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
@ -117,17 +107,4 @@ void meta_backend_warp_pointer (MetaBackend *backend,
struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
void meta_backend_update_last_device (MetaBackend *backend,
int device_id);
gboolean meta_backend_get_relative_motion_deltas (MetaBackend *backend,
const ClutterEvent *event,
double *dx,
double *dy,
double *dx_unaccel,
double *dy_unaccel);
void meta_backend_set_client_pointer_constraint (MetaBackend *backend,
MetaPointerConstraint *constraint);
#endif /* META_BACKEND_PRIVATE_H */

View File

@ -24,24 +24,16 @@
#include "config.h"
#include <stdlib.h>
#include <meta/meta-backend.h>
#include "meta-backend-private.h"
#include "meta-input-settings-private.h"
#include "backends/x11/meta-backend-x11.h"
#include "meta-cursor-tracker-private.h"
#include "meta-stage.h"
#ifdef HAVE_NATIVE_BACKEND
#include "backends/native/meta-backend-native.h"
#endif
#include "backends/meta-idle-monitor-private.h"
#include "backends/meta-monitor-manager-dummy.h"
static MetaBackend *_backend;
/**
@ -61,11 +53,8 @@ struct _MetaBackendPrivate
{
MetaMonitorManager *monitor_manager;
MetaCursorRenderer *cursor_renderer;
MetaInputSettings *input_settings;
ClutterActor *stage;
guint device_update_idle_id;
};
typedef struct _MetaBackendPrivate MetaBackendPrivate;
@ -76,14 +65,15 @@ meta_backend_finalize (GObject *object)
{
MetaBackend *backend = META_BACKEND (object);
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
int i;
g_clear_object (&priv->monitor_manager);
g_clear_object (&priv->input_settings);
if (priv->device_update_idle_id)
g_source_remove (priv->device_update_idle_id);
g_hash_table_destroy (backend->device_monitors);
for (i = 0; i <= backend->device_id_max; i++)
{
if (backend->device_monitors[i])
g_object_unref (backend->device_monitors[i]);
}
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
}
@ -99,169 +89,12 @@ meta_backend_sync_screen_size (MetaBackend *backend)
META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height);
}
static void
center_pointer (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
MetaMonitorInfo *monitors, *primary;
guint n_monitors;
monitors = meta_monitor_manager_get_monitor_infos (priv->monitor_manager, &n_monitors);
primary = &monitors[meta_monitor_manager_get_primary_index (priv->monitor_manager)];
meta_backend_warp_pointer (backend,
primary->rect.x + primary->rect.width / 2,
primary->rect.y + primary->rect.height / 2);
}
static void
on_monitors_changed (MetaMonitorManager *monitors,
gpointer user_data)
{
MetaBackend *backend = META_BACKEND (user_data);
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
ClutterPoint point;
meta_backend_sync_screen_size (backend);
if (clutter_input_device_get_coords (device, NULL, &point))
{
/* If we're outside all monitors, warp the pointer back inside */
if (meta_monitor_manager_get_monitor_at_point (monitors, point.x, point.y) < 0)
center_pointer (backend);
}
}
static MetaIdleMonitor *
meta_backend_create_idle_monitor (MetaBackend *backend,
int device_id)
{
return META_BACKEND_GET_CLASS (backend)->create_idle_monitor (backend, device_id);
}
static void
create_device_monitor (MetaBackend *backend,
int device_id)
{
MetaIdleMonitor *idle_monitor;
g_assert (g_hash_table_lookup (backend->device_monitors, &device_id) == NULL);
idle_monitor = meta_backend_create_idle_monitor (backend, device_id);
g_hash_table_insert (backend->device_monitors, &idle_monitor->device_id, idle_monitor);
}
static void
destroy_device_monitor (MetaBackend *backend,
int device_id)
{
g_hash_table_remove (backend->device_monitors, &device_id);
}
static void
on_device_added (ClutterDeviceManager *device_manager,
ClutterInputDevice *device,
gpointer user_data)
{
MetaBackend *backend = META_BACKEND (user_data);
int device_id = clutter_input_device_get_device_id (device);
create_device_monitor (backend, device_id);
}
static inline gboolean
device_is_slave_touchscreen (ClutterInputDevice *device)
{
return (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER &&
clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE);
}
static inline gboolean
check_has_pointing_device (ClutterDeviceManager *manager)
{
const GSList *devices;
devices = clutter_device_manager_peek_devices (manager);
for (; devices; devices = devices->next)
{
ClutterInputDevice *device = devices->data;
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
continue;
if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE ||
clutter_input_device_get_device_type (device) == CLUTTER_KEYBOARD_DEVICE)
continue;
return TRUE;
}
return FALSE;
}
static inline gboolean
check_has_slave_touchscreen (ClutterDeviceManager *manager)
{
const GSList *devices;
devices = clutter_device_manager_peek_devices (manager);
for (; devices; devices = devices->next)
{
ClutterInputDevice *device = devices->data;
if (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER &&
clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE)
return TRUE;
}
return FALSE;
}
static void
on_device_removed (ClutterDeviceManager *device_manager,
ClutterInputDevice *device,
gpointer user_data)
{
MetaBackend *backend = META_BACKEND (user_data);
int device_id = clutter_input_device_get_device_id (device);
destroy_device_monitor (backend, device_id);
/* If the device the user last interacted goes away, check again pointer
* visibility.
*/
if (backend->current_device_id == device_id)
{
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
gboolean has_touchscreen, has_pointing_device;
ClutterInputDeviceType device_type;
device_type = clutter_input_device_get_device_type (device);
has_touchscreen = check_has_slave_touchscreen (device_manager);
if (device_type == CLUTTER_TOUCHSCREEN_DEVICE && has_touchscreen)
{
/* There's more touchscreens left, keep the pointer hidden */
meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE);
}
else if (device_type != CLUTTER_KEYBOARD_DEVICE)
{
has_pointing_device = check_has_pointing_device (device_manager);
meta_cursor_tracker_set_pointer_visible (cursor_tracker,
has_pointing_device &&
!has_touchscreen);
}
}
}
static MetaMonitorManager *
create_monitor_manager (MetaBackend *backend)
{
if (g_getenv ("META_DUMMY_MONITORS"))
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
}
static void
@ -273,50 +106,13 @@ meta_backend_real_post_init (MetaBackend *backend)
clutter_actor_realize (priv->stage);
META_BACKEND_GET_CLASS (backend)->select_stage_events (backend);
priv->monitor_manager = create_monitor_manager (backend);
priv->monitor_manager = META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
g_signal_connect (priv->monitor_manager, "monitors-changed",
G_CALLBACK (on_monitors_changed), backend);
meta_backend_sync_screen_size (backend);
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
backend->device_monitors = g_hash_table_new_full (g_int_hash, g_int_equal,
NULL, (GDestroyNotify) g_object_unref);
{
MetaCursorTracker *cursor_tracker;
ClutterDeviceManager *manager;
gboolean has_touchscreen = FALSE;
GSList *devices, *l;
/* Create the core device monitor. */
create_device_monitor (backend, 0);
manager = clutter_device_manager_get_default ();
g_signal_connect_object (manager, "device-added",
G_CALLBACK (on_device_added), backend, 0);
g_signal_connect_object (manager, "device-removed",
G_CALLBACK (on_device_removed), backend, 0);
devices = clutter_device_manager_list_devices (manager);
for (l = devices; l != NULL; l = l->next)
{
ClutterInputDevice *device = l->data;
on_device_added (manager, device, backend);
has_touchscreen |= device_is_slave_touchscreen (device);
}
cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
meta_cursor_tracker_set_pointer_visible (cursor_tracker, !has_touchscreen);
g_slist_free (devices);
}
priv->input_settings = meta_input_settings_create ();
center_pointer (backend);
}
static MetaCursorRenderer *
@ -358,17 +154,6 @@ meta_backend_real_select_stage_events (MetaBackend *backend)
/* Do nothing */
}
static gboolean
meta_backend_real_get_relative_motion_deltas (MetaBackend *backend,
const ClutterEvent *event,
double *dx,
double *dy,
double *dx_unaccel,
double *dy_unaccel)
{
return FALSE;
}
static void
meta_backend_class_init (MetaBackendClass *klass)
{
@ -382,7 +167,6 @@ meta_backend_class_init (MetaBackendClass *klass)
klass->ungrab_device = meta_backend_real_ungrab_device;
klass->update_screen_size = meta_backend_real_update_screen_size;
klass->select_stage_events = meta_backend_real_select_stage_events;
klass->get_relative_motion_deltas = meta_backend_real_get_relative_motion_deltas;
g_signal_new ("keymap-changed",
G_TYPE_FROM_CLASS (object_class),
@ -390,18 +174,6 @@ meta_backend_class_init (MetaBackendClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
g_signal_new ("keymap-layout-group-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT);
g_signal_new ("last-device-changed",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_INT);
}
static void
@ -410,6 +182,23 @@ meta_backend_init (MetaBackend *backend)
_backend = backend;
}
/* FIXME -- destroy device monitors at some point */
G_GNUC_UNUSED static void
destroy_device_monitor (MetaBackend *backend,
int device_id)
{
g_clear_object (&backend->device_monitors[device_id]);
if (device_id == backend->device_id_max)
backend->device_id_max--;
}
static MetaIdleMonitor *
meta_backend_create_idle_monitor (MetaBackend *backend,
int device_id)
{
return META_BACKEND_GET_CLASS (backend)->create_idle_monitor (backend, device_id);
}
static void
meta_backend_post_init (MetaBackend *backend)
{
@ -423,7 +212,15 @@ MetaIdleMonitor *
meta_backend_get_idle_monitor (MetaBackend *backend,
int device_id)
{
return g_hash_table_lookup (backend->device_monitors, &device_id);
g_return_val_if_fail (device_id >= 0 && device_id < 256, NULL);
if (!backend->device_monitors[device_id])
{
backend->device_monitors[device_id] = meta_backend_create_idle_monitor (backend, device_id);
backend->device_id_max = MAX (backend->device_id_max, device_id);
}
return backend->device_monitors[device_id];
}
/**
@ -522,94 +319,6 @@ meta_backend_get_stage (MetaBackend *backend)
return priv->stage;
}
static gboolean
update_last_device (MetaBackend *backend)
{
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
ClutterInputDeviceType device_type;
ClutterDeviceManager *manager;
ClutterInputDevice *device;
priv->device_update_idle_id = 0;
manager = clutter_device_manager_get_default ();
device = clutter_device_manager_get_device (manager,
backend->current_device_id);
device_type = clutter_input_device_get_device_type (device);
g_signal_emit_by_name (backend, "last-device-changed",
backend->current_device_id);
switch (device_type)
{
case CLUTTER_KEYBOARD_DEVICE:
break;
case CLUTTER_TOUCHSCREEN_DEVICE:
meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE);
break;
default:
meta_cursor_tracker_set_pointer_visible (cursor_tracker, TRUE);
break;
}
return G_SOURCE_REMOVE;
}
void
meta_backend_update_last_device (MetaBackend *backend,
int device_id)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
ClutterDeviceManager *manager;
ClutterInputDevice *device;
if (backend->current_device_id == device_id)
return;
manager = clutter_device_manager_get_default ();
device = clutter_device_manager_get_device (manager, device_id);
if (!device ||
clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
return;
backend->current_device_id = device_id;
if (priv->device_update_idle_id == 0)
{
priv->device_update_idle_id =
g_idle_add ((GSourceFunc) update_last_device, backend);
g_source_set_name_by_id (priv->device_update_idle_id,
"[mutter] update_last_device");
}
}
gboolean
meta_backend_get_relative_motion_deltas (MetaBackend *backend,
const ClutterEvent *event,
double *dx,
double *dy,
double *dx_unaccel,
double *dy_unaccel)
{
MetaBackendClass *klass = META_BACKEND_GET_CLASS (backend);
return klass->get_relative_motion_deltas (backend,
event,
dx, dy,
dx_unaccel, dy_unaccel);
}
void
meta_backend_set_client_pointer_constraint (MetaBackend *backend,
MetaPointerConstraint *constraint)
{
g_assert (!constraint || (constraint && !backend->client_pointer_constraint));
g_clear_object (&backend->client_pointer_constraint);
if (constraint)
backend->client_pointer_constraint = g_object_ref (constraint);
}
static GType
get_backend_type (void)
{
@ -688,23 +397,12 @@ static GSourceFuncs event_funcs = {
void
meta_clutter_init (void)
{
ClutterSettings *clutter_settings;
GSource *source;
meta_create_backend ();
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
{
g_warning ("Unable to initialize Clutter.\n");
exit (1);
}
/*
* XXX: We cannot handle high dpi scaling yet, so fix the scale to 1
* for now.
*/
clutter_settings = clutter_settings_get_default ();
g_object_set (clutter_settings, "window-scaling-factor", 1, NULL);
g_error ("Unable to initialize Clutter.\n");
source = g_source_new (&event_funcs, sizeof (GSource));
g_source_attach (source, NULL);

View File

@ -1,76 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2014-2015 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jasper St. Pierre <jstpierre@mecheye.net>
* Jonas Ådahl <jadahl@gmail.com>
*/
#ifndef META_BARRIER_PRIVATE_H
#define META_BARRIER_PRIVATE_H
#include "core/meta-border.h"
G_BEGIN_DECLS
#define META_TYPE_BARRIER_IMPL (meta_barrier_impl_get_type ())
#define META_BARRIER_IMPL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER_IMPL, MetaBarrierImpl))
#define META_BARRIER_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER_IMPL, MetaBarrierImplClass))
#define META_IS_BARRIER_IMPL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER_IMPL))
#define META_IS_BARRIER_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER_IMPL))
#define META_BARRIER_IMPL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER_IMPL, MetaBarrierImplClass))
typedef struct _MetaBarrierImpl MetaBarrierImpl;
typedef struct _MetaBarrierImplClass MetaBarrierImplClass;
struct _MetaBarrierImpl
{
GObject parent;
};
struct _MetaBarrierImplClass
{
GObjectClass parent_class;
gboolean (*is_active) (MetaBarrierImpl *barrier);
void (*release) (MetaBarrierImpl *barrier,
MetaBarrierEvent *event);
void (*destroy) (MetaBarrierImpl *barrier);
};
GType meta_barrier_impl_get_type (void) G_GNUC_CONST;
void _meta_barrier_emit_hit_signal (MetaBarrier *barrier,
MetaBarrierEvent *event);
void _meta_barrier_emit_left_signal (MetaBarrier *barrier,
MetaBarrierEvent *event);
void meta_barrier_event_unref (MetaBarrierEvent *event);
G_END_DECLS
struct _MetaBarrierPrivate
{
MetaDisplay *display;
MetaBorder border;
MetaBarrierImpl *impl;
};
#endif /* META_BARRIER_PRIVATE_H */

View File

@ -0,0 +1,51 @@
/* -*- 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>
#include <gbm.h>
typedef struct {
CoglTexture2D *texture;
struct gbm_bo *bo;
int offset_x, offset_y;
} MetaCursorImage;
struct _MetaCursorReference {
int ref_count;
MetaCursor cursor;
MetaCursorImage image;
};
CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
int *offset_x,
int *offset_y);
struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
int *offset_x,
int *offset_y);
#endif /* META_CURSOR_PRIVATE_H */

View File

@ -25,6 +25,7 @@
#include "config.h"
#include "meta-cursor-renderer.h"
#include "meta-cursor-private.h"
#include <meta/meta-backend.h>
#include <meta/util.h>
@ -34,45 +35,44 @@
#include "meta-stage.h"
typedef struct
{
CoglTexture *texture;
MetaRectangle current_rect;
gboolean handled_by_backend;
} MetaCursorLayer;
struct _MetaCursorRendererPrivate
{
int current_x, current_y;
MetaCursorSprite *displayed_cursor;
gboolean handled_by_backend;
MetaCursorLayer core_layer;
MetaCursorLayer dnd_layer;
MetaCursorReference *displayed_cursor;
};
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT);
static void
queue_redraw (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
queue_redraw (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
MetaBackend *backend = meta_get_backend ();
ClutterActor *stage = meta_backend_get_stage (backend);
CoglTexture *texture;
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 (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, &rect);
if (priv->core_layer.texture && !priv->core_layer.handled_by_backend)
meta_stage_set_cursor (META_STAGE (stage), layer->texture, &priv->current_rect);
meta_stage_set_dnd_surface (META_STAGE (stage),
}
static gboolean
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer)
{
return FALSE;
}
@ -88,50 +88,69 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
{
}
MetaRectangle
meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
static void
update_layer (MetaCursorRenderer *renderer,
MetaCursorLayer *layer,
CoglTexture *texture,
int offset_x,
int offset_y)
{
MetaCursorRendererPrivate *priv =
meta_cursor_renderer_get_instance_private (renderer);
CoglTexture *texture;
int hot_x, hot_y;
int width, height;
float texture_scale;
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (!texture)
return (MetaRectangle) { 0 };
layer->texture = texture;
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),
};
if (layer->texture)
{
layer->current_rect.x = priv->current_x + offset_x;
layer->current_rect.y = priv->current_y + offset_y;
layer->current_rect.width = cogl_texture_get_width (layer->texture);
layer->current_rect.height = cogl_texture_get_height (layer->texture);
}
else
{
layer->current_rect.x = 0;
layer->current_rect.y = 0;
layer->current_rect.width = 0;
layer->current_rect.height = 0;
}
}
static void
update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
gboolean handled_by_backend;
gboolean should_redraw = FALSE;
CoglTexture *texture;
int hot_x, hot_y;
if (cursor_sprite)
meta_cursor_sprite_prepare_at (cursor_sprite,
priv->current_x,
priv->current_y);
if (priv->displayed_cursor)
{
<<<<<<< HEAD
CoglTexture *texture;
int offset_x, offset_y;
handled_by_backend =
META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer,
cursor_sprite);
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &offset_x, &offset_y);
priv->current_rect.x = priv->current_x + offset_x;
priv->current_rect.y = priv->current_y + offset_y;
priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
=======
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, &hot_x, &hot_y);
>>>>>>> 75e7834... dnd 2
}
else
{
texture = NULL;
hot_x = 0;
hot_y = 0;
}
update_layer (renderer, &priv->core_layer, texture, hot_x, hot_y);
update_layer (renderer, &priv->
handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
if (handled_by_backend != priv->handled_by_backend)
{
priv->handled_by_backend = handled_by_backend;
@ -142,7 +161,7 @@ update_cursor (MetaCursorRenderer *renderer,
should_redraw = TRUE;
if (should_redraw)
queue_redraw (renderer, cursor_sprite);
queue_redraw (renderer);
}
MetaCursorRenderer *
@ -152,25 +171,27 @@ meta_cursor_renderer_new (void)
}
void
meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
MetaCursorReference *cursor)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
if (priv->displayed_cursor == cursor_sprite)
if (priv->displayed_cursor == cursor)
return;
priv->displayed_cursor = cursor_sprite;
update_cursor (renderer, cursor_sprite);
priv->displayed_cursor = cursor;
update_cursor (renderer);
}
void
meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
meta_cursor_renderer_set_dnd_surface (MetaCursorRenderer *renderer,
CoglTexture *texture,
int offset_x,
int offset_y)
{
MetaCursorRendererPrivate *priv =
meta_cursor_renderer_get_instance_private (renderer);
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
update_cursor (renderer, priv->displayed_cursor);
update_layer (renderer, &priv->dnd_layer,
}
void
@ -184,10 +205,10 @@ meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
priv->current_x = x;
priv->current_y = y;
update_cursor (renderer, priv->displayed_cursor);
update_cursor (renderer);
}
MetaCursorSprite *
MetaCursorReference *
meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
@ -195,27 +216,10 @@ meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer)
return priv->displayed_cursor;
}
#ifdef HAVE_WAYLAND
void
meta_cursor_renderer_realize_cursor_from_wl_buffer (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite,
struct wl_resource *buffer)
const MetaRectangle *
meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
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);
return &priv->core_layer.current_rect;
}

View File

@ -26,56 +26,45 @@
#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 ())
G_DECLARE_DERIVABLE_TYPE (MetaCursorRenderer, meta_cursor_renderer,
META, CURSOR_RENDERER, GObject);
#include <gbm.h>
#define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ())
#define META_CURSOR_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER, MetaCursorRenderer))
#define META_CURSOR_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass))
#define META_IS_CURSOR_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER))
#define META_IS_CURSOR_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_CURSOR_RENDERER))
#define META_CURSOR_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass))
typedef struct _MetaCursorRenderer MetaCursorRenderer;
typedef struct _MetaCursorRendererClass MetaCursorRendererClass;
struct _MetaCursorRenderer
{
GObject parent;
};
struct _MetaCursorRendererClass
{
GObjectClass parent_class;
gboolean (* update_cursor) (MetaCursorRenderer *renderer,
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);
gboolean (* update_cursor) (MetaCursorRenderer *renderer);
};
GType meta_cursor_renderer_get_type (void) G_GNUC_CONST;
MetaCursorRenderer * meta_cursor_renderer_new (void);
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite);
void meta_cursor_renderer_set_cursor (MetaCursorRenderer *renderer,
MetaCursorReference *cursor);
void meta_cursor_renderer_set_position (MetaCursorRenderer *renderer,
int x, int y);
void meta_cursor_renderer_force_update (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);
MetaCursorReference * meta_cursor_renderer_get_cursor (MetaCursorRenderer *renderer);
const MetaRectangle * meta_cursor_renderer_get_rect (MetaCursorRenderer *renderer);
#endif /* META_CURSOR_RENDERER_H */

View File

@ -34,7 +34,7 @@ struct _MetaCursorTracker {
gboolean is_showing;
MetaCursorSprite *displayed_cursor;
MetaCursorReference *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;
MetaCursorSprite *window_cursor;
MetaCursorReference *window_cursor;
MetaCursorSprite *root_cursor;
MetaCursorReference *root_cursor;
/* The cursor from the X11 server. */
MetaCursorSprite *xfixes_cursor;
MetaCursorReference *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,
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_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_update_position (MetaCursorTracker *tracker,
int new_x,
int new_y);
MetaCursorSprite * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
MetaCursorReference * meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker);
#endif

View File

@ -27,9 +27,7 @@
* pointer abstraction"
*/
#include "config.h"
#include "meta-cursor-tracker-private.h"
#include <config.h>
#include <string.h>
#include <meta/main.h>
#include <meta/util.h>
@ -40,10 +38,12 @@
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <X11/extensions/Xfixes.h>
#include "meta-backend-private.h"
#include "meta-cursor-private.h"
#include "meta-cursor-tracker-private.h"
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
enum {
@ -53,7 +53,7 @@ enum {
static guint signals[LAST_SIGNAL];
static MetaCursorSprite *
static MetaCursorReference *
get_displayed_cursor (MetaCursorTracker *tracker)
{
MetaDisplay *display = meta_get_display ();
@ -79,14 +79,14 @@ update_displayed_cursor (MetaCursorTracker *tracker)
static void
sync_cursor (MetaCursorTracker *tracker)
{
MetaCursorSprite *displayed_cursor = get_displayed_cursor (tracker);
MetaCursorReference *displayed_cursor = get_displayed_cursor (tracker);
if (tracker->displayed_cursor == displayed_cursor)
return;
g_clear_object (&tracker->displayed_cursor);
g_clear_pointer (&tracker->displayed_cursor, meta_cursor_reference_unref);
if (displayed_cursor)
tracker->displayed_cursor = g_object_ref (displayed_cursor);
tracker->displayed_cursor = meta_cursor_reference_ref (displayed_cursor);
update_displayed_cursor (tracker);
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
@ -107,9 +107,9 @@ meta_cursor_tracker_finalize (GObject *object)
MetaCursorTracker *self = META_CURSOR_TRACKER (object);
if (self->displayed_cursor)
g_object_unref (self->displayed_cursor);
meta_cursor_reference_unref (self->displayed_cursor);
if (self->root_cursor)
g_object_unref (self->root_cursor);
meta_cursor_reference_unref (self->root_cursor);
G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->finalize (object);
}
@ -155,13 +155,13 @@ meta_cursor_tracker_get_for_screen (MetaScreen *screen)
}
static void
set_window_cursor (MetaCursorTracker *tracker,
gboolean has_cursor,
MetaCursorSprite *cursor_sprite)
set_window_cursor (MetaCursorTracker *tracker,
gboolean has_cursor,
MetaCursorReference *cursor)
{
g_clear_object (&tracker->window_cursor);
if (cursor_sprite)
tracker->window_cursor = g_object_ref (cursor_sprite);
g_clear_pointer (&tracker->window_cursor, meta_cursor_reference_unref);
if (cursor)
tracker->window_cursor = meta_cursor_reference_ref (cursor);
tracker->has_window_cursor = has_cursor;
sync_cursor (tracker);
}
@ -183,12 +183,27 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
if (notify_event->subtype != XFixesDisplayCursorNotify)
return FALSE;
g_clear_object (&tracker->xfixes_cursor);
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref);
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)
{
@ -246,13 +261,10 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
if (sprite != NULL)
{
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;
MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite,
cursor_image->xhot,
cursor_image->yhot);
tracker->xfixes_cursor = cursor;
}
XFree (cursor_image);
}
@ -265,22 +277,22 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
CoglTexture *
meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
{
MetaCursorSprite *cursor_sprite;
MetaCursorReference *cursor;
g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL);
if (meta_is_wayland_compositor ())
{
cursor_sprite = tracker->displayed_cursor;
cursor = tracker->displayed_cursor;
}
else
{
ensure_xfixes_cursor (tracker);
cursor_sprite = tracker->xfixes_cursor;
cursor = tracker->xfixes_cursor;
}
if (cursor_sprite)
return meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (cursor)
return meta_cursor_reference_get_cogl_texture (cursor, NULL, NULL);
else
return NULL;
}
@ -297,36 +309,42 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
int *x,
int *y)
{
MetaCursorSprite *cursor_sprite;
MetaCursorReference *cursor;
int offset_x, offset_y;
g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
if (meta_is_wayland_compositor ())
{
cursor_sprite = tracker->displayed_cursor;
cursor = tracker->displayed_cursor;
}
else
{
ensure_xfixes_cursor (tracker);
cursor_sprite = tracker->xfixes_cursor;
cursor = tracker->xfixes_cursor;
}
if (cursor_sprite)
meta_cursor_sprite_get_hotspot (cursor_sprite, x, y);
if (cursor)
{
meta_cursor_reference_get_cogl_texture (cursor, &offset_x, &offset_y);
}
else
{
if (x)
*x = 0;
if (y)
*y = 0;
offset_x = 0;
offset_y = 0;
}
if (x)
*x = -offset_x;
if (y)
*y = -offset_y;
}
void
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
MetaCursorSprite *cursor_sprite)
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor)
{
set_window_cursor (tracker, TRUE, cursor_sprite);
set_window_cursor (tracker, TRUE, cursor);
}
void
@ -336,12 +354,12 @@ meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker)
}
void
meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
MetaCursorSprite *cursor_sprite)
meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
MetaCursorReference *cursor)
{
g_clear_object (&tracker->root_cursor);
if (cursor_sprite)
tracker->root_cursor = g_object_ref (cursor_sprite);
g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref);
if (cursor)
tracker->root_cursor = meta_cursor_reference_ref (cursor);
sync_cursor (tracker);
}
@ -361,12 +379,12 @@ get_pointer_position_gdk (int *x,
int *y,
int *mods)
{
GdkSeat *gseat;
GdkDeviceManager *gmanager;
GdkDevice *gdevice;
GdkScreen *gscreen;
gseat = gdk_display_get_default_seat (gdk_display_get_default ());
gdevice = gdk_seat_get_pointer (gseat);
gmanager = gdk_display_get_device_manager (gdk_display_get_default ());
gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
gdk_device_get_position (gdevice, &gscreen, x, y);
if (mods)
@ -424,7 +442,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
sync_cursor (tracker);
}
MetaCursorSprite *
MetaCursorReference *
meta_cursor_tracker_get_displayed_cursor (MetaCursorTracker *tracker)
{
return tracker->displayed_cursor;

View File

@ -21,7 +21,7 @@
#include "config.h"
#include "meta-cursor.h"
#include "meta-cursor-private.h"
#include <meta/errors.h>
@ -29,38 +29,52 @@
#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>
enum {
PREPARE_AT,
#ifdef HAVE_WAYLAND
#include <cogl/cogl-wayland-server.h>
#endif
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
struct _MetaCursorSprite
MetaCursorReference *
meta_cursor_reference_ref (MetaCursorReference *self)
{
GObject parent;
g_assert (self->ref_count > 0);
self->ref_count++;
MetaCursor cursor;
return self;
}
CoglTexture2D *texture;
float texture_scale;
int hot_x, hot_y;
static void
meta_cursor_image_free (MetaCursorImage *image)
{
cogl_object_unref (image->texture);
if (image->bo)
gbm_bo_destroy (image->bo);
}
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--;
G_DEFINE_TYPE (MetaCursorSprite, meta_cursor_sprite, G_TYPE_OBJECT)
if (self->ref_count == 0)
meta_cursor_reference_free (self);
}
static const char *
translate_meta_cursor (MetaCursor cursor)
@ -117,242 +131,251 @@ meta_cursor_create_x_cursor (Display *xdisplay,
return XcursorLibraryLoadCursor (xdisplay, translate_meta_cursor (cursor));
}
static XcursorImages *
load_cursor_on_client (MetaCursor cursor, int scale)
static XcursorImage *
load_cursor_on_client (MetaCursor cursor)
{
return XcursorLibraryLoadImages (translate_meta_cursor (cursor),
meta_prefs_get_cursor_theme (),
meta_prefs_get_cursor_size () * scale);
return XcursorLibraryLoadImage (translate_meta_cursor (cursor),
meta_prefs_get_cursor_theme (),
meta_prefs_get_cursor_size ());
}
static void
meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *self,
XcursorImage *xc_image)
meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
MetaCursorImage *image,
uint8_t *pixels,
int width,
int height,
int rowstride,
uint32_t gbm_format)
{
if (width > 64 || height > 64)
{
meta_warning ("Invalid theme cursor size (must be at most 64x64)\n");
return;
}
if (gbm_device_is_format_supported (gbm, gbm_format,
GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE))
{
uint8_t buf[4 * 64 * 64];
int i;
image->bo = gbm_bo_create (gbm, 64, 64,
gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
memset (buf, 0, sizeof(buf));
for (i = 0; i < height; i++)
memcpy (buf + i * 4 * 64, pixels + i * rowstride, width * 4);
gbm_bo_write (image->bo, buf, 64 * 64 * 4);
}
else
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
}
static struct gbm_device *
get_gbm_device (void)
{
#ifdef HAVE_NATIVE_BACKEND
MetaBackend *meta_backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
uint width, height, rowstride;
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer));
#endif
return NULL;
}
static void
meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
XcursorImage *xc_image)
{
int width, height, rowstride;
CoglPixelFormat cogl_format;
uint32_t gbm_format;
ClutterBackend *clutter_backend;
CoglContext *cogl_context;
CoglTexture *texture;
g_assert (self->texture == NULL);
struct gbm_device *gbm;
width = xc_image->width;
height = xc_image->height;
rowstride = width * 4;
gbm_format = GBM_FORMAT_ARGB8888;
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
#else
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);
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);
image->texture = cogl_texture_2d_new_from_data (cogl_context,
width, height,
cogl_format,
rowstride,
(uint8_t *) xc_image->pixels,
NULL);
meta_cursor_renderer_realize_cursor_from_xcursor (renderer, self, xc_image);
gbm = get_gbm_device ();
if (gbm)
meta_cursor_image_load_gbm_buffer (gbm,
image,
(uint8_t *) xc_image->pixels,
width, height, rowstride,
gbm_format);
}
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)
MetaCursorReference *
meta_cursor_reference_from_theme (MetaCursor cursor)
{
MetaCursorReference *self;
XcursorImage *image;
if (!meta_cursor_sprite_is_animated (self))
return;
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);
}
guint
meta_cursor_sprite_get_current_frame_time (MetaCursorSprite *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);
}
static void
meta_cursor_sprite_load_from_theme (MetaCursorSprite *self)
{
XcursorImage *image;
g_assert (self->cursor != META_CURSOR_NONE);
/* We might be reloading with a different scale. If so clear the old data. */
if (self->xcursor_images)
{
g_clear_pointer (&self->texture, cogl_object_unref);
XcursorImagesDestroy (self->xcursor_images);
}
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;
}
MetaCursorSprite *
meta_cursor_sprite_from_theme (MetaCursor cursor)
{
MetaCursorSprite *self;
self = meta_cursor_sprite_new ();
image = load_cursor_on_client (cursor);
if (!image)
return NULL;
self = g_slice_new0 (MetaCursorReference);
self->ref_count = 1;
self->cursor = cursor;
self->theme_dirty = TRUE;
meta_cursor_image_load_from_xcursor_image (&self->image, image);
XcursorImageDestroy (image);
return self;
}
void
meta_cursor_sprite_set_texture (MetaCursorSprite *self,
CoglTexture *texture,
int hot_x,
int hot_y)
#ifdef HAVE_WAYLAND
static void
meta_cursor_image_load_from_buffer (MetaCursorImage *image,
struct wl_resource *buffer,
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;
struct gbm_device *gbm = get_gbm_device ();
ClutterBackend *backend;
CoglContext *cogl_context;
struct wl_shm_buffer *shm_buffer;
uint32_t gbm_format;
int width, height;
image->hot_x = hot_x;
image->hot_y = hot_y;
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);
width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
shm_buffer = wl_shm_buffer_get (buffer);
if (shm_buffer)
{
if (gbm)
{
int rowstride = wl_shm_buffer_get_stride (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);
}
}
else
{
/* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses
that, so themed cursors must be padded with transparent pixels to fill the
overlay. This is trivial if we have CPU access to the data, but it's not
possible if the buffer is in GPU memory (and possibly tiled too), so if we
don't get the right size, we fallback to GL.
*/
if (width != 64 || height != 64)
{
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
return;
}
if (gbm)
{
image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER,
buffer, GBM_BO_USE_CURSOR_64X64);
if (!image->bo)
meta_warning ("Importing HW cursor from wl_buffer failed\n");
}
}
}
void
meta_cursor_sprite_set_texture_scale (MetaCursorSprite *self,
float scale)
MetaCursorReference *
meta_cursor_reference_from_buffer (struct wl_resource *buffer,
int hot_x,
int hot_y)
{
self->texture_scale = scale;
}
MetaCursorReference *self;
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;
self = g_slice_new0 (MetaCursorReference);
self->ref_count = 1;
meta_cursor_image_load_from_buffer (&self->image, buffer, hot_x, hot_y);
return self;
}
#endif
CoglTexture *
meta_cursor_sprite_get_cogl_texture (MetaCursorSprite *self)
meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
int *offset_x,
int *offset_y)
{
return COGL_TEXTURE (self->texture);
if (offset_x)
*offset_x = cursor->image.offset_x;
if (offset_y)
*offset_y = cursor->image.offset_y;
return COGL_TEXTURE (cursor->image.texture);
}
struct gbm_bo *
meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
int *offset_x,
int *offset_y)
{
if (offset_x)
*offset_x = cursor->image.offset_x;
if (offset_y)
*offset_y = cursor->image.offset_y;
return cursor->image.bo;
}
MetaCursor
meta_cursor_sprite_get_meta_cursor (MetaCursorSprite *self)
meta_cursor_reference_get_meta_cursor (MetaCursorReference *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);
return cursor->cursor;
}

View File

@ -22,54 +22,24 @@
#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>
typedef struct _MetaCursorSprite MetaCursorSprite;
MetaCursorReference * meta_cursor_reference_from_theme (MetaCursor cursor);
#define META_TYPE_CURSOR_SPRITE (meta_cursor_sprite_get_type ())
G_DECLARE_FINAL_TYPE (MetaCursorSprite,
meta_cursor_sprite,
META, CURSOR_SPRITE,
GObject);
#ifdef HAVE_WAYLAND
#include <wayland-server.h>
MetaCursorReference * meta_cursor_reference_from_buffer (struct wl_resource *buffer,
int offset_x, int offset_y);
#endif
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);
MetaCursor meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor);
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 */

View File

@ -1,87 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright 2014 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
#ifndef META_INPUT_SETTINGS_PRIVATE_H
#define META_INPUT_SETTINGS_PRIVATE_H
#include "display-private.h"
#include <clutter/clutter.h>
#define META_TYPE_INPUT_SETTINGS (meta_input_settings_get_type ())
#define META_INPUT_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS, MetaInputSettings))
#define META_INPUT_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS, MetaInputSettingsClass))
#define META_IS_INPUT_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS))
#define META_IS_INPUT_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS))
#define META_INPUT_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS, MetaInputSettingsClass))
typedef struct _MetaInputSettings MetaInputSettings;
typedef struct _MetaInputSettingsClass MetaInputSettingsClass;
struct _MetaInputSettings
{
GObject parent_instance;
};
struct _MetaInputSettingsClass
{
GObjectClass parent_class;
void (* set_send_events) (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopDeviceSendEvents mode);
void (* set_matrix) (MetaInputSettings *settings,
ClutterInputDevice *device,
gfloat matrix[6]);
void (* set_speed) (MetaInputSettings *settings,
ClutterInputDevice *device,
gdouble speed);
void (* set_left_handed) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);
void (* set_tap_enabled) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);
void (* set_invert_scroll) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean inverted);
void (* set_edge_scroll) (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled);
void (* set_scroll_button) (MetaInputSettings *settings,
ClutterInputDevice *device,
guint button);
void (* set_click_method) (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopTouchpadClickMethod mode);
void (* set_keyboard_repeat) (MetaInputSettings *settings,
gboolean repeat,
guint delay,
guint interval);
};
GType meta_input_settings_get_type (void) G_GNUC_CONST;
MetaInputSettings * meta_input_settings_create (void);
#endif /* META_INPUT_SETTINGS_PRIVATE_H */

View File

@ -1,893 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright 2014 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
/**
* SECTION:input-settings
* @title: MetaInputSettings
* @short_description: Mutter input device configuration
*/
#include "config.h"
#include <string.h>
#include "meta-backend-private.h"
#include "meta-input-settings-private.h"
#include "x11/meta-input-settings-x11.h"
#ifdef HAVE_NATIVE_BACKEND
#include "native/meta-backend-native.h"
#include "native/meta-input-settings-native.h"
#endif
#include <meta/util.h>
typedef struct _MetaInputSettingsPrivate MetaInputSettingsPrivate;
typedef struct _DeviceMappingInfo DeviceMappingInfo;
struct _DeviceMappingInfo
{
MetaInputSettings *input_settings;
ClutterInputDevice *device;
GSettings *settings;
};
struct _MetaInputSettingsPrivate
{
ClutterDeviceManager *device_manager;
MetaMonitorManager *monitor_manager;
guint monitors_changed_id;
GSettings *mouse_settings;
GSettings *touchpad_settings;
GSettings *trackball_settings;
GSettings *keyboard_settings;
GHashTable *mappable_devices;
};
typedef void (*ConfigBoolFunc) (MetaInputSettings *input_settings,
ClutterInputDevice *device,
gboolean setting);
typedef void (*ConfigDoubleFunc) (MetaInputSettings *input_settings,
ClutterInputDevice *device,
gdouble value);
typedef void (*ConfigUintFunc) (MetaInputSettings *input_settings,
ClutterInputDevice *device,
guint value);
G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT)
static GSList *
meta_input_settings_get_devices (MetaInputSettings *settings,
ClutterInputDeviceType type)
{
MetaInputSettingsPrivate *priv;
const GSList *devices;
GSList *list = NULL;
priv = meta_input_settings_get_instance_private (settings);
devices = clutter_device_manager_peek_devices (priv->device_manager);
while (devices)
{
ClutterInputDevice *device = devices->data;
if (clutter_input_device_get_device_type (device) == type &&
clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER)
list = g_slist_prepend (list, device);
devices = devices->next;
}
return list;
}
static void
meta_input_settings_dispose (GObject *object)
{
MetaInputSettings *settings = META_INPUT_SETTINGS (object);
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (settings);
g_clear_object (&priv->mouse_settings);
g_clear_object (&priv->touchpad_settings);
g_clear_object (&priv->trackball_settings);
g_clear_object (&priv->keyboard_settings);
g_clear_pointer (&priv->mappable_devices, g_hash_table_unref);
if (priv->monitors_changed_id && priv->monitor_manager)
{
g_signal_handler_disconnect (priv->monitor_manager,
priv->monitors_changed_id);
priv->monitors_changed_id = 0;
}
g_clear_object (&priv->monitor_manager);
G_OBJECT_CLASS (meta_input_settings_parent_class)->dispose (object);
}
static void
settings_device_set_bool_setting (MetaInputSettings *input_settings,
ClutterInputDevice *device,
ConfigBoolFunc func,
gboolean enabled)
{
func (input_settings, device, enabled);
}
static void
settings_set_bool_setting (MetaInputSettings *input_settings,
ClutterInputDeviceType type,
ConfigBoolFunc func,
gboolean enabled)
{
GSList *devices, *d;
devices = meta_input_settings_get_devices (input_settings, type);
for (d = devices; d; d = d->next)
settings_device_set_bool_setting (input_settings, d->data, func, enabled);
g_slist_free (devices);
}
static void
settings_device_set_double_setting (MetaInputSettings *input_settings,
ClutterInputDevice *device,
ConfigDoubleFunc func,
gdouble value)
{
func (input_settings, device, value);
}
static void
settings_set_double_setting (MetaInputSettings *input_settings,
ClutterInputDeviceType type,
ConfigDoubleFunc func,
gdouble value)
{
GSList *devices, *d;
devices = meta_input_settings_get_devices (input_settings, type);
for (d = devices; d; d = d->next)
settings_device_set_double_setting (input_settings, d->data, func, value);
g_slist_free (devices);
}
static void
settings_device_set_uint_setting (MetaInputSettings *input_settings,
ClutterInputDevice *device,
ConfigUintFunc func,
guint value)
{
(func) (input_settings, device, value);
}
static void
settings_set_uint_setting (MetaInputSettings *input_settings,
ClutterInputDeviceType type,
ConfigUintFunc func,
guint value)
{
GSList *devices, *d;
devices = meta_input_settings_get_devices (input_settings, type);
for (d = devices; d; d = d->next)
settings_device_set_uint_setting (input_settings, d->data, func, value);
g_slist_free (devices);
}
static void
update_touchpad_left_handed (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
GDesktopTouchpadHandedness handedness;
MetaInputSettingsPrivate *priv;
gboolean enabled = FALSE;
if (device &&
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
return;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
handedness = g_settings_get_enum (priv->touchpad_settings, "left-handed");
switch (handedness)
{
case G_DESKTOP_TOUCHPAD_HANDEDNESS_RIGHT:
enabled = FALSE;
break;
case G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT:
enabled = TRUE;
break;
case G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE:
enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
break;
default:
g_assert_not_reached ();
}
if (device)
{
settings_device_set_bool_setting (input_settings, device,
input_settings_class->set_left_handed,
enabled);
}
else
{
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
input_settings_class->set_left_handed,
enabled);
}
}
static void
update_mouse_left_handed (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
MetaInputSettingsPrivate *priv;
gboolean enabled;
if (device &&
clutter_input_device_get_device_type (device) != CLUTTER_POINTER_DEVICE)
return;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
if (device)
{
settings_device_set_bool_setting (input_settings, device,
input_settings_class->set_left_handed,
enabled);
}
else
{
GDesktopTouchpadHandedness touchpad_handedness;
settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE,
input_settings_class->set_left_handed,
enabled);
touchpad_handedness = g_settings_get_enum (priv->touchpad_settings,
"left-handed");
/* Also update touchpads if they're following mouse settings */
if (touchpad_handedness == G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE)
update_touchpad_left_handed (input_settings, NULL);
}
}
static GSettings *
get_settings_for_device_type (MetaInputSettings *input_settings,
ClutterInputDeviceType type)
{
MetaInputSettingsPrivate *priv;
priv = meta_input_settings_get_instance_private (input_settings);
switch (type)
{
case CLUTTER_POINTER_DEVICE:
return priv->mouse_settings;
case CLUTTER_TOUCHPAD_DEVICE:
return priv->touchpad_settings;
default:
return NULL;
}
}
static void
update_device_speed (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
GSettings *settings;
ConfigDoubleFunc func;
const gchar *key = "speed";
func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_speed;
if (device)
{
settings = get_settings_for_device_type (input_settings,
clutter_input_device_get_device_type (device));
if (!settings)
return;
settings_device_set_double_setting (input_settings, device, func,
g_settings_get_double (settings, key));
}
else
{
settings = get_settings_for_device_type (input_settings, CLUTTER_POINTER_DEVICE);
settings_set_double_setting (input_settings, CLUTTER_POINTER_DEVICE, func,
g_settings_get_double (settings, key));
settings = get_settings_for_device_type (input_settings, CLUTTER_TOUCHPAD_DEVICE);
settings_set_double_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, func,
g_settings_get_double (settings, key));
}
}
static void
update_device_natural_scroll (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
GSettings *settings;
ConfigBoolFunc func;
const gchar *key = "natural-scroll";
func = META_INPUT_SETTINGS_GET_CLASS (input_settings)->set_invert_scroll;
if (device)
{
settings = get_settings_for_device_type (input_settings,
clutter_input_device_get_device_type (device));
if (!settings)
return;
settings_device_set_bool_setting (input_settings, device, func,
g_settings_get_boolean (settings, key));
}
else
{
settings = get_settings_for_device_type (input_settings, CLUTTER_POINTER_DEVICE);
settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE, func,
g_settings_get_boolean (settings, key));
settings = get_settings_for_device_type (input_settings, CLUTTER_TOUCHPAD_DEVICE);
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE, func,
g_settings_get_boolean (settings, key));
}
}
static void
update_touchpad_tap_enabled (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
MetaInputSettingsPrivate *priv;
gboolean enabled;
if (device &&
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
return;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
if (device)
{
settings_device_set_bool_setting (input_settings, device,
input_settings_class->set_tap_enabled,
enabled);
}
else
{
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
input_settings_class->set_tap_enabled,
enabled);
}
}
static void
update_touchpad_edge_scroll (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
gboolean edge_scroll_enabled;
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);
edge_scroll_enabled = g_settings_get_boolean (priv->touchpad_settings, "edge-scrolling-enabled");
if (device)
{
settings_device_set_bool_setting (input_settings, device,
input_settings_class->set_edge_scroll,
edge_scroll_enabled);
}
else
{
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
(ConfigBoolFunc) input_settings_class->set_edge_scroll,
edge_scroll_enabled);
}
}
static void
update_touchpad_click_method (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
GDesktopTouchpadClickMethod method;
MetaInputSettingsPrivate *priv;
if (device &&
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
return;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
method = g_settings_get_enum (priv->touchpad_settings, "click-method");
if (device)
{
settings_device_set_uint_setting (input_settings, device,
input_settings_class->set_click_method,
method);
}
else
{
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
(ConfigUintFunc) input_settings_class->set_click_method,
method);
}
}
static void
update_touchpad_send_events (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
MetaInputSettingsPrivate *priv;
GDesktopDeviceSendEvents mode;
if (device &&
clutter_input_device_get_device_type (device) != CLUTTER_TOUCHPAD_DEVICE)
return;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
mode = g_settings_get_enum (priv->touchpad_settings, "send-events");
if (device)
{
settings_device_set_uint_setting (input_settings, device,
input_settings_class->set_send_events,
mode);
}
else
{
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
input_settings_class->set_send_events,
mode);
}
}
static gboolean
device_is_trackball (ClutterInputDevice *device)
{
gboolean is_trackball;
char *name;
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
return FALSE;
name = g_ascii_strdown (clutter_input_device_get_device_name (device), -1);
is_trackball = strstr (name, "trackball") != NULL;
g_free (name);
return is_trackball;
}
static void
update_trackball_scroll_button (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
MetaInputSettingsPrivate *priv;
guint button;
if (device && !device_is_trackball (device))
return;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
/* This key is 'i' in the schema but it also specifies a minimum
* range of 0 so the cast here is safe. */
button = (guint) g_settings_get_int (priv->trackball_settings, "scroll-wheel-emulation-button");
if (device)
{
input_settings_class->set_scroll_button (input_settings, device, button);
}
else if (!device)
{
const GSList *devices;
devices = clutter_device_manager_peek_devices (priv->device_manager);
while (devices)
{
device = devices->data;
if (device_is_trackball (device))
input_settings_class->set_scroll_button (input_settings, device, button);
devices = devices->next;
}
}
}
static void
update_keyboard_repeat (MetaInputSettings *input_settings)
{
MetaInputSettingsClass *input_settings_class;
MetaInputSettingsPrivate *priv;
guint delay, interval;
gboolean repeat;
priv = meta_input_settings_get_instance_private (input_settings);
repeat = g_settings_get_boolean (priv->keyboard_settings, "repeat");
delay = g_settings_get_uint (priv->keyboard_settings, "delay");
interval = g_settings_get_uint (priv->keyboard_settings, "repeat-interval");
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
input_settings_class->set_keyboard_repeat (input_settings,
repeat, delay, interval);
}
static MetaOutput *
meta_input_settings_find_output (MetaInputSettings *input_settings,
GSettings *settings,
ClutterInputDevice *device)
{
MetaInputSettingsPrivate *priv;
guint n_values, n_outputs, i;
MetaOutput *outputs;
gchar **edid;
priv = meta_input_settings_get_instance_private (input_settings);
edid = g_settings_get_strv (settings, "display");
n_values = g_strv_length (edid);
if (n_values != 3)
{
g_warning ("EDID configuration for device '%s' "
"is incorrect, must have 3 values",
clutter_input_device_get_device_name (device));
return NULL;
}
if (!*edid[0] && !*edid[1] && !*edid[2])
return NULL;
outputs = meta_monitor_manager_get_outputs (priv->monitor_manager,
&n_outputs);
for (i = 0; i < n_outputs; i++)
{
if (g_strcmp0 (outputs[i].vendor, edid[0]) == 0 &&
g_strcmp0 (outputs[i].product, edid[1]) == 0 &&
g_strcmp0 (outputs[i].serial, edid[2]) == 0)
return &outputs[i];
}
return NULL;
}
static void
update_device_display (MetaInputSettings *input_settings,
GSettings *settings,
ClutterInputDevice *device)
{
MetaInputSettingsClass *input_settings_class;
MetaInputSettingsPrivate *priv;
gfloat matrix[6] = { 1, 0, 0, 0, 1, 0 };
MetaOutput *output;
priv = meta_input_settings_get_instance_private (input_settings);
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
output = meta_input_settings_find_output (input_settings, settings, device);
if (output)
meta_monitor_manager_get_monitor_matrix (priv->monitor_manager,
output, matrix);
input_settings_class->set_matrix (input_settings, device, matrix);
}
static void
meta_input_settings_changed_cb (GSettings *settings,
const char *key,
gpointer user_data)
{
MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data);
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
if (settings == priv->mouse_settings)
{
if (strcmp (key, "left-handed") == 0)
update_mouse_left_handed (input_settings, NULL);
else if (strcmp (key, "speed") == 0)
update_device_speed (input_settings, NULL);
else if (strcmp (key, "natural-scroll") == 0)
update_device_natural_scroll (input_settings, NULL);
}
else if (settings == priv->touchpad_settings)
{
if (strcmp (key, "left-handed") == 0)
update_touchpad_left_handed (input_settings, NULL);
else if (strcmp (key, "speed") == 0)
update_device_speed (input_settings, NULL);
else if (strcmp (key, "natural-scroll") == 0)
update_device_natural_scroll (input_settings, NULL);
else if (strcmp (key, "tap-to-click") == 0)
update_touchpad_tap_enabled (input_settings, NULL);
else if (strcmp (key, "send-events") == 0)
update_touchpad_send_events (input_settings, NULL);
else if (strcmp (key, "edge-scrolling-enabled") == 0)
update_touchpad_edge_scroll (input_settings, NULL);
else if (strcmp (key, "click-method") == 0)
update_touchpad_click_method (input_settings, NULL);
}
else if (settings == priv->trackball_settings)
{
if (strcmp (key, "scroll-wheel-emulation-button") == 0)
update_trackball_scroll_button (input_settings, NULL);
}
else if (settings == priv->keyboard_settings)
{
if (strcmp (key, "repeat") == 0 ||
strcmp (key, "repeat-interval") == 0 ||
strcmp (key, "delay") == 0)
update_keyboard_repeat (input_settings);
}
}
static void
mapped_device_changed_cb (GSettings *settings,
const gchar *key,
DeviceMappingInfo *info)
{
if (strcmp (key, "display") == 0)
update_device_display (info->input_settings, settings, info->device);
}
static GSettings *
lookup_device_settings (ClutterInputDevice *device)
{
const gchar *group, *schema, *vendor, *product;
ClutterInputDeviceType type;
GSettings *settings;
gchar *path;
type = clutter_input_device_get_device_type (device);
if (type == CLUTTER_TOUCHSCREEN_DEVICE)
{
group = "touchscreens";
schema = "org.gnome.desktop.peripherals.touchscreen";
}
else if (type == CLUTTER_TABLET_DEVICE ||
type == CLUTTER_PEN_DEVICE ||
type == CLUTTER_ERASER_DEVICE ||
type == CLUTTER_CURSOR_DEVICE)
{
group = "tablets";
schema = "org.gnome.desktop.peripherals.tablet";
}
else
return NULL;
vendor = clutter_input_device_get_vendor_id (device);
product = clutter_input_device_get_product_id (device);
path = g_strdup_printf ("/org/gnome/desktop/peripherals/%s/%s:%s/",
group, vendor, product);
settings = g_settings_new_with_path (schema, path);
g_free (path);
return settings;
}
static void
monitors_changed_cb (MetaMonitorManager *monitor_manager,
MetaInputSettings *input_settings)
{
MetaInputSettingsPrivate *priv;
ClutterInputDevice *device;
GSettings *settings;
GHashTableIter iter;
priv = meta_input_settings_get_instance_private (input_settings);
g_hash_table_iter_init (&iter, priv->mappable_devices);
while (g_hash_table_iter_next (&iter, (gpointer *) &device,
(gpointer *) &settings))
update_device_display (input_settings, settings, device);
}
static gboolean
check_add_mappable_device (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
MetaInputSettingsPrivate *priv;
DeviceMappingInfo *info;
GSettings *settings;
settings = lookup_device_settings (device);
if (!settings)
return FALSE;
priv = meta_input_settings_get_instance_private (input_settings);
info = g_new0 (DeviceMappingInfo, 1);
info->input_settings = input_settings;
info->device = device;
info->settings = settings;
g_signal_connect_data (settings, "changed",
G_CALLBACK (mapped_device_changed_cb),
info, (GClosureNotify) g_free, 0);
g_hash_table_insert (priv->mappable_devices, device, settings);
update_device_display (input_settings, settings, device);
return TRUE;
}
static void
apply_device_settings (MetaInputSettings *input_settings,
ClutterInputDevice *device)
{
update_mouse_left_handed (input_settings, device);
update_device_speed (input_settings, device);
update_device_natural_scroll (input_settings, device);
update_touchpad_left_handed (input_settings, device);
update_device_speed (input_settings, device);
update_device_natural_scroll (input_settings, device);
update_touchpad_tap_enabled (input_settings, device);
update_touchpad_send_events (input_settings, device);
update_touchpad_edge_scroll (input_settings, device);
update_touchpad_click_method (input_settings, device);
update_trackball_scroll_button (input_settings, device);
}
static void
meta_input_settings_device_added (ClutterDeviceManager *device_manager,
ClutterInputDevice *device,
MetaInputSettings *input_settings)
{
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
return;
apply_device_settings (input_settings, device);
check_add_mappable_device (input_settings, device);
}
static void
meta_input_settings_device_removed (ClutterDeviceManager *device_manager,
ClutterInputDevice *device,
MetaInputSettings *input_settings)
{
MetaInputSettingsPrivate *priv;
priv = meta_input_settings_get_instance_private (input_settings);
g_hash_table_remove (priv->mappable_devices, device);
}
static void
check_mappable_devices (MetaInputSettings *input_settings)
{
MetaInputSettingsPrivate *priv;
const GSList *devices, *l;
priv = meta_input_settings_get_instance_private (input_settings);
devices = clutter_device_manager_peek_devices (priv->device_manager);
for (l = devices; l; l = l->next)
{
ClutterInputDevice *device = l->data;
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
continue;
check_add_mappable_device (input_settings, device);
}
}
static void
meta_input_settings_constructed (GObject *object)
{
MetaInputSettings *input_settings = META_INPUT_SETTINGS (object);
apply_device_settings (input_settings, NULL);
update_keyboard_repeat (input_settings);
check_mappable_devices (input_settings);
}
static void
meta_input_settings_class_init (MetaInputSettingsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = meta_input_settings_dispose;
object_class->constructed = meta_input_settings_constructed;
}
static void
meta_input_settings_init (MetaInputSettings *settings)
{
MetaInputSettingsPrivate *priv;
priv = meta_input_settings_get_instance_private (settings);
priv->device_manager = clutter_device_manager_get_default ();
g_signal_connect (priv->device_manager, "device-added",
G_CALLBACK (meta_input_settings_device_added), settings);
g_signal_connect (priv->device_manager, "device-removed",
G_CALLBACK (meta_input_settings_device_removed), settings);
priv->mouse_settings = g_settings_new ("org.gnome.desktop.peripherals.mouse");
g_signal_connect (priv->mouse_settings, "changed",
G_CALLBACK (meta_input_settings_changed_cb), settings);
priv->touchpad_settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
g_signal_connect (priv->touchpad_settings, "changed",
G_CALLBACK (meta_input_settings_changed_cb), settings);
priv->trackball_settings = g_settings_new ("org.gnome.desktop.peripherals.trackball");
g_signal_connect (priv->trackball_settings, "changed",
G_CALLBACK (meta_input_settings_changed_cb), settings);
priv->keyboard_settings = g_settings_new ("org.gnome.desktop.peripherals.keyboard");
g_signal_connect (priv->keyboard_settings, "changed",
G_CALLBACK (meta_input_settings_changed_cb), settings);
priv->mappable_devices =
g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref);
priv->monitor_manager = g_object_ref (meta_monitor_manager_get ());
g_signal_connect (priv->monitor_manager, "monitors-changed",
G_CALLBACK (monitors_changed_cb), settings);
}
MetaInputSettings *
meta_input_settings_create (void)
{
#ifdef HAVE_NATIVE_BACKEND
MetaBackend *backend;
backend = meta_get_backend ();
if (META_IS_BACKEND_NATIVE (backend))
return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL);
#endif
if (!meta_is_wayland_compositor ())
return g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL);
return NULL;
}

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,7 @@
#ifndef META_MONITOR_CONFIG_H
#define META_MONITOR_CONFIG_H
#include "meta-monitor-manager-private.h"
#include "meta-monitor-manager.h"
#define META_TYPE_MONITOR_CONFIG (meta_monitor_config_get_type ())
#define META_MONITOR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfig))
@ -36,6 +36,9 @@ GType meta_monitor_config_get_type (void) G_GNUC_CONST;
MetaMonitorConfig *meta_monitor_config_new (void);
gboolean meta_monitor_config_match_current (MetaMonitorConfig *config,
MetaMonitorManager *manager);
gboolean meta_monitor_config_apply_stored (MetaMonitorConfig *config,
MetaMonitorManager *manager);

View File

@ -27,10 +27,6 @@
#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
@ -48,69 +44,9 @@ 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 * num_monitors;
manager->screen_width = 1024;
manager->screen_height = 768;
manager->modes = g_new0 (MetaMonitorMode, 1);
@ -121,52 +57,44 @@ 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, num_monitors);
manager->n_crtcs = num_monitors;
manager->outputs = g_new0 (MetaOutput, num_monitors);
manager->n_outputs = num_monitors;
manager->crtcs = g_new0 (MetaCRTC, 1);
manager->n_crtcs = 1;
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->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;
current_x += manager->crtcs[i].rect.width;
manager->outputs = g_new0 (MetaOutput, 1);
manager->n_outputs = 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];
}
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;
}
static void
@ -197,7 +125,7 @@ meta_monitor_manager_dummy_apply_config (MetaMonitorManager *manager,
{
MetaMonitorMode *mode;
MetaOutput *output;
unsigned int j;
int i, n_outputs;
int width, height;
mode = crtc_info->mode;
@ -223,9 +151,10 @@ 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);
for (j = 0; j < crtc_info->outputs->len; j++)
n_outputs = crtc_info->outputs->len;
for (i = 0; i < n_outputs; i++)
{
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
output = ((MetaOutput**)crtc_info->outputs->pdata)[i];
output->is_dirty = TRUE;
output->crtc = crtc;

View File

@ -23,7 +23,7 @@
#ifndef META_MONITOR_MANAGER_DUMMY_H
#define META_MONITOR_MANAGER_DUMMY_H
#include "meta-monitor-manager-private.h"
#include "meta-monitor-manager.h"
#define META_TYPE_MONITOR_MANAGER_DUMMY (meta_monitor_manager_dummy_get_type ())
#define META_MONITOR_MANAGER_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummy))

View File

@ -25,7 +25,7 @@
#include "config.h"
#include "meta-monitor-manager-private.h"
#include "meta-monitor-manager.h"
#include <string.h>
#include <math.h>
@ -35,7 +35,6 @@
#include <meta/main.h>
#include "util-private.h"
#include <meta/errors.h>
#include "edid.h"
#include "meta-monitor-config.h"
#include "backends/x11/meta-monitor-manager-xrandr.h"
#include "meta-backend-private.h"
@ -45,16 +44,10 @@ enum {
SIGNALS_LAST
};
/* Array index matches MetaMonitorTransform */
static gfloat transform_matrices[][6] = {
{ 1, 0, 0, 0, 1, 0 }, /* normal */
{ 0, -1, 1, 1, 0, 0 }, /* 90° */
{ -1, 0, 1, 0, -1, 1 }, /* 180° */
{ 0, 1, 0, -1, 0, 1 }, /* 270° */
{ -1, 0, 1, 0, 1, 0 }, /* normal flipped */
{ 0, 1, 0, 1, 0, 0 }, /* 90° flipped */
{ 1, 0, 0, 0, -1, 1 }, /* 180° flipped */
{ 0, -1, 1, -1, 0, 1 }, /* 270° flipped */
enum {
PROP_0,
PROP_POWER_SAVE_MODE,
PROP_LAST
};
static int signals[SIGNALS_LAST];
@ -71,96 +64,12 @@ 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)
read_current_config (MetaMonitorManager *manager)
{
MetaMonitorInfo info;
unsigned i;
manager->serial++;
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);
META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
}
/*
@ -173,26 +82,16 @@ construct_tile_monitor (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;
monitor_infos = g_array_sized_new (FALSE, TRUE, sizeof (MetaMonitorInfo),
manager->n_crtcs);
manager->n_outputs);
/* Walk the list of MetaCRTCs, and build a MetaMonitorInfo
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];
@ -204,8 +103,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_contains_rect (&info->rect,
&crtc->rect))
if (meta_rectangle_equal (&crtc->rect,
&info->rect))
{
crtc->logical_monitor = info;
break;
@ -217,10 +116,7 @@ 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
@ -230,8 +126,7 @@ 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,
@ -253,9 +148,6 @@ 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);
@ -264,17 +156,8 @@ 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->scale = output->scale;
info->winsys_id = output->winsys_id;
}
info->winsys_id = output->winsys_id;
if (info->is_primary)
manager->primary_monitor_index = info->number;
@ -282,35 +165,6 @@ 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
power_save_mode_changed (MetaMonitorManager *manager,
GParamSpec *pspec,
gpointer user_data)
{
MetaMonitorManagerClass *klass;
int mode = meta_dbus_display_config_get_power_save_mode (META_DBUS_DISPLAY_CONFIG (manager));
if (mode == META_POWER_SAVE_UNSUPPORTED)
return;
/* If DPMS is unsupported, force the property back. */
if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED)
{
meta_dbus_display_config_set_power_save_mode (META_DBUS_DISPLAY_CONFIG (manager), META_POWER_SAVE_UNSUPPORTED);
return;
}
klass = META_MONITOR_MANAGER_GET_CLASS (manager);
if (klass->set_power_save_mode)
klass->set_power_save_mode (manager, mode);
manager->power_save_mode = mode;
}
static void
@ -318,14 +172,11 @@ meta_monitor_manager_constructed (GObject *object)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
g_signal_connect_object (manager, "notify::power-save-mode",
G_CALLBACK (power_save_mode_changed), manager, 0);
manager->in_init = TRUE;
manager->config = meta_monitor_config_new ();
meta_monitor_manager_read_current_config (manager);
read_current_config (manager);
if (!meta_monitor_config_apply_stored (manager->config, manager))
meta_monitor_config_make_default (manager->config, manager);
@ -338,7 +189,24 @@ meta_monitor_manager_constructed (GObject *object)
so this is not needed.
*/
if (META_IS_MONITOR_MANAGER_XRANDR (manager))
meta_monitor_manager_read_current_config (manager);
{
MetaOutput *old_outputs;
MetaCRTC *old_crtcs;
MetaMonitorMode *old_modes;
unsigned int n_old_outputs, n_old_modes;
old_outputs = manager->outputs;
n_old_outputs = manager->n_outputs;
old_modes = manager->modes;
n_old_modes = manager->n_modes;
old_crtcs = manager->crtcs;
read_current_config (manager);
meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
g_free (old_crtcs);
}
make_logical_config (manager);
initialize_dbus_interface (manager);
@ -346,79 +214,63 @@ meta_monitor_manager_constructed (GObject *object)
manager->in_init = FALSE;
}
void
meta_monitor_manager_clear_output (MetaOutput *output)
static void
meta_monitor_manager_set_power_save_mode (MetaMonitorManager *manager,
MetaPowerSave mode)
{
g_free (output->name);
g_free (output->vendor);
g_free (output->product);
g_free (output->serial);
g_free (output->modes);
g_free (output->possible_crtcs);
g_free (output->possible_clones);
MetaMonitorManagerClass *klass;
if (output->driver_notify)
output->driver_notify (output);
if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED ||
mode == META_POWER_SAVE_UNSUPPORTED)
return;
memset (output, 0, sizeof (*output));
klass = META_MONITOR_MANAGER_GET_CLASS (manager);
if (klass->set_power_save_mode)
klass->set_power_save_mode (manager, mode);
manager->power_save_mode = mode;
}
static void
void
meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
int n_old_outputs)
{
int i;
for (i = 0; i < n_old_outputs; i++)
meta_monitor_manager_clear_output (&old_outputs[i]);
{
g_free (old_outputs[i].name);
g_free (old_outputs[i].vendor);
g_free (old_outputs[i].product);
g_free (old_outputs[i].serial);
g_free (old_outputs[i].modes);
g_free (old_outputs[i].possible_crtcs);
g_free (old_outputs[i].possible_clones);
if (old_outputs[i].driver_notify)
old_outputs[i].driver_notify (&old_outputs[i]);
}
g_free (old_outputs);
}
void
meta_monitor_manager_clear_mode (MetaMonitorMode *mode)
{
g_free (mode->name);
if (mode->driver_notify)
mode->driver_notify (mode);
memset (mode, 0, sizeof (*mode));
}
static void
meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
int n_old_modes)
{
int i;
for (i = 0; i < n_old_modes; i++)
meta_monitor_manager_clear_mode (&old_modes[i]);
{
g_free (old_modes[i].name);
if (old_modes[i].driver_notify)
old_modes[i].driver_notify (&old_modes[i]);
}
g_free (old_modes);
}
void
meta_monitor_manager_clear_crtc (MetaCRTC *crtc)
{
if (crtc->driver_notify)
crtc->driver_notify (crtc);
memset (crtc, 0, sizeof (*crtc));
}
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++)
meta_monitor_manager_clear_crtc (&old_crtcs[i]);
g_free (old_crtcs);
}
static void
meta_monitor_manager_finalize (GObject *object)
{
@ -426,8 +278,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);
}
@ -446,6 +298,44 @@ meta_monitor_manager_dispose (GObject *object)
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
}
static void
meta_monitor_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
MetaMonitorManager *self = META_MONITOR_MANAGER (object);
switch (prop_id)
{
case PROP_POWER_SAVE_MODE:
meta_monitor_manager_set_power_save_mode (self, g_value_get_int (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
meta_monitor_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
MetaMonitorManager *self = META_MONITOR_MANAGER (object);
switch (prop_id)
{
case PROP_POWER_SAVE_MODE:
g_value_set_int (value, self->power_save_mode);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static GBytes *
meta_monitor_manager_real_read_edid (MetaMonitorManager *manager,
MetaOutput *output)
@ -466,6 +356,8 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = meta_monitor_manager_constructed;
object_class->get_property = meta_monitor_manager_get_property;
object_class->set_property = meta_monitor_manager_set_property;
object_class->dispose = meta_monitor_manager_dispose;
object_class->finalize = meta_monitor_manager_finalize;
@ -479,6 +371,8 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
g_object_class_override_property (object_class, PROP_POWER_SAVE_MODE, "power-save-mode");
}
static const double known_diagonals[] = {
@ -508,16 +402,15 @@ static char *
make_display_name (MetaMonitorManager *manager,
MetaOutput *output)
{
g_autofree char *inches = NULL;
g_autofree char *vendor_name = NULL;
char *inches = NULL;
char *vendor_name = NULL;
char *ret;
switch (output->connector_type)
if (g_str_has_prefix (output->name, "LVDS") ||
g_str_has_prefix (output->name, "eDP"))
{
case META_CONNECTOR_TYPE_LVDS:
case META_CONNECTOR_TYPE_eDP:
return g_strdup (_("Built-in display"));
default:
break;
ret = g_strdup (_("Built-in display"));
goto out;
}
if (output->width_mm > 0 && output->height_mm > 0)
@ -551,38 +444,18 @@ make_display_name (MetaMonitorManager *manager,
/* TRANSLATORS: this is a monitor vendor name, followed by a
* size in inches, like 'Dell 15"'
*/
return g_strdup_printf (_("%s %s"), vendor_name, inches);
ret = g_strdup_printf (_("%s %s"), vendor_name, inches);
}
else
{
return g_strdup (vendor_name);
ret = g_strdup (vendor_name);
}
}
static const char *
get_connector_type_name (MetaConnectorType connector_type)
{
switch (connector_type)
{
case META_CONNECTOR_TYPE_Unknown: return "Unknown";
case META_CONNECTOR_TYPE_VGA: return "VGA";
case META_CONNECTOR_TYPE_DVII: return "DVII";
case META_CONNECTOR_TYPE_DVID: return "DVID";
case META_CONNECTOR_TYPE_DVIA: return "DVIA";
case META_CONNECTOR_TYPE_Composite: return "Composite";
case META_CONNECTOR_TYPE_SVIDEO: return "SVIDEO";
case META_CONNECTOR_TYPE_LVDS: return "LVDS";
case META_CONNECTOR_TYPE_Component: return "Component";
case META_CONNECTOR_TYPE_9PinDIN: return "9PinDIN";
case META_CONNECTOR_TYPE_DisplayPort: return "DisplayPort";
case META_CONNECTOR_TYPE_HDMIA: return "HDMIA";
case META_CONNECTOR_TYPE_HDMIB: return "HDMIB";
case META_CONNECTOR_TYPE_TV: return "TV";
case META_CONNECTOR_TYPE_eDP: return "eDP";
case META_CONNECTOR_TYPE_VIRTUAL: return "VIRTUAL";
case META_CONNECTOR_TYPE_DSI: return "DSI";
default: g_assert_not_reached ();
}
out:
g_free (inches);
g_free (vendor_name);
return ret;
}
static gboolean
@ -665,12 +538,6 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
g_variant_new_boolean (output->is_primary));
g_variant_builder_add (&properties, "{sv}", "presentation",
g_variant_new_boolean (output->is_presentation));
g_variant_builder_add (&properties, "{sv}", "connector-type",
g_variant_new_string (get_connector_type_name (output->connector_type)));
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)
@ -691,20 +558,6 @@ 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,
@ -902,7 +755,8 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
crtc_info->y = 0;
}
if (transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
if (transform < META_MONITOR_TRANSFORM_NORMAL ||
transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
((crtc->all_transforms & (1 << transform)) == 0))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
@ -972,7 +826,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, underscanning;
gboolean primary, presentation;
if (output_index >= manager->n_outputs)
{
@ -991,9 +845,6 @@ 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);
}
@ -1274,13 +1125,6 @@ initialize_dbus_interface (MetaMonitorManager *manager)
g_object_unref);
}
/**
* meta_monitor_manager_get:
*
* Accessor for the singleton MetaMonitorManager.
*
* Returns: (transfer none): The only #MetaMonitorManager there is.
*/
MetaMonitorManager *
meta_monitor_manager_get (void)
{
@ -1355,238 +1199,20 @@ meta_monitor_manager_get_screen_limits (MetaMonitorManager *manager,
*height = manager->max_screen_height;
}
void
meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
{
MetaOutput *old_outputs;
MetaCRTC *old_crtcs;
MetaMonitorMode *old_modes;
unsigned int n_old_outputs, n_old_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;
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);
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);
}
void
meta_output_parse_edid (MetaOutput *meta_output,
GBytes *edid)
{
MonitorInfo *parsed_edid;
gsize len;
if (!edid)
goto out;
parsed_edid = decode_edid (g_bytes_get_data (edid, &len));
if (parsed_edid)
{
meta_output->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
if (!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");
if (!meta_output->product)
meta_output->product = g_strdup ("unknown");
if (!meta_output->serial)
meta_output->serial = g_strdup ("unknown");
}
void
meta_monitor_manager_on_hotplug (MetaMonitorManager *manager)
{
gboolean applied_config = FALSE;
/* If the monitor has hotplug_mode_update (which is used by VMs), don't bother
* applying our stored configuration, because it's likely the user just resizing
* the window.
*/
if (!meta_monitor_manager_has_hotplug_mode_update (manager))
{
if (meta_monitor_config_apply_stored (manager->config, manager))
applied_config = TRUE;
}
/* If we haven't applied any configuration, apply the default configuration. */
if (!applied_config)
meta_monitor_config_make_default (manager->config, manager);
}
static gboolean
calculate_viewport_matrix (MetaMonitorManager *manager,
MetaOutput *output,
gfloat viewport[6])
{
gfloat x, y, width, height;
if (!output->crtc)
return FALSE;
x = (float) output->crtc->rect.x / manager->screen_width;
y = (float) output->crtc->rect.y / manager->screen_height;
width = (float) output->crtc->rect.width / manager->screen_width;
height = (float) output->crtc->rect.height / manager->screen_height;
viewport[0] = width;
viewport[1] = 0.0f;
viewport[2] = x;
viewport[3] = 0.0f;
viewport[4] = height;
viewport[5] = y;
return TRUE;
}
static inline void
multiply_matrix (float a[6],
float b[6],
float res[6])
{
res[0] = a[0] * b[0] + a[1] * b[3];
res[1] = a[0] * b[1] + a[1] * b[4];
res[2] = a[0] * b[2] + a[1] * b[5] + a[2];
res[3] = a[3] * b[0] + a[4] * b[3];
res[4] = a[3] * b[1] + a[4] * b[4];
res[5] = a[3] * b[2] + a[4] * b[5] + a[5];
}
gboolean
meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
MetaOutput *output,
gfloat matrix[6])
{
gfloat viewport[9];
if (!calculate_viewport_matrix (manager, output, viewport))
return FALSE;
multiply_matrix (viewport, transform_matrices[output->crtc->transform],
matrix);
return TRUE;
}
/**
* meta_monitor_manager_get_output_geometry:
* @manager: A #MetaMonitorManager
* @id: A valid #MetaOutput id
*
* Returns: The monitor index or -1 if @id isn't valid or the output
* isn't associated with a logical monitor.
*/
gint
meta_monitor_manager_get_monitor_for_output (MetaMonitorManager *manager,
guint id)
{
MetaOutput *output;
guint i;
g_return_val_if_fail (META_IS_MONITOR_MANAGER (manager), -1);
g_return_val_if_fail (id < manager->n_outputs, -1);
output = &manager->outputs[id];
if (!output || !output->crtc)
return -1;
for (i = 0; i < manager->n_monitor_infos; i++)
if (meta_rectangle_contains_rect (&manager->monitor_infos[i].rect,
&output->crtc->rect))
return i;
return -1;
}
gint
meta_monitor_manager_get_monitor_at_point (MetaMonitorManager *manager,
gfloat x,
gfloat y)
{
unsigned int i;
for (i = 0; i < manager->n_monitor_infos; i++)
{
MetaMonitorInfo *monitor = &manager->monitor_infos[i];
int left, right, top, bottom;
left = monitor->rect.x;
right = left + monitor->rect.width;
top = monitor->rect.y;
bottom = top + monitor->rect.height;
if ((x >= left) && (x < right) && (y >= top) && (y < bottom))
return i;
}
return -1;
}

View File

@ -41,22 +41,22 @@
#include "display-private.h"
#include <meta/screen.h>
#include "stack-tracker.h"
#include <meta/meta-monitor-manager.h>
#include "meta-display-config-shared.h"
#include "meta-dbus-display-config.h"
#include "meta-cursor.h"
typedef struct _MetaMonitorManagerClass MetaMonitorManagerClass;
typedef struct _MetaMonitorManager MetaMonitorManager;
typedef struct _MetaMonitorConfigClass MetaMonitorConfigClass;
typedef struct _MetaMonitorConfig MetaMonitorConfig;
typedef struct _MetaCRTC MetaCRTC;
typedef struct _MetaOutput MetaOutput;
typedef struct _MetaCRTC MetaCRTC;
typedef struct _MetaMonitorMode MetaMonitorMode;
typedef struct _MetaMonitorInfo MetaMonitorInfo;
typedef struct _MetaCRTCInfo MetaCRTCInfo;
typedef struct _MetaOutputInfo MetaOutputInfo;
typedef struct _MetaTileInfo MetaTileInfo;
typedef enum {
META_MONITOR_TRANSFORM_NORMAL,
@ -69,38 +69,6 @@ typedef enum {
META_MONITOR_TRANSFORM_FLIPPED_270,
} MetaMonitorTransform;
/* This matches the values in drm_mode.h */
typedef enum {
META_CONNECTOR_TYPE_Unknown = 0,
META_CONNECTOR_TYPE_VGA = 1,
META_CONNECTOR_TYPE_DVII = 2,
META_CONNECTOR_TYPE_DVID = 3,
META_CONNECTOR_TYPE_DVIA = 4,
META_CONNECTOR_TYPE_Composite = 5,
META_CONNECTOR_TYPE_SVIDEO = 6,
META_CONNECTOR_TYPE_LVDS = 7,
META_CONNECTOR_TYPE_Component = 8,
META_CONNECTOR_TYPE_9PinDIN = 9,
META_CONNECTOR_TYPE_DisplayPort = 10,
META_CONNECTOR_TYPE_HDMIA = 11,
META_CONNECTOR_TYPE_HDMIB = 12,
META_CONNECTOR_TYPE_TV = 13,
META_CONNECTOR_TYPE_eDP = 14,
META_CONNECTOR_TYPE_VIRTUAL = 15,
META_CONNECTOR_TYPE_DSI = 16,
} MetaConnectorType;
struct _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 */
@ -116,8 +84,6 @@ struct _MetaOutput
CoglSubpixelOrder subpixel_order;
int scale;
MetaConnectorType connector_type;
MetaMonitorMode *preferred_mode;
MetaMonitorMode **modes;
unsigned int n_modes;
@ -144,18 +110,12 @@ struct _MetaOutput
*/
gboolean is_primary;
gboolean is_presentation;
gboolean is_underscanning;
gboolean supports_underscanning;
gpointer driver_private;
GDestroyNotify driver_notify;
/* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
gboolean hotplug_mode_update;
gint suggested_x;
gint suggested_y;
MetaTileInfo tile_info;
};
struct _MetaCRTC
@ -174,11 +134,7 @@ struct _MetaCRTC
/* Used when changing configuration */
gboolean is_dirty;
/* Used by cursor renderer backend */
void *cursor_renderer_private;
gpointer driver_private;
GDestroyNotify driver_notify;
MetaCursorReference *cursor;
};
struct _MetaMonitorMode
@ -195,7 +151,6 @@ struct _MetaMonitorMode
GDestroyNotify driver_notify;
};
#define META_MAX_OUTPUTS_PER_MONITOR 4
/**
* MetaMonitorInfo:
*
@ -211,14 +166,9 @@ 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.
@ -229,12 +179,6 @@ 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];
};
/*
@ -256,13 +200,12 @@ struct _MetaCRTCInfo {
/*
* MetaOutputInfo:
* this is the same as MetaCRTCInfo, but for outputs
* this is the same as MetaOutputInfo, but for CRTCs
*/
struct _MetaOutputInfo {
MetaOutput *output;
gboolean is_primary;
gboolean is_presentation;
gboolean is_underscanning;
};
#define META_TYPE_MONITOR_MANAGER (meta_monitor_manager_get_type ())
@ -352,15 +295,12 @@ struct _MetaMonitorManagerClass
unsigned short *,
unsigned short *,
unsigned short *);
void (*add_monitor) (MetaMonitorManager *,
MetaMonitorInfo *);
void (*delete_monitor) (MetaMonitorManager *,
int monitor_winsys_xid);
};
GType meta_monitor_manager_get_type (void);
MetaMonitorManager *meta_monitor_manager_get (void);
void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager);
MetaMonitorInfo *meta_monitor_manager_get_monitor_infos (MetaMonitorManager *manager,
@ -396,27 +336,14 @@ void meta_monitor_manager_apply_configuration (MetaMonitorManager
void meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
gboolean ok);
void meta_output_parse_edid (MetaOutput *output,
GBytes *edid);
void meta_crtc_info_free (MetaCRTCInfo *info);
void meta_output_info_free (MetaOutputInfo *info);
void meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
int n_old_outputs);
void meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
int n_old_modes);
gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager);
void meta_monitor_manager_read_current_config (MetaMonitorManager *manager);
void meta_monitor_manager_on_hotplug (MetaMonitorManager *manager);
gboolean meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
MetaOutput *output,
gfloat matrix[6]);
gint meta_monitor_manager_get_monitor_at_point (MetaMonitorManager *manager,
gfloat x,
gfloat y);
void meta_monitor_manager_clear_output (MetaOutput *output);
void meta_monitor_manager_clear_mode (MetaMonitorMode *mode);
void meta_monitor_manager_clear_crtc (MetaCRTC *crtc);
/* Returns true if transform causes width and height to be inverted
This is true for the odd transforms in the enum */

View File

@ -1,57 +0,0 @@
/* -*- 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/meta-pointer-constraint.h"
#include <glib-object.h>
G_DEFINE_TYPE (MetaPointerConstraint, meta_pointer_constraint, G_TYPE_OBJECT);
static void
meta_pointer_constraint_init (MetaPointerConstraint *constraint)
{
}
static void
meta_pointer_constraint_class_init (MetaPointerConstraintClass *klass)
{
}
void
meta_pointer_constraint_constrain (MetaPointerConstraint *constraint,
ClutterInputDevice *device,
guint32 time,
float prev_x,
float prev_y,
float *x,
float *y)
{
META_POINTER_CONSTRAINT_GET_CLASS (constraint)->constrain (constraint,
device,
time,
prev_x, prev_y,
x, y);
}

View File

@ -1,60 +0,0 @@
/* -*- 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_POINTER_CONSTRAINT_H
#define META_POINTER_CONSTRAINT_H
#include <glib-object.h>
#include <clutter/clutter.h>
G_BEGIN_DECLS
#define META_TYPE_POINTER_CONSTRAINT (meta_pointer_constraint_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaPointerConstraint, meta_pointer_constraint,
META, POINTER_CONSTRAINT, GObject);
struct _MetaPointerConstraintClass
{
GObjectClass parent_class;
void (*constrain) (MetaPointerConstraint *constraint,
ClutterInputDevice *device,
guint32 time,
float prev_x,
float prev_y,
float *x,
float *y);
};
void meta_pointer_constraint_constrain (MetaPointerConstraint *constraint,
ClutterInputDevice *device,
guint32 time,
float prev_x,
float prev_y,
float *x,
float *y);
G_END_DECLS
#endif /* META_POINTER_CONSTRAINT_H */

View File

@ -24,6 +24,7 @@
#include "meta-stage.h"
#include "meta-cursor-private.h"
#include <meta/meta-backend.h>
#include <meta/util.h>
@ -39,8 +40,8 @@ typedef struct {
} MetaOverlay;
struct _MetaStagePrivate {
MetaOverlay dnd_overlay;
MetaOverlay cursor_overlay;
gboolean is_active;
};
typedef struct _MetaStagePrivate MetaStagePrivate;
@ -112,6 +113,7 @@ meta_stage_finalize (GObject *object)
MetaStage *stage = META_STAGE (object);
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
meta_overlay_free (&priv->dnd_overlay);
meta_overlay_free (&priv->cursor_overlay);
}
@ -123,44 +125,19 @@ meta_stage_paint (ClutterActor *actor)
CLUTTER_ACTOR_CLASS (meta_stage_parent_class)->paint (actor);
meta_overlay_paint (&priv->dnd_overlay);
meta_overlay_paint (&priv->cursor_overlay);
}
static void
meta_stage_activate (ClutterStage *actor)
{
MetaStage *stage = META_STAGE (actor);
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->activate (actor);
priv->is_active = TRUE;
}
static void
meta_stage_deactivate (ClutterStage *actor)
{
MetaStage *stage = META_STAGE (actor);
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->deactivate (actor);
priv->is_active = FALSE;
}
static void
meta_stage_class_init (MetaStageClass *klass)
{
ClutterStageClass *stage_class = (ClutterStageClass *) klass;
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
object_class->finalize = meta_stage_finalize;
actor_class->paint = meta_stage_paint;
stage_class->activate = meta_stage_activate;
stage_class->deactivate = meta_stage_deactivate;
}
static void
@ -168,6 +145,7 @@ meta_stage_init (MetaStage *stage)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
meta_overlay_init (&priv->dnd_overlay);
meta_overlay_init (&priv->cursor_overlay);
clutter_stage_set_user_resizable (CLUTTER_STAGE (stage), FALSE);
@ -209,6 +187,19 @@ queue_redraw_for_overlay (MetaStage *stage,
}
}
void
meta_stage_set_dnd_surface (MetaStage *stage,
CoglTexture *texture,
MetaRectangle *rect)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
g_assert (meta_is_wayland_compositor ());
meta_overlay_set (&priv->dnd_overlay, texture, rect);
queue_redraw_for_overlay (stage, &priv->dnd_overlay);
}
void
meta_stage_set_cursor (MetaStage *stage,
CoglTexture *texture,
@ -221,43 +212,3 @@ meta_stage_set_cursor (MetaStage *stage,
meta_overlay_set (&priv->cursor_overlay, texture, rect);
queue_redraw_for_overlay (stage, &priv->cursor_overlay);
}
void
meta_stage_set_active (MetaStage *stage,
gboolean is_active)
{
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
ClutterEvent event = { 0 };
/* Used by the native backend to inform accessibility technologies
* about when the stage loses and gains input focus.
*
* For the X11 backend, clutter transparently takes care of this
* for us.
*/
if (priv->is_active == is_active)
return;
event.type = CLUTTER_STAGE_STATE;
clutter_event_set_stage (&event, CLUTTER_STAGE (stage));
event.stage_state.changed_mask = CLUTTER_STAGE_STATE_ACTIVATED;
if (is_active)
event.stage_state.new_state = CLUTTER_STAGE_STATE_ACTIVATED;
/* Emitting this StageState event will result in the stage getting
* activated or deactivated (with the activated or deactivated signal
* getting emitted from the stage)
*
* FIXME: This won't update ClutterStage's own notion of its
* activeness. For that we would need to somehow trigger a
* _clutter_stage_update_state call, which will probably
* require new API in clutter. In practice, nothing relies
* on the ClutterStage's own notion of activeness when using
* the EGL backend.
*
* See http://bugzilla.gnome.org/746670
*/
clutter_stage_event (CLUTTER_STAGE (stage), &event);
}

View File

@ -51,12 +51,14 @@ GType meta_stage_get_type (void) G_GNUC_CONST;
ClutterActor *meta_stage_new (void);
void meta_stage_set_dnd_surface (MetaStage *stage,
CoglTexture *texture,
MetaRectangle *rect);
void meta_stage_set_cursor (MetaStage *stage,
CoglTexture *texture,
MetaRectangle *rect);
void meta_stage_set_active (MetaStage *stage,
gboolean is_active);
G_END_DECLS
#endif /* META_STAGE_H */

View File

@ -1,32 +0,0 @@
/* -*- 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_BACKEND_NATIVE_PRIVATE_H
#define META_BACKEND_NATIVE_PRIVATE_H
#include "backends/native/meta-barrier-native.h"
MetaBarrierManagerNative *meta_backend_native_get_barrier_manager (MetaBackendNative *native);
#endif /* META_BACKEND_NATIVE_PRIVATE_H */

View File

@ -24,141 +24,23 @@
#include "config.h"
#include "meta-backend-native.h"
#include "meta-backend-native-private.h"
#include <meta/main.h>
#include <clutter/evdev/clutter-evdev.h>
#include <libupower-glib/upower.h>
#include "meta-backend-native.h"
#include "meta-barrier-native.h"
#include "meta-idle-monitor-native.h"
#include "meta-monitor-manager-kms.h"
#include "meta-cursor-renderer-native.h"
#include "meta-launcher.h"
#include "backends/meta-cursor-tracker-private.h"
#include "backends/meta-pointer-constraint.h"
#include <stdlib.h>
struct _MetaBackendNativePrivate
{
MetaLauncher *launcher;
MetaBarrierManagerNative *barrier_manager;
UpClient *up_client;
guint sleep_signal_id;
GCancellable *cancellable;
GDBusConnection *system_bus;
};
typedef struct _MetaBackendNativePrivate MetaBackendNativePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendNative, meta_backend_native, META_TYPE_BACKEND);
static void
meta_backend_native_finalize (GObject *object)
{
MetaBackendNative *native = META_BACKEND_NATIVE (object);
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
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,
float *new_x,
float *new_y)
{
MetaBackendNative *native = META_BACKEND_NATIVE (meta_get_backend ());
MetaBackendNativePrivate *priv =
meta_backend_native_get_instance_private (native);
meta_barrier_manager_native_process (priv->barrier_manager,
device,
time,
new_x, new_y);
}
static void
constrain_to_client_constraint (ClutterInputDevice *device,
guint32 time,
float prev_x,
float prev_y,
float *x,
float *y)
{
MetaBackend *backend = meta_get_backend ();
MetaPointerConstraint *constraint = backend->client_pointer_constraint;
if (!constraint)
return;
meta_pointer_constraint_constrain (constraint, device,
time, prev_x, prev_y, x, y);
}
/*
* The pointer constrain code is mostly a rip-off of the XRandR code from Xorg.
* (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder)
@ -168,6 +50,31 @@ constrain_to_client_constraint (ClutterInputDevice *device,
*
*/
static gboolean
check_all_screen_monitors(MetaMonitorInfo *monitors,
unsigned n_monitors,
float x,
float y)
{
unsigned int i;
for (i = 0; i < n_monitors; i++)
{
MetaMonitorInfo *monitor = &monitors[i];
int left, right, top, bottom;
left = monitor->rect.x;
right = left + monitor->rect.width;
top = monitor->rect.y;
bottom = left + monitor->rect.height;
if ((x >= left) && (x < right) && (y >= top) && (y < bottom))
return TRUE;
}
return FALSE;
}
static void
constrain_all_screen_monitors (ClutterInputDevice *device,
MetaMonitorInfo *monitors,
@ -177,25 +84,25 @@ constrain_all_screen_monitors (ClutterInputDevice *device,
{
ClutterPoint current;
unsigned int i;
float cx, cy;
clutter_input_device_get_coords (device, NULL, &current);
cx = current.x;
cy = current.y;
/* if we're trying to escape, clamp to the CRTC we're coming from */
for (i = 0; i < n_monitors; i++)
{
MetaMonitorInfo *monitor = &monitors[i];
int left, right, top, bottom;
float nx, ny;
left = monitor->rect.x;
right = left + monitor->rect.width;
top = monitor->rect.y;
bottom = top + monitor->rect.height;
bottom = left + monitor->rect.height;
if ((cx >= left) && (cx < right) && (cy >= top) && (cy < bottom))
nx = current.x;
ny = current.y;
if ((nx >= left) && (nx < right) && (ny >= top) && (ny < bottom))
{
if (*x < left)
*x = left;
@ -213,28 +120,22 @@ constrain_all_screen_monitors (ClutterInputDevice *device,
static void
pointer_constrain_callback (ClutterInputDevice *device,
guint32 time,
float prev_x,
float prev_y,
float *new_x,
float *new_y,
gpointer user_data)
guint32 time,
float *new_x,
float *new_y,
gpointer user_data)
{
MetaMonitorManager *monitor_manager;
MetaMonitorInfo *monitors;
unsigned int n_monitors;
/* Constrain to barriers */
constrain_to_barriers (device, time, new_x, new_y);
/* Constrain to pointer lock */
constrain_to_client_constraint (device, time, prev_x, prev_y, new_x, new_y);
gboolean ret;
monitor_manager = meta_monitor_manager_get ();
monitors = meta_monitor_manager_get_monitor_infos (monitor_manager, &n_monitors);
/* if we're moving inside a monitor, we're fine */
if (meta_monitor_manager_get_monitor_at_point (monitor_manager, *new_x, *new_y) >= 0)
ret = check_all_screen_monitors(monitors, n_monitors, *new_x, *new_y);
if (ret == TRUE)
return;
/* if we're trying to escape, clamp to the CRTC we're coming from */
@ -280,16 +181,11 @@ meta_backend_native_warp_pointer (MetaBackend *backend,
{
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (NULL);
/* XXX */
guint32 time_ = 0;
/* Warp the input device pointer state. */
clutter_evdev_warp_pointer (device, time_, x, y);
/* Warp displayed pointer cursor. */
meta_cursor_tracker_update_position (tracker, x, y);
}
static void
@ -333,29 +229,12 @@ meta_backend_native_lock_layout_group (MetaBackend *backend,
{
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
clutter_evdev_set_keyboard_layout_index (manager, idx);
g_signal_emit_by_name (backend, "keymap-layout-group-changed", idx, 0);
}
static gboolean
meta_backend_native_get_relative_motion_deltas (MetaBackend *backend,
const ClutterEvent *event,
double *dx,
double *dy,
double *dx_unaccel,
double *dy_unaccel)
{
return clutter_evdev_event_get_relative_motion (event,
dx, dy,
dx_unaccel, dy_unaccel);
}
static void
meta_backend_native_class_init (MetaBackendNativeClass *klass)
{
MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = meta_backend_native_finalize;
backend_class->post_init = meta_backend_native_post_init;
backend_class->create_idle_monitor = meta_backend_native_create_idle_monitor;
@ -366,33 +245,15 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
backend_class->set_keymap = meta_backend_native_set_keymap;
backend_class->get_keymap = meta_backend_native_get_keymap;
backend_class->lock_layout_group = meta_backend_native_lock_layout_group;
backend_class->get_relative_motion_deltas = meta_backend_native_get_relative_motion_deltas;
}
static void
meta_backend_native_init (MetaBackendNative *native)
{
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
GError *error = NULL;
priv->launcher = meta_launcher_new (&error);
if (priv->launcher == NULL)
{
g_warning ("Can't initialize KMS backend: %s\n", error->message);
exit (1);
}
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);
/* We're a display server, so start talking to weston-launch. */
priv->launcher = meta_launcher_new ();
}
gboolean
@ -405,20 +266,11 @@ meta_activate_vt (int vt, GError **error)
return meta_launcher_activate_vt (priv->launcher, vt, error);
}
MetaBarrierManagerNative *
meta_backend_native_get_barrier_manager (MetaBackendNative *native)
{
MetaBackendNativePrivate *priv =
meta_backend_native_get_instance_private (native);
return priv->barrier_manager;
}
/**
* meta_activate_session:
*
* Tells mutter to activate the session. When mutter is a
* display server, this tells logind to switch over to
* Wayland compositor, this tells logind to switch over to
* the new session.
*/
gboolean

View File

@ -1,617 +0,0 @@
/* -*- 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>
*/
/**
* SECTION:barrier-native
* @Title: MetaBarrierImplNative
* @Short_Description: Pointer barriers implementation for the native backend
*/
#include "config.h"
#include <stdlib.h>
#include <meta/barrier.h>
#include <meta/util.h>
#include "backends/meta-backend-private.h"
#include "backends/meta-barrier-private.h"
#include "backends/native/meta-backend-native.h"
#include "backends/native/meta-backend-native-private.h"
#include "backends/native/meta-barrier-native.h"
struct _MetaBarrierManagerNative
{
GHashTable *barriers;
};
typedef enum {
/* The barrier is active and responsive to pointer motion. */
META_BARRIER_STATE_ACTIVE,
/* An intermediate state after a pointer hit the pointer barrier. */
META_BARRIER_STATE_HIT,
/* The barrier was hit by a pointer and is still within the hit box and
* has not been released.*/
META_BARRIER_STATE_HELD,
/* The pointer was released by the user. If the following motion hits
* the barrier, it will pass through. */
META_BARRIER_STATE_RELEASE,
/* An intermediate state when the pointer has left the barrier. */
META_BARRIER_STATE_LEFT,
} MetaBarrierState;
struct _MetaBarrierImplNativePrivate
{
MetaBarrier *barrier;
MetaBarrierManagerNative *manager;
gboolean is_active;
MetaBarrierState state;
int trigger_serial;
guint32 last_event_time;
MetaBarrierDirection blocked_dir;
};
G_DEFINE_TYPE_WITH_PRIVATE (MetaBarrierImplNative, meta_barrier_impl_native,
META_TYPE_BARRIER_IMPL)
static int
next_serial (void)
{
static int barrier_serial = 1;
barrier_serial++;
/* If it wraps, avoid 0 as it's not a valid serial. */
if (barrier_serial == 0)
barrier_serial++;
return barrier_serial;
}
static gboolean
is_barrier_horizontal (MetaBarrier *barrier)
{
return meta_border_is_horizontal (&barrier->priv->border);
}
static gboolean
is_barrier_blocking_directions (MetaBarrier *barrier,
MetaBarrierDirection directions)
{
return meta_border_is_blocking_directions (&barrier->priv->border,
directions);
}
static void
dismiss_pointer (MetaBarrierImplNative *self)
{
MetaBarrierImplNativePrivate *priv =
meta_barrier_impl_native_get_instance_private (self);
priv->state = META_BARRIER_STATE_LEFT;
}
/*
* Calculate the hit box for a held motion. The hit box is a 2 px wide region
* in the opposite direction of every direction the barrier blocks. The purpose
* of this is to allow small movements without receiving a "left" signal. This
* heuristic comes from the X.org pointer barrier implementation.
*/
static MetaLine2
calculate_barrier_hit_box (MetaBarrier *barrier)
{
MetaLine2 hit_box = barrier->priv->border.line;
if (is_barrier_horizontal (barrier))
{
if (is_barrier_blocking_directions (barrier,
META_BARRIER_DIRECTION_POSITIVE_Y))
hit_box.a.y -= 2.0f;
if (is_barrier_blocking_directions (barrier,
META_BARRIER_DIRECTION_NEGATIVE_Y))
hit_box.b.y += 2.0f;
}
else
{
if (is_barrier_blocking_directions (barrier,
META_BARRIER_DIRECTION_POSITIVE_X))
hit_box.a.x -= 2.0f;
if (is_barrier_blocking_directions (barrier,
META_BARRIER_DIRECTION_NEGATIVE_X))
hit_box.b.x += 2.0f;
}
return hit_box;
}
static gboolean
is_within_box (MetaLine2 box,
MetaVector2 point)
{
return (point.x >= box.a.x && point.x < box.b.x &&
point.y >= box.a.y && point.y < box.b.y);
}
static void
maybe_release_barrier (gpointer key,
gpointer value,
gpointer user_data)
{
MetaBarrierImplNative *self = key;
MetaBarrierImplNativePrivate *priv =
meta_barrier_impl_native_get_instance_private (self);
MetaBarrier *barrier = priv->barrier;
MetaLine2 *motion = user_data;
MetaLine2 hit_box;
if (priv->state != META_BARRIER_STATE_HELD)
return;
/* Release if we end up outside barrier end points. */
if (is_barrier_horizontal (barrier))
{
if (motion->b.x > MAX (barrier->priv->border.line.a.x,
barrier->priv->border.line.b.x) ||
motion->b.x < MIN (barrier->priv->border.line.a.x,
barrier->priv->border.line.b.x))
{
dismiss_pointer (self);
return;
}
}
else
{
if (motion->b.y > MAX (barrier->priv->border.line.a.y,
barrier->priv->border.line.b.y) ||
motion->b.y < MIN (barrier->priv->border.line.a.y,
barrier->priv->border.line.b.y))
{
dismiss_pointer (self);
return;
}
}
/* Release if we don't intersect and end up outside of hit box. */
hit_box = calculate_barrier_hit_box (barrier);
if (!is_within_box (hit_box, motion->b))
{
dismiss_pointer (self);
return;
}
}
static void
maybe_release_barriers (MetaBarrierManagerNative *manager,
float prev_x,
float prev_y,
float x,
float y)
{
MetaLine2 motion = {
.a = {
.x = prev_x,
.y = prev_y,
},
.b = {
.x = x,
.y = y,
},
};
g_hash_table_foreach (manager->barriers,
maybe_release_barrier,
&motion);
}
typedef struct _MetaClosestBarrierData
{
struct
{
MetaLine2 motion;
MetaBarrierDirection directions;
} in;
struct
{
float closest_distance_2;
MetaBarrierImplNative *barrier_impl;
} out;
} MetaClosestBarrierData;
static void
update_closest_barrier (gpointer key,
gpointer value,
gpointer user_data)
{
MetaBarrierImplNative *self = key;
MetaBarrierImplNativePrivate *priv =
meta_barrier_impl_native_get_instance_private (self);
MetaBarrier *barrier = priv->barrier;
MetaClosestBarrierData *data = user_data;
MetaVector2 intersection;
float dx, dy;
float distance_2;
/* Ignore if the barrier is not blocking in any of the motions directions. */
if (!is_barrier_blocking_directions (barrier, data->in.directions))
return;
/* Ignore if the barrier released the pointer. */
if (priv->state == META_BARRIER_STATE_RELEASE)
return;
/* Ignore if we are moving away from barrier. */
if (priv->state == META_BARRIER_STATE_HELD &&
(data->in.directions & priv->blocked_dir) == 0)
return;
/* Check if the motion intersects with the barrier, and retrieve the
* intersection point if any. */
if (!meta_line2_intersects_with (&barrier->priv->border.line,
&data->in.motion,
&intersection))
return;
/* Calculate the distance to the barrier and keep track of the closest
* barrier. */
dx = intersection.x - data->in.motion.a.x;
dy = intersection.y - data->in.motion.a.y;
distance_2 = dx*dx + dy*dy;
if (data->out.barrier_impl == NULL ||
distance_2 < data->out.closest_distance_2)
{
data->out.barrier_impl = self;
data->out.closest_distance_2 = distance_2;
}
}
static gboolean
get_closest_barrier (MetaBarrierManagerNative *manager,
float prev_x,
float prev_y,
float x,
float y,
MetaBarrierDirection motion_dir,
MetaBarrierImplNative **barrier_impl)
{
MetaClosestBarrierData closest_barrier_data;
closest_barrier_data = (MetaClosestBarrierData) {
.in = {
.motion = {
.a = {
.x = prev_x,
.y = prev_y,
},
.b = {
.x = x,
.y = y,
},
},
.directions = motion_dir,
},
};
g_hash_table_foreach (manager->barriers,
update_closest_barrier,
&closest_barrier_data);
if (closest_barrier_data.out.barrier_impl != NULL)
{
*barrier_impl = closest_barrier_data.out.barrier_impl;
return TRUE;
}
else
{
return FALSE;
}
}
typedef struct _MetaBarrierEventData
{
guint32 time;
float prev_x;
float prev_y;
float x;
float y;
float dx;
float dy;
} MetaBarrierEventData;
static void
emit_barrier_event (MetaBarrierImplNative *self,
guint32 time,
float prev_x,
float prev_y,
float x,
float y,
float dx,
float dy)
{
MetaBarrierImplNativePrivate *priv =
meta_barrier_impl_native_get_instance_private (self);
MetaBarrier *barrier = priv->barrier;
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
MetaBarrierState old_state = priv->state;
switch (priv->state)
{
case META_BARRIER_STATE_HIT:
priv->state = META_BARRIER_STATE_HELD;
priv->trigger_serial = next_serial ();
event->dt = 0;
break;
case META_BARRIER_STATE_RELEASE:
case META_BARRIER_STATE_LEFT:
priv->state = META_BARRIER_STATE_ACTIVE;
/* Intentional fall-through. */
case META_BARRIER_STATE_HELD:
event->dt = time - priv->last_event_time;
break;
case META_BARRIER_STATE_ACTIVE:
g_assert_not_reached (); /* Invalid state. */
}
event->ref_count = 1;
event->event_id = priv->trigger_serial;
event->time = time;
event->x = x;
event->y = y;
event->dx = dx;
event->dy = dy;
event->grabbed = priv->state == META_BARRIER_STATE_HELD;
event->released = old_state == META_BARRIER_STATE_RELEASE;
priv->last_event_time = time;
if (priv->state == META_BARRIER_STATE_HELD)
_meta_barrier_emit_hit_signal (barrier, event);
else
_meta_barrier_emit_left_signal (barrier, event);
meta_barrier_event_unref (event);
}
static void
maybe_emit_barrier_event (gpointer key, gpointer value, gpointer user_data)
{
MetaBarrierImplNative *self = key;
MetaBarrierImplNativePrivate *priv =
meta_barrier_impl_native_get_instance_private (self);
MetaBarrierEventData *data = user_data;
switch (priv->state) {
case META_BARRIER_STATE_ACTIVE:
break;
case META_BARRIER_STATE_HIT:
case META_BARRIER_STATE_HELD:
case META_BARRIER_STATE_RELEASE:
case META_BARRIER_STATE_LEFT:
emit_barrier_event (self,
data->time,
data->prev_x,
data->prev_y,
data->x,
data->y,
data->dx,
data->dy);
break;
}
}
/* Clamp (x, y) to the barrier and remove clamped direction from motion_dir. */
static void
clamp_to_barrier (MetaBarrierImplNative *self,
MetaBarrierDirection *motion_dir,
float *x,
float *y)
{
MetaBarrierImplNativePrivate *priv =
meta_barrier_impl_native_get_instance_private (self);
MetaBarrier *barrier = priv->barrier;
if (is_barrier_horizontal (barrier))
{
if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_Y)
*y = barrier->priv->border.line.a.y;
else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_Y)
*y = barrier->priv->border.line.a.y;
priv->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_Y |
META_BARRIER_DIRECTION_NEGATIVE_Y);
*motion_dir &= ~(META_BARRIER_DIRECTION_POSITIVE_Y |
META_BARRIER_DIRECTION_NEGATIVE_Y);
}
else
{
if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_X)
*x = barrier->priv->border.line.a.x;
else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_X)
*x = barrier->priv->border.line.a.x;
priv->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_X |
META_BARRIER_DIRECTION_NEGATIVE_X);
*motion_dir &= ~(META_BARRIER_DIRECTION_POSITIVE_X |
META_BARRIER_DIRECTION_NEGATIVE_X);
}
priv->state = META_BARRIER_STATE_HIT;
}
void
meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
ClutterInputDevice *device,
guint32 time,
float *x,
float *y)
{
ClutterPoint prev_pos;
float prev_x;
float prev_y;
float orig_x = *x;
float orig_y = *y;
MetaBarrierDirection motion_dir = 0;
MetaBarrierEventData barrier_event_data;
MetaBarrierImplNative *barrier_impl;
if (!clutter_input_device_get_coords (device, NULL, &prev_pos))
return;
prev_x = prev_pos.x;
prev_y = prev_pos.y;
/* Get the direction of the motion vector. */
if (prev_x < *x)
motion_dir |= META_BARRIER_DIRECTION_POSITIVE_X;
else if (prev_x > *x)
motion_dir |= META_BARRIER_DIRECTION_NEGATIVE_X;
if (prev_y < *y)
motion_dir |= META_BARRIER_DIRECTION_POSITIVE_Y;
else if (prev_y > *y)
motion_dir |= META_BARRIER_DIRECTION_NEGATIVE_Y;
/* Clamp to the closest barrier in any direction until either there are no
* more barriers to clamp to or all directions have been clamped. */
while (motion_dir != 0)
{
if (get_closest_barrier (manager,
prev_x, prev_y,
*x, *y,
motion_dir,
&barrier_impl))
clamp_to_barrier (barrier_impl, &motion_dir, x, y);
else
break;
}
/* Potentially release active barrier movements. */
maybe_release_barriers (manager, prev_x, prev_y, *x, *y);
/* Initiate or continue barrier interaction. */
barrier_event_data = (MetaBarrierEventData) {
.time = time,
.prev_x = prev_x,
.prev_y = prev_y,
.x = *x,
.y = *y,
.dx = orig_x - prev_x,
.dy = orig_y - prev_y,
};
g_hash_table_foreach (manager->barriers,
maybe_emit_barrier_event,
&barrier_event_data);
}
static gboolean
_meta_barrier_impl_native_is_active (MetaBarrierImpl *impl)
{
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
MetaBarrierImplNativePrivate *priv =
meta_barrier_impl_native_get_instance_private (self);
return priv->is_active;
}
static void
_meta_barrier_impl_native_release (MetaBarrierImpl *impl,
MetaBarrierEvent *event)
{
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
MetaBarrierImplNativePrivate *priv =
meta_barrier_impl_native_get_instance_private (self);
if (priv->state == META_BARRIER_STATE_HELD &&
event->event_id == priv->trigger_serial)
priv->state = META_BARRIER_STATE_RELEASE;
}
static void
_meta_barrier_impl_native_destroy (MetaBarrierImpl *impl)
{
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
MetaBarrierImplNativePrivate *priv =
meta_barrier_impl_native_get_instance_private (self);
g_hash_table_remove (priv->manager->barriers, self);
priv->is_active = FALSE;
}
MetaBarrierImpl *
meta_barrier_impl_native_new (MetaBarrier *barrier)
{
MetaBarrierImplNative *self;
MetaBarrierImplNativePrivate *priv;
MetaBackendNative *native;
MetaBarrierManagerNative *manager;
self = g_object_new (META_TYPE_BARRIER_IMPL_NATIVE, NULL);
priv = meta_barrier_impl_native_get_instance_private (self);
priv->barrier = barrier;
priv->is_active = TRUE;
native = META_BACKEND_NATIVE (meta_get_backend ());
manager = meta_backend_native_get_barrier_manager (native);
priv->manager = manager;
g_hash_table_add (manager->barriers, self);
return META_BARRIER_IMPL (self);
}
static void
meta_barrier_impl_native_class_init (MetaBarrierImplNativeClass *klass)
{
MetaBarrierImplClass *impl_class = META_BARRIER_IMPL_CLASS (klass);
impl_class->is_active = _meta_barrier_impl_native_is_active;
impl_class->release = _meta_barrier_impl_native_release;
impl_class->destroy = _meta_barrier_impl_native_destroy;
}
static void
meta_barrier_impl_native_init (MetaBarrierImplNative *self)
{
}
MetaBarrierManagerNative *
meta_barrier_manager_native_new (void)
{
MetaBarrierManagerNative *manager;
manager = g_new0 (MetaBarrierManagerNative, 1);
manager->barriers = g_hash_table_new (NULL, NULL);
return manager;
}

View File

@ -1,68 +0,0 @@
/* -*- 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_BARRIER_NATIVE_H
#define META_BARRIER_NATIVE_H
#include "backends/meta-barrier-private.h"
G_BEGIN_DECLS
#define META_TYPE_BARRIER_IMPL_NATIVE (meta_barrier_impl_native_get_type ())
#define META_BARRIER_IMPL_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER_IMPL_NATIVE, MetaBarrierImplNative))
#define META_BARRIER_IMPL_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER_IMPL_NATIVE, MetaBarrierImplNativeClass))
#define META_IS_BARRIER_IMPL_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER_IMPL_NATIVE))
#define META_IS_BARRIER_IMPL_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER_IMPL_NATIVE))
#define META_BARRIER_IMPL_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER_IMPL_NATIVE, MetaBarrierImplNativeClass))
typedef struct _MetaBarrierImplNative MetaBarrierImplNative;
typedef struct _MetaBarrierImplNativeClass MetaBarrierImplNativeClass;
typedef struct _MetaBarrierImplNativePrivate MetaBarrierImplNativePrivate;
typedef struct _MetaBarrierManagerNative MetaBarrierManagerNative;
struct _MetaBarrierImplNative
{
MetaBarrierImpl parent;
};
struct _MetaBarrierImplNativeClass
{
MetaBarrierImplClass parent_class;
};
GType meta_barrier_impl_native_get_type (void) G_GNUC_CONST;
MetaBarrierImpl *meta_barrier_impl_native_new (MetaBarrier *barrier);
MetaBarrierManagerNative *meta_barrier_manager_native_new (void);
void meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
ClutterInputDevice *device,
guint32 time,
float *x,
float *y);
G_END_DECLS
#endif /* META_BARRIER_NATIVE_H */

View File

@ -26,215 +26,95 @@
#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-monitor-manager-private.h"
#include "meta/boxes.h"
#ifndef DRM_CAP_CURSOR_WIDTH
#define DRM_CAP_CURSOR_WIDTH 0x8
#endif
#ifndef DRM_CAP_CURSOR_HEIGHT
#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;
#include "meta-cursor-private.h"
#include "meta-monitor-manager.h"
struct _MetaCursorRendererNativePrivate
{
gboolean has_hw_cursor;
MetaCursorSprite *last_cursor;
guint animation_timeout_id;
int drm_fd;
struct gbm_device *gbm;
uint64_t cursor_width;
uint64_t cursor_height;
};
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,
MetaCursorSprite *cursor_sprite,
MetaCursorReference *cursor,
gboolean force)
{
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
if (cursor_sprite)
if (crtc->cursor == cursor && !force)
return;
crtc->cursor = cursor;
if (cursor)
{
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;
int width, height;
int offset_x, offset_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;
bo = meta_cursor_reference_get_gbm_bo (cursor, &offset_x, &offset_y);
handle = gbm_bo_get_handle (bo);
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
width = gbm_bo_get_width (bo);
height = gbm_bo_get_height (bo);
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;
}
width, height, -offset_x, -offset_y);
}
else
{
if (force || crtc->cursor_renderer_private != NULL)
{
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
crtc->cursor_renderer_private = NULL;
}
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
}
}
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_use_cursor;
MetaCursorSprite *crtc_cursor;
gboolean crtc_should_have_cursor;
MetaCursorReference *crtc_cursor;
MetaRectangle *crtc_rect;
crtc_rect = &crtcs[i].rect;
crtc_should_use_cursor = (priv->has_hw_cursor &&
meta_rectangle_overlap (&rect, crtc_rect));
if (crtc_should_use_cursor)
crtc_cursor = cursor_sprite;
crtc_should_have_cursor = (priv->has_hw_cursor && meta_rectangle_overlap (cursor_rect, crtc_rect));
if (crtc_should_have_cursor)
crtc_cursor = cursor;
else
crtc_cursor = NULL;
@ -243,382 +123,34 @@ update_hw_cursor (MetaCursorRendererNative *native,
if (crtc_cursor)
{
drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
rect.x - crtc_rect->x,
rect.y - crtc_rect->y);
cursor_rect->x - crtc_rect->x,
cursor_rect->y - crtc_rect->y);
}
}
}
static gboolean
has_valid_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
should_have_hw_cursor (MetaCursorRenderer *renderer)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
MetaCursorReference *cursor = meta_cursor_renderer_get_cursor (renderer);
if (!cursor_priv)
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
cursor_over_transformed_crtc (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
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);
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
for (i = 0; i < n_crtcs; i++)
{
if (!meta_rectangle_overlap (&rect, &crtcs[i].rect))
continue;
if (crtcs[i].transform != META_MONITOR_TRANSFORM_NORMAL)
return TRUE;
}
return FALSE;
}
static gboolean
should_have_hw_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
CoglTexture *texture;
if (!cursor_sprite)
return FALSE;
if (cursor_over_transformed_crtc (renderer, 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)
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
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);
priv->has_hw_cursor = should_have_hw_cursor (renderer);
update_hw_cursor (native, 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)
{
@ -627,22 +159,6 @@ 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
@ -650,7 +166,7 @@ on_monitors_changed (MetaMonitorManager *monitors,
MetaCursorRendererNative *native)
{
/* Our tracking is all messed up, so force an update. */
force_update_hw_cursor (native);
update_hw_cursor (native, TRUE);
}
static void
@ -669,20 +185,7 @@ meta_cursor_renderer_native_init (MetaCursorRendererNative *native)
{
CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx));
priv->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
priv->gbm = cogl_kms_renderer_get_gbm (cogl_renderer);
uint64_t width, height;
if (drmGetCap (priv->drm_fd, DRM_CAP_CURSOR_WIDTH, &width) == 0 &&
drmGetCap (priv->drm_fd, DRM_CAP_CURSOR_HEIGHT, &height) == 0)
{
priv->cursor_width = width;
priv->cursor_height = height;
}
else
{
priv->cursor_width = 64;
priv->cursor_height = 64;
}
priv->gbm = gbm_create_device (priv->drm_fd);
}
#endif
}
@ -698,5 +201,5 @@ meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *native)
void
meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
{
force_update_hw_cursor (native);
update_hw_cursor (native, TRUE);
}

Some files were not shown because too many files have changed in this diff Show More