Compare commits
4 Commits
3.10.1-way
...
wip/waylan
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10fbaf7695 | ||
|
|
ef73402654 | ||
|
|
22cdf2d650 | ||
|
|
284b497b4c |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -48,11 +48,10 @@ po/*.pot
|
||||
50-metacity-key.xml
|
||||
libmutter-wayland.pc
|
||||
mutter-wayland
|
||||
mutter-launch
|
||||
mutter-theme-viewer
|
||||
mutter-wayland.desktop
|
||||
org.gnome.mutter.gschema.valid
|
||||
org.gnome.mutter.gschema.xml
|
||||
org.gnome.mutter.wayland.gschema.valid
|
||||
org.gnome.mutter.wayland.gschema.xml
|
||||
testasyncgetprop
|
||||
testboxes
|
||||
testgradient
|
||||
@@ -78,12 +77,6 @@ src/stamp-mutter-marshal.h
|
||||
src/meta-dbus-xrandr.[ch]
|
||||
src/meta-dbus-idle-monitor.[ch]
|
||||
src/mutter-plugins.pc
|
||||
src/wayland/gtk-shell-protocol.c
|
||||
src/wayland/gtk-shell-client-protocol.h
|
||||
src/wayland/gtk-shell-server-protocol.h
|
||||
src/wayland/xserver-protocol.c
|
||||
src/wayland/xserver-client-protocol.h
|
||||
src/wayland/xserver-server-protocol.h
|
||||
doc/reference/*.args
|
||||
doc/reference/*.bak
|
||||
doc/reference/*.hierarchy
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
SUBDIRS=src protocol po doc
|
||||
SUBDIRS=src protocol data po doc
|
||||
|
||||
EXTRA_DIST = HACKING MAINTAINERS rationales.txt
|
||||
|
||||
|
||||
88
NEWS
88
NEWS
@@ -1,91 +1,3 @@
|
||||
3.10.1
|
||||
======
|
||||
* Don't apply fullscreen workarounds to CSD windows [Giovanni; #708718]
|
||||
* Fix hangs during DND operations [Adel; #709340]
|
||||
* Misc bug fixes [Dan, Giovanni, Jasper; #708813, #708420]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Adel Gadllah, Dan Horák, Hans Petter Jansson,
|
||||
Jasper St. Pierre
|
||||
|
||||
3.10.0.1
|
||||
========
|
||||
* Fix bug when a window changed size twice in a single frame - this
|
||||
can happen with GTK+ client-side decorations [Giovanni, Owen; #708367]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Owen Taylor
|
||||
|
||||
3.10.0
|
||||
======
|
||||
* Update dependencies [Giovanni; #708210]
|
||||
|
||||
3.9.92
|
||||
======
|
||||
* Constrain the pointer position onto visible monitors [Giovanni; #706655]
|
||||
* Fix keyboard state handling in face of event compression [Giovanni; #706963]
|
||||
* Extend the MetaCursorTracker API with query pointer and cursor visibility [Giovanni; #707474]
|
||||
* Be stricter in checking and exposing the wayland protocol version [#707851]
|
||||
* Don't require plugins to pass event to Clutter [Giovanni; #707482]
|
||||
* Move the --wayland option from the binary to the library [Giovanni; #707897]
|
||||
* Implement running from gnome-session (environment variable setting, process group
|
||||
handling, Clutter backend variables) [Giovanni; #706421]
|
||||
* Add support for more cursor types [Giovanni; #707919]
|
||||
* Drop man pages for removed utilities [Kalev; #706579]
|
||||
* Implement monitor configuration on KMS [Giovanni; #706308]
|
||||
* Implement HW cursors [Giovanni; #707573]
|
||||
* Implement minimal support for resizing and maximizing wayland clients [Giovanni; #707401]
|
||||
* Implement transient hints for wayland clients [Giovanni; #707401]
|
||||
* Implement popup menu surfaces and grabs [Giovanni; #707863]
|
||||
* Immediately fire idle watches that are already expired [Giovanni; #707302]
|
||||
* Remove holes generated by disabling the laptop lid [Giovanni; #707473]
|
||||
* Misc bug fixes [Giovanni, Pavel, Adel; #707649, #706124, #707584, #707851, #707929,
|
||||
#708070]
|
||||
|
||||
Contributors:
|
||||
Adel Gadllah, Giovanni Campagna, Kalev Lember, Pavel Vasin
|
||||
|
||||
Translations:
|
||||
Мирослав Николић po/sr, sr@latin.po, Мирослав Николић [sr, sr@latin],
|
||||
Chao-Hsiung Liao [zh_HK, zh_TW], Yuri Myasoedov [ru],
|
||||
Ville-Pekka Vainio [fi], Changwoo Ryu [ko], A S Alam [pa],
|
||||
Mattias Põldaru [et], Rūdolfs Mazurs [lv], Ihar Hrachyshka [be],
|
||||
Nilamdyuti Goswami [as], Andika Triwidada [id], Baurzhan Muftakhidinov [kk],
|
||||
Benjamin Steinwender [de]
|
||||
|
||||
3.9.91
|
||||
======
|
||||
* Drop man pages for removed utilities [Kalev; #706579]
|
||||
* Add support for idle tracking [Giovanni, Cosimo; #706005, #707250]
|
||||
* Skip CRTC reconfigurations that have no effect [Giovanni; #706672]
|
||||
* Ignore skip-taskbar hints on parentless dialogs [Giovanni; #673399]
|
||||
* Don't save pixbuf data in user data [Tim; #706777]
|
||||
* Don't queue redraws for obscured regions [Adel; #703332]
|
||||
* Suppor the opaque region hints for wayland clients [Jasper; #707019]
|
||||
* Turn blending off when drawing entirely opaque regions [Jasper; #707019]
|
||||
* Check event timestamps before reconfiguring [Giovanni; #706735]
|
||||
* Merge the DBus API for display configuration in the wayland branch [Giovanni]
|
||||
* Install an X IO error handler for XWayland [Giovanni; #706962]
|
||||
* Use the clutter xkbcommon integration for the wayland keyboard [Giovanni; #705862]
|
||||
* Add a setuid helper for running on KMS+evdev [Giovanni, Colin; #705861]
|
||||
* Add keybindings for switching VT [Giovanni; #705861]
|
||||
* Implement plugin modality when running as a wayland compositor [Giovanni; #705917]
|
||||
* Add support for the application menu for wayland clients [Giovanni; #707128]
|
||||
* Several Coverity spotted fixes [Jasper]
|
||||
* Don't create a dummy texture for the texture template [Neil; #707458]
|
||||
* Use a more conservative paint volume for obscured windows [Adel]
|
||||
* Misc bug fixes [Giovanni, Colin, Seán, Jasper, Cosimo; #706582, #706598,
|
||||
#706787, #706729, #706825, #707081, #707090, #707267, #706982, #706289]
|
||||
|
||||
Contributors:
|
||||
Giovanni Campagna, Cosimo Cecchi, Adel Gadllah, Colin Guthrie, Kalev Lember,
|
||||
Tim Lunn, Jasper St. Pierre, Neil Roberts, Rico Tzschichholz, Seán de Búrca
|
||||
|
||||
Translations:
|
||||
Piotr Drąg [pl], Alexandre Franke [fr], Kjartan Maraas [nb],
|
||||
Milo Casagrande [it], Balázs Úr [hu], Seán de Búrca [ga], Fran Diéguez [gl],
|
||||
Daniel Mustieles [es], Aurimas Černius [lt], Gil Forcada [ca]
|
||||
|
||||
3.9.90
|
||||
======
|
||||
* First release from the wayland branch, includes basic support for running
|
||||
|
||||
29
configure.ac
29
configure.ac
@@ -1,8 +1,8 @@
|
||||
AC_PREREQ(2.50)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [10])
|
||||
m4_define([mutter_micro_version], [1])
|
||||
m4_define([mutter_minor_version], [9])
|
||||
m4_define([mutter_micro_version], [90])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -77,7 +77,7 @@ MUTTER_PC_MODULES="
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.7.3
|
||||
xcomposite >= 0.2 xfixes xrender xdamage xi >= 1.6.0
|
||||
$CLUTTER_PACKAGE >= 1.15.94
|
||||
$CLUTTER_PACKAGE >= 1.14.3
|
||||
cogl-1.0 >= 1.13.3
|
||||
upower-glib > 0.9.11
|
||||
gnome-desktop-3.0
|
||||
@@ -139,12 +139,6 @@ AM_GLIB_GNU_GETTEXT
|
||||
## here we get the flags we'll actually use
|
||||
# GRegex requires Glib-2.14.0
|
||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
|
||||
PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login)
|
||||
|
||||
saved_LIBS="$LIBS"
|
||||
LIBS="$LIBS $MUTTER_LAUNCH"
|
||||
AC_CHECK_FUNCS([sd_session_get_vt])
|
||||
LIBS="$saved_LIBS"
|
||||
|
||||
# Unconditionally use this dir to avoid a circular dep with gnomecc
|
||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
||||
@@ -209,7 +203,19 @@ if test x$found_introspection != xno; then
|
||||
AC_SUBST(META_GIR)
|
||||
fi
|
||||
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcursor"
|
||||
AC_MSG_CHECKING([Xcursor])
|
||||
if $PKG_CONFIG xcursor; then
|
||||
have_xcursor=yes
|
||||
else
|
||||
have_xcursor=no
|
||||
fi
|
||||
AC_MSG_RESULT($have_xcursor)
|
||||
|
||||
if test x$have_xcursor = xyes; then
|
||||
echo "Building with Xcursor"
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcursor"
|
||||
AC_DEFINE(HAVE_XCURSOR, , [Building with Xcursor support])
|
||||
fi
|
||||
|
||||
# We always build with wayland enabled
|
||||
AC_DEFINE(HAVE_WAYLAND, , [Building with Wayland support])
|
||||
@@ -220,7 +226,7 @@ AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_SUBST(XWAYLAND_PATH)
|
||||
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server libdrm"
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES wayland-server"
|
||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
||||
|
||||
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
|
||||
@@ -461,6 +467,7 @@ src/Makefile
|
||||
src/libmutter-wayland.pc
|
||||
src/compositor/plugins/Makefile
|
||||
protocol/Makefile
|
||||
data/Makefile
|
||||
po/Makefile.in
|
||||
])
|
||||
|
||||
|
||||
3
data/Makefile.am
Normal file
3
data/Makefile.am
Normal file
@@ -0,0 +1,3 @@
|
||||
defaultcursordir = $(pkgdatadir)/cursors
|
||||
|
||||
dist_defaultcursor_DATA = left_ptr.png
|
||||
BIN
data/left_ptr.png
Normal file
BIN
data/left_ptr.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 736 B |
@@ -1,3 +1,4 @@
|
||||
man_MANS = mutter.1
|
||||
man_MANS = mutter.1 mutter-theme-viewer.1 \
|
||||
mutter-window-demo.1 mutter-message.1
|
||||
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
|
||||
60
doc/man/mutter-message.1
Normal file
60
doc/man/mutter-message.1
Normal file
@@ -0,0 +1,60 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.\" First parameter, NAME, should be all caps
|
||||
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
||||
.\" other parameters are allowed: see man(7), man(1)
|
||||
.\" -----
|
||||
.\" This file was confirmed to be licenced under the GPL
|
||||
.\" by its author and copyright holder, Akira TAGOH, on June 1st 2008:
|
||||
.\"
|
||||
.\" > I'm comfortable with DFSG-free. that sounds great if you think it's
|
||||
.\" > useful and worth containing it in upstream.
|
||||
.\" ...
|
||||
.\" > Right I know. any licenses that is DFSG-free, I'm ok with whatever,
|
||||
.\" > since I have contributed that for Debian. so GPL is no problem for me.
|
||||
.\" -----
|
||||
.TH MUTTER\-MESSAGE 1 "28 August 2002"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
.\" .nh disable hyphenation
|
||||
.\" .hy enable hyphenation
|
||||
.\" .ad l left justify
|
||||
.\" .ad b justify to both left and right margins
|
||||
.\" .nf disable filling
|
||||
.\" .fi enable filling
|
||||
.\" .br insert line break
|
||||
.\" .sp <n> insert n+1 empty lines
|
||||
.\" for manpage-specific macros, see man(7)
|
||||
.SH NAME
|
||||
MUTTER\-MESSAGE \- a command to send a message to Mutter
|
||||
.SH SYNOPSIS
|
||||
.B MUTTER\-MESSAGE
|
||||
[restart|reload\-theme|enable\-keybindings|disable\-keybindings]
|
||||
.SH DESCRIPTION
|
||||
This manual page documents briefly the
|
||||
.B mutter\-message\fP.
|
||||
This manual page was written for the Debian distribution
|
||||
because the original program does not have a manual page.
|
||||
.PP
|
||||
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
|
||||
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
|
||||
.\" respectively.
|
||||
\fBmutter\-message\fP send a specified message to \fBmutter\fP(1).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B restart
|
||||
Restart \fBmutter\fP(1) which is running.
|
||||
.TP
|
||||
.B reload-theme
|
||||
Reload a theme which is specified on gsettings database.
|
||||
.TP
|
||||
.B enable-keybindings
|
||||
Enable all of keybindings which is specified on gsettings database.
|
||||
.TP
|
||||
.B disable-keybindings
|
||||
Disable all of keybindings which is specified on gsettings database.
|
||||
.SH SEE ALSO
|
||||
.BR mutter (1)
|
||||
.SH AUTHOR
|
||||
This manual page was written by Akira TAGOH <tagoh@debian.org>,
|
||||
for the Debian GNU/Linux system (but may be used by others).
|
||||
43
doc/man/mutter-theme-viewer.1
Normal file
43
doc/man/mutter-theme-viewer.1
Normal file
@@ -0,0 +1,43 @@
|
||||
.\" In .TH, FOO should be all caps, SECTION should be 1-8, maybe w/ subsection
|
||||
.\" other parms are allowed: see man(7), man(1)
|
||||
.\"
|
||||
.\" Based on template provided by Tom Christiansen <tchrist@jhereg.perl.com>.
|
||||
.\"
|
||||
.TH MUTTER-THEME-VIEWER 1 "1 June 2004"
|
||||
.SH NAME
|
||||
mutter-theme-viewer \- view mutter themes
|
||||
.SH SYNOPSIS
|
||||
.B mutter-theme-viewer
|
||||
[
|
||||
.I THEMENAME
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.\" Putting a newline after each sentence can generate better output.
|
||||
.B mutter-theme-viewer
|
||||
allows you to preview any installed Mutter theme.
|
||||
.PP
|
||||
When designing a new Mutter theme, you can use
|
||||
.B mutter-theme-viewer
|
||||
to measure the performance of a window frame option, and to preview
|
||||
the option.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I THEMENAME
|
||||
Name of the theme to be shown (\fIAtlanta\fR by default).
|
||||
It is case-sensitive.
|
||||
.SH FILES
|
||||
.br
|
||||
.nf
|
||||
.TP
|
||||
.I /usr/share/themes
|
||||
system themes directory
|
||||
.TP
|
||||
.I /usr/share/themes/*/mutter-1/mutter-theme-1.xml
|
||||
theme specification file
|
||||
.SH AUTHOR
|
||||
This manual page was written by Jose M. Moya <josem@die.upm.es>, for
|
||||
the Debian GNU/Linux system (but may be used by others).
|
||||
.SH "SEE ALSO"
|
||||
.\" Always quote multiple words for .SH
|
||||
.BR mutter (1),
|
||||
.BR mutter-window-demo (1).
|
||||
25
doc/man/mutter-window-demo.1
Normal file
25
doc/man/mutter-window-demo.1
Normal file
@@ -0,0 +1,25 @@
|
||||
.\" In .TH, FOO should be all caps, SECTION should be 1-8, maybe w/ subsection
|
||||
.\" other parms are allowed: see man(7), man(1)
|
||||
.\"
|
||||
.\" Based on template provided by Tom Christiansen <tchrist@jhereg.perl.com>.
|
||||
.\"
|
||||
.TH MUTTER-WINDOW-DEMO 1 "1 June 2004"
|
||||
.SH NAME
|
||||
mutter-window-demo \- demo of window features
|
||||
.SH SYNOPSIS
|
||||
.B mutter-window-demo
|
||||
.SH DESCRIPTION
|
||||
.\" Putting a newline after each sentence can generate better output.
|
||||
This program demonstrates various kinds of windows that window
|
||||
managers and window manager themes should handle.
|
||||
.PP
|
||||
Be sure to tear off the menu and toolbar, those are also a special
|
||||
kind of window.
|
||||
.SH AUTHOR
|
||||
This manual page was written by Jose M. Moya <josem@die.upm.es>, for
|
||||
the Debian GNU/Linux system (but may be used by others).
|
||||
.SH "SEE ALSO"
|
||||
.\" Always quote multiple words for .SH
|
||||
.BR x-window-manager (1),
|
||||
.BR mutter (1),
|
||||
.BR mutter-theme-viewer (1).
|
||||
@@ -44,7 +44,6 @@ is
|
||||
it
|
||||
ja
|
||||
ka
|
||||
kk
|
||||
kn
|
||||
ko
|
||||
ku
|
||||
|
||||
@@ -21,9 +21,9 @@ src/core/util.c
|
||||
src/core/window.c
|
||||
src/core/window-props.c
|
||||
src/core/xprops.c
|
||||
src/mutter-wayland.desktop.in
|
||||
src/mutter.desktop.in
|
||||
src/mutter-wm.desktop.in
|
||||
src/org.gnome.mutter.gschema.xml.in
|
||||
src/org.gnome.mutter.wayland.gschema.xml.in
|
||||
src/ui/frames.c
|
||||
src/ui/menu.c
|
||||
src/ui/metaaccellabel.c
|
||||
|
||||
441
po/be.po
441
po/be.po
@@ -1,10 +1,10 @@
|
||||
# Ihar Hrachyshka <ihar.hrachyshka@gmail.com>, 2011, 2013.
|
||||
# Ihar Hrachyshka <ihar.hrachyshka@gmail.com>, 2011.
|
||||
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: 2013-08-18 20:03+0000\n"
|
||||
"POT-Creation-Date: 2013-03-01 15:50+0000\n"
|
||||
"PO-Revision-Date: 2012-10-13 17:44+0300\n"
|
||||
"Last-Translator: Ігар Грачышка <ihar.hrachyshka@gmail.com>\n"
|
||||
"Language-Team: Belarusian <i18n-bel-gnome@googlegroups.com>\n"
|
||||
@@ -206,7 +206,7 @@ msgstr "Падзяліць прагляд справа"
|
||||
|
||||
#. 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:589
|
||||
#: ../src/compositor/compositor.c:507
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@@ -214,11 +214,11 @@ msgid ""
|
||||
msgstr ""
|
||||
"Іншы кампазітны кіраўнік вокнаў ужо абслугоўвае экран %i дысплея \"%s\"."
|
||||
|
||||
#: ../src/compositor/meta-background.c:1076
|
||||
#: ../src/compositor/meta-background.c:1111
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "не ўдалося стварыць фонавую тэкстуру з файла"
|
||||
|
||||
#: ../src/core/bell.c:322
|
||||
#: ../src/core/bell.c:320
|
||||
msgid "Bell event"
|
||||
msgstr "Падзея з сігналам"
|
||||
|
||||
@@ -251,18 +251,18 @@ msgstr "_Пачакаць"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Змусіць да выхаду"
|
||||
|
||||
#: ../src/core/display.c:421
|
||||
#: ../src/core/display.c:401
|
||||
#, c-format
|
||||
msgid "Missing %s extension required for compositing"
|
||||
msgstr ""
|
||||
"Адсутнічае пашырэнне \"%s\", патрэбнае для ажыццяўлення кампазітнага вываду"
|
||||
|
||||
#: ../src/core/display.c:513
|
||||
#: ../src/core/display.c:493
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Не ўдалося адкрыць X-дысплей аконнай сістэмы \"%s\"\n"
|
||||
|
||||
#: ../src/core/keybindings.c:1136
|
||||
#: ../src/core/keybindings.c:929
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Some other program is already using the key %s with modifiers %x as a "
|
||||
@@ -271,41 +271,41 @@ msgstr ""
|
||||
"Нейкая іншая праграма ўжо выкарыстоўвае як скарот клавішу %s з "
|
||||
"мадыфікатарамі %x\n"
|
||||
|
||||
#: ../src/core/keybindings.c:1333
|
||||
#: ../src/core/keybindings.c:1129
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid accelerator\n"
|
||||
msgstr "\"%s\" - гэта хібны клавіятурны скарот\n"
|
||||
|
||||
#: ../src/core/main.c:197
|
||||
#: ../src/core/main.c:196
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "Выключыць злучэнне з кіраўніком сеансаў"
|
||||
|
||||
#: ../src/core/main.c:203
|
||||
#: ../src/core/main.c:202
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "Замяніць дзейнага кіраўніка вокнаў"
|
||||
|
||||
#: ../src/core/main.c:209
|
||||
#: ../src/core/main.c:208
|
||||
msgid "Specify session management ID"
|
||||
msgstr "Вызначыць ідэнтыфікатар для кіравання сеансам"
|
||||
|
||||
#: ../src/core/main.c:214
|
||||
#: ../src/core/main.c:213
|
||||
msgid "X Display to use"
|
||||
msgstr "Патрэбны X-дысплей"
|
||||
|
||||
#: ../src/core/main.c:220
|
||||
#: ../src/core/main.c:219
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "Ініцыяваць сеанс з файла"
|
||||
|
||||
#: ../src/core/main.c:226
|
||||
#: ../src/core/main.c:225
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "Сінхронна выконваць выклікі X-сістэмы"
|
||||
|
||||
#: ../src/core/main.c:534
|
||||
#: ../src/core/main.c:494
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Не ўдалося праглядзець каталог з матывамі аздаблення: %s\n"
|
||||
|
||||
#: ../src/core/main.c:550
|
||||
#: ../src/core/main.c:510
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
@@ -313,19 +313,6 @@ msgstr ""
|
||||
"Не ўдалося адшукаць матыў аздаблення! Праверце, каб каталог %s існаваў і "
|
||||
"змяшчаў звычайныя матывы.\n"
|
||||
|
||||
#: ../src/core/monitor.c:711
|
||||
msgid "Built-in display"
|
||||
msgstr "Убудаваны дысплей"
|
||||
|
||||
#. TRANSLATORS: this is a monitor name (in case we don't know
|
||||
#. the vendor), it's Unknown followed by a size in inches,
|
||||
#. like 'Unknown 15"'
|
||||
#.
|
||||
#: ../src/core/monitor.c:739
|
||||
#, c-format
|
||||
msgid "Unknown %s"
|
||||
msgstr "Невядомы %s"
|
||||
|
||||
#: ../src/core/mutter.c:40
|
||||
#, c-format
|
||||
msgid ""
|
||||
@@ -350,7 +337,7 @@ msgstr "Вывесці нумар версіі праграмы"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Патрэбны плугін Mutter"
|
||||
|
||||
#: ../src/core/prefs.c:1202
|
||||
#: ../src/core/prefs.c:1087
|
||||
msgid ""
|
||||
"Workarounds for broken applications disabled. Some applications may not "
|
||||
"behave properly.\n"
|
||||
@@ -358,12 +345,12 @@ msgstr ""
|
||||
"Асаблівыя паводзіны для некаторых хібных праграм выключаныя. Некаторыя "
|
||||
"праграмы могуць перастаць працаваць, як мае быць.\n"
|
||||
|
||||
#: ../src/core/prefs.c:1277
|
||||
#: ../src/core/prefs.c:1162
|
||||
#, c-format
|
||||
msgid "Could not parse font description \"%s\" from GSettings key %s\n"
|
||||
msgstr "Не ўдалося разабраць азначэнне шрыфту \"%s\" з GSettings-ключа %s\n"
|
||||
|
||||
#: ../src/core/prefs.c:1343
|
||||
#: ../src/core/prefs.c:1228
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for mouse button "
|
||||
@@ -372,7 +359,7 @@ msgstr ""
|
||||
"Значэнне \"%s\", знойдзенае ў базе канфігурацыйных даных, не азначае "
|
||||
"мадыфікатар мышынай кнопкі\n"
|
||||
|
||||
#: ../src/core/prefs.c:1909
|
||||
#: ../src/core/prefs.c:1780
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for keybinding "
|
||||
@@ -381,17 +368,17 @@ msgstr ""
|
||||
"Значэнне \"%s\", знойдзенае ў базе канфігурацыйных даных, не азначае "
|
||||
"клавіятурны скарот \"%s\"\n"
|
||||
|
||||
#: ../src/core/prefs.c:1999
|
||||
#: ../src/core/prefs.c:1879
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Прастора працы %d"
|
||||
|
||||
#: ../src/core/screen.c:534
|
||||
#: ../src/core/screen.c:673
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Экран %d на дысплеі \"%s\" хібны\n"
|
||||
|
||||
#: ../src/core/screen.c:550
|
||||
#: ../src/core/screen.c:689
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -400,19 +387,19 @@ msgstr ""
|
||||
"Экран %d на дысплеі \"%s\" ужо мае аконнага кіраўніка. Каб замяніць яго "
|
||||
"новым, дадайце опцыю --replace.\n"
|
||||
|
||||
#: ../src/core/screen.c:577
|
||||
#: ../src/core/screen.c:716
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not acquire window manager selection on screen %d display \"%s\"\n"
|
||||
msgstr ""
|
||||
"Не ўдалося пераняць вылучэнне кіраўніка вокнаў для экрана %d дысплея \"%s\"\n"
|
||||
|
||||
#: ../src/core/screen.c:655
|
||||
#: ../src/core/screen.c:794
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "Экран %d на дысплеі \"%s\" ужо мае кіраўніка вокнаў\n"
|
||||
|
||||
#: ../src/core/screen.c:846
|
||||
#: ../src/core/screen.c:979
|
||||
#, c-format
|
||||
msgid "Could not release screen %d on display \"%s\"\n"
|
||||
msgstr "Не ўдалося вызваліць экран %d на дысплеі \"%s\"\n"
|
||||
@@ -473,45 +460,46 @@ msgstr ""
|
||||
"Гэтыя вокны не падтрымліваюць функцыі захавання дзейнага ладу працы, і таму "
|
||||
"іх прыйдзецца запусціць уручную пасля наступнага ўваходу ў сістэму."
|
||||
|
||||
#: ../src/core/util.c:84
|
||||
#: ../src/core/util.c:80
|
||||
#, c-format
|
||||
msgid "Failed to open debug log: %s\n"
|
||||
msgstr "Не ўдалося адкрыць адладачны журнал: %s\n"
|
||||
|
||||
#: ../src/core/util.c:94
|
||||
#: ../src/core/util.c:90
|
||||
#, c-format
|
||||
msgid "Failed to fdopen() log file %s: %s\n"
|
||||
msgstr "Не ўдалося выканаць fdopen() для журнальнага файла %s: %s\n"
|
||||
|
||||
#: ../src/core/util.c:100
|
||||
#: ../src/core/util.c:96
|
||||
#, c-format
|
||||
msgid "Opened log file %s\n"
|
||||
msgstr "Журнальны файл %s адкрыты\n"
|
||||
|
||||
#: ../src/core/util.c:119
|
||||
#: ../src/core/util.c:115 ../src/tools/mutter-message.c:149
|
||||
#, c-format
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr ""
|
||||
"Праграма \"Mutter\" была скампіляваная без падтрымкі падрабязнага "
|
||||
"пратакаліравання\n"
|
||||
|
||||
#: ../src/core/util.c:264
|
||||
#: ../src/core/util.c:259
|
||||
msgid "Window manager: "
|
||||
msgstr "Кіраўнік вокнаў: "
|
||||
|
||||
#: ../src/core/util.c:414
|
||||
#: ../src/core/util.c:407
|
||||
msgid "Bug in window manager: "
|
||||
msgstr "Хіба ў кіраўніку вокнаў: "
|
||||
|
||||
#: ../src/core/util.c:445
|
||||
#: ../src/core/util.c:438
|
||||
msgid "Window manager warning: "
|
||||
msgstr "Перасцярога ад кіраўніка вокнаў: "
|
||||
|
||||
#: ../src/core/util.c:473
|
||||
#: ../src/core/util.c:466
|
||||
msgid "Window manager error: "
|
||||
msgstr "Памылка кіраўніка вокнаў: "
|
||||
|
||||
#. first time through
|
||||
#: ../src/core/window.c:7533
|
||||
#: ../src/core/window.c:7539
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
|
||||
@@ -527,7 +515,7 @@ msgstr ""
|
||||
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
|
||||
#. * about these apps but make them work.
|
||||
#.
|
||||
#: ../src/core/window.c:8257
|
||||
#: ../src/core/window.c:8263
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
||||
@@ -537,22 +525,22 @@ msgstr ""
|
||||
"памеру, але разам з гэтым прызначыла для сябе мінімальны памер %d x %d і "
|
||||
"максімальны памер %d x %d. Такія паводзіны не маюць сэнсу.\n"
|
||||
|
||||
#: ../src/core/window-props.c:347
|
||||
#: ../src/core/window-props.c:318
|
||||
#, c-format
|
||||
msgid "Application set a bogus _NET_WM_PID %lu\n"
|
||||
msgstr "Праграма прызначыла памылковае значэнне _NET_WM_PID %lu\n"
|
||||
|
||||
#: ../src/core/window-props.c:463
|
||||
#: ../src/core/window-props.c:434
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (на %s)"
|
||||
|
||||
#: ../src/core/window-props.c:1546
|
||||
#: ../src/core/window-props.c:1517
|
||||
#, c-format
|
||||
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
|
||||
msgstr "Для %2$s вызначана хібнае акно WM_TRANSIENT_FOR 0x%1$lx.\n"
|
||||
|
||||
#: ../src/core/window-props.c:1557
|
||||
#: ../src/core/window-props.c:1528
|
||||
#, c-format
|
||||
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
|
||||
msgstr "WM_TRANSIENT_FOR акно 0x%lx для %s стварыла б цыкл.\n"
|
||||
@@ -701,8 +689,7 @@ msgstr ""
|
||||
|
||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:17
|
||||
msgid "Auto maximize nearly monitor sized windows"
|
||||
msgstr ""
|
||||
"Аўтаматычна максімалізаваць вокны, якія расцягнутыя амаль на ўвесь экран"
|
||||
msgstr "Аўтаматычна максімалізаваць вокны, якія расцягнутыя амаль на ўвесь экран"
|
||||
|
||||
#: ../src/org.gnome.mutter.gschema.xml.in.h:18
|
||||
msgid ""
|
||||
@@ -720,104 +707,109 @@ msgstr "Выбраць акно з выплыўнога акенца"
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Закрыць выплыўное акенца"
|
||||
|
||||
#: ../src/tools/mutter-message.c:123
|
||||
#, c-format
|
||||
msgid "Usage: %s\n"
|
||||
msgstr "Правілы выкарыстання: %s\n"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:67
|
||||
#: ../src/ui/menu.c:69
|
||||
msgid "Mi_nimize"
|
||||
msgstr "_Мінімалізаваць"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:69
|
||||
#: ../src/ui/menu.c:71
|
||||
msgid "Ma_ximize"
|
||||
msgstr "Ма_ксімалізаваць"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:71
|
||||
#: ../src/ui/menu.c:73
|
||||
msgid "Unma_ximize"
|
||||
msgstr "Скасаваць ма_ксімалізацыю"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:73
|
||||
#: ../src/ui/menu.c:75
|
||||
msgid "Roll _Up"
|
||||
msgstr "_Скруціць акно ў загаловак"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:75
|
||||
#: ../src/ui/menu.c:77
|
||||
msgid "_Unroll"
|
||||
msgstr "Рас_круціць акно з загалоўка"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:77
|
||||
#: ../src/ui/menu.c:79
|
||||
msgid "_Move"
|
||||
msgstr "_Перамясціць акно"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:79
|
||||
#: ../src/ui/menu.c:81
|
||||
msgid "_Resize"
|
||||
msgstr "_Змяніць памер акна"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:81
|
||||
#: ../src/ui/menu.c:83
|
||||
msgid "Move Titlebar On_screen"
|
||||
msgstr "Перамясціць загаловак акна па _экране"
|
||||
|
||||
#. separator
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:84 ../src/ui/menu.c:86
|
||||
#: ../src/ui/menu.c:86 ../src/ui/menu.c:88
|
||||
msgid "Always on _Top"
|
||||
msgstr "Заўсёды _наверсе"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:88
|
||||
#: ../src/ui/menu.c:90
|
||||
msgid "_Always on Visible Workspace"
|
||||
msgstr "Заўсёды на _бачнай прасторы працы"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:90
|
||||
#: ../src/ui/menu.c:92
|
||||
msgid "_Only on This Workspace"
|
||||
msgstr "_Толькі на гэтай прасторы працы"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:92
|
||||
#: ../src/ui/menu.c:94
|
||||
msgid "Move to Workspace _Left"
|
||||
msgstr "Перамясціць на прастору працы з_лева"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:94
|
||||
#: ../src/ui/menu.c:96
|
||||
msgid "Move to Workspace R_ight"
|
||||
msgstr "Перамясціць на прастору працы с_права"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:96
|
||||
#: ../src/ui/menu.c:98
|
||||
msgid "Move to Workspace _Up"
|
||||
msgstr "Перамясціць на прастору працы з_верху"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:98
|
||||
#: ../src/ui/menu.c:100
|
||||
msgid "Move to Workspace _Down"
|
||||
msgstr "Перамясціць на прастору працы з_нізу"
|
||||
|
||||
#. separator
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:102
|
||||
#: ../src/ui/menu.c:104
|
||||
msgid "_Close"
|
||||
msgstr "_Закрыць акно"
|
||||
|
||||
#: ../src/ui/menu.c:202
|
||||
#: ../src/ui/menu.c:204
|
||||
#, c-format
|
||||
msgid "Workspace %d%n"
|
||||
msgstr "Прастора працы %d%n"
|
||||
|
||||
#: ../src/ui/menu.c:212
|
||||
#: ../src/ui/menu.c:214
|
||||
#, c-format
|
||||
msgid "Workspace 1_0"
|
||||
msgstr "Прастора працы 1_0"
|
||||
|
||||
#: ../src/ui/menu.c:214
|
||||
#: ../src/ui/menu.c:216
|
||||
#, c-format
|
||||
msgid "Workspace %s%d"
|
||||
msgstr "Прастора працы %s%d"
|
||||
|
||||
#: ../src/ui/menu.c:384
|
||||
#: ../src/ui/menu.c:397
|
||||
msgid "Move to Another _Workspace"
|
||||
msgstr "П_ерамясціць на іншую прастору працы"
|
||||
|
||||
@@ -919,49 +911,49 @@ msgstr "Mod5"
|
||||
msgid "%d x %d"
|
||||
msgstr "%d x %d"
|
||||
|
||||
#: ../src/ui/theme.c:236
|
||||
#: ../src/ui/theme.c:235
|
||||
msgid "top"
|
||||
msgstr "верхнюю"
|
||||
|
||||
#: ../src/ui/theme.c:238
|
||||
#: ../src/ui/theme.c:237
|
||||
msgid "bottom"
|
||||
msgstr "ніжнюю"
|
||||
|
||||
#: ../src/ui/theme.c:240
|
||||
#: ../src/ui/theme.c:239
|
||||
msgid "left"
|
||||
msgstr "левую"
|
||||
|
||||
#: ../src/ui/theme.c:242
|
||||
#: ../src/ui/theme.c:241
|
||||
msgid "right"
|
||||
msgstr "правую"
|
||||
|
||||
#: ../src/ui/theme.c:270
|
||||
#: ../src/ui/theme.c:269
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify \"%s\" dimension"
|
||||
msgstr "апісанне геаметрыі рамкі акна не вызначае %s граніцу"
|
||||
|
||||
#: ../src/ui/theme.c:289
|
||||
#: ../src/ui/theme.c:288
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
|
||||
msgstr ""
|
||||
"апісанне геаметрыі рамкі акна не вызначае %s граніцу для аблямоўкі \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:326
|
||||
#: ../src/ui/theme.c:325
|
||||
#, c-format
|
||||
msgid "Button aspect ratio %g is not reasonable"
|
||||
msgstr "Прапорцыі кнопкі %g не маюць сэнсу"
|
||||
|
||||
#: ../src/ui/theme.c:338
|
||||
#: ../src/ui/theme.c:337
|
||||
#, c-format
|
||||
msgid "Frame geometry does not specify size of buttons"
|
||||
msgstr "Апісанне геаметрыі рамкі акна не вызначае памер кнопак"
|
||||
|
||||
#: ../src/ui/theme.c:1051
|
||||
#: ../src/ui/theme.c:1050
|
||||
#, c-format
|
||||
msgid "Gradients should have at least two colors"
|
||||
msgstr "Градыент мусіць мець прынамсі два колеры"
|
||||
|
||||
#: ../src/ui/theme.c:1203
|
||||
#: ../src/ui/theme.c:1202
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK custom color specification must have color name and fallback in "
|
||||
@@ -970,7 +962,7 @@ msgstr ""
|
||||
"Уласная спецыфікацыя колеру GTK мусіць змяшчаць назвы асноўнага і запаснога "
|
||||
"колераў у дужках, напрыклад, gtk:custom(foo,bar). Не ўдалося разабраць \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1219
|
||||
#: ../src/ui/theme.c:1218
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
|
||||
@@ -979,7 +971,7 @@ msgstr ""
|
||||
"Хібны знак \"%c\" у параметры color_name спецыфікацыі gtk:custom, дазволеныя "
|
||||
"толькі A-Za-z0-9-_"
|
||||
|
||||
#: ../src/ui/theme.c:1233
|
||||
#: ../src/ui/theme.c:1232
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
||||
@@ -988,7 +980,7 @@ msgstr ""
|
||||
"Фармат gtk:custom: \"gtk:custom(назва_колеру,запасны_колер)\"; \"%s\" не "
|
||||
"адпавядае фармату"
|
||||
|
||||
#: ../src/ui/theme.c:1278
|
||||
#: ../src/ui/theme.c:1277
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
|
||||
@@ -997,7 +989,7 @@ msgstr ""
|
||||
"Спецыфікацыя колеру GTK мусіць мець стан у квадратных дужках, напрыклад, gtk:"
|
||||
"fg[NORMAL], дзе NORMAL - гэта стан. Не ўдалося разабраць \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1292
|
||||
#: ../src/ui/theme.c:1291
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have a close bracket after the state, e.g. gtk:"
|
||||
@@ -1007,17 +999,17 @@ msgstr ""
|
||||
"напрыклад, gtk:fg[NORMAL], дзе NORMAL - гэта стан. Не ўдалося разабраць \"%s"
|
||||
"\""
|
||||
|
||||
#: ../src/ui/theme.c:1303
|
||||
#: ../src/ui/theme.c:1302
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" in color specification"
|
||||
msgstr "Незразумелы стан \"%s\" у спецыфікацыі колеру"
|
||||
|
||||
#: ../src/ui/theme.c:1316
|
||||
#: ../src/ui/theme.c:1315
|
||||
#, c-format
|
||||
msgid "Did not understand color component \"%s\" in color specification"
|
||||
msgstr "Незразумелы складнік колеру \"%s\" у спецыфікацыі колеру"
|
||||
|
||||
#: ../src/ui/theme.c:1345
|
||||
#: ../src/ui/theme.c:1344
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
|
||||
@@ -1026,58 +1018,58 @@ msgstr ""
|
||||
"Фармат змяшанага колеру - \"blend/bg_color/fg_color/alpha\". \"%s\" не "
|
||||
"адпавядае фармату."
|
||||
|
||||
#: ../src/ui/theme.c:1356
|
||||
#: ../src/ui/theme.c:1355
|
||||
#, c-format
|
||||
msgid "Could not parse alpha value \"%s\" in blended color"
|
||||
msgstr "Не ўдалося разабраць значэнне альфа \"%s\" ў змяшаным колеры"
|
||||
|
||||
#: ../src/ui/theme.c:1366
|
||||
#: ../src/ui/theme.c:1365
|
||||
#, 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:1413
|
||||
#: ../src/ui/theme.c:1412
|
||||
#, 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:1424
|
||||
#: ../src/ui/theme.c:1423
|
||||
#, c-format
|
||||
msgid "Could not parse shade factor \"%s\" in shaded color"
|
||||
msgstr "Не ўдалося разабраць каэфіцыент ценю \"%s\" у зацененым колеры"
|
||||
|
||||
#: ../src/ui/theme.c:1434
|
||||
#: ../src/ui/theme.c:1433
|
||||
#, c-format
|
||||
msgid "Shade factor \"%s\" in shaded color is negative"
|
||||
msgstr "Каэфіцыент ценю \"%s\" у зацененым колеры адмоўны"
|
||||
|
||||
#: ../src/ui/theme.c:1463
|
||||
#: ../src/ui/theme.c:1462
|
||||
#, c-format
|
||||
msgid "Could not parse color \"%s\""
|
||||
msgstr "Не ўдалося разабраць колер \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1780
|
||||
#: ../src/ui/theme.c:1779
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains character '%s' which is not allowed"
|
||||
msgstr "Каардынатны выраз змяшчае забаронены знак \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1807
|
||||
#: ../src/ui/theme.c:1806
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contains floating point number '%s' which could not be "
|
||||
"parsed"
|
||||
msgstr "Каардынатны выраз змяшчае незразумелы лік з нефіксаванай коскай \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1821
|
||||
#: ../src/ui/theme.c:1820
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains integer '%s' which could not be parsed"
|
||||
msgstr "Каардынатны выраз змяшчае незразумелы цэлы лік \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1942
|
||||
#: ../src/ui/theme.c:1941
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contained unknown operator at the start of this text: "
|
||||
@@ -1085,17 +1077,17 @@ msgid ""
|
||||
msgstr ""
|
||||
"Каардынатны выраз змяшчае невядомы аператар у пачатку гэтага тэксту: \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1999
|
||||
#: ../src/ui/theme.c:1998
|
||||
#, c-format
|
||||
msgid "Coordinate expression was empty or not understood"
|
||||
msgstr "Каардынатны выраз пусты ці незразумелы"
|
||||
|
||||
#: ../src/ui/theme.c:2112 ../src/ui/theme.c:2122 ../src/ui/theme.c:2156
|
||||
#: ../src/ui/theme.c:2111 ../src/ui/theme.c:2121 ../src/ui/theme.c:2155
|
||||
#, c-format
|
||||
msgid "Coordinate expression results in division by zero"
|
||||
msgstr "Каардынатны выраз вымагае дзялення на нуль"
|
||||
|
||||
#: ../src/ui/theme.c:2164
|
||||
#: ../src/ui/theme.c:2163
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression tries to use mod operator on a floating-point number"
|
||||
@@ -1103,24 +1095,24 @@ msgstr ""
|
||||
"Каардынатны выраз спрабуе ўжыць аператар дзялення па модулі для ліку з "
|
||||
"нефіксаванай коскай"
|
||||
|
||||
#: ../src/ui/theme.c:2220
|
||||
#: ../src/ui/theme.c:2219
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has an operator \"%s\" where an operand was expected"
|
||||
msgstr ""
|
||||
"У каардынатным выразе ўжыты аператар \"%s\" там, дзе мусіў быць аперанд"
|
||||
|
||||
#: ../src/ui/theme.c:2229
|
||||
#: ../src/ui/theme.c:2228
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an operand where an operator was expected"
|
||||
msgstr "У каардынатным выразе ўжыты аперанд там, дзе мусіў быць аператар"
|
||||
|
||||
#: ../src/ui/theme.c:2237
|
||||
#: ../src/ui/theme.c:2236
|
||||
#, c-format
|
||||
msgid "Coordinate expression ended with an operator instead of an operand"
|
||||
msgstr "Каардынатны выраз заканчваецца аператарам, а не аперандам"
|
||||
|
||||
#: ../src/ui/theme.c:2247
|
||||
#: ../src/ui/theme.c:2246
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
|
||||
@@ -1129,41 +1121,41 @@ msgstr ""
|
||||
"У каардынатным выразе за аператарам \"%c\" ідзе аператар \"%c\", але паміж "
|
||||
"імі няма аперанда"
|
||||
|
||||
#: ../src/ui/theme.c:2398 ../src/ui/theme.c:2443
|
||||
#: ../src/ui/theme.c:2397 ../src/ui/theme.c:2442
|
||||
#, c-format
|
||||
msgid "Coordinate expression had unknown variable or constant \"%s\""
|
||||
msgstr "У каардынатным выразе невядомая зменная альбо канстанта \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:2497
|
||||
#: ../src/ui/theme.c:2496
|
||||
#, c-format
|
||||
msgid "Coordinate expression parser overflowed its buffer."
|
||||
msgstr "Прылада для разбору каардынатных выразаў перапоўніла свой буфер."
|
||||
|
||||
#: ../src/ui/theme.c:2526
|
||||
#: ../src/ui/theme.c:2525
|
||||
#, c-format
|
||||
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
|
||||
msgstr ""
|
||||
"У каардынатным выразе ўжытыя дужкі, якія закрываюцца, але няма тых, якія б "
|
||||
"адкрываліся"
|
||||
|
||||
#: ../src/ui/theme.c:2590
|
||||
#: ../src/ui/theme.c:2589
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
|
||||
msgstr ""
|
||||
"У каардынатным выразе ўжытыя дужкі, якія адкрываюцца, але няма тых, якія б "
|
||||
"закрываліся"
|
||||
|
||||
#: ../src/ui/theme.c:2601
|
||||
#: ../src/ui/theme.c:2600
|
||||
#, c-format
|
||||
msgid "Coordinate expression doesn't seem to have any operators or operands"
|
||||
msgstr "У каардынатным выразе няма ні аператараў, ні аперандаў"
|
||||
|
||||
#: ../src/ui/theme.c:2814 ../src/ui/theme.c:2834 ../src/ui/theme.c:2854
|
||||
#: ../src/ui/theme.c:2813 ../src/ui/theme.c:2833 ../src/ui/theme.c:2853
|
||||
#, c-format
|
||||
msgid "Theme contained an expression that resulted in an error: %s\n"
|
||||
msgstr "Матыў аздаблення змяшчае выраз, які стаў прычынай памылкі: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:4500
|
||||
#: ../src/ui/theme.c:4499
|
||||
#, c-format
|
||||
msgid ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
|
||||
@@ -1172,25 +1164,25 @@ msgstr ""
|
||||
"Для гэтага стылю рамкі трэба вызначыць <button function=\"%s\" state=\"%s\" "
|
||||
"draw_ops=\"whatever\"/>"
|
||||
|
||||
#: ../src/ui/theme.c:5011 ../src/ui/theme.c:5036
|
||||
#: ../src/ui/theme.c:5010 ../src/ui/theme.c:5035
|
||||
#, 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:5082
|
||||
#: ../src/ui/theme.c:5083
|
||||
#, c-format
|
||||
msgid "Failed to load theme \"%s\": %s\n"
|
||||
msgstr "Не ўдалося загрузіць матыў аздаблення \"%s\": %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:5218 ../src/ui/theme.c:5225 ../src/ui/theme.c:5232
|
||||
#: ../src/ui/theme.c:5239 ../src/ui/theme.c:5246
|
||||
#: ../src/ui/theme.c:5219 ../src/ui/theme.c:5226 ../src/ui/theme.c:5233
|
||||
#: ../src/ui/theme.c:5240 ../src/ui/theme.c:5247
|
||||
#, c-format
|
||||
msgid "No <%s> set for theme \"%s\""
|
||||
msgstr "Для матыву аздаблення \"%2$s\" не прызначана <%1$s>"
|
||||
|
||||
#: ../src/ui/theme.c:5254
|
||||
#: ../src/ui/theme.c:5255
|
||||
#, c-format
|
||||
msgid ""
|
||||
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
|
||||
@@ -1199,7 +1191,7 @@ msgstr ""
|
||||
"Стыль рамкі не вызначаны для вокнаў тыпу \"%s\" для матыву аздаблення \"%s"
|
||||
"\". Дадайце <window type=\"%s\" style_set=\"штосьці\"/>."
|
||||
|
||||
#: ../src/ui/theme.c:5661 ../src/ui/theme.c:5723 ../src/ui/theme.c:5786
|
||||
#: ../src/ui/theme.c:5662 ../src/ui/theme.c:5724 ../src/ui/theme.c:5787
|
||||
#, c-format
|
||||
msgid ""
|
||||
"User-defined constants must begin with a capital letter; \"%s\" does not"
|
||||
@@ -1207,7 +1199,7 @@ msgstr ""
|
||||
"Назвы канстантаў, вызначаных карыстальнікам, мусяць пачынацца з вялікай "
|
||||
"літары. \"%s\" не адпавядае гэтаму патрабаванню."
|
||||
|
||||
#: ../src/ui/theme.c:5669 ../src/ui/theme.c:5731 ../src/ui/theme.c:5794
|
||||
#: ../src/ui/theme.c:5670 ../src/ui/theme.c:5732 ../src/ui/theme.c:5795
|
||||
#, c-format
|
||||
msgid "Constant \"%s\" has already been defined"
|
||||
msgstr "Канстанта \"%s\" ужо азначана"
|
||||
@@ -1593,8 +1585,207 @@ msgstr "Выкарыстанне тэксту ўнутры элемента <%s>
|
||||
msgid "<%s> specified twice for this theme"
|
||||
msgstr "<%s> двойчы вызначаны для гэтага матыву аздаблення"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4336
|
||||
#: ../src/ui/theme-parser.c:4334
|
||||
#, c-format
|
||||
msgid "Failed to find a valid file for theme %s\n"
|
||||
msgstr "Памылка пошуку правільнага файла для матыву аздаблення %s\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:99
|
||||
msgid "_Windows"
|
||||
msgstr "_Вокны"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:100
|
||||
msgid "_Dialog"
|
||||
msgstr "_Дыялогавае акенца"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:101
|
||||
msgid "_Modal dialog"
|
||||
msgstr "_Мадальнае дыялогавае акенца"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:102
|
||||
msgid "_Utility"
|
||||
msgstr "_Дапаможная праграма"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:103
|
||||
msgid "_Splashscreen"
|
||||
msgstr "_Экранная застаўка"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:104
|
||||
msgid "_Top dock"
|
||||
msgstr "_Верхняя ўбудова"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:105
|
||||
msgid "_Bottom dock"
|
||||
msgstr "_Ніжняя ўбудова"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:106
|
||||
msgid "_Left dock"
|
||||
msgstr "_Левая ўбудова"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:107
|
||||
msgid "_Right dock"
|
||||
msgstr "_Правая ўбудова"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:108
|
||||
msgid "_All docks"
|
||||
msgstr "_Усе ўбудовы"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:109
|
||||
msgid "Des_ktop"
|
||||
msgstr "_Стол"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:115
|
||||
msgid "Open another one of these windows"
|
||||
msgstr "Адкрыць чарговае з гэтых вокнаў"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:117
|
||||
msgid "This is a demo button with an 'open' icon"
|
||||
msgstr "Гэта дэманстрацыйная кнопка са значком \"Адкрыць\""
|
||||
|
||||
#: ../src/ui/theme-viewer.c:119
|
||||
msgid "This is a demo button with a 'quit' icon"
|
||||
msgstr "Гэта дэманстрацыйная кнопка са значком \"Выйсці\""
|
||||
|
||||
#: ../src/ui/theme-viewer.c:248
|
||||
msgid "This is a sample message in a sample dialog"
|
||||
msgstr "Гэта ўзорнае паведамленне ва ўзорным дыялогавым акенцы"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:328
|
||||
#, c-format
|
||||
msgid "Fake menu item %d\n"
|
||||
msgstr "Несапраўдны пункт меню %d\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:363
|
||||
msgid "Border-only window"
|
||||
msgstr "Акно толькі з аблямоўкай"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:365
|
||||
msgid "Bar"
|
||||
msgstr "Стужка"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:382
|
||||
msgid "Normal Application Window"
|
||||
msgstr "Звычайнае акно праграмы"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:386
|
||||
msgid "Dialog Box"
|
||||
msgstr "Дыялогавае акенца"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:390
|
||||
msgid "Modal Dialog Box"
|
||||
msgstr "Мадальнае дыялогавае акенца"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:394
|
||||
msgid "Utility Palette"
|
||||
msgstr "Дапаможная палітра"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:398
|
||||
msgid "Torn-off Menu"
|
||||
msgstr "Адчэпленае меню"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:402
|
||||
msgid "Border"
|
||||
msgstr "Аблямоўка"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:406
|
||||
msgid "Attached Modal Dialog"
|
||||
msgstr "Прычапленае мадальнае дыялогавае акенца"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:737
|
||||
#, c-format
|
||||
msgid "Button layout test %d"
|
||||
msgstr "Выпрабаванне размяшчэння кнопак %d"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:766
|
||||
#, c-format
|
||||
msgid "%g milliseconds to draw one window frame"
|
||||
msgstr "%g мілісекунд, каб намаляваць адну рамку акна"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:811
|
||||
#, c-format
|
||||
msgid "Usage: metacity-theme-viewer [THEMENAME]\n"
|
||||
msgstr "Правілы карыстання: metacity-theme-viewer [НАЗВА_МАТЫВУ]\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:818
|
||||
#, c-format
|
||||
msgid "Error loading theme: %s\n"
|
||||
msgstr "Памылка загрузкі матыву аздаблення: %s\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:824
|
||||
#, c-format
|
||||
msgid "Loaded theme \"%s\" in %g seconds\n"
|
||||
msgstr "Матыў аздаблення \"%s\" загружаны за %g секунд\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:869
|
||||
msgid "Normal Title Font"
|
||||
msgstr "Звычайны шрыфт загалоўка"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:875
|
||||
msgid "Small Title Font"
|
||||
msgstr "Маленькі шрыфт загалоўка"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:881
|
||||
msgid "Large Title Font"
|
||||
msgstr "Вялікі шрыфт загалоўка"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:886
|
||||
msgid "Button Layouts"
|
||||
msgstr "Размяшчэнне кнопак"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:891
|
||||
msgid "Benchmark"
|
||||
msgstr "Выпрабаванне"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:947
|
||||
msgid "Window Title Goes Here"
|
||||
msgstr "Месца для загалоўка акна"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1053
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g "
|
||||
"seconds wall clock time including X server resources (%g milliseconds per "
|
||||
"frame)\n"
|
||||
msgstr ""
|
||||
"Намалявана %d рамак цягам %g секунд кліенцкага часу (%g мілісекунд на рамку) "
|
||||
"і %g секунд каляндарнага часу, уключна з рэсурсамі X-сервера (%g мілісекунд "
|
||||
"на рамку)\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1273
|
||||
msgid "position expression test returned TRUE but set error"
|
||||
msgstr "выпрабаванне выразу пазіцыі вярнула TRUE, але паведаміла аб памылцы"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1275
|
||||
msgid "position expression test returned FALSE but didn't set error"
|
||||
msgstr ""
|
||||
"выпрабаванне выразу пазіцыі вярнула FALSE, але не паведаміла аб памылцы"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1279
|
||||
msgid "Error was expected but none given"
|
||||
msgstr "Чакалася памылка, але звесткі не атрыманыя"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1281
|
||||
#, c-format
|
||||
msgid "Error %d was expected but %d given"
|
||||
msgstr "Чакалася памылка %d, але атрымана %d"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1287
|
||||
#, c-format
|
||||
msgid "Error not expected but one was returned: %s"
|
||||
msgstr "Атрымана нечаканая памылка: %s"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1291
|
||||
#, c-format
|
||||
msgid "x value was %d, %d was expected"
|
||||
msgstr "X-значэнне было %d, а чакалася %d"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1294
|
||||
#, c-format
|
||||
msgid "y value was %d, %d was expected"
|
||||
msgstr "Y-значэнне было %d, а чакалася %d"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1359
|
||||
#, c-format
|
||||
msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
|
||||
msgstr ""
|
||||
"%d каардынатных выразаў разабраныя за %g секунд (у сярэднім %g секунд)\n"
|
||||
|
||||
231
po/et.po
231
po/et.po
@@ -14,8 +14,8 @@ 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: 2013-09-10 15:25+0000\n"
|
||||
"PO-Revision-Date: 2013-09-11 23:20+0300\n"
|
||||
"POT-Creation-Date: 2013-03-12 18:53+0000\n"
|
||||
"PO-Revision-Date: 2013-03-12 20:55+0300\n"
|
||||
"Last-Translator: Mattias Põldaru <mahfiaz@gmail.com>\n"
|
||||
"Language-Team: Estonian <>\n"
|
||||
"Language: et\n"
|
||||
@@ -23,7 +23,6 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
|
||||
"X-Generator: Poedit 1.5.4\n"
|
||||
|
||||
msgid "Navigation"
|
||||
msgstr "Navigeerimine"
|
||||
@@ -250,17 +249,6 @@ msgid ""
|
||||
msgstr ""
|
||||
"Teemat ei leitud! Veendu, et %s on olemas ja sisaldab harilikke teemasid.\n"
|
||||
|
||||
msgid "Built-in display"
|
||||
msgstr "Sisseehitatud kuva"
|
||||
|
||||
#. TRANSLATORS: this is a monitor name (in case we don't know
|
||||
#. the vendor), it's Unknown followed by a size in inches,
|
||||
#. like 'Unknown 15"'
|
||||
#.
|
||||
#, c-format
|
||||
msgid "Unknown %s"
|
||||
msgstr "Tundmatu %s"
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
"mutter %s\n"
|
||||
@@ -393,6 +381,7 @@ msgstr "Tõrge logifaili %s avamisel funktsiooniga fdopen(): %s\n"
|
||||
msgid "Opened log file %s\n"
|
||||
msgstr "Avati logifail %s\n"
|
||||
|
||||
#, c-format
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Mutter kompileeriti ilma jutuka režiimi toeta\n"
|
||||
|
||||
@@ -583,6 +572,10 @@ msgstr "Akna valimine tabulaatori hüpikaknalt"
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Tabulaatori hüpikakna katkestamine"
|
||||
|
||||
#, c-format
|
||||
msgid "Usage: %s\n"
|
||||
msgstr "Kasutamine: %s\n"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
msgid "Mi_nimize"
|
||||
msgstr "_Minimeeri"
|
||||
@@ -1288,151 +1281,159 @@ msgstr "Selle teema jaoks on <%s> määratud kaks korda"
|
||||
msgid "Failed to find a valid file for theme %s\n"
|
||||
msgstr "Tõrge %s teema jaoks korrektse faili leidmisel\n"
|
||||
|
||||
#~ msgid "Usage: %s\n"
|
||||
#~ msgstr "Kasutamine: %s\n"
|
||||
msgid "_Windows"
|
||||
msgstr "_Aknad"
|
||||
|
||||
#~ msgid "_Windows"
|
||||
#~ msgstr "_Aknad"
|
||||
msgid "_Dialog"
|
||||
msgstr "_Dialoog"
|
||||
|
||||
#~ msgid "_Dialog"
|
||||
#~ msgstr "_Dialoog"
|
||||
msgid "_Modal dialog"
|
||||
msgstr "_Modaaldialoog"
|
||||
|
||||
#~ msgid "_Modal dialog"
|
||||
#~ msgstr "_Modaaldialoog"
|
||||
msgid "_Utility"
|
||||
msgstr "_Utiliit"
|
||||
|
||||
#~ msgid "_Utility"
|
||||
#~ msgstr "_Utiliit"
|
||||
msgid "_Splashscreen"
|
||||
msgstr "_Käivitusekraan"
|
||||
|
||||
#~ msgid "_Splashscreen"
|
||||
#~ msgstr "_Käivitusekraan"
|
||||
msgid "_Top dock"
|
||||
msgstr "Ü_lemine dokk"
|
||||
|
||||
#~ msgid "_Top dock"
|
||||
#~ msgstr "Ü_lemine dokk"
|
||||
msgid "_Bottom dock"
|
||||
msgstr "_Alumine dokk"
|
||||
|
||||
#~ msgid "_Bottom dock"
|
||||
#~ msgstr "_Alumine dokk"
|
||||
msgid "_Left dock"
|
||||
msgstr "_Vasak dokk"
|
||||
|
||||
#~ msgid "_Left dock"
|
||||
#~ msgstr "_Vasak dokk"
|
||||
msgid "_Right dock"
|
||||
msgstr "_Parem dokk"
|
||||
|
||||
#~ msgid "_Right dock"
|
||||
#~ msgstr "_Parem dokk"
|
||||
msgid "_All docks"
|
||||
msgstr "_Kõik dokid"
|
||||
|
||||
#~ msgid "_All docks"
|
||||
#~ msgstr "_Kõik dokid"
|
||||
msgid "Des_ktop"
|
||||
msgstr "_Töölaud"
|
||||
|
||||
#~ msgid "Des_ktop"
|
||||
#~ msgstr "_Töölaud"
|
||||
msgid "Open another one of these windows"
|
||||
msgstr "Ava neist akendest järgmine"
|
||||
|
||||
#~ msgid "Open another one of these windows"
|
||||
#~ msgstr "Ava neist akendest järgmine"
|
||||
msgid "This is a demo button with an 'open' icon"
|
||||
msgstr "See on näidisnupp koos 'ava' ikooniga"
|
||||
|
||||
#~ msgid "This is a demo button with an 'open' icon"
|
||||
#~ msgstr "See on näidisnupp koos 'ava' ikooniga"
|
||||
msgid "This is a demo button with a 'quit' icon"
|
||||
msgstr "See on näidisnupp koos 'lõpeta' ikooniga"
|
||||
|
||||
#~ msgid "This is a demo button with a 'quit' icon"
|
||||
#~ msgstr "See on näidisnupp koos 'lõpeta' ikooniga"
|
||||
msgid "This is a sample message in a sample dialog"
|
||||
msgstr "See on näidisteade näidisdialoogis"
|
||||
|
||||
#~ msgid "This is a sample message in a sample dialog"
|
||||
#~ msgstr "See on näidisteade näidisdialoogis"
|
||||
#, c-format
|
||||
msgid "Fake menu item %d\n"
|
||||
msgstr "Võltsitud menüüpunkt %d\n"
|
||||
|
||||
#~ msgid "Fake menu item %d\n"
|
||||
#~ msgstr "Võltsitud menüüpunkt %d\n"
|
||||
msgid "Border-only window"
|
||||
msgstr "Ainult raamiga aken"
|
||||
|
||||
#~ msgid "Border-only window"
|
||||
#~ msgstr "Ainult raamiga aken"
|
||||
msgid "Bar"
|
||||
msgstr "Riba"
|
||||
|
||||
#~ msgid "Bar"
|
||||
#~ msgstr "Riba"
|
||||
msgid "Normal Application Window"
|
||||
msgstr "Tavaline rakenduseaken"
|
||||
|
||||
#~ msgid "Normal Application Window"
|
||||
#~ msgstr "Tavaline rakenduseaken"
|
||||
msgid "Dialog Box"
|
||||
msgstr "Dialoogikast"
|
||||
|
||||
#~ msgid "Dialog Box"
|
||||
#~ msgstr "Dialoogikast"
|
||||
msgid "Modal Dialog Box"
|
||||
msgstr "Modaalne dialoogikast"
|
||||
|
||||
#~ msgid "Modal Dialog Box"
|
||||
#~ msgstr "Modaalne dialoogikast"
|
||||
msgid "Utility Palette"
|
||||
msgstr "Rakendite palett"
|
||||
|
||||
#~ msgid "Utility Palette"
|
||||
#~ msgstr "Rakendite palett"
|
||||
msgid "Torn-off Menu"
|
||||
msgstr "Ärarebitav menüü"
|
||||
|
||||
#~ msgid "Torn-off Menu"
|
||||
#~ msgstr "Ärarebitav menüü"
|
||||
msgid "Border"
|
||||
msgstr "Raam"
|
||||
|
||||
#~ msgid "Border"
|
||||
#~ msgstr "Raam"
|
||||
msgid "Attached Modal Dialog"
|
||||
msgstr "Kinnistatud modaaldialoog"
|
||||
|
||||
#~ msgid "Attached Modal Dialog"
|
||||
#~ msgstr "Kinnistatud modaaldialoog"
|
||||
#, c-format
|
||||
msgid "Button layout test %d"
|
||||
msgstr "Nuppude paigutuse test %d"
|
||||
|
||||
#~ msgid "Button layout test %d"
|
||||
#~ msgstr "Nuppude paigutuse test %d"
|
||||
#, c-format
|
||||
msgid "%g milliseconds to draw one window frame"
|
||||
msgstr "%g millisekundit kulub ühe akna raami joonistamiseks"
|
||||
|
||||
#~ msgid "%g milliseconds to draw one window frame"
|
||||
#~ msgstr "%g millisekundit kulub ühe akna raami joonistamiseks"
|
||||
#, c-format
|
||||
msgid "Usage: metacity-theme-viewer [THEMENAME]\n"
|
||||
msgstr "Kasutamine: metacity-theme-viewer [TEEMANIMI]\n"
|
||||
|
||||
#~ msgid "Usage: metacity-theme-viewer [THEMENAME]\n"
|
||||
#~ msgstr "Kasutamine: metacity-theme-viewer [TEEMANIMI]\n"
|
||||
#, c-format
|
||||
msgid "Error loading theme: %s\n"
|
||||
msgstr "Viga teema laadimisel: %s\n"
|
||||
|
||||
#~ msgid "Error loading theme: %s\n"
|
||||
#~ msgstr "Viga teema laadimisel: %s\n"
|
||||
#, c-format
|
||||
msgid "Loaded theme \"%s\" in %g seconds\n"
|
||||
msgstr "Teema \"%s\" laaditi %g sekundiga\n"
|
||||
|
||||
#~ msgid "Loaded theme \"%s\" in %g seconds\n"
|
||||
#~ msgstr "Teema \"%s\" laaditi %g sekundiga\n"
|
||||
msgid "Normal Title Font"
|
||||
msgstr "Tiitli tavasuurusega kirjatüüp"
|
||||
|
||||
#~ msgid "Normal Title Font"
|
||||
#~ msgstr "Tiitli tavasuurusega kirjatüüp"
|
||||
msgid "Small Title Font"
|
||||
msgstr "Tiitli väike kirjatüüp"
|
||||
|
||||
#~ msgid "Small Title Font"
|
||||
#~ msgstr "Tiitli väike kirjatüüp"
|
||||
msgid "Large Title Font"
|
||||
msgstr "Tiitli suur kirjatüüp"
|
||||
|
||||
#~ msgid "Large Title Font"
|
||||
#~ msgstr "Tiitli suur kirjatüüp"
|
||||
msgid "Button Layouts"
|
||||
msgstr "Nuppude paigutus"
|
||||
|
||||
#~ msgid "Button Layouts"
|
||||
#~ msgstr "Nuppude paigutus"
|
||||
msgid "Benchmark"
|
||||
msgstr "Jõudlus"
|
||||
|
||||
#~ msgid "Benchmark"
|
||||
#~ msgstr "Jõudlus"
|
||||
msgid "Window Title Goes Here"
|
||||
msgstr "Siia tuleb akna pealkiri"
|
||||
|
||||
#~ msgid "Window Title Goes Here"
|
||||
#~ msgstr "Siia tuleb akna pealkiri"
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g "
|
||||
"seconds wall clock time including X server resources (%g milliseconds per "
|
||||
"frame)\n"
|
||||
msgstr ""
|
||||
"Joonistati %d kaadrit %g kliendi-kella sekundiga (%g millisekundit kaadrile) "
|
||||
"ja %g sekundiga seinakella järgi, millesse on kaasatud X-serveri "
|
||||
"ressursikasutus (%g millisekundit kaadrile)\n"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Drew %d frames in %g client-side seconds (%g milliseconds per frame) and "
|
||||
#~ "%g seconds wall clock time including X server resources (%g milliseconds "
|
||||
#~ "per frame)\n"
|
||||
#~ msgstr ""
|
||||
#~ "Joonistati %d kaadrit %g kliendi-kella sekundiga (%g millisekundit "
|
||||
#~ "kaadrile) ja %g sekundiga seinakella järgi, millesse on kaasatud X-"
|
||||
#~ "serveri ressursikasutus (%g millisekundit kaadrile)\n"
|
||||
msgid "position expression test returned TRUE but set error"
|
||||
msgstr "asukoha avaldise kontroll tagastas TÕENE, aga määras vea"
|
||||
|
||||
#~ msgid "position expression test returned TRUE but set error"
|
||||
#~ msgstr "asukoha avaldise kontroll tagastas TÕENE, aga määras vea"
|
||||
msgid "position expression test returned FALSE but didn't set error"
|
||||
msgstr "asukoha avaldise kontroll tagastas VÄÄR, aga ei määranud viga"
|
||||
|
||||
#~ msgid "position expression test returned FALSE but didn't set error"
|
||||
#~ msgstr "asukoha avaldise kontroll tagastas VÄÄR, aga ei määranud viga"
|
||||
msgid "Error was expected but none given"
|
||||
msgstr "Oodati viga, aga ühtegi ei edastatud"
|
||||
|
||||
#~ msgid "Error was expected but none given"
|
||||
#~ msgstr "Oodati viga, aga ühtegi ei edastatud"
|
||||
#, c-format
|
||||
msgid "Error %d was expected but %d given"
|
||||
msgstr "Oodati viga %d, aga edastati viga %d"
|
||||
|
||||
#~ msgid "Error %d was expected but %d given"
|
||||
#~ msgstr "Oodati viga %d, aga edastati viga %d"
|
||||
#, c-format
|
||||
msgid "Error not expected but one was returned: %s"
|
||||
msgstr "Viga ei oodatud, aga üks edastati: %s"
|
||||
|
||||
#~ msgid "Error not expected but one was returned: %s"
|
||||
#~ msgstr "Viga ei oodatud, aga üks edastati: %s"
|
||||
#, c-format
|
||||
msgid "x value was %d, %d was expected"
|
||||
msgstr "x väärtus oli %d, oodati väärtust %d"
|
||||
|
||||
#~ msgid "x value was %d, %d was expected"
|
||||
#~ msgstr "x väärtus oli %d, oodati väärtust %d"
|
||||
#, c-format
|
||||
msgid "y value was %d, %d was expected"
|
||||
msgstr "y väärtus oli %d, oodati väärtust %d"
|
||||
|
||||
#~ msgid "y value was %d, %d was expected"
|
||||
#~ msgstr "y väärtus oli %d, oodati väärtust %d"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
|
||||
#~ msgstr ""
|
||||
#~ "%d koordinaatide avaldis töödeldi %g sekundiga (keskmine %g sekundit)\n"
|
||||
#, c-format
|
||||
msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
|
||||
msgstr ""
|
||||
"%d koordinaatide avaldis töödeldi %g sekundiga (keskmine %g sekundit)\n"
|
||||
|
||||
#~ msgid "Minimize window"
|
||||
#~ msgstr "Akna minimeerimine"
|
||||
|
||||
327
po/id.po
327
po/id.po
@@ -11,15 +11,15 @@ 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: 2013-08-18 20:03+0000\n"
|
||||
"PO-Revision-Date: 2013-09-14 15:44+0700\n"
|
||||
"POT-Creation-Date: 2013-03-28 10:28+0000\n"
|
||||
"PO-Revision-Date: 2013-03-30 11:24+0700\n"
|
||||
"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
|
||||
"Language-Team: Indonesian <gnome@i15n.org>\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.5.7\n"
|
||||
"X-Generator: Poedit 1.5.5\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: ../src/50-mutter-navigation.xml.in.h:1
|
||||
@@ -212,7 +212,7 @@ msgstr "Tampilan dipisah ke kanan"
|
||||
|
||||
#. 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:589
|
||||
#: ../src/compositor/compositor.c:568
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@@ -220,7 +220,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Manajer komposit lain telah berjalan pada layar %i pada tampilan \"%s\"."
|
||||
|
||||
#: ../src/compositor/meta-background.c:1076
|
||||
#: ../src/compositor/meta-background.c:1065
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "tekstur latar tak bisa dibuat dari berkas"
|
||||
|
||||
@@ -257,24 +257,24 @@ msgstr "_Tunggu"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Matikan Paksa"
|
||||
|
||||
#: ../src/core/display.c:421
|
||||
#: ../src/core/display.c:401
|
||||
#, c-format
|
||||
msgid "Missing %s extension required for compositing"
|
||||
msgstr "Kehilangan ekstensi %s yang diperlukan untuk pengkomposisian"
|
||||
|
||||
#: ../src/core/display.c:513
|
||||
#: ../src/core/display.c:493
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Gagal membuka tampilan X Window System '%s'\n"
|
||||
|
||||
#: ../src/core/keybindings.c:1136
|
||||
#: ../src/core/keybindings.c:935
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Some other program is already using the key %s with modifiers %x as a "
|
||||
"binding\n"
|
||||
msgstr "Ada program lain yang menggunakan tombol %s dengan kombinasi %x\n"
|
||||
|
||||
#: ../src/core/keybindings.c:1333
|
||||
#: ../src/core/keybindings.c:1135
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid accelerator\n"
|
||||
msgstr "\"%s\" bukan akselerator yang valid\n"
|
||||
@@ -314,19 +314,6 @@ 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/monitor.c:711
|
||||
msgid "Built-in display"
|
||||
msgstr "Tampilan bawaan"
|
||||
|
||||
#. TRANSLATORS: this is a monitor name (in case we don't know
|
||||
#. the vendor), it's Unknown followed by a size in inches,
|
||||
#. like 'Unknown 15"'
|
||||
#.
|
||||
#: ../src/core/monitor.c:739
|
||||
#, c-format
|
||||
msgid "Unknown %s"
|
||||
msgstr "%s tidak dikenal"
|
||||
|
||||
#: ../src/core/mutter.c:40
|
||||
#, c-format
|
||||
msgid ""
|
||||
@@ -351,7 +338,7 @@ msgstr "Cetak versi"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Pengaya Mutter yang dipakai"
|
||||
|
||||
#: ../src/core/prefs.c:1202
|
||||
#: ../src/core/prefs.c:1095
|
||||
msgid ""
|
||||
"Workarounds for broken applications disabled. Some applications may not "
|
||||
"behave properly.\n"
|
||||
@@ -359,12 +346,12 @@ msgstr ""
|
||||
"Pencegahan kesalahan bagi aplikasi yang rusak sedang dinonaktifkan. Mungkin "
|
||||
"nanti ada beberapa aplikasi yang akan bertingkah aneh.\n"
|
||||
|
||||
#: ../src/core/prefs.c:1277
|
||||
#: ../src/core/prefs.c:1170
|
||||
#, c-format
|
||||
msgid "Could not parse font description \"%s\" from GSettings key %s\n"
|
||||
msgstr "Tak dapat mengurai deskripsi fonta \"%s\" dari kunci GSettings %s\n"
|
||||
|
||||
#: ../src/core/prefs.c:1343
|
||||
#: ../src/core/prefs.c:1236
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for mouse button "
|
||||
@@ -373,7 +360,7 @@ msgstr ""
|
||||
"\"%s\" yang ada pada database konfigurasi bukanlah nilai yang benar untuk "
|
||||
"tombol mouse.\n"
|
||||
|
||||
#: ../src/core/prefs.c:1909
|
||||
#: ../src/core/prefs.c:1788
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for keybinding "
|
||||
@@ -382,17 +369,17 @@ msgstr ""
|
||||
"\"%s\" yang ada pada database konfigurasi bernilai tidak benar untuk "
|
||||
"kombinasi tombol \"%s\"\n"
|
||||
|
||||
#: ../src/core/prefs.c:1999
|
||||
#: ../src/core/prefs.c:1887
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Area kerja %d"
|
||||
|
||||
#: ../src/core/screen.c:534
|
||||
#: ../src/core/screen.c:691
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Layar %d pada tampilan '%s' tidak benar\n"
|
||||
|
||||
#: ../src/core/screen.c:550
|
||||
#: ../src/core/screen.c:707
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -401,7 +388,7 @@ 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:577
|
||||
#: ../src/core/screen.c:734
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not acquire window manager selection on screen %d display \"%s\"\n"
|
||||
@@ -409,12 +396,12 @@ msgstr ""
|
||||
"Tidak dapat mendapatkan pilihan pengatur jendela pada layar %d tampilan \"%s"
|
||||
"\"\n"
|
||||
|
||||
#: ../src/core/screen.c:655
|
||||
#: ../src/core/screen.c:812
|
||||
#, 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/screen.c:846
|
||||
#: ../src/core/screen.c:998
|
||||
#, c-format
|
||||
msgid "Could not release screen %d on display \"%s\"\n"
|
||||
msgstr "Layar %d pada tampilan \"%s\" tidak dapat dilepas\n"
|
||||
@@ -489,7 +476,8 @@ msgstr "Gagal melakukan fdopen pada berkas log %s: %s\n"
|
||||
msgid "Opened log file %s\n"
|
||||
msgstr "Berkas log yang dibuka %s\n"
|
||||
|
||||
#: ../src/core/util.c:119
|
||||
#: ../src/core/util.c:119 ../src/tools/mutter-message.c:149
|
||||
#, c-format
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Muter dikompilasi tanpa dukungan mode riuh\n"
|
||||
|
||||
@@ -497,20 +485,20 @@ msgstr "Muter dikompilasi tanpa dukungan mode riuh\n"
|
||||
msgid "Window manager: "
|
||||
msgstr "Pengatur jendela: "
|
||||
|
||||
#: ../src/core/util.c:414
|
||||
#: ../src/core/util.c:412
|
||||
msgid "Bug in window manager: "
|
||||
msgstr "Bug pada pengatur jendela: "
|
||||
|
||||
#: ../src/core/util.c:445
|
||||
#: ../src/core/util.c:443
|
||||
msgid "Window manager warning: "
|
||||
msgstr "Peringatan pengatur jendela: "
|
||||
|
||||
#: ../src/core/util.c:473
|
||||
#: ../src/core/util.c:471
|
||||
msgid "Window manager error: "
|
||||
msgstr "Eror pengatur jendela: "
|
||||
|
||||
#. first time through
|
||||
#: ../src/core/window.c:7533
|
||||
#: ../src/core/window.c:7596
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
|
||||
@@ -526,7 +514,7 @@ msgstr ""
|
||||
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
|
||||
#. * about these apps but make them work.
|
||||
#.
|
||||
#: ../src/core/window.c:8257
|
||||
#: ../src/core/window.c:8320
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
||||
@@ -536,22 +524,22 @@ msgstr ""
|
||||
"ukurannya, sedangkan ukuran minimalnya adalah %d x %d dan maksimal %d x %d "
|
||||
"yang tidak masuk di akal.\n"
|
||||
|
||||
#: ../src/core/window-props.c:347
|
||||
#: ../src/core/window-props.c:318
|
||||
#, c-format
|
||||
msgid "Application set a bogus _NET_WM_PID %lu\n"
|
||||
msgstr "Aplikasi telah membuat _NET_WM_PID %lu bohongan\n"
|
||||
|
||||
#: ../src/core/window-props.c:463
|
||||
#: ../src/core/window-props.c:434
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (pada %s)"
|
||||
|
||||
#: ../src/core/window-props.c:1546
|
||||
#: ../src/core/window-props.c:1517
|
||||
#, c-format
|
||||
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
|
||||
msgstr "WM_TRANSIENT_FOR salah jendela 0x%lx ditentukan untuk %s.\n"
|
||||
|
||||
#: ../src/core/window-props.c:1557
|
||||
#: ../src/core/window-props.c:1528
|
||||
#, c-format
|
||||
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
|
||||
msgstr "Jendela WM_TRANSIENT_FOR 0x%lx untuk %s akan membuat loop.\n"
|
||||
@@ -715,104 +703,109 @@ msgstr "Pilih jendela dari popup tab"
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "Batalkan popup tab"
|
||||
|
||||
#: ../src/tools/mutter-message.c:123
|
||||
#, c-format
|
||||
msgid "Usage: %s\n"
|
||||
msgstr "Cara pakai: %s\n"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:67
|
||||
#: ../src/ui/menu.c:69
|
||||
msgid "Mi_nimize"
|
||||
msgstr "Kecilka_n"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:69
|
||||
#: ../src/ui/menu.c:71
|
||||
msgid "Ma_ximize"
|
||||
msgstr "Pe_rbesar"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:71
|
||||
#: ../src/ui/menu.c:73
|
||||
msgid "Unma_ximize"
|
||||
msgstr "Kem_balikan"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:73
|
||||
#: ../src/ui/menu.c:75
|
||||
msgid "Roll _Up"
|
||||
msgstr "G_ulung"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:75
|
||||
#: ../src/ui/menu.c:77
|
||||
msgid "_Unroll"
|
||||
msgstr "B_uka"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:77
|
||||
#: ../src/ui/menu.c:79
|
||||
msgid "_Move"
|
||||
msgstr "_Pindahkan"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:79
|
||||
#: ../src/ui/menu.c:81
|
||||
msgid "_Resize"
|
||||
msgstr "Ganti·Uku_ran"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:81
|
||||
#: ../src/ui/menu.c:83
|
||||
msgid "Move Titlebar On_screen"
|
||||
msgstr "Pindahkan Judul Pada _layar"
|
||||
|
||||
#. separator
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:84 ../src/ui/menu.c:86
|
||||
#: ../src/ui/menu.c:86 ../src/ui/menu.c:88
|
||||
msgid "Always on _Top"
|
||||
msgstr "Selalu di A_tas"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:88
|
||||
#: ../src/ui/menu.c:90
|
||||
msgid "_Always on Visible Workspace"
|
||||
msgstr "T_ampak pada Area Kerja Aktif"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:90
|
||||
#: ../src/ui/menu.c:92
|
||||
msgid "_Only on This Workspace"
|
||||
msgstr "_Tampak pada Area Kerja Ini Saja"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:92
|
||||
#: ../src/ui/menu.c:94
|
||||
msgid "Move to Workspace _Left"
|
||||
msgstr "Pindahkan ke Area Kerja _Kiri"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:94
|
||||
#: ../src/ui/menu.c:96
|
||||
msgid "Move to Workspace R_ight"
|
||||
msgstr "Pindahkan ke A_rea Kerja Kanan"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:96
|
||||
#: ../src/ui/menu.c:98
|
||||
msgid "Move to Workspace _Up"
|
||||
msgstr "Pindahkan ke Area Kerja Ata_s"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:98
|
||||
#: ../src/ui/menu.c:100
|
||||
msgid "Move to Workspace _Down"
|
||||
msgstr "Pindahkan ke Area Kerja _Bawah"
|
||||
|
||||
#. separator
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:102
|
||||
#: ../src/ui/menu.c:104
|
||||
msgid "_Close"
|
||||
msgstr "_Tutup"
|
||||
|
||||
#: ../src/ui/menu.c:202
|
||||
#: ../src/ui/menu.c:204
|
||||
#, c-format
|
||||
msgid "Workspace %d%n"
|
||||
msgstr "Area Kerja %d%n"
|
||||
|
||||
#: ../src/ui/menu.c:212
|
||||
#: ../src/ui/menu.c:214
|
||||
#, c-format
|
||||
msgid "Workspace 1_0"
|
||||
msgstr "Area Kerja 1_0"
|
||||
|
||||
#: ../src/ui/menu.c:214
|
||||
#: ../src/ui/menu.c:216
|
||||
#, c-format
|
||||
msgid "Workspace %s%d"
|
||||
msgstr "Area Kerja %s%d"
|
||||
|
||||
#: ../src/ui/menu.c:384
|
||||
#: ../src/ui/menu.c:397
|
||||
msgid "Move to Another _Workspace"
|
||||
msgstr "Pindahkan ke Area Kerja _Lain"
|
||||
|
||||
@@ -1170,18 +1163,18 @@ msgid ""
|
||||
msgstr ""
|
||||
"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> tidak ada"
|
||||
|
||||
#: ../src/ui/theme.c:5082
|
||||
#: ../src/ui/theme.c:5084
|
||||
#, c-format
|
||||
msgid "Failed to load theme \"%s\": %s\n"
|
||||
msgstr "Gagal membuka tema \"%s\": %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:5218 ../src/ui/theme.c:5225 ../src/ui/theme.c:5232
|
||||
#: ../src/ui/theme.c:5239 ../src/ui/theme.c:5246
|
||||
#: ../src/ui/theme.c:5220 ../src/ui/theme.c:5227 ../src/ui/theme.c:5234
|
||||
#: ../src/ui/theme.c:5241 ../src/ui/theme.c:5248
|
||||
#, c-format
|
||||
msgid "No <%s> set for theme \"%s\""
|
||||
msgstr "Tidak ada <%s> yang ditentukan untuk tema \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:5254
|
||||
#: ../src/ui/theme.c:5256
|
||||
#, c-format
|
||||
msgid ""
|
||||
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
|
||||
@@ -1190,14 +1183,14 @@ msgstr ""
|
||||
"Tidak ada gaya frame untuk tipe window \"%s\" pada tema \"%s\". Tambah dulu "
|
||||
"elemen <window type=\"%s\" style_set=\"whatever\"/>"
|
||||
|
||||
#: ../src/ui/theme.c:5661 ../src/ui/theme.c:5723 ../src/ui/theme.c:5786
|
||||
#: ../src/ui/theme.c:5663 ../src/ui/theme.c:5725 ../src/ui/theme.c:5788
|
||||
#, 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:5669 ../src/ui/theme.c:5731 ../src/ui/theme.c:5794
|
||||
#: ../src/ui/theme.c:5671 ../src/ui/theme.c:5733 ../src/ui/theme.c:5796
|
||||
#, c-format
|
||||
msgid "Constant \"%s\" has already been defined"
|
||||
msgstr "Konstanta \"%s\" telah didefinisikan sebelumnya"
|
||||
@@ -1585,3 +1578,201 @@ msgstr "<%s> disebutkan dua kali pada tema ini"
|
||||
#, c-format
|
||||
msgid "Failed to find a valid file for theme %s\n"
|
||||
msgstr "Gagal menemukan berkas yang sah untuk tema %s\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:99
|
||||
msgid "_Windows"
|
||||
msgstr "_Jendela"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:100
|
||||
msgid "_Dialog"
|
||||
msgstr "_Dialog"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:101
|
||||
msgid "_Modal dialog"
|
||||
msgstr "Dialog _modal"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:102
|
||||
msgid "_Utility"
|
||||
msgstr "_Utilitas"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:103
|
||||
msgid "_Splashscreen"
|
||||
msgstr "Layar _pembuka"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:104
|
||||
msgid "_Top dock"
|
||||
msgstr "Dok a_tas"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:105
|
||||
msgid "_Bottom dock"
|
||||
msgstr "Dok _bawah"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:106
|
||||
msgid "_Left dock"
|
||||
msgstr "Dok k_iri"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:107
|
||||
msgid "_Right dock"
|
||||
msgstr "Dok kana_n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:108
|
||||
msgid "_All docks"
|
||||
msgstr "Semu_a dok"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:109
|
||||
msgid "Des_ktop"
|
||||
msgstr "Des_ktop"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:115
|
||||
msgid "Open another one of these windows"
|
||||
msgstr "Buka lagi jendela semacam ini"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:117
|
||||
msgid "This is a demo button with an 'open' icon"
|
||||
msgstr "Ini contoh tombol dengan ikon 'open'"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:119
|
||||
msgid "This is a demo button with a 'quit' icon"
|
||||
msgstr "Ini contoh tombol dengan ikon 'quit'"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:248
|
||||
msgid "This is a sample message in a sample dialog"
|
||||
msgstr "Ini contoh pesan pada suatu dialog"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:328
|
||||
#, c-format
|
||||
msgid "Fake menu item %d\n"
|
||||
msgstr "Item menu %d\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:363
|
||||
msgid "Border-only window"
|
||||
msgstr "Jendela dengan garis pembatas"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:365
|
||||
msgid "Bar"
|
||||
msgstr "Kotak"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:382
|
||||
msgid "Normal Application Window"
|
||||
msgstr "Jendela Aplikasi Normal"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:386
|
||||
msgid "Dialog Box"
|
||||
msgstr "Kotak Dialog"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:390
|
||||
msgid "Modal Dialog Box"
|
||||
msgstr "Kotak Dialog Modal"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:394
|
||||
msgid "Utility Palette"
|
||||
msgstr "Kotak Perkakas"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:398
|
||||
msgid "Torn-off Menu"
|
||||
msgstr "Menu Dapat Dilepas"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:402
|
||||
msgid "Border"
|
||||
msgstr "Batas"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:406
|
||||
msgid "Attached Modal Dialog"
|
||||
msgstr "Dialog Modal yang Dilampirkan"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:737
|
||||
#, c-format
|
||||
msgid "Button layout test %d"
|
||||
msgstr "Tes komposisi tombol %d"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:766
|
||||
#, c-format
|
||||
msgid "%g milliseconds to draw one window frame"
|
||||
msgstr "lama waktu menggambar satu bingkai jendela %g milidetik"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:811
|
||||
#, c-format
|
||||
msgid "Usage: metacity-theme-viewer [THEMENAME]\n"
|
||||
msgstr "Cara pakai: metacity-theme-viewer [NAMA TEMA]\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:818
|
||||
#, c-format
|
||||
msgid "Error loading theme: %s\n"
|
||||
msgstr "Ada error saat membaca tema: %s\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:824
|
||||
#, c-format
|
||||
msgid "Loaded theme \"%s\" in %g seconds\n"
|
||||
msgstr "Tema \"%s\" dibuka dalam %g detik\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:869
|
||||
msgid "Normal Title Font"
|
||||
msgstr "Judul dengan huruf normal"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:875
|
||||
msgid "Small Title Font"
|
||||
msgstr "Judul dengan huruf ukuran kecil"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:881
|
||||
msgid "Large Title Font"
|
||||
msgstr "Judul Raksasa"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:886
|
||||
msgid "Button Layouts"
|
||||
msgstr "Komposisi Tombol"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:891
|
||||
msgid "Benchmark"
|
||||
msgstr "Pengukuran"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:947
|
||||
msgid "Window Title Goes Here"
|
||||
msgstr "Ini tempat judul jendela"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1053
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g "
|
||||
"seconds wall clock time including X server resources (%g milliseconds per "
|
||||
"frame)\n"
|
||||
msgstr ""
|
||||
"%d frame dibuat dalam %g detik dalam waktu klien (%g milidetik per frame) "
|
||||
"dan %g detik dalam waktu sebenarnya (%g milidetik per frame)\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1273
|
||||
msgid "position expression test returned TRUE but set error"
|
||||
msgstr "tes ekspresi posisi berakhir TRUE tapi justru ada error"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1275
|
||||
msgid "position expression test returned FALSE but didn't set error"
|
||||
msgstr "tes ekspresi posisi berakhir FALSE tapi tidak ada error"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1279
|
||||
msgid "Error was expected but none given"
|
||||
msgstr "Seharusnya ada error, tapi ini kok tidak ada"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1281
|
||||
#, c-format
|
||||
msgid "Error %d was expected but %d given"
|
||||
msgstr "Seharunya ada error %d, tapi yang terjadi %d"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1287
|
||||
#, c-format
|
||||
msgid "Error not expected but one was returned: %s"
|
||||
msgstr "Seharusnya tidak ada error, tapi ini tiba-tiba ada error: %s"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1291
|
||||
#, c-format
|
||||
msgid "x value was %d, %d was expected"
|
||||
msgstr "nilai x sebelumnya %d, padahal seharusnya %d"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1294
|
||||
#, c-format
|
||||
msgid "y value was %d, %d was expected"
|
||||
msgstr "nilai y sebelumnya %d, padahal seharusnya %d"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1359
|
||||
#, c-format
|
||||
msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
|
||||
msgstr "ekspresi koordinat %d diambil dalam %g detik (rata-rata %g detik)\n"
|
||||
|
||||
|
||||
458
po/ko.po
458
po/ko.po
@@ -18,8 +18,8 @@ msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?"
|
||||
"product=mutter&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-08-18 20:03+0000\n"
|
||||
"PO-Revision-Date: 2013-09-09 04:46+0900\n"
|
||||
"POT-Creation-Date: 2013-03-01 15:50+0000\n"
|
||||
"PO-Revision-Date: 2013-03-13 03:52+0900\n"
|
||||
"Last-Translator: Changwoo Ryu <cwryu@debian.org>\n"
|
||||
"Language-Team: GNOME Korea <gnome-kr@googlegroups.com>\n"
|
||||
"Language: Korean\n"
|
||||
@@ -218,7 +218,7 @@ msgstr "오른쪽 절반 뷰"
|
||||
|
||||
#. 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:589
|
||||
#: ../src/compositor/compositor.c:507
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@@ -227,11 +227,11 @@ msgstr ""
|
||||
"다른 창 구성 관리 프로그램이 이미 디스플레이 \"%2$s\" 화면 %1$i번에서 실행 중"
|
||||
"입니다."
|
||||
|
||||
#: ../src/compositor/meta-background.c:1076
|
||||
#: ../src/compositor/meta-background.c:1111
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "파일에서 배경 텍스처를 만들 수 없습니다"
|
||||
|
||||
#: ../src/core/bell.c:322
|
||||
#: ../src/core/bell.c:320
|
||||
msgid "Bell event"
|
||||
msgstr "삑소리 이벤트"
|
||||
|
||||
@@ -263,17 +263,17 @@ msgstr "기다리기(_W)"
|
||||
msgid "_Force Quit"
|
||||
msgstr "강제로 끝내기(_F)"
|
||||
|
||||
#: ../src/core/display.c:421
|
||||
#: ../src/core/display.c:401
|
||||
#, c-format
|
||||
msgid "Missing %s extension required for compositing"
|
||||
msgstr "콤포짓에 필요한 %s 확장 기능이 없습니다"
|
||||
|
||||
#: ../src/core/display.c:513
|
||||
#: ../src/core/display.c:493
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "X 윈도 시스템 디스플레이 '%s'을(를) 여는데 실패하였습니다\n"
|
||||
|
||||
#: ../src/core/keybindings.c:1136
|
||||
#: ../src/core/keybindings.c:929
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Some other program is already using the key %s with modifiers %x as a "
|
||||
@@ -282,41 +282,41 @@ msgstr ""
|
||||
"다른 프로그램에서 이미 단축키로 변경 키 %2$x와(과) 키 %1$s을(를) 사용하고 있"
|
||||
"습니다\n"
|
||||
|
||||
#: ../src/core/keybindings.c:1333
|
||||
#: ../src/core/keybindings.c:1129
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid accelerator\n"
|
||||
msgstr "\"%s\"은(는) 올바른 단축키가 아닙니다\n"
|
||||
|
||||
#: ../src/core/main.c:197
|
||||
#: ../src/core/main.c:196
|
||||
msgid "Disable connection to session manager"
|
||||
msgstr "세션 관리자와 연결 하지 않습니다"
|
||||
|
||||
#: ../src/core/main.c:203
|
||||
#: ../src/core/main.c:202
|
||||
msgid "Replace the running window manager"
|
||||
msgstr "실행 중인 창 관리자를 바꿉니다"
|
||||
|
||||
#: ../src/core/main.c:209
|
||||
#: ../src/core/main.c:208
|
||||
msgid "Specify session management ID"
|
||||
msgstr "세션 관리 ID를 지정합니다"
|
||||
|
||||
#: ../src/core/main.c:214
|
||||
#: ../src/core/main.c:213
|
||||
msgid "X Display to use"
|
||||
msgstr "사용할 X 디스플레이"
|
||||
|
||||
#: ../src/core/main.c:220
|
||||
#: ../src/core/main.c:219
|
||||
msgid "Initialize session from savefile"
|
||||
msgstr "저장 파일에서 세션을 초기화 합니다"
|
||||
|
||||
#: ../src/core/main.c:226
|
||||
#: ../src/core/main.c:225
|
||||
msgid "Make X calls synchronous"
|
||||
msgstr "동기 X 호출을 합니다"
|
||||
|
||||
#: ../src/core/main.c:534
|
||||
#: ../src/core/main.c:494
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "테마 디렉터리를 읽는 데 실패했습니다: %s\n"
|
||||
|
||||
#: ../src/core/main.c:550
|
||||
#: ../src/core/main.c:510
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
@@ -324,19 +324,6 @@ msgstr ""
|
||||
"테마를 찾을 수 없습니다! %s이(가) 있고 올바른 테마가 들어 있는지 확인하십시"
|
||||
"오.\n"
|
||||
|
||||
#: ../src/core/monitor.c:711
|
||||
msgid "Built-in display"
|
||||
msgstr "내장 디스플레이"
|
||||
|
||||
#. TRANSLATORS: this is a monitor name (in case we don't know
|
||||
#. the vendor), it's Unknown followed by a size in inches,
|
||||
#. like 'Unknown 15"'
|
||||
#.
|
||||
#: ../src/core/monitor.c:739
|
||||
#, c-format
|
||||
msgid "Unknown %s"
|
||||
msgstr "알 수 없는 %s인치"
|
||||
|
||||
#: ../src/core/mutter.c:40
|
||||
#, c-format
|
||||
msgid ""
|
||||
@@ -360,20 +347,18 @@ msgstr "버전을 출력합니다"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "사용할 머터 플러그인"
|
||||
|
||||
#: ../src/core/prefs.c:1202
|
||||
#: ../src/core/prefs.c:1087
|
||||
msgid ""
|
||||
"Workarounds for broken applications disabled. Some applications may not "
|
||||
"behave properly.\n"
|
||||
msgstr ""
|
||||
"응용 프로그램에 대한 임시 방편을 막았습니다. 몇몇 응용 프로그램이 제대로 동작"
|
||||
"하지 않을것입니다.\n"
|
||||
msgstr "응용 프로그램에 대한 임시 방편을 막았습니다. 몇몇 응용 프로그램이 제대로 동작하지 않을것입니다.\n"
|
||||
|
||||
#: ../src/core/prefs.c:1277
|
||||
#: ../src/core/prefs.c:1162
|
||||
#, c-format
|
||||
msgid "Could not parse font description \"%s\" from GSettings key %s\n"
|
||||
msgstr "GSettings 키 %2$s에서 글꼴 지정 \"%1$s\"을(를) 분석할 수 없습니다\n"
|
||||
|
||||
#: ../src/core/prefs.c:1343
|
||||
#: ../src/core/prefs.c:1228
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for mouse button "
|
||||
@@ -382,7 +367,7 @@ msgstr ""
|
||||
"설정 데이터베이스에서 찾은 \"%s\"이(가) 마우스 단추 변경 키의 올바른 값이 아"
|
||||
"닙니다\n"
|
||||
|
||||
#: ../src/core/prefs.c:1909
|
||||
#: ../src/core/prefs.c:1780
|
||||
#, c-format
|
||||
msgid ""
|
||||
"\"%s\" found in configuration database is not a valid value for keybinding "
|
||||
@@ -391,17 +376,17 @@ msgstr ""
|
||||
"설정 데이터베이스에서 찾은 \"%s\"이(가) 단축키 \"%s\"에 대한 올바른 값이 아닙"
|
||||
"니다\n"
|
||||
|
||||
#: ../src/core/prefs.c:1999
|
||||
#: ../src/core/prefs.c:1879
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "작업 공간 %d"
|
||||
|
||||
#: ../src/core/screen.c:534
|
||||
#: ../src/core/screen.c:673
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "디스플레이 '%2$s'의 화면 %1$d은(는) 잘못되었습니다\n"
|
||||
|
||||
#: ../src/core/screen.c:550
|
||||
#: ../src/core/screen.c:689
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
@@ -410,19 +395,19 @@ msgstr ""
|
||||
"디스플레이 \"%2$s\"의 화면 %1$d에 이미 창 관리자가 실행되고 있습니다. 현재 "
|
||||
"창 관리자를 무시하는 --replace 옵션을 써보십시오.\n"
|
||||
|
||||
#: ../src/core/screen.c:577
|
||||
#: ../src/core/screen.c:716
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not acquire window manager selection on screen %d display \"%s\"\n"
|
||||
msgstr "디스플레이 \"%2$s\"의 화면 %1$d에 창 관리 선택을 가질 수 없습니다\n"
|
||||
|
||||
#: ../src/core/screen.c:655
|
||||
#: ../src/core/screen.c:794
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr ""
|
||||
"디스플레이 \"%2$s\"의 화면 %1$d은(는) 이미 창 관리자가 실행되고 있습니다\n"
|
||||
|
||||
#: ../src/core/screen.c:846
|
||||
#: ../src/core/screen.c:979
|
||||
#, c-format
|
||||
msgid "Could not release screen %d on display \"%s\"\n"
|
||||
msgstr "디스플레이 \"%2$s\"의 화면 %1$d을(를) 떼어 놓을수 없습니다\n"
|
||||
@@ -482,43 +467,44 @@ msgstr ""
|
||||
"이 창은 "현재 설정 저장"을 지원하지 않기 때문에 다음 번에 로그인 "
|
||||
"할 때 수동으로 다시 시작해야 합니다."
|
||||
|
||||
#: ../src/core/util.c:84
|
||||
#: ../src/core/util.c:80
|
||||
#, c-format
|
||||
msgid "Failed to open debug log: %s\n"
|
||||
msgstr "디버그 로그 열기 실패: %s\n"
|
||||
|
||||
#: ../src/core/util.c:94
|
||||
#: ../src/core/util.c:90
|
||||
#, c-format
|
||||
msgid "Failed to fdopen() log file %s: %s\n"
|
||||
msgstr "로그 파일 %s을(를) fdopen()하기 실패: %s\n"
|
||||
|
||||
#: ../src/core/util.c:100
|
||||
#: ../src/core/util.c:96
|
||||
#, c-format
|
||||
msgid "Opened log file %s\n"
|
||||
msgstr "로그 파일 %s을(를) 엽니다\n"
|
||||
|
||||
#: ../src/core/util.c:119
|
||||
#: ../src/core/util.c:115 ../src/tools/mutter-message.c:149
|
||||
#, c-format
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "머터가 자세한 모드 지원 없이 컴파일 되었습니다\n"
|
||||
|
||||
#: ../src/core/util.c:264
|
||||
#: ../src/core/util.c:259
|
||||
msgid "Window manager: "
|
||||
msgstr "창 관리자: "
|
||||
|
||||
#: ../src/core/util.c:414
|
||||
#: ../src/core/util.c:407
|
||||
msgid "Bug in window manager: "
|
||||
msgstr "창 관리자의 벌레: "
|
||||
|
||||
#: ../src/core/util.c:445
|
||||
#: ../src/core/util.c:438
|
||||
msgid "Window manager warning: "
|
||||
msgstr "창 관리자 주의: "
|
||||
|
||||
#: ../src/core/util.c:473
|
||||
#: ../src/core/util.c:466
|
||||
msgid "Window manager error: "
|
||||
msgstr "장 관리자 오류: "
|
||||
|
||||
#. first time through
|
||||
#: ../src/core/window.c:7533
|
||||
#: ../src/core/window.c:7539
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets SM_CLIENT_ID on itself, instead of on the WM_CLIENT_LEADER "
|
||||
@@ -534,7 +520,7 @@ msgstr ""
|
||||
#. * MWM but not WM_NORMAL_HINTS are basically broken. We complain
|
||||
#. * about these apps but make them work.
|
||||
#.
|
||||
#: ../src/core/window.c:8257
|
||||
#: ../src/core/window.c:8263
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Window %s sets an MWM hint indicating it isn't resizable, but sets min size "
|
||||
@@ -543,23 +529,23 @@ msgstr ""
|
||||
"%s 창에서 크기 변경이 불가능하다는 MWM 힌트를 설정했지만, 최소 크기 %d x %d "
|
||||
"및 최대 크기 %d x %d(으)로 설정했습니다. 앞뒤가 맞지 않습니다.\n"
|
||||
|
||||
#: ../src/core/window-props.c:347
|
||||
#: ../src/core/window-props.c:318
|
||||
#, c-format
|
||||
msgid "Application set a bogus _NET_WM_PID %lu\n"
|
||||
msgstr "응용 프로그램이 가짜 _NET_WM_PID %lu을(를) 설정하였습니다\n"
|
||||
|
||||
# <창제목> (on <기계>)
|
||||
#: ../src/core/window-props.c:463
|
||||
#: ../src/core/window-props.c:434
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (%s에서)"
|
||||
|
||||
#: ../src/core/window-props.c:1546
|
||||
#: ../src/core/window-props.c:1517
|
||||
#, c-format
|
||||
msgid "Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n"
|
||||
msgstr "%2$s에 대해 WM_TRANSIENT_FOR 0x%1$lx 창이 잘못되었습니다.\n"
|
||||
|
||||
#: ../src/core/window-props.c:1557
|
||||
#: ../src/core/window-props.c:1528
|
||||
#, c-format
|
||||
msgid "WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n"
|
||||
msgstr "%2$s에 대해 WM_TRANSIENT_FOR 0x%1$lx 창은 무한 반복입니다.\n"
|
||||
@@ -588,7 +574,9 @@ msgstr "창 0x%2$lx의 등록 정보 %1$s은(는) 잘못된 UTF-8이 들어 있
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"
|
||||
msgstr "창 0x%2$lx의 등록 정보 %1$s은(는) 목록안의 항목 %3$d에 잘못된 UTF-8 문자가 들어 있습니다\n"
|
||||
msgstr ""
|
||||
"창 0x%2$lx의 등록 정보 %1$s은(는) 목록안의 항목 %3$d에 잘못된 UTF-8을 포함하"
|
||||
"고 있습니다\n"
|
||||
|
||||
#: ../src/mutter.desktop.in.h:1 ../src/mutter-wm.desktop.in.h:1
|
||||
msgid "Mutter"
|
||||
@@ -717,104 +705,109 @@ msgstr "탭 팝업에서 창 선택"
|
||||
msgid "Cancel tab popup"
|
||||
msgstr "탭 팝업 취소"
|
||||
|
||||
#: ../src/tools/mutter-message.c:123
|
||||
#, c-format
|
||||
msgid "Usage: %s\n"
|
||||
msgstr "사용법: %s\n"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:67
|
||||
#: ../src/ui/menu.c:69
|
||||
msgid "Mi_nimize"
|
||||
msgstr "최소화(_N)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:69
|
||||
#: ../src/ui/menu.c:71
|
||||
msgid "Ma_ximize"
|
||||
msgstr "최대화(_X)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:71
|
||||
#: ../src/ui/menu.c:73
|
||||
msgid "Unma_ximize"
|
||||
msgstr "최대화 취소(_X)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:73
|
||||
#: ../src/ui/menu.c:75
|
||||
msgid "Roll _Up"
|
||||
msgstr "말아올리기(_U)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:75
|
||||
#: ../src/ui/menu.c:77
|
||||
msgid "_Unroll"
|
||||
msgstr "펼치기(_U)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:77
|
||||
#: ../src/ui/menu.c:79
|
||||
msgid "_Move"
|
||||
msgstr "옮기기(_M)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:79
|
||||
#: ../src/ui/menu.c:81
|
||||
msgid "_Resize"
|
||||
msgstr "크기 조정(_R)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:81
|
||||
#: ../src/ui/menu.c:83
|
||||
msgid "Move Titlebar On_screen"
|
||||
msgstr "창 제목막대 화면에 표시(_S)"
|
||||
|
||||
#. separator
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:84 ../src/ui/menu.c:86
|
||||
#: ../src/ui/menu.c:86 ../src/ui/menu.c:88
|
||||
msgid "Always on _Top"
|
||||
msgstr "항상 위(_T)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:88
|
||||
#: ../src/ui/menu.c:90
|
||||
msgid "_Always on Visible Workspace"
|
||||
msgstr "항상 현재 작업 공간에 놓기(_A)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:90
|
||||
#: ../src/ui/menu.c:92
|
||||
msgid "_Only on This Workspace"
|
||||
msgstr "이 작업 공간에만 놓기(_O)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:92
|
||||
#: ../src/ui/menu.c:94
|
||||
msgid "Move to Workspace _Left"
|
||||
msgstr "왼쪽 작업 공간으로 옮기기(_L)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:94
|
||||
#: ../src/ui/menu.c:96
|
||||
msgid "Move to Workspace R_ight"
|
||||
msgstr "오른쪽 작업 공간으로 옮기기(_I)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:96
|
||||
#: ../src/ui/menu.c:98
|
||||
msgid "Move to Workspace _Up"
|
||||
msgstr "위쪽 작업 공간으로 옮기기(_U)"
|
||||
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:98
|
||||
#: ../src/ui/menu.c:100
|
||||
msgid "Move to Workspace _Down"
|
||||
msgstr "아래쪽 작업 공간으로 옮기기(_D)"
|
||||
|
||||
#. separator
|
||||
#. Translators: Translate this string the same way as you do in libwnck!
|
||||
#: ../src/ui/menu.c:102
|
||||
#: ../src/ui/menu.c:104
|
||||
msgid "_Close"
|
||||
msgstr "닫기(_C)"
|
||||
|
||||
#: ../src/ui/menu.c:202
|
||||
#: ../src/ui/menu.c:204
|
||||
#, c-format
|
||||
msgid "Workspace %d%n"
|
||||
msgstr "작업 공간 %d%n"
|
||||
|
||||
#: ../src/ui/menu.c:212
|
||||
#: ../src/ui/menu.c:214
|
||||
#, c-format
|
||||
msgid "Workspace 1_0"
|
||||
msgstr "작업 공간 1_0"
|
||||
|
||||
#: ../src/ui/menu.c:214
|
||||
#: ../src/ui/menu.c:216
|
||||
#, c-format
|
||||
msgid "Workspace %s%d"
|
||||
msgstr "작업 공간 %s%d"
|
||||
|
||||
#: ../src/ui/menu.c:384
|
||||
#: ../src/ui/menu.c:397
|
||||
msgid "Move to Another _Workspace"
|
||||
msgstr "다른 작업 공간으로 옮기기(_W)"
|
||||
|
||||
@@ -916,50 +909,50 @@ msgstr "Mod5"
|
||||
msgid "%d x %d"
|
||||
msgstr "%d x %d"
|
||||
|
||||
#: ../src/ui/theme.c:236
|
||||
#: ../src/ui/theme.c:235
|
||||
msgid "top"
|
||||
msgstr "맨 위"
|
||||
|
||||
#: ../src/ui/theme.c:238
|
||||
#: ../src/ui/theme.c:237
|
||||
msgid "bottom"
|
||||
msgstr "맨 아래"
|
||||
|
||||
#: ../src/ui/theme.c:240
|
||||
#: ../src/ui/theme.c:239
|
||||
msgid "left"
|
||||
msgstr "왼쪽"
|
||||
|
||||
#: ../src/ui/theme.c:242
|
||||
#: ../src/ui/theme.c:241
|
||||
msgid "right"
|
||||
msgstr "오른쪽"
|
||||
|
||||
#: ../src/ui/theme.c:270
|
||||
#: ../src/ui/theme.c:269
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify \"%s\" dimension"
|
||||
msgstr "프레임 위치가 \"%s\"차원으로 지정되지 않았습니다"
|
||||
|
||||
#: ../src/ui/theme.c:289
|
||||
#: ../src/ui/theme.c:288
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
|
||||
msgstr ""
|
||||
"프레임 위치가 가장자리 \"%2$s\" 가장자리의 \"%1$s\"차원으로 지정되지 않았습니"
|
||||
"다."
|
||||
|
||||
#: ../src/ui/theme.c:326
|
||||
#: ../src/ui/theme.c:325
|
||||
#, c-format
|
||||
msgid "Button aspect ratio %g is not reasonable"
|
||||
msgstr "단추의 가로세로 비 %g이(가) 적당하지 않습니다"
|
||||
|
||||
#: ../src/ui/theme.c:338
|
||||
#: ../src/ui/theme.c:337
|
||||
#, c-format
|
||||
msgid "Frame geometry does not specify size of buttons"
|
||||
msgstr "프레임 위치가 단추의 크기로 지정되지 않았습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1051
|
||||
#: ../src/ui/theme.c:1050
|
||||
#, c-format
|
||||
msgid "Gradients should have at least two colors"
|
||||
msgstr "서서히 변하는 색으로 지정하려면 최소 2색이 필요합니다"
|
||||
|
||||
#: ../src/ui/theme.c:1203
|
||||
#: ../src/ui/theme.c:1202
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK custom color specification must have color name and fallback in "
|
||||
@@ -968,7 +961,7 @@ msgstr ""
|
||||
"GTK 사용자 지정 색상 지정은 색 이름과 대체할 색을 괄호 안에 써야 합니다. 예"
|
||||
"를 들어: gtk:custom(foo,bar). \"%s\"을(를) 분석할 수 없습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1219
|
||||
#: ../src/ui/theme.c:1218
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
|
||||
@@ -977,7 +970,7 @@ msgstr ""
|
||||
"gtk:custom의 color_name 파라미터 안에 잘못된 문자 '%c'. A-Za-z0-9-_ 문자만 허"
|
||||
"용합니다."
|
||||
|
||||
#: ../src/ui/theme.c:1233
|
||||
#: ../src/ui/theme.c:1232
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
||||
@@ -986,7 +979,7 @@ msgstr ""
|
||||
"gtk:custom 형식은 \"gtk:custom(색이름,대체색)\"입니다, \"%s\"(은)는 형식에 맞"
|
||||
"지 않습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1278
|
||||
#: ../src/ui/theme.c:1277
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
|
||||
@@ -995,7 +988,7 @@ msgstr ""
|
||||
"GTK 색상 지정은 중괄호안에 있어야 합니다. 예를 들어: gtk:fg[NORMAL], 여기서 "
|
||||
"NORMAL이 값입니다. \"%s\"을(를) 분석할 수 없습니다."
|
||||
|
||||
#: ../src/ui/theme.c:1292
|
||||
#: ../src/ui/theme.c:1291
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have a close bracket after the state, e.g. gtk:"
|
||||
@@ -1004,17 +997,17 @@ msgstr ""
|
||||
"GTK 색상 지정은 값 뒤에 중괄호로 닫혀 있어야 합니다. 예를 들어: gtk:fg"
|
||||
"[NORMAL], 여기서 NORMAL은 값입니다. \"%s\"을(를) 분석할 수 없습니다."
|
||||
|
||||
#: ../src/ui/theme.c:1303
|
||||
#: ../src/ui/theme.c:1302
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" in color specification"
|
||||
msgstr "색상 지정의 \"%s\" 값을 이해할 수 없습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1316
|
||||
#: ../src/ui/theme.c:1315
|
||||
#, c-format
|
||||
msgid "Did not understand color component \"%s\" in color specification"
|
||||
msgstr "색상 지정의 색상 구성요소 \"%s\"을(를) 이해할 수 없습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1345
|
||||
#: ../src/ui/theme.c:1344
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
|
||||
@@ -1023,17 +1016,17 @@ msgstr ""
|
||||
"섞기 형식은 \"blend/bg_color/fg_color/alpha\"입니다, \"%s\"은(는) 형식에 맞"
|
||||
"지 않습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1356
|
||||
#: ../src/ui/theme.c:1355
|
||||
#, c-format
|
||||
msgid "Could not parse alpha value \"%s\" in blended color"
|
||||
msgstr "색상 섞기에서 알파 값 \"%s\"을(를) 분석할 수 없습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1366
|
||||
#: ../src/ui/theme.c:1365
|
||||
#, c-format
|
||||
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
|
||||
msgstr "색상 섞기에서 알파 값 \"%s\"은(는) 0.0과 1.0 사이의 값이 아닙니다"
|
||||
msgstr "색상 섞기에서 알파 값 \"%s\"은(는) 0.0 과 1.0사이의 값이 아닙니다"
|
||||
|
||||
#: ../src/ui/theme.c:1413
|
||||
#: ../src/ui/theme.c:1412
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
|
||||
@@ -1041,78 +1034,79 @@ msgstr ""
|
||||
"그림자 형식은 \"shade/base_color/format\"입니다, \"%s\"(은)는 형식에 맞지 않"
|
||||
"습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1424
|
||||
#: ../src/ui/theme.c:1423
|
||||
#, c-format
|
||||
msgid "Could not parse shade factor \"%s\" in shaded color"
|
||||
msgstr "그림자색에서 그림자 인자 \"%s\"(을)를 해석할 수 없습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1434
|
||||
#: ../src/ui/theme.c:1433
|
||||
#, c-format
|
||||
msgid "Shade factor \"%s\" in shaded color is negative"
|
||||
msgstr "그림자색에서 그림자 인자 \"%s\"(은)는 음수입니다"
|
||||
|
||||
#: ../src/ui/theme.c:1463
|
||||
#: ../src/ui/theme.c:1462
|
||||
#, c-format
|
||||
msgid "Could not parse color \"%s\""
|
||||
msgstr "색상 \"%s\"을(를) 해석할 수 없습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1780
|
||||
#: ../src/ui/theme.c:1779
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains character '%s' which is not allowed"
|
||||
msgstr "좌표식에 허용되지 않는 문자 '%s'(이)가 들어 있습니다"
|
||||
msgstr "좌표식에 허용되지 않는 문자 '%s'(이)가 포함되어 있습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1807
|
||||
#: ../src/ui/theme.c:1806
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contains floating point number '%s' which could not be "
|
||||
"parsed"
|
||||
msgstr "좌표식에 분석할 수 없는 부동소수점 숫자 '%s'이(가) 포함되어 있습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1821
|
||||
#: ../src/ui/theme.c:1820
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains integer '%s' which could not be parsed"
|
||||
msgstr "좌표식에 분석할 수 없는 정수 '%s'이(가) 포함되어 있습니다"
|
||||
|
||||
#: ../src/ui/theme.c:1942
|
||||
#: ../src/ui/theme.c:1941
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contained unknown operator at the start of this text: "
|
||||
"\"%s\""
|
||||
msgstr "좌표식에 이 글자 시작부분에 알 수 없는 연산자가 들어 있습니다: \"%s\""
|
||||
msgstr ""
|
||||
"좌표식에 이 글자 시작부분에 알 수 없는 연산자가 포함되어 있습니다: \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1999
|
||||
#: ../src/ui/theme.c:1998
|
||||
#, c-format
|
||||
msgid "Coordinate expression was empty or not understood"
|
||||
msgstr "좌표식이 비어있거나 이해할 수 없습니다"
|
||||
|
||||
#: ../src/ui/theme.c:2112 ../src/ui/theme.c:2122 ../src/ui/theme.c:2156
|
||||
#: ../src/ui/theme.c:2111 ../src/ui/theme.c:2121 ../src/ui/theme.c:2155
|
||||
#, c-format
|
||||
msgid "Coordinate expression results in division by zero"
|
||||
msgstr "좌표식의 결과 값이 0로 나누었습니다"
|
||||
|
||||
#: ../src/ui/theme.c:2164
|
||||
#: ../src/ui/theme.c:2163
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression tries to use mod operator on a floating-point number"
|
||||
msgstr "좌표식에서 부동소수점 수에 나머지 연산을 하려 합니다"
|
||||
|
||||
#: ../src/ui/theme.c:2220
|
||||
#: ../src/ui/theme.c:2219
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has an operator \"%s\" where an operand was expected"
|
||||
msgstr "좌표식에서 피연산자가 들어갈 곳에 연산자 \"%s\"이(가) 있습니다"
|
||||
|
||||
#: ../src/ui/theme.c:2229
|
||||
#: ../src/ui/theme.c:2228
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an operand where an operator was expected"
|
||||
msgstr "좌표식에서 연산자가 들어갈 곳에 피연산자가 있습니다"
|
||||
|
||||
#: ../src/ui/theme.c:2237
|
||||
#: ../src/ui/theme.c:2236
|
||||
#, c-format
|
||||
msgid "Coordinate expression ended with an operator instead of an operand"
|
||||
msgstr "좌표식에서 피연산자 대신에 연산자로 끝나있습니다"
|
||||
|
||||
#: ../src/ui/theme.c:2247
|
||||
#: ../src/ui/theme.c:2246
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
|
||||
@@ -1121,37 +1115,37 @@ msgstr ""
|
||||
"좌표식에서 피연산자가 없는 연산자 \"%2$c\"다음에 연산자 \"%1$c\"이(가) 있습니"
|
||||
"다"
|
||||
|
||||
#: ../src/ui/theme.c:2398 ../src/ui/theme.c:2443
|
||||
#: ../src/ui/theme.c:2397 ../src/ui/theme.c:2442
|
||||
#, c-format
|
||||
msgid "Coordinate expression had unknown variable or constant \"%s\""
|
||||
msgstr "좌표식에 알 수 없는 변수나 상수 \"%s\"이(가) 있습니다"
|
||||
|
||||
#: ../src/ui/theme.c:2497
|
||||
#: ../src/ui/theme.c:2496
|
||||
#, c-format
|
||||
msgid "Coordinate expression parser overflowed its buffer."
|
||||
msgstr "좌표 계산 파서의 버퍼가 크기를 넘어갔습니다."
|
||||
|
||||
#: ../src/ui/theme.c:2526
|
||||
#: ../src/ui/theme.c:2525
|
||||
#, c-format
|
||||
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
|
||||
msgstr "좌표식에 닫는 괄호는 있지만 여는 괄호가 없습니다"
|
||||
|
||||
#: ../src/ui/theme.c:2590
|
||||
#: ../src/ui/theme.c:2589
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
|
||||
msgstr "좌표식에 여는 괄호는 있지만 닫는 괄호가 없습니다"
|
||||
|
||||
#: ../src/ui/theme.c:2601
|
||||
#: ../src/ui/theme.c:2600
|
||||
#, c-format
|
||||
msgid "Coordinate expression doesn't seem to have any operators or operands"
|
||||
msgstr "좌표식에 어떠한 연산자나 피연산자가 없습니다"
|
||||
|
||||
#: ../src/ui/theme.c:2814 ../src/ui/theme.c:2834 ../src/ui/theme.c:2854
|
||||
#: ../src/ui/theme.c:2813 ../src/ui/theme.c:2833 ../src/ui/theme.c:2853
|
||||
#, c-format
|
||||
msgid "Theme contained an expression that resulted in an error: %s\n"
|
||||
msgstr "테마가 오류 값을 내는 표현식이 들어 있습니다: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:4500
|
||||
#: ../src/ui/theme.c:4499
|
||||
#, c-format
|
||||
msgid ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
|
||||
@@ -1160,7 +1154,7 @@ msgstr ""
|
||||
"이 프레임 스타일에는 <button function=\"%s\" style=\"%s\" draw_ops=\"whatever"
|
||||
"\"/>가 지정되어야 합니다"
|
||||
|
||||
#: ../src/ui/theme.c:5011 ../src/ui/theme.c:5036
|
||||
#: ../src/ui/theme.c:5010 ../src/ui/theme.c:5035
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
|
||||
@@ -1168,18 +1162,18 @@ msgstr ""
|
||||
"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" state=\"whatever\"/> 가 없습니"
|
||||
"다"
|
||||
|
||||
#: ../src/ui/theme.c:5082
|
||||
#: ../src/ui/theme.c:5083
|
||||
#, c-format
|
||||
msgid "Failed to load theme \"%s\": %s\n"
|
||||
msgstr "테마 \"%s\"을(를) 읽을 수 없습니다: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:5218 ../src/ui/theme.c:5225 ../src/ui/theme.c:5232
|
||||
#: ../src/ui/theme.c:5239 ../src/ui/theme.c:5246
|
||||
#: ../src/ui/theme.c:5219 ../src/ui/theme.c:5226 ../src/ui/theme.c:5233
|
||||
#: ../src/ui/theme.c:5240 ../src/ui/theme.c:5247
|
||||
#, c-format
|
||||
msgid "No <%s> set for theme \"%s\""
|
||||
msgstr "테마 \"%2$s\"의 <%1$s>(이)가 설정되지 않았습니다"
|
||||
|
||||
#: ../src/ui/theme.c:5254
|
||||
#: ../src/ui/theme.c:5255
|
||||
#, c-format
|
||||
msgid ""
|
||||
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
|
||||
@@ -1188,14 +1182,14 @@ msgstr ""
|
||||
"테마 \"%2$s\"의 창 형식 \"%1$s\"에 대한 프레임 스타일이 없습니다,<window "
|
||||
"type=\"%3$s\" style_set=\"whatever\"/> 엘리먼트를 추가하십시오"
|
||||
|
||||
#: ../src/ui/theme.c:5661 ../src/ui/theme.c:5723 ../src/ui/theme.c:5786
|
||||
#: ../src/ui/theme.c:5662 ../src/ui/theme.c:5724 ../src/ui/theme.c:5787
|
||||
#, c-format
|
||||
msgid ""
|
||||
"User-defined constants must begin with a capital letter; \"%s\" does not"
|
||||
msgstr ""
|
||||
"사용자 정의 상수는 대문자로 시작되어야 합니다. \"%s\"은(는) 그렇지 않습니다."
|
||||
|
||||
#: ../src/ui/theme.c:5669 ../src/ui/theme.c:5731 ../src/ui/theme.c:5794
|
||||
#: ../src/ui/theme.c:5670 ../src/ui/theme.c:5732 ../src/ui/theme.c:5795
|
||||
#, c-format
|
||||
msgid "Constant \"%s\" has already been defined"
|
||||
msgstr "상수 \"%s\"은(는) 이미 지정되어 있습니다"
|
||||
@@ -1330,7 +1324,9 @@ msgstr "<%s> 엘리먼트는 <%s> 아래에 허용되지 않습니다"
|
||||
msgid ""
|
||||
"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" "
|
||||
"for buttons"
|
||||
msgstr "단추의 \"button_width\"/\"button_height\"와 \"aspect_ratio\"를 한꺼번에 지정할 수 없습니다"
|
||||
msgstr ""
|
||||
"단추의 button_width/button_height 와 \"aspect_ratio\"를 한꺼번에 지정할 수 없"
|
||||
"습니다"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1450
|
||||
#, c-format
|
||||
@@ -1391,7 +1387,7 @@ msgstr "\"%s\"라 불리는 <draw_ops>는 정의되지 않았습니다"
|
||||
#: ../src/ui/theme-parser.c:2706 ../src/ui/theme-parser.c:2802
|
||||
#, c-format
|
||||
msgid "Including draw_ops \"%s\" here would create a circular reference"
|
||||
msgstr "여기서 draw_ops \"%s\"을(를) 포함하면 순환 참조가 됩니다."
|
||||
msgstr "draw_ops를 포함하는 \"%s\"이(가) 자기 자신을 참조하고 있습니다"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2917
|
||||
#, c-format
|
||||
@@ -1573,7 +1569,205 @@ msgstr "<%s> 엘리먼트 안에 텍스트가 허용되지 않습니다"
|
||||
msgid "<%s> specified twice for this theme"
|
||||
msgstr "이 테마에서 <%s> 태그가 두 번 지정되었습니다"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4336
|
||||
#: ../src/ui/theme-parser.c:4334
|
||||
#, c-format
|
||||
msgid "Failed to find a valid file for theme %s\n"
|
||||
msgstr "%s 테마의 올바른 파일을 찾는 데 실패했습니다\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:99
|
||||
msgid "_Windows"
|
||||
msgstr "창(_W)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:100
|
||||
msgid "_Dialog"
|
||||
msgstr "대화 상자(_D)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:101
|
||||
msgid "_Modal dialog"
|
||||
msgstr "모달 대화 상자(_M)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:102
|
||||
msgid "_Utility"
|
||||
msgstr "도구(_U)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:103
|
||||
msgid "_Splashscreen"
|
||||
msgstr "스플래시 화면(_S)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:104
|
||||
msgid "_Top dock"
|
||||
msgstr "위 도크(_T)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:105
|
||||
msgid "_Bottom dock"
|
||||
msgstr "아래 도크(_B)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:106
|
||||
msgid "_Left dock"
|
||||
msgstr "왼쪽 도크(_L)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:107
|
||||
msgid "_Right dock"
|
||||
msgstr "오른쪽 도크(_R)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:108
|
||||
msgid "_All docks"
|
||||
msgstr "모든 도크(_A)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:109
|
||||
msgid "Des_ktop"
|
||||
msgstr "데스크톱(_K)"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:115
|
||||
msgid "Open another one of these windows"
|
||||
msgstr "이 창을 하나 더 엽니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:117
|
||||
msgid "This is a demo button with an 'open' icon"
|
||||
msgstr "'열기' 아이콘이 들어 있는 데모 단추입니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:119
|
||||
msgid "This is a demo button with a 'quit' icon"
|
||||
msgstr "'끝내기' 아이콘이 들어 있는 데모 단추입니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:248
|
||||
msgid "This is a sample message in a sample dialog"
|
||||
msgstr "예제 대화 상자의 예제 메시지입니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:328
|
||||
#, c-format
|
||||
msgid "Fake menu item %d\n"
|
||||
msgstr "가짜 메뉴 항목 %d\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:363
|
||||
msgid "Border-only window"
|
||||
msgstr "테두리만 있는 창"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:365
|
||||
msgid "Bar"
|
||||
msgstr "모음"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:382
|
||||
msgid "Normal Application Window"
|
||||
msgstr "보통 프로그램 창"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:386
|
||||
msgid "Dialog Box"
|
||||
msgstr "대화 상자"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:390
|
||||
msgid "Modal Dialog Box"
|
||||
msgstr "모달 대화 상자"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:394
|
||||
msgid "Utility Palette"
|
||||
msgstr "도구 팔레트"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:398
|
||||
msgid "Torn-off Menu"
|
||||
msgstr "떼어내기 메뉴"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:402
|
||||
msgid "Border"
|
||||
msgstr "테두리"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:406
|
||||
msgid "Attached Modal Dialog"
|
||||
msgstr "부착한 모달 대화 상자"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:737
|
||||
#, c-format
|
||||
msgid "Button layout test %d"
|
||||
msgstr "단추 배치 테스트 %d"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:766
|
||||
#, c-format
|
||||
msgid "%g milliseconds to draw one window frame"
|
||||
msgstr "창 프레임 하나를 그리는 데 %g ms"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:811
|
||||
#, c-format
|
||||
msgid "Usage: metacity-theme-viewer [THEMENAME]\n"
|
||||
msgstr "사용법: metacity-theme-viewer [테마이름]\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:818
|
||||
#, c-format
|
||||
msgid "Error loading theme: %s\n"
|
||||
msgstr "테마를 읽어들이는 데 오류가 발생했습니다: %s\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:824
|
||||
#, c-format
|
||||
msgid "Loaded theme \"%s\" in %g seconds\n"
|
||||
msgstr "\"%s\" 테마를 읽어들이는 데 %g초\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:869
|
||||
msgid "Normal Title Font"
|
||||
msgstr "보통 제목 글꼴"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:875
|
||||
msgid "Small Title Font"
|
||||
msgstr "작은 제목 글꼴"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:881
|
||||
msgid "Large Title Font"
|
||||
msgstr "큰 제목 글꼴"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:886
|
||||
msgid "Button Layouts"
|
||||
msgstr "단추 배치"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:891
|
||||
msgid "Benchmark"
|
||||
msgstr "벤치마크"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:947
|
||||
msgid "Window Title Goes Here"
|
||||
msgstr "창 제목이 여기에 들어갑니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1053
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Drew %d frames in %g client-side seconds (%g milliseconds per frame) and %g "
|
||||
"seconds wall clock time including X server resources (%g milliseconds per "
|
||||
"frame)\n"
|
||||
msgstr ""
|
||||
"%d개 프레임을 그리는 데 클라이언트 입장에서 %g초가 걸렸습니다(한 프레임에 %g "
|
||||
"ms). 그리고 X 서버 리소스까지 포함해 실제 시간으로 %g 초가 걸렸습니다(한 프레"
|
||||
"임에 %g ms).\n"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1273
|
||||
msgid "position expression test returned TRUE but set error"
|
||||
msgstr "위치 표현식 테스트가 참을 리턴했지만 오류가 발생했습니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1275
|
||||
msgid "position expression test returned FALSE but didn't set error"
|
||||
msgstr "위치 표현식 테스트가 거짓을 리턴했지만 오류가 발생하지 않았습니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1279
|
||||
msgid "Error was expected but none given"
|
||||
msgstr "오류가 발생해야 하지만 발생하지 않았습니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1281
|
||||
#, c-format
|
||||
msgid "Error %d was expected but %d given"
|
||||
msgstr "오류 %d번이 발생해야 하지만 오류 %d번이 발생했습니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1287
|
||||
#, c-format
|
||||
msgid "Error not expected but one was returned: %s"
|
||||
msgstr "오류가 발생하면 안 되지만 오류 한 개가 발생했습니다: %s"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1291
|
||||
#, c-format
|
||||
msgid "x value was %d, %d was expected"
|
||||
msgstr "가로값이 %d입니다. 와야 하는 값은 %d입니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1294
|
||||
#, c-format
|
||||
msgid "y value was %d, %d was expected"
|
||||
msgstr "세로값이 %d입니다. 와야 하는 값은 %d입니다"
|
||||
|
||||
#: ../src/ui/theme-viewer.c:1359
|
||||
#, c-format
|
||||
msgid "%d coordinate expressions parsed in %g seconds (%g seconds average)\n"
|
||||
msgstr "좌표 표현식 %d개를 %g초에 파싱했습니다(평균 %g초)\n"
|
||||
|
||||
18
po/sr.po
18
po/sr.po
@@ -10,8 +10,8 @@ msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter"
|
||||
"&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-08-18 20:03+0000\n"
|
||||
"PO-Revision-Date: 2013-09-06 09:19+0200\n"
|
||||
"POT-Creation-Date: 2013-03-01 15:50+0000\n"
|
||||
"PO-Revision-Date: 2013-03-11 11:40+0200\n"
|
||||
"Last-Translator: Мирослав Николић <miroslavnikolic@rocketmail.com>\n"
|
||||
"Language-Team: Serbian <gnom@prevod.org>\n"
|
||||
"Language: sr\n"
|
||||
@@ -320,20 +320,6 @@ msgstr ""
|
||||
"Не могу да пронађем тему! Проверите да „%s“ постоји и да садржи уобичајене "
|
||||
"теме.\n"
|
||||
|
||||
#: ../src/core/monitor.c:711
|
||||
msgid "Built-in display"
|
||||
msgstr "Уграђени дисплеј"
|
||||
|
||||
#. TRANSLATORS: this is a monitor name (in case we don't know
|
||||
#. the vendor), it's Unknown followed by a size in inches,
|
||||
#. like 'Unknown 15"'
|
||||
#.
|
||||
#: ../src/core/monitor.c:739
|
||||
#, c-format
|
||||
#| msgid "Unknown element %s"
|
||||
msgid "Unknown %s"
|
||||
msgstr "Непознат %s"
|
||||
|
||||
#: ../src/core/mutter.c:40
|
||||
#, c-format
|
||||
msgid ""
|
||||
|
||||
@@ -10,8 +10,8 @@ msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=mutter"
|
||||
"&keywords=I18N+L10N&component=general\n"
|
||||
"POT-Creation-Date: 2013-08-18 20:03+0000\n"
|
||||
"PO-Revision-Date: 2013-09-06 09:19+0200\n"
|
||||
"POT-Creation-Date: 2013-03-01 15:50+0000\n"
|
||||
"PO-Revision-Date: 2013-03-11 11:40+0200\n"
|
||||
"Last-Translator: Miroslav Nikolić <miroslavnikolic@rocketmail.com>\n"
|
||||
"Language-Team: Serbian <gnom@prevod.org>\n"
|
||||
"Language: sr\n"
|
||||
@@ -320,20 +320,6 @@ msgstr ""
|
||||
"Ne mogu da pronađem temu! Proverite da „%s“ postoji i da sadrži uobičajene "
|
||||
"teme.\n"
|
||||
|
||||
#: ../src/core/monitor.c:711
|
||||
msgid "Built-in display"
|
||||
msgstr "Ugrađeni displej"
|
||||
|
||||
#. TRANSLATORS: this is a monitor name (in case we don't know
|
||||
#. the vendor), it's Unknown followed by a size in inches,
|
||||
#. like 'Unknown 15"'
|
||||
#.
|
||||
#: ../src/core/monitor.c:739
|
||||
#, c-format
|
||||
#| msgid "Unknown element %s"
|
||||
msgid "Unknown %s"
|
||||
msgstr "Nepoznat %s"
|
||||
|
||||
#: ../src/core/mutter.c:40
|
||||
#, c-format
|
||||
msgid ""
|
||||
|
||||
648
po/zh_HK.po
648
po/zh_HK.po
File diff suppressed because it is too large
Load Diff
648
po/zh_TW.po
648
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -1,30 +0,0 @@
|
||||
<protocol name="gtk">
|
||||
|
||||
<interface name="gtk_shell" version="1">
|
||||
<enum name="capability">
|
||||
<entry name="global_app_menu" value="1"/>
|
||||
<entry name="global_menu_bar" value="2"/>
|
||||
</enum>
|
||||
|
||||
<event name="capabilities">
|
||||
<arg name="capabilities" type="uint"/>
|
||||
</event>
|
||||
|
||||
<request name="get_gtk_surface">
|
||||
<arg name="gtk_surface" type="new_id" interface="gtk_surface"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<interface name="gtk_surface" version="1">
|
||||
<request name="set_dbus_properties">
|
||||
<arg name="application_id" type="string" allow-null="true"/>
|
||||
<arg name="app_menu_path" type="string" allow-null="true"/>
|
||||
<arg name="menubar_path" type="string" allow-null="true"/>
|
||||
<arg name="window_object_path" type="string" allow-null="true"/>
|
||||
<arg name="application_object_path" type="string" allow-null="true"/>
|
||||
<arg name="unique_bus_name" type="string" allow-null="true"/>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
</protocol>
|
||||
@@ -40,9 +40,6 @@ mutter_built_sources = \
|
||||
$(dbus_xrandr_built_sources) \
|
||||
mutter-enum-types.h \
|
||||
mutter-enum-types.c \
|
||||
wayland/gtk-shell-protocol.c \
|
||||
wayland/gtk-shell-server-protocol.h \
|
||||
wayland/gtk-shell-client-protocol.h \
|
||||
wayland/xserver-protocol.c \
|
||||
wayland/xserver-server-protocol.h \
|
||||
wayland/xserver-client-protocol.h
|
||||
@@ -134,7 +131,6 @@ libmutter_wayland_la_SOURCES = \
|
||||
core/meta-xrandr-shared.h \
|
||||
core/monitor.c \
|
||||
core/monitor-config.c \
|
||||
core/monitor-kms.c \
|
||||
core/monitor-private.h \
|
||||
core/monitor-xrandr.c \
|
||||
core/mutter-Xatomtype.h \
|
||||
@@ -154,7 +150,6 @@ libmutter_wayland_la_SOURCES = \
|
||||
core/stack-tracker.h \
|
||||
core/util.c \
|
||||
meta/util.h \
|
||||
core/util-private.h \
|
||||
core/window-props.c \
|
||||
core/window-props.h \
|
||||
core/window.c \
|
||||
@@ -200,13 +195,7 @@ libmutter_wayland_la_SOURCES += \
|
||||
wayland/meta-wayland-seat.c \
|
||||
wayland/meta-wayland-seat.h \
|
||||
wayland/meta-wayland-stage.h \
|
||||
wayland/meta-wayland-stage.c \
|
||||
wayland/meta-wayland-surface.c \
|
||||
wayland/meta-wayland-surface.h \
|
||||
wayland/meta-wayland-types.h \
|
||||
wayland/meta-wayland-versions.h \
|
||||
wayland/meta-weston-launch.c \
|
||||
wayland/meta-weston-launch.h
|
||||
wayland/meta-wayland-stage.c
|
||||
|
||||
libmutter_wayland_la_LDFLAGS = -no-undefined
|
||||
libmutter_wayland_la_LIBADD = $(MUTTER_LIBS)
|
||||
@@ -258,17 +247,6 @@ bin_PROGRAMS=mutter-wayland
|
||||
mutter_wayland_SOURCES = core/mutter.c
|
||||
mutter_wayland_LDADD = $(MUTTER_LIBS) libmutter-wayland.la
|
||||
|
||||
bin_PROGRAMS+=mutter-launch
|
||||
|
||||
mutter_launch_SOURCES = wayland/weston-launch.c wayland/weston-launch.h
|
||||
|
||||
mutter_launch_CFLAGS = $(MUTTER_LAUNCH_CFLAGS) -DLIBDIR=\"$(libdir)\"
|
||||
mutter_launch_LDFLAGS = $(MUTTER_LAUNCH_LIBS) -lpam
|
||||
|
||||
install-exec-hook:
|
||||
-chown root $(DESTDIR)$(bindir)/mutter-launch
|
||||
-chmod u+s $(DESTDIR)$(bindir)/mutter-launch
|
||||
|
||||
if HAVE_INTROSPECTION
|
||||
include $(INTROSPECTION_MAKEFILE)
|
||||
|
||||
@@ -328,7 +306,7 @@ xml_DATA = $(xml_in_files:.xml.in=.xml)
|
||||
|
||||
dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
|
||||
|
||||
gsettings_SCHEMAS = org.gnome.mutter.gschema.xml org.gnome.mutter.wayland.gschema.xml
|
||||
gsettings_SCHEMAS = org.gnome.mutter.gschema.xml
|
||||
@INTLTOOL_XML_NOMERGE_RULE@
|
||||
@GSETTINGS_RULES@
|
||||
|
||||
@@ -339,7 +317,6 @@ CLEANFILES = \
|
||||
mutter-wayland.desktop \
|
||||
mutter-wm.desktop \
|
||||
org.gnome.mutter.gschema.xml \
|
||||
org.gnome.mutter.wayland.gschema.xml \
|
||||
$(xml_DATA) \
|
||||
$(mutter_built_sources) \
|
||||
$(typelib_DATA) \
|
||||
@@ -356,12 +333,10 @@ EXTRA_DIST=$(desktopfiles_files) \
|
||||
$(wmproperties_in_files) \
|
||||
$(xml_in_files) \
|
||||
org.gnome.mutter.gschema.xml.in \
|
||||
org.gnome.mutter.wayland.gschema.xml.in \
|
||||
mutter-schemas.convert \
|
||||
libmutter-wayland.pc.in \
|
||||
mutter-enum-types.h.in \
|
||||
mutter-enum-types.c.in \
|
||||
xrandr.xml idle-monitor.xml
|
||||
mutter-enum-types.c.in
|
||||
|
||||
BUILT_SOURCES = $(mutter_built_sources)
|
||||
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
|
||||
|
||||
@@ -50,7 +50,7 @@ meta_create_color_texture_4ub (guint8 red,
|
||||
CoglColor color;
|
||||
guint8 pixel[4];
|
||||
|
||||
cogl_color_init_from_4ub (&color, red, green, blue, alpha);
|
||||
cogl_color_set_from_4ub (&color, red, green, blue, alpha);
|
||||
cogl_color_premultiply (&color);
|
||||
|
||||
pixel[0] = cogl_color_get_red_byte (&color);
|
||||
@@ -73,8 +73,10 @@ meta_create_color_texture_4ub (guint8 red,
|
||||
* @src_texture: (allow-none): texture to use initially for the layer
|
||||
*
|
||||
* Creates a pipeline with a single layer. Using a common template
|
||||
* makes it easier for Cogl to share a shader for different uses in
|
||||
* Mutter.
|
||||
* allows sharing a shader for different uses in Mutter. To share the same
|
||||
* shader with all other pipelines that are just texture plus opacity
|
||||
* would require Cogl fixes.
|
||||
* (See http://bugzilla.clutter-project.org/show_bug.cgi?id=2425)
|
||||
*
|
||||
* Return value: (transfer full): a newly created #CoglPipeline
|
||||
*/
|
||||
@@ -84,21 +86,22 @@ meta_create_texture_pipeline (CoglTexture *src_texture)
|
||||
static CoglPipeline *texture_pipeline_template = NULL;
|
||||
CoglPipeline *pipeline;
|
||||
|
||||
/* The only state used in the pipeline that would affect the shader
|
||||
generation is the texture type on the layer. Therefore we create
|
||||
a template pipeline which sets this state and all texture
|
||||
pipelines are created as a copy of this. That way Cogl can find
|
||||
the shader state for the pipeline more quickly by looking at the
|
||||
pipeline ancestry instead of resorting to the shader cache. */
|
||||
/* We use a pipeline that has a dummy texture as a base for all
|
||||
texture pipelines. The idea is that only the Cogl texture object
|
||||
would be different in the children so it is likely that Cogl will
|
||||
be able to share GL programs between all the textures. */
|
||||
if (G_UNLIKELY (texture_pipeline_template == NULL))
|
||||
{
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
CoglTexture *dummy_texture;
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
|
||||
dummy_texture = meta_create_color_texture_4ub (0xff, 0xff, 0xff, 0xff,
|
||||
COGL_TEXTURE_NONE);
|
||||
|
||||
|
||||
texture_pipeline_template = cogl_pipeline_new (ctx);
|
||||
cogl_pipeline_set_layer_null_texture (texture_pipeline_template,
|
||||
0, /* layer */
|
||||
COGL_TEXTURE_TYPE_2D);
|
||||
cogl_pipeline_set_layer_texture (texture_pipeline_template, 0, dummy_texture);
|
||||
cogl_object_unref (dummy_texture);
|
||||
}
|
||||
|
||||
pipeline = cogl_pipeline_copy (texture_pipeline_template);
|
||||
|
||||
@@ -84,10 +84,7 @@
|
||||
#include "meta-window-group.h"
|
||||
#include "window-private.h" /* to check window->hidden */
|
||||
#include "display-private.h" /* for meta_display_lookup_x_window() */
|
||||
#include "util-private.h"
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-keyboard.h"
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
@@ -427,20 +424,34 @@ meta_stage_is_focused (MetaScreen *screen)
|
||||
return (screen->display->focus_type == META_FOCUS_STAGE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
begin_modal_x11 (MetaScreen *screen,
|
||||
MetaPlugin *plugin,
|
||||
MetaModalOptions options,
|
||||
guint32 timestamp)
|
||||
gboolean
|
||||
meta_begin_modal_for_plugin (MetaScreen *screen,
|
||||
MetaPlugin *plugin,
|
||||
MetaModalOptions options,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (screen);
|
||||
Window grab_window = clutter_x11_get_stage_window (CLUTTER_STAGE (info->stage));
|
||||
Cursor cursor = None;
|
||||
int result;
|
||||
gboolean pointer_grabbed = FALSE;
|
||||
gboolean keyboard_grabbed = FALSE;
|
||||
/* To some extent this duplicates code in meta_display_begin_grab_op(), but there
|
||||
* are significant differences in how we handle grabs that make it difficult to
|
||||
* merge the two.
|
||||
*/
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdpy = meta_display_get_xdisplay (display);
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
ClutterStage *stage;
|
||||
Window grab_window;
|
||||
Cursor cursor = None;
|
||||
gboolean pointer_grabbed = FALSE;
|
||||
gboolean keyboard_grabbed = FALSE;
|
||||
int result;
|
||||
|
||||
stage = CLUTTER_STAGE (meta_get_stage_for_screen (screen));
|
||||
if (!stage)
|
||||
return FALSE;
|
||||
|
||||
grab_window = clutter_x11_get_stage_window (stage);
|
||||
|
||||
if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE)
|
||||
return FALSE;
|
||||
|
||||
if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0)
|
||||
{
|
||||
@@ -490,80 +501,6 @@ begin_modal_x11 (MetaScreen *screen,
|
||||
keyboard_grabbed = TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
if (pointer_grabbed)
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
|
||||
if (keyboard_grabbed)
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
begin_modal_wayland (MetaScreen *screen,
|
||||
MetaPlugin *plugin,
|
||||
MetaModalOptions options,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
gboolean pointer_grabbed = FALSE;
|
||||
gboolean keyboard_grabbed = FALSE;
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
if ((options & META_MODAL_POINTER_ALREADY_GRABBED) == 0)
|
||||
{
|
||||
if (!meta_wayland_pointer_begin_modal (&compositor->seat->pointer))
|
||||
goto fail;
|
||||
|
||||
pointer_grabbed = TRUE;
|
||||
}
|
||||
if ((options & META_MODAL_KEYBOARD_ALREADY_GRABBED) == 0)
|
||||
{
|
||||
if (!meta_wayland_keyboard_begin_modal (&compositor->seat->keyboard,
|
||||
timestamp))
|
||||
goto fail;
|
||||
|
||||
keyboard_grabbed = TRUE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
if (pointer_grabbed)
|
||||
meta_wayland_pointer_end_modal (&compositor->seat->pointer);
|
||||
if (keyboard_grabbed)
|
||||
meta_wayland_keyboard_end_modal (&compositor->seat->keyboard, timestamp);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_begin_modal_for_plugin (MetaScreen *screen,
|
||||
MetaPlugin *plugin,
|
||||
MetaModalOptions options,
|
||||
guint32 timestamp)
|
||||
{
|
||||
/* To some extent this duplicates code in meta_display_begin_grab_op(), but there
|
||||
* are significant differences in how we handle grabs that make it difficult to
|
||||
* merge the two.
|
||||
*/
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
gboolean ok;
|
||||
|
||||
if (compositor->modal_plugin != NULL || display->grab_op != META_GRAB_OP_NONE)
|
||||
return FALSE;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
ok = begin_modal_wayland (screen, plugin, options, timestamp);
|
||||
else
|
||||
ok = begin_modal_x11 (screen, plugin, options, timestamp);
|
||||
if (!ok)
|
||||
return FALSE;
|
||||
|
||||
display->grab_op = META_GRAB_OP_COMPOSITOR;
|
||||
display->grab_window = NULL;
|
||||
display->grab_screen = screen;
|
||||
@@ -573,6 +510,14 @@ meta_begin_modal_for_plugin (MetaScreen *screen,
|
||||
compositor->modal_plugin = plugin;
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
if (pointer_grabbed)
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
|
||||
if (keyboard_grabbed)
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -586,19 +531,8 @@ meta_end_modal_for_plugin (MetaScreen *screen,
|
||||
|
||||
g_return_if_fail (compositor->modal_plugin == plugin);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
meta_wayland_pointer_end_modal (&compositor->seat->pointer);
|
||||
meta_wayland_keyboard_end_modal (&compositor->seat->keyboard,
|
||||
timestamp);
|
||||
}
|
||||
else
|
||||
{
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
|
||||
}
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_POINTER_ID, timestamp);
|
||||
XIUngrabDevice (xdpy, META_VIRTUAL_CORE_KEYBOARD_ID, timestamp);
|
||||
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->grab_window = NULL;
|
||||
@@ -695,7 +629,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
MetaCompScreen *info;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
Window xwin = None;
|
||||
Window xwin;
|
||||
gint width, height;
|
||||
MetaWaylandCompositor *wayland_compositor;
|
||||
|
||||
@@ -1067,7 +1001,10 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
{
|
||||
if (compositor->modal_plugin && is_grabbed_event (compositor->display, event))
|
||||
{
|
||||
_meta_plugin_xevent_filter (compositor->modal_plugin, event);
|
||||
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (compositor->modal_plugin);
|
||||
|
||||
if (klass->xevent_filter)
|
||||
klass->xevent_filter (compositor->modal_plugin, event);
|
||||
|
||||
/* We always consume events even if the plugin says it didn't handle them;
|
||||
* exclusive is exclusive */
|
||||
@@ -1273,7 +1210,6 @@ sync_actor_stacking (MetaCompScreen *info)
|
||||
* we go ahead and do it */
|
||||
|
||||
children = clutter_actor_get_children (info->window_group);
|
||||
has_windows = FALSE;
|
||||
reordered = FALSE;
|
||||
|
||||
/* We allow for actors in the window group other than the actors we
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#include <meta/screen.h>
|
||||
#include <meta/meta-background-actor.h>
|
||||
|
||||
void meta_background_actor_set_clip_region (MetaBackgroundActor *self,
|
||||
cairo_region_t *clip_region);
|
||||
void meta_background_actor_set_visible_region (MetaBackgroundActor *self,
|
||||
cairo_region_t *visible_region);
|
||||
|
||||
cairo_region_t *meta_background_actor_get_clip_region (MetaBackgroundActor *self);
|
||||
cairo_region_t *meta_background_actor_get_visible_region (MetaBackgroundActor *self);
|
||||
|
||||
#endif /* META_BACKGROUND_ACTOR_PRIVATE_H */
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
struct _MetaBackgroundActorPrivate
|
||||
{
|
||||
cairo_region_t *clip_region;
|
||||
cairo_region_t *visible_region;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
|
||||
@@ -54,7 +54,7 @@ meta_background_actor_dispose (GObject *object)
|
||||
{
|
||||
MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
|
||||
|
||||
meta_background_actor_set_clip_region (self, NULL);
|
||||
meta_background_actor_set_visible_region (self, NULL);
|
||||
|
||||
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
|
||||
}
|
||||
@@ -167,17 +167,17 @@ meta_background_actor_new (void)
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_background_actor_set_clip_region:
|
||||
* meta_background_actor_set_visible_region:
|
||||
* @self: a #MetaBackgroundActor
|
||||
* @clip_region: (allow-none): the area of the actor (in allocate-relative
|
||||
* @visible_region: (allow-none): the area of the actor (in allocate-relative
|
||||
* coordinates) that is visible.
|
||||
*
|
||||
* Sets the area of the background that is unobscured by overlapping windows.
|
||||
* This is used to optimize and only paint the visible portions.
|
||||
*/
|
||||
void
|
||||
meta_background_actor_set_clip_region (MetaBackgroundActor *self,
|
||||
cairo_region_t *clip_region)
|
||||
meta_background_actor_set_visible_region (MetaBackgroundActor *self,
|
||||
cairo_region_t *visible_region)
|
||||
{
|
||||
MetaBackgroundActorPrivate *priv;
|
||||
|
||||
@@ -185,16 +185,16 @@ meta_background_actor_set_clip_region (MetaBackgroundActor *self,
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
g_clear_pointer (&priv->clip_region,
|
||||
g_clear_pointer (&priv->visible_region,
|
||||
(GDestroyNotify)
|
||||
cairo_region_destroy);
|
||||
|
||||
if (clip_region)
|
||||
priv->clip_region = cairo_region_copy (clip_region);
|
||||
if (visible_region)
|
||||
priv->visible_region = cairo_region_copy (visible_region);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_background_actor_get_clip_region:
|
||||
* meta_background_actor_get_visible_region:
|
||||
* @self: a #MetaBackgroundActor
|
||||
*
|
||||
* Return value (transfer full): a #cairo_region_t that represents the part of
|
||||
@@ -202,16 +202,16 @@ meta_background_actor_set_clip_region (MetaBackgroundActor *self,
|
||||
* #MetaWindowActor objects.
|
||||
*/
|
||||
cairo_region_t *
|
||||
meta_background_actor_get_clip_region (MetaBackgroundActor *self)
|
||||
meta_background_actor_get_visible_region (MetaBackgroundActor *self)
|
||||
{
|
||||
MetaBackgroundActorPrivate *priv = self->priv;
|
||||
ClutterActorBox content_box;
|
||||
cairo_rectangle_int_t content_area = { 0 };
|
||||
cairo_region_t *clip_region;
|
||||
cairo_region_t *visible_region;
|
||||
|
||||
g_return_val_if_fail (META_IS_BACKGROUND_ACTOR (self), NULL);
|
||||
|
||||
if (!priv->clip_region)
|
||||
if (!priv->visible_region)
|
||||
return NULL;
|
||||
|
||||
clutter_actor_get_content_box (CLUTTER_ACTOR (self), &content_box);
|
||||
@@ -221,8 +221,8 @@ meta_background_actor_get_clip_region (MetaBackgroundActor *self)
|
||||
content_area.width = content_box.x2 - content_box.x1;
|
||||
content_area.height = content_box.y2 - content_box.y1;
|
||||
|
||||
clip_region = cairo_region_create_rectangle (&content_area);
|
||||
cairo_region_intersect (clip_region, priv->clip_region);
|
||||
visible_region = cairo_region_create_rectangle (&content_area);
|
||||
cairo_region_intersect (visible_region, priv->visible_region);
|
||||
|
||||
return clip_region;
|
||||
return visible_region;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
#include <meta/screen.h>
|
||||
#include <meta/meta-background-group.h>
|
||||
|
||||
void meta_background_group_set_clip_region (MetaBackgroundGroup *self,
|
||||
cairo_region_t *visible_region);
|
||||
void meta_background_group_set_visible_region (MetaBackgroundGroup *self,
|
||||
cairo_region_t *visible_region);
|
||||
#endif /* META_BACKGROUND_GROUP_PRIVATE_H */
|
||||
|
||||
@@ -62,16 +62,16 @@ meta_background_group_init (MetaBackgroundGroup *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_background_group_set_clip_region:
|
||||
* meta_background_group_set_visible_region:
|
||||
* @self: a #MetaBackgroundGroup
|
||||
* @region: (allow-none): the parts of the background to paint
|
||||
* @visible_region: (allow-none): the parts of the background to paint
|
||||
*
|
||||
* Sets the area of the backgrounds that is unobscured by overlapping windows.
|
||||
* This is used to optimize and only paint the visible portions.
|
||||
*/
|
||||
void
|
||||
meta_background_group_set_clip_region (MetaBackgroundGroup *self,
|
||||
cairo_region_t *region)
|
||||
meta_background_group_set_visible_region (MetaBackgroundGroup *self,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
GList *children, *l;
|
||||
|
||||
@@ -82,7 +82,7 @@ meta_background_group_set_clip_region (MetaBackgroundGroup *self,
|
||||
|
||||
if (META_IS_BACKGROUND_ACTOR (actor))
|
||||
{
|
||||
meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (actor), region);
|
||||
meta_background_actor_set_visible_region (META_BACKGROUND_ACTOR (actor), region);
|
||||
}
|
||||
else if (META_IS_BACKGROUND_GROUP (actor))
|
||||
{
|
||||
@@ -92,7 +92,7 @@ meta_background_group_set_clip_region (MetaBackgroundGroup *self,
|
||||
continue;
|
||||
|
||||
cairo_region_translate (region, -x, -y);
|
||||
meta_background_group_set_clip_region (META_BACKGROUND_GROUP (actor), region);
|
||||
meta_background_group_set_visible_region (META_BACKGROUND_GROUP (actor), region);
|
||||
cairo_region_translate (region, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include "mutter-enum-types.h"
|
||||
#include <meta/errors.h>
|
||||
#include <meta/meta-background.h>
|
||||
#include "util-private.h"
|
||||
#include "meta-background-actor-private.h"
|
||||
|
||||
#define FRAGMENT_SHADER_DECLARATIONS \
|
||||
@@ -413,13 +412,13 @@ meta_background_paint_content (ClutterContent *content,
|
||||
*/
|
||||
if (META_IS_BACKGROUND_ACTOR (actor))
|
||||
{
|
||||
cairo_region_t *clip_region;
|
||||
clip_region = meta_background_actor_get_clip_region (META_BACKGROUND_ACTOR (actor));
|
||||
cairo_region_t *visible_region;
|
||||
visible_region = meta_background_actor_get_visible_region (META_BACKGROUND_ACTOR (actor));
|
||||
|
||||
if (clip_region != NULL)
|
||||
if (visible_region != NULL)
|
||||
{
|
||||
cairo_region_intersect (paintable_region, clip_region);
|
||||
cairo_region_destroy (clip_region);
|
||||
cairo_region_intersect (paintable_region, visible_region);
|
||||
cairo_region_destroy (visible_region);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +192,10 @@ meta_module_class_init (MetaModuleClass *klass)
|
||||
static void
|
||||
meta_module_init (MetaModule *self)
|
||||
{
|
||||
self->priv = META_MODULE_GET_PRIVATE (self);
|
||||
MetaModulePrivate *priv;
|
||||
|
||||
self->priv = priv = META_MODULE_GET_PRIVATE (self);
|
||||
|
||||
}
|
||||
|
||||
GType
|
||||
|
||||
@@ -306,13 +306,41 @@ meta_plugin_manager_filter_keybinding (MetaPluginManager *plugin_mgr,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The public method that the compositor hooks into for desktop switching.
|
||||
*
|
||||
* Returns TRUE if the plugin handled the event type (i.e.,
|
||||
* if the return value is FALSE, there will be no subsequent call to the
|
||||
* manager completed() callback, and the compositor must ensure that any
|
||||
* appropriate post-effect cleanup is carried out.
|
||||
*/
|
||||
gboolean
|
||||
meta_plugin_manager_xevent_filter (MetaPluginManager *plugin_mgr,
|
||||
XEvent *xev)
|
||||
{
|
||||
MetaPlugin *plugin = plugin_mgr->plugin;
|
||||
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
return _meta_plugin_xevent_filter (plugin, xev);
|
||||
/* We need to make sure that clutter gets certain events, like
|
||||
* ConfigureNotify on the stage window. If there is a plugin that
|
||||
* provides an xevent_filter function, then it's the responsibility
|
||||
* of that plugin to pass events to Clutter. Otherwise, we send the
|
||||
* event directly to Clutter ourselves.
|
||||
*/
|
||||
if (klass->xevent_filter)
|
||||
return klass->xevent_filter (plugin, xev);
|
||||
|
||||
/* When mutter is running as a wayland compositor, things like input
|
||||
* events just come directly from clutter so it won't have disabled
|
||||
* clutter's event retrieval and won't need to forward it events (if
|
||||
* it did it would lead to recursion). Also when running as a
|
||||
* wayland compositor we shouldn't be assuming that we're running
|
||||
* with the clutter x11 backend.
|
||||
*/
|
||||
if (meta_is_wayland_compositor ())
|
||||
return FALSE;
|
||||
|
||||
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -72,8 +72,6 @@ gboolean meta_plugin_manager_filter_keybinding (MetaPluginManager *mgr,
|
||||
|
||||
gboolean meta_plugin_manager_xevent_filter (MetaPluginManager *mgr,
|
||||
XEvent *xev);
|
||||
gboolean _meta_plugin_xevent_filter (MetaPlugin *plugin,
|
||||
XEvent *xev);
|
||||
|
||||
void meta_plugin_manager_confirm_display_change (MetaPluginManager *mgr);
|
||||
|
||||
|
||||
@@ -138,7 +138,9 @@ meta_plugin_class_init (MetaPluginClass *klass)
|
||||
static void
|
||||
meta_plugin_init (MetaPlugin *self)
|
||||
{
|
||||
self->priv = META_PLUGIN_GET_PRIVATE (self);
|
||||
MetaPluginPrivate *priv;
|
||||
|
||||
self->priv = priv = META_PLUGIN_GET_PRIVATE (self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -183,28 +185,6 @@ _meta_plugin_effect_started (MetaPlugin *plugin)
|
||||
priv->running++;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_meta_plugin_xevent_filter (MetaPlugin *plugin,
|
||||
XEvent *xev)
|
||||
{
|
||||
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
|
||||
|
||||
/* When mutter is running as a wayland compositor, things like input
|
||||
* events just come directly from clutter so it won't have disabled
|
||||
* clutter's event retrieval and won't need to forward it events (if
|
||||
* it did it would lead to recursion). Also when running as a
|
||||
* wayland compositor we shouldn't be assuming that we're running
|
||||
* with the clutter x11 backend.
|
||||
*/
|
||||
|
||||
if (klass->xevent_filter && klass->xevent_filter (plugin, xev))
|
||||
return TRUE;
|
||||
else if (!meta_is_wayland_compositor ())
|
||||
return clutter_x11_handle_event (xev) != CLUTTER_X11_FILTER_CONTINUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_switch_workspace_completed (MetaPlugin *plugin)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
|
||||
#include <meta/meta-shaped-texture.h>
|
||||
#include <meta/util.h>
|
||||
#include "clutter-utils.h"
|
||||
#include "meta-texture-tower.h"
|
||||
|
||||
#include "meta-shaped-texture-private.h"
|
||||
@@ -146,7 +145,6 @@ meta_shaped_texture_dispose (GObject *object)
|
||||
priv->paint_tower = NULL;
|
||||
|
||||
g_clear_pointer (&priv->texture, cogl_object_unref);
|
||||
g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
|
||||
|
||||
meta_shaped_texture_set_mask_texture (self, NULL);
|
||||
meta_shaped_texture_set_clip_region (self, NULL);
|
||||
@@ -238,7 +236,7 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
if (priv->texture)
|
||||
cogl_object_unref (priv->texture);
|
||||
|
||||
priv->texture = cogl_object_ref (cogl_tex);
|
||||
priv->texture = cogl_tex;
|
||||
|
||||
if (cogl_tex != NULL)
|
||||
{
|
||||
@@ -281,7 +279,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
CoglTexture *paint_tex;
|
||||
ClutterActorBox alloc;
|
||||
cairo_region_t *blended_region = NULL;
|
||||
CoglPipelineFilter filter;
|
||||
|
||||
if (priv->clip_region && cairo_region_is_empty (priv->clip_region))
|
||||
return;
|
||||
@@ -318,22 +315,6 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
if (tex_width == 0 || tex_height == 0) /* no contents yet */
|
||||
return;
|
||||
|
||||
/* Use nearest-pixel interpolation if the texture is unscaled. This
|
||||
* improves performance, especially with software rendering.
|
||||
*/
|
||||
|
||||
filter = COGL_PIPELINE_FILTER_LINEAR;
|
||||
|
||||
if (!clutter_actor_is_in_clone_paint (actor))
|
||||
{
|
||||
int x_origin, y_origin;
|
||||
|
||||
if (meta_actor_is_untransformed (actor,
|
||||
&x_origin,
|
||||
&y_origin))
|
||||
filter = COGL_PIPELINE_FILTER_NEAREST;
|
||||
}
|
||||
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
fb = cogl_get_draw_framebuffer ();
|
||||
|
||||
@@ -347,22 +328,14 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
int n_rects;
|
||||
int i;
|
||||
|
||||
if (priv->clip_region != NULL)
|
||||
{
|
||||
region = cairo_region_copy (priv->clip_region);
|
||||
cairo_region_intersect (region, priv->opaque_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
region = cairo_region_reference (priv->opaque_region);
|
||||
}
|
||||
region = cairo_region_copy (priv->clip_region);
|
||||
cairo_region_intersect (region, priv->opaque_region);
|
||||
|
||||
if (cairo_region_is_empty (region))
|
||||
goto paint_blended;
|
||||
|
||||
opaque_pipeline = get_unblended_pipeline (ctx);
|
||||
cogl_pipeline_set_layer_texture (opaque_pipeline, 0, paint_tex);
|
||||
cogl_pipeline_set_layer_filters (opaque_pipeline, 0, filter, filter);
|
||||
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
for (i = 0; i < n_rects; i++)
|
||||
@@ -404,11 +377,9 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
{
|
||||
pipeline = get_masked_pipeline (ctx);
|
||||
cogl_pipeline_set_layer_texture (pipeline, 1, priv->mask_texture);
|
||||
cogl_pipeline_set_layer_filters (pipeline, 1, filter, filter);
|
||||
}
|
||||
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, paint_tex);
|
||||
cogl_pipeline_set_layer_filters (pipeline, 0, filter, filter);
|
||||
|
||||
{
|
||||
CoglColor color;
|
||||
@@ -424,7 +395,7 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
* fall back and draw the whole thing */
|
||||
# define MAX_RECTS 16
|
||||
|
||||
n_rects = cairo_region_num_rectangles (blended_region);
|
||||
n_rects = cairo_region_num_rectangles (priv->clip_region);
|
||||
if (n_rects <= MAX_RECTS)
|
||||
{
|
||||
int i;
|
||||
@@ -434,7 +405,7 @@ meta_shaped_texture_paint (ClutterActor *actor)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (blended_region, i, &rect);
|
||||
cairo_region_get_rectangle (priv->clip_region, i, &rect);
|
||||
|
||||
if (!gdk_rectangle_intersect (&tex_rect, &rect, &rect))
|
||||
continue;
|
||||
@@ -477,6 +448,7 @@ meta_shaped_texture_pick (ClutterActor *actor,
|
||||
int n_rects;
|
||||
float *rectangles;
|
||||
int i;
|
||||
ClutterActorBox alloc;
|
||||
CoglPipeline *pipeline;
|
||||
CoglContext *ctx;
|
||||
CoglFramebuffer *fb;
|
||||
@@ -712,19 +684,19 @@ wayland_surface_update_area (MetaShapedTexture *stex,
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_clip (MetaShapedTexture *stex,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
cairo_rectangle_int_t *clip)
|
||||
static void
|
||||
queue_damage_redraw_with_clip (MetaShapedTexture *stex,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
ClutterActor *self = CLUTTER_ACTOR (stex);
|
||||
MetaShapedTexturePrivate *priv;
|
||||
ClutterActorBox allocation;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
cairo_rectangle_int_t clip;
|
||||
|
||||
/* NB: clutter_actor_queue_redraw_with_clip expects a box in the actor's
|
||||
* coordinate space so we need to convert from surface coordinates to
|
||||
@@ -738,60 +710,41 @@ get_clip (MetaShapedTexture *stex,
|
||||
* it here.
|
||||
*/
|
||||
if (!clutter_actor_has_allocation (self))
|
||||
return FALSE;
|
||||
{
|
||||
clutter_actor_queue_redraw (self);
|
||||
return;
|
||||
}
|
||||
|
||||
priv = stex->priv;
|
||||
|
||||
if (priv->tex_width == 0 || priv->tex_height == 0)
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
clutter_actor_get_allocation_box (self, &allocation);
|
||||
|
||||
scale_x = (allocation.x2 - allocation.x1) / priv->tex_width;
|
||||
scale_y = (allocation.y2 - allocation.y1) / priv->tex_height;
|
||||
|
||||
clip->x = x * scale_x;
|
||||
clip->y = y * scale_y;
|
||||
clip->width = width * scale_x;
|
||||
clip->height = height * scale_y;
|
||||
|
||||
return TRUE;
|
||||
clip.x = x * scale_x;
|
||||
clip.y = y * scale_y;
|
||||
clip.width = width * scale_x;
|
||||
clip.height = height * scale_y;
|
||||
clutter_actor_queue_redraw_with_clip (self, &clip);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_shaped_texture_update_area:
|
||||
* @stex: #MetaShapedTexture
|
||||
* @x: the x coordinate of the damaged area
|
||||
* @y: the y coordinate of the damaged area
|
||||
* @width: the width of the damaged area
|
||||
* @height: the height of the damaged area
|
||||
* @unobscured_region: The unobscured region of the window or %NULL if
|
||||
* there is no valid one (like when the actor is transformed or
|
||||
* has a mapped clone)
|
||||
*
|
||||
* Repairs the damaged area indicated by @x, @y, @width and @height
|
||||
* and queues a redraw for the intersection @visibible_region and
|
||||
* the damage area. If @visibible_region is %NULL a redraw will always
|
||||
* get queued.
|
||||
*
|
||||
* Return value: Whether a redraw have been queued or not
|
||||
*/
|
||||
gboolean
|
||||
void
|
||||
meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
cairo_region_t *unobscured_region)
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv;
|
||||
cairo_rectangle_int_t clip;
|
||||
gboolean has_clip;
|
||||
|
||||
priv = stex->priv;
|
||||
|
||||
if (priv->texture == NULL)
|
||||
return FALSE;
|
||||
return;
|
||||
|
||||
switch (priv->type)
|
||||
{
|
||||
@@ -806,40 +759,7 @@ meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
|
||||
meta_texture_tower_update_area (priv->paint_tower, x, y, width, height);
|
||||
|
||||
has_clip = get_clip (stex, x, y, width, height, &clip);
|
||||
|
||||
if (unobscured_region)
|
||||
{
|
||||
cairo_region_t *intersection;
|
||||
|
||||
if (cairo_region_is_empty (unobscured_region))
|
||||
return FALSE;
|
||||
|
||||
intersection = cairo_region_copy (unobscured_region);
|
||||
if (has_clip)
|
||||
cairo_region_intersect_rectangle (intersection, &clip);
|
||||
|
||||
if (!cairo_region_is_empty (intersection))
|
||||
{
|
||||
cairo_rectangle_int_t damage_rect;
|
||||
cairo_region_get_extents (intersection, &damage_rect);
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &damage_rect);
|
||||
cairo_region_destroy (intersection);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cairo_region_destroy (intersection);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (has_clip)
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stex), &clip);
|
||||
else
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
||||
|
||||
return TRUE;
|
||||
queue_damage_redraw_with_clip (stex, x, y, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -896,7 +816,26 @@ meta_shaped_texture_attach_wayland_buffer (MetaShapedTexture *stex,
|
||||
g_return_if_fail (priv->wayland.surface->buffer_ref.buffer == buffer);
|
||||
|
||||
if (buffer)
|
||||
set_cogl_texture (stex, buffer->texture);
|
||||
{
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
CoglError *catch_error = NULL;
|
||||
CoglTexture *texture =
|
||||
COGL_TEXTURE (cogl_wayland_texture_2d_new_from_buffer (ctx,
|
||||
buffer->resource,
|
||||
&catch_error));
|
||||
if (!texture)
|
||||
{
|
||||
cogl_error_free (catch_error);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->width = cogl_texture_get_width (texture);
|
||||
buffer->height = cogl_texture_get_height (texture);
|
||||
}
|
||||
|
||||
set_cogl_texture (stex, texture);
|
||||
}
|
||||
else
|
||||
set_cogl_texture (stex, NULL);
|
||||
|
||||
@@ -956,8 +895,8 @@ meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
|
||||
/**
|
||||
* meta_shaped_texture_set_clip_region:
|
||||
* @stex: a #MetaShapedTexture
|
||||
* @clip_region: the region of the texture that is visible and
|
||||
* should be painted.
|
||||
* @clip_region: (transfer full): the region of the texture that
|
||||
* is visible and should be painted.
|
||||
*
|
||||
* Provides a hint to the texture about what areas of the texture
|
||||
* are not completely obscured and thus need to be painted. This
|
||||
@@ -978,7 +917,10 @@ meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
|
||||
priv = stex->priv;
|
||||
|
||||
if (priv->clip_region)
|
||||
cairo_region_destroy (priv->clip_region);
|
||||
{
|
||||
cairo_region_destroy (priv->clip_region);
|
||||
priv->clip_region = NULL;
|
||||
}
|
||||
|
||||
if (clip_region)
|
||||
priv->clip_region = cairo_region_copy (clip_region);
|
||||
|
||||
@@ -70,14 +70,11 @@ void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
||||
|
||||
cairo_region_t *meta_window_actor_get_obscured_region (MetaWindowActor *self);
|
||||
|
||||
void meta_window_actor_set_clip_region (MetaWindowActor *self,
|
||||
cairo_region_t *clip_region);
|
||||
void meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
|
||||
cairo_region_t *beneath_region);
|
||||
void meta_window_actor_reset_clip_regions (MetaWindowActor *self);
|
||||
|
||||
void meta_window_actor_set_unobscured_region (MetaWindowActor *self,
|
||||
cairo_region_t *unobscured_region);
|
||||
void meta_window_actor_set_visible_region (MetaWindowActor *self,
|
||||
cairo_region_t *visible_region);
|
||||
void meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
|
||||
cairo_region_t *beneath_region);
|
||||
void meta_window_actor_reset_visible_regions (MetaWindowActor *self);
|
||||
|
||||
void meta_window_actor_effect_completed (MetaWindowActor *actor,
|
||||
gulong event);
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "meta-texture-rectangle.h"
|
||||
#include "region-utils.h"
|
||||
#include "meta-wayland-private.h"
|
||||
#include "monitor-private.h"
|
||||
|
||||
enum {
|
||||
POSITION_CHANGED,
|
||||
@@ -78,12 +77,6 @@ struct _MetaWindowActorPrivate
|
||||
/* The region we should clip to when painting the shadow */
|
||||
cairo_region_t *shadow_clip;
|
||||
|
||||
/* The region that is visible, used to optimize out redraws */
|
||||
cairo_region_t *unobscured_region;
|
||||
|
||||
guint send_frame_messages_timer;
|
||||
gint64 frame_drawn_time;
|
||||
|
||||
/* Extracted size-invariant shape used for shadows */
|
||||
MetaWindowShape *shadow_shape;
|
||||
|
||||
@@ -193,12 +186,6 @@ static void meta_window_actor_handle_updates (MetaWindowActor *self);
|
||||
|
||||
static void check_needs_reshape (MetaWindowActor *self);
|
||||
|
||||
static void do_send_frame_drawn (MetaWindowActor *self, FrameData *frame);
|
||||
static void do_send_frame_timings (MetaWindowActor *self,
|
||||
FrameData *frame,
|
||||
gint refresh_interval,
|
||||
gint64 presentation_time);
|
||||
|
||||
G_DEFINE_TYPE (MetaWindowActor, meta_window_actor, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
static void
|
||||
@@ -369,25 +356,16 @@ meta_window_actor_constructed (GObject *object)
|
||||
Window xwindow = priv->xwindow;
|
||||
MetaWindow *window = priv->window;
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
XRenderPictFormat *format;
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
priv->damage = XDamageCreate (xdisplay, xwindow,
|
||||
XDamageReportBoundingBox);
|
||||
|
||||
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
XRenderPictFormat *format;
|
||||
format = XRenderFindVisualFormat (xdisplay, window->xvisual);
|
||||
|
||||
format = XRenderFindVisualFormat (xdisplay, window->xvisual);
|
||||
|
||||
if (format && format->type == PictTypeDirect && format->direct.alphaMask)
|
||||
priv->argb32 = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* XXX: parse shm formats to determine argb32 */
|
||||
priv->argb32 = TRUE;
|
||||
}
|
||||
if (format && format->type == PictTypeDirect && format->direct.alphaMask)
|
||||
priv->argb32 = TRUE;
|
||||
|
||||
if (!priv->actor)
|
||||
{
|
||||
@@ -451,15 +429,13 @@ meta_window_actor_dispose (GObject *object)
|
||||
info = meta_screen_get_compositor_data (screen);
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
meta_window_actor_detach_x11_pixmap (self);
|
||||
|
||||
if (priv->send_frame_messages_timer != 0)
|
||||
{
|
||||
g_source_remove (priv->send_frame_messages_timer);
|
||||
priv->send_frame_messages_timer = 0;
|
||||
display = meta_screen_get_display (screen);
|
||||
xdisplay = meta_display_get_xdisplay (display);
|
||||
|
||||
meta_window_actor_detach_x11_pixmap (self);
|
||||
}
|
||||
|
||||
g_clear_pointer (&priv->unobscured_region, cairo_region_destroy);
|
||||
g_clear_pointer (&priv->shape_region, cairo_region_destroy);
|
||||
g_clear_pointer (&priv->input_region, cairo_region_destroy);
|
||||
g_clear_pointer (&priv->opaque_region, cairo_region_destroy);
|
||||
@@ -472,9 +448,6 @@ meta_window_actor_dispose (GObject *object)
|
||||
|
||||
if (!meta_is_wayland_compositor () && priv->damage != None)
|
||||
{
|
||||
display = meta_screen_get_display (screen);
|
||||
xdisplay = meta_display_get_xdisplay (display);
|
||||
|
||||
meta_error_trap_push (display);
|
||||
XDamageDestroy (xdisplay, priv->damage);
|
||||
meta_error_trap_pop (display);
|
||||
@@ -687,16 +660,6 @@ meta_window_actor_paint (ClutterActor *actor)
|
||||
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
||||
MetaShadow *shadow = appears_focused ? priv->focused_shadow : priv->unfocused_shadow;
|
||||
|
||||
/* This window got damage when obscured; we set up a timer
|
||||
* to send frame completion events, but since we're drawing
|
||||
* the window now (for some other reason) cancel the timer
|
||||
* and send the completion events normally */
|
||||
if (priv->send_frame_messages_timer != 0)
|
||||
{
|
||||
g_source_remove (priv->send_frame_messages_timer);
|
||||
priv->send_frame_messages_timer = 0;
|
||||
}
|
||||
|
||||
if (shadow != NULL)
|
||||
{
|
||||
MetaShadowParams params;
|
||||
@@ -767,9 +730,6 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
|
||||
gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
|
||||
}
|
||||
|
||||
if (priv->unobscured_region)
|
||||
cairo_region_intersect_rectangle (priv->unobscured_region, &bounds);
|
||||
|
||||
origin.x = bounds.x;
|
||||
origin.y = bounds.y;
|
||||
origin.z = 0.0f;
|
||||
@@ -962,66 +922,11 @@ meta_window_actor_freeze (MetaWindowActor *self)
|
||||
self->priv->freeze_count++;
|
||||
}
|
||||
|
||||
static
|
||||
gboolean send_frame_messages_timeout (gpointer data)
|
||||
{
|
||||
MetaWindowActor *self = (MetaWindowActor *) data;
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
FrameData *frame = g_slice_new0 (FrameData);
|
||||
|
||||
frame->sync_request_serial = priv->window->sync_request_serial;
|
||||
|
||||
do_send_frame_drawn (self, frame);
|
||||
do_send_frame_timings (self, frame, 0, 0);
|
||||
|
||||
priv->needs_frame_drawn = FALSE;
|
||||
priv->send_frame_messages_timer = 0;
|
||||
frame_data_free (frame);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
queue_send_frame_messages_timeout (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
gint64 current_time = meta_compositor_monotonic_time_to_server_time (display, g_get_monotonic_time ());
|
||||
MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
|
||||
MetaWindow *window = priv->window;
|
||||
|
||||
MetaOutput *outputs;
|
||||
guint n_outputs, i;
|
||||
float refresh_rate = 60.0f;
|
||||
gint interval, offset;
|
||||
|
||||
outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
if (outputs[i].output_id == window->monitor->output_id && outputs[i].crtc)
|
||||
{
|
||||
refresh_rate = outputs[i].crtc->current_mode->refresh_rate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
interval = (int)(1000000 / refresh_rate) * 6;
|
||||
offset = MAX (0, priv->frame_drawn_time + interval - current_time) / 1000;
|
||||
|
||||
/* The clutter master clock source has already been added with META_PRIORITY_REDRAW,
|
||||
* so the timer will run *after* the clutter frame handling, if a frame is ready
|
||||
* to be drawn when the timer expires.
|
||||
*/
|
||||
priv->send_frame_messages_timer = g_timeout_add_full (META_PRIORITY_REDRAW, offset, send_frame_messages_timeout, self, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_damage_all (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
CoglTexture *texture;
|
||||
gboolean redraw_queued;
|
||||
|
||||
if (!priv->needs_damage_all)
|
||||
return;
|
||||
@@ -1031,16 +936,13 @@ meta_window_actor_damage_all (MetaWindowActor *self)
|
||||
if (!priv->mapped || priv->needs_pixmap)
|
||||
return;
|
||||
|
||||
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||
0, 0,
|
||||
cogl_texture_get_width (texture),
|
||||
cogl_texture_get_height (texture),
|
||||
clutter_actor_has_mapped_clones (priv->actor) ?
|
||||
NULL : priv->unobscured_region);
|
||||
|
||||
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
|
||||
meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||
0, 0,
|
||||
cogl_texture_get_width (texture),
|
||||
cogl_texture_get_height (texture));
|
||||
|
||||
priv->needs_damage_all = FALSE;
|
||||
priv->repaint_scheduled = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1096,31 +998,14 @@ meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
||||
|
||||
if (!priv->repaint_scheduled)
|
||||
{
|
||||
gboolean is_obscured = FALSE;
|
||||
|
||||
/* Find out whether the window is completly obscured */
|
||||
if (priv->unobscured_region)
|
||||
{
|
||||
cairo_region_t *unobscured_window_region;
|
||||
unobscured_window_region = cairo_region_copy (priv->shape_region);
|
||||
cairo_region_intersect (unobscured_window_region, priv->unobscured_region);
|
||||
is_obscured = cairo_region_is_empty (unobscured_window_region);
|
||||
cairo_region_destroy (unobscured_window_region);
|
||||
}
|
||||
|
||||
/* A frame was marked by the client without actually doing any
|
||||
* damage or any unobscured, or while we had the window frozen
|
||||
* (e.g. during an interactive resize.) We need to make sure that the
|
||||
* damage, or while we had the window frozen (e.g. during an
|
||||
* interactive resize.) We need to make sure that the
|
||||
* pre_paint/post_paint functions get called, enabling us to
|
||||
* send a _NET_WM_FRAME_DRAWN. We do a 1-pixel redraw to get
|
||||
* consistent timing with non-empty frames. If the window
|
||||
* is completely obscured we fire off the send_frame_messages timeout.
|
||||
* consistent timing with non-empty frames.
|
||||
*/
|
||||
if (is_obscured)
|
||||
{
|
||||
queue_send_frame_messages_timeout (self);
|
||||
}
|
||||
else if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap))
|
||||
if (priv->mapped && (!meta_is_wayland_compositor () || !priv->needs_pixmap))
|
||||
{
|
||||
const cairo_rectangle_int_t clip = { 0, 0, 1, 1 };
|
||||
clutter_actor_queue_redraw_with_clip (priv->actor, &clip);
|
||||
@@ -1473,22 +1358,6 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaRectangle window_rect;
|
||||
|
||||
meta_window_get_input_rect (priv->window, &window_rect);
|
||||
|
||||
/* When running as a display server we catch size changes when new
|
||||
buffers are attached */
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
if (priv->last_width != window_rect.width ||
|
||||
priv->last_height != window_rect.height)
|
||||
{
|
||||
priv->x11_size_changed = TRUE;
|
||||
|
||||
priv->last_width = window_rect.width;
|
||||
priv->last_height = window_rect.height;
|
||||
}
|
||||
}
|
||||
|
||||
/* Normally we want freezing a window to also freeze its position; this allows
|
||||
* windows to atomically move and resize together, either under app control,
|
||||
* or because the user is resizing from the left/top. But on initial placement
|
||||
@@ -1499,12 +1368,22 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
|
||||
if (is_frozen (self) && !did_placement)
|
||||
return;
|
||||
|
||||
meta_window_get_input_rect (priv->window, &window_rect);
|
||||
|
||||
/* When running as a display server then we instead catch size changes when
|
||||
* new buffers are attached */
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
if (priv->x11_size_changed)
|
||||
if (priv->last_width != window_rect.width ||
|
||||
priv->last_height != window_rect.height)
|
||||
{
|
||||
priv->x11_size_changed = TRUE;
|
||||
meta_window_actor_queue_create_x11_pixmap (self);
|
||||
|
||||
meta_window_actor_update_shape (self);
|
||||
|
||||
priv->last_width = window_rect.width;
|
||||
priv->last_height = window_rect.height;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1846,67 +1725,40 @@ see_region (cairo_region_t *region,
|
||||
#endif
|
||||
|
||||
/**
|
||||
* meta_window_actor_set_unobscured_region:
|
||||
* meta_window_actor_set_visible_region:
|
||||
* @self: a #MetaWindowActor
|
||||
* @unobscured_region: the region of the screen that isn't completely
|
||||
* obscured.
|
||||
*
|
||||
* Provides a hint as to what areas of the window need to queue
|
||||
* redraws when damaged. Regions not in @unobscured_region are completely obscured.
|
||||
* Unlike meta_window_actor_set_clip_region(), the region here
|
||||
* doesn't take into account any clipping that is in effect while drawing.
|
||||
*/
|
||||
void
|
||||
meta_window_actor_set_unobscured_region (MetaWindowActor *self,
|
||||
cairo_region_t *unobscured_region)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
if (priv->unobscured_region)
|
||||
cairo_region_destroy (priv->unobscured_region);
|
||||
|
||||
if (unobscured_region)
|
||||
priv->unobscured_region = cairo_region_copy (unobscured_region);
|
||||
else
|
||||
priv->unobscured_region = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_actor_set_clip_region:
|
||||
* @self: a #MetaWindowActor
|
||||
* @clip_region: the region of the screen that isn't completely
|
||||
* @visible_region: the region of the screen that isn't completely
|
||||
* obscured.
|
||||
*
|
||||
* Provides a hint as to what areas of the window need to be
|
||||
* drawn. Regions not in @clip_region are completely obscured or
|
||||
* not drawn in this frame.
|
||||
* drawn. Regions not in @visible_region are completely obscured.
|
||||
* This will be set before painting then unset afterwards.
|
||||
*/
|
||||
void
|
||||
meta_window_actor_set_clip_region (MetaWindowActor *self,
|
||||
cairo_region_t *clip_region)
|
||||
meta_window_actor_set_visible_region (MetaWindowActor *self,
|
||||
cairo_region_t *visible_region)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
meta_shaped_texture_set_clip_region (META_SHAPED_TEXTURE (priv->actor),
|
||||
clip_region);
|
||||
visible_region);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_actor_set_clip_region_beneath:
|
||||
* meta_window_actor_set_visible_region_beneath:
|
||||
* @self: a #MetaWindowActor
|
||||
* @clip_region: the region of the screen that isn't completely
|
||||
* @visible_region: the region of the screen that isn't completely
|
||||
* obscured beneath the main window texture.
|
||||
*
|
||||
* Provides a hint as to what areas need to be drawn *beneath*
|
||||
* the main window texture. This is the relevant clip region
|
||||
* the main window texture. This is the relevant visible region
|
||||
* when drawing the shadow, properly accounting for areas of the
|
||||
* shadow hid by the window itself. This will be set before painting
|
||||
* then unset afterwards.
|
||||
*/
|
||||
void
|
||||
meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
|
||||
cairo_region_t *beneath_region)
|
||||
meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
|
||||
cairo_region_t *beneath_region)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
||||
@@ -1925,14 +1777,14 @@ meta_window_actor_set_clip_region_beneath (MetaWindowActor *self,
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_window_actor_reset_clip_regions:
|
||||
* meta_window_actor_reset_visible_regions:
|
||||
* @self: a #MetaWindowActor
|
||||
*
|
||||
* Unsets the regions set by meta_window_actor_set_clip_region() and
|
||||
* meta_window_actor_set_clip_region_beneath()
|
||||
* Unsets the regions set by meta_window_actor_set_visible_region() and
|
||||
* meta_window_actor_set_visible_region_beneath()
|
||||
*/
|
||||
void
|
||||
meta_window_actor_reset_clip_regions (MetaWindowActor *self)
|
||||
meta_window_actor_reset_visible_regions (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
@@ -2107,7 +1959,6 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self,
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (priv->screen);
|
||||
gboolean redraw_queued;
|
||||
|
||||
priv->received_x11_damage = TRUE;
|
||||
|
||||
@@ -2155,16 +2006,12 @@ meta_window_actor_process_x11_damage (MetaWindowActor *self,
|
||||
if (!priv->mapped || priv->needs_pixmap)
|
||||
return;
|
||||
|
||||
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||
event->area.x,
|
||||
event->area.y,
|
||||
event->area.width,
|
||||
event->area.height,
|
||||
clutter_actor_has_mapped_clones (priv->actor) ?
|
||||
NULL : priv->unobscured_region);
|
||||
|
||||
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
|
||||
|
||||
meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||
event->area.x,
|
||||
event->area.y,
|
||||
event->area.width,
|
||||
event->area.height);
|
||||
priv->repaint_scheduled = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2175,17 +2022,13 @@ meta_window_actor_process_wayland_damage (MetaWindowActor *self,
|
||||
int height)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
gboolean redraw_queued;
|
||||
|
||||
if (!priv->mapped)
|
||||
return;
|
||||
|
||||
redraw_queued = meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||
x, y, width, height,
|
||||
clutter_actor_has_mapped_clones (priv->actor) ?
|
||||
NULL : priv->unobscured_region);
|
||||
|
||||
priv->repaint_scheduled = priv->repaint_scheduled || redraw_queued;
|
||||
meta_shaped_texture_update_area (META_SHAPED_TEXTURE (priv->actor),
|
||||
x, y, width, height);
|
||||
priv->repaint_scheduled = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2358,7 +2201,11 @@ meta_window_actor_update_shape_region (MetaWindowActor *self,
|
||||
g_clear_pointer (&priv->shape_region, cairo_region_destroy);
|
||||
priv->shape_region = region;
|
||||
|
||||
g_clear_pointer (&priv->shadow_shape, meta_window_shape_unref);
|
||||
if (priv->shadow_shape != NULL)
|
||||
{
|
||||
meta_window_shape_unref (priv->shadow_shape);
|
||||
priv->shadow_shape = NULL;
|
||||
}
|
||||
|
||||
meta_window_actor_invalidate_shadow (self);
|
||||
}
|
||||
@@ -2371,17 +2218,16 @@ meta_window_actor_update_input_region (MetaWindowActor *self,
|
||||
MetaShapedTexture *stex = META_SHAPED_TEXTURE (priv->actor);
|
||||
cairo_region_t *region = NULL;
|
||||
|
||||
if (priv->window->frame != NULL && priv->window->input_region != NULL)
|
||||
if (priv->window->frame != NULL && priv->window->shape_region != NULL)
|
||||
{
|
||||
cairo_region_t *client_region = cairo_region_copy (priv->window->input_region);
|
||||
|
||||
region = meta_frame_get_frame_bounds (priv->window->frame);
|
||||
|
||||
cairo_region_subtract_rectangle (region, client_area);
|
||||
|
||||
/* input_region is in client window coordinates, so translate the
|
||||
* input region into that coordinate system and back */
|
||||
cairo_region_translate (region, -client_area->x, -client_area->y);
|
||||
cairo_region_union (region, priv->window->input_region);
|
||||
cairo_region_translate (region, client_area->x, client_area->y);
|
||||
cairo_region_translate (client_region, client_area->x, client_area->y);
|
||||
cairo_region_union (region, client_region);
|
||||
cairo_region_destroy (client_region);
|
||||
}
|
||||
else if (priv->window->shape_region != NULL)
|
||||
{
|
||||
@@ -2521,6 +2367,8 @@ meta_window_actor_set_wayland_surface (MetaWindowActor *self,
|
||||
surface);
|
||||
if (surface && surface->buffer_ref.buffer)
|
||||
maybe_emit_size_changed (self, surface->buffer_ref.buffer);
|
||||
|
||||
meta_window_actor_invalidate_shadow (self);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2618,35 +2466,6 @@ meta_window_actor_pre_paint (MetaWindowActor *self)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_send_frame_drawn (MetaWindowActor *self, FrameData *frame)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
|
||||
XClientMessageEvent ev = { 0, };
|
||||
|
||||
frame->frame_drawn_time = meta_compositor_monotonic_time_to_server_time (display,
|
||||
g_get_monotonic_time ());
|
||||
priv->frame_drawn_time = frame->frame_drawn_time;
|
||||
|
||||
ev.type = ClientMessage;
|
||||
ev.window = meta_window_get_xwindow (priv->window);
|
||||
ev.message_type = display->atom__NET_WM_FRAME_DRAWN;
|
||||
ev.format = 32;
|
||||
ev.data.l[0] = frame->sync_request_serial & G_GUINT64_CONSTANT(0xffffffff);
|
||||
ev.data.l[1] = frame->sync_request_serial >> 32;
|
||||
ev.data.l[2] = frame->frame_drawn_time & G_GUINT64_CONSTANT(0xffffffff);
|
||||
ev.data.l[3] = frame->frame_drawn_time >> 32;
|
||||
|
||||
meta_error_trap_push (display);
|
||||
XSendEvent (xdisplay, ev.window, False, 0, (XEvent*) &ev);
|
||||
XFlush (xdisplay);
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_post_paint (MetaWindowActor *self)
|
||||
{
|
||||
@@ -2654,29 +2473,47 @@ meta_window_actor_post_paint (MetaWindowActor *self)
|
||||
|
||||
priv->repaint_scheduled = FALSE;
|
||||
|
||||
/* This window had damage, but wasn't actually redrawn because
|
||||
* it is obscured. So we should wait until timer expiration
|
||||
* before sending _NET_WM_FRAME_* messages.
|
||||
*/
|
||||
if (priv->send_frame_messages_timer != 0)
|
||||
return;
|
||||
|
||||
if (priv->needs_frame_drawn)
|
||||
{
|
||||
do_send_frame_drawn (self, priv->frames->data);
|
||||
MetaScreen *screen = priv->screen;
|
||||
MetaDisplay *display = meta_screen_get_display (screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
|
||||
XClientMessageEvent ev = { 0, };
|
||||
|
||||
FrameData *frame = priv->frames->data;
|
||||
|
||||
frame->frame_drawn_time = meta_compositor_monotonic_time_to_server_time (display,
|
||||
g_get_monotonic_time ());
|
||||
ev.type = ClientMessage;
|
||||
ev.window = meta_window_get_xwindow (priv->window);
|
||||
ev.message_type = display->atom__NET_WM_FRAME_DRAWN;
|
||||
ev.format = 32;
|
||||
ev.data.l[0] = frame->sync_request_serial & G_GUINT64_CONSTANT(0xffffffff);
|
||||
ev.data.l[1] = frame->sync_request_serial >> 32;
|
||||
ev.data.l[2] = frame->frame_drawn_time & G_GUINT64_CONSTANT(0xffffffff);
|
||||
ev.data.l[3] = frame->frame_drawn_time >> 32;
|
||||
|
||||
meta_error_trap_push (display);
|
||||
XSendEvent (xdisplay, ev.window, False, 0, (XEvent*) &ev);
|
||||
XFlush (xdisplay);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
priv->needs_frame_drawn = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
do_send_frame_timings (MetaWindowActor *self,
|
||||
FrameData *frame,
|
||||
gint refresh_interval,
|
||||
gint64 presentation_time)
|
||||
send_frame_timings (MetaWindowActor *self,
|
||||
FrameData *frame,
|
||||
CoglFrameInfo *frame_info,
|
||||
gint64 presentation_time)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaDisplay *display = meta_screen_get_display (priv->screen);
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
float refresh_rate;
|
||||
int refresh_interval;
|
||||
|
||||
XClientMessageEvent ev = { 0, };
|
||||
|
||||
@@ -2687,6 +2524,13 @@ do_send_frame_timings (MetaWindowActor *self,
|
||||
ev.data.l[0] = frame->sync_request_serial & G_GUINT64_CONSTANT(0xffffffff);
|
||||
ev.data.l[1] = frame->sync_request_serial >> 32;
|
||||
|
||||
refresh_rate = cogl_frame_info_get_refresh_rate (frame_info);
|
||||
/* 0.0 is a flag for not known, but sanity-check against other odd numbers */
|
||||
if (refresh_rate >= 1.0)
|
||||
refresh_interval = (int) (0.5 + 1000000 / refresh_rate);
|
||||
else
|
||||
refresh_interval = 0;
|
||||
|
||||
if (presentation_time != 0)
|
||||
{
|
||||
gint64 presentation_time_server = meta_compositor_monotonic_time_to_server_time (display,
|
||||
@@ -2708,25 +2552,6 @@ do_send_frame_timings (MetaWindowActor *self,
|
||||
meta_error_trap_pop (display);
|
||||
}
|
||||
|
||||
static void
|
||||
send_frame_timings (MetaWindowActor *self,
|
||||
FrameData *frame,
|
||||
CoglFrameInfo *frame_info,
|
||||
gint64 presentation_time)
|
||||
{
|
||||
float refresh_rate;
|
||||
int refresh_interval;
|
||||
|
||||
refresh_rate = cogl_frame_info_get_refresh_rate (frame_info);
|
||||
/* 0.0 is a flag for not known, but sanity-check against other odd numbers */
|
||||
if (refresh_rate >= 1.0)
|
||||
refresh_interval = (int) (0.5 + 1000000 / refresh_rate);
|
||||
else
|
||||
refresh_interval = 0;
|
||||
|
||||
do_send_frame_timings (self, frame, refresh_interval, presentation_time);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_frame_complete (MetaWindowActor *self,
|
||||
CoglFrameInfo *frame_info,
|
||||
|
||||
@@ -90,30 +90,17 @@ painting_untransformed (MetaWindowGroup *window_group,
|
||||
static void
|
||||
meta_window_group_paint (ClutterActor *actor)
|
||||
{
|
||||
cairo_region_t *clip_region;
|
||||
cairo_region_t *unobscured_region;
|
||||
cairo_region_t *visible_region;
|
||||
ClutterActor *stage;
|
||||
ClutterActorIter iter;
|
||||
ClutterActor *child;
|
||||
cairo_rectangle_int_t visible_rect, clip_rect;
|
||||
cairo_rectangle_int_t visible_rect;
|
||||
int paint_x_origin, paint_y_origin;
|
||||
int actor_x_origin, actor_y_origin;
|
||||
int paint_x_offset, paint_y_offset;
|
||||
|
||||
MetaWindowGroup *window_group = META_WINDOW_GROUP (actor);
|
||||
MetaCompScreen *info = meta_screen_get_compositor_data (window_group->screen);
|
||||
ClutterActor *stage = clutter_actor_get_stage (actor);
|
||||
|
||||
/* Start off by treating all windows as completely unobscured, so damage anywhere
|
||||
* in a window queues redraws, but confine it more below. */
|
||||
clutter_actor_iter_init (&iter, actor);
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
{
|
||||
if (META_IS_WINDOW_ACTOR (child))
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
|
||||
meta_window_actor_set_unobscured_region (window_actor, NULL);
|
||||
}
|
||||
}
|
||||
MetaCompScreen *info;
|
||||
|
||||
/* Normally we expect an actor to be drawn at it's position on the screen.
|
||||
* However, if we're inside the paint of a ClutterClone, that won't be the
|
||||
@@ -138,22 +125,17 @@ meta_window_group_paint (ClutterActor *actor)
|
||||
paint_x_offset = paint_x_origin - actor_x_origin;
|
||||
paint_y_offset = paint_y_origin - actor_y_origin;
|
||||
|
||||
visible_rect.x = visible_rect.y = 0;
|
||||
visible_rect.width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
||||
visible_rect.height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
||||
|
||||
unobscured_region = cairo_region_create_rectangle (&visible_rect);
|
||||
|
||||
/* Get the clipped redraw bounds from Clutter so that we can avoid
|
||||
* painting shadows on windows that don't need to be painted in this
|
||||
* frame. In the case of a multihead setup with mismatched monitor
|
||||
* sizes, we could intersect this with an accurate union of the
|
||||
* monitors to avoid painting shadows that are visible only in the
|
||||
* holes. */
|
||||
stage = clutter_actor_get_stage (actor);
|
||||
clutter_stage_get_redraw_clip_bounds (CLUTTER_STAGE (stage),
|
||||
&clip_rect);
|
||||
&visible_rect);
|
||||
|
||||
clip_region = cairo_region_create_rectangle (&clip_rect);
|
||||
visible_region = cairo_region_create_rectangle (&visible_rect);
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
{
|
||||
@@ -164,8 +146,7 @@ meta_window_group_paint (ClutterActor *actor)
|
||||
MetaWindow *window = meta_window_actor_get_meta_window (info->unredirected_window);
|
||||
|
||||
meta_window_get_outer_rect (window, (MetaRectangle *)&unredirected_rect);
|
||||
cairo_region_subtract_rectangle (unobscured_region, &unredirected_rect);
|
||||
cairo_region_subtract_rectangle (clip_region, &unredirected_rect);
|
||||
cairo_region_subtract_rectangle (visible_region, &unredirected_rect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,28 +195,20 @@ meta_window_group_paint (ClutterActor *actor)
|
||||
x += paint_x_offset;
|
||||
y += paint_y_offset;
|
||||
|
||||
|
||||
/* Temporarily move to the coordinate system of the actor */
|
||||
cairo_region_translate (unobscured_region, - x, - y);
|
||||
cairo_region_translate (clip_region, - x, - y);
|
||||
cairo_region_translate (visible_region, - x, - y);
|
||||
|
||||
meta_window_actor_set_unobscured_region (window_actor, unobscured_region);
|
||||
meta_window_actor_set_clip_region (window_actor, clip_region);
|
||||
meta_window_actor_set_visible_region (window_actor, visible_region);
|
||||
|
||||
if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
|
||||
{
|
||||
cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
|
||||
if (obscured_region)
|
||||
{
|
||||
cairo_region_subtract (unobscured_region, obscured_region);
|
||||
cairo_region_subtract (clip_region, obscured_region);
|
||||
}
|
||||
cairo_region_subtract (visible_region, obscured_region);
|
||||
}
|
||||
|
||||
meta_window_actor_set_clip_region_beneath (window_actor, clip_region);
|
||||
|
||||
cairo_region_translate (unobscured_region, x, y);
|
||||
cairo_region_translate (clip_region, x, y);
|
||||
meta_window_actor_set_visible_region_beneath (window_actor, visible_region);
|
||||
cairo_region_translate (visible_region, x, y);
|
||||
}
|
||||
else if (META_IS_BACKGROUND_ACTOR (child) ||
|
||||
META_IS_BACKGROUND_GROUP (child))
|
||||
@@ -248,18 +221,17 @@ meta_window_group_paint (ClutterActor *actor)
|
||||
x += paint_x_offset;
|
||||
y += paint_y_offset;
|
||||
|
||||
cairo_region_translate (clip_region, - x, - y);
|
||||
cairo_region_translate (visible_region, - x, - y);
|
||||
|
||||
if (META_IS_BACKGROUND_GROUP (child))
|
||||
meta_background_group_set_clip_region (META_BACKGROUND_GROUP (child), clip_region);
|
||||
meta_background_group_set_visible_region (META_BACKGROUND_GROUP (child), visible_region);
|
||||
else
|
||||
meta_background_actor_set_clip_region (META_BACKGROUND_ACTOR (child), clip_region);
|
||||
cairo_region_translate (clip_region, x, y);
|
||||
meta_background_actor_set_visible_region (META_BACKGROUND_ACTOR (child), visible_region);
|
||||
cairo_region_translate (visible_region, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
cairo_region_destroy (unobscured_region);
|
||||
cairo_region_destroy (clip_region);
|
||||
cairo_region_destroy (visible_region);
|
||||
|
||||
CLUTTER_ACTOR_CLASS (meta_window_group_parent_class)->paint (actor);
|
||||
|
||||
@@ -272,12 +244,12 @@ meta_window_group_paint (ClutterActor *actor)
|
||||
if (META_IS_WINDOW_ACTOR (child))
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (child);
|
||||
meta_window_actor_reset_clip_regions (window_actor);
|
||||
meta_window_actor_reset_visible_regions (window_actor);
|
||||
}
|
||||
else if (META_IS_BACKGROUND_ACTOR (child))
|
||||
{
|
||||
MetaBackgroundActor *background_actor = META_BACKGROUND_ACTOR (child);
|
||||
meta_background_actor_set_clip_region (background_actor, NULL);
|
||||
meta_background_actor_set_visible_region (background_actor, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,15 @@
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <meta/meta-plugin.h>
|
||||
#include <meta/window.h>
|
||||
#include <meta/util.h>
|
||||
#include <meta/meta-background-group.h>
|
||||
#include <meta/meta-background-actor.h>
|
||||
#include <meta/util.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include <libintl.h>
|
||||
#define _(x) dgettext (GETTEXT_PACKAGE, x)
|
||||
#define N_(x) x
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <gmodule.h>
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
#include "bell.h"
|
||||
#include "screen-private.h"
|
||||
#include "window-private.h"
|
||||
#include "util-private.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/compositor.h>
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
|
||||
@@ -447,14 +447,12 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
|
||||
/* Workaround braindead legacy apps that don't know how to
|
||||
* fullscreen themselves properly - don't get fooled by
|
||||
* windows which hide their titlebar when maximized or which are
|
||||
* client decorated; that's not the same as fullscreen, even
|
||||
* if there are no struts making the workarea smaller than
|
||||
* the monitor.
|
||||
* windows which hide their titlebar when maximized; that's
|
||||
* not the same as fullscreen, even if there are no struts
|
||||
* making the workarea smaller than the monitor.
|
||||
*/
|
||||
if (meta_prefs_get_force_fullscreen() &&
|
||||
!window->hide_titlebar_when_maximized &&
|
||||
window->decorated &&
|
||||
meta_rectangle_equal (new, &monitor_info->rect) &&
|
||||
window->has_fullscreen_func &&
|
||||
!window->fullscreen)
|
||||
|
||||
@@ -35,8 +35,7 @@ typedef enum
|
||||
META_DO_GRAVITY_ADJUST = 1 << 1,
|
||||
META_IS_USER_ACTION = 1 << 2,
|
||||
META_IS_MOVE_ACTION = 1 << 3,
|
||||
META_IS_RESIZE_ACTION = 1 << 4,
|
||||
META_IS_WAYLAND_RESIZE = 1 << 5
|
||||
META_IS_RESIZE_ACTION = 1 << 4
|
||||
} MetaMoveResizeFlags;
|
||||
|
||||
void meta_window_constrain (MetaWindow *window,
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "workspace-private.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/errors.h>
|
||||
#include "util-private.h"
|
||||
|
||||
/* Looks up the MetaWindow representing the frame of the given X window.
|
||||
* Used as a helper function by a bunch of the functions below.
|
||||
@@ -90,7 +89,7 @@ meta_core_get (Display *xdisplay,
|
||||
if (request != META_CORE_WINDOW_HAS_FRAME &&
|
||||
(window == NULL || window->frame == NULL)) {
|
||||
meta_bug ("No such frame window 0x%lx!\n", xwindow);
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
while (request != META_CORE_GET_END) {
|
||||
@@ -100,7 +99,7 @@ meta_core_get (Display *xdisplay,
|
||||
switch (request) {
|
||||
case META_CORE_WINDOW_HAS_FRAME:
|
||||
*((gboolean*)answer) = window != NULL && window->frame != NULL;
|
||||
if (!*((gboolean*)answer)) goto out; /* see above */
|
||||
if (!*((gboolean*)answer)) return; /* see above */
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_WIDTH:
|
||||
*((gint*)answer) = window->rect.width;
|
||||
@@ -155,13 +154,12 @@ meta_core_get (Display *xdisplay,
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_warning("Unknown window information request: %d\n", request);
|
||||
meta_warning(_("Unknown window information request: %d"), request);
|
||||
}
|
||||
|
||||
request = va_arg (args, MetaCoreGetType);
|
||||
}
|
||||
|
||||
out:
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#define _XOPEN_SOURCE /* for kill() */
|
||||
|
||||
#include <config.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include "window-private.h"
|
||||
#include <meta/errors.h>
|
||||
#include <meta/workspace.h>
|
||||
|
||||
@@ -154,7 +154,6 @@ struct _MetaDisplay
|
||||
GSList *screens;
|
||||
MetaScreen *active_screen;
|
||||
GHashTable *xids;
|
||||
GHashTable *wayland_windows;
|
||||
int error_traps;
|
||||
int (* error_trap_handler) (Display *display,
|
||||
XErrorEvent *error);
|
||||
@@ -381,11 +380,6 @@ void meta_display_register_x_window (MetaDisplay *display,
|
||||
void meta_display_unregister_x_window (MetaDisplay *display,
|
||||
Window xwindow);
|
||||
|
||||
void meta_display_register_wayland_window (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
void meta_display_unregister_wayland_window (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
|
||||
#ifdef HAVE_XSYNC
|
||||
MetaWindow* meta_display_lookup_sync_alarm (MetaDisplay *display,
|
||||
XSyncAlarm alarm);
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#include <config.h>
|
||||
#include "display-private.h"
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include <meta/main.h>
|
||||
#include "screen-private.h"
|
||||
#include "window-private.h"
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <meta/compositor.h>
|
||||
#include <meta/compositor-mutter.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/cursorfont.h>
|
||||
#include "mutter-enum-types.h"
|
||||
#include "meta-idle-monitor-private.h"
|
||||
|
||||
@@ -63,7 +64,9 @@
|
||||
#ifdef HAVE_XKB
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_XCURSOR
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
#endif
|
||||
#include <X11/extensions/Xrender.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
#include <X11/extensions/Xdamage.h>
|
||||
@@ -418,7 +421,7 @@ enable_compositor (MetaDisplay *display)
|
||||
!META_DISPLAY_HAS_DAMAGE (display) ||
|
||||
!META_DISPLAY_HAS_RENDER (display))
|
||||
{
|
||||
meta_warning ("Missing %s extension required for compositing",
|
||||
meta_warning (_("Missing %s extension required for compositing"),
|
||||
!META_DISPLAY_HAS_COMPOSITE (display) ? "composite" :
|
||||
!META_DISPLAY_HAS_DAMAGE (display) ? "damage" : "render");
|
||||
return;
|
||||
@@ -606,7 +609,6 @@ meta_display_open (void)
|
||||
|
||||
the_display->xids = g_hash_table_new (meta_unsigned_long_hash,
|
||||
meta_unsigned_long_equal);
|
||||
the_display->wayland_windows = g_hash_table_new (NULL, NULL);
|
||||
|
||||
i = 0;
|
||||
while (i < N_IGNORED_CROSSING_SERIALS)
|
||||
@@ -826,10 +828,14 @@ meta_display_open (void)
|
||||
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
|
||||
}
|
||||
|
||||
#ifdef HAVE_XCURSOR
|
||||
{
|
||||
XcursorSetTheme (the_display->xdisplay, meta_prefs_get_cursor_theme ());
|
||||
XcursorSetDefaultSize (the_display->xdisplay, meta_prefs_get_cursor_size ());
|
||||
}
|
||||
#else /* HAVE_XCURSOR */
|
||||
meta_verbose ("Not compiled with Xcursor support\n");
|
||||
#endif /* !HAVE_XCURSOR */
|
||||
|
||||
/* Create the leader window here. Set its properties and
|
||||
* use the timestamp from one of the PropertyNotify events
|
||||
@@ -1048,19 +1054,6 @@ meta_display_list_windows (MetaDisplay *display,
|
||||
winlist = g_slist_prepend (winlist, window);
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, display->wayland_windows);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
MetaWindow *window = value;
|
||||
|
||||
if (!META_IS_WINDOW (window))
|
||||
continue;
|
||||
|
||||
if (!window->override_redirect ||
|
||||
(flags & META_LIST_INCLUDE_OVERRIDE_REDIRECT) != 0)
|
||||
winlist = g_slist_prepend (winlist, window);
|
||||
}
|
||||
|
||||
/* Uniquify the list, since both frame windows and plain
|
||||
* windows are in the hash
|
||||
*/
|
||||
@@ -1883,17 +1876,14 @@ get_input_event (MetaDisplay *display,
|
||||
case XI_ButtonRelease:
|
||||
if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID)
|
||||
return input_event;
|
||||
break;
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
if (((XIDeviceEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID)
|
||||
return input_event;
|
||||
break;
|
||||
case XI_FocusIn:
|
||||
case XI_FocusOut:
|
||||
if (((XIEnterEvent *) input_event)->deviceid == META_VIRTUAL_CORE_KEYBOARD_ID)
|
||||
return input_event;
|
||||
break;
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
if (((XIEnterEvent *) input_event)->deviceid == META_VIRTUAL_CORE_POINTER_ID)
|
||||
@@ -3877,20 +3867,6 @@ meta_display_unregister_x_window (MetaDisplay *display,
|
||||
remove_pending_pings_for_window (display, xwindow);
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_register_wayland_window (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
g_hash_table_add (display->wayland_windows, window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_display_unregister_wayland_window (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
g_hash_table_remove (display->wayland_windows, window);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XSYNC
|
||||
/* We store sync alarms in the window ID hash table, because they are
|
||||
* just more types of XIDs in the same global space, but we have
|
||||
@@ -3958,6 +3934,60 @@ meta_display_xwindow_is_a_no_focus_window (MetaDisplay *display,
|
||||
return is_a_no_focus_window;
|
||||
}
|
||||
|
||||
Cursor
|
||||
meta_display_create_x_cursor (MetaDisplay *display,
|
||||
MetaCursor cursor)
|
||||
{
|
||||
Cursor xcursor;
|
||||
guint glyph;
|
||||
|
||||
switch (cursor)
|
||||
{
|
||||
case META_CURSOR_DEFAULT:
|
||||
glyph = XC_left_ptr;
|
||||
break;
|
||||
case META_CURSOR_NORTH_RESIZE:
|
||||
glyph = XC_top_side;
|
||||
break;
|
||||
case META_CURSOR_SOUTH_RESIZE:
|
||||
glyph = XC_bottom_side;
|
||||
break;
|
||||
case META_CURSOR_WEST_RESIZE:
|
||||
glyph = XC_left_side;
|
||||
break;
|
||||
case META_CURSOR_EAST_RESIZE:
|
||||
glyph = XC_right_side;
|
||||
break;
|
||||
case META_CURSOR_SE_RESIZE:
|
||||
glyph = XC_bottom_right_corner;
|
||||
break;
|
||||
case META_CURSOR_SW_RESIZE:
|
||||
glyph = XC_bottom_left_corner;
|
||||
break;
|
||||
case META_CURSOR_NE_RESIZE:
|
||||
glyph = XC_top_right_corner;
|
||||
break;
|
||||
case META_CURSOR_NW_RESIZE:
|
||||
glyph = XC_top_left_corner;
|
||||
break;
|
||||
case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
|
||||
glyph = XC_fleur;
|
||||
break;
|
||||
case META_CURSOR_BUSY:
|
||||
glyph = XC_watch;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
glyph = 0; /* silence compiler */
|
||||
break;
|
||||
}
|
||||
|
||||
xcursor = XCreateFontCursor (display->xdisplay, glyph);
|
||||
|
||||
return xcursor;
|
||||
}
|
||||
|
||||
static Cursor
|
||||
xcursor_for_op (MetaDisplay *display,
|
||||
MetaGrabOp op)
|
||||
@@ -4668,6 +4698,7 @@ void
|
||||
meta_display_set_cursor_theme (const char *theme,
|
||||
int size)
|
||||
{
|
||||
#ifdef HAVE_XCURSOR
|
||||
GSList *tmp;
|
||||
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
@@ -4684,6 +4715,8 @@ meta_display_set_cursor_theme (const char *theme,
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5951,7 +5984,7 @@ meta_display_get_xinput_opcode (MetaDisplay *display)
|
||||
gboolean
|
||||
meta_display_supports_extended_barriers (MetaDisplay *display)
|
||||
{
|
||||
return META_DISPLAY_HAS_XINPUT_23 (display) && !meta_is_wayland_compositor ();
|
||||
return META_DISPLAY_HAS_XINPUT_23 (display);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "frame.h"
|
||||
#include "place.h"
|
||||
#include <meta/prefs.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <string.h>
|
||||
@@ -53,13 +53,8 @@
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "meta-wayland-private.h"
|
||||
#endif
|
||||
|
||||
#define SCHEMA_COMMON_KEYBINDINGS "org.gnome.desktop.wm.keybindings"
|
||||
#define SCHEMA_MUTTER_KEYBINDINGS "org.gnome.mutter.keybindings"
|
||||
#define SCHEMA_MUTTER_WAYLAND_KEYBINDINGS "org.gnome.mutter.wayland.keybindings"
|
||||
|
||||
static gboolean add_builtin_keybinding (MetaDisplay *display,
|
||||
const char *name,
|
||||
@@ -1138,7 +1133,7 @@ meta_change_keygrab (MetaDisplay *display,
|
||||
if (grab && result != Success)
|
||||
{
|
||||
if (result == BadAccess)
|
||||
meta_warning ("Some other program is already using the key %s with modifiers %x as a binding\n", keysym_name (keysym), modmask | ignored_mask);
|
||||
meta_warning (_("Some other program is already using the key %s with modifiers %x as a binding\n"), keysym_name (keysym), modmask | ignored_mask);
|
||||
else
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Failed to grab key %s with modifiers %x\n",
|
||||
@@ -1335,7 +1330,7 @@ meta_display_grab_accelerator (MetaDisplay *display,
|
||||
{
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Failed to parse accelerator\n");
|
||||
meta_warning ("\"%s\" is not a valid accelerator\n", accelerator);
|
||||
meta_warning (_("\"%s\" is not a valid accelerator\n"), accelerator);
|
||||
|
||||
return META_KEYBINDING_ACTION_NONE;
|
||||
}
|
||||
@@ -4103,40 +4098,6 @@ handle_set_spew_mark (MetaDisplay *display,
|
||||
meta_verbose ("-- MARK MARK MARK MARK --\n");
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
static void
|
||||
handle_switch_vt (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
MetaWindow *window,
|
||||
XIDeviceEvent *event,
|
||||
MetaKeyBinding *binding,
|
||||
gpointer dummy)
|
||||
{
|
||||
gint vt = binding->handler->data;
|
||||
MetaWaylandCompositor *compositor;
|
||||
MetaLauncher *launcher;
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
launcher = meta_wayland_compositor_get_launcher (compositor);
|
||||
|
||||
if (launcher)
|
||||
{
|
||||
GError *error;
|
||||
|
||||
error = NULL;
|
||||
if (!meta_launcher_activate_vt (launcher, vt, &error))
|
||||
{
|
||||
g_warning ("Failed to switch VT: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_debug ("Ignoring VT switch keybinding, not running as VT manager");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* meta_keybindings_set_custom_handler:
|
||||
* @name: The name of the keybinding to set
|
||||
@@ -4200,7 +4161,6 @@ init_builtin_key_bindings (MetaDisplay *display)
|
||||
META_KEY_BINDING_IS_REVERSED)
|
||||
GSettings *common_keybindings = g_settings_new (SCHEMA_COMMON_KEYBINDINGS);
|
||||
GSettings *mutter_keybindings = g_settings_new (SCHEMA_MUTTER_KEYBINDINGS);
|
||||
GSettings *mutter_wayland_keybindings = g_settings_new (SCHEMA_MUTTER_WAYLAND_KEYBINDINGS);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-workspace-1",
|
||||
@@ -4462,60 +4422,6 @@ init_builtin_key_bindings (MetaDisplay *display)
|
||||
META_KEYBINDING_ACTION_SET_SPEW_MARK,
|
||||
handle_set_spew_mark, 0);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-1",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 1);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-2",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 2);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-3",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 3);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-4",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 4);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-5",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 5);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-6",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 6);
|
||||
|
||||
add_builtin_keybinding (display,
|
||||
"switch-to-session-7",
|
||||
mutter_wayland_keybindings,
|
||||
META_KEY_BINDING_NONE,
|
||||
META_KEYBINDING_ACTION_NONE,
|
||||
handle_switch_vt, 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef REVERSES_AND_REVERSED
|
||||
|
||||
/************************ PER WINDOW BINDINGS ************************/
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <meta/main.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include "display-private.h"
|
||||
#include <meta/errors.h>
|
||||
#include "ui.h"
|
||||
@@ -58,7 +58,6 @@
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <glib-unix.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -191,7 +190,6 @@ static gchar *opt_client_id;
|
||||
static gboolean opt_replace_wm;
|
||||
static gboolean opt_disable_sm;
|
||||
static gboolean opt_sync;
|
||||
static gboolean opt_wayland;
|
||||
|
||||
static GOptionEntry meta_options[] = {
|
||||
{
|
||||
@@ -229,12 +227,6 @@ static GOptionEntry meta_options[] = {
|
||||
N_("Make X calls synchronous"),
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"wayland", 0, 0, G_OPTION_ARG_NONE,
|
||||
&opt_wayland,
|
||||
N_("Run as a wayland compositor"),
|
||||
NULL
|
||||
},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
@@ -256,14 +248,6 @@ meta_get_option_context (void)
|
||||
bindtextdomain (GETTEXT_PACKAGE, MUTTER_LOCALEDIR);
|
||||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||
|
||||
/* We must set the windowing backend here, because Clutter creates the backend
|
||||
object when the first call is made.
|
||||
|
||||
We consider running from mutter-launch equivalent to running from bare metal.
|
||||
*/
|
||||
if (getenv ("WESTON_LAUNCHER_SOCK"))
|
||||
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
|
||||
|
||||
ctx = g_option_context_new (NULL);
|
||||
g_option_context_add_main_entries (ctx, meta_options, GETTEXT_PACKAGE);
|
||||
g_option_context_add_group (ctx, clutter_get_option_group_without_init ());
|
||||
@@ -368,12 +352,59 @@ meta_finalize (void)
|
||||
meta_wayland_finalize ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_sigterm (gpointer user_data)
|
||||
{
|
||||
meta_quit (EXIT_SUCCESS);
|
||||
static int signal_pipe_fds[2] = { -1, -1 };
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
static void
|
||||
signal_handler (int signum)
|
||||
{
|
||||
if (signal_pipe_fds[1] >= 0)
|
||||
{
|
||||
switch (signum)
|
||||
{
|
||||
case SIGTERM:
|
||||
write (signal_pipe_fds[1], "T", 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_signal (GIOChannel *source,
|
||||
GIOCondition condition,
|
||||
void *data)
|
||||
{
|
||||
char signal;
|
||||
int count;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
count = read (signal_pipe_fds[0], &signal, 1);
|
||||
if (count == EINTR)
|
||||
continue;
|
||||
if (count < 0)
|
||||
{
|
||||
const char *msg = strerror (errno);
|
||||
g_warning ("Error handling signal: %s", msg);
|
||||
}
|
||||
if (count != 1)
|
||||
{
|
||||
g_warning ("Unexpectedly failed to read byte from signal pipe\n");
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (signal)
|
||||
{
|
||||
case 'T': /* SIGTERM */
|
||||
meta_quit (META_EXIT_SUCCESS);
|
||||
break;
|
||||
default:
|
||||
g_warning ("Spurious character '%c' read from signal pipe", signal);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -387,6 +418,7 @@ meta_init (void)
|
||||
{
|
||||
struct sigaction act;
|
||||
sigset_t empty_mask;
|
||||
GIOChannel *channel;
|
||||
|
||||
sigemptyset (&empty_mask);
|
||||
act.sa_handler = SIG_IGN;
|
||||
@@ -401,15 +433,26 @@ meta_init (void)
|
||||
g_strerror (errno));
|
||||
#endif
|
||||
|
||||
g_unix_signal_add (SIGTERM, on_sigterm, NULL);
|
||||
if (pipe (signal_pipe_fds) != 0)
|
||||
g_printerr ("Failed to create signal pipe: %s\n",
|
||||
g_strerror (errno));
|
||||
|
||||
channel = g_io_channel_unix_new (signal_pipe_fds[0]);
|
||||
g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
|
||||
g_io_add_watch (channel, G_IO_IN, (GIOFunc) on_signal, NULL);
|
||||
g_io_channel_set_close_on_unref (channel, TRUE);
|
||||
g_io_channel_unref (channel);
|
||||
|
||||
act.sa_handler = &signal_handler;
|
||||
if (sigaction (SIGTERM, &act, NULL) < 0)
|
||||
g_printerr ("Failed to register SIGTERM handler: %s\n",
|
||||
g_strerror (errno));
|
||||
|
||||
if (g_getenv ("MUTTER_VERBOSE"))
|
||||
meta_set_verbose (TRUE);
|
||||
if (g_getenv ("MUTTER_DEBUG"))
|
||||
meta_set_debugging (TRUE);
|
||||
|
||||
meta_set_is_wayland_compositor (opt_wayland);
|
||||
|
||||
if (g_get_home_dir ())
|
||||
if (chdir (g_get_home_dir ()) < 0)
|
||||
meta_warning ("Could not change to home directory %s.\n",
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#define META_CURSOR_TRACKER_PRIVATE_H
|
||||
|
||||
#include <meta/meta-cursor-tracker.h>
|
||||
#include <wayland-server.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
@@ -34,10 +33,10 @@ gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
void meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursor cursor);
|
||||
void meta_cursor_tracker_revert_root (MetaCursorTracker *tracker);
|
||||
void meta_cursor_tracker_set_buffer (MetaCursorTracker *tracker,
|
||||
struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
void meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker,
|
||||
CoglTexture2D *texture,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
|
||||
void meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
||||
int new_x,
|
||||
|
||||
@@ -24,65 +24,50 @@
|
||||
/**
|
||||
* SECTION:cursor-tracker
|
||||
* @title: MetaCursorTracker
|
||||
* @short_description: Mutter cursor tracking helper. Originally only
|
||||
* tracking the cursor image, now more of a "core
|
||||
* pointer abstraction"
|
||||
* @short_description: Mutter cursor tracking helper
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <meta/main.h>
|
||||
#include <meta/util.h>
|
||||
#include <meta/errors.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#include <clutter/clutter.h>
|
||||
#include <gbm.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
#include <X11/cursorfont.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "screen-private.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "meta-wayland-private.h"
|
||||
#include "monitor-private.h"
|
||||
#endif
|
||||
|
||||
#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X 7
|
||||
#define META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y 4
|
||||
|
||||
typedef struct {
|
||||
CoglTexture2D *texture;
|
||||
struct gbm_bo *bo;
|
||||
int hot_x, hot_y;
|
||||
|
||||
int ref_count;
|
||||
} MetaCursorReference;
|
||||
|
||||
struct _MetaCursorTracker {
|
||||
GObject parent_instance;
|
||||
|
||||
MetaScreen *screen;
|
||||
|
||||
gboolean is_showing;
|
||||
gboolean has_cursor;
|
||||
gboolean has_hw_cursor;
|
||||
|
||||
MetaCursorReference *sprite;
|
||||
MetaCursorReference *root_cursor;
|
||||
MetaCursorReference *default_cursors[META_CURSOR_LAST];
|
||||
CoglTexture2D *sprite;
|
||||
int hot_x, hot_y;
|
||||
|
||||
CoglTexture2D *root_cursor;
|
||||
int root_hot_x, root_hot_y;
|
||||
|
||||
CoglTexture2D *default_cursor;
|
||||
|
||||
int current_x, current_y;
|
||||
MetaRectangle current_rect;
|
||||
MetaRectangle previous_rect;
|
||||
cairo_rectangle_int_t current_rect;
|
||||
cairo_rectangle_int_t previous_rect;
|
||||
gboolean previous_is_valid;
|
||||
|
||||
CoglPipeline *pipeline;
|
||||
int drm_fd;
|
||||
struct gbm_device *gbm;
|
||||
};
|
||||
|
||||
struct _MetaCursorTrackerClass {
|
||||
@@ -98,409 +83,6 @@ enum {
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static void meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *sprite);
|
||||
|
||||
static void meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
|
||||
MetaCRTC *crtc,
|
||||
gboolean has_hw_cursor);
|
||||
|
||||
static MetaCursorReference *
|
||||
meta_cursor_reference_ref (MetaCursorReference *self)
|
||||
{
|
||||
g_assert (self->ref_count > 0);
|
||||
self->ref_count++;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_reference_unref (MetaCursorReference *self)
|
||||
{
|
||||
self->ref_count--;
|
||||
|
||||
if (self->ref_count == 0)
|
||||
{
|
||||
cogl_object_unref (self->texture);
|
||||
if (self->bo)
|
||||
gbm_bo_destroy (self->bo);
|
||||
|
||||
g_slice_free (MetaCursorReference, self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
translate_meta_cursor (MetaCursor cursor,
|
||||
guint *glyph_out,
|
||||
const char **name_out)
|
||||
{
|
||||
guint glyph = XC_num_glyphs;
|
||||
const char *name = NULL;
|
||||
|
||||
switch (cursor)
|
||||
{
|
||||
case META_CURSOR_DEFAULT:
|
||||
glyph = XC_left_ptr;
|
||||
break;
|
||||
case META_CURSOR_NORTH_RESIZE:
|
||||
glyph = XC_top_side;
|
||||
break;
|
||||
case META_CURSOR_SOUTH_RESIZE:
|
||||
glyph = XC_bottom_side;
|
||||
break;
|
||||
case META_CURSOR_WEST_RESIZE:
|
||||
glyph = XC_left_side;
|
||||
break;
|
||||
case META_CURSOR_EAST_RESIZE:
|
||||
glyph = XC_right_side;
|
||||
break;
|
||||
case META_CURSOR_SE_RESIZE:
|
||||
glyph = XC_bottom_right_corner;
|
||||
break;
|
||||
case META_CURSOR_SW_RESIZE:
|
||||
glyph = XC_bottom_left_corner;
|
||||
break;
|
||||
case META_CURSOR_NE_RESIZE:
|
||||
glyph = XC_top_right_corner;
|
||||
break;
|
||||
case META_CURSOR_NW_RESIZE:
|
||||
glyph = XC_top_left_corner;
|
||||
break;
|
||||
case META_CURSOR_MOVE_OR_RESIZE_WINDOW:
|
||||
glyph = XC_fleur;
|
||||
break;
|
||||
case META_CURSOR_BUSY:
|
||||
glyph = XC_watch;
|
||||
break;
|
||||
case META_CURSOR_DND_IN_DRAG:
|
||||
name = "dnd-none";
|
||||
break;
|
||||
case META_CURSOR_DND_MOVE:
|
||||
name = "dnd-move";
|
||||
break;
|
||||
case META_CURSOR_DND_COPY:
|
||||
name = "dnd-copy";
|
||||
break;
|
||||
case META_CURSOR_DND_UNSUPPORTED_TARGET:
|
||||
name = "dnd-none";
|
||||
break;
|
||||
case META_CURSOR_POINTING_HAND:
|
||||
glyph = XC_hand2;
|
||||
break;
|
||||
case META_CURSOR_CROSSHAIR:
|
||||
glyph = XC_crosshair;
|
||||
break;
|
||||
case META_CURSOR_IBEAM:
|
||||
glyph = XC_xterm;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
glyph = 0; /* silence compiler */
|
||||
break;
|
||||
}
|
||||
|
||||
*glyph_out = glyph;
|
||||
*name_out = name;
|
||||
}
|
||||
|
||||
static Cursor
|
||||
load_cursor_on_server (MetaDisplay *display,
|
||||
MetaCursor cursor)
|
||||
{
|
||||
Cursor xcursor;
|
||||
guint glyph;
|
||||
const char *name;
|
||||
|
||||
translate_meta_cursor (cursor, &glyph, &name);
|
||||
|
||||
if (name != NULL)
|
||||
xcursor = XcursorLibraryLoadCursor (display->xdisplay, name);
|
||||
else
|
||||
xcursor = XCreateFontCursor (display->xdisplay, glyph);
|
||||
|
||||
return xcursor;
|
||||
}
|
||||
|
||||
Cursor
|
||||
meta_display_create_x_cursor (MetaDisplay *display,
|
||||
MetaCursor cursor)
|
||||
{
|
||||
return load_cursor_on_server (display, cursor);
|
||||
}
|
||||
|
||||
static XcursorImage *
|
||||
load_cursor_on_client (MetaDisplay *display,
|
||||
MetaCursor cursor)
|
||||
{
|
||||
XcursorImage *image;
|
||||
guint glyph;
|
||||
const char *name;
|
||||
const char *theme = XcursorGetTheme (display->xdisplay);
|
||||
int size = XcursorGetDefaultSize (display->xdisplay);
|
||||
|
||||
translate_meta_cursor (cursor, &glyph, &name);
|
||||
|
||||
if (name != NULL)
|
||||
image = XcursorLibraryLoadImage (name, theme, size);
|
||||
else
|
||||
image = XcursorShapeLoadImage (glyph, theme, size);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static MetaCursorReference *
|
||||
meta_cursor_reference_from_theme (MetaCursorTracker *tracker,
|
||||
MetaCursor cursor)
|
||||
{
|
||||
XcursorImage *image;
|
||||
int width, height, rowstride;
|
||||
CoglPixelFormat cogl_format;
|
||||
uint32_t gbm_format;
|
||||
ClutterBackend *clutter_backend;
|
||||
CoglContext *cogl_context;
|
||||
MetaCursorReference *self;
|
||||
|
||||
image = load_cursor_on_client (tracker->screen->display, cursor);
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
width = image->width;
|
||||
height = image->height;
|
||||
rowstride = width * 4;
|
||||
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
|
||||
#else
|
||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||
#endif
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
self->hot_x = image->xhot;
|
||||
self->hot_y = image->yhot;
|
||||
|
||||
clutter_backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||
self->texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
rowstride,
|
||||
(uint8_t*)image->pixels,
|
||||
NULL);
|
||||
|
||||
if (tracker->gbm)
|
||||
{
|
||||
if (width > 64 || height > 64)
|
||||
{
|
||||
meta_warning ("Invalid theme cursor size (must be at most 64x64)\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (gbm_device_is_format_supported (tracker->gbm, gbm_format,
|
||||
GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE))
|
||||
{
|
||||
uint32_t buf[64 * 64];
|
||||
int i;
|
||||
|
||||
self->bo = gbm_bo_create (tracker->gbm, 64, 64,
|
||||
gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
|
||||
|
||||
memset (buf, 0, sizeof(buf));
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy (buf + i * 64, image->pixels + i * width, width * 4);
|
||||
|
||||
gbm_bo_write (self->bo, buf, 64 * 64 * 4);
|
||||
}
|
||||
else
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
}
|
||||
|
||||
out:
|
||||
XcursorImageDestroy (image);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static MetaCursorReference *
|
||||
meta_cursor_reference_take_texture (CoglTexture2D *texture)
|
||||
{
|
||||
MetaCursorReference *self;
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
|
||||
self->texture = texture;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static MetaCursorReference *
|
||||
meta_cursor_reference_from_buffer (MetaCursorTracker *tracker,
|
||||
struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
MetaCursorReference *self;
|
||||
CoglPixelFormat cogl_format, cogl_internal_format;
|
||||
struct wl_shm_buffer *shm_buffer;
|
||||
uint32_t gbm_format;
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
shm_buffer = wl_shm_buffer_get (buffer);
|
||||
if (shm_buffer)
|
||||
{
|
||||
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
|
||||
int width = wl_shm_buffer_get_width (shm_buffer);
|
||||
int height = wl_shm_buffer_get_height (shm_buffer);
|
||||
|
||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
||||
{
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE;
|
||||
cogl_internal_format = COGL_PIXEL_FORMAT_ANY;
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||
cogl_internal_format = COGL_PIXEL_FORMAT_RGB_888;
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#else
|
||||
case WL_SHM_FORMAT_ARGB8888:
|
||||
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE;
|
||||
cogl_internal_format = COGL_PIXEL_FORMAT_ANY;
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case WL_SHM_FORMAT_XRGB8888:
|
||||
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
|
||||
cogl_internal_format = COGL_PIXEL_FORMAT_BGR_888;
|
||||
gbm_format = GBM_FORMAT_XRGB8888;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
cogl_format = COGL_PIXEL_FORMAT_ARGB_8888;
|
||||
cogl_internal_format = COGL_PIXEL_FORMAT_ANY;
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
}
|
||||
|
||||
self->texture = cogl_texture_2d_new_from_data (cogl_context,
|
||||
width, height,
|
||||
cogl_format,
|
||||
cogl_internal_format,
|
||||
rowstride,
|
||||
wl_shm_buffer_get_data (shm_buffer),
|
||||
NULL);
|
||||
|
||||
if (width > 64 || height > 64)
|
||||
{
|
||||
meta_warning ("Invalid cursor size (must be at most 64x64), falling back to software (GL) cursors\n");
|
||||
return self;
|
||||
}
|
||||
|
||||
if (tracker->gbm)
|
||||
{
|
||||
if (gbm_device_is_format_supported (tracker->gbm, gbm_format,
|
||||
GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE))
|
||||
{
|
||||
uint8_t *data;
|
||||
uint8_t buf[4 * 64 * 64];
|
||||
int i;
|
||||
|
||||
self->bo = gbm_bo_create (tracker->gbm, 64, 64,
|
||||
gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
|
||||
|
||||
data = wl_shm_buffer_get_data (shm_buffer);
|
||||
memset (buf, 0, sizeof(buf));
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy (buf + i * 4 * 64, data + i * rowstride, 4 * width);
|
||||
|
||||
gbm_bo_write (self->bo, buf, 64 * 64 * 4);
|
||||
}
|
||||
else
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int width, height;
|
||||
|
||||
self->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
|
||||
width = cogl_texture_get_width (COGL_TEXTURE (self->texture));
|
||||
height = cogl_texture_get_height (COGL_TEXTURE (self->texture));
|
||||
|
||||
/* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses
|
||||
that, so themed cursors must be padded with transparent pixels to fill the
|
||||
overlay. This is trivial if we have CPU access to the data, but it's not
|
||||
possible if the buffer is in GPU memory (and possibly tiled too), so if we
|
||||
don't get the right size, we fallback to GL.
|
||||
*/
|
||||
if (width != 64 || height != 64)
|
||||
{
|
||||
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
|
||||
return self;
|
||||
}
|
||||
|
||||
if (tracker->gbm)
|
||||
{
|
||||
cogl_format = cogl_texture_get_format (COGL_TEXTURE (self->texture));
|
||||
switch (cogl_format)
|
||||
{
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888:
|
||||
gbm_format = GBM_FORMAT_BGRA8888;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888:
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_RGB_888:
|
||||
break;
|
||||
#else
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_ARGB_8888:
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888_PRE:
|
||||
case COGL_PIXEL_FORMAT_BGRA_8888:
|
||||
gbm_format = GBM_FORMAT_BGRA8888;
|
||||
break;
|
||||
case COGL_PIXEL_FORMAT_RGB_888:
|
||||
gbm_format = GBM_FORMAT_RGB888;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
meta_warning ("Unknown cogl format %d\n", cogl_format);
|
||||
return self;
|
||||
}
|
||||
|
||||
if (gbm_device_is_format_supported (tracker->gbm, gbm_format,
|
||||
GBM_BO_USE_CURSOR_64X64))
|
||||
{
|
||||
self->bo = gbm_bo_import (tracker->gbm, GBM_BO_IMPORT_WL_BUFFER,
|
||||
buffer, GBM_BO_USE_CURSOR_64X64);
|
||||
if (!self->bo)
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
}
|
||||
else
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_tracker_init (MetaCursorTracker *self)
|
||||
{
|
||||
@@ -516,21 +98,15 @@ static void
|
||||
meta_cursor_tracker_finalize (GObject *object)
|
||||
{
|
||||
MetaCursorTracker *self = META_CURSOR_TRACKER (object);
|
||||
int i;
|
||||
|
||||
if (self->sprite)
|
||||
meta_cursor_reference_unref (self->sprite);
|
||||
cogl_object_unref (self->sprite);
|
||||
if (self->root_cursor)
|
||||
meta_cursor_reference_unref (self->root_cursor);
|
||||
|
||||
for (i = 0; i < META_CURSOR_LAST; i++)
|
||||
if (self->default_cursors[i])
|
||||
meta_cursor_reference_unref (self->default_cursors[i]);
|
||||
|
||||
cogl_object_unref (self->root_cursor);
|
||||
if (self->default_cursor)
|
||||
cogl_object_unref (self->default_cursor);
|
||||
if (self->pipeline)
|
||||
cogl_object_unref (self->pipeline);
|
||||
if (self->gbm)
|
||||
gbm_device_destroy (self->gbm);
|
||||
|
||||
G_OBJECT_CLASS (meta_cursor_tracker_parent_class)->finalize (object);
|
||||
}
|
||||
@@ -550,41 +126,13 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
on_monitors_changed (MetaMonitorManager *monitors,
|
||||
MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaCRTC *crtcs;
|
||||
unsigned int i, n_crtcs;
|
||||
|
||||
if (!tracker->has_hw_cursor)
|
||||
return;
|
||||
|
||||
/* Go through the new list of monitors, find out where the cursor is */
|
||||
meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
MetaRectangle *rect = &crtcs[i].rect;
|
||||
gboolean has;
|
||||
|
||||
has = meta_rectangle_overlap (&tracker->current_rect, rect);
|
||||
|
||||
/* Need to do it unconditionally here, our tracking is
|
||||
wrong because we reloaded the CRTCs */
|
||||
meta_cursor_tracker_set_crtc_has_hw_cursor (tracker, &crtcs[i], has);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
static MetaCursorTracker *
|
||||
make_wayland_cursor_tracker (MetaScreen *screen)
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
CoglContext *ctx;
|
||||
MetaMonitorManager *monitors;
|
||||
MetaCursorTracker *self;
|
||||
|
||||
self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
|
||||
MetaCursorTracker *self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
|
||||
self->screen = screen;
|
||||
|
||||
ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
@@ -593,16 +141,9 @@ make_wayland_cursor_tracker (MetaScreen *screen)
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
compositor->seat->cursor_tracker = self;
|
||||
|
||||
self->drm_fd = compositor->drm_fd;
|
||||
if (self->drm_fd >= 0)
|
||||
self->gbm = gbm_create_device (compositor->drm_fd);
|
||||
|
||||
monitors = meta_monitor_manager_get ();
|
||||
g_signal_connect_object (monitors, "monitors-changed",
|
||||
G_CALLBACK (on_monitors_changed), self, 0);
|
||||
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
static MetaCursorTracker *
|
||||
make_x11_cursor_tracker (MetaScreen *screen)
|
||||
@@ -660,7 +201,7 @@ meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
if (notify_event->subtype != XFixesDisplayCursorNotify)
|
||||
return FALSE;
|
||||
|
||||
g_clear_pointer (&tracker->sprite, meta_cursor_reference_unref);
|
||||
g_clear_pointer (&tracker->sprite, cogl_object_unref);
|
||||
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
|
||||
|
||||
return TRUE;
|
||||
@@ -723,9 +264,9 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
|
||||
if (sprite != NULL)
|
||||
{
|
||||
tracker->sprite = meta_cursor_reference_take_texture (sprite);
|
||||
tracker->sprite->hot_x = cursor_image->xhot;
|
||||
tracker->sprite->hot_y = cursor_image->yhot;
|
||||
tracker->sprite = sprite;
|
||||
tracker->hot_x = cursor_image->xhot;
|
||||
tracker->hot_y = cursor_image->yhot;
|
||||
}
|
||||
XFree (cursor_image);
|
||||
}
|
||||
@@ -743,10 +284,7 @@ meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
|
||||
if (!meta_is_wayland_compositor ())
|
||||
ensure_xfixes_cursor (tracker);
|
||||
|
||||
if (tracker->sprite)
|
||||
return COGL_TEXTURE (tracker->sprite->texture);
|
||||
else
|
||||
return NULL;
|
||||
return COGL_TEXTURE (tracker->sprite);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -766,34 +304,32 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
if (!meta_is_wayland_compositor ())
|
||||
ensure_xfixes_cursor (tracker);
|
||||
|
||||
if (tracker->sprite)
|
||||
{
|
||||
if (x)
|
||||
*x = tracker->sprite->hot_x;
|
||||
if (y)
|
||||
*y = tracker->sprite->hot_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x)
|
||||
*x = 0;
|
||||
if (y)
|
||||
*y = 0;
|
||||
}
|
||||
if (x)
|
||||
*x = tracker->hot_x;
|
||||
if (y)
|
||||
*y = tracker->hot_y;
|
||||
}
|
||||
|
||||
static MetaCursorReference *
|
||||
ensure_wayland_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursor cursor)
|
||||
static void
|
||||
ensure_wayland_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
if (tracker->default_cursors[cursor])
|
||||
return tracker->default_cursors[cursor];
|
||||
CoglBitmap *bitmap;
|
||||
char *filename;
|
||||
|
||||
tracker->default_cursors[cursor] = meta_cursor_reference_from_theme (tracker, cursor);
|
||||
if (!tracker->default_cursors[cursor])
|
||||
meta_warning ("Failed to load cursor from theme\n");
|
||||
if (tracker->default_cursor)
|
||||
return;
|
||||
|
||||
return tracker->default_cursors[cursor];
|
||||
filename = g_build_filename (MUTTER_PKGDATADIR,
|
||||
"cursors/left_ptr.png",
|
||||
NULL);
|
||||
|
||||
bitmap = cogl_bitmap_new_from_file (filename, NULL);
|
||||
tracker->default_cursor = cogl_texture_2d_new_from_bitmap (bitmap,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
NULL);
|
||||
|
||||
cogl_object_unref (bitmap);
|
||||
g_free (filename);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -813,115 +349,45 @@ meta_cursor_tracker_set_root_cursor (MetaCursorTracker *tracker,
|
||||
/* Now update the real root cursor */
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaCursorReference *ref;
|
||||
/* FIXME! We need to load all the other cursors too */
|
||||
ensure_wayland_cursor (tracker);
|
||||
|
||||
ref = ensure_wayland_cursor (tracker, cursor);
|
||||
|
||||
g_clear_pointer (&tracker->root_cursor, meta_cursor_reference_unref);
|
||||
tracker->root_cursor = meta_cursor_reference_ref (ref);
|
||||
g_clear_pointer (&tracker->root_cursor, cogl_object_unref);
|
||||
tracker->root_cursor = cogl_object_ref (tracker->default_cursor);
|
||||
tracker->root_hot_x = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_X;
|
||||
tracker->root_hot_y = META_WAYLAND_DEFAULT_CURSOR_HOTSPOT_Y;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_revert_root (MetaCursorTracker *tracker)
|
||||
{
|
||||
meta_cursor_tracker_set_sprite (tracker, tracker->root_cursor);
|
||||
}
|
||||
|
||||
static void
|
||||
update_hw_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaMonitorManager *monitors;
|
||||
MetaCRTC *crtcs;
|
||||
unsigned int i, n_crtcs;
|
||||
gboolean enabled;
|
||||
|
||||
enabled = tracker->has_cursor && tracker->sprite->bo != NULL;
|
||||
tracker->has_hw_cursor = enabled;
|
||||
|
||||
monitors = meta_monitor_manager_get ();
|
||||
meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
MetaRectangle *rect = &crtcs[i].rect;
|
||||
gboolean has;
|
||||
|
||||
has = enabled && meta_rectangle_overlap (&tracker->current_rect, rect);
|
||||
|
||||
if (has || crtcs[i].has_hw_cursor)
|
||||
meta_cursor_tracker_set_crtc_has_hw_cursor (tracker, &crtcs[i], has);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
move_hw_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaMonitorManager *monitors;
|
||||
MetaCRTC *crtcs;
|
||||
unsigned int i, n_crtcs;
|
||||
|
||||
monitors = meta_monitor_manager_get ();
|
||||
meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
|
||||
|
||||
g_assert (tracker->has_hw_cursor);
|
||||
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
MetaRectangle *rect = &crtcs[i].rect;
|
||||
gboolean has;
|
||||
|
||||
has = meta_rectangle_overlap (&tracker->current_rect, rect);
|
||||
|
||||
if (has != crtcs[i].has_hw_cursor)
|
||||
meta_cursor_tracker_set_crtc_has_hw_cursor (tracker, &crtcs[i], has);
|
||||
if (has)
|
||||
drmModeMoveCursor (tracker->drm_fd, crtcs[i].crtc_id,
|
||||
tracker->current_rect.x - rect->x,
|
||||
tracker->current_rect.y - rect->y);
|
||||
}
|
||||
meta_cursor_tracker_set_sprite (tracker,
|
||||
tracker->root_cursor,
|
||||
tracker->root_hot_x,
|
||||
tracker->root_hot_y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_buffer (MetaCursorTracker *tracker,
|
||||
struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
MetaCursorReference *new_cursor;
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
new_cursor = meta_cursor_reference_from_buffer (tracker, buffer, hot_x, hot_y);
|
||||
meta_cursor_tracker_set_sprite (tracker, new_cursor);
|
||||
meta_cursor_reference_unref (new_cursor);
|
||||
}
|
||||
else
|
||||
meta_cursor_tracker_set_sprite (tracker, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *sprite)
|
||||
meta_cursor_tracker_set_sprite (MetaCursorTracker *tracker,
|
||||
CoglTexture2D *sprite,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
if (sprite == tracker->sprite)
|
||||
return;
|
||||
|
||||
g_clear_pointer (&tracker->sprite, meta_cursor_reference_unref);
|
||||
g_clear_pointer (&tracker->sprite, cogl_object_unref);
|
||||
|
||||
if (sprite)
|
||||
{
|
||||
tracker->sprite = meta_cursor_reference_ref (sprite);
|
||||
cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (tracker->sprite->texture));
|
||||
tracker->sprite = cogl_object_ref (sprite);
|
||||
tracker->hot_x = hot_x;
|
||||
tracker->hot_y = hot_y;
|
||||
cogl_pipeline_set_layer_texture (tracker->pipeline, 0, COGL_TEXTURE (tracker->sprite));
|
||||
}
|
||||
else
|
||||
cogl_pipeline_set_layer_texture (tracker->pipeline, 0, NULL);
|
||||
|
||||
tracker->has_cursor = tracker->sprite != NULL && tracker->is_showing;
|
||||
update_hw_cursor (tracker);
|
||||
|
||||
g_signal_emit (tracker, signals[CURSOR_CHANGED], 0);
|
||||
|
||||
meta_cursor_tracker_update_position (tracker, tracker->current_x, tracker->current_y);
|
||||
@@ -936,24 +402,19 @@ meta_cursor_tracker_update_position (MetaCursorTracker *tracker,
|
||||
|
||||
tracker->current_x = new_x;
|
||||
tracker->current_y = new_y;
|
||||
tracker->current_rect.x = tracker->current_x - tracker->hot_x;
|
||||
tracker->current_rect.y = tracker->current_y - tracker->hot_y;
|
||||
|
||||
if (tracker->sprite)
|
||||
{
|
||||
tracker->current_rect.x = tracker->current_x - tracker->sprite->hot_x;
|
||||
tracker->current_rect.y = tracker->current_y - tracker->sprite->hot_y;
|
||||
tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (tracker->sprite->texture));
|
||||
tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (tracker->sprite->texture));
|
||||
tracker->current_rect.width = cogl_texture_get_width (COGL_TEXTURE (tracker->sprite));
|
||||
tracker->current_rect.height = cogl_texture_get_height (COGL_TEXTURE (tracker->sprite));
|
||||
}
|
||||
else
|
||||
{
|
||||
tracker->current_rect.x = 0;
|
||||
tracker->current_rect.y = 0;
|
||||
tracker->current_rect.width = 0;
|
||||
tracker->current_rect.height = 0;
|
||||
}
|
||||
|
||||
if (tracker->has_hw_cursor)
|
||||
move_hw_cursor (tracker);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -961,9 +422,10 @@ meta_cursor_tracker_paint (MetaCursorTracker *tracker)
|
||||
{
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
if (tracker->has_hw_cursor || !tracker->has_cursor)
|
||||
if (tracker->sprite == NULL)
|
||||
return;
|
||||
|
||||
/* FIXME: try to use a DRM cursor when possible */
|
||||
cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
|
||||
tracker->pipeline,
|
||||
tracker->current_rect.x,
|
||||
@@ -981,138 +443,16 @@ void
|
||||
meta_cursor_tracker_queue_redraw (MetaCursorTracker *tracker,
|
||||
ClutterActor *stage)
|
||||
{
|
||||
cairo_rectangle_int_t clip;
|
||||
|
||||
g_assert (meta_is_wayland_compositor ());
|
||||
|
||||
if (tracker->previous_is_valid)
|
||||
{
|
||||
cairo_rectangle_int_t clip = {
|
||||
.x = tracker->previous_rect.x,
|
||||
.y = tracker->previous_rect.y,
|
||||
.width = tracker->previous_rect.width,
|
||||
.height = tracker->previous_rect.height
|
||||
};
|
||||
clutter_actor_queue_redraw_with_clip (stage, &clip);
|
||||
clutter_actor_queue_redraw_with_clip (stage, &tracker->previous_rect);
|
||||
tracker->previous_is_valid = FALSE;
|
||||
}
|
||||
|
||||
if (tracker->has_hw_cursor || !tracker->has_cursor)
|
||||
if (tracker->sprite == NULL)
|
||||
return;
|
||||
|
||||
clip.x = tracker->current_rect.x;
|
||||
clip.y = tracker->current_rect.y;
|
||||
clip.width = tracker->current_rect.width;
|
||||
clip.height = tracker->current_rect.height;
|
||||
clutter_actor_queue_redraw_with_clip (stage, &clip);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_tracker_set_crtc_has_hw_cursor (MetaCursorTracker *tracker,
|
||||
MetaCRTC *crtc,
|
||||
gboolean has)
|
||||
{
|
||||
if (has)
|
||||
{
|
||||
union gbm_bo_handle handle;
|
||||
int width, height;
|
||||
int hot_x, hot_y;
|
||||
|
||||
handle = gbm_bo_get_handle (tracker->sprite->bo);
|
||||
width = gbm_bo_get_width (tracker->sprite->bo);
|
||||
height = gbm_bo_get_height (tracker->sprite->bo);
|
||||
hot_x = tracker->sprite->hot_x;
|
||||
hot_y = tracker->sprite->hot_y;
|
||||
|
||||
drmModeSetCursor2 (tracker->drm_fd, crtc->crtc_id, handle.u32,
|
||||
width, height, hot_x, hot_y);
|
||||
crtc->has_hw_cursor = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
drmModeSetCursor2 (tracker->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
|
||||
crtc->has_hw_cursor = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_pointer_position_gdk (int *x,
|
||||
int *y,
|
||||
int *mods)
|
||||
{
|
||||
GdkDeviceManager *gmanager;
|
||||
GdkDevice *gdevice;
|
||||
GdkScreen *gscreen;
|
||||
|
||||
gmanager = gdk_display_get_device_manager (gdk_display_get_default ());
|
||||
gdevice = gdk_device_manager_get_client_pointer (gmanager);
|
||||
|
||||
gdk_device_get_position (gdevice, &gscreen, x, y);
|
||||
gdk_device_get_state (gdevice,
|
||||
gdk_screen_get_root_window (gscreen),
|
||||
NULL, (GdkModifierType*)mods);
|
||||
}
|
||||
|
||||
static void
|
||||
get_pointer_position_clutter (int *x,
|
||||
int *y,
|
||||
int *mods)
|
||||
{
|
||||
ClutterDeviceManager *cmanager;
|
||||
ClutterInputDevice *cdevice;
|
||||
ClutterPoint point;
|
||||
|
||||
cmanager = clutter_device_manager_get_default ();
|
||||
cdevice = clutter_device_manager_get_core_device (cmanager, CLUTTER_POINTER_DEVICE);
|
||||
|
||||
clutter_input_device_get_coords (cdevice, NULL, &point);
|
||||
*x = point.x;
|
||||
*y = point.y;
|
||||
*mods = clutter_input_device_get_modifier_state (cdevice);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker,
|
||||
int *x,
|
||||
int *y,
|
||||
ClutterModifierType *mods)
|
||||
{
|
||||
/* We can't use the clutter interface when not running as a wayland compositor,
|
||||
because we need to query the server, rather than using the last cached value.
|
||||
OTOH, on wayland we can't use GDK, because that only sees the events
|
||||
we forward to xwayland.
|
||||
*/
|
||||
if (meta_is_wayland_compositor ())
|
||||
get_pointer_position_clutter (x, y, (int*)mods);
|
||||
else
|
||||
get_pointer_position_gdk (x, y, (int*)mods);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
|
||||
gboolean visible)
|
||||
{
|
||||
if (visible == tracker->is_showing)
|
||||
return;
|
||||
tracker->is_showing = visible;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
tracker->has_cursor = tracker->sprite != NULL && visible;
|
||||
update_hw_cursor (tracker);
|
||||
meta_cursor_tracker_queue_redraw (tracker, compositor->stage);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (visible)
|
||||
XFixesShowCursor (tracker->screen->display->xdisplay,
|
||||
tracker->screen->xroot);
|
||||
else
|
||||
XFixesHideCursor (tracker->screen->display->xdisplay,
|
||||
tracker->screen->xroot);
|
||||
}
|
||||
clutter_actor_queue_redraw_with_clip (stage, &tracker->current_rect);
|
||||
}
|
||||
|
||||
@@ -77,8 +77,7 @@ typedef struct
|
||||
guint64 timeout_msec;
|
||||
|
||||
/* x11 */
|
||||
XSyncAlarm xalarm;
|
||||
int idle_source_id;
|
||||
XSyncAlarm xalarm;
|
||||
|
||||
/* wayland */
|
||||
GSource *timeout_source;
|
||||
@@ -117,12 +116,6 @@ fire_watch (MetaIdleMonitorWatch *watch)
|
||||
monitor = watch->monitor;
|
||||
g_object_ref (monitor);
|
||||
|
||||
if (watch->idle_source_id)
|
||||
{
|
||||
g_source_remove (watch->idle_source_id);
|
||||
watch->idle_source_id = 0;
|
||||
}
|
||||
|
||||
id = watch->id;
|
||||
is_user_active_watch = (watch->timeout_msec == 0);
|
||||
|
||||
@@ -237,7 +230,7 @@ meta_idle_monitor_handle_xevent_all (XEvent *xevent)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= device_id_max; i++)
|
||||
for (i = 0; i < device_id_max; i++)
|
||||
if (device_monitors[i])
|
||||
meta_idle_monitor_handle_xevent (device_monitors[i], (XSyncAlarmNotifyEvent*)xevent);
|
||||
}
|
||||
@@ -293,13 +286,6 @@ idle_monitor_watch_free (MetaIdleMonitorWatch *watch)
|
||||
return;
|
||||
|
||||
monitor = watch->monitor;
|
||||
g_object_ref (monitor);
|
||||
|
||||
if (watch->idle_source_id)
|
||||
{
|
||||
g_source_remove (watch->idle_source_id);
|
||||
watch->idle_source_id = 0;
|
||||
}
|
||||
|
||||
if (watch->notify != NULL)
|
||||
watch->notify (watch->user_data);
|
||||
@@ -314,7 +300,6 @@ idle_monitor_watch_free (MetaIdleMonitorWatch *watch)
|
||||
if (watch->timeout_source != NULL)
|
||||
g_source_destroy (watch->timeout_source);
|
||||
|
||||
g_object_unref (monitor);
|
||||
g_slice_free (MetaIdleMonitorWatch, watch);
|
||||
}
|
||||
|
||||
@@ -495,17 +480,6 @@ static GSourceFuncs wayland_source_funcs = {
|
||||
NULL, /* finalize */
|
||||
};
|
||||
|
||||
static gboolean
|
||||
fire_watch_idle (gpointer data)
|
||||
{
|
||||
MetaIdleMonitorWatch *watch = data;
|
||||
|
||||
watch->idle_source_id = 0;
|
||||
fire_watch (watch);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static MetaIdleMonitorWatch *
|
||||
make_watch (MetaIdleMonitor *monitor,
|
||||
guint64 timeout_msec,
|
||||
@@ -544,9 +518,6 @@ make_watch (MetaIdleMonitor *monitor,
|
||||
watch->xalarm = _xsync_alarm_set (monitor, XSyncPositiveTransition, timeout_msec, TRUE);
|
||||
|
||||
g_hash_table_add (monitor->alarms, (gpointer) watch->xalarm);
|
||||
|
||||
if (meta_idle_monitor_get_idletime (monitor) > (gint64)timeout_msec)
|
||||
watch->idle_source_id = g_idle_add (fire_watch_idle, watch);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#define META_XRANDR_SHARED_H
|
||||
|
||||
typedef enum {
|
||||
META_POWER_SAVE_UNSUPPORTED = -1,
|
||||
META_POWER_SAVE_UNKNOWN = -1,
|
||||
META_POWER_SAVE_ON = 0,
|
||||
META_POWER_SAVE_STANDBY,
|
||||
META_POWER_SAVE_SUSPEND,
|
||||
|
||||
@@ -55,8 +55,6 @@ typedef struct {
|
||||
char *serial;
|
||||
} MetaOutputKey;
|
||||
|
||||
/* Keep this structure packed, so that we
|
||||
can use memcmp */
|
||||
typedef struct {
|
||||
gboolean enabled;
|
||||
MetaRectangle rect;
|
||||
@@ -149,13 +147,6 @@ output_key_equal (const MetaOutputKey *one,
|
||||
strcmp (one->serial, two->serial) == 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_config_equal (const MetaOutputConfig *one,
|
||||
const MetaOutputConfig *two)
|
||||
{
|
||||
return memcmp (one, two, sizeof (MetaOutputConfig)) == 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
config_hash (gconstpointer data)
|
||||
{
|
||||
@@ -189,30 +180,6 @@ config_equal (gconstpointer one,
|
||||
return ok;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
config_equal_full (gconstpointer one,
|
||||
gconstpointer two)
|
||||
{
|
||||
const MetaConfiguration *c_one = one;
|
||||
const MetaConfiguration *c_two = two;
|
||||
unsigned int i;
|
||||
gboolean ok;
|
||||
|
||||
if (c_one->n_outputs != c_two->n_outputs)
|
||||
return FALSE;
|
||||
|
||||
ok = TRUE;
|
||||
for (i = 0; i < c_one->n_outputs && ok; i++)
|
||||
{
|
||||
ok = output_key_equal (&c_one->keys[i],
|
||||
&c_two->keys[i]);
|
||||
ok = ok && output_config_equal (&c_one->outputs[i],
|
||||
&c_two->outputs[i]);
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_config_init (MetaMonitorConfig *self)
|
||||
{
|
||||
@@ -749,9 +716,6 @@ meta_monitor_config_load (MetaMonitorConfig *self)
|
||||
|
||||
free_output_key (&parser.key);
|
||||
}
|
||||
|
||||
g_markup_parse_context_free (context);
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
MetaMonitorConfig *
|
||||
@@ -914,8 +878,6 @@ make_laptop_lid_config (MetaConfiguration *reference)
|
||||
MetaConfiguration *new;
|
||||
unsigned int i;
|
||||
gboolean has_primary;
|
||||
int x_after, y_after;
|
||||
int x_offset, y_offset;
|
||||
|
||||
g_assert (reference->n_outputs > 1);
|
||||
|
||||
@@ -924,8 +886,6 @@ make_laptop_lid_config (MetaConfiguration *reference)
|
||||
new->keys = g_new0 (MetaOutputKey, reference->n_outputs);
|
||||
new->outputs = g_new0 (MetaOutputConfig, reference->n_outputs);
|
||||
|
||||
x_after = G_MAXINT; y_after = G_MAXINT;
|
||||
x_offset = 0; y_offset = 0;
|
||||
for (i = 0; i < new->n_outputs; i++)
|
||||
{
|
||||
MetaOutputKey *current_key = &reference->keys[i];
|
||||
@@ -938,26 +898,14 @@ make_laptop_lid_config (MetaConfiguration *reference)
|
||||
|
||||
if (g_str_has_prefix (current_key->connector, "LVDS") ||
|
||||
g_str_has_prefix (current_key->connector, "eDP"))
|
||||
{
|
||||
new->outputs[i].enabled = FALSE;
|
||||
x_after = current_output->rect.x;
|
||||
y_after = current_output->rect.y;
|
||||
x_offset = current_output->rect.width;
|
||||
y_offset = current_output->rect.height;
|
||||
}
|
||||
new->outputs[i].enabled = FALSE;
|
||||
else
|
||||
/* This can potentially leave a "hole" in the screen,
|
||||
but this is actually a good thing, as it means windows
|
||||
don't move around.
|
||||
*/
|
||||
new->outputs[i] = *current_output;
|
||||
}
|
||||
for (i = 0; i < new->n_outputs; i++)
|
||||
{
|
||||
if (new->outputs[i].enabled)
|
||||
{
|
||||
if (new->outputs[i].rect.x > x_after)
|
||||
new->outputs[i].rect.x -= x_offset;
|
||||
if (new->outputs[i].rect.y > y_after)
|
||||
new->outputs[i].rect.y -= y_offset;
|
||||
}
|
||||
}
|
||||
|
||||
has_primary = FALSE;
|
||||
for (i = 0; i < new->n_outputs; i++)
|
||||
@@ -1295,12 +1243,6 @@ meta_monitor_config_update_current (MetaMonitorConfig *self,
|
||||
init_config_from_output (¤t->outputs[i], &outputs[i]);
|
||||
}
|
||||
|
||||
if (self->current && config_equal_full (current, self->current))
|
||||
{
|
||||
config_free (current);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->current && !self->current_is_stored)
|
||||
config_free (self->current);
|
||||
|
||||
|
||||
@@ -1,939 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* 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: Giovanni Campagna <gcampagn@redhat.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#include <meta/main.h>
|
||||
#include <meta/errors.h>
|
||||
#include "monitor-private.h"
|
||||
#include "edid.h"
|
||||
|
||||
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
|
||||
typedef struct {
|
||||
drmModeConnector *connector;
|
||||
|
||||
unsigned n_encoders;
|
||||
drmModeEncoderPtr *encoders;
|
||||
drmModeEncoderPtr current_encoder;
|
||||
|
||||
/* bitmasks of encoder position in the resources array */
|
||||
uint32_t encoder_mask;
|
||||
uint32_t enc_clone_mask;
|
||||
|
||||
uint32_t dpms_prop_id;
|
||||
uint32_t edid_blob_id;
|
||||
} MetaOutputKms;
|
||||
|
||||
struct _MetaMonitorManagerKms
|
||||
{
|
||||
MetaMonitorManager parent_instance;
|
||||
|
||||
int fd;
|
||||
|
||||
drmModeConnector **connectors;
|
||||
unsigned int n_connectors;
|
||||
|
||||
drmModeEncoder **encoders;
|
||||
unsigned int n_encoders;
|
||||
|
||||
drmModeEncoder *current_encoder;
|
||||
};
|
||||
|
||||
struct _MetaMonitorManagerKmsClass
|
||||
{
|
||||
MetaMonitorManagerClass parent_class;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaMonitorManagerKms, meta_monitor_manager_kms, META_TYPE_MONITOR_MANAGER);
|
||||
|
||||
static void
|
||||
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);
|
||||
}
|
||||
|
||||
static int
|
||||
compare_outputs (const void *one,
|
||||
const void *two)
|
||||
{
|
||||
const MetaOutput *o_one = one, *o_two = two;
|
||||
|
||||
return strcmp (o_one->name, o_two->name);
|
||||
}
|
||||
|
||||
static char *
|
||||
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"
|
||||
};
|
||||
const char *connector_type_name;
|
||||
|
||||
if (connector->connector_type >= 0 &&
|
||||
connector->connector_type < G_N_ELEMENTS (connector_type_names))
|
||||
connector_type_name = connector_type_names[connector->connector_type];
|
||||
else
|
||||
connector_type_name = "unknown";
|
||||
|
||||
return g_strdup_printf ("%s%d", connector_type_name, connector->connector_id);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_output_destroy_notify (MetaOutput *output)
|
||||
{
|
||||
MetaOutputKms *output_kms;
|
||||
unsigned i;
|
||||
|
||||
output_kms = output->driver_private;
|
||||
|
||||
for (i = 0; i < output_kms->n_encoders; i++)
|
||||
drmModeFreeEncoder (output_kms->encoders[i]);
|
||||
g_free (output_kms->encoders);
|
||||
|
||||
g_slice_free (MetaOutputKms, output_kms);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_mode_destroy_notify (MetaMonitorMode *output)
|
||||
{
|
||||
g_slice_free (drmModeModeInfo, output->driver_private);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
drm_mode_equal (gconstpointer one,
|
||||
gconstpointer two)
|
||||
{
|
||||
const drmModeModeInfo *m_one = one;
|
||||
const drmModeModeInfo *m_two = two;
|
||||
|
||||
return m_one->clock == m_two->clock &&
|
||||
m_one->hdisplay == m_two->hdisplay &&
|
||||
m_one->hsync_start == m_two->hsync_start &&
|
||||
m_one->hsync_end == m_two->hsync_end &&
|
||||
m_one->htotal == m_two->htotal &&
|
||||
m_one->hskew == m_two->hskew &&
|
||||
m_one->vdisplay == m_two->vdisplay &&
|
||||
m_one->vsync_start == m_two->vsync_start &&
|
||||
m_one->vsync_end == m_two->vsync_end &&
|
||||
m_one->vtotal == m_two->vtotal &&
|
||||
m_one->vscan == m_two->vscan &&
|
||||
m_one->vrefresh == m_two->vrefresh &&
|
||||
m_one->flags == m_two->flags &&
|
||||
m_one->type == m_two->type &&
|
||||
strncmp (m_one->name, m_two->name, DRM_DISPLAY_MODE_LEN) == 0;
|
||||
}
|
||||
|
||||
static guint
|
||||
drm_mode_hash (gconstpointer ptr)
|
||||
{
|
||||
const drmModeModeInfo *mode = ptr;
|
||||
guint hash = 0;
|
||||
|
||||
/* We don't include the name in the hash because it's generally
|
||||
derived from the other fields (hdisplay, vdisplay and flags)
|
||||
*/
|
||||
|
||||
hash ^= mode->clock;
|
||||
hash ^= mode->hdisplay ^ mode->hsync_start ^ mode->hsync_end;
|
||||
hash ^= mode->vdisplay ^ mode->vsync_start ^ mode->vsync_end;
|
||||
hash ^= mode->vrefresh;
|
||||
hash ^= mode->flags ^ mode->type;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void
|
||||
find_properties (MetaMonitorManagerKms *manager_kms,
|
||||
MetaOutputKms *output_kms)
|
||||
{
|
||||
drmModePropertyPtr prop;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < output_kms->connector->count_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)
|
||||
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];
|
||||
|
||||
drmModeFreeProperty(prop);
|
||||
}
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
read_output_edid (MetaMonitorManagerKms *manager_kms,
|
||||
MetaOutput *output)
|
||||
{
|
||||
MetaOutputKms *output_kms = output->driver_private;
|
||||
drmModePropertyBlobPtr edid_blob = NULL;
|
||||
|
||||
if (output_kms->edid_blob_id == 0)
|
||||
return NULL;
|
||||
|
||||
edid_blob = drmModeGetPropertyBlob (manager_kms->fd, output_kms->edid_blob_id);
|
||||
if (!edid_blob)
|
||||
{
|
||||
meta_warning ("Failed to read EDID of output %s: %s\n", output->name, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (edid_blob->length > 0)
|
||||
return g_bytes_new_with_free_func (edid_blob->data, edid_blob->length,
|
||||
(GDestroyNotify)drmModeFreePropertyBlob, edid_blob);
|
||||
else
|
||||
{
|
||||
drmModeFreePropertyBlob (edid_blob);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static MetaMonitorMode *
|
||||
find_meta_mode (MetaMonitorManager *manager,
|
||||
const drmModeModeInfo *drm_mode)
|
||||
{
|
||||
unsigned k;
|
||||
|
||||
for (k = 0; k < manager->n_modes; k++)
|
||||
{
|
||||
if (drm_mode_equal (drm_mode, manager->modes[k].driver_private))
|
||||
return &manager->modes[k];
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static MetaOutput *
|
||||
find_output_by_id (MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
glong id)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
if (outputs[i].output_id == id)
|
||||
return &outputs[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
drmModeRes *resources;
|
||||
GHashTable *modes;
|
||||
GHashTableIter iter;
|
||||
drmModeModeInfo *mode;
|
||||
unsigned int i, j, k;
|
||||
unsigned int n_actual_outputs;
|
||||
int width, height;
|
||||
MetaOutput *old_outputs;
|
||||
unsigned int n_old_outputs;
|
||||
|
||||
resources = drmModeGetResources(manager_kms->fd);
|
||||
modes = g_hash_table_new (drm_mode_hash, drm_mode_equal);
|
||||
|
||||
manager->max_screen_width = resources->max_width;
|
||||
manager->max_screen_height = resources->max_height;
|
||||
|
||||
manager->power_save_mode = META_POWER_SAVE_ON;
|
||||
|
||||
old_outputs = manager->outputs;
|
||||
n_old_outputs = manager->n_outputs;
|
||||
|
||||
/* Note: we must not free the public structures (output, crtc, monitor
|
||||
mode and monitor info) here, they must be kept alive until the API
|
||||
users are done with them after we emit monitors-changed, and thus
|
||||
are freed by the platform-independent layer. */
|
||||
free_resources (manager_kms);
|
||||
|
||||
manager_kms->n_connectors = resources->count_connectors;
|
||||
manager_kms->connectors = g_new (drmModeConnector *, manager_kms->n_connectors);
|
||||
for (i = 0; i < manager_kms->n_connectors; i++)
|
||||
{
|
||||
drmModeConnector *connector;
|
||||
|
||||
connector = drmModeGetConnector (manager_kms->fd, resources->connectors[i]);
|
||||
manager_kms->connectors[i] = connector;
|
||||
|
||||
if (connector->connection == DRM_MODE_CONNECTED)
|
||||
{
|
||||
/* Collect all modes for this connector */
|
||||
for (j = 0; j < (unsigned)connector->count_modes; j++)
|
||||
g_hash_table_add (modes, &connector->modes[j]);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
g_hash_table_iter_init (&iter, modes);
|
||||
i = 0;
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer)&mode))
|
||||
{
|
||||
MetaMonitorMode *meta_mode;
|
||||
|
||||
meta_mode = &manager->modes[i];
|
||||
|
||||
meta_mode->mode_id = i;
|
||||
meta_mode->name = g_strndup (mode->name, DRM_DISPLAY_MODE_LEN);
|
||||
meta_mode->width = mode->hdisplay;
|
||||
meta_mode->height = mode->vdisplay;
|
||||
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;
|
||||
|
||||
i++;
|
||||
}
|
||||
g_hash_table_destroy (modes);
|
||||
|
||||
manager->n_crtcs = resources->count_crtcs;
|
||||
manager->crtcs = g_new0 (MetaCRTC, manager->n_crtcs);
|
||||
width = 0; height = 0;
|
||||
for (i = 0; i < (unsigned)resources->count_crtcs; i++)
|
||||
{
|
||||
drmModeCrtc *crtc;
|
||||
MetaCRTC *meta_crtc;
|
||||
|
||||
crtc = drmModeGetCrtc (manager_kms->fd, resources->crtcs[i]);
|
||||
|
||||
meta_crtc = &manager->crtcs[i];
|
||||
|
||||
meta_crtc->crtc_id = crtc->crtc_id;
|
||||
meta_crtc->rect.x = crtc->x;
|
||||
meta_crtc->rect.y = crtc->y;
|
||||
meta_crtc->rect.width = crtc->width;
|
||||
meta_crtc->rect.height = crtc->height;
|
||||
meta_crtc->is_dirty = FALSE;
|
||||
meta_crtc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
/* FIXME: implement! */
|
||||
meta_crtc->all_transforms = 1 << WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
|
||||
if (crtc->mode_valid)
|
||||
{
|
||||
for (j = 0; j < manager->n_modes; j++)
|
||||
{
|
||||
if (drm_mode_equal (&crtc->mode, manager->modes[j].driver_private))
|
||||
{
|
||||
meta_crtc->current_mode = &manager->modes[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
width = MAX (width, meta_crtc->rect.x + meta_crtc->rect.width);
|
||||
height = MAX (height, meta_crtc->rect.y + meta_crtc->rect.height);
|
||||
}
|
||||
|
||||
drmModeFreeCrtc (crtc);
|
||||
}
|
||||
|
||||
manager->screen_width = width;
|
||||
manager->screen_height = height;
|
||||
|
||||
manager->outputs = g_new0 (MetaOutput, manager_kms->n_connectors);
|
||||
n_actual_outputs = 0;
|
||||
|
||||
for (i = 0; i < manager_kms->n_connectors; i++)
|
||||
{
|
||||
MetaOutput *meta_output, *old_output;
|
||||
MetaOutputKms *output_kms;
|
||||
drmModeConnector *connector;
|
||||
GArray *crtcs;
|
||||
unsigned int crtc_mask;
|
||||
GBytes *edid;
|
||||
|
||||
connector = manager_kms->connectors[i];
|
||||
meta_output = &manager->outputs[n_actual_outputs];
|
||||
|
||||
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;
|
||||
|
||||
meta_output->output_id = connector->connector_id;
|
||||
meta_output->name = make_output_name (connector);
|
||||
meta_output->width_mm = connector->mmWidth;
|
||||
meta_output->height_mm = connector->mmHeight;
|
||||
|
||||
switch (connector->subpixel)
|
||||
{
|
||||
case DRM_MODE_SUBPIXEL_NONE:
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_NONE;
|
||||
break;
|
||||
case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_RGB;
|
||||
break;
|
||||
case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_HORIZONTAL_BGR;
|
||||
break;
|
||||
case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_VERTICAL_RGB;
|
||||
break;
|
||||
case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_VERTICAL_BGR;
|
||||
break;
|
||||
case DRM_MODE_SUBPIXEL_UNKNOWN:
|
||||
default:
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
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++)
|
||||
meta_output->modes[j] = find_meta_mode (manager, &connector->modes[j]);
|
||||
meta_output->preferred_mode = meta_output->modes[0];
|
||||
|
||||
output_kms->connector = connector;
|
||||
output_kms->n_encoders = connector->count_encoders;
|
||||
output_kms->encoders = g_new0 (drmModeEncoderPtr, output_kms->n_encoders);
|
||||
|
||||
crtc_mask = ~(unsigned int)0;
|
||||
for (j = 0; j < output_kms->n_encoders; j++)
|
||||
{
|
||||
output_kms->encoders[j] = drmModeGetEncoder (manager_kms->fd, connector->encoders[j]);
|
||||
|
||||
/* We only list CRTCs as supported if they are supported by all encoders
|
||||
for this connectors.
|
||||
|
||||
This is what xf86-video-modesetting does (see drmmode_output_init())
|
||||
*/
|
||||
crtc_mask &= output_kms->encoders[j]->possible_crtcs;
|
||||
|
||||
if (output_kms->encoders[j]->encoder_id == connector->encoder_id)
|
||||
output_kms->current_encoder = output_kms->encoders[j];
|
||||
}
|
||||
|
||||
crtcs = g_array_new (FALSE, FALSE, sizeof (MetaCRTC*));
|
||||
|
||||
for (j = 0; j < manager->n_crtcs; j++)
|
||||
{
|
||||
if (crtc_mask & (1 << j))
|
||||
{
|
||||
MetaCRTC *crtc = &manager->crtcs[j];
|
||||
g_array_append_val (crtcs, crtc);
|
||||
}
|
||||
}
|
||||
|
||||
meta_output->n_possible_crtcs = crtcs->len;
|
||||
meta_output->possible_crtcs = (void*)g_array_free (crtcs, FALSE);
|
||||
|
||||
if (output_kms->current_encoder && output_kms->current_encoder->crtc_id != 0)
|
||||
{
|
||||
for (j = 0; j < manager->n_crtcs; j++)
|
||||
{
|
||||
if (manager->crtcs[j].crtc_id == output_kms->current_encoder->crtc_id)
|
||||
{
|
||||
meta_output->crtc = &manager->crtcs[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
meta_output->crtc = NULL;
|
||||
|
||||
old_output = find_output_by_id (old_outputs, n_old_outputs,
|
||||
meta_output->output_id);
|
||||
if (old_output)
|
||||
{
|
||||
meta_output->is_primary = old_output->is_primary;
|
||||
meta_output->is_presentation = old_output->is_presentation;
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_output->is_primary = FALSE;
|
||||
meta_output->is_presentation = FALSE;
|
||||
}
|
||||
|
||||
find_properties (manager_kms, output_kms);
|
||||
|
||||
edid = read_output_edid (manager_kms, meta_output);
|
||||
if (edid)
|
||||
{
|
||||
MonitorInfo *parsed_edid;
|
||||
gsize len;
|
||||
|
||||
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);
|
||||
|
||||
g_free (parsed_edid);
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
For example, xf86-video-intel has a list of paths to probe in /sys/class/backlight
|
||||
(one for each major HW maker, and then some).
|
||||
We can't do the same because we're not root.
|
||||
It might be best to leave backlight out of the story and rely on the setuid
|
||||
helper in gnome-settings-daemon.
|
||||
*/
|
||||
meta_output->backlight_min = 0;
|
||||
meta_output->backlight_max = 0;
|
||||
meta_output->backlight = -1;
|
||||
|
||||
n_actual_outputs++;
|
||||
}
|
||||
}
|
||||
|
||||
manager->n_outputs = n_actual_outputs;
|
||||
manager->outputs = g_renew (MetaOutput, manager->outputs, manager->n_outputs);
|
||||
|
||||
/* Sort the outputs for easier handling in MetaMonitorConfig */
|
||||
qsort (manager->outputs, manager->n_outputs, sizeof (MetaOutput), compare_outputs);
|
||||
|
||||
/* Now fix the clones.
|
||||
Code mostly inspired by xf86-video-modesetting. */
|
||||
|
||||
/* XXX: intel hardware doesn't usually have clones, but I only have laptops with
|
||||
intel cards, so this code was never tested! */
|
||||
for (i = 0; i < manager->n_outputs; i++)
|
||||
{
|
||||
MetaOutput *meta_output;
|
||||
MetaOutputKms *output_kms;
|
||||
|
||||
meta_output = &manager->outputs[i];
|
||||
output_kms = meta_output->driver_private;
|
||||
|
||||
output_kms->enc_clone_mask = 0xff;
|
||||
output_kms->encoder_mask = 0;
|
||||
|
||||
for (j = 0; j < output_kms->n_encoders; j++)
|
||||
{
|
||||
for (k = 0; k < manager_kms->n_encoders; k++)
|
||||
{
|
||||
if (output_kms->encoders[j]->encoder_id == manager_kms->encoders[k]->encoder_id)
|
||||
{
|
||||
output_kms->encoder_mask |= (1 << k);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
output_kms->enc_clone_mask &= output_kms->encoders[j]->possible_clones;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < manager->n_outputs; i++)
|
||||
{
|
||||
MetaOutput *meta_output;
|
||||
MetaOutputKms *output_kms;
|
||||
|
||||
meta_output = &manager->outputs[i];
|
||||
output_kms = meta_output->driver_private;
|
||||
|
||||
if (output_kms->enc_clone_mask == 0)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < manager->n_outputs; j++)
|
||||
{
|
||||
MetaOutput *meta_clone;
|
||||
MetaOutputKms *clone_kms;
|
||||
|
||||
meta_clone = &manager->outputs[i];
|
||||
clone_kms = meta_clone->driver_private;
|
||||
|
||||
if (meta_clone == meta_output)
|
||||
continue;
|
||||
|
||||
if (clone_kms->encoder_mask == 0)
|
||||
continue;
|
||||
|
||||
if (clone_kms->encoder_mask == output_kms->enc_clone_mask)
|
||||
{
|
||||
meta_output->n_possible_clones++;
|
||||
meta_output->possible_clones = g_renew (MetaOutput *,
|
||||
meta_output->possible_clones,
|
||||
meta_output->n_possible_clones);
|
||||
meta_output->possible_clones[meta_output->n_possible_clones - 1] = meta_clone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drmModeFreeResources (resources);
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
meta_monitor_manager_kms_read_edid (MetaMonitorManager *manager,
|
||||
MetaOutput *output)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
|
||||
return read_output_edid (manager_kms, output);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
MetaPowerSave mode)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
uint64_t state;
|
||||
unsigned i;
|
||||
|
||||
switch (mode) {
|
||||
case META_POWER_SAVE_ON:
|
||||
state = DRM_MODE_DPMS_ON;
|
||||
break;
|
||||
case META_POWER_SAVE_STANDBY:
|
||||
state = DRM_MODE_DPMS_STANDBY;
|
||||
break;
|
||||
case META_POWER_SAVE_SUSPEND:
|
||||
state = DRM_MODE_DPMS_SUSPEND;
|
||||
break;
|
||||
case META_POWER_SAVE_OFF:
|
||||
state = DRM_MODE_DPMS_SUSPEND;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < manager->n_outputs; i++)
|
||||
{
|
||||
MetaOutput *meta_output;
|
||||
MetaOutputKms *output_kms;
|
||||
|
||||
meta_output = &manager->outputs[i];
|
||||
output_kms = meta_output->driver_private;
|
||||
|
||||
if (output_kms->dpms_prop_id != 0)
|
||||
{
|
||||
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->output_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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
crtc_free (CoglKmsCrtc *crtc)
|
||||
{
|
||||
g_free (crtc->connectors);
|
||||
g_slice_free (CoglKmsCrtc, crtc);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
MetaCRTCInfo **crtcs,
|
||||
unsigned int n_crtcs,
|
||||
MetaOutputInfo **outputs,
|
||||
unsigned int n_outputs)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
CoglDisplay *cogl_display;
|
||||
unsigned i;
|
||||
GPtrArray *cogl_crtcs;
|
||||
int screen_width, screen_height;
|
||||
gboolean ok;
|
||||
GError *error;
|
||||
|
||||
cogl_crtcs = g_ptr_array_new_full (manager->n_crtcs, (GDestroyNotify)crtc_free);
|
||||
screen_width = 0; screen_height = 0;
|
||||
for (i = 0; i < n_crtcs; i++)
|
||||
{
|
||||
MetaCRTCInfo *crtc_info = crtcs[i];
|
||||
MetaCRTC *crtc = crtc_info->crtc;
|
||||
CoglKmsCrtc *cogl_crtc;
|
||||
|
||||
crtc->is_dirty = TRUE;
|
||||
|
||||
cogl_crtc = g_slice_new0 (CoglKmsCrtc);
|
||||
g_ptr_array_add (cogl_crtcs, cogl_crtc);
|
||||
|
||||
if (crtc_info->mode == NULL)
|
||||
{
|
||||
cogl_crtc->id = crtc->crtc_id;
|
||||
cogl_crtc->x = 0;
|
||||
cogl_crtc->y = 0;
|
||||
cogl_crtc->count = 0;
|
||||
memset (&cogl_crtc->mode, 0, sizeof (drmModeModeInfo));
|
||||
cogl_crtc->connectors = NULL;
|
||||
cogl_crtc->count = 0;
|
||||
|
||||
crtc->rect.x = 0;
|
||||
crtc->rect.y = 0;
|
||||
crtc->rect.width = 0;
|
||||
crtc->rect.height = 0;
|
||||
crtc->current_mode = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaMonitorMode *mode;
|
||||
uint32_t *connectors;
|
||||
unsigned int j, n_connectors;
|
||||
int width, height;
|
||||
|
||||
mode = crtc_info->mode;
|
||||
|
||||
cogl_crtc->id = crtc->crtc_id;
|
||||
cogl_crtc->x = crtc_info->x;
|
||||
cogl_crtc->y = crtc_info->y;
|
||||
cogl_crtc->count = n_connectors = crtc_info->outputs->len;
|
||||
cogl_crtc->connectors = connectors = g_new (uint32_t, n_connectors);
|
||||
|
||||
for (j = 0; j < n_connectors; j++)
|
||||
{
|
||||
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
|
||||
|
||||
connectors[j] = output->output_id;
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
}
|
||||
|
||||
memcpy (&cogl_crtc->mode, crtc_info->mode->driver_private,
|
||||
sizeof (drmModeModeInfo));
|
||||
|
||||
if (meta_monitor_transform_is_rotated (crtc_info->transform))
|
||||
{
|
||||
width = mode->height;
|
||||
height = mode->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
width = mode->width;
|
||||
height = mode->height;
|
||||
}
|
||||
|
||||
screen_width = MAX (screen_width, crtc_info->x + width);
|
||||
screen_height = MAX (screen_height, crtc_info->y + height);
|
||||
|
||||
crtc->rect.x = crtc_info->x;
|
||||
crtc->rect.y = crtc_info->y;
|
||||
crtc->rect.width = width;
|
||||
crtc->rect.height = height;
|
||||
crtc->current_mode = mode;
|
||||
crtc->transform = crtc_info->transform;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable CRTCs not mentioned in the list (they have is_dirty == FALSE,
|
||||
because they weren't seen in the first loop) */
|
||||
for (i = 0; i < manager->n_crtcs; i++)
|
||||
{
|
||||
MetaCRTC *crtc = &manager->crtcs[i];
|
||||
CoglKmsCrtc *cogl_crtc;
|
||||
|
||||
crtc->logical_monitor = NULL;
|
||||
|
||||
if (crtc->is_dirty)
|
||||
{
|
||||
crtc->is_dirty = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
cogl_crtc = g_slice_new0 (CoglKmsCrtc);
|
||||
g_ptr_array_add (cogl_crtcs, cogl_crtc);
|
||||
|
||||
cogl_crtc->id = crtc->crtc_id;
|
||||
cogl_crtc->x = 0;
|
||||
cogl_crtc->y = 0;
|
||||
cogl_crtc->count = 0;
|
||||
memset (&cogl_crtc->mode, 0, sizeof (drmModeModeInfo));
|
||||
cogl_crtc->connectors = NULL;
|
||||
cogl_crtc->count = 0;
|
||||
|
||||
crtc->rect.x = 0;
|
||||
crtc->rect.y = 0;
|
||||
crtc->rect.width = 0;
|
||||
crtc->rect.height = 0;
|
||||
crtc->current_mode = NULL;
|
||||
}
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
cogl_display = cogl_context_get_display (cogl_context);
|
||||
|
||||
error = NULL;
|
||||
ok = cogl_kms_display_set_layout (cogl_display, screen_width, screen_height,
|
||||
(CoglKmsCrtc**)cogl_crtcs->pdata, cogl_crtcs->len, &error);
|
||||
g_ptr_array_unref (cogl_crtcs);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
meta_warning ("Applying display configuration failed: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
MetaOutputInfo *output_info = outputs[i];
|
||||
MetaOutput *output = output_info->output;
|
||||
|
||||
output->is_primary = output_info->is_primary;
|
||||
output->is_presentation = output_info->is_presentation;
|
||||
}
|
||||
|
||||
/* Disable outputs not mentioned in the list */
|
||||
for (i = 0; i < manager->n_outputs; i++)
|
||||
{
|
||||
MetaOutput *output = &manager->outputs[i];
|
||||
|
||||
if (output->is_dirty)
|
||||
{
|
||||
output->is_dirty = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
output->crtc = NULL;
|
||||
output->is_primary = FALSE;
|
||||
}
|
||||
|
||||
manager->screen_width = screen_width;
|
||||
manager->screen_height = screen_height;
|
||||
|
||||
meta_monitor_manager_rebuild_derived (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_get_crtc_gamma (MetaMonitorManager *manager,
|
||||
MetaCRTC *crtc,
|
||||
gsize *size,
|
||||
unsigned short **red,
|
||||
unsigned short **green,
|
||||
unsigned short **blue)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
drmModeCrtc *kms_crtc;
|
||||
|
||||
kms_crtc = drmModeGetCrtc (manager_kms->fd, crtc->crtc_id);
|
||||
|
||||
*size = kms_crtc->gamma_size;
|
||||
*red = g_new (unsigned short, *size);
|
||||
*green = g_new (unsigned short, *size);
|
||||
*blue = g_new (unsigned short, *size);
|
||||
|
||||
drmModeCrtcGetGamma (manager_kms->fd, crtc->crtc_id, *size, *red, *green, *blue);
|
||||
|
||||
drmModeFreeCrtc (kms_crtc);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
MetaCRTC *crtc,
|
||||
gsize size,
|
||||
unsigned short *red,
|
||||
unsigned short *green,
|
||||
unsigned short *blue)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
|
||||
drmModeCrtcSetGamma (manager_kms->fd, crtc->crtc_id, size, red, green, blue);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
CoglDisplay *cogl_display;
|
||||
CoglRenderer *cogl_renderer;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
cogl_display = cogl_context_get_display (cogl_context);
|
||||
cogl_renderer = cogl_display_get_renderer (cogl_display);
|
||||
|
||||
manager_kms->fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_finalize (GObject *object)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
|
||||
|
||||
free_resources (manager_kms);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
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->finalize = meta_monitor_manager_kms_finalize;
|
||||
|
||||
manager_class->read_current = meta_monitor_manager_kms_read_current;
|
||||
manager_class->read_edid = meta_monitor_manager_kms_read_edid;
|
||||
manager_class->apply_configuration = meta_monitor_manager_kms_apply_configuration;
|
||||
manager_class->set_power_save_mode = meta_monitor_manager_kms_set_power_save_mode;
|
||||
manager_class->get_crtc_gamma = meta_monitor_manager_kms_get_crtc_gamma;
|
||||
manager_class->set_crtc_gamma = meta_monitor_manager_kms_set_crtc_gamma;
|
||||
}
|
||||
|
||||
@@ -116,9 +116,6 @@ struct _MetaOutput
|
||||
*/
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
};
|
||||
|
||||
struct _MetaCRTC
|
||||
@@ -136,23 +133,16 @@ struct _MetaCRTC
|
||||
|
||||
/* Used when changing configuration */
|
||||
gboolean is_dirty;
|
||||
|
||||
/* Updated by MetaCursorTracker */
|
||||
gboolean has_hw_cursor;
|
||||
};
|
||||
|
||||
struct _MetaMonitorMode
|
||||
{
|
||||
/* The low-level ID of this mode, used to apply back configuration */
|
||||
glong mode_id;
|
||||
char *name;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
float refresh_rate;
|
||||
|
||||
gpointer driver_private;
|
||||
GDestroyNotify driver_notify;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -311,8 +301,6 @@ GType meta_monitor_manager_get_type (void);
|
||||
void meta_monitor_manager_initialize (void);
|
||||
MetaMonitorManager *meta_monitor_manager_get (void);
|
||||
|
||||
void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager);
|
||||
|
||||
MetaMonitorInfo *meta_monitor_manager_get_monitor_infos (MetaMonitorManager *manager,
|
||||
unsigned int *n_infos);
|
||||
|
||||
@@ -361,18 +349,6 @@ typedef struct _MetaMonitorManagerXrandr MetaMonitorManagerXrandr;
|
||||
|
||||
GType meta_monitor_manager_xrandr_get_type (void);
|
||||
|
||||
#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))
|
||||
#define META_MONITOR_MANAGER_KMS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKmsClass))
|
||||
#define META_IS_MONITOR_MANAGER_KMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_MONITOR_MANAGER_KMS))
|
||||
#define META_IS_MONITOR_MANAGER_KMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_MONITOR_MANAGER_KMS))
|
||||
#define META_MONITOR_MANAGER_KMS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKmsClass))
|
||||
|
||||
typedef struct _MetaMonitorManagerKmsClass MetaMonitorManagerKmsClass;
|
||||
typedef struct _MetaMonitorManagerKms MetaMonitorManagerKms;
|
||||
|
||||
GType meta_monitor_manager_kms_get_type (void);
|
||||
|
||||
#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))
|
||||
#define META_MONITOR_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_MONITOR_CONFIG, MetaMonitorConfigClass))
|
||||
@@ -403,11 +379,6 @@ void meta_monitor_config_restore_previous (MetaMonitorConfig *con
|
||||
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);
|
||||
|
||||
/* Returns true if transform causes width and height to be inverted
|
||||
This is true for the odd transforms in the enum */
|
||||
static inline gboolean
|
||||
|
||||
@@ -351,13 +351,13 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
manager->power_save_mode = META_POWER_SAVE_OFF;
|
||||
break;
|
||||
default:
|
||||
manager->power_save_mode = META_POWER_SAVE_UNSUPPORTED;
|
||||
manager->power_save_mode = META_POWER_SAVE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
manager->power_save_mode = META_POWER_SAVE_UNSUPPORTED;
|
||||
manager->power_save_mode = META_POWER_SAVE_UNKNOWN;
|
||||
}
|
||||
|
||||
XRRGetScreenSizeRange (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay),
|
||||
@@ -974,58 +974,11 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
|
||||
XEvent *event)
|
||||
{
|
||||
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
|
||||
MetaOutput *old_outputs;
|
||||
MetaCRTC *old_crtcs;
|
||||
MetaMonitorMode *old_modes;
|
||||
unsigned int n_old_outputs, n_old_modes;
|
||||
|
||||
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
|
||||
return FALSE;
|
||||
|
||||
XRRUpdateConfiguration (event);
|
||||
|
||||
/* Save the old structures, so they stay valid during the update */
|
||||
old_outputs = manager->outputs;
|
||||
n_old_outputs = manager->n_outputs;
|
||||
old_modes = manager->modes;
|
||||
n_old_modes = manager->n_modes;
|
||||
old_crtcs = manager->crtcs;
|
||||
|
||||
manager->serial++;
|
||||
meta_monitor_manager_xrandr_read_current (manager);
|
||||
|
||||
/* Check if the current intended configuration has the same outputs
|
||||
as the new real one, or if the event is a result of an XRandR call.
|
||||
If so, we can go straight to rebuild the logical config and tell
|
||||
the outside world.
|
||||
Otherwise, this event was caused by hotplug, so give a chance to
|
||||
MetaMonitorConfig.
|
||||
|
||||
Note that we need to check both the timestamps and the list of
|
||||
outputs, because the X server might emit spurious events with
|
||||
new configTimestamps (bug 702804), and the driver may have
|
||||
changed the EDID for some other reason (old broken qxl and vbox
|
||||
drivers...).
|
||||
*/
|
||||
if (manager_xrandr->resources->timestamp >= manager_xrandr->resources->configTimestamp ||
|
||||
meta_monitor_config_match_current (manager->config, manager))
|
||||
{
|
||||
/* This will be a no-op if the change was from our side, as
|
||||
we already called it in the DBus method handler */
|
||||
meta_monitor_config_update_current (manager->config, manager);
|
||||
|
||||
meta_monitor_manager_rebuild_derived (manager);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!meta_monitor_config_apply_stored (manager->config, manager))
|
||||
meta_monitor_config_make_default (manager->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);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,9 @@
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <meta/main.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include <meta/errors.h>
|
||||
#include "monitor-private.h"
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
#include "meta-dbus-xrandr.h"
|
||||
|
||||
@@ -60,28 +59,67 @@ static void meta_monitor_manager_display_config_init (MetaDBusDisplayConfigIface
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaMonitorManager, meta_monitor_manager, META_DBUS_TYPE_DISPLAY_CONFIG_SKELETON,
|
||||
G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_DISPLAY_CONFIG, meta_monitor_manager_display_config_init));
|
||||
|
||||
static void free_output_array (MetaOutput *old_outputs,
|
||||
int n_old_outputs);
|
||||
static void invalidate_logical_config (MetaMonitorManager *manager);
|
||||
static void initialize_dbus_interface (MetaMonitorManager *manager);
|
||||
|
||||
static void
|
||||
read_current_dummy (MetaMonitorManager *manager)
|
||||
{
|
||||
/* The dummy monitor config has:
|
||||
- one enabled output, LVDS, primary, at 0x0 and 1024x768
|
||||
- one free CRTC
|
||||
- two disabled outputs
|
||||
- three modes, 1024x768, 800x600 and 640x480
|
||||
- no clones are possible (use different CRTCs)
|
||||
|
||||
Low-level IDs should be assigned sequentially, to
|
||||
mimick what XRandR and KMS do
|
||||
*/
|
||||
|
||||
manager->max_screen_width = 65535;
|
||||
manager->max_screen_height = 65535;
|
||||
manager->screen_width = 1024;
|
||||
manager->screen_height = 768;
|
||||
|
||||
manager->modes = g_new0 (MetaMonitorMode, 1);
|
||||
manager->n_modes = 1;
|
||||
manager->modes = g_new0 (MetaMonitorMode, 6);
|
||||
manager->n_modes = 6;
|
||||
|
||||
manager->modes[0].mode_id = 0;
|
||||
manager->modes[0].mode_id = 1;
|
||||
manager->modes[0].width = 1024;
|
||||
manager->modes[0].height = 768;
|
||||
manager->modes[0].refresh_rate = 60.0;
|
||||
|
||||
manager->crtcs = g_new0 (MetaCRTC, 1);
|
||||
manager->n_crtcs = 1;
|
||||
manager->modes[1].mode_id = 2;
|
||||
manager->modes[1].width = 800;
|
||||
manager->modes[1].height = 600;
|
||||
manager->modes[1].refresh_rate = 60.0;
|
||||
|
||||
manager->crtcs[0].crtc_id = 1;
|
||||
manager->modes[2].mode_id = 3;
|
||||
manager->modes[2].width = 640;
|
||||
manager->modes[2].height = 480;
|
||||
manager->modes[2].refresh_rate = 60.0;
|
||||
|
||||
manager->modes[3].mode_id = 4;
|
||||
manager->modes[3].width = 1920;
|
||||
manager->modes[3].height = 1080;
|
||||
manager->modes[3].refresh_rate = 60.0;
|
||||
|
||||
manager->modes[4].mode_id = 5;
|
||||
manager->modes[4].width = 1920;
|
||||
manager->modes[4].height = 1080;
|
||||
manager->modes[4].refresh_rate = 55.0;
|
||||
|
||||
manager->modes[5].mode_id = 6;
|
||||
manager->modes[5].width = 1600;
|
||||
manager->modes[5].height = 900;
|
||||
manager->modes[5].refresh_rate = 60.0;
|
||||
|
||||
manager->crtcs = g_new0 (MetaCRTC, 3);
|
||||
manager->n_crtcs = 3;
|
||||
|
||||
manager->crtcs[0].crtc_id = 4;
|
||||
manager->crtcs[0].rect.x = 0;
|
||||
manager->crtcs[0].rect.y = 0;
|
||||
manager->crtcs[0].rect.width = manager->modes[0].width;
|
||||
@@ -92,30 +130,111 @@ read_current_dummy (MetaMonitorManager *manager)
|
||||
manager->crtcs[0].is_dirty = FALSE;
|
||||
manager->crtcs[0].logical_monitor = NULL;
|
||||
|
||||
manager->outputs = g_new0 (MetaOutput, 1);
|
||||
manager->n_outputs = 1;
|
||||
manager->crtcs[1].crtc_id = 5;
|
||||
manager->crtcs[1].rect.x = 0;
|
||||
manager->crtcs[1].rect.y = 0;
|
||||
manager->crtcs[1].rect.width = 0;
|
||||
manager->crtcs[1].rect.height = 0;
|
||||
manager->crtcs[1].current_mode = NULL;
|
||||
manager->crtcs[1].transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
manager->crtcs[1].all_transforms = ALL_WL_TRANSFORMS;
|
||||
manager->crtcs[1].is_dirty = FALSE;
|
||||
manager->crtcs[1].logical_monitor = NULL;
|
||||
|
||||
manager->outputs[0].crtc = &manager->crtcs[0];
|
||||
manager->outputs[0].output_id = 1;
|
||||
manager->outputs[0].name = g_strdup ("LVDS");
|
||||
manager->crtcs[2].crtc_id = 5;
|
||||
manager->crtcs[2].rect.x = 0;
|
||||
manager->crtcs[2].rect.y = 0;
|
||||
manager->crtcs[2].rect.width = 0;
|
||||
manager->crtcs[2].rect.height = 0;
|
||||
manager->crtcs[2].current_mode = NULL;
|
||||
manager->crtcs[2].transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
manager->crtcs[2].all_transforms = ALL_WL_TRANSFORMS;
|
||||
manager->crtcs[2].is_dirty = FALSE;
|
||||
manager->crtcs[2].logical_monitor = NULL;
|
||||
|
||||
manager->outputs = g_new0 (MetaOutput, 3);
|
||||
manager->n_outputs = 3;
|
||||
|
||||
manager->outputs[0].crtc = NULL;
|
||||
manager->outputs[0].output_id = 6;
|
||||
manager->outputs[0].name = g_strdup ("HDMI");
|
||||
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].serial = g_strdup ("0xC0F01A");
|
||||
manager->outputs[0].width_mm = 510;
|
||||
manager->outputs[0].height_mm = 287;
|
||||
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].preferred_mode = &manager->modes[3];
|
||||
manager->outputs[0].n_modes = 5;
|
||||
manager->outputs[0].modes = g_new0 (MetaMonitorMode *, 5);
|
||||
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].modes[1] = &manager->modes[1];
|
||||
manager->outputs[0].modes[2] = &manager->modes[2];
|
||||
manager->outputs[0].modes[3] = &manager->modes[3];
|
||||
manager->outputs[0].modes[4] = &manager->modes[4];
|
||||
manager->outputs[0].n_possible_crtcs = 3;
|
||||
manager->outputs[0].possible_crtcs = g_new0 (MetaCRTC *, 3);
|
||||
manager->outputs[0].possible_crtcs[0] = &manager->crtcs[0];
|
||||
manager->outputs[0].possible_crtcs[1] = &manager->crtcs[1];
|
||||
manager->outputs[0].possible_crtcs[2] = &manager->crtcs[2];
|
||||
manager->outputs[0].n_possible_clones = 0;
|
||||
manager->outputs[0].possible_clones = g_new0 (MetaOutput *, 0);
|
||||
manager->outputs[0].backlight = -1;
|
||||
manager->outputs[0].backlight_min = 0;
|
||||
manager->outputs[0].backlight_max = 0;
|
||||
|
||||
manager->outputs[1].crtc = &manager->crtcs[0];
|
||||
manager->outputs[1].output_id = 7;
|
||||
manager->outputs[1].name = g_strdup ("LVDS");
|
||||
manager->outputs[1].vendor = g_strdup ("MetaProducts Inc.");
|
||||
manager->outputs[1].product = g_strdup ("unknown");
|
||||
manager->outputs[1].serial = g_strdup ("0xC0FFEE");
|
||||
manager->outputs[1].width_mm = 222;
|
||||
manager->outputs[1].height_mm = 125;
|
||||
manager->outputs[1].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
manager->outputs[1].preferred_mode = &manager->modes[5];
|
||||
manager->outputs[1].n_modes = 4;
|
||||
manager->outputs[1].modes = g_new0 (MetaMonitorMode *, 4);
|
||||
manager->outputs[1].modes[0] = &manager->modes[0];
|
||||
manager->outputs[1].modes[1] = &manager->modes[1];
|
||||
manager->outputs[1].modes[2] = &manager->modes[2];
|
||||
manager->outputs[1].modes[3] = &manager->modes[5];
|
||||
manager->outputs[1].n_possible_crtcs = 3;
|
||||
manager->outputs[1].possible_crtcs = g_new0 (MetaCRTC *, 3);
|
||||
manager->outputs[1].possible_crtcs[0] = &manager->crtcs[0];
|
||||
manager->outputs[1].possible_crtcs[1] = &manager->crtcs[1];
|
||||
manager->outputs[1].possible_crtcs[2] = &manager->crtcs[2];
|
||||
manager->outputs[1].n_possible_clones = 0;
|
||||
manager->outputs[1].possible_clones = g_new0 (MetaOutput *, 0);
|
||||
manager->outputs[1].backlight = -1;
|
||||
manager->outputs[1].backlight_min = 0;
|
||||
manager->outputs[1].backlight_max = 0;
|
||||
|
||||
manager->outputs[2].crtc = NULL;
|
||||
manager->outputs[2].output_id = 8;
|
||||
manager->outputs[2].name = g_strdup ("VGA");
|
||||
manager->outputs[2].vendor = g_strdup ("MetaProducts Inc.");
|
||||
manager->outputs[2].product = g_strdup ("unknown");
|
||||
manager->outputs[2].serial = g_strdup ("0xC4FE");
|
||||
manager->outputs[2].width_mm = 309;
|
||||
manager->outputs[2].height_mm = 174;
|
||||
manager->outputs[2].subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
manager->outputs[2].preferred_mode = &manager->modes[0];
|
||||
manager->outputs[2].n_modes = 3;
|
||||
manager->outputs[2].modes = g_new0 (MetaMonitorMode *, 3);
|
||||
manager->outputs[2].modes[0] = &manager->modes[0];
|
||||
manager->outputs[2].modes[1] = &manager->modes[1];
|
||||
manager->outputs[2].modes[2] = &manager->modes[2];
|
||||
manager->outputs[2].n_possible_crtcs = 3;
|
||||
manager->outputs[2].possible_crtcs = g_new0 (MetaCRTC *, 3);
|
||||
manager->outputs[2].possible_crtcs[0] = &manager->crtcs[0];
|
||||
manager->outputs[2].possible_crtcs[1] = &manager->crtcs[1];
|
||||
manager->outputs[2].possible_crtcs[2] = &manager->crtcs[2];
|
||||
manager->outputs[2].n_possible_clones = 0;
|
||||
manager->outputs[2].possible_clones = g_new0 (MetaOutput *, 0);
|
||||
manager->outputs[2].backlight = -1;
|
||||
manager->outputs[2].backlight_min = 0;
|
||||
manager->outputs[2].backlight_max = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -230,7 +349,7 @@ apply_config_dummy (MetaMonitorManager *manager,
|
||||
manager->screen_width = screen_width;
|
||||
manager->screen_height = screen_height;
|
||||
|
||||
meta_monitor_manager_rebuild_derived (manager);
|
||||
invalidate_logical_config (manager);
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
@@ -359,16 +478,7 @@ static GType
|
||||
get_default_backend (void)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaWaylandCompositor *compositor;
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
|
||||
if (meta_wayland_compositor_is_native (compositor))
|
||||
return META_TYPE_MONITOR_MANAGER_KMS;
|
||||
else
|
||||
return META_TYPE_MONITOR_MANAGER;
|
||||
}
|
||||
return META_TYPE_MONITOR_MANAGER; /* FIXME: KMS */
|
||||
else
|
||||
return META_TYPE_MONITOR_MANAGER_XRANDR;
|
||||
}
|
||||
@@ -417,18 +527,17 @@ meta_monitor_manager_constructed (GObject *object)
|
||||
MetaOutput *old_outputs;
|
||||
MetaCRTC *old_crtcs;
|
||||
MetaMonitorMode *old_modes;
|
||||
unsigned int n_old_outputs, n_old_modes;
|
||||
int n_old_outputs;
|
||||
|
||||
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);
|
||||
free_output_array (old_outputs, n_old_outputs);
|
||||
g_free (old_modes);
|
||||
g_free (old_crtcs);
|
||||
}
|
||||
|
||||
@@ -444,8 +553,11 @@ meta_monitor_manager_set_power_save_mode (MetaMonitorManager *manager,
|
||||
{
|
||||
MetaMonitorManagerClass *klass;
|
||||
|
||||
if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED ||
|
||||
mode == META_POWER_SAVE_UNSUPPORTED)
|
||||
if (mode == manager->power_save_mode)
|
||||
return;
|
||||
|
||||
if (manager->power_save_mode == META_POWER_SAVE_UNKNOWN ||
|
||||
mode == META_POWER_SAVE_UNKNOWN)
|
||||
return;
|
||||
|
||||
klass = META_MONITOR_MANAGER_GET_CLASS (manager);
|
||||
@@ -455,9 +567,9 @@ meta_monitor_manager_set_power_save_mode (MetaMonitorManager *manager,
|
||||
manager->power_save_mode = mode;
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
||||
int n_old_outputs)
|
||||
static void
|
||||
free_output_array (MetaOutput *old_outputs,
|
||||
int n_old_outputs)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -470,39 +582,19 @@ meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
||||
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_free_mode_array (MetaMonitorMode *old_modes,
|
||||
int n_old_modes)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_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);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_finalize (GObject *object)
|
||||
{
|
||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
|
||||
|
||||
meta_monitor_manager_free_output_array (manager->outputs, manager->n_outputs);
|
||||
meta_monitor_manager_free_mode_array (manager->modes, manager->n_modes);
|
||||
free_output_array (manager->outputs, manager->n_outputs);
|
||||
g_free (manager->monitor_infos);
|
||||
g_free (manager->modes);
|
||||
g_free (manager->crtcs);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->finalize (object);
|
||||
@@ -1361,21 +1453,12 @@ meta_monitor_manager_get_resources (MetaMonitorManager *manager,
|
||||
MetaOutput **outputs,
|
||||
unsigned int *n_outputs)
|
||||
{
|
||||
if (modes)
|
||||
{
|
||||
*modes = manager->modes;
|
||||
*n_modes = manager->n_modes;
|
||||
}
|
||||
if (crtcs)
|
||||
{
|
||||
*crtcs = manager->crtcs;
|
||||
*n_crtcs = manager->n_crtcs;
|
||||
}
|
||||
if (outputs)
|
||||
{
|
||||
*outputs = manager->outputs;
|
||||
*n_outputs = manager->n_outputs;
|
||||
}
|
||||
*modes = manager->modes;
|
||||
*n_modes = manager->n_modes;
|
||||
*crtcs = manager->crtcs;
|
||||
*n_crtcs = manager->n_crtcs;
|
||||
*outputs = manager->outputs;
|
||||
*n_outputs = manager->n_outputs;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1402,8 +1485,8 @@ meta_monitor_manager_get_screen_limits (MetaMonitorManager *manager,
|
||||
*height = manager->max_screen_height;
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
|
||||
static void
|
||||
invalidate_logical_config (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaMonitorInfo *old_monitor_infos;
|
||||
|
||||
@@ -1424,11 +1507,51 @@ meta_monitor_manager_handle_xevent (MetaMonitorManager *manager,
|
||||
XEvent *event)
|
||||
{
|
||||
MetaMonitorManagerClass *klass;
|
||||
MetaOutput *old_outputs;
|
||||
MetaCRTC *old_crtcs;
|
||||
MetaMonitorMode *old_modes;
|
||||
int n_old_outputs;
|
||||
gboolean changed;
|
||||
|
||||
klass = META_MONITOR_MANAGER_GET_CLASS (manager);
|
||||
if (klass->handle_xevent)
|
||||
return klass->handle_xevent (manager, event);
|
||||
changed = klass->handle_xevent (manager, event);
|
||||
else
|
||||
changed = FALSE;
|
||||
|
||||
if (!changed)
|
||||
return FALSE;
|
||||
|
||||
/* Save the old structures, so they stay valid during the update */
|
||||
old_outputs = manager->outputs;
|
||||
n_old_outputs = manager->n_outputs;
|
||||
old_modes = manager->modes;
|
||||
old_crtcs = manager->crtcs;
|
||||
|
||||
read_current_config (manager);
|
||||
|
||||
/* Check if the current intended configuration has the same outputs
|
||||
as the new real one. If so, this was a result of an ApplyConfiguration
|
||||
call (or a change from ourselves), and we can go straight to rebuild
|
||||
the logical config and tell the outside world.
|
||||
|
||||
Otherwise, this event was caused by hotplug, so give a chance to
|
||||
MetaMonitorConfig.
|
||||
*/
|
||||
if (meta_monitor_config_match_current (manager->config, manager))
|
||||
{
|
||||
invalidate_logical_config (manager);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!meta_monitor_config_apply_stored (manager->config, manager))
|
||||
meta_monitor_config_make_default (manager->config, manager);
|
||||
}
|
||||
|
||||
free_output_array (old_outputs, n_old_outputs);
|
||||
g_free (old_modes);
|
||||
g_free (old_crtcs);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
#include <meta/main.h>
|
||||
#include <meta/util.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include "meta-plugin-manager.h"
|
||||
|
||||
#include <glib.h>
|
||||
@@ -47,8 +46,15 @@ print_version (const gchar *option_name,
|
||||
}
|
||||
|
||||
static gchar *plugin = "default";
|
||||
static gboolean opt_nested = FALSE;
|
||||
|
||||
GOptionEntry mutter_options[] = {
|
||||
{
|
||||
"nested", 0, 0, G_OPTION_ARG_NONE,
|
||||
&opt_nested,
|
||||
N_("Run nested as an application for testing"),
|
||||
NULL,
|
||||
},
|
||||
{
|
||||
"version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
|
||||
print_version,
|
||||
@@ -78,6 +84,8 @@ main (int argc, char **argv)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
meta_set_is_wayland_compositor (opt_nested);
|
||||
|
||||
if (plugin)
|
||||
meta_plugin_manager_load (plugin);
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <config.h>
|
||||
#include <meta/prefs.h>
|
||||
#include "ui.h"
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include "meta-plugin-manager.h"
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
@@ -1199,8 +1199,8 @@ maybe_give_disable_workarounds_warning (void)
|
||||
{
|
||||
first_disable = FALSE;
|
||||
|
||||
meta_warning ("Workarounds for broken applications disabled. "
|
||||
"Some applications may not behave properly.\n");
|
||||
meta_warning (_("Workarounds for broken applications disabled. "
|
||||
"Some applications may not behave properly.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1274,8 +1274,8 @@ titlebar_handler (GVariant *value,
|
||||
|
||||
if (desc == NULL)
|
||||
{
|
||||
meta_warning ("Could not parse font description "
|
||||
"\"%s\" from GSettings key %s\n",
|
||||
meta_warning (_("Could not parse font description "
|
||||
"\"%s\" from GSettings key %s\n"),
|
||||
string_value ? string_value : "(null)",
|
||||
KEY_TITLEBAR_FONT);
|
||||
return FALSE;
|
||||
@@ -1340,8 +1340,8 @@ mouse_button_mods_handler (GVariant *value,
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Failed to parse new GSettings value\n");
|
||||
|
||||
meta_warning ("\"%s\" found in configuration database is "
|
||||
"not a valid value for mouse button modifier\n",
|
||||
meta_warning (_("\"%s\" found in configuration database is "
|
||||
"not a valid value for mouse button modifier\n"),
|
||||
string_value);
|
||||
|
||||
return FALSE;
|
||||
@@ -1906,7 +1906,7 @@ update_binding (MetaKeyPref *binding,
|
||||
{
|
||||
meta_topic (META_DEBUG_KEYBINDINGS,
|
||||
"Failed to parse new GSettings value\n");
|
||||
meta_warning ("\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n",
|
||||
meta_warning (_("\"%s\" found in configuration database is not a valid value for keybinding \"%s\"\n"),
|
||||
strokes[i], binding->name);
|
||||
|
||||
/* Value is kept and will thus be removed next time we save the key.
|
||||
|
||||
@@ -151,6 +151,8 @@ void meta_screen_foreach_window (MetaScreen *scree
|
||||
MetaScreenWindowFunc func,
|
||||
gpointer data);
|
||||
|
||||
void meta_screen_set_cursor (MetaScreen *screen,
|
||||
MetaCursor cursor);
|
||||
void meta_screen_update_cursor (MetaScreen *screen);
|
||||
|
||||
void meta_screen_tab_popup_create (MetaScreen *screen,
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <config.h>
|
||||
#include "screen-private.h"
|
||||
#include <meta/main.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include <meta/errors.h>
|
||||
#include "window-private.h"
|
||||
#include "frame.h"
|
||||
@@ -579,7 +579,7 @@ meta_screen_new (MetaDisplay *display,
|
||||
|
||||
if (XGetSelectionOwner (xdisplay, wm_sn_atom) != new_wm_sn_owner)
|
||||
{
|
||||
meta_warning ("Could not acquire window manager selection on screen %d display \"%s\"\n",
|
||||
meta_warning (_("Could not acquire window manager selection on screen %d display \"%s\"\n"),
|
||||
number, display->name);
|
||||
|
||||
XDestroyWindow (xdisplay, new_wm_sn_owner);
|
||||
@@ -850,7 +850,7 @@ meta_screen_free (MetaScreen *screen,
|
||||
meta_error_trap_push_with_return (screen->display);
|
||||
XSelectInput (screen->display->xdisplay, screen->xroot, 0);
|
||||
if (meta_error_trap_pop_with_return (screen->display) != Success)
|
||||
meta_warning ("Could not release screen %d on display \"%s\"\n",
|
||||
meta_warning (_("Could not release screen %d on display \"%s\"\n"),
|
||||
screen->number, screen->display->name);
|
||||
|
||||
unset_wm_check_hint (screen);
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "util-private.h"
|
||||
#include <meta/main.h>
|
||||
#include "session.h"
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
@@ -533,12 +531,6 @@ die_callback (SmcConn smc_conn, SmPointer client_data)
|
||||
* Anything that wants us to go away outside of session management
|
||||
* can use kill().
|
||||
*/
|
||||
|
||||
/* All of that is true - unless we're a wayland compositor. In which
|
||||
* case the X server won't go down until we do, so we must die first.
|
||||
*/
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_quit (0);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -848,14 +840,14 @@ save_state (void)
|
||||
if (mkdir (mutter_dir, 0700) < 0 &&
|
||||
errno != EEXIST)
|
||||
{
|
||||
meta_warning ("Could not create directory '%s': %s\n",
|
||||
meta_warning (_("Could not create directory '%s': %s\n"),
|
||||
mutter_dir, g_strerror (errno));
|
||||
}
|
||||
|
||||
if (mkdir (session_dir, 0700) < 0 &&
|
||||
errno != EEXIST)
|
||||
{
|
||||
meta_warning ("Could not create directory '%s': %s\n",
|
||||
meta_warning (_("Could not create directory '%s': %s\n"),
|
||||
session_dir, g_strerror (errno));
|
||||
}
|
||||
|
||||
@@ -865,7 +857,7 @@ save_state (void)
|
||||
|
||||
if (outfile == NULL)
|
||||
{
|
||||
meta_warning ("Could not open session file '%s' for writing: %s\n",
|
||||
meta_warning (_("Could not open session file '%s' for writing: %s\n"),
|
||||
full_save_file (), g_strerror (errno));
|
||||
goto out;
|
||||
}
|
||||
@@ -1006,12 +998,12 @@ save_state (void)
|
||||
/* FIXME need a dialog for this */
|
||||
if (ferror (outfile))
|
||||
{
|
||||
meta_warning ("Error writing session file '%s': %s\n",
|
||||
meta_warning (_("Error writing session file '%s': %s\n"),
|
||||
full_save_file (), g_strerror (errno));
|
||||
}
|
||||
if (fclose (outfile))
|
||||
{
|
||||
meta_warning ("Error closing session file '%s': %s\n",
|
||||
meta_warning (_("Error closing session file '%s': %s\n"),
|
||||
full_save_file (), g_strerror (errno));
|
||||
}
|
||||
}
|
||||
@@ -1141,7 +1133,7 @@ load_state (const char *previous_save_file)
|
||||
|
||||
error:
|
||||
|
||||
meta_warning ("Failed to parse saved session file: %s\n",
|
||||
meta_warning (_("Failed to parse saved session file: %s\n"),
|
||||
error->message);
|
||||
g_error_free (error);
|
||||
|
||||
@@ -1190,7 +1182,7 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_PARSE,
|
||||
"<mutter_session> attribute seen but we already have the session ID");
|
||||
_("<mutter_session> attribute seen but we already have the session ID"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1203,7 +1195,7 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
"Unknown attribute %s on <%s> element",
|
||||
_("Unknown attribute %s on <%s> element"),
|
||||
name, "mutter_session");
|
||||
return;
|
||||
}
|
||||
@@ -1220,7 +1212,7 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_PARSE,
|
||||
"nested <window> tag");
|
||||
_("nested <window> tag"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1278,7 +1270,7 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
"Unknown attribute %s on <%s> element",
|
||||
_("Unknown attribute %s on <%s> element"),
|
||||
name, "window");
|
||||
session_info_free (pd->info);
|
||||
pd->info = NULL;
|
||||
@@ -1310,7 +1302,7 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
"Unknown attribute %s on <%s> element",
|
||||
_("Unknown attribute %s on <%s> element"),
|
||||
name, "window");
|
||||
session_info_free (pd->info);
|
||||
pd->info = NULL;
|
||||
@@ -1382,7 +1374,7 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
"Unknown attribute %s on <%s> element",
|
||||
_("Unknown attribute %s on <%s> element"),
|
||||
name, "maximized");
|
||||
return;
|
||||
}
|
||||
@@ -1442,7 +1434,7 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
|
||||
"Unknown attribute %s on <%s> element",
|
||||
_("Unknown attribute %s on <%s> element"),
|
||||
name, "geometry");
|
||||
return;
|
||||
}
|
||||
@@ -1462,7 +1454,7 @@ start_element_handler (GMarkupParseContext *context,
|
||||
g_set_error (error,
|
||||
G_MARKUP_ERROR,
|
||||
G_MARKUP_ERROR_UNKNOWN_ELEMENT,
|
||||
"Unknown element %s",
|
||||
_("Unknown element %s"),
|
||||
element_name);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1051,6 +1051,7 @@ stack_tracker_event_received (MetaStackTracker *tracker,
|
||||
|
||||
tracker->xserver_serial = op->any.serial;
|
||||
|
||||
#warning "TODO: remove unused tracker->xserver_stack"
|
||||
/* XXX: With the design we have ended up with it looks like we've
|
||||
* ended up making it unnecessary to maintain tracker->xserver_stack
|
||||
* since we only need an xserver_stack during the
|
||||
|
||||
@@ -1724,12 +1724,14 @@ get_default_focus_window (MetaStack *stack,
|
||||
* or top window in same group as not_this_one.
|
||||
*/
|
||||
|
||||
MetaWindow *topmost_dock;
|
||||
MetaWindow *transient_parent;
|
||||
MetaWindow *topmost_in_group;
|
||||
MetaWindow *topmost_overall;
|
||||
MetaGroup *not_this_one_group;
|
||||
GList *link;
|
||||
|
||||
topmost_dock = NULL;
|
||||
transient_parent = NULL;
|
||||
topmost_in_group = NULL;
|
||||
topmost_overall = NULL;
|
||||
@@ -1755,6 +1757,10 @@ get_default_focus_window (MetaStack *stack,
|
||||
(workspace == NULL ||
|
||||
meta_window_located_on_workspace (window, workspace)))
|
||||
{
|
||||
if (topmost_dock == NULL &&
|
||||
window->type == META_WINDOW_DOCK)
|
||||
topmost_dock = window;
|
||||
|
||||
if (not_this_one != NULL)
|
||||
{
|
||||
if (transient_parent == NULL &&
|
||||
@@ -1772,6 +1778,10 @@ get_default_focus_window (MetaStack *stack,
|
||||
topmost_in_group = window;
|
||||
}
|
||||
|
||||
/* Note that DESKTOP windows can be topmost_overall so
|
||||
* we prefer focusing desktop or other windows over
|
||||
* focusing dock, even though docks are stacked higher.
|
||||
*/
|
||||
if (topmost_overall == NULL &&
|
||||
window->type != META_WINDOW_DOCK &&
|
||||
(!must_be_at_point ||
|
||||
@@ -1793,7 +1803,7 @@ get_default_focus_window (MetaStack *stack,
|
||||
else if (topmost_overall)
|
||||
return topmost_overall;
|
||||
else
|
||||
return NULL;
|
||||
return topmost_dock;
|
||||
}
|
||||
|
||||
MetaWindow*
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/* Mutter utilities */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_UTIL_PRIVATE_H
|
||||
#define META_UTIL_PRIVATE_H
|
||||
|
||||
#include <meta/util.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
void meta_set_verbose (gboolean setting);
|
||||
void meta_set_debugging (gboolean setting);
|
||||
void meta_set_syncing (gboolean setting);
|
||||
void meta_set_replace_current_wm (gboolean setting);
|
||||
void meta_set_is_wayland_compositor (gboolean setting);
|
||||
|
||||
#endif
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <meta/common.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include <meta/main.h>
|
||||
|
||||
#include <clutter/clutter.h> /* For clutter_threads_add_repaint_func() */
|
||||
@@ -82,7 +82,7 @@ ensure_logfile (void)
|
||||
|
||||
if (err != NULL)
|
||||
{
|
||||
meta_warning ("Failed to open debug log: %s\n",
|
||||
meta_warning (_("Failed to open debug log: %s\n"),
|
||||
err->message);
|
||||
g_error_free (err);
|
||||
return;
|
||||
@@ -92,13 +92,13 @@ ensure_logfile (void)
|
||||
|
||||
if (logfile == NULL)
|
||||
{
|
||||
meta_warning ("Failed to fdopen() log file %s: %s\n",
|
||||
meta_warning (_("Failed to fdopen() log file %s: %s\n"),
|
||||
filename, strerror (errno));
|
||||
close (fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_printerr ("Opened log file %s\n", filename);
|
||||
g_printerr (_("Opened log file %s\n"), filename);
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
@@ -274,7 +274,7 @@ meta_debug_spew_real (const char *format, ...)
|
||||
out = logfile ? logfile : stderr;
|
||||
|
||||
if (no_prefix == 0)
|
||||
utf8_fputs ("Window manager: ", out);
|
||||
utf8_fputs (_("Window manager: "), out);
|
||||
utf8_fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
@@ -424,7 +424,7 @@ meta_bug (const char *format, ...)
|
||||
#endif
|
||||
|
||||
if (no_prefix == 0)
|
||||
utf8_fputs ("Bug in window manager: ", out);
|
||||
utf8_fputs (_("Bug in window manager: "), out);
|
||||
utf8_fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
@@ -455,7 +455,7 @@ meta_warning (const char *format, ...)
|
||||
#endif
|
||||
|
||||
if (no_prefix == 0)
|
||||
utf8_fputs ("Window manager warning: ", out);
|
||||
utf8_fputs (_("Window manager warning: "), out);
|
||||
utf8_fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
@@ -483,7 +483,7 @@ meta_fatal (const char *format, ...)
|
||||
#endif
|
||||
|
||||
if (no_prefix == 0)
|
||||
utf8_fputs ("Window manager error: ", out);
|
||||
utf8_fputs (_("Window manager error: "), out);
|
||||
utf8_fputs (str, out);
|
||||
|
||||
fflush (out);
|
||||
|
||||
@@ -44,7 +44,15 @@
|
||||
#include <X11/Xutil.h>
|
||||
#include <cairo.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include "meta-wayland-types.h"
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
/* XXX: We should find a nicer approach to deal with the
|
||||
* circular dependency we have with the current headers
|
||||
* (meta-wayland-private.h which typedefs MetaWaylandSurface
|
||||
* also includes window-private.h) */
|
||||
#ifndef HAVE_META_WAYLAND_SURFACE_TYPE
|
||||
typedef struct _MetaWaylandSurface MetaWaylandSurface;
|
||||
#endif
|
||||
|
||||
typedef struct _MetaWindowQueue MetaWindowQueue;
|
||||
|
||||
@@ -127,7 +135,6 @@ struct _MetaWindow
|
||||
Window xtransient_for;
|
||||
Window xgroup_leader;
|
||||
Window xclient_leader;
|
||||
MetaWindow *transient_for;
|
||||
|
||||
/* Initial workspace property */
|
||||
int initial_workspace;
|
||||
@@ -404,12 +411,6 @@ struct _MetaWindow
|
||||
*/
|
||||
MetaRectangle rect;
|
||||
|
||||
/* The size and position we want the window to be (i.e. what we last asked
|
||||
* the client to configure).
|
||||
* This is only used for wayland clients.
|
||||
*/
|
||||
MetaRectangle expected_rect;
|
||||
|
||||
gboolean has_custom_frame_extents;
|
||||
GtkBorder custom_frame_extents;
|
||||
|
||||
@@ -607,11 +608,6 @@ void meta_window_move_resize_request(MetaWindow *window,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
void meta_window_move_resize_wayland (MetaWindow *window,
|
||||
int width,
|
||||
int height,
|
||||
int dx,
|
||||
int dy);
|
||||
gboolean meta_window_configure_request (MetaWindow *window,
|
||||
XEvent *event);
|
||||
gboolean meta_window_property_notify (MetaWindow *window,
|
||||
@@ -678,9 +674,7 @@ void meta_window_update_layer (MetaWindow *window);
|
||||
|
||||
void meta_window_recalc_features (MetaWindow *window);
|
||||
|
||||
/* recalc_window_type is x11 only, wayland does its thing and then calls type_changed */
|
||||
void meta_window_recalc_window_type (MetaWindow *window);
|
||||
void meta_window_type_changed (MetaWindow *window);
|
||||
|
||||
void meta_window_stack_just_below (MetaWindow *window,
|
||||
MetaWindow *below_this_one);
|
||||
@@ -717,20 +711,4 @@ void meta_window_set_shape_region (MetaWindow *window,
|
||||
cairo_region_t *region);
|
||||
void meta_window_update_shape_region_x11 (MetaWindow *window);
|
||||
|
||||
void meta_window_set_title (MetaWindow *window,
|
||||
const char *title);
|
||||
void meta_window_set_wm_class (MetaWindow *window,
|
||||
const char *wm_class,
|
||||
const char *wm_instance);
|
||||
void meta_window_set_gtk_dbus_properties (MetaWindow *window,
|
||||
const char *application_id,
|
||||
const char *unique_bus_name,
|
||||
const char *appmenu_path,
|
||||
const char *menubar_path,
|
||||
const char *application_object_path,
|
||||
const char *window_object_path);
|
||||
|
||||
void meta_window_set_transient_for (MetaWindow *window,
|
||||
MetaWindow *parent);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
#include <X11/Xatom.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "util-private.h"
|
||||
|
||||
#ifndef HOST_NAME_MAX
|
||||
/* Solaris headers apparently don't define this so do so manually; #326745 */
|
||||
@@ -345,7 +344,7 @@ reload_net_wm_pid (MetaWindow *window,
|
||||
gulong cardinal = (int) value->v.cardinal;
|
||||
|
||||
if (cardinal <= 0)
|
||||
meta_warning ("Application set a bogus _NET_WM_PID %lu\n",
|
||||
meta_warning (_("Application set a bogus _NET_WM_PID %lu\n"),
|
||||
cardinal);
|
||||
else
|
||||
{
|
||||
@@ -490,19 +489,28 @@ static void
|
||||
set_window_title (MetaWindow *window,
|
||||
const char *title)
|
||||
{
|
||||
char *new_title = NULL;
|
||||
char *str;
|
||||
|
||||
gboolean modified =
|
||||
set_title_text (window,
|
||||
window->using_net_wm_visible_name,
|
||||
title,
|
||||
window->display->atom__NET_WM_VISIBLE_NAME,
|
||||
&new_title);
|
||||
&window->title);
|
||||
window->using_net_wm_visible_name = modified;
|
||||
|
||||
meta_window_set_title (window, new_title);
|
||||
/* strndup is a hack since GNU libc has broken %.10s */
|
||||
str = g_strndup (window->title, 10);
|
||||
g_free (window->desc);
|
||||
window->desc = g_strdup_printf ("0x%lx (%s)", window->xwindow, str);
|
||||
g_free (str);
|
||||
|
||||
g_free (new_title);
|
||||
if (window->frame)
|
||||
meta_ui_set_frame_title (window->screen->ui,
|
||||
window->frame->xwindow,
|
||||
window->title);
|
||||
|
||||
g_object_notify (G_OBJECT (window), "title");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -867,15 +875,23 @@ reload_wm_class (MetaWindow *window,
|
||||
MetaPropValue *value,
|
||||
gboolean initial)
|
||||
{
|
||||
if (window->res_class)
|
||||
g_free (window->res_class);
|
||||
if (window->res_name)
|
||||
g_free (window->res_name);
|
||||
|
||||
window->res_class = NULL;
|
||||
window->res_name = NULL;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
meta_window_set_wm_class (window,
|
||||
value->v.class_hint.res_class,
|
||||
value->v.class_hint.res_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_window_set_wm_class (window, NULL, NULL);
|
||||
{
|
||||
if (value->v.class_hint.res_name)
|
||||
window->res_name = g_strdup (value->v.class_hint.res_name);
|
||||
|
||||
if (value->v.class_hint.res_class)
|
||||
window->res_class = g_strdup (value->v.class_hint.res_class);
|
||||
|
||||
g_object_notify (G_OBJECT (window), "wm-class");
|
||||
}
|
||||
|
||||
meta_verbose ("Window %s class: '%s' name: '%s'\n",
|
||||
@@ -1518,7 +1534,7 @@ reload_transient_for (MetaWindow *window,
|
||||
gboolean initial)
|
||||
{
|
||||
MetaWindow *parent = NULL;
|
||||
Window transient_for;
|
||||
Window transient_for, old_transient_for;
|
||||
|
||||
if (value->type != META_PROP_VALUE_INVALID)
|
||||
{
|
||||
@@ -1527,7 +1543,8 @@ reload_transient_for (MetaWindow *window,
|
||||
parent = meta_display_lookup_x_window (window->display, transient_for);
|
||||
if (!parent)
|
||||
{
|
||||
meta_warning ("Invalid WM_TRANSIENT_FOR window 0x%lx specified for %s.\n",
|
||||
meta_warning (_("Invalid WM_TRANSIENT_FOR window 0x%lx specified "
|
||||
"for %s.\n"),
|
||||
transient_for, window->desc);
|
||||
transient_for = None;
|
||||
}
|
||||
@@ -1537,7 +1554,8 @@ reload_transient_for (MetaWindow *window,
|
||||
{
|
||||
if (parent == window)
|
||||
{
|
||||
meta_warning ("WM_TRANSIENT_FOR window 0x%lx for %s would create loop.\n",
|
||||
meta_warning (_("WM_TRANSIENT_FOR window 0x%lx for %s "
|
||||
"would create loop.\n"),
|
||||
transient_for, window->desc);
|
||||
transient_for = None;
|
||||
break;
|
||||
@@ -1553,6 +1571,10 @@ reload_transient_for (MetaWindow *window,
|
||||
if (transient_for == window->xtransient_for)
|
||||
return;
|
||||
|
||||
if (meta_window_appears_focused (window) && window->xtransient_for != None)
|
||||
meta_window_propagate_focus_appearance (window, FALSE);
|
||||
|
||||
old_transient_for = window->xtransient_for;
|
||||
window->xtransient_for = transient_for;
|
||||
|
||||
window->transient_parent_is_root_window =
|
||||
@@ -1564,14 +1586,46 @@ reload_transient_for (MetaWindow *window,
|
||||
else
|
||||
meta_verbose ("Window %s is not transient\n", window->desc);
|
||||
|
||||
if (window->transient_parent_is_root_window || window->xtransient_for == None)
|
||||
meta_window_set_transient_for (window, NULL);
|
||||
else
|
||||
/* may now be a dialog */
|
||||
meta_window_recalc_window_type (window);
|
||||
|
||||
if (!window->constructing)
|
||||
{
|
||||
parent = meta_display_lookup_x_window (window->display,
|
||||
window->xtransient_for);
|
||||
meta_window_set_transient_for (window, parent);
|
||||
/* If the window attaches, detaches, or changes attached
|
||||
* parents, we need to destroy the MetaWindow and let a new one
|
||||
* be created (which happens as a side effect of
|
||||
* meta_window_unmanage()). The condition below is correct
|
||||
* because we know window->xtransient_for has changed.
|
||||
*/
|
||||
if (window->attached || meta_window_should_attach_to_parent (window))
|
||||
{
|
||||
guint32 timestamp;
|
||||
|
||||
window->xtransient_for = old_transient_for;
|
||||
timestamp = meta_display_get_current_time_roundtrip (window->display);
|
||||
meta_window_unmanage (window, timestamp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* update stacking constraints */
|
||||
if (!window->override_redirect)
|
||||
meta_stack_update_transient (window->screen->stack, window);
|
||||
|
||||
/* possibly change its group. We treat being a window's transient as
|
||||
* equivalent to making it your group leader, to work around shortcomings
|
||||
* in programs such as xmms-- see #328211.
|
||||
*/
|
||||
if (window->xtransient_for != None &&
|
||||
window->xgroup_leader != None &&
|
||||
window->xtransient_for != window->xgroup_leader)
|
||||
meta_window_group_leader_changed (window);
|
||||
|
||||
if (!window->constructing && !window->override_redirect)
|
||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
|
||||
|
||||
if (meta_window_appears_focused (window) && window->xtransient_for != None)
|
||||
meta_window_propagate_focus_appearance (window, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -78,7 +78,6 @@ static void
|
||||
meta_workspace_finalize (GObject *object)
|
||||
{
|
||||
/* Actual freeing done in meta_workspace_remove() for now */
|
||||
G_OBJECT_CLASS (meta_workspace_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -83,7 +83,7 @@ from The Open Group.
|
||||
#include <config.h>
|
||||
#include "xprops.h"
|
||||
#include <meta/errors.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include "async-getprop.h"
|
||||
#include "ui.h"
|
||||
#include "mutter-Xatomtype.h"
|
||||
@@ -152,7 +152,7 @@ validate_or_free_results (GetPropertyResults *results,
|
||||
if (res_name == NULL)
|
||||
res_name = "unknown";
|
||||
|
||||
meta_warning ("Window 0x%lx has property %s\nthat was expected to have type %s format %d\nand actually has type %s format %d n_items %d.\nThis is most likely an application bug, not a window manager bug.\nThe window has title=\"%s\" class=\"%s\" name=\"%s\"\n",
|
||||
meta_warning (_("Window 0x%lx has property %s\nthat was expected to have type %s format %d\nand actually has type %s format %d n_items %d.\nThis is most likely an application bug, not a window manager bug.\nThe window has title=\"%s\" class=\"%s\" name=\"%s\"\n"),
|
||||
results->xwindow,
|
||||
prop_name ? prop_name : "(bad atom)",
|
||||
expected_name ? expected_name : "(bad atom)",
|
||||
@@ -408,7 +408,7 @@ utf8_string_from_results (GetPropertyResults *results,
|
||||
char *name;
|
||||
|
||||
name = XGetAtomName (results->display->xdisplay, results->xatom);
|
||||
meta_warning ("Property %s on window 0x%lx contained invalid UTF-8\n",
|
||||
meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8\n"),
|
||||
name, results->xwindow);
|
||||
meta_XFree (name);
|
||||
XFree (results->prop);
|
||||
@@ -491,7 +491,7 @@ utf8_list_from_results (GetPropertyResults *results,
|
||||
meta_error_trap_push (results->display);
|
||||
name = XGetAtomName (results->display->xdisplay, results->xatom);
|
||||
meta_error_trap_pop (results->display);
|
||||
meta_warning ("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n",
|
||||
meta_warning (_("Property %s on window 0x%lx contained invalid UTF-8 for item %d in the list\n"),
|
||||
name, results->xwindow, i);
|
||||
meta_XFree (name);
|
||||
meta_XFree (results->prop);
|
||||
|
||||
@@ -260,13 +260,6 @@ typedef enum
|
||||
* @META_CURSOR_NW_RESIZE: Resize north-western corner cursor
|
||||
* @META_CURSOR_MOVE_OR_RESIZE_WINDOW: Move or resize cursor
|
||||
* @META_CURSOR_BUSY: Busy cursor
|
||||
* @META_CURSOR_DND_IN_DRAG: DND in drag cursor
|
||||
* @META_CURSOR_DND_MOVE: DND move cursor
|
||||
* @META_CURSOR_DND_COPY: DND copy cursor
|
||||
* @META_CURSOR_DND_UNSUPPORTED_TARGET: DND unsupported target
|
||||
* @META_CURSOR_POINTING_HAND: pointing hand
|
||||
* @META_CURSOR_CROSSHAIR: crosshair (action forbidden)
|
||||
* @META_CURSOR_IBEAM: I-beam (text input)
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@@ -280,15 +273,8 @@ typedef enum
|
||||
META_CURSOR_NE_RESIZE,
|
||||
META_CURSOR_NW_RESIZE,
|
||||
META_CURSOR_MOVE_OR_RESIZE_WINDOW,
|
||||
META_CURSOR_BUSY,
|
||||
META_CURSOR_DND_IN_DRAG,
|
||||
META_CURSOR_DND_MOVE,
|
||||
META_CURSOR_DND_COPY,
|
||||
META_CURSOR_DND_UNSUPPORTED_TARGET,
|
||||
META_CURSOR_POINTING_HAND,
|
||||
META_CURSOR_CROSSHAIR,
|
||||
META_CURSOR_IBEAM,
|
||||
META_CURSOR_LAST
|
||||
META_CURSOR_BUSY
|
||||
|
||||
} MetaCursor;
|
||||
|
||||
/**
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <meta/types.h>
|
||||
#include <meta/workspace.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#define META_TYPE_CURSOR_TRACKER (meta_cursor_tracker_get_type ())
|
||||
#define META_CURSOR_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_TRACKER, MetaCursorTracker))
|
||||
@@ -48,11 +47,4 @@ void meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
int *y);
|
||||
CoglTexture *meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker);
|
||||
|
||||
void meta_cursor_tracker_get_pointer (MetaCursorTracker *tracker,
|
||||
int *x,
|
||||
int *y,
|
||||
ClutterModifierType *mods);
|
||||
void meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
|
||||
gboolean visible);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -67,12 +67,11 @@ GType meta_shaped_texture_get_type (void) G_GNUC_CONST;
|
||||
void meta_shaped_texture_set_create_mipmaps (MetaShapedTexture *stex,
|
||||
gboolean create_mipmaps);
|
||||
|
||||
gboolean meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
cairo_region_t *unobscured_region);
|
||||
void meta_shaped_texture_update_area (MetaShapedTexture *stex,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
CoglTexture * meta_shaped_texture_get_texture (MetaShapedTexture *stex);
|
||||
|
||||
@@ -81,6 +80,7 @@ void meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
|
||||
void meta_shaped_texture_set_input_shape_region (MetaShapedTexture *stex,
|
||||
cairo_region_t *shape_region);
|
||||
|
||||
/* Assumes ownership of clip_region */
|
||||
void meta_shaped_texture_set_clip_region (MetaShapedTexture *stex,
|
||||
cairo_region_t *clip_region);
|
||||
|
||||
|
||||
@@ -419,13 +419,13 @@ typedef struct
|
||||
*/
|
||||
GSList *bindings;
|
||||
|
||||
/* for keybindings that can have shift or not like Alt+Tab */
|
||||
/** for keybindings that can have shift or not like Alt+Tab */
|
||||
gboolean add_shift:1;
|
||||
|
||||
/* for keybindings that apply only to a window */
|
||||
/** for keybindings that apply only to a window */
|
||||
gboolean per_window:1;
|
||||
|
||||
/* for keybindings not added with meta_display_add_keybinding() */
|
||||
/** for keybindings not added with meta_display_add_keybinding() */
|
||||
gboolean builtin:1;
|
||||
} MetaKeyPref;
|
||||
|
||||
|
||||
@@ -114,8 +114,4 @@ void meta_screen_override_workspace_layout (MetaScreen *screen,
|
||||
gboolean vertical_layout,
|
||||
int n_rows,
|
||||
int n_columns);
|
||||
|
||||
void meta_screen_set_cursor (MetaScreen *screen,
|
||||
MetaCursor cursor);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,9 +31,14 @@
|
||||
#include <meta/common.h>
|
||||
|
||||
gboolean meta_is_verbose (void);
|
||||
void meta_set_verbose (gboolean setting);
|
||||
gboolean meta_is_debugging (void);
|
||||
void meta_set_debugging (gboolean setting);
|
||||
gboolean meta_is_syncing (void);
|
||||
void meta_set_syncing (gboolean setting);
|
||||
void meta_set_replace_current_wm (gboolean setting);
|
||||
gboolean meta_is_wayland_compositor (void);
|
||||
void meta_set_is_wayland_compositor (gboolean setting);
|
||||
|
||||
void meta_debug_spew_real (const char *format,
|
||||
...) G_GNUC_PRINTF (1, 2);
|
||||
@@ -119,6 +124,10 @@ const char* meta_gravity_to_string (int gravity);
|
||||
|
||||
char* meta_external_binding_name_for_action (guint keybinding_action);
|
||||
|
||||
#include <libintl.h>
|
||||
#define _(x) dgettext (GETTEXT_PACKAGE, x)
|
||||
#define N_(x) x
|
||||
|
||||
char* meta_g_utf8_strndup (const gchar *src, gsize n);
|
||||
|
||||
void meta_free_gslist_and_elements (GSList *list_to_deep_free);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
_Name=Mutter (wayland compositor)
|
||||
Exec=mutter-launch -- mutter --wayland
|
||||
Exec=mutter-launch -- mutter --nested
|
||||
NoDisplay=true
|
||||
# name of loadable control center module
|
||||
X-GNOME-WMSettingsModule=metacity
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
<schemalist>
|
||||
<schema id="org.gnome.mutter.wayland.keybindings" path="/org/gnome/mutter/wayland/keybindings/"
|
||||
gettext-domain="@GETTEXT_DOMAIN@">
|
||||
<key name="switch-to-session-1" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F1']]]></default>
|
||||
<_summary>Switch to VT 1</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-2" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F2']]]></default>
|
||||
<_summary>Switch to VT 2</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-3" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F3']]]></default>
|
||||
<_summary>Switch to VT 3</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-4" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F4']]]></default>
|
||||
<_summary>Switch to VT 4</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-5" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F5']]]></default>
|
||||
<_summary>Switch to VT 5</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-6" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F6']]]></default>
|
||||
<_summary>Switch to VT 6</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-7" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F7']]]></default>
|
||||
<_summary>Switch to VT 7</_summary>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
@@ -28,7 +28,7 @@
|
||||
#include <string.h>
|
||||
#include "menu.h"
|
||||
#include <meta/main.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include "core.h"
|
||||
#include "metaaccellabel.h"
|
||||
#include "ui.h"
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include "metaaccellabel.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
|
||||
static void meta_accel_label_destroy (GtkWidget *object);
|
||||
static void meta_accel_label_finalize (GObject *object);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <config.h>
|
||||
#include "resizepopup.h"
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <config.h>
|
||||
#include "theme-private.h"
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -430,11 +430,7 @@ locate_attributes (GMarkupParseContext *context,
|
||||
|
||||
while (name != NULL)
|
||||
{
|
||||
if (retloc == NULL)
|
||||
{
|
||||
retval = FALSE;
|
||||
goto out;
|
||||
}
|
||||
g_return_val_if_fail (retloc != NULL, FALSE);
|
||||
|
||||
g_assert (n_attrs < MAX_ATTRS);
|
||||
|
||||
@@ -3216,6 +3212,9 @@ parse_style_set_element (GMarkupParseContext *context,
|
||||
meta_frame_style_ref (frame_style);
|
||||
info->style_set->tiled_right_styles[frame_focus] = frame_style;
|
||||
break;
|
||||
meta_frame_style_ref (frame_style);
|
||||
info->style_set->tiled_right_styles[frame_focus] = frame_style;
|
||||
break;
|
||||
case META_FRAME_STATE_SHADED:
|
||||
if (info->style_set->shaded_styles[frame_resize][frame_focus])
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include <config.h>
|
||||
#include "theme-private.h"
|
||||
#include "frames.h" /* for META_TYPE_FRAMES */
|
||||
#include "util-private.h"
|
||||
#include <meta/util.h>
|
||||
#include <meta/gradient.h>
|
||||
#include <meta/prefs.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "meta-wayland-data-device.h"
|
||||
#include "meta-wayland-seat.h"
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
static void
|
||||
data_offer_accept (struct wl_client *client,
|
||||
@@ -109,12 +108,12 @@ meta_wayland_data_source_send_offer (MetaWaylandDataSource *source,
|
||||
offer->source = source;
|
||||
offer->source_destroy_listener.notify = destroy_offer_data_source;
|
||||
|
||||
offer->resource = wl_resource_create (wl_resource_get_client (target),
|
||||
&wl_data_offer_interface,
|
||||
MIN (META_WL_DATA_OFFER_VERSION,
|
||||
wl_resource_get_version (target)), 0);
|
||||
wl_resource_set_implementation (offer->resource, &data_offer_interface,
|
||||
offer, destroy_data_offer);
|
||||
offer->resource = wl_client_add_object (wl_resource_get_client (target),
|
||||
&wl_data_offer_interface,
|
||||
&data_offer_interface,
|
||||
0,
|
||||
offer);
|
||||
wl_resource_set_destructor (offer->resource, destroy_data_offer);
|
||||
wl_resource_add_destroy_listener (source->resource,
|
||||
&offer->source_destroy_listener);
|
||||
|
||||
@@ -151,63 +150,42 @@ static struct wl_data_source_interface data_source_interface = {
|
||||
data_source_destroy
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
MetaWaylandPointerGrab generic;
|
||||
|
||||
MetaWaylandSeat *seat;
|
||||
struct wl_client *drag_client;
|
||||
|
||||
MetaWaylandSurface *drag_focus;
|
||||
struct wl_resource *drag_focus_data_device;
|
||||
struct wl_listener drag_focus_listener;
|
||||
|
||||
MetaWaylandSurface *drag_surface;
|
||||
struct wl_listener drag_icon_listener;
|
||||
|
||||
MetaWaylandDataSource *drag_data_source;
|
||||
struct wl_listener drag_data_source_listener;
|
||||
} MetaWaylandDragGrab;
|
||||
|
||||
static void
|
||||
destroy_drag_focus (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandDragGrab *grab = wl_container_of (listener, grab, drag_focus_listener);
|
||||
MetaWaylandSeat *seat = wl_container_of (listener, seat, drag_focus_listener);
|
||||
|
||||
grab->drag_focus_data_device = NULL;
|
||||
seat->drag_focus_resource = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event)
|
||||
MetaWaylandSurface *surface,
|
||||
wl_fixed_t x,
|
||||
wl_fixed_t y)
|
||||
{
|
||||
MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
|
||||
MetaWaylandSeat *seat = drag_grab->seat;
|
||||
MetaWaylandSeat *seat = wl_container_of (grab, seat, drag_grab);
|
||||
struct wl_resource *resource, *offer = NULL;
|
||||
struct wl_display *display;
|
||||
guint32 serial;
|
||||
wl_fixed_t sx, sy;
|
||||
|
||||
if (drag_grab->drag_focus == surface)
|
||||
return;
|
||||
|
||||
if (drag_grab->drag_focus_data_device)
|
||||
if (seat->drag_focus_resource)
|
||||
{
|
||||
wl_data_device_send_leave (drag_grab->drag_focus_data_device);
|
||||
wl_list_remove (&drag_grab->drag_focus_listener.link);
|
||||
drag_grab->drag_focus_data_device = NULL;
|
||||
drag_grab->drag_focus = NULL;
|
||||
wl_data_device_send_leave (seat->drag_focus_resource);
|
||||
wl_list_remove (&seat->drag_focus_listener.link);
|
||||
seat->drag_focus_resource = NULL;
|
||||
seat->drag_focus = NULL;
|
||||
}
|
||||
|
||||
if (!surface)
|
||||
return;
|
||||
|
||||
if (!drag_grab->drag_data_source &&
|
||||
wl_resource_get_client (surface->resource) != drag_grab->drag_client)
|
||||
if (!seat->drag_data_source &&
|
||||
wl_resource_get_client (surface->resource) != seat->drag_client)
|
||||
return;
|
||||
|
||||
resource =
|
||||
wl_resource_find_for_client (&seat->data_device_resource_list,
|
||||
wl_resource_find_for_client (&seat->drag_resource_list,
|
||||
wl_resource_get_client (surface->resource));
|
||||
if (!resource)
|
||||
return;
|
||||
@@ -215,73 +193,68 @@ drag_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
display = wl_client_get_display (wl_resource_get_client (resource));
|
||||
serial = wl_display_next_serial (display);
|
||||
|
||||
if (drag_grab->drag_data_source)
|
||||
offer = meta_wayland_data_source_send_offer (drag_grab->drag_data_source,
|
||||
if (seat->drag_data_source)
|
||||
offer = meta_wayland_data_source_send_offer (seat->drag_data_source,
|
||||
resource);
|
||||
|
||||
meta_wayland_pointer_get_relative_coordinates (grab->pointer, surface, &sx, &sy);
|
||||
wl_data_device_send_enter (resource, serial, surface->resource,
|
||||
sx, sy, offer);
|
||||
x, y, offer);
|
||||
|
||||
drag_grab->drag_focus = surface;
|
||||
|
||||
drag_grab->drag_focus_data_device = resource;
|
||||
drag_grab->drag_focus_listener.notify = destroy_drag_focus;
|
||||
wl_resource_add_destroy_listener (resource, &drag_grab->drag_focus_listener);
|
||||
seat->drag_focus = surface;
|
||||
seat->drag_focus_listener.notify = destroy_drag_focus;
|
||||
wl_resource_add_destroy_listener (resource, &seat->drag_focus_listener);
|
||||
seat->drag_focus_resource = resource;
|
||||
grab->focus = surface;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_grab_motion (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
guint32 time, wl_fixed_t x, wl_fixed_t y)
|
||||
{
|
||||
MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
|
||||
wl_fixed_t sx, sy;
|
||||
MetaWaylandSeat *seat = wl_container_of (grab, seat, drag_grab);
|
||||
|
||||
if (drag_grab->drag_focus_data_device)
|
||||
{
|
||||
meta_wayland_pointer_get_relative_coordinates (grab->pointer,
|
||||
drag_grab->drag_focus,
|
||||
&sx, &sy);
|
||||
wl_data_device_send_motion (drag_grab->drag_focus_data_device,
|
||||
clutter_event_get_time (event),
|
||||
sx, sy);
|
||||
}
|
||||
if (seat->drag_focus_resource)
|
||||
wl_data_device_send_motion (seat->drag_focus_resource, time, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
data_device_end_drag_grab (MetaWaylandDragGrab *drag_grab)
|
||||
data_device_end_drag_grab (MetaWaylandSeat *seat)
|
||||
{
|
||||
if (drag_grab->drag_surface)
|
||||
if (seat->drag_surface)
|
||||
{
|
||||
drag_grab->drag_surface = NULL;
|
||||
wl_list_remove (&drag_grab->drag_icon_listener.link);
|
||||
seat->drag_surface = NULL;
|
||||
wl_signal_emit (&seat->drag_icon_signal, NULL);
|
||||
wl_list_remove (&seat->drag_icon_listener.link);
|
||||
}
|
||||
|
||||
if (drag_grab->drag_data_source)
|
||||
wl_list_remove (&drag_grab->drag_data_source_listener.link);
|
||||
drag_grab_focus (&seat->drag_grab, NULL,
|
||||
wl_fixed_from_int (0), wl_fixed_from_int (0));
|
||||
|
||||
drag_grab_focus (&drag_grab->generic, NULL, NULL);
|
||||
meta_wayland_pointer_end_grab (&seat->pointer);
|
||||
|
||||
meta_wayland_pointer_end_grab (drag_grab->generic.pointer);
|
||||
g_slice_free (MetaWaylandDragGrab, drag_grab);
|
||||
seat->drag_data_source = NULL;
|
||||
seat->drag_client = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_grab_button (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
guint32 time, guint32 button, guint32 state_w)
|
||||
{
|
||||
MetaWaylandDragGrab *drag_grab = (MetaWaylandDragGrab*) grab;
|
||||
MetaWaylandSeat *seat = drag_grab->seat;
|
||||
ClutterEventType event_type = clutter_event_type (event);
|
||||
MetaWaylandSeat *seat = wl_container_of (grab, seat, drag_grab);
|
||||
enum wl_pointer_button_state state = state_w;
|
||||
|
||||
if (drag_grab->drag_focus_data_device &&
|
||||
drag_grab->generic.pointer->grab_button == clutter_event_get_button (event) &&
|
||||
event_type == CLUTTER_BUTTON_RELEASE)
|
||||
wl_data_device_send_drop (drag_grab->drag_focus_data_device);
|
||||
if (seat->drag_focus_resource &&
|
||||
seat->pointer.grab_button == button &&
|
||||
state == WL_POINTER_BUTTON_STATE_RELEASED)
|
||||
wl_data_device_send_drop (seat->drag_focus_resource);
|
||||
|
||||
if (seat->pointer.button_count == 0 &&
|
||||
event_type == CLUTTER_BUTTON_RELEASE)
|
||||
data_device_end_drag_grab (drag_grab);
|
||||
state == WL_POINTER_BUTTON_STATE_RELEASED)
|
||||
{
|
||||
if (seat->drag_data_source)
|
||||
wl_list_remove (&seat->drag_data_source_listener.link);
|
||||
data_device_end_drag_grab (seat);
|
||||
}
|
||||
}
|
||||
|
||||
static const MetaWaylandPointerGrabInterface drag_grab_interface = {
|
||||
@@ -293,20 +266,19 @@ static const MetaWaylandPointerGrabInterface drag_grab_interface = {
|
||||
static void
|
||||
destroy_data_device_source (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandDragGrab *drag_grab =
|
||||
wl_container_of (listener, drag_grab, drag_data_source_listener);
|
||||
MetaWaylandSeat *seat =
|
||||
wl_container_of (listener, seat, drag_data_source_listener);
|
||||
|
||||
drag_grab->drag_data_source = NULL;
|
||||
data_device_end_drag_grab (drag_grab);
|
||||
data_device_end_drag_grab (seat);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_data_device_icon (struct wl_listener *listener, void *data)
|
||||
{
|
||||
MetaWaylandDragGrab *drag_grab =
|
||||
wl_container_of (listener, drag_grab, drag_data_source_listener);
|
||||
MetaWaylandSeat *seat =
|
||||
wl_container_of (listener, seat, drag_icon_listener);
|
||||
|
||||
drag_grab->drag_surface = NULL;
|
||||
seat->drag_surface = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -317,40 +289,38 @@ data_device_start_drag (struct wl_client *client,
|
||||
struct wl_resource *icon_resource, guint32 serial)
|
||||
{
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
||||
MetaWaylandDragGrab *drag_grab;
|
||||
|
||||
/* FIXME: Check that client has implicit grab on the origin
|
||||
* surface that matches the given time. */
|
||||
|
||||
/* FIXME: Check that the data source type array isn't empty. */
|
||||
|
||||
if (seat->pointer.grab != &seat->pointer.default_grab)
|
||||
return;
|
||||
seat->drag_grab.interface = &drag_grab_interface;
|
||||
|
||||
drag_grab = g_slice_new0 (MetaWaylandDragGrab);
|
||||
|
||||
drag_grab->generic.interface = &drag_grab_interface;
|
||||
drag_grab->generic.pointer = &seat->pointer;
|
||||
|
||||
drag_grab->drag_client = client;
|
||||
seat->drag_client = client;
|
||||
seat->drag_data_source = NULL;
|
||||
|
||||
if (source_resource)
|
||||
{
|
||||
drag_grab->drag_data_source = wl_resource_get_user_data (source_resource);
|
||||
drag_grab->drag_data_source_listener.notify = destroy_data_device_source;
|
||||
seat->drag_data_source = wl_resource_get_user_data (source_resource);
|
||||
seat->drag_data_source_listener.notify = destroy_data_device_source;
|
||||
wl_resource_add_destroy_listener (source_resource,
|
||||
&drag_grab->drag_data_source_listener);
|
||||
&seat->drag_data_source_listener);
|
||||
}
|
||||
|
||||
if (icon_resource)
|
||||
{
|
||||
drag_grab->drag_surface = wl_resource_get_user_data (icon_resource);
|
||||
drag_grab->drag_icon_listener.notify = destroy_data_device_icon;
|
||||
seat->drag_surface = wl_resource_get_user_data (icon_resource);
|
||||
seat->drag_icon_listener.notify = destroy_data_device_icon;
|
||||
wl_resource_add_destroy_listener (icon_resource,
|
||||
&drag_grab->drag_icon_listener);
|
||||
&seat->drag_icon_listener);
|
||||
wl_signal_emit (&seat->drag_icon_signal, icon_resource);
|
||||
}
|
||||
|
||||
meta_wayland_pointer_set_focus (&seat->pointer, NULL);
|
||||
meta_wayland_pointer_start_grab (&seat->pointer, (MetaWaylandPointerGrab*)drag_grab);
|
||||
meta_wayland_pointer_set_focus (&seat->pointer, NULL,
|
||||
wl_fixed_from_int (0),
|
||||
wl_fixed_from_int (0));
|
||||
meta_wayland_pointer_start_grab (&seat->pointer, &seat->drag_grab);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -368,11 +338,13 @@ destroy_selection_data_source (struct wl_listener *listener, void *data)
|
||||
if (focus)
|
||||
{
|
||||
data_device =
|
||||
wl_resource_find_for_client (&seat->data_device_resource_list,
|
||||
wl_resource_find_for_client (&seat->drag_resource_list,
|
||||
wl_resource_get_client (focus));
|
||||
if (data_device)
|
||||
wl_data_device_send_selection (data_device, NULL);
|
||||
}
|
||||
|
||||
wl_signal_emit (&seat->selection_signal, seat);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -402,7 +374,7 @@ meta_wayland_seat_set_selection (MetaWaylandSeat *seat,
|
||||
if (focus)
|
||||
{
|
||||
data_device =
|
||||
wl_resource_find_for_client (&seat->data_device_resource_list,
|
||||
wl_resource_find_for_client (&seat->drag_resource_list,
|
||||
wl_resource_get_client (focus));
|
||||
if (data_device && source)
|
||||
{
|
||||
@@ -417,6 +389,8 @@ meta_wayland_seat_set_selection (MetaWaylandSeat *seat,
|
||||
}
|
||||
}
|
||||
|
||||
wl_signal_emit (&seat->selection_signal, seat);
|
||||
|
||||
if (source)
|
||||
{
|
||||
seat->selection_data_source_listener.notify =
|
||||
@@ -491,11 +465,12 @@ create_data_source (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
source->resource = wl_resource_create (client, &wl_data_source_interface,
|
||||
MIN (META_WL_DATA_SOURCE_VERSION,
|
||||
wl_resource_get_version (resource)), id);
|
||||
wl_resource_set_implementation (source->resource, &data_source_interface,
|
||||
source, destroy_data_source);
|
||||
source->resource = wl_client_add_object (client,
|
||||
&wl_data_source_interface,
|
||||
&data_source_interface,
|
||||
id,
|
||||
source);
|
||||
wl_resource_set_destructor (source->resource, destroy_data_source);
|
||||
|
||||
source->accept = client_source_accept;
|
||||
source->send = client_source_send;
|
||||
@@ -518,11 +493,11 @@ get_data_device (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (seat_resource);
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &wl_data_device_interface,
|
||||
MIN (META_WL_DATA_DEVICE_VERSION,
|
||||
wl_resource_get_version (manager_resource)), id);
|
||||
wl_resource_set_implementation (resource, &data_device_interface, seat, unbind_data_device);
|
||||
wl_list_insert (&seat->data_device_resource_list, wl_resource_get_link (resource));
|
||||
resource = wl_client_add_object (client, &wl_data_device_interface,
|
||||
&data_device_interface, id, seat);
|
||||
|
||||
wl_list_insert (&seat->drag_resource_list, wl_resource_get_link (resource));
|
||||
wl_resource_set_destructor (resource, unbind_data_device);
|
||||
}
|
||||
|
||||
static const struct wl_data_device_manager_interface manager_interface = {
|
||||
@@ -534,11 +509,8 @@ static void
|
||||
bind_manager (struct wl_client *client,
|
||||
void *data, guint32 version, guint32 id)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &wl_data_device_manager_interface,
|
||||
MIN (version, META_WL_DATA_DEVICE_MANAGER_VERSION), id);
|
||||
wl_resource_set_implementation (resource, &manager_interface, NULL, NULL);
|
||||
wl_client_add_object (client, &wl_data_device_manager_interface,
|
||||
&manager_interface, id, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -551,7 +523,7 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandSeat *seat)
|
||||
if (!focus)
|
||||
return;
|
||||
|
||||
data_device = wl_resource_find_for_client (&seat->data_device_resource_list,
|
||||
data_device = wl_resource_find_for_client (&seat->drag_resource_list,
|
||||
wl_resource_get_client (focus));
|
||||
if (!data_device)
|
||||
return;
|
||||
@@ -567,10 +539,9 @@ meta_wayland_data_device_set_keyboard_focus (MetaWaylandSeat *seat)
|
||||
int
|
||||
meta_wayland_data_device_manager_init (struct wl_display *display)
|
||||
{
|
||||
if (wl_global_create (display,
|
||||
&wl_data_device_manager_interface,
|
||||
META_WL_DATA_DEVICE_MANAGER_VERSION,
|
||||
NULL, bind_manager) == NULL)
|
||||
if (wl_display_add_global (display,
|
||||
&wl_data_device_manager_interface,
|
||||
NULL, bind_manager) == NULL)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -56,9 +56,8 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta-wayland-keyboard.h"
|
||||
|
||||
static MetaWaylandSeat *
|
||||
meta_wayland_keyboard_get_seat (MetaWaylandKeyboard *keyboard)
|
||||
@@ -202,7 +201,7 @@ lose_keyboard_focus (struct wl_listener *listener, void *data)
|
||||
keyboard->focus_resource = NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
static void
|
||||
default_grab_key (MetaWaylandKeyboardGrab *grab,
|
||||
uint32_t time, uint32_t key, uint32_t state)
|
||||
{
|
||||
@@ -218,8 +217,6 @@ default_grab_key (MetaWaylandKeyboardGrab *grab,
|
||||
serial = wl_display_next_serial (display);
|
||||
wl_keyboard_send_key (resource, serial, time, key, state);
|
||||
}
|
||||
|
||||
return resource != NULL;
|
||||
}
|
||||
|
||||
static struct wl_resource *
|
||||
@@ -261,11 +258,12 @@ default_grab_modifiers (MetaWaylandKeyboardGrab *grab, uint32_t serial,
|
||||
pointer->focus);
|
||||
if (pr)
|
||||
{
|
||||
wl_keyboard_send_modifiers (pr, serial,
|
||||
mods_depressed,
|
||||
mods_latched,
|
||||
mods_locked,
|
||||
group);
|
||||
wl_keyboard_send_modifiers (pr,
|
||||
serial,
|
||||
keyboard->modifiers.mods_depressed,
|
||||
keyboard->modifiers.mods_latched,
|
||||
keyboard->modifiers.mods_locked,
|
||||
keyboard->modifiers.group);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,38 +274,10 @@ static const MetaWaylandKeyboardGrabInterface
|
||||
default_grab_modifiers,
|
||||
};
|
||||
|
||||
static gboolean
|
||||
modal_key (MetaWaylandKeyboardGrab *grab,
|
||||
uint32_t time,
|
||||
uint32_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
/* FALSE means: let the event through to clutter */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
modal_modifiers (MetaWaylandKeyboardGrab *grab,
|
||||
uint32_t serial,
|
||||
uint32_t mods_depressed,
|
||||
uint32_t mods_latched,
|
||||
uint32_t mods_locked,
|
||||
uint32_t group)
|
||||
{
|
||||
}
|
||||
|
||||
static MetaWaylandKeyboardGrabInterface modal_grab = {
|
||||
modal_key,
|
||||
modal_modifiers,
|
||||
};
|
||||
|
||||
gboolean
|
||||
meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
struct wl_display *display,
|
||||
gboolean is_evdev)
|
||||
struct wl_display *display)
|
||||
{
|
||||
ClutterDeviceManager *manager;
|
||||
|
||||
memset (keyboard, 0, sizeof *keyboard);
|
||||
|
||||
wl_list_init (&keyboard->resource_list);
|
||||
@@ -316,22 +286,15 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
keyboard->default_grab.interface = &default_keyboard_grab_interface;
|
||||
keyboard->default_grab.keyboard = keyboard;
|
||||
keyboard->grab = &keyboard->default_grab;
|
||||
wl_signal_init (&keyboard->focus_signal);
|
||||
|
||||
keyboard->display = display;
|
||||
|
||||
keyboard->xkb_context = xkb_context_new (0 /* flags */);
|
||||
|
||||
meta_wayland_keyboard_build_global_keymap (keyboard->xkb_context,
|
||||
&keyboard->xkb_names,
|
||||
&keyboard->xkb_info);
|
||||
|
||||
keyboard->is_evdev = is_evdev;
|
||||
if (is_evdev)
|
||||
{
|
||||
manager = clutter_device_manager_get_default ();
|
||||
|
||||
clutter_evdev_set_keyboard_map (manager, keyboard->xkb_info.keymap);
|
||||
}
|
||||
&keyboard->xkb_names,
|
||||
&keyboard->xkb_info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -348,64 +311,90 @@ meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
|
||||
close (xkb_info->keymap_fd);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
state_equal (MetaWaylandXkbState *one,
|
||||
MetaWaylandXkbState *two)
|
||||
{
|
||||
return one->mods_depressed == two->mods_depressed &&
|
||||
one->mods_latched == two->mods_latched &&
|
||||
one->mods_locked == two->mods_locked &&
|
||||
one->group == two->group;
|
||||
}
|
||||
|
||||
static void
|
||||
set_modifiers (MetaWaylandKeyboard *keyboard,
|
||||
guint32 serial,
|
||||
ClutterEvent *event)
|
||||
guint32 serial,
|
||||
ClutterModifierType modifier_state)
|
||||
{
|
||||
MetaWaylandKeyboardGrab *grab = keyboard->grab;
|
||||
MetaWaylandXkbState new_state;
|
||||
guint effective_state;
|
||||
uint32_t depressed_mods = 0;
|
||||
uint32_t locked_mods = 0;
|
||||
|
||||
clutter_event_get_state_full (event,
|
||||
NULL,
|
||||
&new_state.mods_depressed,
|
||||
&new_state.mods_latched,
|
||||
&new_state.mods_locked,
|
||||
&effective_state);
|
||||
new_state.group = (effective_state >> 13) & 0x3;
|
||||
|
||||
if (state_equal (&keyboard->modifier_state, &new_state))
|
||||
if (keyboard->last_modifier_state == modifier_state)
|
||||
return;
|
||||
|
||||
keyboard->modifier_state = new_state;
|
||||
if ((modifier_state & CLUTTER_SHIFT_MASK) &&
|
||||
keyboard->xkb_info.shift_mod != XKB_MOD_INVALID)
|
||||
depressed_mods |= (1 << keyboard->xkb_info.shift_mod);
|
||||
|
||||
if ((modifier_state & CLUTTER_LOCK_MASK) &&
|
||||
keyboard->xkb_info.caps_mod != XKB_MOD_INVALID)
|
||||
locked_mods |= (1 << keyboard->xkb_info.caps_mod);
|
||||
|
||||
if ((modifier_state & CLUTTER_CONTROL_MASK) &&
|
||||
keyboard->xkb_info.ctrl_mod != XKB_MOD_INVALID)
|
||||
depressed_mods |= (1 << keyboard->xkb_info.ctrl_mod);
|
||||
|
||||
if ((modifier_state & CLUTTER_MOD1_MASK) &&
|
||||
keyboard->xkb_info.alt_mod != XKB_MOD_INVALID)
|
||||
depressed_mods |= (1 << keyboard->xkb_info.alt_mod);
|
||||
|
||||
if ((modifier_state & CLUTTER_MOD2_MASK) &&
|
||||
keyboard->xkb_info.mod2_mod != XKB_MOD_INVALID)
|
||||
depressed_mods |= (1 << keyboard->xkb_info.mod2_mod);
|
||||
|
||||
if ((modifier_state & CLUTTER_MOD3_MASK) &&
|
||||
keyboard->xkb_info.mod3_mod != XKB_MOD_INVALID)
|
||||
depressed_mods |= (1 << keyboard->xkb_info.mod3_mod);
|
||||
|
||||
if ((modifier_state & CLUTTER_SUPER_MASK) &&
|
||||
keyboard->xkb_info.super_mod != XKB_MOD_INVALID)
|
||||
depressed_mods |= (1 << keyboard->xkb_info.super_mod);
|
||||
|
||||
if ((modifier_state & CLUTTER_MOD5_MASK) &&
|
||||
keyboard->xkb_info.mod5_mod != XKB_MOD_INVALID)
|
||||
depressed_mods |= (1 << keyboard->xkb_info.mod5_mod);
|
||||
|
||||
keyboard->last_modifier_state = modifier_state;
|
||||
|
||||
grab->interface->modifiers (grab,
|
||||
serial,
|
||||
new_state.mods_depressed,
|
||||
new_state.mods_latched,
|
||||
new_state.mods_locked,
|
||||
new_state.group);
|
||||
depressed_mods,
|
||||
0, /* latched_modes */
|
||||
locked_mods,
|
||||
0 /* group */);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_pressed_keys (MetaWaylandKeyboard *keyboard,
|
||||
uint32_t evdev_code,
|
||||
gboolean is_press)
|
||||
void
|
||||
meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
||||
const ClutterKeyEvent *event)
|
||||
{
|
||||
if (is_press)
|
||||
gboolean state = event->type == CLUTTER_KEY_PRESS;
|
||||
guint evdev_code;
|
||||
uint32_t serial;
|
||||
|
||||
/* We can't do anything with the event if we can't get an evdev
|
||||
keycode for it */
|
||||
if (event->device == NULL ||
|
||||
!clutter_input_device_keycode_to_evdev (event->device,
|
||||
event->hardware_keycode,
|
||||
&evdev_code))
|
||||
return;
|
||||
|
||||
/* We want to ignore events that are sent because of auto-repeat. In
|
||||
the Clutter event stream these appear as a single key press
|
||||
event. We can detect that because the key will already have been
|
||||
pressed */
|
||||
if (state)
|
||||
{
|
||||
uint32_t *end = (void *) ((char *) keyboard->keys.data +
|
||||
keyboard->keys.size);
|
||||
uint32_t *k;
|
||||
|
||||
/* We want to ignore events that are sent because of auto-repeat. In
|
||||
the Clutter event stream these appear as a single key press
|
||||
event. We can detect that because the key will already have been
|
||||
pressed */
|
||||
/* Ignore the event if the key is already down */
|
||||
for (k = keyboard->keys.data; k < end; k++)
|
||||
if (*k == evdev_code)
|
||||
return TRUE;
|
||||
return;
|
||||
|
||||
/* Otherwise add the key to the list of pressed keys */
|
||||
k = wl_array_add (&keyboard->keys, sizeof (*k));
|
||||
@@ -428,56 +417,19 @@ update_pressed_keys (MetaWaylandKeyboard *keyboard,
|
||||
}
|
||||
|
||||
g_warning ("unexpected key release event for key 0x%x", evdev_code);
|
||||
return FALSE;
|
||||
|
||||
found:
|
||||
(void) 0;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
||||
const ClutterKeyEvent *event)
|
||||
{
|
||||
gboolean is_press = event->type == CLUTTER_KEY_PRESS;
|
||||
guint xkb_keycode, evdev_code;
|
||||
uint32_t serial;
|
||||
gboolean autorepeat;
|
||||
gboolean handled;
|
||||
|
||||
xkb_keycode = event->hardware_keycode;
|
||||
if (event->device == NULL ||
|
||||
!clutter_input_device_keycode_to_evdev (event->device,
|
||||
xkb_keycode, &evdev_code))
|
||||
evdev_code = xkb_keycode - 8; /* What everyone is doing in practice... */
|
||||
|
||||
autorepeat = update_pressed_keys (keyboard, evdev_code, is_press);
|
||||
|
||||
meta_verbose ("Handling key %s%s event code %d\n",
|
||||
is_press ? "press" : "release",
|
||||
autorepeat ? " (autorepeat)" : "",
|
||||
xkb_keycode);
|
||||
|
||||
if (autorepeat)
|
||||
return FALSE;
|
||||
|
||||
serial = wl_display_next_serial (keyboard->display);
|
||||
|
||||
set_modifiers (keyboard, serial, (ClutterEvent*)event);
|
||||
set_modifiers (keyboard, serial, event->modifier_state);
|
||||
|
||||
handled = keyboard->grab->interface->key (keyboard->grab,
|
||||
event->time,
|
||||
evdev_code,
|
||||
is_press);
|
||||
|
||||
if (handled)
|
||||
meta_verbose ("Sent event to wayland client\n");
|
||||
else
|
||||
meta_verbose ("No wayland surface is focused, continuing normal operation\n");
|
||||
|
||||
return handled;
|
||||
keyboard->grab->interface->key (keyboard->grab,
|
||||
event->time,
|
||||
evdev_code,
|
||||
state);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -509,35 +461,20 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard,
|
||||
|
||||
display = wl_client_get_display (client);
|
||||
serial = wl_display_next_serial (display);
|
||||
|
||||
/* If we're in a modal grab, the client is focused but doesn't see
|
||||
modifiers or pressed keys (and fix that up when we exit the modal) */
|
||||
if (keyboard->grab->interface == &modal_grab)
|
||||
{
|
||||
struct wl_array empty;
|
||||
wl_array_init (&empty);
|
||||
|
||||
wl_keyboard_send_modifiers (resource, serial,
|
||||
0, 0, 0, 0);
|
||||
wl_keyboard_send_enter (resource, serial, surface->resource,
|
||||
&empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
wl_keyboard_send_modifiers (resource, serial,
|
||||
keyboard->modifier_state.mods_depressed,
|
||||
keyboard->modifier_state.mods_latched,
|
||||
keyboard->modifier_state.mods_locked,
|
||||
keyboard->modifier_state.group);
|
||||
wl_keyboard_send_enter (resource, serial, surface->resource,
|
||||
&keyboard->keys);
|
||||
}
|
||||
wl_keyboard_send_modifiers (resource, serial,
|
||||
keyboard->modifiers.mods_depressed,
|
||||
keyboard->modifiers.mods_latched,
|
||||
keyboard->modifiers.mods_locked,
|
||||
keyboard->modifiers.group);
|
||||
wl_keyboard_send_enter (resource, serial, surface->resource,
|
||||
&keyboard->keys);
|
||||
wl_resource_add_destroy_listener (resource, &keyboard->focus_listener);
|
||||
keyboard->focus_serial = serial;
|
||||
}
|
||||
|
||||
keyboard->focus_resource = resource;
|
||||
keyboard->focus = surface;
|
||||
wl_signal_emit (&keyboard->focus_signal, keyboard);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -573,82 +510,3 @@ meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard)
|
||||
wl_list_remove (&keyboard->focus_listener.link);
|
||||
wl_array_release (&keyboard->keys);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_keyboard_begin_modal (MetaWaylandKeyboard *keyboard,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWaylandKeyboardGrab *grab;
|
||||
uint32_t *end = (void *) ((char *) keyboard->keys.data +
|
||||
keyboard->keys.size);
|
||||
uint32_t *k;
|
||||
uint32_t serial;
|
||||
|
||||
meta_verbose ("Asked to acquire modal keyboard grab, timestamp %d\n", timestamp);
|
||||
|
||||
if (keyboard->grab != &keyboard->default_grab)
|
||||
return FALSE;
|
||||
|
||||
if (keyboard->focus)
|
||||
{
|
||||
/* Fake key release events for the focused app */
|
||||
serial = wl_display_next_serial (keyboard->display);
|
||||
keyboard->grab->interface->modifiers (keyboard->grab,
|
||||
serial,
|
||||
0, 0, 0, 0);
|
||||
|
||||
for (k = keyboard->keys.data; k < end; k++)
|
||||
{
|
||||
keyboard->grab->interface->key (keyboard->grab,
|
||||
timestamp,
|
||||
*k, 0);
|
||||
}
|
||||
}
|
||||
|
||||
grab = g_slice_new0 (MetaWaylandKeyboardGrab);
|
||||
grab->interface = &modal_grab;
|
||||
meta_wayland_keyboard_start_grab (keyboard, grab);
|
||||
|
||||
meta_verbose ("Acquired modal keyboard grab, timestamp %d\n", timestamp);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWaylandKeyboardGrab *grab;
|
||||
uint32_t *end = (void *) ((char *) keyboard->keys.data +
|
||||
keyboard->keys.size);
|
||||
uint32_t *k;
|
||||
uint32_t serial;
|
||||
|
||||
grab = keyboard->grab;
|
||||
|
||||
g_assert (grab->interface == &modal_grab);
|
||||
|
||||
meta_wayland_keyboard_end_grab (keyboard);
|
||||
g_slice_free (MetaWaylandKeyboardGrab, grab);
|
||||
|
||||
if (keyboard->focus)
|
||||
{
|
||||
/* Fake key press events for the focused app */
|
||||
serial = wl_display_next_serial (keyboard->display);
|
||||
keyboard->grab->interface->modifiers (keyboard->grab,
|
||||
serial,
|
||||
keyboard->modifier_state.mods_depressed,
|
||||
keyboard->modifier_state.mods_latched,
|
||||
keyboard->modifier_state.mods_locked,
|
||||
keyboard->modifier_state.group);
|
||||
|
||||
for (k = keyboard->keys.data; k < end; k++)
|
||||
{
|
||||
keyboard->grab->interface->key (keyboard->grab,
|
||||
timestamp,
|
||||
*k, 1);
|
||||
}
|
||||
}
|
||||
|
||||
meta_verbose ("Released modal keyboard grab, timestamp %d\n", timestamp);
|
||||
}
|
||||
|
||||
@@ -48,82 +48,13 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <wayland-server.h>
|
||||
|
||||
struct _MetaWaylandKeyboardGrabInterface
|
||||
{
|
||||
gboolean (*key) (MetaWaylandKeyboardGrab * grab, uint32_t time,
|
||||
uint32_t key, uint32_t state);
|
||||
void (*modifiers) (MetaWaylandKeyboardGrab * grab, uint32_t serial,
|
||||
uint32_t mods_depressed, uint32_t mods_latched,
|
||||
uint32_t mods_locked, uint32_t group);
|
||||
};
|
||||
|
||||
struct _MetaWaylandKeyboardGrab
|
||||
{
|
||||
const MetaWaylandKeyboardGrabInterface *interface;
|
||||
MetaWaylandKeyboard *keyboard;
|
||||
MetaWaylandSurface *focus;
|
||||
uint32_t key;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct xkb_keymap *keymap;
|
||||
int keymap_fd;
|
||||
size_t keymap_size;
|
||||
char *keymap_area;
|
||||
xkb_mod_index_t shift_mod;
|
||||
xkb_mod_index_t caps_mod;
|
||||
xkb_mod_index_t ctrl_mod;
|
||||
xkb_mod_index_t alt_mod;
|
||||
xkb_mod_index_t mod2_mod;
|
||||
xkb_mod_index_t mod3_mod;
|
||||
xkb_mod_index_t super_mod;
|
||||
xkb_mod_index_t mod5_mod;
|
||||
} MetaWaylandXkbInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t mods_depressed;
|
||||
uint32_t mods_latched;
|
||||
uint32_t mods_locked;
|
||||
uint32_t group;
|
||||
} MetaWaylandXkbState;
|
||||
|
||||
struct _MetaWaylandKeyboard
|
||||
{
|
||||
struct wl_list resource_list;
|
||||
MetaWaylandSurface *focus;
|
||||
struct wl_resource *focus_resource;
|
||||
struct wl_listener focus_listener;
|
||||
uint32_t focus_serial;
|
||||
|
||||
MetaWaylandKeyboardGrab *grab;
|
||||
MetaWaylandKeyboardGrab default_grab;
|
||||
uint32_t grab_key;
|
||||
uint32_t grab_serial;
|
||||
uint32_t grab_time;
|
||||
|
||||
struct wl_array keys;
|
||||
|
||||
MetaWaylandXkbState modifier_state;
|
||||
|
||||
struct wl_display *display;
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
gboolean is_evdev;
|
||||
MetaWaylandXkbInfo xkb_info;
|
||||
struct xkb_rule_names xkb_names;
|
||||
|
||||
MetaWaylandKeyboardGrab input_method_grab;
|
||||
struct wl_resource *input_method_resource;
|
||||
};
|
||||
#include "meta-wayland-seat.h"
|
||||
|
||||
gboolean
|
||||
meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard,
|
||||
struct wl_display *display,
|
||||
gboolean is_evdev);
|
||||
struct wl_display *display);
|
||||
|
||||
gboolean
|
||||
void
|
||||
meta_wayland_keyboard_handle_event (MetaWaylandKeyboard *keyboard,
|
||||
const ClutterKeyEvent *event);
|
||||
|
||||
@@ -138,13 +69,6 @@ meta_wayland_keyboard_start_grab (MetaWaylandKeyboard *device,
|
||||
void
|
||||
meta_wayland_keyboard_end_grab (MetaWaylandKeyboard *keyboard);
|
||||
|
||||
gboolean
|
||||
meta_wayland_keyboard_begin_modal (MetaWaylandKeyboard *keyboard,
|
||||
guint32 timestamp);
|
||||
void
|
||||
meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard,
|
||||
guint32 timestamp);
|
||||
|
||||
void
|
||||
meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard);
|
||||
|
||||
|
||||
@@ -43,17 +43,10 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include "meta-wayland-pointer.h"
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static void meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer);
|
||||
|
||||
static MetaWaylandSeat *
|
||||
meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer)
|
||||
{
|
||||
@@ -74,79 +67,50 @@ lose_pointer_focus (struct wl_listener *listener, void *data)
|
||||
|
||||
static void
|
||||
default_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event)
|
||||
MetaWaylandSurface *surface,
|
||||
wl_fixed_t x,
|
||||
wl_fixed_t y)
|
||||
{
|
||||
MetaWaylandPointer *pointer = grab->pointer;
|
||||
|
||||
if (pointer->button_count > 0)
|
||||
return;
|
||||
|
||||
meta_wayland_pointer_set_focus (pointer, surface);
|
||||
meta_wayland_pointer_set_focus (pointer, surface, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
default_grab_motion (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
uint32_t time, wl_fixed_t x, wl_fixed_t y)
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = grab->pointer->focus_resource;
|
||||
if (resource)
|
||||
{
|
||||
wl_fixed_t sx, sy;
|
||||
|
||||
meta_wayland_pointer_get_relative_coordinates (grab->pointer,
|
||||
grab->pointer->focus,
|
||||
&sx, &sy);
|
||||
wl_pointer_send_motion (resource, clutter_event_get_time (event), sx, sy);
|
||||
}
|
||||
wl_pointer_send_motion (resource, time, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
default_grab_button (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
uint32_t time, uint32_t button, uint32_t state_w)
|
||||
{
|
||||
MetaWaylandPointer *pointer = grab->pointer;
|
||||
struct wl_resource *resource;
|
||||
ClutterEventType event_type;
|
||||
|
||||
event_type = clutter_event_type (event);
|
||||
uint32_t serial;
|
||||
enum wl_pointer_button_state state = state_w;
|
||||
|
||||
resource = pointer->focus_resource;
|
||||
if (resource)
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
uint32_t button;
|
||||
uint32_t serial;
|
||||
|
||||
button = clutter_event_get_button (event);
|
||||
switch (button)
|
||||
{
|
||||
/* The evdev input right and middle button numbers are swapped
|
||||
relative to how Clutter numbers them */
|
||||
case 2:
|
||||
button = BTN_MIDDLE;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
button = BTN_RIGHT;
|
||||
break;
|
||||
|
||||
default:
|
||||
button = button + BTN_LEFT - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
serial = wl_display_next_serial (display);
|
||||
wl_pointer_send_button (resource, serial,
|
||||
clutter_event_get_time (event), button,
|
||||
event_type == CLUTTER_BUTTON_PRESS ? 1 : 0);
|
||||
wl_pointer_send_button (resource, serial, time, button, state_w);
|
||||
}
|
||||
|
||||
if (pointer->button_count == 0 && event_type == CLUTTER_BUTTON_RELEASE)
|
||||
meta_wayland_pointer_set_focus (pointer, pointer->current);
|
||||
if (pointer->button_count == 0 && state == WL_POINTER_BUTTON_STATE_RELEASED)
|
||||
meta_wayland_pointer_set_focus (pointer, pointer->current,
|
||||
pointer->current_x, pointer->current_y);
|
||||
}
|
||||
|
||||
static const MetaWaylandPointerGrabInterface default_pointer_grab_interface = {
|
||||
@@ -155,132 +119,20 @@ static const MetaWaylandPointerGrabInterface default_pointer_grab_interface = {
|
||||
default_grab_button
|
||||
};
|
||||
|
||||
/*
|
||||
* The pointer constrain code is mostly a rip-off of the XRandR code from Xorg.
|
||||
* (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder)
|
||||
*
|
||||
* Copyright © 2006 Keith Packard
|
||||
* Copyright 2010 Red Hat, Inc
|
||||
*
|
||||
*/
|
||||
|
||||
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,
|
||||
unsigned n_monitors,
|
||||
float *x,
|
||||
float *y)
|
||||
{
|
||||
ClutterPoint current;
|
||||
unsigned int i;
|
||||
|
||||
clutter_input_device_get_coords (device, NULL, ¤t);
|
||||
|
||||
/* 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 = left + monitor->rect.height;
|
||||
|
||||
nx = current.x;
|
||||
ny = current.y;
|
||||
|
||||
if ((nx >= left) && (nx < right) && (ny >= top) && (ny < bottom))
|
||||
{
|
||||
if (*x < left)
|
||||
*x = left;
|
||||
if (*x >= right)
|
||||
*x = right - 1;
|
||||
if (*y < top)
|
||||
*y = top;
|
||||
if (*y >= bottom)
|
||||
*y = bottom - 1;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_constrain_callback (ClutterInputDevice *device,
|
||||
guint32 time,
|
||||
float *new_x,
|
||||
float *new_y,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaMonitorManager *monitor_manager;
|
||||
MetaMonitorInfo *monitors;
|
||||
unsigned int n_monitors;
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_init (MetaWaylandPointer *pointer,
|
||||
gboolean is_native)
|
||||
meta_wayland_pointer_init (MetaWaylandPointer *pointer)
|
||||
{
|
||||
ClutterDeviceManager *manager;
|
||||
ClutterInputDevice *device;
|
||||
ClutterPoint current;
|
||||
|
||||
memset (pointer, 0, sizeof *pointer);
|
||||
wl_list_init (&pointer->resource_list);
|
||||
pointer->focus_listener.notify = lose_pointer_focus;
|
||||
pointer->default_grab.interface = &default_pointer_grab_interface;
|
||||
pointer->default_grab.pointer = pointer;
|
||||
pointer->grab = &pointer->default_grab;
|
||||
wl_signal_init (&pointer->focus_signal);
|
||||
|
||||
manager = clutter_device_manager_get_default ();
|
||||
device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
|
||||
|
||||
if (is_native)
|
||||
clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback,
|
||||
pointer, NULL);
|
||||
|
||||
clutter_input_device_get_coords (device, NULL, ¤t);
|
||||
pointer->x = wl_fixed_from_double (current.x);
|
||||
pointer->y = wl_fixed_from_double (current.y);
|
||||
/* FIXME: Pick better co-ords. */
|
||||
pointer->x = wl_fixed_from_int (100);
|
||||
pointer->y = wl_fixed_from_int (100);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -310,7 +162,8 @@ find_resource_for_surface (struct wl_list *list, MetaWaylandSurface *surface)
|
||||
|
||||
void
|
||||
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface)
|
||||
MetaWaylandSurface *surface,
|
||||
wl_fixed_t sx, wl_fixed_t sy)
|
||||
{
|
||||
MetaWaylandSeat *seat = meta_wayland_pointer_get_seat (pointer);
|
||||
MetaWaylandKeyboard *kbd = &seat->keyboard;
|
||||
@@ -333,10 +186,7 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
{
|
||||
struct wl_client *client = wl_resource_get_client (resource);
|
||||
struct wl_display *display = wl_client_get_display (client);
|
||||
wl_fixed_t sx, sy;
|
||||
|
||||
serial = wl_display_next_serial (display);
|
||||
|
||||
if (kbd)
|
||||
{
|
||||
kr = find_resource_for_surface (&kbd->resource_list, surface);
|
||||
@@ -344,14 +194,12 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
{
|
||||
wl_keyboard_send_modifiers (kr,
|
||||
serial,
|
||||
kbd->modifier_state.mods_depressed,
|
||||
kbd->modifier_state.mods_latched,
|
||||
kbd->modifier_state.mods_locked,
|
||||
kbd->modifier_state.group);
|
||||
kbd->modifiers.mods_depressed,
|
||||
kbd->modifiers.mods_latched,
|
||||
kbd->modifiers.mods_locked,
|
||||
kbd->modifiers.group);
|
||||
}
|
||||
}
|
||||
|
||||
meta_wayland_pointer_get_relative_coordinates (pointer, surface, &sx, &sy);
|
||||
wl_pointer_send_enter (resource, serial, surface->resource, sx, sy);
|
||||
wl_resource_add_destroy_listener (resource, &pointer->focus_listener);
|
||||
pointer->focus_serial = serial;
|
||||
@@ -359,6 +207,8 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
|
||||
pointer->focus_resource = resource;
|
||||
pointer->focus = surface;
|
||||
pointer->default_grab.focus = surface;
|
||||
wl_signal_emit (&pointer->focus_signal, pointer);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -372,7 +222,8 @@ meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
||||
grab->pointer = pointer;
|
||||
|
||||
if (pointer->current)
|
||||
interface->focus (pointer->grab, pointer->current, NULL);
|
||||
interface->focus (pointer->grab, pointer->current,
|
||||
pointer->current_x, pointer->current_y);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -382,7 +233,8 @@ meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer)
|
||||
|
||||
pointer->grab = &pointer->default_grab;
|
||||
interface = pointer->grab->interface;
|
||||
interface->focus (pointer->grab, pointer->current, NULL);
|
||||
interface->focus (pointer->grab, pointer->current,
|
||||
pointer->current_x, pointer->current_y);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -410,245 +262,3 @@ meta_wayland_pointer_set_current (MetaWaylandPointer *pointer,
|
||||
&pointer->current_listener);
|
||||
pointer->current_listener.notify = current_surface_destroy;
|
||||
}
|
||||
|
||||
static void
|
||||
modal_focus (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
modal_motion (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
modal_button (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
}
|
||||
|
||||
static MetaWaylandPointerGrabInterface modal_grab = {
|
||||
modal_focus,
|
||||
modal_motion,
|
||||
modal_button
|
||||
};
|
||||
|
||||
gboolean
|
||||
meta_wayland_pointer_begin_modal (MetaWaylandPointer *pointer)
|
||||
{
|
||||
MetaWaylandPointerGrab *grab;
|
||||
|
||||
if (pointer->grab != &pointer->default_grab)
|
||||
return FALSE;
|
||||
|
||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||
|
||||
grab = g_slice_new0 (MetaWaylandPointerGrab);
|
||||
grab->interface = &modal_grab;
|
||||
meta_wayland_pointer_start_grab (pointer, grab);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer)
|
||||
{
|
||||
MetaWaylandPointerGrab *grab;
|
||||
|
||||
grab = pointer->grab;
|
||||
|
||||
g_assert (grab->interface == &modal_grab);
|
||||
|
||||
meta_wayland_pointer_end_grab (pointer);
|
||||
g_slice_free (MetaWaylandPointerGrab, grab);
|
||||
}
|
||||
|
||||
/* Called when the focused resource is destroyed */
|
||||
void
|
||||
meta_wayland_pointer_destroy_focus (MetaWaylandPointer *pointer)
|
||||
{
|
||||
if (pointer->grab == &pointer->default_grab)
|
||||
{
|
||||
/* The surface was destroyed, but had the implicit pointer grab.
|
||||
Bypass the grab interface. */
|
||||
g_assert (pointer->button_count > 0);
|
||||
|
||||
/* Note: we focus the NULL interface, not the current one, because
|
||||
we have button down, and the clients would be confused if the
|
||||
pointer enters the surface.
|
||||
*/
|
||||
meta_wayland_pointer_set_focus (pointer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
MetaWaylandPointerGrab generic;
|
||||
|
||||
struct wl_client *grab_client;
|
||||
struct wl_list all_popups;
|
||||
} MetaWaylandPopupGrab;
|
||||
|
||||
typedef struct {
|
||||
MetaWaylandPopupGrab *grab;
|
||||
MetaWaylandSurface *surface;
|
||||
struct wl_listener surface_destroy_listener;
|
||||
|
||||
struct wl_list link;
|
||||
} MetaWaylandPopup;
|
||||
|
||||
static void
|
||||
popup_grab_focus (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandPopupGrab *popup_grab = (MetaWaylandPopupGrab*)grab;
|
||||
|
||||
/* Popup grabs are in owner-events mode (ie, events for the same client
|
||||
are reported as normal) */
|
||||
if (wl_resource_get_client (surface->resource) == popup_grab->grab_client)
|
||||
default_grab_focus (grab, surface, event);
|
||||
else
|
||||
meta_wayland_pointer_set_focus (grab->pointer, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
popup_grab_motion (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
default_grab_motion (grab, event);
|
||||
}
|
||||
|
||||
static void
|
||||
popup_grab_button (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandPopupGrab *popup_grab = (MetaWaylandPopupGrab*)grab;
|
||||
MetaWaylandPointer *pointer = grab->pointer;
|
||||
|
||||
if (pointer->focus_resource)
|
||||
{
|
||||
/* This is ensured by popup_grab_focus */
|
||||
g_assert (wl_resource_get_client (pointer->focus_resource) == popup_grab->grab_client);
|
||||
|
||||
default_grab_button (grab, event);
|
||||
}
|
||||
else if (clutter_event_type (event) == CLUTTER_BUTTON_RELEASE &&
|
||||
pointer->button_count == 0)
|
||||
meta_wayland_pointer_end_popup_grab (grab->pointer);
|
||||
}
|
||||
|
||||
static MetaWaylandPointerGrabInterface popup_grab_interface = {
|
||||
popup_grab_focus,
|
||||
popup_grab_motion,
|
||||
popup_grab_button
|
||||
};
|
||||
|
||||
static void
|
||||
meta_wayland_pointer_end_popup_grab (MetaWaylandPointer *pointer)
|
||||
{
|
||||
MetaWaylandPopupGrab *popup_grab;
|
||||
MetaWaylandPopup *popup, *tmp;
|
||||
|
||||
popup_grab = (MetaWaylandPopupGrab*)pointer->grab;
|
||||
|
||||
g_assert (popup_grab->generic.interface == &popup_grab_interface);
|
||||
|
||||
wl_list_for_each_safe (popup, tmp, &popup_grab->all_popups, link)
|
||||
{
|
||||
MetaWaylandSurfaceExtension *shell_surface = popup->surface->shell_surface;
|
||||
|
||||
wl_shell_surface_send_popup_done (shell_surface->resource);
|
||||
wl_list_remove (&popup->surface_destroy_listener.link);
|
||||
wl_list_remove (&popup->link);
|
||||
g_slice_free (MetaWaylandPopup, popup);
|
||||
}
|
||||
|
||||
meta_wayland_pointer_end_grab (pointer);
|
||||
g_slice_free (MetaWaylandPopupGrab, popup_grab);
|
||||
}
|
||||
|
||||
static void
|
||||
on_popup_surface_destroy (struct wl_listener *listener,
|
||||
void *data)
|
||||
{
|
||||
MetaWaylandPopup *popup =
|
||||
wl_container_of (listener, popup, surface_destroy_listener);
|
||||
MetaWaylandPopupGrab *popup_grab = popup->grab;
|
||||
|
||||
wl_list_remove (&popup->link);
|
||||
g_slice_free (MetaWaylandPopup, popup);
|
||||
|
||||
if (wl_list_empty (&popup_grab->all_popups))
|
||||
meta_wayland_pointer_end_popup_grab (popup_grab->generic.pointer);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface)
|
||||
{
|
||||
MetaWaylandPopupGrab *grab;
|
||||
MetaWaylandPopup *popup;
|
||||
|
||||
if (pointer->grab != &pointer->default_grab)
|
||||
{
|
||||
if (pointer->grab->interface == &popup_grab_interface)
|
||||
{
|
||||
grab = (MetaWaylandPopupGrab*)pointer->grab;
|
||||
|
||||
if (wl_resource_get_client (surface->resource) != grab->grab_client)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pointer->grab == &pointer->default_grab)
|
||||
{
|
||||
grab = g_slice_new0 (MetaWaylandPopupGrab);
|
||||
grab->generic.interface = &popup_grab_interface;
|
||||
grab->generic.pointer = pointer;
|
||||
grab->grab_client = wl_resource_get_client (surface->resource);
|
||||
wl_list_init (&grab->all_popups);
|
||||
|
||||
meta_wayland_pointer_start_grab (pointer, (MetaWaylandPointerGrab*)grab);
|
||||
}
|
||||
else
|
||||
grab = (MetaWaylandPopupGrab*)pointer->grab;
|
||||
|
||||
popup = g_slice_new0 (MetaWaylandPopup);
|
||||
popup->grab = grab;
|
||||
popup->surface = surface;
|
||||
popup->surface_destroy_listener.notify = on_popup_surface_destroy;
|
||||
wl_resource_add_destroy_listener (surface->resource, &popup->surface_destroy_listener);
|
||||
|
||||
wl_list_insert (&grab->all_popups, &popup->link);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface,
|
||||
wl_fixed_t *sx,
|
||||
wl_fixed_t *sy)
|
||||
{
|
||||
float xf = 0.0f, yf = 0.0f;
|
||||
|
||||
if (surface->window)
|
||||
{
|
||||
ClutterActor *actor =
|
||||
CLUTTER_ACTOR (meta_window_get_compositor_private (surface->window));
|
||||
|
||||
if (actor)
|
||||
clutter_actor_transform_stage_point (actor,
|
||||
wl_fixed_to_double (pointer->x),
|
||||
wl_fixed_to_double (pointer->y),
|
||||
&xf, &yf);
|
||||
}
|
||||
|
||||
*sx = wl_fixed_from_double (xf);
|
||||
*sy = wl_fixed_from_double (yf);
|
||||
}
|
||||
|
||||
@@ -22,65 +22,19 @@
|
||||
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "meta-wayland-types.h"
|
||||
|
||||
struct _MetaWaylandPointerGrabInterface
|
||||
{
|
||||
void (*focus) (MetaWaylandPointerGrab *grab,
|
||||
MetaWaylandSurface *surface,
|
||||
const ClutterEvent *event);
|
||||
void (*motion) (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event);
|
||||
void (*button) (MetaWaylandPointerGrab *grab,
|
||||
const ClutterEvent *event);
|
||||
};
|
||||
|
||||
struct _MetaWaylandPointerGrab
|
||||
{
|
||||
const MetaWaylandPointerGrabInterface *interface;
|
||||
MetaWaylandPointer *pointer;
|
||||
};
|
||||
|
||||
struct _MetaWaylandPointer
|
||||
{
|
||||
struct wl_list resource_list;
|
||||
MetaWaylandSurface *focus;
|
||||
struct wl_resource *focus_resource;
|
||||
struct wl_listener focus_listener;
|
||||
guint32 focus_serial;
|
||||
guint32 click_serial;
|
||||
|
||||
MetaWaylandPointerGrab *grab;
|
||||
MetaWaylandPointerGrab default_grab;
|
||||
wl_fixed_t grab_x, grab_y;
|
||||
wl_fixed_t focus_x, focus_y;
|
||||
guint32 grab_button;
|
||||
guint32 grab_serial;
|
||||
guint32 grab_time;
|
||||
|
||||
wl_fixed_t x, y; /* TODO: remove, use ClutterInputDevice instead */
|
||||
MetaWaylandSurface *current;
|
||||
struct wl_listener current_listener;
|
||||
wl_fixed_t current_x, current_y;
|
||||
|
||||
guint32 button_count;
|
||||
};
|
||||
#include "meta-wayland-seat.h"
|
||||
|
||||
void
|
||||
meta_wayland_pointer_init (MetaWaylandPointer *pointer,
|
||||
gboolean is_native);
|
||||
meta_wayland_pointer_init (MetaWaylandPointer *pointer);
|
||||
|
||||
void
|
||||
meta_wayland_pointer_release (MetaWaylandPointer *pointer);
|
||||
|
||||
void
|
||||
meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface);
|
||||
void
|
||||
meta_wayland_pointer_destroy_focus (MetaWaylandPointer *pointer);
|
||||
|
||||
MetaWaylandSurface *surface,
|
||||
wl_fixed_t sx,
|
||||
wl_fixed_t sy);
|
||||
void
|
||||
meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
||||
MetaWaylandPointerGrab *grab);
|
||||
@@ -88,23 +42,8 @@ meta_wayland_pointer_start_grab (MetaWaylandPointer *pointer,
|
||||
void
|
||||
meta_wayland_pointer_end_grab (MetaWaylandPointer *pointer);
|
||||
|
||||
gboolean
|
||||
meta_wayland_pointer_begin_modal (MetaWaylandPointer *pointer);
|
||||
void
|
||||
meta_wayland_pointer_end_modal (MetaWaylandPointer *pointer);
|
||||
|
||||
gboolean
|
||||
meta_wayland_pointer_start_popup_grab (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *popup);
|
||||
|
||||
void
|
||||
meta_wayland_pointer_set_current (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface);
|
||||
|
||||
void
|
||||
meta_wayland_pointer_get_relative_coordinates (MetaWaylandPointer *pointer,
|
||||
MetaWaylandSurface *surface,
|
||||
wl_fixed_t *x,
|
||||
wl_fixed_t *y);
|
||||
|
||||
#endif /* __META_WAYLAND_POINTER_H__ */
|
||||
|
||||
@@ -28,13 +28,43 @@
|
||||
#include <cairo.h>
|
||||
|
||||
#include "window-private.h"
|
||||
#include "meta-weston-launch.h"
|
||||
#include <meta/meta-cursor-tracker.h>
|
||||
|
||||
#include "meta-wayland-types.h"
|
||||
#include "meta-wayland-versions.h"
|
||||
#include "meta-wayland-surface.h"
|
||||
#include "meta-wayland-seat.h"
|
||||
typedef struct _MetaWaylandCompositor MetaWaylandCompositor;
|
||||
|
||||
typedef struct _MetaWaylandSeat MetaWaylandSeat;
|
||||
typedef struct _MetaWaylandPointer MetaWaylandPointer;
|
||||
typedef struct _MetaWaylandPointerGrab MetaWaylandPointerGrab;
|
||||
typedef struct _MetaWaylandPointerGrabInterface MetaWaylandPointerGrabInterface;
|
||||
typedef struct _MetaWaylandKeyboard MetaWaylandKeyboard;
|
||||
typedef struct _MetaWaylandKeyboardGrab MetaWaylandKeyboardGrab;
|
||||
typedef struct _MetaWaylandKeyboardGrabInterface MetaWaylandKeyboardGrabInterface;
|
||||
typedef struct _MetaWaylandDataOffer MetaWaylandDataOffer;
|
||||
typedef struct _MetaWaylandDataSource MetaWaylandDataSource;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
struct wl_signal destroy_signal;
|
||||
struct wl_listener destroy_listener;
|
||||
|
||||
union
|
||||
{
|
||||
struct wl_shm_buffer *shm_buffer;
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
|
||||
struct wl_buffer *legacy_buffer;
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS;
|
||||
};
|
||||
|
||||
int32_t width, height;
|
||||
uint32_t busy_count;
|
||||
} MetaWaylandBuffer;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaWaylandBuffer *buffer;
|
||||
struct wl_listener destroy_listener;
|
||||
} MetaWaylandBufferReference;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -42,6 +72,46 @@ typedef struct
|
||||
cairo_region_t *region;
|
||||
} MetaWaylandRegion;
|
||||
|
||||
struct _MetaWaylandSurface
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandCompositor *compositor;
|
||||
guint32 xid;
|
||||
int x;
|
||||
int y;
|
||||
MetaWaylandBufferReference buffer_ref;
|
||||
MetaWindow *window;
|
||||
gboolean has_shell_surface;
|
||||
|
||||
/* All the pending state, that wl_surface.commit will apply. */
|
||||
struct
|
||||
{
|
||||
/* wl_surface.attach */
|
||||
gboolean newly_attached;
|
||||
MetaWaylandBuffer *buffer;
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
int32_t sx;
|
||||
int32_t sy;
|
||||
|
||||
/* wl_surface.damage */
|
||||
cairo_region_t *damage;
|
||||
|
||||
/* wl_surface.frame */
|
||||
struct wl_list frame_callback_list;
|
||||
} pending;
|
||||
};
|
||||
|
||||
#ifndef HAVE_META_WAYLAND_SURFACE_TYPE
|
||||
typedef struct _MetaWaylandSurface MetaWaylandSurface;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
struct wl_resource *resource;
|
||||
struct wl_listener surface_destroy_listener;
|
||||
} MetaWaylandShellSurface;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GSource source;
|
||||
@@ -62,7 +132,6 @@ typedef struct
|
||||
struct _MetaWaylandCompositor
|
||||
{
|
||||
struct wl_display *wayland_display;
|
||||
char *display_name;
|
||||
struct wl_event_loop *wayland_loop;
|
||||
GMainLoop *init_loop;
|
||||
ClutterActor *stage;
|
||||
@@ -79,9 +148,6 @@ struct _MetaWaylandCompositor
|
||||
struct wl_client *xwayland_client;
|
||||
struct wl_resource *xserver_resource;
|
||||
|
||||
MetaLauncher *launcher;
|
||||
int drm_fd;
|
||||
|
||||
MetaWaylandSeat *seat;
|
||||
|
||||
/* This surface is only used to keep drag of the implicit grab when
|
||||
@@ -93,6 +159,173 @@ struct _MetaWaylandCompositor
|
||||
guint32 implicit_grab_button;
|
||||
};
|
||||
|
||||
struct _MetaWaylandPointerGrabInterface
|
||||
{
|
||||
void (*focus) (MetaWaylandPointerGrab * grab,
|
||||
MetaWaylandSurface * surface, wl_fixed_t x, wl_fixed_t y);
|
||||
void (*motion) (MetaWaylandPointerGrab * grab,
|
||||
uint32_t time, wl_fixed_t x, wl_fixed_t y);
|
||||
void (*button) (MetaWaylandPointerGrab * grab,
|
||||
uint32_t time, uint32_t button, uint32_t state);
|
||||
};
|
||||
|
||||
struct _MetaWaylandPointerGrab
|
||||
{
|
||||
const MetaWaylandPointerGrabInterface *interface;
|
||||
MetaWaylandPointer *pointer;
|
||||
MetaWaylandSurface *focus;
|
||||
wl_fixed_t x, y;
|
||||
};
|
||||
|
||||
struct _MetaWaylandPointer
|
||||
{
|
||||
struct wl_list resource_list;
|
||||
MetaWaylandSurface *focus;
|
||||
struct wl_resource *focus_resource;
|
||||
struct wl_listener focus_listener;
|
||||
guint32 focus_serial;
|
||||
struct wl_signal focus_signal;
|
||||
|
||||
MetaWaylandPointerGrab *grab;
|
||||
MetaWaylandPointerGrab default_grab;
|
||||
wl_fixed_t grab_x, grab_y;
|
||||
guint32 grab_button;
|
||||
guint32 grab_serial;
|
||||
guint32 grab_time;
|
||||
|
||||
wl_fixed_t x, y;
|
||||
MetaWaylandSurface *current;
|
||||
struct wl_listener current_listener;
|
||||
wl_fixed_t current_x, current_y;
|
||||
|
||||
guint32 button_count;
|
||||
};
|
||||
|
||||
struct _MetaWaylandKeyboardGrabInterface
|
||||
{
|
||||
void (*key) (MetaWaylandKeyboardGrab * grab, uint32_t time,
|
||||
uint32_t key, uint32_t state);
|
||||
void (*modifiers) (MetaWaylandKeyboardGrab * grab, uint32_t serial,
|
||||
uint32_t mods_depressed, uint32_t mods_latched,
|
||||
uint32_t mods_locked, uint32_t group);
|
||||
};
|
||||
|
||||
struct _MetaWaylandKeyboardGrab
|
||||
{
|
||||
const MetaWaylandKeyboardGrabInterface *interface;
|
||||
MetaWaylandKeyboard *keyboard;
|
||||
MetaWaylandSurface *focus;
|
||||
uint32_t key;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct xkb_keymap *keymap;
|
||||
int keymap_fd;
|
||||
size_t keymap_size;
|
||||
char *keymap_area;
|
||||
xkb_mod_index_t shift_mod;
|
||||
xkb_mod_index_t caps_mod;
|
||||
xkb_mod_index_t ctrl_mod;
|
||||
xkb_mod_index_t alt_mod;
|
||||
xkb_mod_index_t mod2_mod;
|
||||
xkb_mod_index_t mod3_mod;
|
||||
xkb_mod_index_t super_mod;
|
||||
xkb_mod_index_t mod5_mod;
|
||||
} MetaWaylandXkbInfo;
|
||||
|
||||
struct _MetaWaylandKeyboard
|
||||
{
|
||||
struct wl_list resource_list;
|
||||
MetaWaylandSurface *focus;
|
||||
struct wl_resource *focus_resource;
|
||||
struct wl_listener focus_listener;
|
||||
uint32_t focus_serial;
|
||||
struct wl_signal focus_signal;
|
||||
|
||||
MetaWaylandKeyboardGrab *grab;
|
||||
MetaWaylandKeyboardGrab default_grab;
|
||||
uint32_t grab_key;
|
||||
uint32_t grab_serial;
|
||||
uint32_t grab_time;
|
||||
|
||||
struct wl_array keys;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32_t mods_depressed;
|
||||
uint32_t mods_latched;
|
||||
uint32_t mods_locked;
|
||||
uint32_t group;
|
||||
} modifiers;
|
||||
|
||||
struct wl_display *display;
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
|
||||
MetaWaylandXkbInfo xkb_info;
|
||||
struct xkb_rule_names xkb_names;
|
||||
|
||||
MetaWaylandKeyboardGrab input_method_grab;
|
||||
struct wl_resource *input_method_resource;
|
||||
|
||||
ClutterModifierType last_modifier_state;
|
||||
};
|
||||
|
||||
struct _MetaWaylandDataOffer
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandDataSource *source;
|
||||
struct wl_listener source_destroy_listener;
|
||||
};
|
||||
|
||||
struct _MetaWaylandDataSource
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
struct wl_array mime_types;
|
||||
|
||||
void (*accept) (MetaWaylandDataSource * source,
|
||||
uint32_t serial, const char *mime_type);
|
||||
void (*send) (MetaWaylandDataSource * source,
|
||||
const char *mime_type, int32_t fd);
|
||||
void (*cancel) (MetaWaylandDataSource * source);
|
||||
};
|
||||
|
||||
struct _MetaWaylandSeat
|
||||
{
|
||||
struct wl_list base_resource_list;
|
||||
struct wl_signal destroy_signal;
|
||||
|
||||
uint32_t selection_serial;
|
||||
MetaWaylandDataSource *selection_data_source;
|
||||
struct wl_listener selection_data_source_listener;
|
||||
struct wl_signal selection_signal;
|
||||
|
||||
struct wl_list drag_resource_list;
|
||||
struct wl_client *drag_client;
|
||||
MetaWaylandDataSource *drag_data_source;
|
||||
struct wl_listener drag_data_source_listener;
|
||||
MetaWaylandSurface *drag_focus;
|
||||
struct wl_resource *drag_focus_resource;
|
||||
struct wl_listener drag_focus_listener;
|
||||
MetaWaylandPointerGrab drag_grab;
|
||||
MetaWaylandSurface *drag_surface;
|
||||
struct wl_listener drag_icon_listener;
|
||||
struct wl_signal drag_icon_signal;
|
||||
|
||||
MetaWaylandPointer pointer;
|
||||
MetaWaylandKeyboard keyboard;
|
||||
|
||||
struct wl_display *display;
|
||||
|
||||
MetaCursorTracker *cursor_tracker;
|
||||
MetaWaylandSurface *sprite;
|
||||
int hotspot_x, hotspot_y;
|
||||
struct wl_listener sprite_destroy_listener;
|
||||
|
||||
ClutterActor *current_stage;
|
||||
};
|
||||
|
||||
void meta_wayland_init (void);
|
||||
void meta_wayland_finalize (void);
|
||||
|
||||
@@ -105,13 +338,6 @@ void meta_wayland_compositor_repick (MetaWaylandComp
|
||||
void meta_wayland_compositor_set_input_focus (MetaWaylandCompositor *compositor,
|
||||
MetaWindow *window);
|
||||
|
||||
MetaLauncher *meta_wayland_compositor_get_launcher (MetaWaylandCompositor *compositor);
|
||||
gboolean meta_wayland_compositor_is_native (MetaWaylandCompositor *compositor);
|
||||
|
||||
MetaWaylandBuffer * meta_wayland_buffer_from_resource (struct wl_resource *resource);
|
||||
|
||||
void meta_wayland_buffer_reference (MetaWaylandBufferReference *ref,
|
||||
MetaWaylandBuffer *buffer);
|
||||
|
||||
void meta_wayland_surface_free (MetaWaylandSurface *surface);
|
||||
|
||||
#endif /* META_WAYLAND_PRIVATE_H */
|
||||
|
||||
@@ -47,12 +47,37 @@ unbind_resource (struct wl_resource *resource)
|
||||
wl_list_remove (wl_resource_get_link (resource));
|
||||
}
|
||||
|
||||
static void
|
||||
transform_stage_point_fixed (MetaWaylandSurface *surface,
|
||||
wl_fixed_t x,
|
||||
wl_fixed_t y,
|
||||
wl_fixed_t *sx,
|
||||
wl_fixed_t *sy)
|
||||
{
|
||||
float xf = 0.0f, yf = 0.0f;
|
||||
|
||||
if (surface->window)
|
||||
{
|
||||
ClutterActor *actor =
|
||||
CLUTTER_ACTOR (meta_window_get_compositor_private (surface->window));
|
||||
|
||||
if (actor)
|
||||
clutter_actor_transform_stage_point (actor,
|
||||
wl_fixed_to_double (x),
|
||||
wl_fixed_to_double (y),
|
||||
&xf, &yf);
|
||||
}
|
||||
|
||||
*sx = wl_fixed_from_double (xf);
|
||||
*sy = wl_fixed_from_double (yf);
|
||||
}
|
||||
|
||||
static void
|
||||
pointer_unmap_sprite (MetaWaylandSeat *seat)
|
||||
{
|
||||
if (seat->cursor_tracker)
|
||||
{
|
||||
meta_cursor_tracker_set_buffer (seat->cursor_tracker,
|
||||
meta_cursor_tracker_set_sprite (seat->cursor_tracker,
|
||||
NULL, 0, 0);
|
||||
|
||||
if (seat->current_stage)
|
||||
@@ -70,20 +95,29 @@ pointer_unmap_sprite (MetaWaylandSeat *seat)
|
||||
void
|
||||
meta_wayland_seat_update_sprite (MetaWaylandSeat *seat)
|
||||
{
|
||||
ClutterBackend *backend;
|
||||
CoglContext *context;
|
||||
struct wl_resource *buffer;
|
||||
CoglTexture2D *texture;
|
||||
|
||||
if (seat->cursor_tracker == NULL)
|
||||
return;
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
context = clutter_backend_get_cogl_context (backend);
|
||||
buffer = seat->sprite->buffer_ref.buffer->resource;
|
||||
meta_cursor_tracker_set_buffer (seat->cursor_tracker,
|
||||
buffer,
|
||||
texture = cogl_wayland_texture_2d_new_from_buffer (context, buffer, NULL);
|
||||
|
||||
meta_cursor_tracker_set_sprite (seat->cursor_tracker,
|
||||
texture,
|
||||
seat->hotspot_x,
|
||||
seat->hotspot_y);
|
||||
|
||||
if (seat->current_stage)
|
||||
meta_cursor_tracker_queue_redraw (seat->cursor_tracker,
|
||||
CLUTTER_ACTOR (seat->current_stage));
|
||||
|
||||
cogl_object_unref (texture);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -141,14 +175,26 @@ seat_get_pointer (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
||||
struct wl_resource *cr;
|
||||
|
||||
cr = wl_resource_create (client, &wl_pointer_interface,
|
||||
MIN (META_WL_POINTER_VERSION, wl_resource_get_version (resource)), id);
|
||||
wl_resource_set_implementation (cr, &pointer_interface, seat, unbind_resource);
|
||||
cr = wl_client_add_object (client, &wl_pointer_interface,
|
||||
&pointer_interface, id, seat);
|
||||
wl_list_insert (&seat->pointer.resource_list, wl_resource_get_link (cr));
|
||||
wl_resource_set_destructor (cr, unbind_resource);
|
||||
|
||||
if (seat->pointer.focus &&
|
||||
wl_resource_get_client (seat->pointer.focus->resource) == client)
|
||||
meta_wayland_pointer_set_focus (&seat->pointer, seat->pointer.focus);
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
wl_fixed_t sx, sy;
|
||||
|
||||
surface = (MetaWaylandSurface *) seat->pointer.focus;
|
||||
transform_stage_point_fixed (surface,
|
||||
seat->pointer.x,
|
||||
seat->pointer.y,
|
||||
&sx, &sy);
|
||||
meta_wayland_pointer_set_focus (&seat->pointer,
|
||||
seat->pointer.focus,
|
||||
sx, sy);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -159,10 +205,9 @@ seat_get_keyboard (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = wl_resource_get_user_data (resource);
|
||||
struct wl_resource *cr;
|
||||
|
||||
cr = wl_resource_create (client, &wl_keyboard_interface,
|
||||
MIN (META_WL_KEYBOARD_VERSION, wl_resource_get_version (resource)), id);
|
||||
wl_resource_set_implementation (cr, NULL, seat, unbind_resource);
|
||||
cr = wl_client_add_object (client, &wl_keyboard_interface, NULL, id, seat);
|
||||
wl_list_insert (&seat->keyboard.resource_list, wl_resource_get_link (cr));
|
||||
wl_resource_set_destructor (cr, unbind_resource);
|
||||
|
||||
wl_keyboard_send_keymap (cr,
|
||||
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
||||
@@ -172,7 +217,8 @@ seat_get_keyboard (struct wl_client *client,
|
||||
if (seat->keyboard.focus &&
|
||||
wl_resource_get_client (seat->keyboard.focus->resource) == client)
|
||||
{
|
||||
meta_wayland_keyboard_set_focus (&seat->keyboard, seat->keyboard.focus);
|
||||
meta_wayland_keyboard_set_focus (&seat->keyboard,
|
||||
seat->keyboard.focus);
|
||||
meta_wayland_data_device_set_keyboard_focus (seat);
|
||||
}
|
||||
}
|
||||
@@ -202,17 +248,17 @@ bind_seat (struct wl_client *client,
|
||||
MetaWaylandSeat *seat = data;
|
||||
struct wl_resource *resource;
|
||||
|
||||
resource = wl_resource_create (client, &wl_seat_interface,
|
||||
MIN (META_WL_SEAT_VERSION, version), id);
|
||||
wl_resource_set_implementation (resource, &seat_interface, seat, unbind_resource);
|
||||
resource = wl_client_add_object (client,
|
||||
&wl_seat_interface,
|
||||
&seat_interface,
|
||||
id,
|
||||
data);
|
||||
wl_list_insert (&seat->base_resource_list, wl_resource_get_link (resource));
|
||||
wl_resource_set_destructor (resource, unbind_resource);
|
||||
|
||||
wl_seat_send_capabilities (resource,
|
||||
WL_SEAT_CAPABILITY_POINTER |
|
||||
WL_SEAT_CAPABILITY_KEYBOARD);
|
||||
|
||||
if (version >= META_WL_SEAT_HAS_NAME)
|
||||
wl_seat_send_name (resource, "seat0");
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -225,18 +271,21 @@ pointer_handle_sprite_destroy (struct wl_listener *listener, void *data)
|
||||
}
|
||||
|
||||
MetaWaylandSeat *
|
||||
meta_wayland_seat_new (struct wl_display *display,
|
||||
gboolean is_native)
|
||||
meta_wayland_seat_new (struct wl_display *display)
|
||||
{
|
||||
MetaWaylandSeat *seat = g_new0 (MetaWaylandSeat, 1);
|
||||
|
||||
wl_signal_init (&seat->destroy_signal);
|
||||
|
||||
seat->selection_data_source = NULL;
|
||||
wl_list_init (&seat->base_resource_list);
|
||||
wl_list_init (&seat->data_device_resource_list);
|
||||
wl_signal_init (&seat->selection_signal);
|
||||
wl_list_init (&seat->drag_resource_list);
|
||||
wl_signal_init (&seat->drag_icon_signal);
|
||||
|
||||
meta_wayland_pointer_init (&seat->pointer, is_native);
|
||||
meta_wayland_pointer_init (&seat->pointer);
|
||||
|
||||
meta_wayland_keyboard_init (&seat->keyboard, display, is_native);
|
||||
meta_wayland_keyboard_init (&seat->keyboard, display);
|
||||
|
||||
seat->display = display;
|
||||
|
||||
@@ -247,13 +296,13 @@ meta_wayland_seat_new (struct wl_display *display,
|
||||
seat->hotspot_x = 16;
|
||||
seat->hotspot_y = 16;
|
||||
|
||||
wl_global_create (display, &wl_seat_interface, META_WL_SEAT_VERSION, seat, bind_seat);
|
||||
wl_display_add_global (display, &wl_seat_interface, seat, bind_seat);
|
||||
|
||||
return seat;
|
||||
}
|
||||
|
||||
static void
|
||||
notify_motion (MetaWaylandSeat *seat,
|
||||
notify_motion (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
MetaWaylandPointer *pointer = &seat->pointer;
|
||||
@@ -263,64 +312,91 @@ notify_motion (MetaWaylandSeat *seat,
|
||||
pointer->x = wl_fixed_from_double (x);
|
||||
pointer->y = wl_fixed_from_double (y);
|
||||
|
||||
meta_wayland_seat_repick (seat, event);
|
||||
meta_wayland_seat_repick (seat,
|
||||
clutter_event_get_time (event),
|
||||
clutter_event_get_source (event));
|
||||
|
||||
pointer->grab->interface->motion (pointer->grab, event);
|
||||
pointer->grab->interface->motion (pointer->grab,
|
||||
clutter_event_get_time (event),
|
||||
pointer->grab->x,
|
||||
pointer->grab->y);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_motion_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
handle_motion_event (MetaWaylandSeat *seat,
|
||||
const ClutterMotionEvent *event)
|
||||
{
|
||||
notify_motion (seat, event);
|
||||
notify_motion (seat, (const ClutterEvent *) event);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_button_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
handle_button_event (MetaWaylandSeat *seat,
|
||||
const ClutterButtonEvent *event)
|
||||
{
|
||||
MetaWaylandPointer *pointer = &seat->pointer;
|
||||
gboolean state = event->type == CLUTTER_BUTTON_PRESS;
|
||||
uint32_t button;
|
||||
MetaWaylandSurface *surface;
|
||||
|
||||
notify_motion (seat, event);
|
||||
notify_motion (seat, (const ClutterEvent *) event);
|
||||
|
||||
if (state && pointer->button_count == 1)
|
||||
switch (event->button)
|
||||
{
|
||||
button = clutter_event_get_button (event);
|
||||
pointer->grab_button = button;
|
||||
pointer->grab_time = clutter_event_get_time (event);
|
||||
pointer->grab_x = pointer->x;
|
||||
pointer->grab_y = pointer->y;
|
||||
/* The evdev input right and middle button numbers are swapped
|
||||
relative to how Clutter numbers them */
|
||||
case 2:
|
||||
button = BTN_MIDDLE;
|
||||
break;
|
||||
|
||||
/* FIXME: synth a XI2 event and handle in display.c */
|
||||
surface = pointer->current;
|
||||
if (button == CLUTTER_BUTTON_PRIMARY &&
|
||||
surface &&
|
||||
surface->window &&
|
||||
surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
{
|
||||
meta_window_raise (surface->window);
|
||||
}
|
||||
case 3:
|
||||
button = BTN_RIGHT;
|
||||
break;
|
||||
|
||||
default:
|
||||
button = event->button + BTN_LEFT - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
pointer->grab->interface->button (pointer->grab, event);
|
||||
if (state)
|
||||
{
|
||||
if (pointer->button_count == 0)
|
||||
{
|
||||
MetaWaylandSurface *surface = pointer->current;
|
||||
|
||||
pointer->grab_button = button;
|
||||
pointer->grab_time = event->time;
|
||||
pointer->grab_x = pointer->x;
|
||||
pointer->grab_y = pointer->y;
|
||||
|
||||
if (button == BTN_LEFT &&
|
||||
surface &&
|
||||
surface->window &&
|
||||
surface->window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND)
|
||||
{
|
||||
meta_window_raise (surface->window);
|
||||
}
|
||||
}
|
||||
|
||||
pointer->button_count++;
|
||||
}
|
||||
else
|
||||
pointer->button_count--;
|
||||
|
||||
pointer->grab->interface->button (pointer->grab, event->time, button, state);
|
||||
|
||||
if (pointer->button_count == 1)
|
||||
pointer->grab_serial = wl_display_get_serial (seat->display);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_scroll_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
handle_scroll_event (MetaWaylandSeat *seat,
|
||||
const ClutterScrollEvent *event)
|
||||
{
|
||||
enum wl_pointer_axis axis;
|
||||
wl_fixed_t value;
|
||||
|
||||
notify_motion (seat, event);
|
||||
notify_motion (seat, (const ClutterEvent *) event);
|
||||
|
||||
switch (clutter_event_get_scroll_direction (event))
|
||||
switch (event->direction)
|
||||
{
|
||||
case CLUTTER_SCROLL_UP:
|
||||
axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
|
||||
@@ -348,64 +424,41 @@ handle_scroll_event (MetaWaylandSeat *seat,
|
||||
|
||||
if (seat->pointer.focus_resource)
|
||||
wl_pointer_send_axis (seat->pointer.focus_resource,
|
||||
clutter_event_get_time (event),
|
||||
event->time,
|
||||
axis,
|
||||
value);
|
||||
}
|
||||
|
||||
static int
|
||||
count_buttons (const ClutterEvent *event)
|
||||
{
|
||||
static gint maskmap[5] =
|
||||
{
|
||||
CLUTTER_BUTTON1_MASK, CLUTTER_BUTTON2_MASK, CLUTTER_BUTTON3_MASK,
|
||||
CLUTTER_BUTTON4_MASK, CLUTTER_BUTTON5_MASK
|
||||
};
|
||||
ClutterModifierType mod_mask;
|
||||
int i, count;
|
||||
|
||||
mod_mask = clutter_event_get_state (event);
|
||||
count = 0;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
if (mod_mask & maskmap[i])
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
gboolean
|
||||
void
|
||||
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
seat->pointer.button_count = count_buttons (event);
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_MOTION:
|
||||
handle_motion_event (seat, event);
|
||||
handle_motion_event (seat,
|
||||
(const ClutterMotionEvent *) event);
|
||||
break;
|
||||
|
||||
case CLUTTER_BUTTON_PRESS:
|
||||
case CLUTTER_BUTTON_RELEASE:
|
||||
handle_button_event (seat, event);
|
||||
handle_button_event (seat,
|
||||
(const ClutterButtonEvent *) event);
|
||||
break;
|
||||
|
||||
case CLUTTER_KEY_PRESS:
|
||||
case CLUTTER_KEY_RELEASE:
|
||||
return meta_wayland_keyboard_handle_event (&seat->keyboard,
|
||||
(const ClutterKeyEvent *) event);
|
||||
meta_wayland_keyboard_handle_event (&seat->keyboard,
|
||||
(const ClutterKeyEvent *) event);
|
||||
break;
|
||||
|
||||
case CLUTTER_SCROLL:
|
||||
handle_scroll_event (seat, event);
|
||||
handle_scroll_event (seat, (const ClutterScrollEvent *) event);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -428,18 +481,14 @@ update_pointer_position_for_actor (MetaWaylandPointer *pointer,
|
||||
case Clutter will have already performed a pick so we can avoid
|
||||
redundantly doing another one */
|
||||
void
|
||||
meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *for_event)
|
||||
meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
||||
uint32_t time,
|
||||
ClutterActor *actor)
|
||||
{
|
||||
ClutterActor *actor = NULL;
|
||||
MetaWaylandPointer *pointer = &seat->pointer;
|
||||
MetaWaylandSurface *surface = NULL;
|
||||
|
||||
if (for_event)
|
||||
{
|
||||
actor = clutter_event_get_source (for_event);
|
||||
}
|
||||
else if (seat->current_stage)
|
||||
if (actor == NULL && seat->current_stage)
|
||||
{
|
||||
ClutterStage *stage = CLUTTER_STAGE (seat->current_stage);
|
||||
actor = clutter_stage_get_actor_at_pos (stage,
|
||||
@@ -477,8 +526,16 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
||||
const MetaWaylandPointerGrabInterface *interface =
|
||||
pointer->grab->interface;
|
||||
interface->focus (pointer->grab,
|
||||
surface, for_event);
|
||||
surface,
|
||||
pointer->current_x, pointer->current_y);
|
||||
}
|
||||
|
||||
if (pointer->grab->focus)
|
||||
transform_stage_point_fixed (pointer->grab->focus,
|
||||
pointer->x,
|
||||
pointer->y,
|
||||
&pointer->grab->x,
|
||||
&pointer->grab->y);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -489,5 +546,7 @@ meta_wayland_seat_free (MetaWaylandSeat *seat)
|
||||
meta_wayland_pointer_release (&seat->pointer);
|
||||
meta_wayland_keyboard_release (&seat->keyboard);
|
||||
|
||||
wl_signal_emit (&seat->destroy_signal, seat);
|
||||
|
||||
g_slice_free (MetaWaylandSeat, seat);
|
||||
}
|
||||
|
||||
@@ -27,63 +27,19 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <meta/meta-cursor-tracker.h>
|
||||
#include "meta-wayland-types.h"
|
||||
#include "meta-wayland-keyboard.h"
|
||||
#include "meta-wayland-pointer.h"
|
||||
|
||||
struct _MetaWaylandDataOffer
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
MetaWaylandDataSource *source;
|
||||
struct wl_listener source_destroy_listener;
|
||||
};
|
||||
|
||||
struct _MetaWaylandDataSource
|
||||
{
|
||||
struct wl_resource *resource;
|
||||
struct wl_array mime_types;
|
||||
|
||||
void (*accept) (MetaWaylandDataSource * source,
|
||||
uint32_t serial, const char *mime_type);
|
||||
void (*send) (MetaWaylandDataSource * source,
|
||||
const char *mime_type, int32_t fd);
|
||||
void (*cancel) (MetaWaylandDataSource * source);
|
||||
};
|
||||
|
||||
struct _MetaWaylandSeat
|
||||
{
|
||||
struct wl_list base_resource_list;
|
||||
|
||||
uint32_t selection_serial;
|
||||
MetaWaylandDataSource *selection_data_source;
|
||||
struct wl_listener selection_data_source_listener;
|
||||
|
||||
struct wl_list data_device_resource_list;
|
||||
MetaWaylandPointer pointer;
|
||||
MetaWaylandKeyboard keyboard;
|
||||
|
||||
struct wl_display *display;
|
||||
|
||||
MetaCursorTracker *cursor_tracker;
|
||||
MetaWaylandSurface *sprite;
|
||||
int hotspot_x, hotspot_y;
|
||||
struct wl_listener sprite_destroy_listener;
|
||||
|
||||
ClutterActor *current_stage;
|
||||
};
|
||||
#include "meta-wayland-private.h"
|
||||
|
||||
MetaWaylandSeat *
|
||||
meta_wayland_seat_new (struct wl_display *display,
|
||||
gboolean is_native);
|
||||
meta_wayland_seat_new (struct wl_display *display);
|
||||
|
||||
gboolean
|
||||
void
|
||||
meta_wayland_seat_handle_event (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *event);
|
||||
|
||||
void
|
||||
meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
||||
const ClutterEvent *for_event);
|
||||
meta_wayland_seat_repick (MetaWaylandSeat *seat,
|
||||
uint32_t time,
|
||||
ClutterActor *actor);
|
||||
|
||||
void
|
||||
meta_wayland_seat_update_sprite (MetaWaylandSeat *seat);
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
|
||||
#include "meta-wayland-stage.h"
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta/meta-window-actor.h"
|
||||
#include "meta/meta-shaped-texture.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user