Compare commits

..

13 Commits

Author SHA1 Message Date
08d81b6f7f Bump version to 3.14.2
Update NEWS.
2014-11-12 19:00:56 +01:00
e01077914d configure: Actually make gbm optional
Whoops, I made the code work without it, but forgot to strip it from the
actual list of requires packages.

Spotted-by: Rico Tzschichholz <ricotz@ubuntu.com>
2014-11-10 14:54:31 +01:00
d7cf6bed63 Make gbm optional
Now it's only required by the native backend. The cursor code is getting
quite messy, but it was already considerable messy to start with.
2014-11-10 14:54:11 +01:00
d071ba8446 cursor: Clean up code flow slightly
Reverse the set of expressions so testing for gbm is at the top.
2014-11-10 14:53:19 +01:00
4d08e89c16 xrandr: ignore hotplug_mode_update value
The important thing is whether this property exists or not, but the value
doesn't matter.
2014-11-05 16:36:24 -06:00
21d8c4b032 monitor-manager: Don't try to match the outputs on hotplug
meta_monitor_config_match_current() only matches the number of outputs
and if the output connector, vendor, product and serial match.

This means that we can't use it to bypass doing any
work because it won't detect cases where we actually want to update
ourselves like e.g. an output being turned off either by us or by
another X client (e.g. xrandr).

https://bugzilla.gnome.org/show_bug.cgi?id=738630
2014-11-05 15:51:26 +01:00
c98686da92 monitor-config: Prevent a crash applying config for a closed lid
When a laptop's lid is closed we try to build and apply a temporary
configuration that disables the laptop's display if we have other
outputs.

This isn't enough though, we must also check if at least one of these
other outputs is enabled otherwise we'll try to resize the screen to
0x0 which (rightfully) hits an assertion.

https://bugzilla.gnome.org/show_bug.cgi?id=739450
2014-10-31 17:38:29 +01:00
a19eda5ae7 Bump version to 3.14.1.5
Update NEWS.
2014-10-30 11:01:04 +00:00
0a9bbe0109 meta-wayland-surface: Correcly scale the input region
The input region currently only gets scaled by the surface
scale while ignoring the output scale, which causes input events to not get
delivered correctly for clients on hidpi screens. So take the output scale
into account when doing so.

https://bugzilla.gnome.org/show_bug.cgi?id=739161
2014-10-27 18:13:00 +01:00
a8eb42e43c Revert "wayland-surface: Apply the surface scale only if needed"
This commit is wrong, it assumes that the scale only applies to the one
set by the client but its not. meta_surface_actor_wayland_scale_texture
also handles the output scale. Revert the commit to fix hidpi for wayland
clients like weston-terminal.

This reverts commit 0364ea9140.

https://bugzilla.gnome.org/show_bug.cgi?id=739161
2014-10-27 18:12:52 +01:00
9d0c9f1f42 Updated Slovak translation 2014-10-19 17:43:23 +00:00
9fa0743394 Remove unused variable 2014-10-16 11:00:51 +02:00
bb79a20fac display: Fix accidental inversion from 2f9c601
Commit 2f9c601 accidentally changed the logic here, changing the grab
behavior when not using raise-on-click. Fix this.

Spotted-by: Adam Goode <adam@spicenitz.org>
2014-10-15 23:54:20 +02:00
264 changed files with 73640 additions and 47793 deletions

21
.gitignore vendored
View File

@ -46,7 +46,6 @@ 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
@ -58,23 +57,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

377
NEWS
View File

@ -1,375 +1,20 @@
3.20.0
3.14.2
======
* 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]
* Misc. fixes [Rui, Jonathon, Jasper; #738630]
Contributors:
Emmanuele Bassi, Carlos Garnacho, Jonathon Jongsma, Ting-Wei Lan, Rui Matos,
Florian Müllner, Bastien Nocera, Jasper St. Pierre, Ray Strode
Jonathon Jongsma, Rui Matos, Jasper St. Pierre
3.14.1.5
========
* Fix wayland hiDPI regressions [Adel; #739161]
Contributors:
Adel Gadllah, Florian Müllner, Jasper St. Pierre
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
Dušan Kazik [sk]
3.14.1
======

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], [14])
m4_define([mutter_micro_version], [2])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])
@ -46,25 +46,37 @@ 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
cogl-1.0 >= 1.17.1
upower-glib >= 0.99.0
gnome-desktop-3.0
@ -78,7 +90,6 @@ MUTTER_PC_MODULES="
xkeyboard-config
xkbcommon >= 0.4.3
xkbcommon-x11
xrender
x11-xcb
xcb-randr
"
@ -189,43 +200,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, [clutter-egl-1.0 libdrm libsystemd libinput gbm >= 10.3], [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 +266,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 +312,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 +385,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 +416,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

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

@ -0,0 +1,171 @@
## 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)
if !HAVE_WAYLAND
IGNORE_HFILES += \
meta-surface-actor-wayland.h \
wayland \
$(NULL)
endif
MKDB_OPTIONS+=--ignore-files="$(IGNORE_HFILES)"
# Images to copy into HTML directory.
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
HTML_IMAGES=
# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
content_files= \
mutter-overview.xml \
running-mutter.xml \
$(NULL)
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
# These files must be listed here *and* in content_files
# e.g. expand_content_files=running.sgml
expand_content_files= \
mutter-overview.xml \
running-mutter.xml \
$(NULL)
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
# signals and properties.
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS=$(MUTTER_CFLAGS)
GTKDOC_LIBS=$(MUTTER_LIBS) $(top_builddir)/src/libmutter.la
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make
# Other files to distribute
# e.g. EXTRA_DIST += version.xml.in
EXTRA_DIST +=
# Files not to distribute
# for --rebuild-types in $(SCAN_OPTIONS), e.g. $(DOC_MODULE).types
# for --rebuild-sections in $(SCAN_OPTIONS) e.g. $(DOC_MODULE)-sections.txt
DISTCLEANFILES = $(DOC_MODULES).types
# Comment this out if you want 'make check' to test you doc status
# and run some sanity checks
if ENABLE_GTK_DOC
TESTS_ENVIRONMENT = cd $(srcdir) && \
DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
#TESTS = $(GTKDOC_CHECK)
endif
-include $(top_srcdir)/git.mk

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

766
po/bg.po
View File

@ -1,9 +1,9 @@
# Bulgarian translation of mutter po-file.
# Copyright (C) 2002, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
# Copyright (C) 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
# Copyright (C) 2014, 2015 Free Software Foundation, Inc.
# Copyright (C) 2014 Free Software Foundation, Inc.
# Alexander Shopov <ash@kambanaria.org>, 2002, 2006, 2007, 2009, 2010.
# Alexander Shopov <ash@kambanaria.org>, 2011, 2012, 2013, 2014, 2015.
# Alexander Shopov <ash@kambanaria.org>, 2011, 2012, 2013, 2014.
# Vladimir Petkov <kaladan@gmail.com>, 2004.
# Rostislav Raykov <zbrox@i-space.org>, 2004.
# Yavor Doganov <yavor@gnu.org>, 2008.
@ -12,8 +12,8 @@ msgid ""
msgstr ""
"Project-Id-Version: mutter master\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-03-10 09:51+0200\n"
"PO-Revision-Date: 2015-03-10 09:51+0200\n"
"POT-Creation-Date: 2014-09-25 06:27+0300\n"
"PO-Revision-Date: 2014-09-25 06:27+0300\n"
"Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
"Language-Team: Bulgarian <dict@fsa-bg.org>\n"
"Language: bg\n"
@ -437,49 +437,29 @@ msgstr "Превключване към виртуална графична ко
msgid "Switch to VT 7"
msgstr "Превключване към виртуална графична конзола 7"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
msgid "Switch to VT 8"
msgstr "Превключване към виртуална графична конзола 8"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
msgid "Switch to VT 9"
msgstr "Превключване към виртуална графична конзола 9"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
msgid "Switch to VT 10"
msgstr "Превключване към виртуална графична конзола 10"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
msgid "Switch to VT 11"
msgstr "Превключване към виртуална графична конзола 11"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
msgid "Switch to VT 12"
msgstr "Превключване към виртуална графична конзола 12"
#: ../src/backends/meta-monitor-manager.c:364
#: ../src/backends/meta-monitor-manager.c:412
msgid "Built-in display"
msgstr "Вграден екран"
#: ../src/backends/meta-monitor-manager.c:391
#: ../src/backends/meta-monitor-manager.c:437
msgid "Unknown"
msgstr "Непознат"
#: ../src/backends/meta-monitor-manager.c:393
#: ../src/backends/meta-monitor-manager.c:439
msgid "Unknown Display"
msgstr "Непознат екран"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c:401
#: ../src/backends/meta-monitor-manager.c: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"
@ -515,7 +495,7 @@ msgstr "Из_чакване"
msgid "_Force Quit"
msgstr "_Принудително спиране"
#: ../src/core/display.c:562
#: ../src/core/display.c:547
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Неуспешно отваряне на дисплея на X Window „%s“\n"
@ -554,6 +534,19 @@ msgstr "Wayland да е мениджър за наслагване"
msgid "Run as a full display server, rather than nested"
msgstr "Изпълнение като самостоятелен, а не вграден сървър за изобразяване"
#: ../src/core/main.c:451
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Неуспешно сканиране на папката с темите: %s\n"
#: ../src/core/main.c:467
#, c-format
msgid ""
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
msgstr ""
"Не е открита тема! Проверете дали папката „%s“ съществува и съдържа "
"обичайните теми.\n"
#: ../src/core/mutter.c:39
#, c-format
msgid ""
@ -578,29 +571,718 @@ msgstr "Отпечатване на версията на програмата"
msgid "Mutter plugin to use"
msgstr "Приставка, която да се ползва"
#: ../src/core/prefs.c:2004
#: ../src/core/prefs.c:2065
#, c-format
msgid "Workspace %d"
msgstr "Работен плот %d"
#: ../src/core/screen.c:525
#, c-format
msgid ""
"Display \"%s\" already has a window manager; try using the --replace option "
"to replace the current window manager."
msgstr ""
"Вече има мениджър на прозорци на дисплей „%s“. Пробвайте да го замените с "
"опцията „--replace“."
#: ../src/core/screen.c:607
#: ../src/core/screen.c:543
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Екранът %d на дисплей „%s“ е невалиден\n"
#: ../src/core/screen.c:559
#, 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 ""
"Екранът %d на дисплей „%s“ вече има мениджър на прозорци; пробвайте да го "
"замените с опцията --replace.\n"
#: ../src/core/screen.c:652
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "Екран %d на дисплей „%s“ вече има мениджър за прозорци\n"
#: ../src/core/util.c:118
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Mutter е компилиран без поддръжка на подробен режим\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×%d"
#: ../src/ui/theme.c:233
msgid "top"
msgstr "горния"
#: ../src/ui/theme.c:235
msgid "bottom"
msgstr "долния"
#: ../src/ui/theme.c:237
msgid "left"
msgstr "левия"
#: ../src/ui/theme.c:239
msgid "right"
msgstr "десния"
#: ../src/ui/theme.c:267
#, c-format
msgid "frame geometry does not specify \"%s\" dimension"
msgstr "геометрията на рамката не указва %s размер"
#: ../src/ui/theme.c:286
#, c-format
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
msgstr "геометрията на рамката не указва %s размер на %s ръб"
#: ../src/ui/theme.c:323
#, c-format
msgid "Button aspect ratio %g is not reasonable"
msgstr "Отношението на размерите на бутона %g е неподходящо"
#: ../src/ui/theme.c:335
#, c-format
msgid "Frame geometry does not specify size of buttons"
msgstr "Геометрията на рамката не указва размера на бутоните"
#: ../src/ui/theme.c:1061
#, c-format
msgid "Gradients should have at least two colors"
msgstr "Преливките трябва да имат поне два цвята"
#: ../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 ""
"Цветовата спецификация на GTK трябва да съдържа в скоби име на основен и "
"резервен цвят: напр. gtk:custom(foo,bar). Неуспешен анализ на „%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 ""
"Неправилен знак „%c“ в параметъра за име на цвят (color_name) на gtk:custom. "
"Позволени са само A-Za-z0-9-_."
#: ../src/ui/theme.c:1241
#, c-format
msgid ""
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
"fit the format"
msgstr ""
"Форматът на Gtk:custom е „gtk:custom(основен_цвят,резервен_цвят)“, „%s“ не "
"съответства на формата"
#: ../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 ""
"Цветовата спецификация на GTK трябва да указва състоянието в квадратни "
"скоби, напр. gtk:fg[NORMAL], където NORMAL е състоянието. Неуспешен анализ "
"на „%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 ""
"Цветовата спецификация на GTK трябва да съдържа квадратна скоба след "
"състоянието, напр. gtk:fg[NORMAL], където NORMAL е състоянието. Неуспешен "
"анализ на „%s“"
#: ../src/ui/theme.c:1311
#, c-format
msgid "Did not understand state \"%s\" in color specification"
msgstr "Неуспешен анализ на състоянието „%s“ в цветовата спецификация"
#: ../src/ui/theme.c:1324
#, c-format
msgid "Did not understand color component \"%s\" in color specification"
msgstr "Неуспешен анализ на цветови компонент „%s“ в цветовата спецификация"
#: ../src/ui/theme.c:1352
#, c-format
msgid ""
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
"format"
msgstr ""
"Форматът на смесването е „blend/bg_color/fg_color/alpha“, „%s“ не се "
"подчинява на форма̀та"
#: ../src/ui/theme.c:1363
#, c-format
msgid "Could not parse alpha value \"%s\" in blended color"
msgstr "Неуспешен анализ на алфа стойността „%s“ в смесения цвят"
#: ../src/ui/theme.c:1373
#, c-format
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
msgstr "Алфа стойността „%s“ в смесения цвят не е между 0.0 и 1.0"
#: ../src/ui/theme.c:1419
#, c-format
msgid ""
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
msgstr ""
"Форматът на навиването е един от „shade“/„base_color“/„factor“, „%s“ не "
"съответства на формата"
#: ../src/ui/theme.c:1430
#, c-format
msgid "Could not parse shade factor \"%s\" in shaded color"
msgstr "Неуспешен анализа на фактора на навиването „%s“ в цвета за навиване"
#: ../src/ui/theme.c:1440
#, c-format
msgid "Shade factor \"%s\" in shaded color is negative"
msgstr "Факторът на навиване „%s“ в цвета за сянката е отрицателен"
#: ../src/ui/theme.c:1469
#, c-format
msgid "Could not parse color \"%s\""
msgstr "Неуспешен анализ на цвета „%s“"
#: ../src/ui/theme.c:1778
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr "Изразът за координати съдържа символа „%s“, който не е позволен"
#: ../src/ui/theme.c:1805
#, c-format
msgid ""
"Coordinate expression contains floating point number '%s' which could not be "
"parsed"
msgstr ""
"Изразът за координати съдържа числото с плаваща запетая „%s“, което не може "
"да бъде анализирано"
#: ../src/ui/theme.c:1819
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr ""
"Изразът за координати съдържа цялото число „%s“, което не може да бъде "
"анализирано"
#: ../src/ui/theme.c:1940
#, c-format
msgid ""
"Coordinate expression contained unknown operator at the start of this text: "
"\"%s\""
msgstr ""
"Изразът за координати съдържа непознат оператор в началото на този текст: "
"„%s“"
#: ../src/ui/theme.c:1997
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr "Изразът за координати бе празен или не бе разбран"
#: ../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 "Изразът за координати дава деление на нула"
#: ../src/ui/theme.c:2162
#, c-format
msgid ""
"Coordinate expression tries to use mod operator on a floating-point number"
msgstr ""
"Изразът за координати използва оператора mod върху число с плаваща запетая"
#: ../src/ui/theme.c:2218
#, c-format
msgid ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
msgstr ""
"Изразът за координати използва оператора „%s“ на място, където се очаква "
"операнд"
#: ../src/ui/theme.c:2227
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr ""
"Изразът за координати използва оператор на място, където се очаква операнд"
#: ../src/ui/theme.c:2235
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr "Изразът за координати завършва с оператор вместо с операнд"
#: ../src/ui/theme.c:2245
#, c-format
msgid ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
"operand in between"
msgstr ""
"Изразът за координати използва оператора „%c“ след „%c“ без да има операнд "
"между тях"
#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr ""
"Изразът за координати използва непознатата променлива или константа „%s“"
#: ../src/ui/theme.c:2495
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr "Анализаторът на изрази за координати препълни буфера си."
#: ../src/ui/theme.c:2524
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr "В израза за координати има затваряща скоба без съответна отваряща"
#: ../src/ui/theme.c:2588
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr "В израза за координати има отваряща скоба без съответна затваряща"
#: ../src/ui/theme.c:2599
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr "Изразът за координати не съдържа нито оператори, нито операнди"
#: ../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 "Темата съдържа израз, който даде грешка: %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=\"нещо си\"/>"
#: ../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=\"нещо си\"/>"
#: ../src/ui/theme.c:5041
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "Неуспешно зареждане на темата „%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 "Не е даден елементът <%s> за темата „%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 ""
"Няма указан стил на рамката за „%s“ прозорците в тема „%s“. Добавете елемент "
"<window type=\"%s\" style_set=\"нещо си\"/>"
#: ../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 ""
"Константите определени от потребителя трябва да започват с главна буква, а "
"„%s“ не започва така"
#: ../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 "Константата „%s“ вече е дефинирана"
#. 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 "Елементът <%s> няма атрибут „%s“"
#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281
#, c-format
msgid "Line %d character %d: %s"
msgstr "Ред %d, знак %d: %s"
#: ../src/ui/theme-parser.c:481
#, c-format
msgid "Attribute \"%s\" repeated twice on the same <%s> element"
msgstr "Атрибутът „%s“ се повтаря два пъти в един елемент <%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 "Атрибутът „%s“ е невалиден за елемента <%s> в този контекст"
#: ../src/ui/theme-parser.c:596
#, c-format
msgid "Could not parse \"%s\" as an integer"
msgstr "„%s“ не може да се анализира като цяло число"
#: ../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 "Крайните символи „%s“ в низа „%s“ са неразбираеми"
#: ../src/ui/theme-parser.c:615
#, c-format
msgid "Integer %ld must be positive"
msgstr "Цялото число %ld трябва да е положително"
#: ../src/ui/theme-parser.c:623
#, c-format
msgid "Integer %ld is too large, current max is %d"
msgstr "Цялото число %ld е прекалено голямо, максимумът е %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 "„%s“ не може да се интерпретира като число с плаваща запетая"
#: ../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 ""
"Булевите стойности са или „true“ (истина), или „false“ (лъжа). Не са „%s“"
#: ../src/ui/theme-parser.c:737
#, c-format
msgid "Angle must be between 0.0 and 360.0, was %g\n"
msgstr "Ъгълът трябва да е между 0.0 и 360.0, а е %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 ""
"Алфа трябва да е между 0.0 (пълна прозрачност) и 1.0 (пълна непрозрачност), "
"а е %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 ""
"Невалидно увеличение на заглавието „%s“ (трябва да е едно от „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 "Името „%2$s“ на <%1$s> е използвано втори път"
#: ../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 "Родителят „%2$s“ на <%1$s> не е дефиниран"
#: ../src/ui/theme-parser.c:1143
#, c-format
msgid "<%s> geometry \"%s\" has not been defined"
msgstr "Геометрията „%2$s“ на <%1$s> не е дефинирана"
#: ../src/ui/theme-parser.c:1156
#, c-format
msgid "<%s> must specify either a geometry or a parent that has a geometry"
msgstr "<%s> трябва да указва или геометрия, или родител с геометрия"
#: ../src/ui/theme-parser.c:1198
msgid "You must specify a background for an alpha value to be meaningful"
msgstr "За да бъде алфа стойността валидна, трябва да е указан фон"
#: ../src/ui/theme-parser.c:1266
#, c-format
msgid "Unknown type \"%s\" on <%s> element"
msgstr "Непознат вид „%s“ на елемента <%s>"
#: ../src/ui/theme-parser.c:1277
#, c-format
msgid "Unknown style_set \"%s\" on <%s> element"
msgstr "Непознат style_set „%s“ на елемента <%s>"
#: ../src/ui/theme-parser.c:1285
#, c-format
msgid "Window type \"%s\" has already been assigned a style set"
msgstr "Видът прозорци „%s“ вече има установен вид на стила"
#: ../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 "Елементът <%s> не е позволен под <%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 ""
"Не може да се указват едновременно и двата размера („button_width“, "
"„button_height“ — височина и широчина на бутоните), и съотношението на "
"размерите им — „aspect_ratio“"
#: ../src/ui/theme-parser.c:1452
#, c-format
msgid "Distance \"%s\" is unknown"
msgstr "Разстоянието „%s“ е неизвестно"
#: ../src/ui/theme-parser.c:1497
#, c-format
msgid "Aspect ratio \"%s\" is unknown"
msgstr "Пропорцията „%s“ е неизвестна"
#: ../src/ui/theme-parser.c:1559
#, c-format
msgid "Border \"%s\" is unknown"
msgstr "Границата „%s“ е непозната"
#: ../src/ui/theme-parser.c:1870
#, c-format
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
msgstr "Елементът <%s> няма атрибут „start_angle“ или „from“"
#: ../src/ui/theme-parser.c:1877
#, c-format
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
msgstr "Елементът <%s> няма атрибут „extent_angle“ или „to“"
#: ../src/ui/theme-parser.c:2117
#, c-format
msgid "Did not understand value \"%s\" for type of gradient"
msgstr "Стойността „%s“ не може да се анализира като вид градиент"
#: ../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 "Непознато запълване „%s“ за елемента <%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 "Неуспешен анализ на състоянието „%s“ на елемента <%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 "Неуспешен анализ на сянката „%s“ на елемента <%s>"
#: ../src/ui/theme-parser.c:2382
#, c-format
msgid "Did not understand arrow \"%s\" for <%s> element"
msgstr "Неуспешен анализ на стрелката „%s“ на елемента <%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 "Няма дефинирани <draw_ops> с име „%s“"
#: ../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 "Включването на draw_ops „%s“ тук би предизвикало циклична зависимост"
#: ../src/ui/theme-parser.c:2919
#, c-format
msgid "Unknown position \"%s\" for frame piece"
msgstr "Непозната позиция „%s“ за елемент на рамката"
#: ../src/ui/theme-parser.c:2927
#, c-format
msgid "Frame style already has a piece at position %s"
msgstr "Стилът на рамката вече има елемент на позицията %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 "Няма дефиниран <draw_ops> с името „%s“"
#: ../src/ui/theme-parser.c:2974
#, c-format
msgid "Unknown function \"%s\" for button"
msgstr "Непозната функция „%s“ за бутона"
#: ../src/ui/theme-parser.c:2984
#, c-format
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
msgstr ""
"Функцията на бутона „%s“ не съществува в тази версия (%d, а трябва да е %d)"
#: ../src/ui/theme-parser.c:2996
#, c-format
msgid "Unknown state \"%s\" for button"
msgstr "Непознато състояние „%s“ за бутона"
#: ../src/ui/theme-parser.c:3004
#, c-format
msgid "Frame style already has a button for function %s state %s"
msgstr "Стилът на рамката има бутон за функция %s, състояние %s"
#: ../src/ui/theme-parser.c:3075
#, c-format
msgid "\"%s\" is not a valid value for focus attribute"
msgstr "„%s“ не е валидна стойност за атрибута фокус"
#: ../src/ui/theme-parser.c:3084
#, c-format
msgid "\"%s\" is not a valid value for state attribute"
msgstr "„%s“ не е валидна стойност за атрибута състояние"
#: ../src/ui/theme-parser.c:3094
#, c-format
msgid "A style called \"%s\" has not been defined"
msgstr "Не е дефиниран стил на име „%s“"
#: ../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“ не е валидна стойност за атрибута оразмеряване"
#: ../src/ui/theme-parser.c:3149
#, c-format
msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
"states"
msgstr ""
"Елементът <%s> не трябва да има атрибут „resize“ за състоянията максимизиран/"
"засенчен"
#: ../src/ui/theme-parser.c:3163
#, c-format
msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized states"
msgstr ""
"Елементът <%s> не трябва да има атрибут „resize“ за състоянието максимизиран"
#: ../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 "Вече е указан стил за състояние %s, оразмеряване %s, фокус %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 "Вече е указан стил за състояние %s, фокус %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 ""
"Не може да има два draw_ops за елемент <piece> (темата е указала атрибут "
"draw_ops и елемент <draw_ops> или два елемента)"
#: ../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 ""
"Не може да има два draw_ops за елемент <button> (темата е указала атрибут "
"draw_ops и елемент <draw_ops> или два елемента)"
#: ../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 ""
"Не може да има два draw_ops за елемент <menu_icon> (темата е указала атрибут "
"draw_ops и елемент <draw_ops> или два елемента)"
#: ../src/ui/theme-parser.c:3433
#, c-format
msgid "Bad version specification '%s'"
msgstr "Неправилна версия „%s“"
#: ../src/ui/theme-parser.c:3506
msgid ""
"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
"theme-2.xml"
msgstr ""
"Атрибутът „version“ (версия) не може да се използва в in metacity-theme-1."
"xml или 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 "Темата изисква версия %s, но най-високата поддържана версия е %d.%d"
#: ../src/ui/theme-parser.c:3561
#, c-format
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
msgstr "Най-външният елемент в темата трябва да е <metacity_theme>, а не <%s>"
#: ../src/ui/theme-parser.c:3581
#, c-format
msgid ""
"Element <%s> is not allowed inside a name/author/date/description element"
msgstr "Елементът <%s> не е разрешен в елементите name/author/date/description"
#: ../src/ui/theme-parser.c:3586
#, c-format
msgid "Element <%s> is not allowed inside a <constant> element"
msgstr "Елементът <%s> не е позволен в <constant> елемент"
#: ../src/ui/theme-parser.c:3598
#, c-format
msgid ""
"Element <%s> is not allowed inside a distance/border/aspect_ratio element"
msgstr "Елементът <%s> не е позволен в елемент distance/border/aspect_ratio"
#: ../src/ui/theme-parser.c:3620
#, c-format
msgid "Element <%s> is not allowed inside a draw operation element"
msgstr "Елементът <%s> не е позволен в елемент с операция за чертане"
#: ../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 "Елементът <%s> не е позволен в елемент <%s>"
#: ../src/ui/theme-parser.c:3898
msgid "No draw_ops provided for frame piece"
msgstr "Няма draw_ops за детайл от рамката"
#: ../src/ui/theme-parser.c:3913
msgid "No draw_ops provided for button"
msgstr "Няма draw_ops за бутон"
#: ../src/ui/theme-parser.c:3967
#, c-format
msgid "No text is allowed inside element <%s>"
msgstr "Не е позволен текст в елемента <%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> е указан два пъти за тази тема"
#: ../src/ui/theme-parser.c:4335
#, c-format
msgid "Failed to find a valid file for theme %s\n"
msgstr "Не е намерен валиден файл за темата %s\n"
#: ../src/x11/session.c:1815
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
@ -609,7 +1291,7 @@ msgstr ""
"Тези прозорци не поддържат операцията по записване на текущото състояние и "
"ще трябва да се стартират ръчно при следващото ви влизане."
#: ../src/x11/window-props.c:549
#: ../src/x11/window-props.c:558
#, c-format
msgid "%s (on %s)"
msgstr "%s (от %s)"

3797
po/bs.po

File diff suppressed because it is too large Load Diff

1286
po/ca.po

File diff suppressed because it is too large Load Diff

1342
po/cs.po

File diff suppressed because it is too large Load Diff

1261
po/da.po

File diff suppressed because it is too large Load Diff

1307
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

1248
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

1247
po/he.po

File diff suppressed because it is too large Load Diff

1291
po/hu.po

File diff suppressed because it is too large Load Diff

764
po/id.po
View File

@ -5,21 +5,21 @@
# Mohammad DAMT <mdamt@bisnisweb.com>, 2003-2005.
# Ahmad Riza H Nst <rizahnst@eriagempita.co.id>, 2006.
# Dirgita <dirgitadevina@yahoo.co.id>, 2011, 2012, 2014.
# Andika Triwidada <andika@gmail.com>, 2011-2015.
# Andika Triwidada <andika@gmail.com>, 2011, 2012, 2013, 2014.
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: 2015-03-21 11:13+0000\n"
"PO-Revision-Date: 2015-03-21 19:04+0700\n"
"POT-Creation-Date: 2014-09-01 21:52+0000\n"
"PO-Revision-Date: 2014-09-03 20:56+0700\n"
"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
"Language-Team: Indonesian <gnome-l10n-id@googlegroups.com>\n"
"Language: id\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.7.1\n"
"X-Generator: Poedit 1.6.9\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: ../data/50-mutter-navigation.xml.in.h:1
@ -434,49 +434,29 @@ msgstr "Pindah ke VT 6"
msgid "Switch to VT 7"
msgstr "Pindah ke VT 7"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
msgid "Switch to VT 8"
msgstr "Pindah ke VT 8"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
msgid "Switch to VT 9"
msgstr "Pindah ke VT 9"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
msgid "Switch to VT 10"
msgstr "Pindah ke VT 10"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
msgid "Switch to VT 11"
msgstr "Pindah ke VT 11"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
msgid "Switch to VT 12"
msgstr "Pindah ke VT 12"
#: ../src/backends/meta-monitor-manager.c:364
#: ../src/backends/meta-monitor-manager.c:412
msgid "Built-in display"
msgstr "Tampilan bawaan"
#: ../src/backends/meta-monitor-manager.c:391
#: ../src/backends/meta-monitor-manager.c:437
msgid "Unknown"
msgstr "Tak Dikenal"
#: ../src/backends/meta-monitor-manager.c:393
#: ../src/backends/meta-monitor-manager.c:439
msgid "Unknown Display"
msgstr "Tampilan Tak Dikenal"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c:401
#: ../src/backends/meta-monitor-manager.c: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"
@ -484,6 +464,10 @@ msgid ""
msgstr ""
"Manajer komposit lain telah berjalan pada layar %i pada tampilan \"%s\"."
#: ../src/compositor/meta-background.c:1044
msgid "background texture could not be created from file"
msgstr "tekstur latar tak bisa dibuat dari berkas"
#: ../src/core/bell.c:185
msgid "Bell event"
msgstr "Bel peristiwa"
@ -512,7 +496,7 @@ msgstr "_Tunggu"
msgid "_Force Quit"
msgstr "_Matikan Paksa"
#: ../src/core/display.c:562
#: ../src/core/display.c:547
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Gagal membuka tampilan X Window System '%s'\n"
@ -549,6 +533,17 @@ msgstr "Jalankan sebagai kompositor wayland"
msgid "Run as a full display server, rather than nested"
msgstr "Jalankan sebagai server tampilan penuh, ketimbang tampilan bersarang"
#: ../src/core/main.c:459
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Gagal memeriksa direktori tema: %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 "Tak menemukan tema! Pastikan %s ada dan berisi tema yang biasa.\n"
#: ../src/core/mutter.c:39
#, c-format
msgid ""
@ -573,29 +568,714 @@ msgstr "Cetak versi"
msgid "Mutter plugin to use"
msgstr "Pengaya Mutter yang dipakai"
#: ../src/core/prefs.c:2004
#: ../src/core/prefs.c:2101
#, c-format
msgid "Workspace %d"
msgstr "Area kerja %d"
#: ../src/core/screen.c:525
#, c-format
msgid ""
"Display \"%s\" already has a window manager; try using the --replace option "
"to replace the current window manager."
msgstr ""
"Tampilan \"%s\" sudah memiliki manajer jendela; cobalah gunakan pilihan --"
"replace untuk mengganti manajer jendela saat ini."
#: ../src/core/screen.c:607
#: ../src/core/screen.c:548
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Layar %d pada tampilan '%s' tidak benar\n"
#: ../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 ""
"Layar %d pada tampilan \"%s\" sudah memiliki pengatur jendela. Cobalah "
"gunakan pilihan --replace untuk mengganti pengatur jendela yang aktif.\n"
#: ../src/core/screen.c:657
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "Layar %d pada tampilan \"%s\" sudah ada pengatur jendelanya\n"
#: ../src/core/util.c:118
msgid "Mutter was compiled without support for verbose mode\n"
msgstr "Muter dikompilasi tanpa dukungan mode riuh\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 "atas"
#: ../src/ui/theme.c:235
msgid "bottom"
msgstr "bawah"
#: ../src/ui/theme.c:237
msgid "left"
msgstr "kiri"
#: ../src/ui/theme.c:239
msgid "right"
msgstr "kanan"
#: ../src/ui/theme.c:267
#, c-format
msgid "frame geometry does not specify \"%s\" dimension"
msgstr "ukuran frame tidak menyebutkan dimensi \"%s\""
#: ../src/ui/theme.c:286
#, c-format
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
msgstr "ukuran frame tidak menyebutkan dimensi \"%s\" untuk batas \"%s\""
#: ../src/ui/theme.c:323
#, c-format
msgid "Button aspect ratio %g is not reasonable"
msgstr "Aspek rasio tombol %g tidak wajar"
#: ../src/ui/theme.c:335
#, c-format
msgid "Frame geometry does not specify size of buttons"
msgstr "Ukuran frame tidak menyebutkan ukuran tombol"
#: ../src/ui/theme.c:1061
#, c-format
msgid "Gradients should have at least two colors"
msgstr "Gradien harus paling tidak ada dua warna"
#: ../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 ""
"Spesifikasi warna ubahan GTK mesti memiliki nama warna dan cadangan dalam "
"kurung, mis. gtk:custom(foo,bar); tak bisa mengurai \"%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 ""
"Karakter tak valid '%c' dalam parameter color_name dari gtk:custom, hanya A-"
"Za-z0-9-_ yang valid"
#: ../src/ui/theme.c:1241
#, c-format
msgid ""
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
"fit the format"
msgstr ""
"Format Gtk:custom adalah \"gtk:custom(color_name,fallback)\", \"%s\" tak "
"memenuhi 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 ""
"Spesifikasi warna GTK harus memiliki kondisi pada kurung, misal gtk:"
"fg[NORMAL] dengan NORMAL adalah jenis kondisinya, tidak dapat membaca \"%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 ""
"Spesifikasi warna GTK harus memiliki kurung tutup pada kondisinya, misal gtk:"
"fg[NORMAL] dengan NORMAL adalah jenis kondisinya, tidak dapat membaca \"%s\""
#: ../src/ui/theme.c:1311
#, c-format
msgid "Did not understand state \"%s\" in color specification"
msgstr "Kondisi \"%s\" tidak benar pada spesifikasi warna"
#: ../src/ui/theme.c:1324
#, c-format
msgid "Did not understand color component \"%s\" in color specification"
msgstr "Komponen warna \"%s\" tidak benar pada spesifikasi warna"
#: ../src/ui/theme.c:1352
#, c-format
msgid ""
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
"format"
msgstr ""
"Format pencampuran adalah \"blend/bg_color/fg_color/alpha\", \"%s\" bukan "
"ditulis dalam format yang benar"
#: ../src/ui/theme.c:1363
#, c-format
msgid "Could not parse alpha value \"%s\" in blended color"
msgstr "Tak dapat membaca nilai alpha \"%s\" pada pencampuran warna"
#: ../src/ui/theme.c:1373
#, c-format
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
msgstr ""
"Nilai alpha \"%s\" pada warna yang dicampur tidak ada dalam rentang 0.0 dan "
"1.0"
#: ../src/ui/theme.c:1419
#, c-format
msgid ""
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
msgstr ""
"Format bayangan adalah \"shade/base_color/factor\", \"%s\" ditulis dalam "
"format yang keliru"
#: ../src/ui/theme.c:1430
#, c-format
msgid "Could not parse shade factor \"%s\" in shaded color"
msgstr "Tak dapat membaca faktor bayangan \"%s\" pada warna berbayang"
#: ../src/ui/theme.c:1440
#, c-format
msgid "Shade factor \"%s\" in shaded color is negative"
msgstr "Faktor bayangan \"%s\" pada warna berbayang bernilai negatif"
#: ../src/ui/theme.c:1469
#, c-format
msgid "Could not parse color \"%s\""
msgstr "Tak dapat membaca warna \"%s\""
#: ../src/ui/theme.c:1778
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr "Ekspresi koordinat berisi karakter '%s' yang tidak diperbolehkan"
#: ../src/ui/theme.c:1805
#, c-format
msgid ""
"Coordinate expression contains floating point number '%s' which could not be "
"parsed"
msgstr ""
"Ekspresi koordinat berisi angka floating point '%s' yang tidak dapat dibaca"
#: ../src/ui/theme.c:1819
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr "Ekspresi koordinat berisi integer '%s' yang tidak dapat dibaca"
#: ../src/ui/theme.c:1940
#, c-format
msgid ""
"Coordinate expression contained unknown operator at the start of this text: "
"\"%s\""
msgstr ""
"Ekspresi koordinat berisi operator tak dikenal pada awal teks berikut: \"%s\""
#: ../src/ui/theme.c:1997
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr "Ekspresi koordinat kosong atau tidak dapat dimengerti"
#: ../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 "Ekspresi koordinat menghasilkan pembagian dengan nol"
#: ../src/ui/theme.c:2162
#, c-format
msgid ""
"Coordinate expression tries to use mod operator on a floating-point number"
msgstr "Ekspresi koordinat menggunakan operator mod pada angka bilangan nyata"
#: ../src/ui/theme.c:2218
#, c-format
msgid ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
msgstr "Ekspresi koordinat menggunakan operator \"%s\" tanpa adanya operan"
#: ../src/ui/theme.c:2227
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr "Ekspresi koordinat menggunakan operand tanpa operator"
#: ../src/ui/theme.c:2235
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr ""
"Ekspresi koordinat diakhiri dengan operator, seharusnya diakhiri dengan "
"operand"
#: ../src/ui/theme.c:2245
#, c-format
msgid ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
"operand in between"
msgstr ""
"Ekspresi koordinat memiliki operator \"%c\" diikuti operator \"%c\" tanpa "
"adanya operand di antarany"
#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr ""
"Ada variabel atau konstanta \"%s\" tidak diketahui pada ekspresi koordinat"
#: ../src/ui/theme.c:2495
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr "Ekspresi koordinat melampaui batasannya."
#: ../src/ui/theme.c:2524
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr "Terdapat kurung tutup tanpa kurung buka pada ekspresi koordinat"
#: ../src/ui/theme.c:2588
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr "Terdapat kurung buka tanpa kurung tutup pada ekspresi koordinat"
#: ../src/ui/theme.c:2599
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr "Ekspresi koordinat sepertinya tidak memiliki operator atau operan"
#: ../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 "Tema mengandung ekspresi yang menghasilkan galat: %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\"/> tidak "
"disebutkan pada gaya frame ini"
#: ../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\"/> tidak ada"
#: ../src/ui/theme.c:5041
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "Gagal membuka tema \"%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 "Tak ada <%s> yang ditentukan untuk tema \"%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 ""
"Tak ada gaya frame untuk tipe window \"%s\" pada tema \"%s\". Tambah dulu "
"elemen <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 ""
"Konstanta buatan pengguna harus dimulai dengan huruf besar: \"%s\" tidak"
#: ../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 "Konstanta \"%s\" telah didefinisikan sebelumnya"
#. 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 "Tak ada atribut \"%s\" pada elemen <%s>"
#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281
#, c-format
msgid "Line %d character %d: %s"
msgstr "Baris %d karakter %d: %s"
#: ../src/ui/theme-parser.c:481
#, c-format
msgid "Attribute \"%s\" repeated twice on the same <%s> element"
msgstr "Atribut \"%s\" diulangi dua kali pada elemen <%s> yang sama"
#: ../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 "Atribut \"%s\" tidak diperkenankan pada elemen <%s> pada konteks ini"
#: ../src/ui/theme-parser.c:596
#, c-format
msgid "Could not parse \"%s\" as an integer"
msgstr "Tak dapat menguraikan \"%s\" sebagai integer"
#: ../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 "Tak mengerti karakter \"%s\" kenapa ada dibuntut string \"%s\""
#: ../src/ui/theme-parser.c:615
#, c-format
msgid "Integer %ld must be positive"
msgstr "Integer %ld harus bernilai positif"
#: ../src/ui/theme-parser.c:623
#, c-format
msgid "Integer %ld is too large, current max is %d"
msgstr "Integer %ld terlalu besar, maksimal %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 "Tak dapat membaca \"%s\" sebagai angka floating point"
#: ../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 "Nilai boolean harus \"true\" atau \"false\" dan bukannya \"%s\""
#: ../src/ui/theme-parser.c:737
#, c-format
msgid "Angle must be between 0.0 and 360.0, was %g\n"
msgstr "Sudut harus ada dalam rentang 0.0 dan 360.0, dalam berkas didapat %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 ""
"Alpha harus ada dalam rentang 0.0 (tidak kelihatan) dan 1.0 (nampak semua, "
"dalam berkas didapat %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 ""
"Skala judul \"%s\" tidak benar (harusnya bernilai 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 "Nama <%s> \"%s\" digunakan kedua kali"
#: ../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 "Induk <%s> \"%s\" belum didefinisikan"
#: ../src/ui/theme-parser.c:1143
#, c-format
msgid "<%s> geometry \"%s\" has not been defined"
msgstr "Geometri <%s> \"%s\" belum didefinisikan"
#: ../src/ui/theme-parser.c:1156
#, c-format
msgid "<%s> must specify either a geometry or a parent that has a geometry"
msgstr "<%s> harus menentukan geometri atau induk yang ada geometrinya"
#: ../src/ui/theme-parser.c:1198
msgid "You must specify a background for an alpha value to be meaningful"
msgstr ""
"Anda mesti menyatakan suatu latar belakang bagi nilai alfa agar berarti"
#: ../src/ui/theme-parser.c:1266
#, c-format
msgid "Unknown type \"%s\" on <%s> element"
msgstr "Tipe \"%s\" tidak dikenal pada elemen <%s>"
#: ../src/ui/theme-parser.c:1277
#, c-format
msgid "Unknown style_set \"%s\" on <%s> element"
msgstr "style_set \"%s\" tidak dikenali pada elemen <%s>"
#: ../src/ui/theme-parser.c:1285
#, c-format
msgid "Window type \"%s\" has already been assigned a style set"
msgstr "Tipe jendela \"%s\" sudah memiliki set gaya"
#: ../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 "Elemen <%s> tidak diperkenankan ada di bawah <%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 ""
"Tak dapat menyatakan \"button_width\"/\"button_height\" dan \"aspect_ratio\" "
"sekaligus untuk tombol"
#: ../src/ui/theme-parser.c:1452
#, c-format
msgid "Distance \"%s\" is unknown"
msgstr "Jarak \"%s\" tidak dikenal"
#: ../src/ui/theme-parser.c:1497
#, c-format
msgid "Aspect ratio \"%s\" is unknown"
msgstr "Rasio aspek \"%s\" tidak dikenal"
#: ../src/ui/theme-parser.c:1559
#, c-format
msgid "Border \"%s\" is unknown"
msgstr "Batas \"%s\" tidak dikenal"
#: ../src/ui/theme-parser.c:1870
#, c-format
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
msgstr "Tak ada atribut \"start_angle\" atau \"from\" pada elemen <%s>"
#: ../src/ui/theme-parser.c:1877
#, c-format
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
msgstr "Tak ada atribut \"extent_angle\" atau \"to\" pada elemen <%s>"
#: ../src/ui/theme-parser.c:2117
#, c-format
msgid "Did not understand value \"%s\" for type of gradient"
msgstr "Nilai \"%s\" bukan nilai yang sah untuk tipe gradien"
#: ../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 "Tipe isian \"%s\" tidak dikenal untuk elemen <%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 "Kondisi \"%s\" tidak dikenal untuk elemen <%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 "Bayangan \"%s\" tidak dikenal untuk elemen <%s>"
#: ../src/ui/theme-parser.c:2382
#, c-format
msgid "Did not understand arrow \"%s\" for <%s> element"
msgstr "Panah \"%s\" tidak dikenal untuk elemen <%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 "Tak ada <draw_ops> bernama \"%s\" yang telah didefinisikan"
#: ../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 ""
"Menyertakan draw_ops \"%s\" di sini akan membuat referensi tak berujung"
#: ../src/ui/theme-parser.c:2919
#, c-format
msgid "Unknown position \"%s\" for frame piece"
msgstr "Posisi \"%s\" tidak dikenal untuk bagian frame"
#: ../src/ui/theme-parser.c:2927
#, c-format
msgid "Frame style already has a piece at position %s"
msgstr "Gaya frame sudah memiliki bagian pada posisi %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 "Tak ada <draw_ops> dengan nama \"%s\" yang didefinisikan"
#: ../src/ui/theme-parser.c:2974
#, c-format
msgid "Unknown function \"%s\" for button"
msgstr "Fungsi \"%s\" tidak dikenal untuk tombol"
#: ../src/ui/theme-parser.c:2984
#, c-format
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
msgstr ""
"Tombol fungsi \"%s\" tidak tersedia untuk versi ini (%d, memerlukan %d)"
#: ../src/ui/theme-parser.c:2996
#, c-format
msgid "Unknown state \"%s\" for button"
msgstr "Kondisi \"%s\" tidak dikenal untuk tombol"
#: ../src/ui/theme-parser.c:3004
#, c-format
msgid "Frame style already has a button for function %s state %s"
msgstr "Gaya bingkai sudah memiliki tombol untuk fungsi %s kondisi %s"
#: ../src/ui/theme-parser.c:3075
#, c-format
msgid "\"%s\" is not a valid value for focus attribute"
msgstr "\"%s\" bukan nilai yang benar untuk atribut focus"
#: ../src/ui/theme-parser.c:3084
#, c-format
msgid "\"%s\" is not a valid value for state attribute"
msgstr "\"%s\" bukan nilai yang benar untuk atribut state"
#: ../src/ui/theme-parser.c:3094
#, c-format
msgid "A style called \"%s\" has not been defined"
msgstr "Gaya bernama \"%s\" belum didefinisikan"
#: ../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\" bukan nilai yang benar untuk atribut resize"
#: ../src/ui/theme-parser.c:3149
#, c-format
msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
"states"
msgstr ""
"Atribut \"resize\" tidak boleh ada pada elemen <%s> untuk kondisi ukuran "
"window maksimum/tergulung"
#: ../src/ui/theme-parser.c:3163
#, c-format
msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized states"
msgstr ""
"Atribut \"resize\" tidak boleh ada pada elemen <%s> untuk kondisi ukuran "
"jendela maksimal"
#: ../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 "Gaya sudah menjelaskan kondisi %s resize %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 "Gaya sudah menjelaskan kondisi %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 ""
"Tak boleh ada dua draw_ops untuk elemen <piece> (tema menyebutkan atribut "
"draw_ops dan juga elemen <draw_ops> atau meyebutkan dua elemen tersebut "
#: ../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 ""
"Tak boleh ada dua draw_ops untuk elemen <button> (tema menyebutkan atribut "
"draw_ops dan juga elemen <draw_ops> atau meyebutkan dua elemen tersebut "
#: ../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 ""
"Tak boleh ada dua draw_ops untuk elemen <menu_icon> (tema menyebutkan "
"atribut draw_ops dan juga elemen <draw_ops> atau meyebutkan dua elemen "
"tersebut "
#: ../src/ui/theme-parser.c:3433
#, c-format
msgid "Bad version specification '%s'"
msgstr "Spesifikasi versi '%s' jelek"
#: ../src/ui/theme-parser.c:3506
msgid ""
"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
"theme-2.xml"
msgstr ""
"Atribut \"version\" tidak dapat dipakai dalam metacity-theme-1.xml atau "
"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 "Tema memerlukan versi %s tetapi versi yang didukung adalah %d.%d"
#: ../src/ui/theme-parser.c:3561
#, c-format
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
msgstr "Elemen tema paling luar haruslah <metacity_theme> dan bukan <%s>"
#: ../src/ui/theme-parser.c:3581
#, c-format
msgid ""
"Element <%s> is not allowed inside a name/author/date/description element"
msgstr ""
"Elemen <%s> tidak diperbolehkan berada elemen name/author/date/description"
#: ../src/ui/theme-parser.c:3586
#, c-format
msgid "Element <%s> is not allowed inside a <constant> element"
msgstr "Elemen <%s> tidak boleh ada dalam elemen <constat>"
#: ../src/ui/theme-parser.c:3598
#, c-format
msgid ""
"Element <%s> is not allowed inside a distance/border/aspect_ratio element"
msgstr ""
"Elemen <%s> tidak boleh ada di dalam elemen distance/border/aspec_ratio"
#: ../src/ui/theme-parser.c:3620
#, c-format
msgid "Element <%s> is not allowed inside a draw operation element"
msgstr "Elemen <%s> tidak boleh ada di dalam elemen operasi gambar"
#: ../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 "Elemen <%s> tidak boleh ada di dalam elemen <%s>"
#: ../src/ui/theme-parser.c:3898
msgid "No draw_ops provided for frame piece"
msgstr "Tak ada draw_ops yang disediakan untuk bagian frame"
#: ../src/ui/theme-parser.c:3913
msgid "No draw_ops provided for button"
msgstr "Tak ada draw_ops yang disediakan untuk tombol"
#: ../src/ui/theme-parser.c:3967
#, c-format
msgid "No text is allowed inside element <%s>"
msgstr "Tak boleh ada teks di dalam elemen <%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> disebutkan dua kali pada tema ini"
#: ../src/ui/theme-parser.c:4335
#, c-format
msgid "Failed to find a valid file for theme %s\n"
msgstr "Gagal menemukan berkas yang sah untuk tema %s\n"
#: ../src/x11/session.c:1815
msgid ""
"These windows do not support &quot;save current setup&quot; and will have to "
@ -604,7 +1284,7 @@ msgstr ""
"Jendela ini tidak bisa &quot;menyimpan setelan aktif saat ini&quot; dan bila "
"log masuk kali lain Anda harus menjalankannya ulang."
#: ../src/x11/window-props.c:549
#: ../src/x11/window-props.c:515
#, c-format
msgid "%s (on %s)"
msgstr "%s (pada %s)"

1094
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

1240
po/ko.po

File diff suppressed because it is too large Load Diff

1352
po/lt.po

File diff suppressed because it is too large Load Diff

1887
po/lv.po

File diff suppressed because it is too large Load Diff

1138
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

1225
po/pa.po

File diff suppressed because it is too large Load Diff

858
po/pl.po
View File

@ -9,14 +9,14 @@
# Marek Stępień <marcoos@aviary.pl>, 2007.
# Wadim Dziedzic <wdziedzic@aviary.pl>, 2007.
# Tomasz Dominikowski <dominikowski@gmail.com>, 2008-2009.
# Piotr Drąg <piotrdrag@gmail.com>, 2010-2016.
# Aviary.pl <gnomepl@aviary.pl>, 2007-2016.
# Piotr Drąg <piotrdrag@gmail.com>, 2010-2014.
# Aviary.pl <gnomepl@aviary.pl>, 2007-2014.
msgid ""
msgstr ""
"Project-Id-Version: mutter\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-02-25 17:29+0100\n"
"PO-Revision-Date: 2016-02-25 17:30+0100\n"
"POT-Creation-Date: 2014-09-03 15:55+0200\n"
"PO-Revision-Date: 2014-09-03 15:58+0200\n"
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
"Language-Team: Polish <gnomepl@aviary.pl>\n"
"Language: pl\n"
@ -285,10 +285,10 @@ msgid ""
"\"Windows key\" on PC hardware. It's expected that this binding either the "
"default or set to the empty string."
msgstr ""
"Ten klawisz inicjuje tryb overlay” (nakładki), który jest połączeniem "
"podglądu okien i systemu uruchamiania programów. Domyślnie jest przeznaczony "
"do powiązania z klawiszem Windows na komputerach typu PC. Ustawienie tego "
"powiązania powinno być domyślne lub puste."
"Ten klawisz inicjuje tryb \"overlay\", który jest połączeniem podglądu okien "
"i systemu uruchamiania programów. Domyślnie jest przeznaczony do powiązania "
"z klawiszem \"Windows\" na komputerach typu PC. Ustawienie tego powiązania "
"powinno być domyślne lub puste."
#: ../data/org.gnome.mutter.gschema.xml.in.h:3
msgid "Attach modal dialogs"
@ -300,9 +300,9 @@ msgid ""
"attached to the titlebar of the parent window and are moved together with "
"the parent window."
msgstr ""
"Jeśli wynosi wartość „true, to modalne okna dialogowe pojawiają się "
"dołączone do paska tytułowego okna nadrzędnego zamiast posiadać oddzielne "
"paski tytułowe i są przenoszone razem z nim."
"Jeśli wynosi \"true\", to modalne okna dialogowe pojawiają się dołączone do "
"paska tytułowego okna nadrzędnego zamiast posiadać oddzielne paski tytułowe "
"i są przenoszone razem z nim."
#: ../data/org.gnome.mutter.gschema.xml.in.h:5
msgid "Enable edge tiling when dropping windows on screen edges"
@ -332,8 +332,8 @@ msgid ""
"gnome.desktop.wm.preferences)."
msgstr ""
"Określa, czy obszary robocze są zarządzane dynamicznie, czy istnieje "
"statyczna liczba obszarów (określona przez klucz num-workspaces w org."
"gnome.desktop.wm.preferences)."
"statyczna liczba obszarów (określona przez klucz \"num-workspaces\" w org."
"gnome.desktop.wm.preferences)."
#: ../data/org.gnome.mutter.gschema.xml.in.h:9
msgid "Workspaces only on primary"
@ -369,9 +369,9 @@ msgid ""
"the focus will not be changed immediately when entering a window, but only "
"after the pointer stops moving."
msgstr ""
"Jeśli jest ustawione na wartość true, a tryb aktywności to sloppy” lub "
"mouse, to aktywność nie będzie zmieniana od razu po przejściu do okna, ale "
"dopiero po zatrzymaniu ruchu kursora."
"Jeśli jest ustawione na wartość \"true\", a tryb aktywności to \"sloppy\" "
"lub \"mouse\", to aktywność nie będzie zmieniana od razu po przejściu do "
"okna, ale dopiero po zatrzymaniu ruchu kursora."
#: ../data/org.gnome.mutter.gschema.xml.in.h:15
msgid "Draggable border width"
@ -409,7 +409,7 @@ msgid ""
"When true, the new windows will always be put in the center of the active "
"screen of the monitor."
msgstr ""
"Jeśli wynosi wartość „true, to nowe okna będą zawsze umieszczane na środku "
"Jeśli wynosi \"true\", to nowe okna będą zawsze umieszczane na środku "
"aktywnego ekranu monitora."
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
@ -448,55 +448,39 @@ msgstr "Przełączenie na 6. konsolę wirtualną"
msgid "Switch to VT 7"
msgstr "Przełączenie na 7. konsolę wirtualną"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
msgid "Switch to VT 8"
msgstr "Przełączenie na 8. konsolę wirtualną"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
msgid "Switch to VT 9"
msgstr "Przełączenie na 9. konsolę wirtualną"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
msgid "Switch to VT 10"
msgstr "Przełączenie na 10. konsolę wirtualną"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
msgid "Switch to VT 11"
msgstr "Przełączenie na 11. konsolę wirtualną"
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
msgid "Switch to VT 12"
msgstr "Przełączenie na 12. konsolę wirtualną"
#: ../src/backends/meta-monitor-manager.c:518
#: ../src/backends/meta-monitor-manager.c:412
msgid "Built-in display"
msgstr "Wbudowany ekran"
#: ../src/backends/meta-monitor-manager.c:544
#: ../src/backends/meta-monitor-manager.c:437
msgid "Unknown"
msgstr "Nieznany"
#: ../src/backends/meta-monitor-manager.c:546
#: ../src/backends/meta-monitor-manager.c:439
msgid "Unknown Display"
msgstr "Nieznany ekran"
#. TRANSLATORS: this is a monitor vendor name, followed by a
#. * size in inches, like 'Dell 15"'
#.
#: ../src/backends/meta-monitor-manager.c: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"
"\"."
msgstr ""
"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu „%s”."
"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu \"%s\"."
#: ../src/compositor/meta-background.c:1044
msgid "background texture could not be created from file"
msgstr "nie można utworzyć tekstury tła z pliku"
#: ../src/core/bell.c:185
msgid "Bell event"
@ -505,7 +489,7 @@ msgstr "Zdarzenie sygnału dźwiękowego"
#: ../src/core/delete.c:127
#, c-format
msgid "“%s” is not responding."
msgstr "Okno „%s” nie odpowiada."
msgstr "Okno \"%s\" nie odpowiada."
#: ../src/core/delete.c:129
msgid "Application is not responding."
@ -525,46 +509,56 @@ msgstr "_Czekaj"
msgid "_Force Quit"
msgstr "_Zakończ"
#: ../src/core/display.c:555
#: ../src/core/display.c:547
#, c-format
msgid "Failed to open X Window System display '%s'\n"
msgstr "Otwarcie połączenia z ekranem „%s” systemu X Window się nie powiodło\n"
msgstr ""
"Otwarcie połączenia z ekranem \"%s\" systemu X Window się nie powiodło\n"
#: ../src/core/main.c:181
#: ../src/core/main.c:176
msgid "Disable connection to session manager"
msgstr "Rozłącza połączenie z menedżerem sesji"
#: ../src/core/main.c:187
#: ../src/core/main.c:182
msgid "Replace the running window manager"
msgstr "Zastępuje uruchomionego menedżera okien"
#: ../src/core/main.c:193
#: ../src/core/main.c:188
msgid "Specify session management ID"
msgstr "Podaje identyfikator zarządzania sesją"
#: ../src/core/main.c:198
#: ../src/core/main.c:193
msgid "X Display to use"
msgstr "Używany ekran X"
#: ../src/core/main.c:204
#: ../src/core/main.c:199
msgid "Initialize session from savefile"
msgstr "Inicjuje sesję z zapisanego pliku"
#: ../src/core/main.c:210
#: ../src/core/main.c:205
msgid "Make X calls synchronous"
msgstr "Synchroniczne wywołania X"
#: ../src/core/main.c:217
#: ../src/core/main.c:212
msgid "Run as a wayland compositor"
msgstr "Uruchamia jako menedżer składania Wayland"
#: ../src/core/main.c:223
msgid "Run as a nested compositor"
msgstr "Uruchamia jako osadzony menedżer składania"
#: ../src/core/main.c:231
#: ../src/core/main.c:220
msgid "Run as a full display server, rather than nested"
msgstr "Uruchamia jako pełny serwer wyświetlania zamiast osadzonego"
msgstr "Uruchamia pełny serwer wyświetlania zamiast osadzonego"
#: ../src/core/main.c:459
#, c-format
msgid "Failed to scan themes directory: %s\n"
msgstr "Przejrzenie katalogu z motywami się nie powiodło: %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 ""
"Nie można odnaleźć żadnego motywu. Proszę sprawdzić, czy katalog %s istnieje "
"i zawiera standardowe motywy.\n"
#: ../src/core/mutter.c:39
#, c-format
@ -588,41 +582,751 @@ msgstr "Wyświetla wersję"
#: ../src/core/mutter.c:59
msgid "Mutter plugin to use"
msgstr "Używana wtyczka menedżera Mutter"
msgstr "Używana wtyczka programu Mutter"
#: ../src/core/prefs.c:1997
#: ../src/core/prefs.c:2101
#, c-format
msgid "Workspace %d"
msgstr "%d. obszar roboczy"
msgstr "Obszar roboczy %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 ""
"Na ekranie „%s” działa już menedżer okien. Aby zastąpić działającego "
"menedżera okien, należy użyć opcji „--replace”."
#: ../src/core/screen.c:603
#: ../src/core/screen.c:548
#, c-format
msgid "Screen %d on display '%s' is invalid\n"
msgstr "Podekran %d ekranu „%s” jest nieprawidłowy\n"
msgstr "Podekran %d ekranu \"%s\" jest nieprawidłowy\n"
#: ../src/core/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 ""
"Na podekranie %d ekranu \"%s\" działa już menedżer okien. Aby zastąpić "
"działającego menedżera okien, proszę spróbować użyć opcji --replace.\n"
#: ../src/core/screen.c:657
#, c-format
msgid "Screen %d on display \"%s\" already has a window manager\n"
msgstr "Na podekranie %d ekranu \"%s\" działa już menedżer okien\n"
#: ../src/core/util.c:118
msgid "Mutter was compiled without support for verbose mode\n"
msgstr ""
"Menedżer Mutter został skompilowany bez obsługi trybu z obszerną informacją\n"
"Program Mutter został skompilowany bez obsługi trybu z obszerną informacją\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 "góra"
#: ../src/ui/theme.c:235
msgid "bottom"
msgstr "dół"
#: ../src/ui/theme.c:237
msgid "left"
msgstr "lewa"
#: ../src/ui/theme.c:239
msgid "right"
msgstr "prawa"
#: ../src/ui/theme.c:267
#, c-format
msgid "frame geometry does not specify \"%s\" dimension"
msgstr "Rozmiar ramki nie określa wymiaru \"%s\""
#: ../src/ui/theme.c:286
#, c-format
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
msgstr "Rozmiar ramki nie określa wymiaru \"%s\" dla krawędzi \"%s\""
#: ../src/ui/theme.c:323
#, c-format
msgid "Button aspect ratio %g is not reasonable"
msgstr ""
"Współczynnik proporcji przycisku %g nie mieści się w rozsądnych granicach"
#: ../src/ui/theme.c:335
#, c-format
msgid "Frame geometry does not specify size of buttons"
msgstr "Rozmiar ramki nie określa liczby przycisków"
#: ../src/ui/theme.c:1061
#, c-format
msgid "Gradients should have at least two colors"
msgstr "Gradienty powinny się składać co najmniej z dwóch kolorów"
#: ../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 ""
"Własna specyfikacja koloru biblioteki GTK+ musi posiadać nazwę koloru i "
"kolor zastępczy w nawiasach, np. gtk:custom(foo,bar); nie można przetworzyć "
"\"%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 ""
"Nieprawidłowy znak \"%c\" w parametrze nazwa_koloru opcji gtk:custom, tylko "
"znaki A-Za-z0-9-_ są prawidłowe"
#: ../src/ui/theme.c:1241
#, c-format
msgid ""
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
"fit the format"
msgstr ""
"Formatem Gtk:custom jest \"gtk:custom(nazwa_koloru,kolor_zastępczy)\", \"%s"
"\" nie pasuje do formatu"
#: ../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 ""
"Specyfikacja koloru biblioteki GTK+ musi zawierać stan w nawiasach "
"kwadratowych, np. gtk:fg[NORMAL], gdzie NORMAL jest nazwą stanu; nie można "
"przetworzyć \"%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 ""
"Specyfikacja koloru biblioteki GTK+ musi po nazwie stanu zawierać zamykający "
"nawias kwadratowy, np. gtk:fg[NORMAL], gdzie NORMAL jest nazwą stanu; nie "
"można przetworzyć \"%s\""
#: ../src/ui/theme.c:1311
#, c-format
msgid "Did not understand state \"%s\" in color specification"
msgstr "Niezrozumiały stan \"%s\" w specyfikacji koloru"
#: ../src/ui/theme.c:1324
#, c-format
msgid "Did not understand color component \"%s\" in color specification"
msgstr "Niezrozumiała definicja koloru \"%s\" w specyfikacji koloru"
#: ../src/ui/theme.c:1352
#, c-format
msgid ""
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
"format"
msgstr ""
"Formatem przenikania jest \"blend/bg_color/fg_color/alpha\", \"%s\" nie "
"pasuje do formatu"
#: ../src/ui/theme.c:1363
#, c-format
msgid "Could not parse alpha value \"%s\" in blended color"
msgstr "Nie można przetworzyć wartości alfa \"%s\" w przenikającym kolorze"
#: ../src/ui/theme.c:1373
#, c-format
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
msgstr ""
"Wartość alfa \"%s\" w przenikającym kolorze nie zawiera się pomiędzy 0,0 i "
"1,0"
#: ../src/ui/theme.c:1419
#, c-format
msgid ""
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
msgstr ""
"Formatem przenikania jest \"shade/base_color/factor\", \"%s\" nie pasuje do "
"formatu"
#: ../src/ui/theme.c:1430
#, c-format
msgid "Could not parse shade factor \"%s\" in shaded color"
msgstr ""
"Nie można przetworzyć współczynnika przenikania \"%s\" w przenikającym "
"kolorze"
#: ../src/ui/theme.c:1440
#, c-format
msgid "Shade factor \"%s\" in shaded color is negative"
msgstr "Współczynnik przenikania \"%s\" w przenikającym kolorze jest ujemny"
#: ../src/ui/theme.c:1469
#, c-format
msgid "Could not parse color \"%s\""
msgstr "Nie można przetworzyć koloru \"%s\""
#: ../src/ui/theme.c:1778
#, c-format
msgid "Coordinate expression contains character '%s' which is not allowed"
msgstr "Wyrażenie określające współrzędne zawiera niedozwolony znak \"%s\""
#: ../src/ui/theme.c:1805
#, c-format
msgid ""
"Coordinate expression contains floating point number '%s' which could not be "
"parsed"
msgstr ""
"Wyrażenie określające współrzędne zawiera liczbę zmiennoprzecinkową \"%s\", "
"której nie można przetworzyć"
#: ../src/ui/theme.c:1819
#, c-format
msgid "Coordinate expression contains integer '%s' which could not be parsed"
msgstr ""
"Wyrażenie określające współrzędne zawiera liczbę całkowitą \"%s\", której "
"nie można przetworzyć"
#: ../src/ui/theme.c:1940
#, c-format
msgid ""
"Coordinate expression contained unknown operator at the start of this text: "
"\"%s\""
msgstr ""
"Wyrażenie określające współrzędne zawiera nieznany operator na początku "
"tekstu: \"%s\""
#: ../src/ui/theme.c:1997
#, c-format
msgid "Coordinate expression was empty or not understood"
msgstr ""
"Wyrażenie określające współrzędne jest puste lub nie można go rozpoznać"
#: ../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 "Wyrażenie opisujące położenie zawiera dzielenie przez zero"
#: ../src/ui/theme.c:2162
#, c-format
msgid ""
"Coordinate expression tries to use mod operator on a floating-point number"
msgstr ""
"Wyrażenie opisujące położenie używa operatora dzielenia modulo z liczbą "
"zmiennoprzecinkową"
#: ../src/ui/theme.c:2218
#, c-format
msgid ""
"Coordinate expression has an operator \"%s\" where an operand was expected"
msgstr ""
"Wyrażenie opisujące położenie zawiera operator \"%s\" w miejscu, w którym "
"oczekiwano operandu"
#: ../src/ui/theme.c:2227
#, c-format
msgid "Coordinate expression had an operand where an operator was expected"
msgstr ""
"Wyrażenie opisujące położenie zawiera operand w miejscu, w którym oczekiwano "
"operatora"
#: ../src/ui/theme.c:2235
#, c-format
msgid "Coordinate expression ended with an operator instead of an operand"
msgstr "Wyrażenie opisujące położenie kończy się operatorem zamiast operandem"
#: ../src/ui/theme.c:2245
#, c-format
msgid ""
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
"operand in between"
msgstr ""
"Wyrażenie opisujące położenie zawiera operator \"%c\" bezpośrednio po "
"operatorze \"%c\" bez rozdzielającego ich operandu"
#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441
#, c-format
msgid "Coordinate expression had unknown variable or constant \"%s\""
msgstr ""
"Wyrażenie opisujące położenie zawiera nieznaną zmienną lub stałą \"%s\""
#: ../src/ui/theme.c:2495
#, c-format
msgid "Coordinate expression parser overflowed its buffer."
msgstr "Parser wyrażeń określających współrzędne przepełnił swój bufor."
#: ../src/ui/theme.c:2524
#, c-format
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
msgstr ""
"Wyrażenie opisujące położenie zawiera nawias zamykający bez odpowiadającego "
"mu nawiasu otwierającego"
#: ../src/ui/theme.c:2588
#, c-format
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
msgstr ""
"Wyrażenie opisujące położenie zawiera nawias otwierający bez odpowiadającego "
"mu nawiasu zamykającego"
#: ../src/ui/theme.c:2599
#, c-format
msgid "Coordinate expression doesn't seem to have any operators or operands"
msgstr ""
"Wyrażenie opisujące położenie nie zawiera żadnych operatorów ani operandów"
#: ../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 "Motyw zawiera wyrażenie, przy którego obliczaniu wystąpił błąd: %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 ""
"Przy tym stylu ramki należy podać <button function=\"%s\" state=\"%s\" "
"draw_ops=\"cokolwiek\"/>"
#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995
#, c-format
msgid ""
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
msgstr ""
"Brak <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"cokolwiek\"/>"
#: ../src/ui/theme.c:5041
#, c-format
msgid "Failed to load theme \"%s\": %s\n"
msgstr "Wczytanie motywu \"%s\" się nie powiodło: %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 "Nie określono elementu <%s> dla motywu \"%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 ""
"Przy typie okna \"%s\" w motywie \"%s\" nie ustawiono stylu ramki. Należy "
"dodać element <window type=\"%s\" style_set=\"cokolwiek\"/>"
#: ../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 ""
"Stałe definiowane przez użytkownika powinny rozpoczynać się wielką literą, "
"natomiast \"%s\" nie spełnia tego warunku"
#: ../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 "Stała \"%s\" została już określona"
#. 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 "Brak atrybutu \"%s\" w elemencie <%s>"
#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281
#, c-format
msgid "Line %d character %d: %s"
msgstr "Wiersz %d, znak %d: %s"
#: ../src/ui/theme-parser.c:481
#, c-format
msgid "Attribute \"%s\" repeated twice on the same <%s> element"
msgstr "Atrybut \"%s\" wystąpił dwukrotnie wewnątrz jednego elementu <%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 ""
"Atrybut \"%s\" jest nieprawidłowy wewnątrz elementu <%s> w tym kontekście"
#: ../src/ui/theme-parser.c:596
#, c-format
msgid "Could not parse \"%s\" as an integer"
msgstr "Nie można przetworzyć \"%s\" jako liczby całkowitej"
#: ../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 "Nie można rozpoznać końcowych znaków \"%s\" w napisie \"%s\""
#: ../src/ui/theme-parser.c:615
#, c-format
msgid "Integer %ld must be positive"
msgstr "Liczba całkowita %ld musi być dodatnia"
#: ../src/ui/theme-parser.c:623
#, c-format
msgid "Integer %ld is too large, current max is %d"
msgstr "Liczba całkowita %ld jest za duża, obecne maksimum to %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 "Napis \"%s\" nie jest zapisem liczby zmiennoprzecinkowej"
#: ../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 "Wartościami logicznymi są \"true\" i \"false\", a nie \"%s\""
#: ../src/ui/theme-parser.c:737
#, c-format
msgid "Angle must be between 0.0 and 360.0, was %g\n"
msgstr "Wartość kąta musi się mieścić pomiędzy 0,0 i 360,0, odczytano %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 ""
"Wartość alfa musi się mieścić pomiędzy 0,0 (niewidoczne) i 1,0 (w pełni "
"nieprzezroczyste), odczytano %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 ""
"Nieprawidłowy rozmiar tytułu \"%s\" (musi on być jedną z wartości: 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>: użyto nazwy \"%s\" po raz drugi"
#: ../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>: nie określono elementu nadrzędnego o nazwie \"%s\""
#: ../src/ui/theme-parser.c:1143
#, c-format
msgid "<%s> geometry \"%s\" has not been defined"
msgstr "<%s>: nie określono geometrii o nazwie \"%s\""
#: ../src/ui/theme-parser.c:1156
#, c-format
msgid "<%s> must specify either a geometry or a parent that has a geometry"
msgstr "<%s> musi albo określać geometrię, albo element nadrzędny z geometrią"
#: ../src/ui/theme-parser.c:1198
msgid "You must specify a background for an alpha value to be meaningful"
msgstr "Aby wartość alfa miała sens, należy określić tło"
#: ../src/ui/theme-parser.c:1266
#, c-format
msgid "Unknown type \"%s\" on <%s> element"
msgstr "Nieznany typ \"%s\" wewnątrz elementu <%s>"
#: ../src/ui/theme-parser.c:1277
#, c-format
msgid "Unknown style_set \"%s\" on <%s> element"
msgstr "Nieznana wartość atrybutu \"style_set\" (%s) wewnątrz elementu <%s>"
#: ../src/ui/theme-parser.c:1285
#, c-format
msgid "Window type \"%s\" has already been assigned a style set"
msgstr "Z typem okna \"%s\" powiązano już zbiór stylów"
#: ../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 "Element <%s> nie jest dopuszczalny poniżej <%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 ""
"Nie można jednocześnie określać dla przycisku jego szerokości i wysokości "
"oraz współczynnika proporcji"
#: ../src/ui/theme-parser.c:1452
#, c-format
msgid "Distance \"%s\" is unknown"
msgstr "Odległość \"%s\" jest nieznana"
#: ../src/ui/theme-parser.c:1497
#, c-format
msgid "Aspect ratio \"%s\" is unknown"
msgstr "Współczynnik proporcji \"%s\" jest nieznany"
#: ../src/ui/theme-parser.c:1559
#, c-format
msgid "Border \"%s\" is unknown"
msgstr "Krawędź \"%s\" jest nieznana"
#: ../src/ui/theme-parser.c:1870
#, c-format
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
msgstr "Brak atrybutu \"start_angle\" wewnątrz elementu <%s>"
#: ../src/ui/theme-parser.c:1877
#, c-format
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
msgstr "Brak atrybutu \"extent_angle\" wewnątrz elementu <%s>"
#: ../src/ui/theme-parser.c:2117
#, c-format
msgid "Did not understand value \"%s\" for type of gradient"
msgstr "Niezrozumiała wartość \"%s\" typu gradientu"
#: ../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 "Niezrozumiały typ wypełnienia \"%s\" elementu <%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 "Niezrozumiały stan \"%s\" (atrybut \"state\") elementu <%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 "Niezrozumiały cień \"%s\" (atrybut \"shadow\") elementu <%s>"
#: ../src/ui/theme-parser.c:2382
#, c-format
msgid "Did not understand arrow \"%s\" for <%s> element"
msgstr "Niezrozumiała strzałka \"%s\" (atrybut \"arrow\") elementu <%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 "Nie określono elementu <draw_ops> o nazwie \"%s\""
#: ../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 ""
"Włączenie tutaj elementu \"draw_ops\" o nazwie \"%s\" spowodowałoby "
"zapętlone odwołanie"
#: ../src/ui/theme-parser.c:2919
#, c-format
msgid "Unknown position \"%s\" for frame piece"
msgstr "Nieznane położenie \"%s\" elementu ramki"
#: ../src/ui/theme-parser.c:2927
#, c-format
msgid "Frame style already has a piece at position %s"
msgstr "Styl ramki zawiera już element o położeniu %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 "Nie określono elementu <draw_ops> o nazwie \"%s\""
#: ../src/ui/theme-parser.c:2974
#, c-format
msgid "Unknown function \"%s\" for button"
msgstr "Nieznana funkcja \"%s\" powiązana z przyciskiem"
#: ../src/ui/theme-parser.c:2984
#, c-format
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
msgstr "Funkcja \"%s\" przycisku nie istnieje w tej wersji (%d, wymaga %d)"
#: ../src/ui/theme-parser.c:2996
#, c-format
msgid "Unknown state \"%s\" for button"
msgstr "Nieznany stan \"%s\" powiązany z przyciskiem"
#: ../src/ui/theme-parser.c:3004
#, c-format
msgid "Frame style already has a button for function %s state %s"
msgstr ""
"Dla stylu ramki określono już przycisk, związany z funkcją %s i stanem %s"
#: ../src/ui/theme-parser.c:3075
#, c-format
msgid "\"%s\" is not a valid value for focus attribute"
msgstr "\"%s\" nie jest prawidłową wartością atrybutu \"focus\""
#: ../src/ui/theme-parser.c:3084
#, c-format
msgid "\"%s\" is not a valid value for state attribute"
msgstr "\"%s\" nie jest prawidłową wartością atrybutu \"state\""
#: ../src/ui/theme-parser.c:3094
#, c-format
msgid "A style called \"%s\" has not been defined"
msgstr "Nie określono stylu o nazwie \"%s\""
#: ../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\" nie jest prawidłową wartością atrybutu \"resize\""
#: ../src/ui/theme-parser.c:3149
#, c-format
msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
"states"
msgstr ""
"Element <%s> nie powinien zawierać atrybutu \"resize\" przy stanie "
"zmaksymalizowanym lub zwiniętym"
#: ../src/ui/theme-parser.c:3163
#, c-format
msgid ""
"Should not have \"resize\" attribute on <%s> element for maximized states"
msgstr ""
"Element <%s> nie powinien zawierać atrybutu \"resize\" przy stanie "
"zmaksymalizowanym"
#: ../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 "Określono już styl dla stanu %s, rozmiaru %s i uaktywnienia %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 "Określono już styl dla stanu %s i uaktywnienia %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 ""
"Element <piece> nie może zawierać dwóch \"draw_ops\" (motyw zawiera atrybut "
"\"draw_ops\" i element <draw_ops> lub dwa elementy)"
#: ../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 ""
"Element <button> nie może zawierać dwóch \"draw_ops\" (motyw zawiera atrybut "
"\"draw_ops\" i element <draw_ops> lub dwa elementy)"
#: ../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 ""
"Element <menu_icon> nie może zawierać dwóch \"draw_ops\" (motyw zawiera "
"atrybut \"draw_ops\" i element <draw_ops> lub dwa elementy)"
#: ../src/ui/theme-parser.c:3433
#, c-format
msgid "Bad version specification '%s'"
msgstr "Błędne określenie wersji \"%s\""
#: ../src/ui/theme-parser.c:3506
msgid ""
"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
"theme-2.xml"
msgstr ""
"Atrybut \"version\" nie może być używany w plikach metacity-theme-1.xml lub "
"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 ""
"Motyw wymaga wersji %s, ale najnowsza obsługiwana wersja motywów to %d.%d"
#: ../src/ui/theme-parser.c:3561
#, c-format
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
msgstr "Głównym elementem motywu musi być <metacity_theme>, nie <%s>"
#: ../src/ui/theme-parser.c:3581
#, c-format
msgid ""
"Element <%s> is not allowed inside a name/author/date/description element"
msgstr ""
"Element <%s> nie jest dopuszczalny wewnątrz elementu name/author/date/"
"description"
#: ../src/ui/theme-parser.c:3586
#, c-format
msgid "Element <%s> is not allowed inside a <constant> element"
msgstr "Element <%s> nie jest dopuszczalny wewnątrz elementu <constant>"
#: ../src/ui/theme-parser.c:3598
#, c-format
msgid ""
"Element <%s> is not allowed inside a distance/border/aspect_ratio element"
msgstr ""
"Element <%s> nie jest dopuszczalny wewnątrz elementu distance/border/"
"aspect_ratio"
#: ../src/ui/theme-parser.c:3620
#, c-format
msgid "Element <%s> is not allowed inside a draw operation element"
msgstr ""
"Element <%s> nie jest dopuszczalny wewnątrz elementu działania rysowania"
#: ../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 "Element <%s> nie jest dopuszczalny wewnątrz elementu <%s>"
#: ../src/ui/theme-parser.c:3898
msgid "No draw_ops provided for frame piece"
msgstr "Brak elementu \"draw_ops\" powiązanego z elementem ramki"
#: ../src/ui/theme-parser.c:3913
msgid "No draw_ops provided for button"
msgstr "Brak elementu \"draw_ops\" powiązanego z przyciskiem"
#: ../src/ui/theme-parser.c:3967
#, c-format
msgid "No text is allowed inside element <%s>"
msgstr "Wewnątrz elementu <%s> nie jest dopuszczalny tekst"
#: ../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> określono dwukrotnie dla tego motywu"
#: ../src/ui/theme-parser.c:4335
#, c-format
msgid "Failed to find a valid file for theme %s\n"
msgstr "Odnalezienie prawidłowego pliku dla motywu %s się nie powiodło\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 ""
"Te okna nie obsługują opcji zapisu obecnego stanu (save current setup”), "
"więc przy następnym zalogowaniu będą musiały zostać uruchomione ręcznie."
"Te okna nie obsługują opcji zapisu aktualnego stanu (\"save current setup"
"\"), więc przy następnym zalogowaniu będą musiały zostać uruchomione ręcznie."
#: ../src/x11/window-props.c:549
#: ../src/x11/window-props.c:515
#, c-format
msgid "%s (on %s)"
msgstr "%s (na %s)"

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

1296
po/ru.po

File diff suppressed because it is too large Load Diff

1453
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

1275
po/sr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1496
po/sv.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

View File

@ -9,7 +9,6 @@ dist_stacking_DATA = \
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
@ -19,9 +18,9 @@ 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
installedtestsbin_PROGRAMS = mutter-test-client mutter-test-runner
else
noinst_PROGRAMS += mutter-test-client mutter-test-runner mutter-test-unit-tests
noinst_PROGRAMS += mutter-test-client mutter-test-runner
endif
EXTRA_DIST += tests/mutter-all.test.in
@ -32,24 +31,21 @@ 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
.PHONY: run-tests run-test-runner-tests run-unit-tests
run-test-runner-tests: mutter-test-client mutter-test-runner
run-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
testgradient_SOURCES = ui/testgradient.c
testasyncgetprop_SOURCES = x11/testasyncgetprop.c
noinst_PROGRAMS += testboxes
noinst_PROGRAMS+=testboxes testgradient testasyncgetprop
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la

View File

@ -6,7 +6,6 @@ lib_LTLIBRARIES = libmutter.la
SUBDIRS=compositor/plugins
EXTRA_DIST =
NULL =
AM_CPPFLAGS = \
-DCLUTTER_ENABLE_COMPOSITOR_API \
@ -32,47 +31,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 +68,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 \
@ -145,14 +119,13 @@ libmutter_la_SOURCES = \
compositor/meta-plugin-manager.c \
compositor/meta-plugin-manager.h \
compositor/meta-shadow-factory.c \
compositor/meta-shadow-factory-private.h \
compositor/meta-shaped-texture.c \
compositor/meta-shaped-texture-private.h \
compositor/meta-surface-actor.c \
compositor/meta-surface-actor.h \
compositor/meta-surface-actor-x11.c \
compositor/meta-surface-actor-x11.h \
compositor/meta-sync-ring.c \
compositor/meta-sync-ring.h \
compositor/meta-texture-rectangle.c \
compositor/meta-texture-rectangle.h \
compositor/meta-texture-tower.c \
@ -162,6 +135,7 @@ 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 \
@ -172,7 +146,6 @@ libmutter_la_SOURCES = \
meta/meta-plugin.h \
meta/meta-shadow-factory.h \
meta/meta-window-actor.h \
meta/meta-window-shape.h \
meta/compositor-mutter.h \
core/constraints.c \
core/constraints.h \
@ -189,6 +162,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 +176,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 +195,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 +213,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 +222,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,8 +233,6 @@ 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 \
@ -266,25 +240,10 @@ libmutter_la_SOURCES += \
wayland/meta-wayland-region.h \
wayland/meta-wayland-data-device.c \
wayland/meta-wayland-data-device.h \
wayland/meta-wayland-data-device-private.h \
wayland/meta-wayland-pointer-gestures.c \
wayland/meta-wayland-pointer-gestures.h \
wayland/meta-wayland-pointer-gesture-swipe.c \
wayland/meta-wayland-pointer-gesture-swipe.h \
wayland/meta-wayland-pointer-gesture-pinch.c \
wayland/meta-wayland-pointer-gesture-pinch.h \
wayland/meta-wayland-keyboard.c \
wayland/meta-wayland-keyboard.h \
wayland/meta-wayland-pointer.c \
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 +254,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,6 +290,7 @@ libmutterinclude_headers = \
meta/compositor.h \
meta/display.h \
meta/errors.h \
meta/gradient.h \
meta/group.h \
meta/keybindings.h \
meta/main.h \
@ -348,33 +302,34 @@ libmutterinclude_headers = \
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)
@ -417,6 +372,7 @@ 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
@ -436,40 +392,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 +453,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

@ -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,37 +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 *
@ -143,19 +108,27 @@ static void
create_device_monitor (MetaBackend *backend,
int device_id)
{
MetaIdleMonitor *idle_monitor;
g_assert (backend->device_monitors[device_id] == NULL);
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);
backend->device_monitors[device_id] = meta_backend_create_idle_monitor (backend, device_id);
backend->device_id_max = MAX (backend->device_id_max, device_id);
}
static void
destroy_device_monitor (MetaBackend *backend,
int device_id)
{
g_hash_table_remove (backend->device_monitors, &device_id);
g_clear_object (&backend->device_monitors[device_id]);
if (device_id == backend->device_id_max)
{
/* Reset the max device ID */
int i, new_max = 0;
for (i = 0; i < backend->device_id_max; i++)
if (backend->device_monitors[i] != NULL)
new_max = i;
backend->device_id_max = new_max;
}
}
static void
@ -169,55 +142,6 @@ on_device_added (ClutterDeviceManager *device_manager,
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,
@ -227,41 +151,6 @@ on_device_removed (ClutterDeviceManager *device_manager,
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,7 +162,7 @@ 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);
@ -281,13 +170,8 @@ meta_backend_real_post_init (MetaBackend *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. */
@ -305,18 +189,10 @@ meta_backend_real_post_init (MetaBackend *backend)
{
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 +234,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 +247,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),
@ -396,12 +260,6 @@ meta_backend_class_init (MetaBackendClass *klass)
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
@ -423,7 +281,9 @@ 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);
return backend->device_monitors[device_id];
}
/**
@ -522,94 +382,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)
{
@ -694,10 +466,7 @@ meta_clutter_init (void)
meta_create_backend ();
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
{
g_warning ("Unable to initialize Clutter.\n");
exit (1);
}
g_error ("Unable to initialize Clutter.\n");
/*
* XXX: We cannot handle high dpi scaling yet, so fix the scale to 1

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,56 @@
/* -*- 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;
int hot_x, hot_y;
#ifdef HAVE_NATIVE_BACKEND
struct gbm_bo *bo;
#endif
} MetaCursorImage;
struct _MetaCursorReference {
int ref_count;
MetaCursor cursor;
MetaCursorImage image;
};
CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
int *hot_x,
int *hot_y);
#ifdef HAVE_NATIVE_BACKEND
struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
int *hot_x,
int *hot_y);
#endif
#endif /* META_CURSOR_PRIVATE_H */

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>
@ -37,8 +38,9 @@
struct _MetaCursorRendererPrivate
{
int current_x, current_y;
MetaRectangle current_rect;
MetaCursorSprite *displayed_cursor;
MetaCursorReference *displayed_cursor;
gboolean handled_by_backend;
};
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
@ -46,33 +48,27 @@ 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);
if (priv->displayed_cursor && !priv->handled_by_backend)
texture = meta_cursor_reference_get_cogl_texture (priv->displayed_cursor, NULL, NULL);
else
texture = NULL;
meta_stage_set_cursor (META_STAGE (stage), texture, &rect);
meta_stage_set_cursor (META_STAGE (stage), texture, &priv->current_rect);
}
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 +84,34 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
{
}
MetaRectangle
meta_cursor_renderer_calculate_rect (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
{
MetaCursorRendererPrivate *priv =
meta_cursor_renderer_get_instance_private (renderer);
CoglTexture *texture;
int hot_x, hot_y;
int width, height;
float texture_scale;
texture = meta_cursor_sprite_get_cogl_texture (cursor_sprite);
if (!texture)
return (MetaRectangle) { 0 };
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
texture_scale = meta_cursor_sprite_get_texture_scale (cursor_sprite);
width = cogl_texture_get_width (texture);
height = cogl_texture_get_height (texture);
return (MetaRectangle) {
.x = (int)roundf (priv->current_x - (hot_x * texture_scale)),
.y = (int)roundf (priv->current_y - (hot_y * texture_scale)),
.width = (int)roundf (width * texture_scale),
.height = (int)roundf (height * texture_scale),
};
}
static void
update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
gboolean handled_by_backend;
gboolean should_redraw = FALSE;
if (cursor_sprite)
meta_cursor_sprite_prepare_at (cursor_sprite,
priv->current_x,
priv->current_y);
if (priv->displayed_cursor)
{
CoglTexture *texture;
int hot_x, hot_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, &hot_x, &hot_y);
priv->current_rect.x = priv->current_x - hot_x;
priv->current_rect.y = priv->current_y - hot_y;
priv->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (texture));
priv->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (texture));
}
else
{
priv->current_rect.x = 0;
priv->current_rect.y = 0;
priv->current_rect.width = 0;
priv->current_rect.height = 0;
}
handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
if (handled_by_backend != priv->handled_by_backend)
{
priv->handled_by_backend = handled_by_backend;
@ -142,7 +122,7 @@ update_cursor (MetaCursorRenderer *renderer,
should_redraw = TRUE;
if (should_redraw)
queue_redraw (renderer, cursor_sprite);
queue_redraw (renderer);
}
MetaCursorRenderer *
@ -152,25 +132,16 @@ 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);
}
void
meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
{
MetaCursorRendererPrivate *priv =
meta_cursor_renderer_get_instance_private (renderer);
update_cursor (renderer, priv->displayed_cursor);
priv->displayed_cursor = cursor;
update_cursor (renderer);
}
void
@ -184,10 +155,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 +166,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->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,22 +309,22 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
int *x,
int *y)
{
MetaCursorSprite *cursor_sprite;
MetaCursorReference *cursor;
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, x, y);
else
{
if (x)
@ -323,10 +335,10 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
}
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 +348,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 +373,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 +436,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,55 @@
#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);
int current_frame;
XcursorImages *xcursor_images;
#ifdef HAVE_NATIVE_BACKEND
if (image->bo)
gbm_bo_destroy (image->bo);
#endif
}
int theme_scale;
gboolean theme_dirty;
};
static void
meta_cursor_reference_free (MetaCursorReference *self)
{
meta_cursor_image_free (&self->image);
g_slice_free (MetaCursorReference, self);
}
G_DEFINE_TYPE (MetaCursorSprite, meta_cursor_sprite, G_TYPE_OBJECT)
void
meta_cursor_reference_unref (MetaCursorReference *self)
{
self->ref_count--;
if (self->ref_count == 0)
meta_cursor_reference_free (self);
}
static const char *
translate_meta_cursor (MetaCursor cursor)
@ -117,27 +134,93 @@ 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 ());
}
#ifdef HAVE_NATIVE_BACKEND
static void
meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *self,
XcursorImage *xc_image)
get_hardware_cursor_size (uint64_t *cursor_width, uint64_t *cursor_height)
{
MetaBackend *meta_backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
{
meta_cursor_renderer_native_get_cursor_size (META_CURSOR_RENDERER_NATIVE (renderer), cursor_width, cursor_height);
return;
}
g_assert_not_reached ();
}
#endif
#ifdef HAVE_NATIVE_BACKEND
static void
meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
MetaCursorImage *image,
uint8_t *pixels,
uint width,
uint height,
int rowstride,
uint32_t gbm_format)
{
uint64_t cursor_width, cursor_height;
get_hardware_cursor_size (&cursor_width, &cursor_height);
if (width > cursor_width || height > cursor_height)
{
meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
(unsigned int)cursor_width, (unsigned int)cursor_height);
return;
}
if (gbm_device_is_format_supported (gbm, gbm_format,
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
{
uint8_t buf[4 * cursor_width * cursor_height];
uint i;
image->bo = gbm_bo_create (gbm, cursor_width, cursor_height,
gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
memset (buf, 0, sizeof(buf));
for (i = 0; i < height; i++)
memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
gbm_bo_write (image->bo, buf, cursor_width * cursor_height * 4);
}
else
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
}
#endif
#ifdef HAVE_NATIVE_BACKEND
static struct gbm_device *
get_gbm_device (void)
{
MetaBackend *meta_backend = meta_get_backend ();
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer));
else
return NULL;
}
#endif
static void
meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
XcursorImage *xc_image)
{
uint width, height, rowstride;
CoglPixelFormat cogl_format;
ClutterBackend *clutter_backend;
CoglContext *cogl_context;
CoglTexture *texture;
g_assert (self->texture == NULL);
width = xc_image->width;
height = xc_image->height;
@ -149,210 +232,177 @@ meta_cursor_sprite_load_from_xcursor_image (MetaCursorSprite *self,
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);
#ifdef HAVE_NATIVE_BACKEND
struct gbm_device *gbm = get_gbm_device ();
if (gbm)
meta_cursor_image_load_gbm_buffer (gbm,
image,
(uint8_t *) xc_image->pixels,
width, height, rowstride,
GBM_FORMAT_ARGB8888);
#endif
}
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;
ClutterBackend *backend;
CoglContext *cogl_context;
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);
#ifdef HAVE_NATIVE_BACKEND
struct gbm_device *gbm = get_gbm_device ();
if (gbm)
{
uint32_t gbm_format;
uint64_t cursor_width, cursor_height;
uint width, height;
width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
if (shm_buffer)
{
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
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 have a predefined size (at least 64x64), which usually is bigger than cursor theme
size, so themed cursors must be padded with transparent pixels to fill the
overlay. This is trivial if we have CPU access to the data, but it's not
possible if the buffer is in GPU memory (and possibly tiled too), so if we
don't get the right size, we fallback to GL.
*/
get_hardware_cursor_size (&cursor_width, &cursor_height);
if (width != cursor_width || height != cursor_height)
{
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
return;
}
image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER, buffer, GBM_BO_USE_CURSOR);
if (!image->bo)
meta_warning ("Importing HW cursor from wl_buffer failed\n");
}
}
#endif
}
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 *hot_x,
int *hot_y)
{
return COGL_TEXTURE (self->texture);
if (hot_x)
*hot_x = cursor->image.hot_x;
if (hot_y)
*hot_y = cursor->image.hot_y;
return COGL_TEXTURE (cursor->image.texture);
}
#ifdef HAVE_NATIVE_BACKEND
struct gbm_bo *
meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
int *hot_x,
int *hot_y)
{
if (hot_x)
*hot_x = cursor->image.hot_x;
if (hot_y)
*hot_y = cursor->image.hot_y;
return cursor->image.bo;
}
#endif
MetaCursor
meta_cursor_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,25 @@
#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 hot_x,
int hot_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))

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,18 +44,6 @@ 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 */
};
static int signals[SIGNALS_LAST];
static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface *iface);
@ -71,96 +58,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 +76,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 +97,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 +110,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 +120,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 +142,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 +150,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,10 +159,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
@ -325,7 +198,7 @@ meta_monitor_manager_constructed (GObject *object)
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 +211,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);
@ -347,78 +237,45 @@ meta_monitor_manager_constructed (GObject *object)
}
void
meta_monitor_manager_clear_output (MetaOutput *output)
{
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);
if (output->driver_notify)
output->driver_notify (output);
memset (output, 0, sizeof (*output));
}
static 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 +283,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);
}
@ -508,16 +365,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 +407,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 +501,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 +521,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 +718,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 +789,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 +808,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 +1088,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 +1162,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>
@ -40,7 +41,6 @@ typedef struct {
struct _MetaStagePrivate {
MetaOverlay cursor_overlay;
gboolean is_active;
};
typedef struct _MetaStagePrivate MetaStagePrivate;
@ -126,41 +126,15 @@ meta_stage_paint (ClutterActor *actor)
meta_overlay_paint (&priv->cursor_overlay);
}
static void
meta_stage_activate (ClutterStage *actor)
{
MetaStage *stage = META_STAGE (actor);
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->activate (actor);
priv->is_active = TRUE;
}
static void
meta_stage_deactivate (ClutterStage *actor)
{
MetaStage *stage = META_STAGE (actor);
MetaStagePrivate *priv = meta_stage_get_instance_private (stage);
CLUTTER_STAGE_CLASS (meta_stage_parent_class)->deactivate (actor);
priv->is_active = FALSE;
}
static void
meta_stage_class_init (MetaStageClass *klass)
{
ClutterStageClass *stage_class = (ClutterStageClass *) klass;
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
GObjectClass *object_class = (GObjectClass *) klass;
object_class->finalize = meta_stage_finalize;
actor_class->paint = meta_stage_paint;
stage_class->activate = meta_stage_activate;
stage_class->deactivate = meta_stage_deactivate;
}
static void
@ -221,43 +195,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

@ -54,9 +54,6 @@ ClutterActor *meta_stage_new (void);
void meta_stage_set_cursor (MetaStage *stage,
CoglTexture *texture,
MetaRectangle *rect);
void meta_stage_set_active (MetaStage *stage,
gboolean is_active);
G_END_DECLS
#endif /* META_STAGE_H */

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,31 +24,20 @@
#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;
GSettings *keyboard_settings;
};
typedef struct _MetaBackendNativePrivate MetaBackendNativePrivate;
@ -60,105 +49,11 @@ 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_clear_object (&priv->keyboard_settings);
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 +63,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 +97,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,43 +133,68 @@ 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 */
constrain_all_screen_monitors(device, monitors, n_monitors, new_x, new_y);
}
static void
set_keyboard_repeat (MetaBackendNative *native)
{
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
gboolean repeat;
unsigned int delay, interval;
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");
clutter_evdev_set_keyboard_repeat (manager, repeat, delay, interval);
}
static void
keyboard_settings_changed (GSettings *settings,
const char *key,
gpointer data)
{
MetaBackendNative *native = data;
set_keyboard_repeat (native);
}
static void
meta_backend_native_post_init (MetaBackend *backend)
{
MetaBackendNative *native = META_BACKEND_NATIVE (backend);
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback,
NULL, NULL);
priv->keyboard_settings = g_settings_new ("org.gnome.settings-daemon.peripherals.keyboard");
g_signal_connect (priv->keyboard_settings, "changed",
G_CALLBACK (keyboard_settings_changed), native);
set_keyboard_repeat (native);
}
static MetaIdleMonitor *
@ -280,16 +225,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
@ -336,19 +276,6 @@ meta_backend_native_lock_layout_group (MetaBackend *backend,
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)
{
@ -366,33 +293,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,15 +314,6 @@ 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:
*

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,16 +26,11 @@
#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"
#include "meta-cursor-private.h"
#include "meta-monitor-manager.h"
#ifndef DRM_CAP_CURSOR_WIDTH
#define DRM_CAP_CURSOR_WIDTH 0x8
@ -44,28 +39,10 @@
#define DRM_CAP_CURSOR_HEIGHT 0x9
#endif
/* When animating a cursor, we usually call drmModeSetCursor2 once per frame.
* Though, testing shows that we need to triple buffer the cursor buffer in
* order to avoid glitches when animating the cursor, at least when running on
* Intel. The reason for this might be (but is not confirmed to be) due to
* the user space gbm_bo cache, making us reuse and overwrite the kernel side
* buffer content before it was scanned out. To avoid this, we keep a user space
* reference to each buffer we set until at least one frame after it was drawn.
* In effect, this means we three active cursor gbm_bo's: one that that just has
* been set, one that was previously set and may or may not have been scanned
* out, and one pending that will be replaced if the cursor sprite changes.
*/
#define HW_CURSOR_BUFFER_COUNT 3
static GQuark quark_cursor_sprite = 0;
struct _MetaCursorRendererNativePrivate
{
gboolean has_hw_cursor;
MetaCursorSprite *last_cursor;
guint animation_timeout_id;
int drm_fd;
struct gbm_device *gbm;
@ -74,167 +51,77 @@ struct _MetaCursorRendererNativePrivate
};
typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate;
typedef enum _MetaCursorGbmBoState
{
META_CURSOR_GBM_BO_STATE_NONE,
META_CURSOR_GBM_BO_STATE_SET,
META_CURSOR_GBM_BO_STATE_INVALIDATED,
} MetaCursorGbmBoState;
typedef struct _MetaCursorNativePrivate
{
guint active_bo;
MetaCursorGbmBoState pending_bo_state;
struct gbm_bo *bos[HW_CURSOR_BUFFER_COUNT];
} MetaCursorNativePrivate;
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_native, META_TYPE_CURSOR_RENDERER);
static MetaCursorNativePrivate *
ensure_cursor_priv (MetaCursorSprite *cursor_sprite);
static void
meta_cursor_renderer_native_finalize (GObject *object)
{
MetaCursorRendererNative *renderer = META_CURSOR_RENDERER_NATIVE (object);
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (renderer);
if (priv->animation_timeout_id)
g_source_remove (priv->animation_timeout_id);
if (priv->gbm)
gbm_device_destroy (priv->gbm);
G_OBJECT_CLASS (meta_cursor_renderer_native_parent_class)->finalize (object);
}
static guint
get_pending_cursor_sprite_gbm_bo_index (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
return (cursor_priv->active_bo + 1) % HW_CURSOR_BUFFER_COUNT;
}
static struct gbm_bo *
get_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
guint pending_bo;
if (!cursor_priv)
return NULL;
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
return cursor_priv->bos[pending_bo];
}
static struct gbm_bo *
get_active_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite)
{
MetaCursorNativePrivate *cursor_priv =
g_object_get_qdata (G_OBJECT (cursor_sprite), quark_cursor_sprite);
if (!cursor_priv)
return NULL;
return cursor_priv->bos[cursor_priv->active_bo];
}
static void
set_pending_cursor_sprite_gbm_bo (MetaCursorSprite *cursor_sprite,
struct gbm_bo *bo)
{
MetaCursorNativePrivate *cursor_priv;
guint pending_bo;
cursor_priv = ensure_cursor_priv (cursor_sprite);
pending_bo = get_pending_cursor_sprite_gbm_bo_index (cursor_sprite);
cursor_priv->bos[pending_bo] = bo;
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_SET;
}
static void
set_crtc_cursor (MetaCursorRendererNative *native,
MetaCRTC *crtc,
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;
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, &hot_x, &hot_y);
handle = gbm_bo_get_handle (bo);
meta_cursor_sprite_get_hotspot (cursor_sprite, &hot_x, &hot_y);
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
priv->cursor_width, priv->cursor_height, hot_x, hot_y);
if (cursor_priv->pending_bo_state == META_CURSOR_GBM_BO_STATE_SET)
{
cursor_priv->active_bo =
(cursor_priv->active_bo + 1) % HW_CURSOR_BUFFER_COUNT;
cursor_priv->pending_bo_state = META_CURSOR_GBM_BO_STATE_NONE;
}
}
else
{
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 +130,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 +166,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 +173,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,7 +192,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);
priv->gbm = gbm_create_device (priv->drm_fd);
uint64_t width, height;
if (drmGetCap (priv->drm_fd, DRM_CAP_CURSOR_WIDTH, &width) == 0 &&
@ -695,8 +218,18 @@ meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *native)
return priv->gbm;
}
void
meta_cursor_renderer_native_get_cursor_size (MetaCursorRendererNative *native,
uint64_t *width, uint64_t *height)
{
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
*width = priv->cursor_width;
*height = priv->cursor_height;
}
void
meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
{
force_update_hw_cursor (native);
update_hw_cursor (native, TRUE);
}

View File

@ -164,36 +164,56 @@ meta_idle_monitor_native_init (MetaIdleMonitorNative *monitor_native)
monitor->watches = g_hash_table_new_full (NULL, NULL, NULL, free_watch);
}
typedef struct {
MetaIdleMonitorNative *monitor_native;
GList *fired_watches;
} CheckNativeClosure;
static gboolean
check_native_watch (gpointer key,
gpointer value,
gpointer user_data)
{
MetaIdleMonitorWatchNative *watch_native = value;
MetaIdleMonitorWatch *watch = (MetaIdleMonitorWatch *) watch_native;
CheckNativeClosure *closure = user_data;
gboolean steal;
if (watch->timeout_msec == 0)
{
closure->fired_watches = g_list_prepend (closure->fired_watches, watch);
steal = TRUE;
}
else
{
g_source_set_ready_time (watch_native->timeout_source,
closure->monitor_native->last_event_time +
watch->timeout_msec * 1000);
steal = FALSE;
}
return steal;
}
static void
fire_native_watch (gpointer watch,
gpointer data)
{
_meta_idle_monitor_watch_fire (watch);
}
void
meta_idle_monitor_native_reset_idletime (MetaIdleMonitor *monitor)
{
MetaIdleMonitorNative *monitor_native = META_IDLE_MONITOR_NATIVE (monitor);
GList *node, *watch_ids;
CheckNativeClosure closure;
monitor_native->last_event_time = g_get_monotonic_time ();
watch_ids = g_hash_table_get_keys (monitor->watches);
closure.monitor_native = monitor_native;
closure.fired_watches = NULL;
g_hash_table_foreach_steal (monitor->watches, check_native_watch, &closure);
for (node = watch_ids; node != NULL; node = node->next)
{
guint watch_id = GPOINTER_TO_UINT (node->data);
MetaIdleMonitorWatchNative *watch;
watch = g_hash_table_lookup (monitor->watches, GUINT_TO_POINTER (watch_id));
if (!watch)
continue;
if (watch->base.timeout_msec == 0)
{
_meta_idle_monitor_watch_fire ((MetaIdleMonitorWatch *) watch);
}
else
{
g_source_set_ready_time (watch->timeout_source,
monitor_native->last_event_time +
watch->base.timeout_msec * 1000);
}
}
g_list_free (watch_ids);
g_list_foreach (closure.fired_watches, fire_native_watch, NULL);
g_list_free (closure.fired_watches);
}

View File

@ -1,264 +0,0 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2014 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Author: Carlos Garnacho <carlosg@gnome.org>
*/
#include "config.h"
#include <clutter/evdev/clutter-evdev.h>
#include <libinput.h>
#include "meta-input-settings-native.h"
G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS)
static void
meta_input_settings_native_set_send_events (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopDeviceSendEvents mode)
{
enum libinput_config_send_events_mode libinput_mode;
struct libinput_device *libinput_device;
switch (mode)
{
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED:
libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
break;
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
break;
case G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED:
libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
break;
default:
g_assert_not_reached ();
}
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
libinput_device_config_send_events_set_mode (libinput_device, libinput_mode);
}
static void
meta_input_settings_native_set_matrix (MetaInputSettings *settings,
ClutterInputDevice *device,
gfloat matrix[6])
{
struct libinput_device *libinput_device;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
if (libinput_device_config_calibration_has_matrix (libinput_device) > 0)
libinput_device_config_calibration_set_matrix (libinput_device, matrix);
}
static void
meta_input_settings_native_set_speed (MetaInputSettings *settings,
ClutterInputDevice *device,
gdouble speed)
{
struct libinput_device *libinput_device;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
libinput_device_config_accel_set_speed (libinput_device,
CLAMP (speed, -1, 1));
}
static void
meta_input_settings_native_set_left_handed (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled)
{
struct libinput_device *libinput_device;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
if (libinput_device_config_left_handed_is_available (libinput_device))
libinput_device_config_left_handed_set (libinput_device, enabled);
}
static void
meta_input_settings_native_set_tap_enabled (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean enabled)
{
struct libinput_device *libinput_device;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
if (libinput_device_config_tap_get_finger_count (libinput_device) > 0)
libinput_device_config_tap_set_enabled (libinput_device,
enabled ?
LIBINPUT_CONFIG_TAP_ENABLED :
LIBINPUT_CONFIG_TAP_DISABLED);
}
static void
meta_input_settings_native_set_invert_scroll (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean inverted)
{
struct libinput_device *libinput_device;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
if (libinput_device_config_scroll_has_natural_scroll (libinput_device))
libinput_device_config_scroll_set_natural_scroll_enabled (libinput_device,
inverted);
}
static gboolean
device_set_scroll_method (struct libinput_device *libinput_device,
enum libinput_config_scroll_method method)
{
enum libinput_config_scroll_method supported;
supported = libinput_device_config_scroll_get_methods (libinput_device);
if (method & supported)
libinput_device_config_scroll_set_method (libinput_device, method);
return (method & supported) != 0;
}
static gboolean
device_set_click_method (struct libinput_device *libinput_device,
enum libinput_config_click_method method)
{
enum libinput_config_click_method supported;
supported = libinput_device_config_click_get_methods (libinput_device);
if (method & supported)
libinput_device_config_click_set_method (libinput_device, method);
return (method & supported) != 0;
}
static void
meta_input_settings_native_set_edge_scroll (MetaInputSettings *settings,
ClutterInputDevice *device,
gboolean edge_scrolling_enabled)
{
enum libinput_config_scroll_method scroll_method = 0;
struct libinput_device *libinput_device;
enum libinput_config_scroll_method supported;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
supported = libinput_device_config_scroll_get_methods (libinput_device);
if (supported & LIBINPUT_CONFIG_SCROLL_2FG)
{
scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
}
else if (supported & LIBINPUT_CONFIG_SCROLL_EDGE &&
edge_scrolling_enabled)
{
scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
}
else
{
scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
}
device_set_scroll_method (libinput_device, scroll_method);
}
static void
meta_input_settings_native_set_scroll_button (MetaInputSettings *settings,
ClutterInputDevice *device,
guint button)
{
struct libinput_device *libinput_device;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
if (!device_set_scroll_method (libinput_device,
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN))
return;
libinput_device_config_scroll_set_button (libinput_device, button);
}
static void
meta_input_settings_native_set_click_method (MetaInputSettings *settings,
ClutterInputDevice *device,
GDesktopTouchpadClickMethod mode)
{
enum libinput_config_click_method click_method = 0;
struct libinput_device *libinput_device;
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
switch (mode)
{
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT:
click_method = libinput_device_config_click_get_default_method (libinput_device);
break;
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE:
click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
break;
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS:
click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
break;
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS:
click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
break;
default:
g_assert_not_reached ();
return;
}
device_set_click_method (libinput_device, click_method);
}
static void
meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings,
gboolean enabled,
guint delay,
guint interval)
{
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
clutter_evdev_set_keyboard_repeat (manager, enabled, delay, interval);
}
static void
meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
{
MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass);
input_settings_class->set_send_events = meta_input_settings_native_set_send_events;
input_settings_class->set_matrix = meta_input_settings_native_set_matrix;
input_settings_class->set_speed = meta_input_settings_native_set_speed;
input_settings_class->set_left_handed = meta_input_settings_native_set_left_handed;
input_settings_class->set_tap_enabled = meta_input_settings_native_set_tap_enabled;
input_settings_class->set_invert_scroll = meta_input_settings_native_set_invert_scroll;
input_settings_class->set_edge_scroll = meta_input_settings_native_set_edge_scroll;
input_settings_class->set_scroll_button = meta_input_settings_native_set_scroll_button;
input_settings_class->set_click_method = meta_input_settings_native_set_click_method;
input_settings_class->set_keyboard_repeat = meta_input_settings_native_set_keyboard_repeat;
}
static void
meta_input_settings_native_init (MetaInputSettingsNative *settings)
{
}

View File

@ -1,49 +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_NATIVE_H
#define META_INPUT_SETTINGS_NATIVE_H
#include "meta-input-settings-private.h"
#define META_TYPE_INPUT_SETTINGS_NATIVE (meta_input_settings_native_get_type ())
#define META_INPUT_SETTINGS_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNative))
#define META_INPUT_SETTINGS_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNativeClass))
#define META_IS_INPUT_SETTINGS_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS_NATIVE))
#define META_IS_INPUT_SETTINGS_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS_NATIVE))
#define META_INPUT_SETTINGS_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNativeClass))
typedef struct _MetaInputSettingsNative MetaInputSettingsNative;
typedef struct _MetaInputSettingsNativeClass MetaInputSettingsNativeClass;
struct _MetaInputSettingsNative
{
MetaInputSettings parent_instance;
};
struct _MetaInputSettingsNativeClass
{
MetaInputSettingsClass parent_class;
};
GType meta_input_settings_native_get_type (void) G_GNUC_CONST;
#endif /* META_INPUT_SETTINGS_NATIVE_H */

View File

@ -37,20 +37,12 @@
#include <unistd.h>
#include <systemd/sd-login.h>
#include <gudev/gudev.h>
#include "dbus-utils.h"
#include "meta-dbus-login1.h"
#include "backends/meta-backend-private.h"
#include "meta-cursor-renderer-native.h"
#include "meta-idle-monitor-native.h"
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevClient, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevEnumerator, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(Login1Session, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(Login1Seat, g_object_unref)
struct _MetaLauncher
{
@ -61,21 +53,14 @@ struct _MetaLauncher
};
static Login1Session *
get_session_proxy (GCancellable *cancellable,
GError **error)
get_session_proxy (GCancellable *cancellable)
{
g_autofree char *proxy_path = NULL;
g_autofree char *session_id = NULL;
char *proxy_path;
char *session_id;
Login1Session *session_proxy;
if (sd_pid_get_session (getpid (), &session_id) < 0)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Could not get session ID: %m");
return NULL;
}
return NULL;
proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/session", session_id);
@ -83,37 +68,31 @@ get_session_proxy (GCancellable *cancellable,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
proxy_path,
cancellable, error);
if (!session_proxy)
g_prefix_error(error, "Could not get session proxy: ");
cancellable, NULL);
free (proxy_path);
return session_proxy;
}
static Login1Seat *
get_seat_proxy (GCancellable *cancellable,
GError **error)
get_seat_proxy (GCancellable *cancellable)
{
Login1Seat *seat = login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
"/org/freedesktop/login1/seat/self",
cancellable, error);
if (!seat)
g_prefix_error(error, "Could not get seat proxy: ");
return seat;
return login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
"org.freedesktop.login1",
"/org/freedesktop/login1/seat/self",
cancellable, NULL);
}
static void
session_unpause (void)
{
ClutterBackend *clutter_backend;
ClutterBackend *backend;
CoglContext *cogl_context;
CoglDisplay *cogl_display;
clutter_backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (backend);
cogl_display = cogl_context_get_display (cogl_context);
cogl_kms_display_queue_modes_reset (cogl_display);
@ -131,7 +110,6 @@ session_unpause (void)
clutter_actor_queue_redraw (stage);
meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer));
meta_idle_monitor_native_reset_idletime (meta_idle_monitor_get_core ());
}
}
@ -150,9 +128,10 @@ take_device (Login1Session *session_proxy,
GCancellable *cancellable,
GError **error)
{
g_autoptr (GVariant) fd_variant = NULL;
g_autoptr (GUnixFDList) fd_list = NULL;
gboolean ret = FALSE;
GVariant *fd_variant = NULL;
int fd = -1;
GUnixFDList *fd_list;
if (!login1_session_call_take_device_sync (session_proxy,
dev_major,
@ -163,14 +142,21 @@ take_device (Login1Session *session_proxy,
&fd_list,
cancellable,
error))
return FALSE;
goto out;
fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), error);
if (fd == -1)
return FALSE;
goto out;
*out_fd = fd;
return TRUE;
ret = TRUE;
out:
if (fd_variant)
g_variant_unref (fd_variant);
if (fd_list)
g_object_unref (fd_list);
return ret;
}
static gboolean
@ -178,16 +164,22 @@ get_device_info_from_path (const char *path,
int *out_major,
int *out_minor)
{
gboolean ret = FALSE;
int r;
struct stat st;
r = stat (path, &st);
if (r < 0 || !S_ISCHR (st.st_mode))
return FALSE;
if (r < 0)
goto out;
if (!S_ISCHR (st.st_mode))
goto out;
*out_major = major (st.st_rdev);
*out_minor = minor (st.st_rdev);
return TRUE;
ret = TRUE;
out:
return ret;
}
static gboolean
@ -195,16 +187,22 @@ get_device_info_from_fd (int fd,
int *out_major,
int *out_minor)
{
gboolean ret = FALSE;
int r;
struct stat st;
r = fstat (fd, &st);
if (r < 0 || !S_ISCHR (st.st_mode))
return FALSE;
if (r < 0)
goto out;
if (!S_ISCHR (st.st_mode))
goto out;
*out_major = major (st.st_rdev);
*out_minor = minor (st.st_rdev);
return TRUE;
ret = TRUE;
out:
return ret;
}
static int
@ -243,7 +241,7 @@ on_evdev_device_close (int fd,
if (!get_device_info_from_fd (fd, &major, &minor))
{
g_warning ("Could not get device info for fd %d: %m", fd);
goto out;
return;
}
if (!login1_session_call_release_device_sync (self->session_proxy,
@ -252,9 +250,6 @@ on_evdev_device_close (int fd,
{
g_warning ("Could not release device %d,%d: %s", major, minor, error->message);
}
out:
close (fd);
}
static void
@ -282,111 +277,25 @@ on_active_changed (Login1Session *session,
sync_active (self);
}
static gchar *
get_primary_gpu_path (const gchar *seat_name)
{
const gchar *subsystems[] = {"drm", NULL};
gchar *path = NULL;
GList *devices, *tmp;
g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems);
g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client);
g_udev_enumerator_add_match_name (enumerator, "card*");
g_udev_enumerator_add_match_tag (enumerator, "seat");
devices = g_udev_enumerator_execute (enumerator);
if (!devices)
goto out;
for (tmp = devices; tmp != NULL; tmp = tmp->next)
{
g_autoptr (GUdevDevice) platform_device = NULL;
g_autoptr (GUdevDevice) pci_device = NULL;
GUdevDevice *dev = tmp->data;
gint boot_vga;
const gchar *device_seat;
/* filter out devices that are not character device, like card0-VGA-1 */
if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
continue;
device_seat = g_udev_device_get_property (dev, "ID_SEAT");
if (!device_seat)
{
/* when ID_SEAT is not set, it means seat0 */
device_seat = "seat0";
}
else if (g_strcmp0 (device_seat, "seat0") != 0)
{
/* if the device has been explicitly assigned other seat
* than seat0, it is probably the right device to use */
path = g_strdup (g_udev_device_get_device_file (dev));
break;
}
/* skip devices that do not belong to our seat */
if (g_strcmp0 (seat_name, device_seat))
continue;
platform_device = g_udev_device_get_parent_with_subsystem (dev, "platform", NULL);
if (platform_device != NULL)
{
path = g_strdup (g_udev_device_get_device_file (dev));
break;
}
pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
if (pci_device != NULL)
{
/* get value of boot_vga attribute or 0 if the device has no boot_vga */
boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
if (boot_vga == 1)
{
/* found the boot_vga device */
path = g_strdup (g_udev_device_get_device_file (dev));
break;
}
}
}
g_list_free_full (devices, g_object_unref);
out:
return path;
}
static gboolean
get_kms_fd (Login1Session *session_proxy,
const gchar *seat_id,
int *fd_out,
GError **error)
int *fd_out)
{
int major, minor;
int fd;
GError *error = NULL;
g_autofree gchar *path = get_primary_gpu_path (seat_id);
if (!path)
/* XXX -- use udev to find the DRM master device */
if (!get_device_info_from_path ("/dev/dri/card0", &major, &minor))
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"could not find drm kms device");
g_warning ("Could not stat /dev/dri/card0: %m");
return FALSE;
}
if (!get_device_info_from_path (path, &major, &minor))
if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Could not get device info for path %s: %m", path);
return FALSE;
}
if (!take_device (session_proxy, major, minor, &fd, NULL, error))
{
g_prefix_error (error, "Could not open DRM device: ");
g_warning ("Could not open DRM device: %s\n", error->message);
g_error_free (error);
return FALSE;
}
@ -395,72 +304,28 @@ get_kms_fd (Login1Session *session_proxy,
return TRUE;
}
static gchar *
get_seat_id (GError **error)
{
g_autofree char *session_id = NULL;
char *seat_id = NULL;
int r;
r = sd_pid_get_session (0, &session_id);
if (r < 0)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Could not get session for PID: %s", g_strerror (-r));
return NULL;
}
r = sd_session_get_seat (session_id, &seat_id);
if (r < 0)
{
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_NOT_FOUND,
"Could not get seat for session: %s", g_strerror (-r));
return NULL;
}
return seat_id;
}
MetaLauncher *
meta_launcher_new (GError **error)
meta_launcher_new (void)
{
MetaLauncher *self = NULL;
g_autoptr (Login1Session) session_proxy = NULL;
g_autoptr (Login1Seat) seat_proxy = NULL;
g_autofree char *seat_id = NULL;
gboolean have_control = FALSE;
MetaLauncher *self;
Login1Session *session_proxy;
GError *error = NULL;
int kms_fd;
session_proxy = get_session_proxy (NULL, error);
if (!session_proxy)
goto fail;
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, error))
session_proxy = get_session_proxy (NULL);
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error))
{
g_prefix_error (error, "Could not take control: ");
goto fail;
g_warning ("Could not take control: %s", error->message);
g_error_free (error);
return NULL;
}
have_control = TRUE;
seat_id = get_seat_id (error);
if (!seat_id)
goto fail;
seat_proxy = get_seat_proxy (NULL, error);
if (!seat_proxy)
goto fail;
if (!get_kms_fd (session_proxy, seat_id, &kms_fd, error))
goto fail;
if (!get_kms_fd (session_proxy, &kms_fd))
return NULL;
self = g_slice_new0 (MetaLauncher);
self->session_proxy = g_object_ref (session_proxy);
self->seat_proxy = g_object_ref (seat_proxy);
self->session_proxy = session_proxy;
self->seat_proxy = get_seat_proxy (NULL);
self->session_active = TRUE;
@ -470,12 +335,8 @@ meta_launcher_new (GError **error)
self);
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
return self;
fail:
if (have_control)
login1_session_call_release_control_sync (session_proxy, NULL, NULL);
return NULL;
return self;
}
void

View File

@ -24,7 +24,7 @@
typedef struct _MetaLauncher MetaLauncher;
MetaLauncher *meta_launcher_new (GError **error);
MetaLauncher *meta_launcher_new (void);
void meta_launcher_free (MetaLauncher *self);
gboolean meta_launcher_activate_session (MetaLauncher *self,

View File

@ -24,7 +24,6 @@
#include "config.h"
#include "meta-monitor-manager-kms.h"
#include "meta-monitor-config.h"
#include <string.h>
#include <stdlib.h>
@ -39,10 +38,7 @@
#include <meta/main.h>
#include <meta/errors.h>
#include <gudev/gudev.h>
#define ALL_TRANSFORMS (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)
#include "edid.h"
typedef struct {
drmModeConnector *connector;
@ -57,22 +53,8 @@ typedef struct {
uint32_t dpms_prop_id;
uint32_t edid_blob_id;
uint32_t tile_blob_id;
int suggested_x;
int suggested_y;
uint32_t hotplug_mode_update;
} MetaOutputKms;
typedef struct {
uint32_t underscan_prop_id;
uint32_t underscan_hborder_prop_id;
uint32_t underscan_vborder_prop_id;
uint32_t primary_plane_id;
uint32_t rotation_prop_id;
uint32_t rotation_map[ALL_TRANSFORMS];
} MetaCRTCKms;
struct _MetaMonitorManagerKms
{
MetaMonitorManager parent_instance;
@ -82,9 +64,10 @@ struct _MetaMonitorManagerKms
drmModeConnector **connectors;
unsigned int n_connectors;
GUdevClient *udev;
drmModeEncoder **encoders;
unsigned int n_encoders;
GSettings *desktop_settings;
drmModeEncoder *current_encoder;
};
struct _MetaMonitorManagerKmsClass
@ -99,9 +82,12 @@ free_resources (MetaMonitorManagerKms *manager_kms)
{
unsigned i;
for (i = 0; i < manager_kms->n_encoders; i++)
drmModeFreeEncoder (manager_kms->encoders[i]);
for (i = 0; i < manager_kms->n_connectors; i++)
drmModeFreeConnector (manager_kms->connectors[i]);
g_free (manager_kms->encoders);
g_free (manager_kms->connectors);
}
@ -120,7 +106,7 @@ make_output_name (drmModeConnector *connector)
static const char * const connector_type_names[] = {
"unknown", "VGA", "DVII", "DVID", "DVID", "Composite",
"SVIDEO", "LVDS", "Component", "9PinDIN", "DisplayPort",
"HDMIA", "HDMIB", "TV", "eDP", "Virtual", "DSI"
"HDMIA", "HDMIB", "TV", "eDP"
};
const char *connector_type_name;
@ -153,12 +139,6 @@ meta_monitor_mode_destroy_notify (MetaMonitorMode *output)
g_slice_free (drmModeModeInfo, output->driver_private);
}
static void
meta_crtc_destroy_notify (MetaCRTC *crtc)
{
g_free (crtc->driver_private);
}
static gboolean
drm_mode_equal (gconstpointer one,
gconstpointer two)
@ -203,69 +183,26 @@ drm_mode_hash (gconstpointer ptr)
}
static void
find_connector_properties (MetaMonitorManagerKms *manager_kms,
MetaOutputKms *output_kms)
find_properties (MetaMonitorManagerKms *manager_kms,
MetaOutputKms *output_kms)
{
drmModePropertyPtr prop;
int i;
output_kms->hotplug_mode_update = 0;
output_kms->suggested_x = -1;
output_kms->suggested_y = -1;
for (i = 0; i < output_kms->connector->count_props; i++)
{
drmModePropertyPtr prop = drmModeGetProperty (manager_kms->fd, output_kms->connector->props[i]);
prop = drmModeGetProperty (manager_kms->fd, output_kms->connector->props[i]);
if (!prop)
continue;
if ((prop->flags & DRM_MODE_PROP_ENUM) && strcmp (prop->name, "DPMS") == 0)
if ((prop->flags & DRM_MODE_PROP_ENUM) &&
strcmp(prop->name, "DPMS") == 0)
output_kms->dpms_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_BLOB) && strcmp (prop->name, "EDID") == 0)
output_kms->edid_blob_id = output_kms->connector->prop_values[i];
else if ((prop->flags & DRM_MODE_PROP_BLOB) &&
strcmp (prop->name, "TILE") == 0)
output_kms->tile_blob_id = output_kms->connector->prop_values[i];
else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
strcmp (prop->name, "suggested X") == 0)
output_kms->suggested_x = output_kms->connector->prop_values[i];
else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
strcmp (prop->name, "suggested Y") == 0)
output_kms->suggested_y = output_kms->connector->prop_values[i];
else if ((prop->flags & DRM_MODE_PROP_RANGE) &&
strcmp (prop->name, "hotplug_mode_update") == 0)
output_kms->hotplug_mode_update = output_kms->connector->prop_values[i];
drmModeFreeProperty (prop);
}
}
strcmp (prop->name, "EDID") == 0)
output_kms->edid_blob_id = output_kms->connector->prop_values[i];
static void
find_crtc_properties (MetaMonitorManagerKms *manager_kms,
MetaCRTC *meta_crtc)
{
MetaCRTCKms *crtc_kms;
drmModeObjectPropertiesPtr props;
size_t i;
crtc_kms = meta_crtc->driver_private;
props = drmModeObjectGetProperties (manager_kms->fd, meta_crtc->crtc_id, DRM_MODE_OBJECT_CRTC);
if (!props)
return;
for (i = 0; i < props->count_props; i++)
{
drmModePropertyPtr prop = drmModeGetProperty (manager_kms->fd, props->props[i]);
if (!prop)
continue;
if ((prop->flags & DRM_MODE_PROP_ENUM) && strcmp (prop->name, "underscan") == 0)
crtc_kms->underscan_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_RANGE) && strcmp (prop->name, "underscan hborder") == 0)
crtc_kms->underscan_hborder_prop_id = prop->prop_id;
else if ((prop->flags & DRM_MODE_PROP_RANGE) && strcmp (prop->name, "underscan vborder") == 0)
crtc_kms->underscan_vborder_prop_id = prop->prop_id;
drmModeFreeProperty (prop);
drmModeFreeProperty(prop);
}
}
@ -287,10 +224,8 @@ read_output_edid (MetaMonitorManagerKms *manager_kms,
}
if (edid_blob->length > 0)
{
return g_bytes_new_with_free_func (edid_blob->data, edid_blob->length,
(GDestroyNotify)drmModeFreePropertyBlob, edid_blob);
}
return g_bytes_new_with_free_func (edid_blob->data, edid_blob->length,
(GDestroyNotify)drmModeFreePropertyBlob, edid_blob);
else
{
drmModeFreePropertyBlob (edid_blob);
@ -298,47 +233,6 @@ read_output_edid (MetaMonitorManagerKms *manager_kms,
}
}
static gboolean
output_get_tile_info (MetaMonitorManagerKms *manager_kms,
MetaOutput *output)
{
MetaOutputKms *output_kms = output->driver_private;
drmModePropertyBlobPtr tile_blob = NULL;
int ret;
if (output_kms->tile_blob_id == 0)
return FALSE;
tile_blob = drmModeGetPropertyBlob (manager_kms->fd, output_kms->tile_blob_id);
if (!tile_blob)
{
meta_warning ("Failed to read TILE of output %s: %s\n", output->name, strerror(errno));
return FALSE;
}
if (tile_blob->length > 0)
{
ret = sscanf ((char *)tile_blob->data, "%d:%d:%d:%d:%d:%d:%d:%d",
&output->tile_info.group_id,
&output->tile_info.flags,
&output->tile_info.max_h_tiles,
&output->tile_info.max_v_tiles,
&output->tile_info.loc_h_tile,
&output->tile_info.loc_v_tile,
&output->tile_info.tile_w,
&output->tile_info.tile_h);
if (ret != 8)
return FALSE;
return TRUE;
}
else
{
drmModeFreePropertyBlob (tile_blob);
return FALSE;
}
}
static MetaMonitorMode *
find_meta_mode (MetaMonitorManager *manager,
const drmModeModeInfo *drm_mode)
@ -369,208 +263,11 @@ find_output_by_id (MetaOutput *outputs,
return NULL;
}
/* The minimum resolution at which we turn on a window-scale of 2 */
#define HIDPI_LIMIT 192
/* The minimum screen height at which we turn on a window-scale of 2;
* below this there just isn't enough vertical real estate for GNOME
* apps to work, and it's better to just be tiny */
#define HIDPI_MIN_HEIGHT 1200
/* From http://en.wikipedia.org/wiki/4K_resolution#Resolutions_of_common_formats */
#define SMALLEST_4K_WIDTH 3656
/* Based on code from gnome-settings-daemon */
static int
compute_scale (MetaOutput *output)
{
int scale = 1;
if (!output->crtc)
goto out;
/* Scaling makes no sense */
if (output->crtc->rect.width < HIDPI_MIN_HEIGHT)
goto out;
/* 4K TV */
if (output->name != NULL && strstr(output->name, "HDMI") != NULL &&
output->crtc->rect.width >= SMALLEST_4K_WIDTH)
goto out;
/* Somebody encoded the aspect ratio (16/9 or 16/10)
* instead of the physical size */
if ((output->width_mm == 160 && output->height_mm == 90) ||
(output->width_mm == 160 && output->height_mm == 100) ||
(output->width_mm == 16 && output->height_mm == 9) ||
(output->width_mm == 16 && output->height_mm == 10))
goto out;
if (output->width_mm > 0 && output->height_mm > 0)
{
double dpi_x, dpi_y;
dpi_x = (double)output->crtc->rect.width / (output->width_mm / 25.4);
dpi_y = (double)output->crtc->rect.height / (output->height_mm / 25.4);
/* We don't completely trust these values so both
must be high, and never pick higher ratio than
2 automatically */
if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT)
scale = 2;
}
out:
return scale;
}
static int
get_output_scale (MetaMonitorManager *manager,
MetaOutput *output)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
int scale = g_settings_get_uint (manager_kms->desktop_settings, "scaling-factor");
if (scale > 0)
return scale;
else
return compute_scale (output);
}
static int
find_property_index (MetaMonitorManager *manager,
drmModeObjectPropertiesPtr props,
const gchar *prop_name,
drmModePropertyPtr *found)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
unsigned int i;
for (i = 0; i < props->count_props; i++)
{
drmModePropertyPtr prop;
prop = drmModeGetProperty (manager_kms->fd, props->props[i]);
if (!prop)
continue;
if (strcmp (prop->name, prop_name) == 0)
{
*found = prop;
return i;
}
drmModeFreeProperty (prop);
}
return -1;
}
static void
parse_transforms (MetaMonitorManager *manager,
drmModePropertyPtr prop,
MetaCRTC *crtc)
{
MetaCRTCKms *crtc_kms = crtc->driver_private;
int i;
for (i = 0; i < prop->count_enums; i++)
{
int cur = -1;
if (strcmp (prop->enums[i].name, "rotate-0") == 0)
cur = META_MONITOR_TRANSFORM_NORMAL;
else if (strcmp (prop->enums[i].name, "rotate-90") == 0)
cur = META_MONITOR_TRANSFORM_90;
else if (strcmp (prop->enums[i].name, "rotate-180") == 0)
cur = META_MONITOR_TRANSFORM_180;
else if (strcmp (prop->enums[i].name, "rotate-270") == 0)
cur = META_MONITOR_TRANSFORM_270;
if (cur != -1)
{
crtc->all_transforms |= 1 << cur;
crtc_kms->rotation_map[cur] = 1 << prop->enums[i].value;
}
}
}
static gboolean
is_primary_plane (MetaMonitorManager *manager,
drmModeObjectPropertiesPtr props)
{
drmModePropertyPtr prop;
int idx;
idx = find_property_index (manager, props, "type", &prop);
if (idx < 0)
return FALSE;
drmModeFreeProperty (prop);
return props->prop_values[idx] == DRM_PLANE_TYPE_PRIMARY;
}
static void
init_crtc_rotations (MetaMonitorManager *manager,
MetaCRTC *crtc,
unsigned int idx)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
drmModeObjectPropertiesPtr props;
drmModePlaneRes *planes;
drmModePlane *drm_plane;
MetaCRTCKms *crtc_kms;
unsigned int i;
crtc_kms = crtc->driver_private;
planes = drmModeGetPlaneResources(manager_kms->fd);
if (planes == NULL)
return;
for (i = 0; i < planes->count_planes; i++)
{
drmModePropertyPtr prop;
drm_plane = drmModeGetPlane (manager_kms->fd, planes->planes[i]);
if (!drm_plane)
continue;
if ((drm_plane->possible_crtcs & (1 << idx)))
{
props = drmModeObjectGetProperties (manager_kms->fd,
drm_plane->plane_id,
DRM_MODE_OBJECT_PLANE);
if (props && is_primary_plane (manager, props))
{
int rotation_idx;
crtc_kms->primary_plane_id = drm_plane->plane_id;
rotation_idx = find_property_index (manager, props, "rotation", &prop);
if (rotation_idx >= 0)
{
crtc_kms->rotation_prop_id = props->props[rotation_idx];
parse_transforms (manager, prop, crtc);
drmModeFreeProperty (prop);
}
}
if (props)
drmModeFreeObjectProperties (props);
}
drmModeFreePlane (drm_plane);
}
drmModeFreePlaneResources (planes);
}
static void
meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
drmModeRes *resources;
drmModeEncoder **encoders;
GHashTable *modes;
GHashTableIter iter;
drmModeModeInfo *mode;
@ -606,7 +303,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
connector = drmModeGetConnector (manager_kms->fd, resources->connectors[i]);
manager_kms->connectors[i] = connector;
if (connector && connector->connection == DRM_MODE_CONNECTED)
if (connector->connection == DRM_MODE_CONNECTED)
{
/* Collect all modes for this connector */
for (j = 0; j < (unsigned)connector->count_modes; j++)
@ -614,9 +311,13 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
}
}
encoders = g_new (drmModeEncoder *, resources->count_encoders);
for (i = 0; i < (unsigned)resources->count_encoders; i++)
encoders[i] = drmModeGetEncoder (manager_kms->fd, resources->encoders[i]);
manager_kms->n_encoders = resources->count_encoders;
manager_kms->encoders = g_new (drmModeEncoder *, manager_kms->n_encoders);
for (i = 0; i < manager_kms->n_encoders; i++)
{
manager_kms->encoders[i] = drmModeGetEncoder (manager_kms->fd,
resources->encoders[i]);
}
manager->n_modes = g_hash_table_size (modes);
manager->modes = g_new0 (MetaMonitorMode, manager->n_modes);
@ -632,18 +333,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_mode->name = g_strndup (mode->name, DRM_DISPLAY_MODE_LEN);
meta_mode->width = mode->hdisplay;
meta_mode->height = mode->vdisplay;
/* Calculate refresh rate in milliHz first for extra precision. */
meta_mode->refresh_rate = (mode->clock * 1000000LL) / mode->htotal;
meta_mode->refresh_rate += (mode->vtotal / 2);
meta_mode->refresh_rate /= mode->vtotal;
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
meta_mode->refresh_rate *= 2;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
meta_mode->refresh_rate /= 2;
if (mode->vscan > 1)
meta_mode->refresh_rate /= mode->vscan;
meta_mode->refresh_rate /= 1000.0;
meta_mode->refresh_rate = (1000 * mode->clock /
((float)mode->htotal * mode->vtotal));
meta_mode->driver_private = g_slice_dup (drmModeModeInfo, mode);
meta_mode->driver_notify = (GDestroyNotify)meta_monitor_mode_destroy_notify;
@ -689,11 +380,6 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
height = MAX (height, meta_crtc->rect.y + meta_crtc->rect.height);
}
meta_crtc->driver_private = g_new0 (MetaCRTCKms, 1);
meta_crtc->driver_notify = (GDestroyNotify) meta_crtc_destroy_notify;
find_crtc_properties (manager_kms, meta_crtc);
init_crtc_rotations (manager, meta_crtc, i);
drmModeFreeCrtc (crtc);
}
@ -715,7 +401,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
connector = manager_kms->connectors[i];
meta_output = &manager->outputs[n_actual_outputs];
if (connector && connector->connection == DRM_MODE_CONNECTED)
if (connector->connection == DRM_MODE_CONNECTED)
{
meta_output->driver_private = output_kms = g_slice_new0 (MetaOutputKms);
meta_output->driver_notify = (GDestroyNotify)meta_output_destroy_notify;
@ -748,17 +434,11 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
break;
}
meta_output->preferred_mode = NULL;
meta_output->n_modes = connector->count_modes;
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
for (j = 0; j < meta_output->n_modes; j++) {
for (j = 0; j < meta_output->n_modes; j++)
meta_output->modes[j] = find_meta_mode (manager, &connector->modes[j]);
if (connector->modes[j].type & DRM_MODE_TYPE_PREFERRED)
meta_output->preferred_mode = meta_output->modes[j];
}
if (!meta_output->preferred_mode)
meta_output->preferred_mode = meta_output->modes[0];
meta_output->preferred_mode = meta_output->modes[0];
output_kms->connector = connector;
output_kms->n_encoders = connector->count_encoders;
@ -768,8 +448,6 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
for (j = 0; j < output_kms->n_encoders; j++)
{
output_kms->encoders[j] = drmModeGetEncoder (manager_kms->fd, connector->encoders[j]);
if (!output_kms->encoders[j])
continue;
/* We only list CRTCs as supported if they are supported by all encoders
for this connectors.
@ -823,21 +501,32 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_output->is_presentation = FALSE;
}
find_connector_properties (manager_kms, output_kms);
meta_output->suggested_x = output_kms->suggested_x;
meta_output->suggested_y = output_kms->suggested_y;
meta_output->hotplug_mode_update = output_kms->hotplug_mode_update;
find_properties (manager_kms, output_kms);
edid = read_output_edid (manager_kms, meta_output);
meta_output_parse_edid (meta_output, edid);
g_bytes_unref (edid);
if (edid)
{
MonitorInfo *parsed_edid;
gsize len;
/* MetaConnectorType matches DRM's connector types */
meta_output->connector_type = (MetaConnectorType) connector->connector_type;
parsed_edid = decode_edid (g_bytes_get_data (edid, &len));
if (parsed_edid)
{
meta_output->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
meta_output->product = g_strndup (parsed_edid->dsc_product_name, 14);
meta_output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
meta_output->scale = get_output_scale (manager, meta_output);
g_free (parsed_edid);
}
output_get_tile_info (manager_kms, meta_output);
g_bytes_unref (edid);
}
if (!meta_output->vendor)
{
meta_output->vendor = g_strdup ("unknown");
meta_output->product = g_strdup ("unknown");
meta_output->serial = g_strdup ("unknown");
}
/* FIXME: backlight is a very driver specific thing unfortunately,
every DDX does its own thing, and the dumb KMS API does not include it.
@ -880,10 +569,9 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
for (j = 0; j < output_kms->n_encoders; j++)
{
for (k = 0; k < (unsigned)resources->count_encoders; k++)
for (k = 0; k < manager_kms->n_encoders; k++)
{
if (output_kms->encoders[j] && encoders[k] &&
output_kms->encoders[j]->encoder_id == encoders[k]->encoder_id)
if (output_kms->encoders[j]->encoder_id == manager_kms->encoders[k]->encoder_id)
{
output_kms->encoder_mask |= (1 << k);
break;
@ -930,10 +618,6 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
}
}
for (i = 0; i < (unsigned)resources->count_encoders; i++)
drmModeFreeEncoder (encoders[i]);
g_free (encoders);
drmModeFreeResources (resources);
}
@ -951,9 +635,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
MetaPowerSave mode)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
ClutterBackend *backend;
CoglContext *cogl_context;
CoglDisplay *cogl_display;
uint64_t state;
unsigned i;
@ -984,23 +665,14 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
if (output_kms->dpms_prop_id != 0)
{
int ok = drmModeObjectSetProperty (manager_kms->fd, meta_output->winsys_id,
DRM_MODE_OBJECT_CONNECTOR,
output_kms->dpms_prop_id, state);
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->winsys_id,
output_kms->dpms_prop_id, state);
if (ok < 0)
meta_warning ("Failed to set power save mode for output %s: %s\n",
meta_output->name, strerror (errno));
}
}
backend = clutter_get_default_backend ();
cogl_context = clutter_backend_get_cogl_context (backend);
cogl_display = cogl_context_get_display (cogl_context);
for (i = 0; i < manager->n_crtcs; i++)
cogl_kms_display_set_ignore_crtc (cogl_display, manager->crtcs[i].crtc_id,
mode != META_POWER_SAVE_ON);
}
static void
@ -1010,48 +682,6 @@ crtc_free (CoglKmsCrtc *crtc)
g_slice_free (CoglKmsCrtc, crtc);
}
static void
set_underscan (MetaMonitorManagerKms *manager_kms,
MetaOutput *output)
{
if (!output->crtc)
return;
MetaCRTC *crtc = output->crtc;
MetaCRTCKms *crtc_kms = crtc->driver_private;
if (!crtc_kms->underscan_prop_id)
return;
if (output->is_underscanning)
{
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_prop_id, (uint64_t) 1);
if (crtc_kms->underscan_hborder_prop_id)
{
uint64_t value = crtc->current_mode->width * 0.05;
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_hborder_prop_id, value);
}
if (crtc_kms->underscan_vborder_prop_id)
{
uint64_t value = crtc->current_mode->height * 0.05;
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_vborder_prop_id, value);
}
}
else
{
drmModeObjectSetProperty (manager_kms->fd, crtc->crtc_id,
DRM_MODE_OBJECT_CRTC,
crtc_kms->underscan_prop_id, (uint64_t) 0);
}
}
static void
meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
MetaCRTCInfo **crtcs,
@ -1059,7 +689,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
MetaOutputInfo **outputs,
unsigned int n_outputs)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
ClutterBackend *backend;
CoglContext *cogl_context;
CoglDisplay *cogl_display;
@ -1075,7 +704,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
{
MetaCRTCInfo *crtc_info = crtcs[i];
MetaCRTC *crtc = crtc_info->crtc;
MetaCRTCKms *crtc_kms = crtc->driver_private;
CoglKmsCrtc *cogl_crtc;
crtc->is_dirty = TRUE;
@ -1148,13 +776,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
crtc->current_mode = mode;
crtc->transform = crtc_info->transform;
}
if (crtc->all_transforms & (1 << crtc->transform))
drmModeObjectSetProperty (manager_kms->fd,
crtc_kms->primary_plane_id,
DRM_MODE_OBJECT_PLANE,
crtc_kms->rotation_prop_id,
crtc_kms->rotation_map[crtc->transform]);
}
/* Disable CRTCs not mentioned in the list (they have is_dirty == FALSE,
@ -1213,9 +834,6 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
output->is_primary = output_info->is_primary;
output->is_presentation = output_info->is_presentation;
output->is_underscanning = output_info->is_underscanning;
set_underscan (manager_kms, output);
}
/* Disable outputs not mentioned in the list */
@ -1275,23 +893,6 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
drmModeCrtcSetGamma (manager_kms->fd, crtc->crtc_id, size, red, green, blue);
}
static void
on_uevent (GUdevClient *client,
const char *action,
GUdevDevice *device,
gpointer user_data)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (user_data);
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
if (!g_udev_device_get_property_as_boolean (device, "HOTPLUG"))
return;
meta_monitor_manager_read_current_config (manager);
meta_monitor_manager_on_hotplug (manager);
}
static void
meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
{
@ -1306,26 +907,6 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
cogl_renderer = cogl_display_get_renderer (cogl_display);
manager_kms->fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
drmSetClientCap (manager_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
const char *subsystems[2] = { "drm", NULL };
manager_kms->udev = g_udev_client_new (subsystems);
g_signal_connect (manager_kms->udev, "uevent",
G_CALLBACK (on_uevent), manager_kms);
manager_kms->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
}
static void
meta_monitor_manager_kms_dispose (GObject *object)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
g_clear_object (&manager_kms->udev);
g_clear_object (&manager_kms->desktop_settings);
G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->dispose (object);
}
static void
@ -1344,7 +925,6 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = meta_monitor_manager_kms_dispose;
object_class->finalize = meta_monitor_manager_kms_finalize;
manager_class->read_current = meta_monitor_manager_kms_read_current;

View File

@ -23,7 +23,7 @@
#ifndef META_MONITOR_MANAGER_KMS_H
#define META_MONITOR_MANAGER_KMS_H
#include "meta-monitor-manager-private.h"
#include "meta-monitor-manager.h"
#define META_TYPE_MONITOR_MANAGER_KMS (meta_monitor_manager_kms_get_type ())
#define META_MONITOR_MANAGER_KMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKms))

View File

@ -40,24 +40,12 @@
#include "meta-idle-monitor-xsync.h"
#include "meta-monitor-manager-xrandr.h"
#include "backends/meta-monitor-manager-dummy.h"
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
#include "meta-cursor-renderer-x11.h"
#ifdef HAVE_WAYLAND
#include "wayland/meta-wayland.h"
#endif
#include <meta/util.h>
#include "display-private.h"
#include "compositor/compositor-private.h"
typedef enum {
/* We're a traditional CM running under the host. */
META_BACKEND_X11_MODE_COMPOSITOR,
/* We're a nested X11 client */
META_BACKEND_X11_MODE_NESTED,
} MetaBackendX11Mode;
struct _MetaBackendX11Private
{
/* The host X11 display */
@ -65,8 +53,6 @@ struct _MetaBackendX11Private
xcb_connection_t *xcb;
GSource *source;
MetaBackendX11Mode mode;
int xsync_event_base;
int xsync_error_base;
@ -82,7 +68,6 @@ struct _MetaBackendX11Private
gchar *keymap_layouts;
gchar *keymap_variants;
gchar *keymap_options;
int locked_group;
};
typedef struct _MetaBackendX11Private MetaBackendX11Private;
@ -94,15 +79,11 @@ static void
handle_alarm_notify (MetaBackend *backend,
XEvent *event)
{
GHashTableIter iter;
gpointer value;
int i;
g_hash_table_iter_init (&iter, backend->device_monitors);
while (g_hash_table_iter_next (&iter, NULL, &value))
{
MetaIdleMonitor *device_monitor = META_IDLE_MONITOR (value);
meta_idle_monitor_xsync_handle_xevent (device_monitor, (XSyncAlarmNotifyEvent*) event);
}
for (i = 0; i <= backend->device_id_max; i++)
if (backend->device_monitors[i])
meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*) event);
}
static void
@ -117,7 +98,7 @@ translate_device_event (MetaBackendX11 *x11,
/* This codepath should only ever trigger as an X11 compositor,
* and never under nested, as under nested all backend events
* should be reported with respect to the stage window. */
g_assert (priv->mode == META_BACKEND_X11_MODE_COMPOSITOR);
g_assert (!meta_is_wayland_compositor ());
device_event->event = stage_window;
@ -144,48 +125,6 @@ translate_device_event (MetaBackendX11 *x11,
}
}
static void
translate_crossing_event (MetaBackendX11 *x11,
XIEnterEvent *enter_event)
{
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
/* Throw out weird events generated by grabs. */
if (enter_event->mode == XINotifyGrab ||
enter_event->mode == XINotifyUngrab)
{
enter_event->event = None;
return;
}
Window stage_window = meta_backend_x11_get_xwindow (x11);
if (enter_event->event != stage_window &&
priv->mode == META_BACKEND_X11_MODE_COMPOSITOR)
{
enter_event->event = meta_backend_x11_get_xwindow (x11);
enter_event->event_x = enter_event->root_x;
enter_event->event_y = enter_event->root_y;
}
}
static void
handle_device_change (MetaBackendX11 *x11,
XIEvent *event)
{
XIDeviceChangedEvent *device_changed;
if (event->evtype != XI_DeviceChanged)
return;
device_changed = (XIDeviceChangedEvent *) event;
if (device_changed->reason != XISlaveSwitch)
return;
meta_backend_update_last_device (META_BACKEND (x11),
device_changed->sourceid);
}
/* Clutter makes the assumption that there is only one X window
* per stage, which is a valid assumption to make for a generic
* application toolkit. As such, it will ignore any events sent
@ -197,32 +136,7 @@ handle_device_change (MetaBackendX11 *x11,
*/
static void
maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
XIEvent *input_event)
{
switch (input_event->evtype)
{
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
case XI_TouchBegin:
case XI_TouchUpdate:
case XI_TouchEnd:
translate_device_event (x11, (XIDeviceEvent *) input_event);
break;
case XI_Enter:
case XI_Leave:
translate_crossing_event (x11, (XIEnterEvent *) input_event);
break;
default:
break;
}
}
static void
handle_input_event (MetaBackendX11 *x11,
XEvent *event)
XEvent *event)
{
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
@ -231,10 +145,21 @@ handle_input_event (MetaBackendX11 *x11,
{
XIEvent *input_event = (XIEvent *) event->xcookie.data;
if (input_event->evtype == XI_DeviceChanged)
handle_device_change (x11, input_event);
else
maybe_spoof_event_as_stage_event (x11, input_event);
switch (input_event->evtype)
{
case XI_Motion:
case XI_ButtonPress:
case XI_ButtonRelease:
case XI_KeyPress:
case XI_KeyRelease:
case XI_TouchBegin:
case XI_TouchUpdate:
case XI_TouchEnd:
translate_device_event (x11, (XIDeviceEvent *) input_event);
break;
default:
break;
}
}
}
@ -274,47 +199,20 @@ handle_host_xevent (MetaBackend *backend,
}
}
if (priv->mode == META_BACKEND_X11_MODE_NESTED && event->type == FocusIn)
{
#ifdef HAVE_WAYLAND
Window xwin = meta_backend_x11_get_xwindow(x11);
XEvent xev;
if (event->xfocus.window == xwin)
{
/* Since we've selected for KeymapStateMask, every FocusIn is followed immediately
* by a KeymapNotify event */
XMaskEvent(priv->xdisplay, KeymapStateMask, &xev);
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
meta_wayland_compositor_update_key_state (compositor, xev.xkeymap.key_vector, 32, 8);
}
#else
g_assert_not_reached ();
#endif
}
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
handle_alarm_notify (backend, event);
if (event->type == priv->xkb_event_base)
{
XkbEvent *xkb_ev = (XkbEvent *) event;
XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID)
if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
{
switch (xkb_ev->any.xkb_type)
switch (xkb_ev->xkb_type)
{
case XkbNewKeyboardNotify:
case XkbMapNotify:
keymap_changed (backend);
break;
case XkbStateNotify:
if (xkb_ev->state.changed & XkbGroupLockMask)
{
if (priv->locked_group != xkb_ev->state.locked_group)
XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, priv->locked_group);
}
break;
default:
break;
}
@ -330,7 +228,7 @@ handle_host_xevent (MetaBackend *backend,
if (!bypass_clutter)
{
handle_input_event (x11, event);
maybe_spoof_event_as_stage_event (x11, event);
clutter_x11_handle_event (event);
}
@ -450,7 +348,6 @@ meta_backend_x11_post_init (MetaBackend *backend)
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
int major, minor;
gboolean has_xi = FALSE;
priv->xdisplay = clutter_x11_get_default_display ();
@ -460,27 +357,29 @@ meta_backend_x11_post_init (MetaBackend *backend)
!XSyncInitialize (priv->xdisplay, &major, &minor))
meta_fatal ("Could not initialize XSync");
if (XQueryExtension (priv->xdisplay,
"XInputExtension",
&priv->xinput_opcode,
&priv->xinput_error_base,
&priv->xinput_event_base))
{
major = 2; minor = 3;
if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
{
int version = (major * 10) + minor;
if (version >= 22)
has_xi = TRUE;
}
}
{
int major = 2, minor = 3;
gboolean has_xi = FALSE;
if (!has_xi)
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
if (XQueryExtension (priv->xdisplay,
"XInputExtension",
&priv->xinput_opcode,
&priv->xinput_error_base,
&priv->xinput_event_base))
{
if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
{
int version = (major * 10) + minor;
if (version >= 22)
has_xi = TRUE;
}
}
/* We only take the passive touch grab if we are a X11 compositor */
if (priv->mode == META_BACKEND_X11_MODE_COMPOSITOR)
take_touch_grab (backend);
if (!has_xi)
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
}
take_touch_grab (backend);
priv->xcb = XGetXCBConnection (priv->xdisplay);
if (!xkb_x11_setup_xkb_extension (priv->xcb,
@ -511,37 +410,19 @@ meta_backend_x11_create_idle_monitor (MetaBackend *backend,
static MetaMonitorManager *
meta_backend_x11_create_monitor_manager (MetaBackend *backend)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
/* If we're a Wayland compositor using the X11 backend,
* we're a nested configuration, so return the dummy
* monitor setup. */
if (meta_is_wayland_compositor ())
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
switch (priv->mode)
{
case META_BACKEND_X11_MODE_COMPOSITOR:
return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
case META_BACKEND_X11_MODE_NESTED:
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
default:
g_assert_not_reached ();
}
return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
}
static MetaCursorRenderer *
meta_backend_x11_create_cursor_renderer (MetaBackend *backend)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
switch (priv->mode)
{
case META_BACKEND_X11_MODE_COMPOSITOR:
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
break;
case META_BACKEND_X11_MODE_NESTED:
return g_object_new (META_TYPE_CURSOR_RENDERER_X11_NESTED, NULL);
break;
default:
g_assert_not_reached ();
}
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
}
static gboolean
@ -769,9 +650,6 @@ meta_backend_x11_get_keymap (MetaBackend *backend)
priv->xcb,
xkb_x11_get_core_keyboard_device_id (priv->xcb),
XKB_KEYMAP_COMPILE_NO_FLAGS);
if (priv->keymap == NULL)
priv->keymap = xkb_keymap_new_from_names (context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS);
xkb_context_unref (context);
}
@ -785,7 +663,6 @@ meta_backend_x11_lock_layout_group (MetaBackend *backend,
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
priv->locked_group = idx;
XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, idx);
}
@ -793,10 +670,7 @@ static void
meta_backend_x11_update_screen_size (MetaBackend *backend,
int width, int height)
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
if (priv->mode == META_BACKEND_X11_MODE_NESTED)
if (meta_is_wayland_compositor ())
{
/* For a nested wayland session, we want to go through Clutter to update the
* toplevel window size, rather than doing it directly.
@ -805,6 +679,8 @@ meta_backend_x11_update_screen_size (MetaBackend *backend,
}
else
{
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
Window xwin = meta_backend_x11_get_xwindow (x11);
XResizeWindow (priv->xdisplay, xwin, width, height);
}
@ -828,36 +704,10 @@ meta_backend_x11_select_stage_events (MetaBackend *backend)
XISetMask (mask.mask, XI_FocusIn);
XISetMask (mask.mask, XI_FocusOut);
XISetMask (mask.mask, XI_Motion);
if (priv->mode == META_BACKEND_X11_MODE_NESTED)
{
/* When we're an X11 compositor, we can't take these events or else
* replaying events from our passive root window grab will cause
* them to come back to us.
*
* When we're a nested application, we want to behave like any other
* application, so select these events like normal apps do.
*/
XISetMask (mask.mask, XI_TouchBegin);
XISetMask (mask.mask, XI_TouchEnd);
XISetMask (mask.mask, XI_TouchUpdate);
}
XIClearMask (mask.mask, XI_TouchBegin);
XIClearMask (mask.mask, XI_TouchEnd);
XIClearMask (mask.mask, XI_TouchUpdate);
XISelectEvents (priv->xdisplay, xwin, &mask, 1);
if (priv->mode == META_BACKEND_X11_MODE_NESTED)
{
/* We have no way of tracking key changes when the stage doesn't have
* focus, so we select for KeymapStateMask so that we get a complete
* dump of the keyboard state in a KeymapNotify event that immediately
* follows each FocusIn (and EnterNotify, but we ignore that.)
*/
XWindowAttributes xwa;
XGetWindowAttributes(priv->xdisplay, xwin, &xwa);
XSelectInput(priv->xdisplay, xwin,
xwa.your_event_mask | FocusChangeMask | KeymapStateMask);
}
}
static void
@ -882,15 +732,8 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
static void
meta_backend_x11_init (MetaBackendX11 *x11)
{
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
/* We do X11 event retrieval ourselves */
clutter_x11_disable_event_retrieval ();
if (meta_is_wayland_compositor ())
priv->mode = META_BACKEND_X11_MODE_NESTED;
else
priv->mode = META_BACKEND_X11_MODE_COMPOSITOR;
}
Display *

View File

@ -1,219 +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>
*/
/**
* SECTION:barrier-x11
* @Title: MetaBarrierImplX11
* @Short_Description: Pointer barriers implementation for X11
*/
#include "config.h"
#ifdef HAVE_XI23
#include <glib-object.h>
#include <X11/extensions/XInput2.h>
#include <X11/extensions/Xfixes.h>
#include <meta/barrier.h>
#include "backends/x11/meta-barrier-x11.h"
#include "display-private.h"
struct _MetaBarrierImplX11Private
{
MetaBarrier *barrier;
PointerBarrier xbarrier;
};
G_DEFINE_TYPE_WITH_PRIVATE (MetaBarrierImplX11, meta_barrier_impl_x11,
META_TYPE_BARRIER_IMPL)
static gboolean
_meta_barrier_impl_x11_is_active (MetaBarrierImpl *impl)
{
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
MetaBarrierImplX11Private *priv =
meta_barrier_impl_x11_get_instance_private (self);
return priv->xbarrier != 0;
}
static void
_meta_barrier_impl_x11_release (MetaBarrierImpl *impl,
MetaBarrierEvent *event)
{
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
MetaBarrierImplX11Private *priv =
meta_barrier_impl_x11_get_instance_private (self);
MetaDisplay *display = priv->barrier->priv->display;
if (META_DISPLAY_HAS_XINPUT_23 (display))
{
XIBarrierReleasePointer (display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
priv->xbarrier, event->event_id);
}
}
static void
_meta_barrier_impl_x11_destroy (MetaBarrierImpl *impl)
{
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
MetaBarrierImplX11Private *priv =
meta_barrier_impl_x11_get_instance_private (self);
MetaDisplay *display = priv->barrier->priv->display;
Display *dpy;
if (display == NULL)
return;
dpy = display->xdisplay;
if (!meta_barrier_is_active (priv->barrier))
return;
XFixesDestroyPointerBarrier (dpy, priv->xbarrier);
g_hash_table_remove (display->xids, &priv->xbarrier);
priv->xbarrier = 0;
}
MetaBarrierImpl *
meta_barrier_impl_x11_new (MetaBarrier *barrier)
{
MetaBarrierImplX11 *self;
MetaBarrierImplX11Private *priv;
MetaDisplay *display = barrier->priv->display;
Display *dpy;
Window root;
unsigned int allowed_motion_dirs;
if (display == NULL)
{
g_warning ("A display must be provided when constructing a barrier.");
return NULL;
}
self = g_object_new (META_TYPE_BARRIER_IMPL_X11, NULL);
priv = meta_barrier_impl_x11_get_instance_private (self);
priv->barrier = barrier;
dpy = display->xdisplay;
root = DefaultRootWindow (dpy);
allowed_motion_dirs =
meta_border_get_allows_directions (&barrier->priv->border);
priv->xbarrier = XFixesCreatePointerBarrier (dpy, root,
barrier->priv->border.line.a.x,
barrier->priv->border.line.a.y,
barrier->priv->border.line.b.x,
barrier->priv->border.line.b.y,
allowed_motion_dirs,
0, NULL);
g_hash_table_insert (display->xids, &priv->xbarrier, barrier);
return META_BARRIER_IMPL (self);
}
static void
meta_barrier_fire_xevent (MetaBarrier *barrier,
XIBarrierEvent *xevent)
{
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
event->ref_count = 1;
event->event_id = xevent->eventid;
event->time = xevent->time;
event->dt = xevent->dtime;
event->x = xevent->root_x;
event->y = xevent->root_y;
event->dx = xevent->dx;
event->dy = xevent->dy;
event->released = (xevent->flags & XIBarrierPointerReleased) != 0;
event->grabbed = (xevent->flags & XIBarrierDeviceIsGrabbed) != 0;
switch (xevent->evtype)
{
case XI_BarrierHit:
_meta_barrier_emit_hit_signal (barrier, event);
break;
case XI_BarrierLeave:
_meta_barrier_emit_left_signal (barrier, event);
break;
default:
g_assert_not_reached ();
}
meta_barrier_event_unref (event);
}
gboolean
meta_display_process_barrier_xevent (MetaDisplay *display,
XIEvent *event)
{
MetaBarrier *barrier;
XIBarrierEvent *xev;
if (event == NULL)
return FALSE;
switch (event->evtype)
{
case XI_BarrierHit:
case XI_BarrierLeave:
break;
default:
return FALSE;
}
xev = (XIBarrierEvent *) event;
barrier = g_hash_table_lookup (display->xids, &xev->barrier);
if (barrier != NULL)
{
meta_barrier_fire_xevent (barrier, xev);
return TRUE;
}
return FALSE;
}
static void
meta_barrier_impl_x11_class_init (MetaBarrierImplX11Class *klass)
{
MetaBarrierImplClass *impl_class = META_BARRIER_IMPL_CLASS (klass);
impl_class->is_active = _meta_barrier_impl_x11_is_active;
impl_class->release = _meta_barrier_impl_x11_release;
impl_class->destroy = _meta_barrier_impl_x11_destroy;
}
static void
meta_barrier_impl_x11_init (MetaBarrierImplX11 *self)
{
}
#endif /* HAVE_XI23 */

View File

@ -1,59 +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_X11_H
#define META_BARRIER_X11_H
#include "backends/meta-barrier-private.h"
G_BEGIN_DECLS
#define META_TYPE_BARRIER_IMPL_X11 (meta_barrier_impl_x11_get_type ())
#define META_BARRIER_IMPL_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER_IMPL_X11, MetaBarrierImplX11))
#define META_BARRIER_IMPL_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER_IMPL_X11, MetaBarrierImplX11Class))
#define META_IS_BARRIER_IMPL_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER_IMPL_X11))
#define META_IS_BARRIER_IMPL_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER_IMPL_X11))
#define META_BARRIER_IMPL_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER_IMPL_X11, MetaBarrierImplX11Class))
typedef struct _MetaBarrierImplX11 MetaBarrierImplX11;
typedef struct _MetaBarrierImplX11Class MetaBarrierImplX11Class;
typedef struct _MetaBarrierImplX11Private MetaBarrierImplX11Private;
struct _MetaBarrierImplX11
{
MetaBarrierImpl parent;
};
struct _MetaBarrierImplX11Class
{
MetaBarrierImplClass parent_class;
};
GType meta_barrier_impl_x11_get_type (void) G_GNUC_CONST;
MetaBarrierImpl *meta_barrier_impl_x11_new (MetaBarrier *barrier);
G_END_DECLS
#endif /* META_BARRIER_X11_H1 */

View File

@ -26,8 +26,6 @@
#include "meta-cursor-renderer-x11.h"
#include <X11/extensions/Xfixes.h>
#include "meta-backend-x11.h"
#include "meta-stage.h"
@ -40,29 +38,25 @@ typedef struct _MetaCursorRendererX11Private MetaCursorRendererX11Private;
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER);
static gboolean
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer)
{
MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer);
MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11);
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
Window xwindow = meta_backend_x11_get_xwindow (backend);
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
if (xwindow == None)
{
if (cursor_sprite)
meta_cursor_sprite_realize_texture (cursor_sprite);
return FALSE;
}
return FALSE;
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
MetaCursorReference *cursor_ref = meta_cursor_renderer_get_cursor (renderer);
gboolean has_server_cursor = FALSE;
if (cursor_sprite)
if (cursor_ref)
{
MetaCursor cursor = meta_cursor_sprite_get_meta_cursor (cursor_sprite);
MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref);
if (cursor != META_CURSOR_NONE)
{
Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor);
@ -84,9 +78,6 @@ meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer,
priv->server_cursor_visible = has_server_cursor;
}
if (!priv->server_cursor_visible && cursor_sprite)
meta_cursor_sprite_realize_texture (cursor_sprite);
return priv->server_cursor_visible;
}

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