Compare commits
438 Commits
Author | SHA1 | Date | |
---|---|---|---|
4917e367d5 | |||
955c3c7c71 | |||
8821162aef | |||
0356f7afb3 | |||
ba6fa54fdd | |||
b2d4ecab30 | |||
882a222d5c | |||
7b79c44608 | |||
580483d516 | |||
57c1078ee7 | |||
3a2920d4bc | |||
ad13fa3bb3 | |||
9b50119d31 | |||
3ff6316562 | |||
43058a3698 | |||
8c16ac47c1 | |||
6880cae3fb | |||
4fc684b2ed | |||
d63b9a1797 | |||
72bd934604 | |||
ed70e99b7b | |||
6d72b7c017 | |||
656fe49dbe | |||
3471ef3441 | |||
af9d8f1931 | |||
a30ca3e62f | |||
9e3bac0237 | |||
67a30b7a89 | |||
68ba45bcb2 | |||
6bacbac656 | |||
87e52b18c2 | |||
637cc9269d | |||
fcdd1944a4 | |||
5636784604 | |||
9a3b178da1 | |||
a1488005b6 | |||
cca68b31b1 | |||
85452aff4f | |||
d9d83abae2 | |||
0bc6cb2aeb | |||
d628cce058 | |||
b646e25fee | |||
94c3c8f412 | |||
d3988c04d6 | |||
dd0cb55997 | |||
aef27647a0 | |||
18f958d06d | |||
3efbb96119 | |||
e5d97666af | |||
83d7e932d6 | |||
f858f66fe0 | |||
fffb863f37 | |||
adf7c0e730 | |||
bbcee174ce | |||
9c6e6ea381 | |||
db9645fcb3 | |||
6af48d75a4 | |||
6234f7d1db | |||
301a65e05a | |||
376d4911b6 | |||
0559d2c19f | |||
54e482bc7b | |||
37c3b79551 | |||
78d8525699 | |||
23c00688b4 | |||
438410c22c | |||
59f348eb11 | |||
cbad65f657 | |||
1e8e107dd9 | |||
8631bf2bbb | |||
b9b41c20a6 | |||
2d3deccd8e | |||
68289a5d61 | |||
adccbc9b7b | |||
94b111cf6c | |||
7303955618 | |||
5e8bb9cc9d | |||
accfdf7936 | |||
c215247a6c | |||
96b202c80d | |||
0ac2f61a2c | |||
2aa6dcd9d8 | |||
469b85eb7c | |||
673ddfde04 | |||
56ca7eeb65 | |||
b414955230 | |||
af9072e725 | |||
9b903e93e3 | |||
7966f00a18 | |||
9a99a80710 | |||
be77874ec9 | |||
768286bffb | |||
f5c65d9ea1 | |||
f328890ed1 | |||
945bf626c6 | |||
f6869bbbc2 | |||
eafe11a7cf | |||
daba1b511b | |||
87a13d2c00 | |||
11a9b4baa0 | |||
de71fd0941 | |||
87c973c260 | |||
644ab0e270 | |||
3142220443 | |||
1f0ed5483a | |||
72f5a36522 | |||
7f19db1f7b | |||
3f2d658f20 | |||
05353c1f7e | |||
4d23e7c202 | |||
ad90b7dd2f | |||
3356a43c04 | |||
3a5a647d49 | |||
a2ff8f4e1e | |||
e294f6df8c | |||
422ddeddb9 | |||
8ef48a99ae | |||
9d7af8a5fc | |||
764c3dd137 | |||
7e7c8ecbd4 | |||
d561b3b18f | |||
ce14bde08d | |||
b91461ee39 | |||
22c13b3144 | |||
0bfebc3cae | |||
db384a656c | |||
1dea1813b1 | |||
71c4138933 | |||
9d73b4efbb | |||
049f67df0a | |||
2d878d3f55 | |||
3c06f2dc90 | |||
460e1fd7ca | |||
f083935c6e | |||
5c66bee84b | |||
ef32bbdc99 | |||
5f91a62f6f | |||
152b2dab59 | |||
625d3de2ee | |||
f71315eb1e | |||
0484ef142d | |||
6609d9c6a4 | |||
73c4342580 | |||
0d5c24f13d | |||
b6d070b06f | |||
87eb5f8632 | |||
5c60ea6635 | |||
9abcf424b8 | |||
cc7af83f8a | |||
ae91a174e9 | |||
9c73e21113 | |||
a1d8110221 | |||
9d6357f05a | |||
1fc58faff9 | |||
fea7ac84ee | |||
20bee6f48e | |||
fb5c0c3352 | |||
5bc2bcd109 | |||
d12390002a | |||
13acf9e35d | |||
3beb187cac | |||
a3b8dcbd04 | |||
3ff8b0051d | |||
a8bf7934fb | |||
7159845c6e | |||
7bccd4f22f | |||
e4e00b383e | |||
36454542ae | |||
34ba868b4c | |||
274ea76eea | |||
a180e8b87e | |||
26c8086190 | |||
34fbca0181 | |||
4496fb4447 | |||
7e66d2a484 | |||
12135afa5e | |||
cac660a5bc | |||
dcce4e64bc | |||
4d3511649b | |||
d4ea2bbd9c | |||
f303ec2eaa | |||
2ca4ed6b04 | |||
a5ad89dd65 | |||
4a4d724e59 | |||
8fdbae192a | |||
2413e672c8 | |||
c8432cc430 | |||
015864da09 | |||
669c9da2a4 | |||
4d1d8e831e | |||
9e199e6350 | |||
4673d8f245 | |||
90111c03a1 | |||
23681800d9 | |||
b47afe89d3 | |||
af7f51b992 | |||
f3d30d897f | |||
dcc4ce4ff4 | |||
b9fb4a5887 | |||
d9985cd9bc | |||
6e3f7b7ddc | |||
2dd1f37820 | |||
57af975154 | |||
c5940580ed | |||
8296d4cdce | |||
bf9a00d5c9 | |||
c1db9d9181 | |||
9d2cd8ff87 | |||
d514e8ab41 | |||
44a60eb7e9 | |||
6b92b45021 | |||
ee461b5495 | |||
46f3eb0b71 | |||
ef32899b4d | |||
5e9db422c9 | |||
662dd6a289 | |||
d5e6177900 | |||
34ac80348c | |||
8a7a01b0cf | |||
2cabc067d1 | |||
26c4c21e13 | |||
6eda784cf0 | |||
fb1459062f | |||
bc9547f29e | |||
89a371ec98 | |||
2db71e73b4 | |||
472f2a4b8e | |||
db04ac9eb7 | |||
75105e254f | |||
901a05ad80 | |||
ab6c4c82f6 | |||
cacb32482c | |||
4450b5bb14 | |||
34421e90c3 | |||
93b7137c62 | |||
5ad15bb5e5 | |||
cd4206764e | |||
b10a017446 | |||
d393cba39e | |||
578f593d56 | |||
55df99447a | |||
d45080d32e | |||
fa97364fa8 | |||
41303101e5 | |||
68542ae1ef | |||
0c730d8feb | |||
aeef98fd19 | |||
69079b3b48 | |||
ad7292faef | |||
2f7843b295 | |||
b24cd5ae08 | |||
c782078e00 | |||
5a86286aba | |||
b1ac83d3b6 | |||
e73f5cc8ab | |||
593b417e5e | |||
5e84c8f20b | |||
9745f9f8ce | |||
99f7be33ad | |||
6492845f27 | |||
fd1243d881 | |||
00535b34b6 | |||
a2b2a7a26f | |||
9fdf487da1 | |||
c5033616e9 | |||
a0e038f34b | |||
71dab32769 | |||
c408cf7aac | |||
e96eb0e82e | |||
0015963457 | |||
b832bc7424 | |||
89b14babb9 | |||
7ecde19aee | |||
d7854794cf | |||
f6f5f624d4 | |||
7012c82fc7 | |||
a0d2d207e7 | |||
6e25c37da1 | |||
061f434201 | |||
638087fe78 | |||
286a6ada5a | |||
cb66ab5a87 | |||
e72c6916aa | |||
8b98cb818c | |||
f8a4d450a5 | |||
681cf95236 | |||
90d6734f8c | |||
213cd8a334 | |||
3b1271d9be | |||
13b6bd20ca | |||
63e31af476 | |||
718a89eb2f | |||
a43ca7b5b1 | |||
af00ca534a | |||
4b2b431700 | |||
2c1a6b6a12 | |||
b3544f8ec1 | |||
df384965c3 | |||
700d367937 | |||
7c5989c978 | |||
8819d9ce66 | |||
b63413e5b0 | |||
cd1e1d4bf1 | |||
9710c013c5 | |||
05f8d79323 | |||
f2546dfeea | |||
47e339b46e | |||
016b8f5b4a | |||
b3821c4f90 | |||
29e5c6c363 | |||
e1704acda4 | |||
60cbb41f42 | |||
d88c8d9ced | |||
60ab11ecbf | |||
34516aeab6 | |||
a37f632b1b | |||
8a6542c242 | |||
7e12000d97 | |||
23f086da8a | |||
4c2c1c4dd2 | |||
545f298921 | |||
64295e8cd7 | |||
722d4c6c17 | |||
cc8462969d | |||
989bb6ebb1 | |||
1dbda68839 | |||
a460f88b31 | |||
3e511b9591 | |||
5664c703b7 | |||
5c80c4b006 | |||
22f91eba8d | |||
d07e2f4090 | |||
cd32e4a68a | |||
4040a70781 | |||
cb084cc841 | |||
2deea6e0a3 | |||
a116509301 | |||
ead79f834c | |||
7e431bd6bc | |||
272e1fb296 | |||
c39f18c2d4 | |||
33acb5fea0 | |||
591718dc02 | |||
b6127eeda4 | |||
eeff1b8b02 | |||
354cc466af | |||
9f5c38d121 | |||
ead0e902ed | |||
5d16194b03 | |||
a74acf0ec2 | |||
3044cfb7bf | |||
f658740043 | |||
c1613a16c0 | |||
8e85015f91 | |||
f127ee3bde | |||
acd928044f | |||
4ef2f2ce09 | |||
bc81736e6b | |||
49092397f2 | |||
97705d3cfe | |||
0364ea9140 | |||
c0bdb3018b | |||
924eaac358 | |||
a9f5a5661f | |||
9c589b6798 | |||
113be01ce8 | |||
28e59c5a8f | |||
b588baf9f5 | |||
9a825d9bee | |||
f211b3ec90 | |||
0510c3a621 | |||
18db5d0799 | |||
c061e26da5 | |||
166668adc4 | |||
ec797b055d | |||
082cc9c83a | |||
993bec37d7 | |||
e496ed50d6 | |||
a127d05790 | |||
607730e96c | |||
9203db0655 | |||
64d40792c4 | |||
e7356917b0 | |||
fa58752276 | |||
478b75e803 | |||
492a1b244f | |||
5d8ff2e34d | |||
310083aeb2 | |||
0faa900207 | |||
b735571688 | |||
5e249ad5eb | |||
21bffe4aef | |||
68283df4d9 | |||
4f3de2ce39 | |||
9f8b641472 | |||
a9a21c801c | |||
482a97466d | |||
4e14bb9df3 | |||
df90545258 | |||
c954f9cc24 | |||
d06b39d13c | |||
f3595ebd08 | |||
1e1ca47ec1 | |||
2eec11b445 | |||
8ff4597201 | |||
d5f2468d88 | |||
488dd0b402 | |||
6565bca210 | |||
60c22b6236 | |||
d3111a9f07 | |||
cdfb301200 | |||
371560c2b6 | |||
7616881afa | |||
74c37d49c4 | |||
d3142b92f0 | |||
ae2afa7c5e | |||
4a71621fbc | |||
565b9d73d5 | |||
90bd02ff4d | |||
73ca0efaeb | |||
790269db95 | |||
cb82bd8afa | |||
b1e06ed110 | |||
fabe66e65f | |||
4a965a37d1 | |||
302ff7b95a | |||
e2e241340c | |||
461aea47dd | |||
d87093fe29 | |||
0cde7879d6 | |||
89ffcee7ca | |||
1250afef7b | |||
3a577edaa7 | |||
48dfde2073 | |||
4a41d415f8 | |||
1fb7ca398d | |||
2b79935fd8 | |||
e3c915350e |
165
NEWS
165
NEWS
@ -1,3 +1,168 @@
|
||||
3.16.0
|
||||
======
|
||||
* wayland: Don't skip notifying about initial maximized state [Jonas; #745303]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl
|
||||
|
||||
Translations:
|
||||
Kjartan Maraas [nb], Jiri Grönroos [fi], Andika Triwidada [id],
|
||||
Inaki Larranaga Murgoitio [eu], Ask H. Larsen [da], Muhammet Kara [tr]
|
||||
|
||||
3.15.92
|
||||
=======
|
||||
* Ensure pointer visibility on monitor changes [Rui, Marek; #745121, #745752]
|
||||
* Fix geometry of shaded windows [Florian; #746145]
|
||||
* Take over cursor visibility handling from gsd [Carlos; #712775]
|
||||
* Fix touch interaction on window decorations [Carlos; #745335]
|
||||
* Add options for libinput_config_click_method [Carlos; #746290]
|
||||
* Scale window decorations on HiDPI displays [Florian; #744354]
|
||||
* Misc. bug fixes [Carlos, Ray, Rui; #745163, #746295, #746098, #745734]
|
||||
|
||||
Contributors:
|
||||
Marek Chalupa, Carlos Garnacho, Rui Matos, Florian Müllner,
|
||||
Jasper St. Pierre, Ray Strode
|
||||
|
||||
Translations:
|
||||
Piotr Drąg [pl], Milo Casagrande [it], Changwoo Ryu [ko],
|
||||
Daniel Korostil [uk], Baurzhan Muftakhidinov [kk], Trần Ngọc Quân [vi],
|
||||
Alexander Shopov [bg], Jordi Mas [ca], Samir Ribic [bs], A S Alam [pa],
|
||||
Matej Urbančič [sl]
|
||||
|
||||
3.15.91
|
||||
=======
|
||||
* wayland: Fix nested compositor mode [Jonas; #745401]
|
||||
* wayland: Fix pointer constraining [Marek; #727337]
|
||||
* wayland: Fix input region on HiDPI [Jonas; #744933]
|
||||
* Allow themes to style buttons differently based on function [Horst; #745108]
|
||||
* Misc. bug fixes and cleanups [Ray, Rui, Alban; #745141, #745118, #745476,
|
||||
#745442]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Alban Browaeys, Marek Chalupa, Horst, Rui Matos,
|
||||
Jasper St. Pierre, Ray Strode
|
||||
|
||||
Translations:
|
||||
Chao-Hsiung Liao [zh_TW], Efstathios Iosifidis [el], Dušan Kazik [sk],
|
||||
Balázs Úr [hu], Daniel Mustieles [es], Claude Paroz [fr], Stas Solovey [ru],
|
||||
Yosef Or Boczko [he], Rafael Ferreira [pt_BR], Aurimas Černius [lt],
|
||||
Fran Dieguez [gl], Anders Jonsson [sv], Мирослав Николић [sr, sr@latin]
|
||||
|
||||
3.15.90
|
||||
=======
|
||||
* Initialize MetaOutput even when we can't get the EDID [Rui; #743412]
|
||||
* Expose MetaMonitorManager to introspection [Rui; #743745]
|
||||
* Fix flash on unredirection [Chris; #743858]
|
||||
* Update xdg-shell implementation to v5 [Jonas; #744452]
|
||||
* Do not try to use seat devices that aren't (yet) present [Ray; #744640]
|
||||
* Add keybindings for switching to VT8-VT12 [Ray; #744800]
|
||||
* Misc bug fixes [Jonas, Cosimo; #743678, #744500]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Cosimo Cecchi, Carlos Garnacho, Rui Matos, Jasper St. Pierre,
|
||||
Ray Strode, Chris Wilson
|
||||
|
||||
Translations:
|
||||
Yosef Or Boczko [he], Yuri Myasoedov [ru], Kristjan SCHMIDT [eo],
|
||||
Matej Urbančič [sl], Dušan Kazik [sk]
|
||||
|
||||
3.15.4
|
||||
======
|
||||
* Use GTK+ theme for window decorations instead of metacity [Florian; #741917]
|
||||
* Export the same EDID information on X11 and wayland [Carlos; #742882]
|
||||
* Apply input device configuration on wayland [Carlos; #739397]
|
||||
* Implement pointer barriers on wayland [Jonas; #706655]
|
||||
* Misc. bug fixes (Ting-Wei, Rui, Ikey, Florian, Marek, Jonas; #741829,
|
||||
#738630, #737463, #698995, #727893, #742825, #742824, #742841, #743173,
|
||||
#743189, #743217, #743254]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Giovanni Campagna, Marek Chalupa, Ikey Doherty, Adel Gadllah,
|
||||
Carlos Garnacho, Ting-Wei Lan, Rui Matos, Florian Müllner, Jasper St. Pierre,
|
||||
Rico Tzschichholz
|
||||
|
||||
Translations:
|
||||
Matej Urbančič [sl], Balázs Úr [hu], Marek Černocký [cs],
|
||||
Inaki Larranaga Murgoitio [eu], Rafael Ferreira [pt_BR],
|
||||
Daniel Mustieles [es], Fran Dieguez [gl]
|
||||
|
||||
3.15.3
|
||||
======
|
||||
* Don't leave left-over frames queued [Owen; #738686]
|
||||
* Set CRTC configuration even if it might be redundant [Rui; #740838]
|
||||
|
||||
Contributors:
|
||||
Rui Matos, Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Trần Ngọc Quân [vi], Muhammet Kara [tr]
|
||||
|
||||
3.15.2
|
||||
======
|
||||
* Don't enable hiDPI on monitors with broken EDID [Bastien; #734839]
|
||||
* Prevent crash applying monitor config for a closed lid [Rui; #739450]
|
||||
* Fix "flicker" during startup transition [Ray; #740377]
|
||||
* Misc. bug fixes [Lan, Florian, Carlos; #731521, #740133, #738890]
|
||||
|
||||
Contributors:
|
||||
Emmanuele Bassi, Carlos Garnacho, Jonathon Jongsma, Ting-Wei Lan, Rui Matos,
|
||||
Florian Müllner, Bastien Nocera, Jasper St. Pierre, Ray Strode
|
||||
|
||||
Translations:
|
||||
Kjartan Maraas [nb]
|
||||
|
||||
3.15.1
|
||||
======
|
||||
* Use GResources for theme loading [Cosimo; #736936]
|
||||
* Fix headerbar drag getting stuck on xwayland [Carlos; #738411]
|
||||
* Fix wayland hiDPI regressions [Adel; #739161]
|
||||
* Misc bug fixes and cleanups [Jasper, Rui, Carlos; #662962, #738630, #738888,
|
||||
#738890]
|
||||
|
||||
Contributors:
|
||||
Cosimo Cecchi, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner,
|
||||
Jasper St. Pierre
|
||||
|
||||
3.14.1
|
||||
======
|
||||
* Fix move-titlebar-onscreen function [Florian; #736915]
|
||||
* Fix stacking of the guard window [Owen; #737233]
|
||||
* Fix keycode lookup for non-default layouts [Rui; #737134]
|
||||
* Fix workspaces-only-on-primary handling [Florian; #737178]
|
||||
* Don't unstick sticky windows on workspace removal [Florian; #737625]
|
||||
* Do not auto-minimize fullscreen windows [Jasper; #705177]
|
||||
* Upload keymap to newly added keyboard devices [Rui; #737673]
|
||||
* Apply keyboard repeat settings [Rui; #728055]
|
||||
* Don't send pressed keys on enter [Rui; #727178]
|
||||
* Fix build without wayland/native [Rico; #738225]
|
||||
* Send modifiers after the key event [Rui; #738238]
|
||||
* Fix unredirect heuristic [Adel; #738271]
|
||||
* Do not show system chrome over fullscreen windows [Florian; #693991]
|
||||
* Misc. bug fixes [Florian, Adel, Tom; #737135, #737581, #738146, #738384]
|
||||
|
||||
Contributors:
|
||||
Tom Beckmann, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner,
|
||||
Jasper St. Pierre, Rico Tzschichholz, Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Krishnababu Krothapalli [te], Мирослав Николић [sr, sr@latin],
|
||||
Alexander Shopov [bg], Saibal Ray [bn_IN], Milo Casagrande [it],
|
||||
Rūdolfs Mazurs [lv]
|
||||
|
||||
3.14.0
|
||||
======
|
||||
* Fix placement of popup windows on wayland [Jasper; #736812]
|
||||
* Only increment serial once per event [Jasper; #736840]
|
||||
* Fix window positioning regression with non-GTK+ toolkits [Owen; #736719]
|
||||
|
||||
Contributors:
|
||||
Jasper St. Pierre, Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Saibal Ray [bn_IN], Dušan Kazik [sk], Manoj Kumar Giri [or],
|
||||
Christian Kirbach [de], Ask H. Larsen [da], YunQiang Su [zh_CN],
|
||||
Bernd Homuth [de], Shankar Prasad [kn], Petr Kovar [cs], Rajesh Ranjan [hi]
|
||||
|
||||
3.13.92
|
||||
=======
|
||||
* Rewrite background code [Owen; #735637, #736568]
|
||||
|
@ -4,7 +4,6 @@
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
PKG_NAME="mutter"
|
||||
REQUIRED_AUTOMAKE_VERSION=1.11
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
@ -19,4 +18,4 @@ which gnome-autogen.sh || {
|
||||
echo "your distribution's package manager)."
|
||||
exit 1
|
||||
}
|
||||
USE_GNOME2_MACROS=1 USE_COMMON_DOC_BUILD=yes . gnome-autogen.sh
|
||||
. gnome-autogen.sh
|
||||
|
59
configure.ac
59
configure.ac
@ -1,8 +1,8 @@
|
||||
AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [13])
|
||||
m4_define([mutter_micro_version], [92])
|
||||
m4_define([mutter_minor_version], [16])
|
||||
m4_define([mutter_micro_version], [0])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@ -72,14 +72,12 @@ CLUTTER_PACKAGE=clutter-1.0
|
||||
|
||||
MUTTER_PC_MODULES="
|
||||
gtk+-3.0 >= 3.9.11
|
||||
gio-unix-2.0 >= 2.25.10
|
||||
gio-unix-2.0 >= 2.35.1
|
||||
pango >= 1.2.0
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.7.3
|
||||
$CLUTTER_PACKAGE >= 1.19.5
|
||||
clutter-egl-1.0
|
||||
gsettings-desktop-schemas >= 3.15.92
|
||||
$CLUTTER_PACKAGE >= 1.21.3
|
||||
cogl-1.0 >= 1.17.1
|
||||
gbm
|
||||
upower-glib >= 0.99.0
|
||||
gnome-desktop-3.0
|
||||
xcomposite >= 0.2
|
||||
@ -202,22 +200,39 @@ AC_SUBST(XWAYLAND_PATH)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd libinput], [have_native_backend=yes], [have_native_backend=no])
|
||||
if test $have_native_backend = yes; then
|
||||
AC_DEFINE([HAVE_NATIVE_BACKEND],[1],[Define if you want to enable the native (KMS) backend based on systemd])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test $have_native_backend = yes])
|
||||
MUTTER_NATIVE_BACKEND_MODULES="clutter-egl-1.0 libdrm libsystemd libinput gudev-1.0 gbm >= 10.3"
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_WAYLAND, [clutter-wayland-1.0 clutter-wayland-compositor-1.0 wayland-server >= 1.5.90], [have_wayland=yes], [have_wayland=no])
|
||||
if test $have_wayland = yes; then
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
AS_IF([test $WAYLAND_SCANNER = "no"],
|
||||
AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols]))
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_ARG_ENABLE(native-backend,
|
||||
AS_HELP_STRING([--disable-native-backend], [disable mutter native (KMS) backend]),,
|
||||
enable_native_backend=auto
|
||||
)
|
||||
AS_IF([test "$enable_native_backend" = "yes"], [have_native_backend=yes],
|
||||
[test "$enable_native_backend" = "auto"], PKG_CHECK_EXISTS([$MUTTER_NATIVE_BACKEND_MODULES], [have_native_backend=yes]))
|
||||
|
||||
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_WAYLAND],[test $have_wayland = yes])
|
||||
AS_IF([test "$have_native_backend" = "yes"], [
|
||||
PKG_CHECK_MODULES([MUTTER_NATIVE_BACKEND], [$MUTTER_NATIVE_BACKEND_MODULES])
|
||||
AC_DEFINE([HAVE_NATIVE_BACKEND],[1], [Define if you want to enable the native (KMS) backend based on systemd])
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_NATIVE_BACKEND],[test "$have_native_backend" = "yes"])
|
||||
|
||||
MUTTER_WAYLAND_MODULES="clutter-wayland-1.0 clutter-wayland-compositor-1.0 wayland-server >= 1.6.90"
|
||||
|
||||
AC_ARG_ENABLE(wayland,
|
||||
AS_HELP_STRING([--disable-wayland], [disable mutter on wayland support]),,
|
||||
enable_wayland=auto
|
||||
)
|
||||
AS_IF([test "$enable_wayland" = "yes"], [have_wayland=yes],
|
||||
[test "$enable_wayland" = "auto"], PKG_CHECK_EXISTS([$MUTTER_WAYLAND_MODULES], [have_wayland=yes]))
|
||||
|
||||
AS_IF([test "$have_wayland" = "yes"], [
|
||||
PKG_CHECK_MODULES([MUTTER_WAYLAND], [$MUTTER_WAYLAND_MODULES])
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
AS_IF([test $WAYLAND_SCANNER = "no"],
|
||||
[AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols])])
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
|
||||
])
|
||||
AM_CONDITIONAL([HAVE_WAYLAND],[test "$have_wayland" = "yes"])
|
||||
|
||||
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
|
||||
AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))
|
||||
@ -418,6 +433,8 @@ mutter-$VERSION
|
||||
libcanberra: ${have_libcanberra}
|
||||
Introspection: ${found_introspection}
|
||||
Session management: ${found_sm}
|
||||
Wayland: ${have_wayland}
|
||||
Native (KMS) backend: ${have_native_backend}
|
||||
"
|
||||
|
||||
|
||||
|
@ -29,5 +29,25 @@
|
||||
<default><![CDATA[['<Primary><Alt>F7']]]></default>
|
||||
<_summary>Switch to VT 7</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-8" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F8']]]></default>
|
||||
<_summary>Switch to VT 8</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-9" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F9']]]></default>
|
||||
<_summary>Switch to VT 9</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-10" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F10']]]></default>
|
||||
<_summary>Switch to VT 10</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-11" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F11']]]></default>
|
||||
<_summary>Switch to VT 11</_summary>
|
||||
</key>
|
||||
<key name="switch-to-session-12" type="as">
|
||||
<default><![CDATA[['<Primary><Alt>F12']]]></default>
|
||||
<_summary>Switch to VT 12</_summary>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
|
@ -1,4 +1,4 @@
|
||||
SUBDIRS = man reference
|
||||
|
||||
EXTRA_DIST=theme-format.txt dialogs.txt code-overview.txt \
|
||||
EXTRA_DIST = dialogs.txt code-overview.txt \
|
||||
how-to-get-focus-right.txt rationales.txt
|
||||
|
@ -81,6 +81,7 @@ IGNORE_HFILES= \
|
||||
keybindings-private.h \
|
||||
meta-background-actor-private.h \
|
||||
meta-background-group-private.h \
|
||||
meta-dbus-login1.h \
|
||||
meta-module.h \
|
||||
meta-plugin-manager.h \
|
||||
meta-shadow-factory-private.h \
|
||||
@ -111,6 +112,17 @@ IGNORE_HFILES= \
|
||||
xprops.h \
|
||||
$(NULL)
|
||||
|
||||
if !HAVE_NATIVE_BACKEND
|
||||
IGNORE_HFILES+= \
|
||||
meta-backend-native.h \
|
||||
meta-barrier-native.h \
|
||||
meta-cursor-renderer-native.h \
|
||||
meta-idle-monitor-native.h \
|
||||
meta-input-settings-native.h \
|
||||
meta-monitor-manager-kms.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
if !HAVE_WAYLAND
|
||||
IGNORE_HFILES += \
|
||||
meta-surface-actor-wayland.h \
|
||||
|
@ -22,7 +22,6 @@
|
||||
<title>Mutter Core Reference</title>
|
||||
<xi:include href="xml/main.xml"/>
|
||||
<xi:include href="xml/common.xml"/>
|
||||
<xi:include href="xml/gradient.xml"/>
|
||||
<xi:include href="xml/prefs.xml"/>
|
||||
<xi:include href="xml/util.xml"/>
|
||||
<xi:include href="xml/errors.xml"/>
|
||||
|
@ -172,15 +172,6 @@ meta_error_trap_push_with_return
|
||||
meta_error_trap_pop_with_return
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gradient</FILE>
|
||||
MetaGradientType
|
||||
meta_gradient_create_simple
|
||||
meta_gradient_create_multi
|
||||
meta_gradient_create_interwoven
|
||||
meta_gradient_add_alpha
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>group</FILE>
|
||||
MetaGroup
|
||||
@ -558,7 +549,6 @@ meta_window_is_skip_taskbar
|
||||
meta_window_get_rect
|
||||
meta_window_get_buffer_rect
|
||||
meta_window_get_frame_rect
|
||||
meta_window_get_outer_rect
|
||||
meta_window_client_rect_to_frame_rect
|
||||
meta_window_frame_rect_to_client_rect
|
||||
meta_window_get_screen
|
||||
|
@ -1,396 +0,0 @@
|
||||
Themes are in a simple XML-subset format. There are multiple versions
|
||||
of the theme format, and a given theme can support more than one format.
|
||||
|
||||
Version 1: THEMEDIR/metacity-1/metacity-theme-1.xml
|
||||
(original metacity format)
|
||||
Version 2: THEMEDIR/metacity-1/metacity-theme-2.xml
|
||||
Version 3: THEMEDIR/metacity-1/metacity-theme-3.xml
|
||||
|
||||
The subdirectory name is "metacity-1" in all versions.
|
||||
|
||||
As you might expect, older versions of metacity will not understand
|
||||
newer theme formats. However, newer versions will use old themes.
|
||||
Metacity will always use the newest theme format it understands that
|
||||
the X server supports. Some format versions are only supported if you
|
||||
have the right X server features.
|
||||
|
||||
Each format *requires* the corresponding filename. If you put version
|
||||
2 format features in the metacity-1/metacity-theme-1.xml file, then
|
||||
metacity will get angry.
|
||||
|
||||
This document has separate sections for each format version. You may
|
||||
want to read the document in reverse order, since the base features
|
||||
are discussed under version 1.
|
||||
|
||||
New Features in Theme Format Version 3.4
|
||||
========================================
|
||||
|
||||
An additional color type is added to pick up custom colors defined
|
||||
in the GTK+ theme's CSS:
|
||||
|
||||
gtk:custom(name,fallback)
|
||||
|
||||
where <name> refers to a custom color defined with @define-color in
|
||||
the GTK+ theme, and <fallback> provides an alternative color definition
|
||||
in case the color referenced by <name> is not found.
|
||||
|
||||
New Features in Theme Format Version 3.3
|
||||
========================================
|
||||
|
||||
Add two additional button background functions - left_single_background and
|
||||
right_single_background - for button groups with just a single button.
|
||||
|
||||
There are now additional frame states to style left/right tiled windows
|
||||
differently ("tiled_left", "tiled_right", "tiled_left_and_shaded",
|
||||
"tiled_right_and_shaded").
|
||||
|
||||
New Features in Theme Format Version 3.2
|
||||
========================================
|
||||
|
||||
A new window type 'attached' is added for modal dialogs which are
|
||||
attached to their parent window. (When the attach_modal_dialogs preference
|
||||
is turned on.) If no style is defined for the 'attached' window type,
|
||||
the 'border' window type will be used instead.
|
||||
|
||||
New Features in Theme Format Version 3.1
|
||||
========================================
|
||||
|
||||
Additional predefined variables are added for positioning expressions:
|
||||
|
||||
frame_x_center: the X center of the entire frame, with respect to the
|
||||
piece currently being drawn.
|
||||
frame_y_center: the Y center of the entire frame, with respect to the
|
||||
piece currently being drawn.
|
||||
|
||||
The <title/> element now supports an "ellipsize_width" attribute. When
|
||||
specified, this gives a width at which to ellipsize the title. If not
|
||||
specified, the title will simply be clipped to the title area.
|
||||
|
||||
New Features in Theme Format Version 3
|
||||
======================================
|
||||
|
||||
Format version 3 has exactly one new feature; any element in the file
|
||||
can now have a version attribute:
|
||||
|
||||
version="[<|<=|=>|>] MAJOR.MINOR"
|
||||
|
||||
(< and > should be to be entity escaped as < and >). If this
|
||||
version check is not met, then the element and its children will be
|
||||
ignored. This allows having alternate sections of the theme file for
|
||||
older and newer version of the Metacity theme format.
|
||||
|
||||
When placed on the toplevel <metacity_theme> element, an unsatisfied
|
||||
version check will not just cause the contents of the file to be
|
||||
ignored, it will also cause the lookup of a theme file to proceed on
|
||||
and look for an older format 2 or format 1 file. This allows making a
|
||||
metacity-theme-3.xml file that is only used the format version 3.2 or
|
||||
newer is supported, and using metacity-theme-1.xml for older window
|
||||
managers.
|
||||
|
||||
New Features in Theme Format Version 2
|
||||
======================================
|
||||
|
||||
The optional attributes rounded_top_left, rounded_top_right,
|
||||
rounded_bottom_left and rounded_bottom_right on <frame_geometry>
|
||||
should now be the radius of the corner in pixels. You may still use
|
||||
the values "false" for 0 and "true" for 5, which means v1 values will
|
||||
still work just fine.
|
||||
|
||||
<frame_geometry> has a new optional attribute, hide_buttons. If this
|
||||
is true, no buttons will be displayed on the titlebar.
|
||||
|
||||
Anywhere you can use a positive integer, you can use an integer constant.
|
||||
|
||||
As well as constant integers and reals, you may define constant colours,
|
||||
thus:
|
||||
<constant name="RevoltingPink" value="#FF00FF"/>
|
||||
<constant name="Background" value="gtk:bg[NORMAL]"/>
|
||||
|
||||
<frame_style> has two new optional attributes, background and alpha.
|
||||
If you specify alpha, you must specify background. background is a
|
||||
colour used for the background of the frame. alpha is the transparency
|
||||
as a real between 0.0 and 1.0. If the current X server does not support
|
||||
alpha channels, the value is ignored.
|
||||
|
||||
The filename attribute of <image> may begin with "theme:". If so, the
|
||||
rest of the string is the name of a theme icon. The 64x64 version of the
|
||||
icon is used, except for fallback mini_icons, which use the 16x16 version.
|
||||
This does not affect ordinary resizing. For example:
|
||||
<button function="close" state="normal">
|
||||
<draw_ops>
|
||||
<include name="active_button"/>
|
||||
<image filename="theme:gnome-logout" x="2" y="2"
|
||||
width="width-4" height="height-4"/>
|
||||
<!-- Note: not "theme:gnome-logout.png" or similar. -->
|
||||
</draw_ops>
|
||||
</button>
|
||||
|
||||
<menu_icon>s are parsed but ignored.
|
||||
|
||||
Fallback icons can be specified using <fallback>. There are two
|
||||
optional arguments, icon and mini_icon. The values of these arguments
|
||||
are identical to that of the filename attribute of <image>. Fallback
|
||||
icons are used when a window does not supply its own icon. If a fallback
|
||||
icon is not specified with <fallback>, Metacity will use a built-in
|
||||
icon, as in metacity-theme-1.
|
||||
|
||||
The <arc> element, as well as the original start_angle and end_angle
|
||||
attributes, may be given from and to attributes. The values of these
|
||||
attributes are given in degrees clockwise, with 0 being straight up.
|
||||
For example:
|
||||
<arc from="0.0" to="90.0" filled="true" color="#FF00FF"
|
||||
x="0" y="5" width="15" height="15"/>
|
||||
|
||||
<frame state="shaded"> may now take an optional resize attribute, with
|
||||
the same interpretation as the resize attribute on <frame state="normal">.
|
||||
If this attribute is omitted for state="shaded", it defaults to "both".
|
||||
(If it is omitted for state="normal", it remains an error.)
|
||||
|
||||
In addition to the four <button> functions which are required in
|
||||
metacity-theme-1, there are six new functions in metacity-theme-2:
|
||||
shade, unshade, above, unabove, stick and unstick.
|
||||
|
||||
Overview of Theme Format Version 1
|
||||
==================================
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<metacity_theme>
|
||||
<!-- Only one info section is allowed -->
|
||||
<info>
|
||||
<name>Foo</name>
|
||||
<author>Foo P. Bar</author>
|
||||
<copyright>whoever, 2002</copyright>
|
||||
<date>Jan 31 2005</date>
|
||||
<description>A sentence about the theme.</description>
|
||||
</info>
|
||||
|
||||
<!-- define a frame geometry to be referenced later -->
|
||||
<!-- frame_geometry has an optional has_title attribute which
|
||||
determines whether the title text height is included in the
|
||||
height calculation. if not specified, defaults to true.
|
||||
It also has an optional text_size="medium" attribute
|
||||
(same sizes as with Pango markup, xx-small thru medium thru
|
||||
xx-large)
|
||||
|
||||
Finally it has optional args rounded_top_left=true,
|
||||
rounded_top_right=true, rounded_bottom_left=true,
|
||||
rounded_bottom_right=true.
|
||||
|
||||
-->
|
||||
<frame_geometry name="normal" has_title="true" title_scale="medium">
|
||||
<distance name="left_width" value="6"/>
|
||||
<distance name="right_width" value="6"/>
|
||||
<distance name="bottom_height" value="7"/>
|
||||
<distance name="left_titlebar_edge" value="6"/>
|
||||
<distance name="right_titlebar_edge" value="6"/>
|
||||
<distance name="button_width" value="17"/>
|
||||
<distance name="button_height" value="17"/>
|
||||
<!-- alternative to button_width button_height distances -->
|
||||
<aspect_ratio name="button" value="1.0"/>
|
||||
<distance name="title_vertical_pad" value="4"/>
|
||||
<border name="title_border" left="3" right="12" top="4" bottom="3"/>
|
||||
<border name="button_border" left="0" right="0" top="1" bottom="1"/>
|
||||
</frame_geometry>
|
||||
|
||||
<!-- inheritance is allowed; simply overwrites values from parent -->
|
||||
<frame_geometry name="borderless" parent="normal">
|
||||
<distance name="left_width" value="0"/>
|
||||
<distance name="right_width" value="0"/>
|
||||
<distance name="bottom_height" value="0"/>
|
||||
<distance name="left_titlebar_edge" value="0"/>
|
||||
<distance name="right_titlebar_edge" value="0"/>
|
||||
</frame_geometry>
|
||||
|
||||
<!-- define a constant to use in positions/sizes of draw operations;
|
||||
constant names must start with a capital letter.
|
||||
-->
|
||||
<constant name="LineOffset" value="3"/>
|
||||
|
||||
<!-- define drawing operations to be referenced later;
|
||||
these draw-op lists can also be placed inline.
|
||||
|
||||
Positions/lengths are given as expressions.
|
||||
Operators are: +,-,*,/,%,`max`,`min`
|
||||
All operators are infix including `max` and `min`,
|
||||
i.e. "2 `max` 5"
|
||||
|
||||
Some variables are predefined, and constants can also
|
||||
be used. Variables are:
|
||||
|
||||
width - width of target area
|
||||
height - height of target area
|
||||
object_width - natural width of object being drawn
|
||||
object_height - natural height of object being drawn
|
||||
left_width - distance from left of frame to client window
|
||||
right_width - distance from right of frame to client window
|
||||
top_height - distance from top of frame to client window
|
||||
bottom_height - distance from bottom of frame to client window
|
||||
mini_icon_width - width of mini icon for window
|
||||
mini_icon_height - height of mini icon
|
||||
icon_width - width of large icon
|
||||
icon_height - height of large icon
|
||||
title_width - width of title text
|
||||
title_height - height of title text
|
||||
|
||||
All these are always defined, except object_width/object_height
|
||||
which only exists for <image> right now.
|
||||
|
||||
-->
|
||||
|
||||
<draw_ops name="demo_all_ops">
|
||||
<line color="#00FF00" x1="LineOffset" y1="0" x2="0" y2="height"/>
|
||||
<line color="gtk:fg[NORMAL]"
|
||||
x1="width - 1" y1="0" x2="width - 1" y2="height"
|
||||
width="3" dash_on_length="2" dash_off_length="3"/>
|
||||
<rectangle color="blend/gtk:fg[NORMAL]/gtk:bg[NORMAL]/0.7"
|
||||
x="0" y="0" width="width - 1" height="height - 1" filled="true"/>
|
||||
<arc color="dark gray" x="0" y="0" width="width - 1" height="height - 1"
|
||||
filled="false" start_angle="30" extent_angle="180"/>
|
||||
<tint color="orange" alpha="0.5" x="0" y="0" width="width" height="height"/>
|
||||
<!-- may be vertical, horizontal, diagonal -->
|
||||
<gradient type="diagonal"
|
||||
x="10" y="30" width="width / 3" height="height / 4">
|
||||
<!-- any number of colors allowed here. A color can be
|
||||
a color name like "blue" (look at gcolorsel), a hex color
|
||||
as in HTML (#FFBB99), or a color from the gtk theme
|
||||
given as "gtk:base[NORMAL]", "gtk:fg[ACTIVE]", etc.
|
||||
-->
|
||||
<color value="gtk:fg[SELECTED]"/>
|
||||
<!-- color obtained by a 0.5 alpha composite of the second color onto the first -->
|
||||
<color value="blend/gtk:bg[SELECTED]/gtk:fg[SELECTED]/0.5"/>
|
||||
</gradient>
|
||||
<!-- image has an optional colorize="#color" attribute to give the
|
||||
image a certain color -->
|
||||
<image filename="foo.png" alpha="0.7"
|
||||
x="10" y="30" width="width / 3" height="height / 4"/>
|
||||
<gtk_arrow state="normal" shadow="in" arrow="up"
|
||||
filled="true"
|
||||
x="2" y="2" width="width - 4" height="height - 4"/>
|
||||
<gtk_box state="normal" shadow="out"
|
||||
x="2" y="2" width="width - 4" height="height - 4"/>
|
||||
<gtk_vline state="normal" x="2" y1="0" y2="height"/>
|
||||
<!-- window's icon -->
|
||||
<icon alpha="0.7"
|
||||
x="10" y="30" width="width / 3" height="height / 4"/>
|
||||
<!-- window's title -->
|
||||
<title color="gtk:text[NORMAL]" x="20" y="30"/>
|
||||
<!-- include another draw ops list; has optional x/y/width/height attrs -->
|
||||
<include name="some_other_draw_ops"/>
|
||||
<!-- tile another draw ops list; has optional
|
||||
x/y/width/height/tile_xoffset/tile_yoffset -->
|
||||
<tile name="some_other_draw_ops" tile_width="10" tile_height="10"/>
|
||||
</draw_ops>
|
||||
|
||||
<frame_style name="normal" geometry="normal">
|
||||
<!-- How to draw each piece of the frame.
|
||||
For each piece, a draw_ops can be given inline or referenced
|
||||
by name. If a piece is omitted, then nothing will be drawn
|
||||
for that piece.
|
||||
|
||||
For each piece, the "width" and "height" variables in
|
||||
coordinate expressions refers to the dimensions of the piece,
|
||||
the origin is at the top left of the piece.
|
||||
|
||||
So <rectangle x="0" y="0" width="width-1" height="height-1"/>
|
||||
will outline a piece.
|
||||
-->
|
||||
|
||||
<piece position="entire_background" draw_ops="demo_all_ops"/>
|
||||
<piece position="left_titlebar_edge">
|
||||
<draw_ops>
|
||||
<line color="#00FF00" x1="0" y1="0" x2="0" y2="height"/>
|
||||
</draw_ops>
|
||||
</piece>
|
||||
|
||||
<!-- The complete list of frame pieces:
|
||||
|
||||
entire_background: whole frame
|
||||
titlebar: entire area above the app's window
|
||||
titlebar_middle: area of titlebar_background not considered
|
||||
part of an edge
|
||||
left_titlebar_edge: left side of titlebar background
|
||||
right_titlebar_edge: right side of titlebar background
|
||||
top_titlebar_edge: top side of titlebar background
|
||||
bottom_titlebar_edge: bottom side of titlebar background
|
||||
title: the title area (doesn't include buttons)
|
||||
left_edge: left edge of the frame
|
||||
right_edge: right edge of the frame
|
||||
bottom_edge: bottom edge of the frame
|
||||
overlay: same area as entire_background, but drawn after
|
||||
drawing all sub-pieces instead of before
|
||||
|
||||
-->
|
||||
|
||||
<!-- For buttons, drawing methods have to be provided for
|
||||
each of three states:
|
||||
normal, pressed, prelight
|
||||
and the button function or position must be provided:
|
||||
close, maximize, minimize, menu,
|
||||
left_left_background, left_middle_background,
|
||||
left_right_background, right_left_background,
|
||||
right_middle_background, right_right_background
|
||||
So a working theme needs 3*4 = 12 button declarations
|
||||
and a theme may have up to 3*10 = 30 button declarations
|
||||
in order to handle button-rearrangement preferences.
|
||||
|
||||
(The name "function" for the attribute is from before the
|
||||
background values existed.)
|
||||
-->
|
||||
|
||||
<button function="close" state="normal" draw_ops="previously_named"/>
|
||||
<button function="menu" state="normal">
|
||||
<draw_ops>
|
||||
<icon alpha="0.7"
|
||||
x="0" y="0" width="object_width" height="object_height"/>
|
||||
</draw_ops>
|
||||
</button>
|
||||
|
||||
</frame_style>
|
||||
|
||||
<!-- styles can inherit from each other with the parent="" attribute.
|
||||
In a subclass anything can be re-specified to override
|
||||
the parent style. -->
|
||||
<frame_style name="focused" parent="normal">
|
||||
<piece position="title">
|
||||
<draw_ops>
|
||||
<rectangle color="gtk:bg[SELECTED]"
|
||||
x="0" y="0" width="width-1" height="height-1"/>
|
||||
<title color="gtk:fg[SELECTED]" x="(width - title_width) / 2"
|
||||
y="(height - title_height) / 2"/>
|
||||
</draw_ops>
|
||||
</piece>
|
||||
</frame_style>
|
||||
|
||||
<!-- Maps styles to states of frame.
|
||||
|
||||
Focus: yes (focused), no (not focused)
|
||||
Window states: normal, maximized, shaded, maximized_and_shaded
|
||||
Window resizability: none, vertical, horizontal, both
|
||||
|
||||
Everything unspecified just does the same as
|
||||
unfocused/normal/both.
|
||||
|
||||
only state="normal" needs a resize="" attribute.
|
||||
-->
|
||||
<frame_style_set name="normal">
|
||||
<frame focus="yes" state="normal" resize="both" style="focused"/>
|
||||
<frame focus="no" state="normal" resize="both" style="normal"/>
|
||||
</frame_style_set>
|
||||
|
||||
<!-- Each window type needs a style set
|
||||
Types: normal, dialog, modal_dialog, menu, utility, border
|
||||
-->
|
||||
<window type="normal" style_set="normal"/>
|
||||
|
||||
|
||||
<!-- For menu icons, drawing methods are needed for the same
|
||||
four types as the buttons, and GTK states
|
||||
(insensitive,prelight,normal,etc.)
|
||||
-->
|
||||
|
||||
<menu_icon function="close" state="normal" draw_ops="previously_named"/>
|
||||
|
||||
|
||||
</metacity_theme>
|
||||
|
||||
|
@ -22,9 +22,7 @@ src/core/screen.c
|
||||
src/core/util.c
|
||||
src/core/window.c
|
||||
src/ui/frames.c
|
||||
src/ui/resizepopup.c
|
||||
src/ui/theme.c
|
||||
src/ui/theme-parser.c
|
||||
src/x11/session.c
|
||||
src/x11/window-props.c
|
||||
src/x11/xprops.c
|
||||
|
2679
po/bn_IN.po
2679
po/bn_IN.po
File diff suppressed because it is too large
Load Diff
818
po/fr.po
818
po/fr.po
@ -1,5 +1,5 @@
|
||||
# French translation of mutter.
|
||||
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2015 Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the metacity package.
|
||||
#
|
||||
# Christophe Fergeau <teuf@users.sourceforge.net>, 2002.
|
||||
@ -11,17 +11,16 @@
|
||||
# Cyprien Le Pannérer <cyplp@free.fr>, 2006.
|
||||
# Robert-André Mauchin <zebob.m@gmail.com>, 2007.
|
||||
# Stéphane Raimbault <stephane.raimbault@gmail.com>, 2007.
|
||||
# Claude Paroz <claude@2xlibre.net>, 2008-2014.
|
||||
# Claude Paroz <claude@2xlibre.net>, 2008-2015.
|
||||
# Bruno Brouard <annoa.b@gmail.com>, 2011-12.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter masterReport-Msgid-Bugs-To: http://bugzilla.gnome."
|
||||
"org/enter_bug.cgi?product=mutter&component=general\n"
|
||||
"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: 2014-08-29 21:52+0000\n"
|
||||
"PO-Revision-Date: 2014-08-30 11:59+0200\n"
|
||||
"POT-Creation-Date: 2015-02-23 23:11+0000\n"
|
||||
"PO-Revision-Date: 2015-02-24 10:08+0100\n"
|
||||
"Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
|
||||
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
|
||||
"Language: fr\n"
|
||||
@ -408,8 +407,8 @@ msgid ""
|
||||
"When true, the new windows will always be put in the center of the active "
|
||||
"screen of the monitor."
|
||||
msgstr ""
|
||||
"Si true (vrai), les nouvelles fenêtres seront toujours placées au centre "
|
||||
"de l'écran actif du moniteur."
|
||||
"Si true (vrai), les nouvelles fenêtres seront toujours placées au centre de "
|
||||
"l'écran actif du moniteur."
|
||||
|
||||
#: ../data/org.gnome.mutter.gschema.xml.in.h:21
|
||||
msgid "Select window from tab popup"
|
||||
@ -449,29 +448,49 @@ msgstr "Passer à l'émulateur de terminal 6"
|
||||
msgid "Switch to VT 7"
|
||||
msgstr "Passer à l'émulateur de terminal 7"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:412
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
|
||||
msgid "Switch to VT 8"
|
||||
msgstr "Passer à l'émulateur de terminal 8"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
|
||||
msgid "Switch to VT 9"
|
||||
msgstr "Passer à l'émulateur de terminal 9"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
|
||||
msgid "Switch to VT 10"
|
||||
msgstr "Passer à l'émulateur de terminal 10"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
|
||||
msgid "Switch to VT 11"
|
||||
msgstr "Passer à l'émulateur de terminal 11"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "Passer à l'émulateur de terminal 12"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:364
|
||||
msgid "Built-in display"
|
||||
msgstr "Affichage intégré"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:437
|
||||
#: ../src/backends/meta-monitor-manager.c:391
|
||||
msgid "Unknown"
|
||||
msgstr "Inconnu"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:439
|
||||
#: ../src/backends/meta-monitor-manager.c:393
|
||||
msgid "Unknown Display"
|
||||
msgstr "Affichage inconnu"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:447
|
||||
#: ../src/backends/meta-monitor-manager.c:401
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:443
|
||||
#: ../src/compositor/compositor.c:456
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@ -480,10 +499,6 @@ msgstr ""
|
||||
"Un autre gestionnaire de composition est déjà lancé sur l'écran %i de "
|
||||
"l'affichage « %s »."
|
||||
|
||||
#: ../src/compositor/meta-background.c:1044
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "la texture d'arrière-plan n'a pas pu être créée depuis le fichier"
|
||||
|
||||
#: ../src/core/bell.c:185
|
||||
msgid "Bell event"
|
||||
msgstr "Évènement sonore"
|
||||
@ -513,7 +528,7 @@ msgstr "_Attendre"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Forcer à quitter"
|
||||
|
||||
#: ../src/core/display.c:547
|
||||
#: ../src/core/display.c:562
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Impossible d'ouvrir l'affichage « %s » du système X Window\n"
|
||||
@ -550,19 +565,6 @@ msgstr "Lancer comme un compositeur wayland"
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Lancer comme un serveur d'affichage complet, plutôt qu'imbriqué"
|
||||
|
||||
#: ../src/core/main.c:459
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Le parcours du répertoire de thèmes a échoué : %s\n"
|
||||
|
||||
#: ../src/core/main.c:475
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
msgstr ""
|
||||
"Impossible de trouver un thème ! Assurez-vous que %s existe et contient les "
|
||||
"thèmes habituels.\n"
|
||||
|
||||
#: ../src/core/mutter.c:39
|
||||
#, c-format
|
||||
msgid ""
|
||||
@ -587,759 +589,29 @@ msgstr "Afficher la version"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Greffon de Mutter à utiliser"
|
||||
|
||||
#: ../src/core/prefs.c:2101
|
||||
#: ../src/core/prefs.c:2004
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Espace de travail %d"
|
||||
|
||||
#: ../src/core/screen.c:548
|
||||
#: ../src/core/screen.c:525
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display \"%s\" already has a window manager; try using the --replace option "
|
||||
"to replace the current window manager."
|
||||
msgstr ""
|
||||
"L'affichage « %s » a déjà un gestionnaire de fenêtres ; essayez d'utiliser "
|
||||
"l'option --replace pour remplacer le gestionnaire de fenêtres actuel."
|
||||
|
||||
#: ../src/core/screen.c:607
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "L'écran %d sur l'affichage « %s » n'est pas valide\n"
|
||||
|
||||
#: ../src/core/screen.c:564
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
"replace option to replace the current window manager.\n"
|
||||
msgstr ""
|
||||
"L'écran %d sur l'affichage « %s » a déjà un gestionnaire de fenêtres ; "
|
||||
"essayez d'utiliser l'option --replace pour remplacer le gestionnaire de "
|
||||
"fenêtres actuel.\n"
|
||||
|
||||
#: ../src/core/screen.c:657
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "L'écran %d sur l'affichage « %s » a déjà un gestionnaire de fenêtres\n"
|
||||
|
||||
#: ../src/core/util.c:118
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Mutter a été compilé sans la prise en charge du mode bavard\n"
|
||||
|
||||
#. Translators: This represents the size of a window. The first number is
|
||||
#. * the width of the window and the second is the height.
|
||||
#.
|
||||
#: ../src/ui/resizepopup.c:134
|
||||
#, c-format
|
||||
msgid "%d x %d"
|
||||
msgstr "%d x %d"
|
||||
|
||||
#: ../src/ui/theme.c:233
|
||||
msgid "top"
|
||||
msgstr "haut"
|
||||
|
||||
#: ../src/ui/theme.c:235
|
||||
msgid "bottom"
|
||||
msgstr "bas"
|
||||
|
||||
#: ../src/ui/theme.c:237
|
||||
msgid "left"
|
||||
msgstr "gauche"
|
||||
|
||||
#: ../src/ui/theme.c:239
|
||||
msgid "right"
|
||||
msgstr "droite"
|
||||
|
||||
#: ../src/ui/theme.c:267
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify \"%s\" dimension"
|
||||
msgstr "la géométrie du cadre n'indique pas la dimension « %s »"
|
||||
|
||||
#: ../src/ui/theme.c:286
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
|
||||
msgstr ""
|
||||
"la géométrie du cadre n'indique pas la dimension « %s » pour la bordure "
|
||||
"« %s »"
|
||||
|
||||
#: ../src/ui/theme.c:323
|
||||
#, c-format
|
||||
msgid "Button aspect ratio %g is not reasonable"
|
||||
msgstr "La proportion du bouton %g n'est pas raisonnable"
|
||||
|
||||
#: ../src/ui/theme.c:335
|
||||
#, c-format
|
||||
msgid "Frame geometry does not specify size of buttons"
|
||||
msgstr "La géométrie du cadre n'indique pas la taille des boutons"
|
||||
|
||||
#: ../src/ui/theme.c:1061
|
||||
#, c-format
|
||||
msgid "Gradients should have at least two colors"
|
||||
msgstr "Les dégradés doivent comporter au moins deux couleurs"
|
||||
|
||||
#: ../src/ui/theme.c:1211
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK custom color specification must have color name and fallback in "
|
||||
"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
|
||||
msgstr ""
|
||||
"Une spécification de couleur personnalisée GTK doit comporter un nom de "
|
||||
"couleur et un substitut entre parenthèses, par ex. gtk:custom(foo,bar) ; "
|
||||
"impossible d'analyser « %s »"
|
||||
|
||||
#: ../src/ui/theme.c:1227
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
|
||||
"_ are valid"
|
||||
msgstr ""
|
||||
"Caractère « %c » non valide dans le paramètre color_name de gtk:custom, "
|
||||
"seuls A-Za-z0-9-_ sont acceptés"
|
||||
|
||||
#: ../src/ui/theme.c:1241
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
||||
"fit the format"
|
||||
msgstr ""
|
||||
"Le format de gtk:custom est « gtk:custom(nom_couleur,substitut) », « %s » ne "
|
||||
"correspond pas à ce format"
|
||||
|
||||
#: ../src/ui/theme.c:1286
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
|
||||
"where NORMAL is the state; could not parse \"%s\""
|
||||
msgstr ""
|
||||
"La spécification de couleur GTK doit présenter l'état entre crochets, p. ex. "
|
||||
"gtk:fg[NORMAL] où NORMAL est l'état ; impossible d'analyser « %s »"
|
||||
|
||||
#: ../src/ui/theme.c:1300
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have a close bracket after the state, e.g. gtk:"
|
||||
"fg[NORMAL] where NORMAL is the state; could not parse \"%s\""
|
||||
msgstr ""
|
||||
"La spécification de couleur GTK doit comporter un crochet de fermeture après "
|
||||
"l'état, p. ex. gtk:fg[NORMAL] où NORMAL est l'état ; impossible d'analyser "
|
||||
"« %s »"
|
||||
|
||||
#: ../src/ui/theme.c:1311
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" in color specification"
|
||||
msgstr ""
|
||||
"Impossible de comprendre l'état « %s » dans la spécification de couleur"
|
||||
|
||||
#: ../src/ui/theme.c:1324
|
||||
#, c-format
|
||||
msgid "Did not understand color component \"%s\" in color specification"
|
||||
msgstr ""
|
||||
"Impossible de comprendre le composant de couleur « %s » dans la "
|
||||
"spécification de couleur"
|
||||
|
||||
#: ../src/ui/theme.c:1352
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
|
||||
"format"
|
||||
msgstr ""
|
||||
"Le format de mélange est « blend/bg_color/fg_color/alpha », « %s » ne "
|
||||
"correspond pas à ce format ."
|
||||
|
||||
#: ../src/ui/theme.c:1363
|
||||
#, c-format
|
||||
msgid "Could not parse alpha value \"%s\" in blended color"
|
||||
msgstr "Impossible d'analyser la valeur alpha « %s » en couleur mélangée"
|
||||
|
||||
#: ../src/ui/theme.c:1373
|
||||
#, c-format
|
||||
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
|
||||
msgstr ""
|
||||
"La valeur alpha « %s » en couleur mélangée n'est pas comprise entre 0,0 et "
|
||||
"1,0"
|
||||
|
||||
#: ../src/ui/theme.c:1419
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
|
||||
msgstr ""
|
||||
"Le format d'ombre est « shade/base_color/factor », « %s » ne correspond pas "
|
||||
"au format"
|
||||
|
||||
#: ../src/ui/theme.c:1430
|
||||
#, c-format
|
||||
msgid "Could not parse shade factor \"%s\" in shaded color"
|
||||
msgstr "Impossible d'analyser le facteur d'ombre « %s » en couleur ombrée"
|
||||
|
||||
#: ../src/ui/theme.c:1440
|
||||
#, c-format
|
||||
msgid "Shade factor \"%s\" in shaded color is negative"
|
||||
msgstr "Le facteur d'ombre « %s » en couleur ombrée est négatif"
|
||||
|
||||
#: ../src/ui/theme.c:1469
|
||||
#, c-format
|
||||
msgid "Could not parse color \"%s\""
|
||||
msgstr "Impossible d'analyser la couleur « %s »"
|
||||
|
||||
#: ../src/ui/theme.c:1778
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains character '%s' which is not allowed"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée contient le caractère « %s » qui n'est pas "
|
||||
"autorisé"
|
||||
|
||||
#: ../src/ui/theme.c:1805
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contains floating point number '%s' which could not be "
|
||||
"parsed"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée contient la valeur en virgule flottante « %s » "
|
||||
"qui ne peut pas être analysée"
|
||||
|
||||
#: ../src/ui/theme.c:1819
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains integer '%s' which could not be parsed"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée contient l'entier « %s » qui n'a pas pu être "
|
||||
"analysé"
|
||||
|
||||
#: ../src/ui/theme.c:1940
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contained unknown operator at the start of this text: "
|
||||
"\"%s\""
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée contenait un opérateur inconnu au début de ce "
|
||||
"texte : « %s »"
|
||||
|
||||
#: ../src/ui/theme.c:1997
|
||||
#, c-format
|
||||
msgid "Coordinate expression was empty or not understood"
|
||||
msgstr "L'expression de la coordonnée était vide ou incomprise"
|
||||
|
||||
#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154
|
||||
#, c-format
|
||||
msgid "Coordinate expression results in division by zero"
|
||||
msgstr "L'expression de la coordonnée entraîne une division par zéro"
|
||||
|
||||
#: ../src/ui/theme.c:2162
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression tries to use mod operator on a floating-point number"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée tente d'utiliser l'opérateur mod sur une "
|
||||
"valeur en virgule flottante"
|
||||
|
||||
#: ../src/ui/theme.c:2218
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has an operator \"%s\" where an operand was expected"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée a un opérateur « %s » là où un opérande était "
|
||||
"attendu"
|
||||
|
||||
#: ../src/ui/theme.c:2227
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an operand where an operator was expected"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée a un opérande là où un opérateur était attendu"
|
||||
|
||||
#: ../src/ui/theme.c:2235
|
||||
#, c-format
|
||||
msgid "Coordinate expression ended with an operator instead of an operand"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée était terminée par un opérateur au lieu d'un "
|
||||
"opérande"
|
||||
|
||||
#: ../src/ui/theme.c:2245
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
|
||||
"operand in between"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée a un opérateur « %c » suivant l'opérateur "
|
||||
"« %c » sans opérande entre eux"
|
||||
|
||||
#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441
|
||||
#, c-format
|
||||
msgid "Coordinate expression had unknown variable or constant \"%s\""
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée possède une variable ou constante inconnue "
|
||||
"« %s »"
|
||||
|
||||
#: ../src/ui/theme.c:2495
|
||||
#, c-format
|
||||
msgid "Coordinate expression parser overflowed its buffer."
|
||||
msgstr ""
|
||||
"L'analyseur d'expression de coordonnées a dépassé la capacité de son tampon."
|
||||
|
||||
#: ../src/ui/theme.c:2524
|
||||
#, c-format
|
||||
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée comporte une parenthèse de fermeture, mais pas "
|
||||
"de parenthèse d'ouverture"
|
||||
|
||||
#: ../src/ui/theme.c:2588
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée comporte une parenthèse d'ouverture, mais pas "
|
||||
"de parenthèse de fermeture"
|
||||
|
||||
#: ../src/ui/theme.c:2599
|
||||
#, c-format
|
||||
msgid "Coordinate expression doesn't seem to have any operators or operands"
|
||||
msgstr ""
|
||||
"L'expression de la coordonnée ne semble pas comprendre d'opérateur ni "
|
||||
"d'opérande"
|
||||
|
||||
#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852
|
||||
#, c-format
|
||||
msgid "Theme contained an expression that resulted in an error: %s\n"
|
||||
msgstr "Le thème contient une expression qui a entraîné une erreur : %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:4455
|
||||
#, c-format
|
||||
msgid ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
|
||||
"specified for this frame style"
|
||||
msgstr ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> doit être "
|
||||
"indiqué pour ce style de cadre"
|
||||
|
||||
#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
|
||||
msgstr ""
|
||||
"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> manquant"
|
||||
|
||||
#: ../src/ui/theme.c:5041
|
||||
#, c-format
|
||||
msgid "Failed to load theme \"%s\": %s\n"
|
||||
msgstr "Impossible de charger le thème « %s » : %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191
|
||||
#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205
|
||||
#, c-format
|
||||
msgid "No <%s> set for theme \"%s\""
|
||||
msgstr "Aucun <%s> défini pour le thème « %s »"
|
||||
|
||||
#: ../src/ui/theme.c:5213
|
||||
#, c-format
|
||||
msgid ""
|
||||
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
|
||||
"type=\"%s\" style_set=\"whatever\"/> element"
|
||||
msgstr ""
|
||||
"Aucun style de cadre défini pour le type de fenêtre « %s » dans le thème "
|
||||
"« %s », ajoutez un élément <window type=\"%s\" style_set=\"whatever\"/>"
|
||||
|
||||
#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745
|
||||
#, c-format
|
||||
msgid ""
|
||||
"User-defined constants must begin with a capital letter; \"%s\" does not"
|
||||
msgstr ""
|
||||
"Les constantes définies par l'utilisateur doivent commencer par une "
|
||||
"majuscule ; « %s » commence par une minuscule"
|
||||
|
||||
#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753
|
||||
#, c-format
|
||||
msgid "Constant \"%s\" has already been defined"
|
||||
msgstr "La constante « %s » a déjà été définie"
|
||||
|
||||
#. Translators: This means that an attribute which should have been found
|
||||
#. * on an XML element was not in fact found.
|
||||
#.
|
||||
#: ../src/ui/theme-parser.c:234
|
||||
#, c-format
|
||||
msgid "No \"%s\" attribute on element <%s>"
|
||||
msgstr "Aucun attribut « %s » sur l'élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281
|
||||
#, c-format
|
||||
msgid "Line %d character %d: %s"
|
||||
msgstr "Ligne %d caractère %d: %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:481
|
||||
#, c-format
|
||||
msgid "Attribute \"%s\" repeated twice on the same <%s> element"
|
||||
msgstr "Attribut « %s » répété deux fois sur le même élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554
|
||||
#, c-format
|
||||
msgid "Attribute \"%s\" is invalid on <%s> element in this context"
|
||||
msgstr "Attribut « %s » non valide sur l'élément <%s> dans ce contexte"
|
||||
|
||||
#: ../src/ui/theme-parser.c:596
|
||||
#, c-format
|
||||
msgid "Could not parse \"%s\" as an integer"
|
||||
msgstr "Impossible d'analyser « %s » en tant qu'entier"
|
||||
|
||||
#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660
|
||||
#, c-format
|
||||
msgid "Did not understand trailing characters \"%s\" in string \"%s\""
|
||||
msgstr "Caractères de fin « %s » non compris dans la chaîne « %s »"
|
||||
|
||||
#: ../src/ui/theme-parser.c:615
|
||||
#, c-format
|
||||
msgid "Integer %ld must be positive"
|
||||
msgstr "L'entier %ld doit être positif"
|
||||
|
||||
#: ../src/ui/theme-parser.c:623
|
||||
#, c-format
|
||||
msgid "Integer %ld is too large, current max is %d"
|
||||
msgstr "L'entier %ld est trop élevé, le max. actuel est %d"
|
||||
|
||||
#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767
|
||||
#, c-format
|
||||
msgid "Could not parse \"%s\" as a floating point number"
|
||||
msgstr "Impossible d'analyser « %s » en tant que valeur en virgule flottante"
|
||||
|
||||
#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710
|
||||
#, c-format
|
||||
msgid "Boolean values must be \"true\" or \"false\" not \"%s\""
|
||||
msgstr ""
|
||||
"Les valeurs booléennes doivent être « true » ou « false » et non « %s »"
|
||||
|
||||
#: ../src/ui/theme-parser.c:737
|
||||
#, c-format
|
||||
msgid "Angle must be between 0.0 and 360.0, was %g\n"
|
||||
msgstr "L'angle doit être compris entre 0,0 et 360,0. Il était de %g\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:800
|
||||
#, c-format
|
||||
msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n"
|
||||
msgstr ""
|
||||
"La valeur alpha doit être comprise entre 0,0 (invisible) et 1,0 (entièrement "
|
||||
"opaque). Elle était de %g\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:865
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,"
|
||||
"large,x-large,xx-large)\n"
|
||||
msgstr ""
|
||||
"Échelle de titre non valide « %s » (elle doit avoir l'une des valeurs "
|
||||
"suivantes : xx-small, x-small, small, medium,large, x-large, xx-large)\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084
|
||||
#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221
|
||||
#, c-format
|
||||
msgid "<%s> name \"%s\" used a second time"
|
||||
msgstr "<%s> - nom « %s » utilisé une deuxième fois"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130
|
||||
#: ../src/ui/theme-parser.c:1233
|
||||
#, c-format
|
||||
msgid "<%s> parent \"%s\" has not been defined"
|
||||
msgstr "<%s> - parent « %s » non défini"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1143
|
||||
#, c-format
|
||||
msgid "<%s> geometry \"%s\" has not been defined"
|
||||
msgstr "<%s> - géométrie « %s » non définie"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1156
|
||||
#, c-format
|
||||
msgid "<%s> must specify either a geometry or a parent that has a geometry"
|
||||
msgstr "<%s> doit indiquer une géométrie ou un parent qui en possède une"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1198
|
||||
msgid "You must specify a background for an alpha value to be meaningful"
|
||||
msgstr ""
|
||||
"Vous devez indiquer un arrière-plan pour qu'une valeur alpha ait du sens."
|
||||
|
||||
#: ../src/ui/theme-parser.c:1266
|
||||
#, c-format
|
||||
msgid "Unknown type \"%s\" on <%s> element"
|
||||
msgstr "Type inconnu « %s » sur l'élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1277
|
||||
#, c-format
|
||||
msgid "Unknown style_set \"%s\" on <%s> element"
|
||||
msgstr "style_set inconnu « %s » sur l'élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1285
|
||||
#, c-format
|
||||
msgid "Window type \"%s\" has already been assigned a style set"
|
||||
msgstr "Le type de fenêtre « %s » s'est déjà vu attribuer un jeu de styles"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379
|
||||
#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840
|
||||
#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036
|
||||
#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310
|
||||
#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed below <%s>"
|
||||
msgstr "L'élément <%s> n'est pas autorisé sous <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443
|
||||
#: ../src/ui/theme-parser.c:1488
|
||||
msgid ""
|
||||
"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" "
|
||||
"for buttons"
|
||||
msgstr ""
|
||||
"Impossible d'indiquer à la fois « button_width » / "
|
||||
"« button_height » (largeur/hauteur) et « aspect_ratio » (proportion) pour "
|
||||
"les boutons"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1452
|
||||
#, c-format
|
||||
msgid "Distance \"%s\" is unknown"
|
||||
msgstr "Distance « %s » inconnue"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1497
|
||||
#, c-format
|
||||
msgid "Aspect ratio \"%s\" is unknown"
|
||||
msgstr "Proportion « %s » inconnue"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1559
|
||||
#, c-format
|
||||
msgid "Border \"%s\" is unknown"
|
||||
msgstr "Bordure « %s » inconnue"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1870
|
||||
#, c-format
|
||||
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
|
||||
msgstr ""
|
||||
"Aucun attribut « start_angle » (« début d'angle ») ou « from » (« depuis ») "
|
||||
"sur l'élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1877
|
||||
#, c-format
|
||||
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
|
||||
msgstr ""
|
||||
"Aucun attribut « extent_angle » (« extension d'angle ») ou « to » (« vers ») "
|
||||
"sur l'élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2117
|
||||
#, c-format
|
||||
msgid "Did not understand value \"%s\" for type of gradient"
|
||||
msgstr "Impossible de comprendre la valeur « %s » pour le type de dégradé"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570
|
||||
#, c-format
|
||||
msgid "Did not understand fill type \"%s\" for <%s> element"
|
||||
msgstr ""
|
||||
"Impossible de comprendre le type de remplissage « %s » pour l'élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445
|
||||
#: ../src/ui/theme-parser.c:2508
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" for <%s> element"
|
||||
msgstr "Impossible de comprendre l'état « %s » pour l'élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455
|
||||
#, c-format
|
||||
msgid "Did not understand shadow \"%s\" for <%s> element"
|
||||
msgstr "Impossible de comprendre l'ombre « %s » pour l'élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2382
|
||||
#, c-format
|
||||
msgid "Did not understand arrow \"%s\" for <%s> element"
|
||||
msgstr "Impossible de comprendre la flèche « %s » pour l'élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792
|
||||
#, c-format
|
||||
msgid "No <draw_ops> called \"%s\" has been defined"
|
||||
msgstr "Aucun <draw_ops> appelé « %s » n'a été défini"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804
|
||||
#, c-format
|
||||
msgid "Including draw_ops \"%s\" here would create a circular reference"
|
||||
msgstr "L'inclusion du draw_ops « %s » ici créerait une référence circulaire"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2919
|
||||
#, c-format
|
||||
msgid "Unknown position \"%s\" for frame piece"
|
||||
msgstr "Position inconnue « %s » de la pièce du cadre"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2927
|
||||
#, c-format
|
||||
msgid "Frame style already has a piece at position %s"
|
||||
msgstr "Le style de cadre a déjà une pièce à la position %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021
|
||||
#, c-format
|
||||
msgid "No <draw_ops> with the name \"%s\" has been defined"
|
||||
msgstr "Aucun <draw_ops> avec le nom « %s » n'a été défini"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2974
|
||||
#, c-format
|
||||
msgid "Unknown function \"%s\" for button"
|
||||
msgstr "Fonction inconnue « %s » pour le bouton"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2984
|
||||
#, c-format
|
||||
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
|
||||
msgstr ""
|
||||
"La fonction « %s » du bouton n'existe pas dans la version (%d, a besoin de "
|
||||
"%d)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2996
|
||||
#, c-format
|
||||
msgid "Unknown state \"%s\" for button"
|
||||
msgstr "État inconnu « %s » pour le bouton"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3004
|
||||
#, c-format
|
||||
msgid "Frame style already has a button for function %s state %s"
|
||||
msgstr "Le style de cadre a déjà un bouton pour la fonction %s, état %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3075
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for focus attribute"
|
||||
msgstr "« %s » n'est pas une valeur valide pour l'attribut de focus"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3084
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for state attribute"
|
||||
msgstr "« %s » n'est pas une valeur valide pour l'attribut d'état"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3094
|
||||
#, c-format
|
||||
msgid "A style called \"%s\" has not been defined"
|
||||
msgstr "Aucun style appelé « %s » n'a été défini"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for resize attribute"
|
||||
msgstr ""
|
||||
"« %s » n'est pas une valeur valide pour l'attribut de redimensionnement"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3149
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
|
||||
"states"
|
||||
msgstr ""
|
||||
"L'attribut « resize » (« redimensionnement ») ne devrait pas figurer sur "
|
||||
"l'élément <%s> pour les états maximisé/réduit dans la barre de titre"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3163
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized states"
|
||||
msgstr ""
|
||||
"L'attribut « resize » (« redimensionnement ») ne devrait pas figurer sur "
|
||||
"l'élément <%s> pour l'état maximisé"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s resize %s focus %s"
|
||||
msgstr ""
|
||||
"Le style a déjà été indiqué pour l'état %s, redimensionnement %s, focus %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199
|
||||
#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232
|
||||
#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s focus %s"
|
||||
msgstr "Le style a déjà été indiqué pour l'état %s, focus %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3293
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
msgstr ""
|
||||
"Impossible d'avoir deux attributs draw_ops pour un élément <piece> (le thème "
|
||||
"indiquait un attribut draw_ops et un élément <draw_ops> ou deux éléments)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3331
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <button> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
msgstr ""
|
||||
"Impossible d'avoir deux attributs draw_ops pour un élément <button> (le "
|
||||
"thème indiquait un attribut draw_ops et un élément <draw_ops> ou deux "
|
||||
"éléments)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3369
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <menu_icon> element (theme specified a "
|
||||
"draw_ops attribute and also a <draw_ops> element, or specified two elements)"
|
||||
msgstr ""
|
||||
"Impossible d'avoir deux attributs draw_ops pour un élément <menu_icon> (le "
|
||||
"thème indiquait un attribut draw_ops et un élément <draw_ops> ou deux "
|
||||
"éléments)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3433
|
||||
#, c-format
|
||||
msgid "Bad version specification '%s'"
|
||||
msgstr "Mauvaise spécification de version « %s »"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3506
|
||||
msgid ""
|
||||
"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
|
||||
"theme-2.xml"
|
||||
msgstr ""
|
||||
"L'attribut « version » ne peut pas être utilisé dans metacity-theme-1.xml or "
|
||||
"metacity-theme-2.xml"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3529
|
||||
#, c-format
|
||||
msgid "Theme requires version %s but latest supported theme version is %d.%d"
|
||||
msgstr ""
|
||||
"Le thème nécessite la version %s mais la version de thème la plus récente "
|
||||
"prise en charge est %d.%d"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3561
|
||||
#, c-format
|
||||
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
|
||||
msgstr ""
|
||||
"L'élément le plus extérieur dans le thème doit être <metacity_theme> et non <"
|
||||
"%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3581
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Element <%s> is not allowed inside a name/author/date/description element"
|
||||
msgstr ""
|
||||
"L'élément <%s> n'est pas autorisé dans un élément name/author/date/"
|
||||
"description"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3586
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <constant> element"
|
||||
msgstr "L'élément <%s> n'est pas autorisé dans un élément <constant>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3598
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Element <%s> is not allowed inside a distance/border/aspect_ratio element"
|
||||
msgstr ""
|
||||
"L'élément <%s> n'est pas autorisé dans un élément distance/border/"
|
||||
"aspect_ratio"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3620
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a draw operation element"
|
||||
msgstr ""
|
||||
"L'élément <%s> n'est pas autorisé dans un élément d'opération de dessin"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660
|
||||
#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <%s> element"
|
||||
msgstr "L'élément <%s> n'est pas autorisé dans un élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3898
|
||||
msgid "No draw_ops provided for frame piece"
|
||||
msgstr "Aucun attribut draw_ops fourni pour la pièce du cadre"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3913
|
||||
msgid "No draw_ops provided for button"
|
||||
msgstr "Aucun attribut draw_ops fourni pour le bouton"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3967
|
||||
#, c-format
|
||||
msgid "No text is allowed inside element <%s>"
|
||||
msgstr "Aucun texte autorisé dans l'élément <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037
|
||||
#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061
|
||||
#: ../src/ui/theme-parser.c:4073
|
||||
#, c-format
|
||||
msgid "<%s> specified twice for this theme"
|
||||
msgstr "<%s> indiqué deux fois pour ce thème"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4335
|
||||
#, c-format
|
||||
msgid "Failed to find a valid file for theme %s\n"
|
||||
msgstr "Impossible de trouver un fichier valide pour le thème %s\n"
|
||||
|
||||
#: ../src/x11/session.c:1815
|
||||
msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
@ -1349,7 +621,7 @@ msgstr ""
|
||||
"configuration actuelle » et devront être redémarrées manuellement à la "
|
||||
"prochaine connexion."
|
||||
|
||||
#: ../src/x11/window-props.c:515
|
||||
#: ../src/x11/window-props.c:549
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (sur %s)"
|
||||
|
764
po/id.po
764
po/id.po
@ -5,21 +5,21 @@
|
||||
# Mohammad DAMT <mdamt@bisnisweb.com>, 2003-2005.
|
||||
# Ahmad Riza H Nst <rizahnst@eriagempita.co.id>, 2006.
|
||||
# Dirgita <dirgitadevina@yahoo.co.id>, 2011, 2012, 2014.
|
||||
# Andika Triwidada <andika@gmail.com>, 2011, 2012, 2013, 2014.
|
||||
# Andika Triwidada <andika@gmail.com>, 2011-2015.
|
||||
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: 2014-09-01 21:52+0000\n"
|
||||
"PO-Revision-Date: 2014-09-03 20:56+0700\n"
|
||||
"POT-Creation-Date: 2015-03-21 11:13+0000\n"
|
||||
"PO-Revision-Date: 2015-03-21 19:04+0700\n"
|
||||
"Last-Translator: Andika Triwidada <andika@gmail.com>\n"
|
||||
"Language-Team: Indonesian <gnome-l10n-id@googlegroups.com>\n"
|
||||
"Language: id\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.6.9\n"
|
||||
"X-Generator: Poedit 1.7.1\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: ../data/50-mutter-navigation.xml.in.h:1
|
||||
@ -434,29 +434,49 @@ msgstr "Pindah ke VT 6"
|
||||
msgid "Switch to VT 7"
|
||||
msgstr "Pindah ke VT 7"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:412
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
|
||||
msgid "Switch to VT 8"
|
||||
msgstr "Pindah ke VT 8"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
|
||||
msgid "Switch to VT 9"
|
||||
msgstr "Pindah ke VT 9"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
|
||||
msgid "Switch to VT 10"
|
||||
msgstr "Pindah ke VT 10"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
|
||||
msgid "Switch to VT 11"
|
||||
msgstr "Pindah ke VT 11"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "Pindah ke VT 12"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:364
|
||||
msgid "Built-in display"
|
||||
msgstr "Tampilan bawaan"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:437
|
||||
#: ../src/backends/meta-monitor-manager.c:391
|
||||
msgid "Unknown"
|
||||
msgstr "Tak Dikenal"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:439
|
||||
#: ../src/backends/meta-monitor-manager.c:393
|
||||
msgid "Unknown Display"
|
||||
msgstr "Tampilan Tak Dikenal"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:447
|
||||
#: ../src/backends/meta-monitor-manager.c:401
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:443
|
||||
#: ../src/compositor/compositor.c:456
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@ -464,10 +484,6 @@ msgid ""
|
||||
msgstr ""
|
||||
"Manajer komposit lain telah berjalan pada layar %i pada tampilan \"%s\"."
|
||||
|
||||
#: ../src/compositor/meta-background.c:1044
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "tekstur latar tak bisa dibuat dari berkas"
|
||||
|
||||
#: ../src/core/bell.c:185
|
||||
msgid "Bell event"
|
||||
msgstr "Bel peristiwa"
|
||||
@ -496,7 +512,7 @@ msgstr "_Tunggu"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Matikan Paksa"
|
||||
|
||||
#: ../src/core/display.c:547
|
||||
#: ../src/core/display.c:562
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr "Gagal membuka tampilan X Window System '%s'\n"
|
||||
@ -533,17 +549,6 @@ msgstr "Jalankan sebagai kompositor wayland"
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Jalankan sebagai server tampilan penuh, ketimbang tampilan bersarang"
|
||||
|
||||
#: ../src/core/main.c:459
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Gagal memeriksa direktori tema: %s\n"
|
||||
|
||||
#: ../src/core/main.c:475
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
msgstr "Tak menemukan tema! Pastikan %s ada dan berisi tema yang biasa.\n"
|
||||
|
||||
#: ../src/core/mutter.c:39
|
||||
#, c-format
|
||||
msgid ""
|
||||
@ -568,714 +573,29 @@ msgstr "Cetak versi"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Pengaya Mutter yang dipakai"
|
||||
|
||||
#: ../src/core/prefs.c:2101
|
||||
#: ../src/core/prefs.c:2004
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Area kerja %d"
|
||||
|
||||
#: ../src/core/screen.c:548
|
||||
#: ../src/core/screen.c:525
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display \"%s\" already has a window manager; try using the --replace option "
|
||||
"to replace the current window manager."
|
||||
msgstr ""
|
||||
"Tampilan \"%s\" sudah memiliki manajer jendela; cobalah gunakan pilihan --"
|
||||
"replace untuk mengganti manajer jendela saat ini."
|
||||
|
||||
#: ../src/core/screen.c:607
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Layar %d pada tampilan '%s' tidak benar\n"
|
||||
|
||||
#: ../src/core/screen.c:564
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
"replace option to replace the current window manager.\n"
|
||||
msgstr ""
|
||||
"Layar %d pada tampilan \"%s\" sudah memiliki pengatur jendela. Cobalah "
|
||||
"gunakan pilihan --replace untuk mengganti pengatur jendela yang aktif.\n"
|
||||
|
||||
#: ../src/core/screen.c:657
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "Layar %d pada tampilan \"%s\" sudah ada pengatur jendelanya\n"
|
||||
|
||||
#: ../src/core/util.c:118
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr "Muter dikompilasi tanpa dukungan mode riuh\n"
|
||||
|
||||
#. Translators: This represents the size of a window. The first number is
|
||||
#. * the width of the window and the second is the height.
|
||||
#.
|
||||
#: ../src/ui/resizepopup.c:134
|
||||
#, c-format
|
||||
msgid "%d x %d"
|
||||
msgstr "%d x %d"
|
||||
|
||||
#: ../src/ui/theme.c:233
|
||||
msgid "top"
|
||||
msgstr "atas"
|
||||
|
||||
#: ../src/ui/theme.c:235
|
||||
msgid "bottom"
|
||||
msgstr "bawah"
|
||||
|
||||
#: ../src/ui/theme.c:237
|
||||
msgid "left"
|
||||
msgstr "kiri"
|
||||
|
||||
#: ../src/ui/theme.c:239
|
||||
msgid "right"
|
||||
msgstr "kanan"
|
||||
|
||||
#: ../src/ui/theme.c:267
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify \"%s\" dimension"
|
||||
msgstr "ukuran frame tidak menyebutkan dimensi \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:286
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
|
||||
msgstr "ukuran frame tidak menyebutkan dimensi \"%s\" untuk batas \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:323
|
||||
#, c-format
|
||||
msgid "Button aspect ratio %g is not reasonable"
|
||||
msgstr "Aspek rasio tombol %g tidak wajar"
|
||||
|
||||
#: ../src/ui/theme.c:335
|
||||
#, c-format
|
||||
msgid "Frame geometry does not specify size of buttons"
|
||||
msgstr "Ukuran frame tidak menyebutkan ukuran tombol"
|
||||
|
||||
#: ../src/ui/theme.c:1061
|
||||
#, c-format
|
||||
msgid "Gradients should have at least two colors"
|
||||
msgstr "Gradien harus paling tidak ada dua warna"
|
||||
|
||||
#: ../src/ui/theme.c:1211
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK custom color specification must have color name and fallback in "
|
||||
"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
|
||||
msgstr ""
|
||||
"Spesifikasi warna ubahan GTK mesti memiliki nama warna dan cadangan dalam "
|
||||
"kurung, mis. gtk:custom(foo,bar); tak bisa mengurai \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1227
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
|
||||
"_ are valid"
|
||||
msgstr ""
|
||||
"Karakter tak valid '%c' dalam parameter color_name dari gtk:custom, hanya A-"
|
||||
"Za-z0-9-_ yang valid"
|
||||
|
||||
#: ../src/ui/theme.c:1241
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
||||
"fit the format"
|
||||
msgstr ""
|
||||
"Format Gtk:custom adalah \"gtk:custom(color_name,fallback)\", \"%s\" tak "
|
||||
"memenuhi format"
|
||||
|
||||
#: ../src/ui/theme.c:1286
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
|
||||
"where NORMAL is the state; could not parse \"%s\""
|
||||
msgstr ""
|
||||
"Spesifikasi warna GTK harus memiliki kondisi pada kurung, misal gtk:"
|
||||
"fg[NORMAL] dengan NORMAL adalah jenis kondisinya, tidak dapat membaca \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1300
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have a close bracket after the state, e.g. gtk:"
|
||||
"fg[NORMAL] where NORMAL is the state; could not parse \"%s\""
|
||||
msgstr ""
|
||||
"Spesifikasi warna GTK harus memiliki kurung tutup pada kondisinya, misal gtk:"
|
||||
"fg[NORMAL] dengan NORMAL adalah jenis kondisinya, tidak dapat membaca \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1311
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" in color specification"
|
||||
msgstr "Kondisi \"%s\" tidak benar pada spesifikasi warna"
|
||||
|
||||
#: ../src/ui/theme.c:1324
|
||||
#, c-format
|
||||
msgid "Did not understand color component \"%s\" in color specification"
|
||||
msgstr "Komponen warna \"%s\" tidak benar pada spesifikasi warna"
|
||||
|
||||
#: ../src/ui/theme.c:1352
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
|
||||
"format"
|
||||
msgstr ""
|
||||
"Format pencampuran adalah \"blend/bg_color/fg_color/alpha\", \"%s\" bukan "
|
||||
"ditulis dalam format yang benar"
|
||||
|
||||
#: ../src/ui/theme.c:1363
|
||||
#, c-format
|
||||
msgid "Could not parse alpha value \"%s\" in blended color"
|
||||
msgstr "Tak dapat membaca nilai alpha \"%s\" pada pencampuran warna"
|
||||
|
||||
#: ../src/ui/theme.c:1373
|
||||
#, c-format
|
||||
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
|
||||
msgstr ""
|
||||
"Nilai alpha \"%s\" pada warna yang dicampur tidak ada dalam rentang 0.0 dan "
|
||||
"1.0"
|
||||
|
||||
#: ../src/ui/theme.c:1419
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
|
||||
msgstr ""
|
||||
"Format bayangan adalah \"shade/base_color/factor\", \"%s\" ditulis dalam "
|
||||
"format yang keliru"
|
||||
|
||||
#: ../src/ui/theme.c:1430
|
||||
#, c-format
|
||||
msgid "Could not parse shade factor \"%s\" in shaded color"
|
||||
msgstr "Tak dapat membaca faktor bayangan \"%s\" pada warna berbayang"
|
||||
|
||||
#: ../src/ui/theme.c:1440
|
||||
#, c-format
|
||||
msgid "Shade factor \"%s\" in shaded color is negative"
|
||||
msgstr "Faktor bayangan \"%s\" pada warna berbayang bernilai negatif"
|
||||
|
||||
#: ../src/ui/theme.c:1469
|
||||
#, c-format
|
||||
msgid "Could not parse color \"%s\""
|
||||
msgstr "Tak dapat membaca warna \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1778
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains character '%s' which is not allowed"
|
||||
msgstr "Ekspresi koordinat berisi karakter '%s' yang tidak diperbolehkan"
|
||||
|
||||
#: ../src/ui/theme.c:1805
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contains floating point number '%s' which could not be "
|
||||
"parsed"
|
||||
msgstr ""
|
||||
"Ekspresi koordinat berisi angka floating point '%s' yang tidak dapat dibaca"
|
||||
|
||||
#: ../src/ui/theme.c:1819
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains integer '%s' which could not be parsed"
|
||||
msgstr "Ekspresi koordinat berisi integer '%s' yang tidak dapat dibaca"
|
||||
|
||||
#: ../src/ui/theme.c:1940
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contained unknown operator at the start of this text: "
|
||||
"\"%s\""
|
||||
msgstr ""
|
||||
"Ekspresi koordinat berisi operator tak dikenal pada awal teks berikut: \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1997
|
||||
#, c-format
|
||||
msgid "Coordinate expression was empty or not understood"
|
||||
msgstr "Ekspresi koordinat kosong atau tidak dapat dimengerti"
|
||||
|
||||
#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154
|
||||
#, c-format
|
||||
msgid "Coordinate expression results in division by zero"
|
||||
msgstr "Ekspresi koordinat menghasilkan pembagian dengan nol"
|
||||
|
||||
#: ../src/ui/theme.c:2162
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression tries to use mod operator on a floating-point number"
|
||||
msgstr "Ekspresi koordinat menggunakan operator mod pada angka bilangan nyata"
|
||||
|
||||
#: ../src/ui/theme.c:2218
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has an operator \"%s\" where an operand was expected"
|
||||
msgstr "Ekspresi koordinat menggunakan operator \"%s\" tanpa adanya operan"
|
||||
|
||||
#: ../src/ui/theme.c:2227
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an operand where an operator was expected"
|
||||
msgstr "Ekspresi koordinat menggunakan operand tanpa operator"
|
||||
|
||||
#: ../src/ui/theme.c:2235
|
||||
#, c-format
|
||||
msgid "Coordinate expression ended with an operator instead of an operand"
|
||||
msgstr ""
|
||||
"Ekspresi koordinat diakhiri dengan operator, seharusnya diakhiri dengan "
|
||||
"operand"
|
||||
|
||||
#: ../src/ui/theme.c:2245
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
|
||||
"operand in between"
|
||||
msgstr ""
|
||||
"Ekspresi koordinat memiliki operator \"%c\" diikuti operator \"%c\" tanpa "
|
||||
"adanya operand di antarany"
|
||||
|
||||
#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441
|
||||
#, c-format
|
||||
msgid "Coordinate expression had unknown variable or constant \"%s\""
|
||||
msgstr ""
|
||||
"Ada variabel atau konstanta \"%s\" tidak diketahui pada ekspresi koordinat"
|
||||
|
||||
#: ../src/ui/theme.c:2495
|
||||
#, c-format
|
||||
msgid "Coordinate expression parser overflowed its buffer."
|
||||
msgstr "Ekspresi koordinat melampaui batasannya."
|
||||
|
||||
#: ../src/ui/theme.c:2524
|
||||
#, c-format
|
||||
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
|
||||
msgstr "Terdapat kurung tutup tanpa kurung buka pada ekspresi koordinat"
|
||||
|
||||
#: ../src/ui/theme.c:2588
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
|
||||
msgstr "Terdapat kurung buka tanpa kurung tutup pada ekspresi koordinat"
|
||||
|
||||
#: ../src/ui/theme.c:2599
|
||||
#, c-format
|
||||
msgid "Coordinate expression doesn't seem to have any operators or operands"
|
||||
msgstr "Ekspresi koordinat sepertinya tidak memiliki operator atau operan"
|
||||
|
||||
#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852
|
||||
#, c-format
|
||||
msgid "Theme contained an expression that resulted in an error: %s\n"
|
||||
msgstr "Tema mengandung ekspresi yang menghasilkan galat: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:4455
|
||||
#, c-format
|
||||
msgid ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
|
||||
"specified for this frame style"
|
||||
msgstr ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> tidak "
|
||||
"disebutkan pada gaya frame ini"
|
||||
|
||||
#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
|
||||
msgstr ""
|
||||
"<frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/> tidak ada"
|
||||
|
||||
#: ../src/ui/theme.c:5041
|
||||
#, c-format
|
||||
msgid "Failed to load theme \"%s\": %s\n"
|
||||
msgstr "Gagal membuka tema \"%s\": %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191
|
||||
#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205
|
||||
#, c-format
|
||||
msgid "No <%s> set for theme \"%s\""
|
||||
msgstr "Tak ada <%s> yang ditentukan untuk tema \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:5213
|
||||
#, c-format
|
||||
msgid ""
|
||||
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
|
||||
"type=\"%s\" style_set=\"whatever\"/> element"
|
||||
msgstr ""
|
||||
"Tak ada gaya frame untuk tipe window \"%s\" pada tema \"%s\". Tambah dulu "
|
||||
"elemen <window type=\"%s\" style_set=\"whatever\"/>"
|
||||
|
||||
#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745
|
||||
#, c-format
|
||||
msgid ""
|
||||
"User-defined constants must begin with a capital letter; \"%s\" does not"
|
||||
msgstr ""
|
||||
"Konstanta buatan pengguna harus dimulai dengan huruf besar: \"%s\" tidak"
|
||||
|
||||
#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753
|
||||
#, c-format
|
||||
msgid "Constant \"%s\" has already been defined"
|
||||
msgstr "Konstanta \"%s\" telah didefinisikan sebelumnya"
|
||||
|
||||
#. Translators: This means that an attribute which should have been found
|
||||
#. * on an XML element was not in fact found.
|
||||
#.
|
||||
#: ../src/ui/theme-parser.c:234
|
||||
#, c-format
|
||||
msgid "No \"%s\" attribute on element <%s>"
|
||||
msgstr "Tak ada atribut \"%s\" pada elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281
|
||||
#, c-format
|
||||
msgid "Line %d character %d: %s"
|
||||
msgstr "Baris %d karakter %d: %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:481
|
||||
#, c-format
|
||||
msgid "Attribute \"%s\" repeated twice on the same <%s> element"
|
||||
msgstr "Atribut \"%s\" diulangi dua kali pada elemen <%s> yang sama"
|
||||
|
||||
#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554
|
||||
#, c-format
|
||||
msgid "Attribute \"%s\" is invalid on <%s> element in this context"
|
||||
msgstr "Atribut \"%s\" tidak diperkenankan pada elemen <%s> pada konteks ini"
|
||||
|
||||
#: ../src/ui/theme-parser.c:596
|
||||
#, c-format
|
||||
msgid "Could not parse \"%s\" as an integer"
|
||||
msgstr "Tak dapat menguraikan \"%s\" sebagai integer"
|
||||
|
||||
#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660
|
||||
#, c-format
|
||||
msgid "Did not understand trailing characters \"%s\" in string \"%s\""
|
||||
msgstr "Tak mengerti karakter \"%s\" kenapa ada dibuntut string \"%s\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:615
|
||||
#, c-format
|
||||
msgid "Integer %ld must be positive"
|
||||
msgstr "Integer %ld harus bernilai positif"
|
||||
|
||||
#: ../src/ui/theme-parser.c:623
|
||||
#, c-format
|
||||
msgid "Integer %ld is too large, current max is %d"
|
||||
msgstr "Integer %ld terlalu besar, maksimal %d"
|
||||
|
||||
#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767
|
||||
#, c-format
|
||||
msgid "Could not parse \"%s\" as a floating point number"
|
||||
msgstr "Tak dapat membaca \"%s\" sebagai angka floating point"
|
||||
|
||||
#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710
|
||||
#, c-format
|
||||
msgid "Boolean values must be \"true\" or \"false\" not \"%s\""
|
||||
msgstr "Nilai boolean harus \"true\" atau \"false\" dan bukannya \"%s\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:737
|
||||
#, c-format
|
||||
msgid "Angle must be between 0.0 and 360.0, was %g\n"
|
||||
msgstr "Sudut harus ada dalam rentang 0.0 dan 360.0, dalam berkas didapat %g\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:800
|
||||
#, c-format
|
||||
msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n"
|
||||
msgstr ""
|
||||
"Alpha harus ada dalam rentang 0.0 (tidak kelihatan) dan 1.0 (nampak semua, "
|
||||
"dalam berkas didapat %g\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:865
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,"
|
||||
"large,x-large,xx-large)\n"
|
||||
msgstr ""
|
||||
"Skala judul \"%s\" tidak benar (harusnya bernilai xx-small, x-small, small, "
|
||||
"medium, large, x-large, xx-large)\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084
|
||||
#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221
|
||||
#, c-format
|
||||
msgid "<%s> name \"%s\" used a second time"
|
||||
msgstr "Nama <%s> \"%s\" digunakan kedua kali"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130
|
||||
#: ../src/ui/theme-parser.c:1233
|
||||
#, c-format
|
||||
msgid "<%s> parent \"%s\" has not been defined"
|
||||
msgstr "Induk <%s> \"%s\" belum didefinisikan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1143
|
||||
#, c-format
|
||||
msgid "<%s> geometry \"%s\" has not been defined"
|
||||
msgstr "Geometri <%s> \"%s\" belum didefinisikan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1156
|
||||
#, c-format
|
||||
msgid "<%s> must specify either a geometry or a parent that has a geometry"
|
||||
msgstr "<%s> harus menentukan geometri atau induk yang ada geometrinya"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1198
|
||||
msgid "You must specify a background for an alpha value to be meaningful"
|
||||
msgstr ""
|
||||
"Anda mesti menyatakan suatu latar belakang bagi nilai alfa agar berarti"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1266
|
||||
#, c-format
|
||||
msgid "Unknown type \"%s\" on <%s> element"
|
||||
msgstr "Tipe \"%s\" tidak dikenal pada elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1277
|
||||
#, c-format
|
||||
msgid "Unknown style_set \"%s\" on <%s> element"
|
||||
msgstr "style_set \"%s\" tidak dikenali pada elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1285
|
||||
#, c-format
|
||||
msgid "Window type \"%s\" has already been assigned a style set"
|
||||
msgstr "Tipe jendela \"%s\" sudah memiliki set gaya"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379
|
||||
#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840
|
||||
#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036
|
||||
#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310
|
||||
#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed below <%s>"
|
||||
msgstr "Elemen <%s> tidak diperkenankan ada di bawah <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443
|
||||
#: ../src/ui/theme-parser.c:1488
|
||||
msgid ""
|
||||
"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" "
|
||||
"for buttons"
|
||||
msgstr ""
|
||||
"Tak dapat menyatakan \"button_width\"/\"button_height\" dan \"aspect_ratio\" "
|
||||
"sekaligus untuk tombol"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1452
|
||||
#, c-format
|
||||
msgid "Distance \"%s\" is unknown"
|
||||
msgstr "Jarak \"%s\" tidak dikenal"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1497
|
||||
#, c-format
|
||||
msgid "Aspect ratio \"%s\" is unknown"
|
||||
msgstr "Rasio aspek \"%s\" tidak dikenal"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1559
|
||||
#, c-format
|
||||
msgid "Border \"%s\" is unknown"
|
||||
msgstr "Batas \"%s\" tidak dikenal"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1870
|
||||
#, c-format
|
||||
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
|
||||
msgstr "Tak ada atribut \"start_angle\" atau \"from\" pada elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1877
|
||||
#, c-format
|
||||
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
|
||||
msgstr "Tak ada atribut \"extent_angle\" atau \"to\" pada elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2117
|
||||
#, c-format
|
||||
msgid "Did not understand value \"%s\" for type of gradient"
|
||||
msgstr "Nilai \"%s\" bukan nilai yang sah untuk tipe gradien"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570
|
||||
#, c-format
|
||||
msgid "Did not understand fill type \"%s\" for <%s> element"
|
||||
msgstr "Tipe isian \"%s\" tidak dikenal untuk elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445
|
||||
#: ../src/ui/theme-parser.c:2508
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" for <%s> element"
|
||||
msgstr "Kondisi \"%s\" tidak dikenal untuk elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455
|
||||
#, c-format
|
||||
msgid "Did not understand shadow \"%s\" for <%s> element"
|
||||
msgstr "Bayangan \"%s\" tidak dikenal untuk elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2382
|
||||
#, c-format
|
||||
msgid "Did not understand arrow \"%s\" for <%s> element"
|
||||
msgstr "Panah \"%s\" tidak dikenal untuk elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792
|
||||
#, c-format
|
||||
msgid "No <draw_ops> called \"%s\" has been defined"
|
||||
msgstr "Tak ada <draw_ops> bernama \"%s\" yang telah didefinisikan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804
|
||||
#, c-format
|
||||
msgid "Including draw_ops \"%s\" here would create a circular reference"
|
||||
msgstr ""
|
||||
"Menyertakan draw_ops \"%s\" di sini akan membuat referensi tak berujung"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2919
|
||||
#, c-format
|
||||
msgid "Unknown position \"%s\" for frame piece"
|
||||
msgstr "Posisi \"%s\" tidak dikenal untuk bagian frame"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2927
|
||||
#, c-format
|
||||
msgid "Frame style already has a piece at position %s"
|
||||
msgstr "Gaya frame sudah memiliki bagian pada posisi %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021
|
||||
#, c-format
|
||||
msgid "No <draw_ops> with the name \"%s\" has been defined"
|
||||
msgstr "Tak ada <draw_ops> dengan nama \"%s\" yang didefinisikan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2974
|
||||
#, c-format
|
||||
msgid "Unknown function \"%s\" for button"
|
||||
msgstr "Fungsi \"%s\" tidak dikenal untuk tombol"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2984
|
||||
#, c-format
|
||||
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
|
||||
msgstr ""
|
||||
"Tombol fungsi \"%s\" tidak tersedia untuk versi ini (%d, memerlukan %d)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2996
|
||||
#, c-format
|
||||
msgid "Unknown state \"%s\" for button"
|
||||
msgstr "Kondisi \"%s\" tidak dikenal untuk tombol"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3004
|
||||
#, c-format
|
||||
msgid "Frame style already has a button for function %s state %s"
|
||||
msgstr "Gaya bingkai sudah memiliki tombol untuk fungsi %s kondisi %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3075
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for focus attribute"
|
||||
msgstr "\"%s\" bukan nilai yang benar untuk atribut focus"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3084
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for state attribute"
|
||||
msgstr "\"%s\" bukan nilai yang benar untuk atribut state"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3094
|
||||
#, c-format
|
||||
msgid "A style called \"%s\" has not been defined"
|
||||
msgstr "Gaya bernama \"%s\" belum didefinisikan"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for resize attribute"
|
||||
msgstr "\"%s\" bukan nilai yang benar untuk atribut resize"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3149
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
|
||||
"states"
|
||||
msgstr ""
|
||||
"Atribut \"resize\" tidak boleh ada pada elemen <%s> untuk kondisi ukuran "
|
||||
"window maksimum/tergulung"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3163
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized states"
|
||||
msgstr ""
|
||||
"Atribut \"resize\" tidak boleh ada pada elemen <%s> untuk kondisi ukuran "
|
||||
"jendela maksimal"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s resize %s focus %s"
|
||||
msgstr "Gaya sudah menjelaskan kondisi %s resize %s focus %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199
|
||||
#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232
|
||||
#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s focus %s"
|
||||
msgstr "Gaya sudah menjelaskan kondisi %s focus %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3293
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
msgstr ""
|
||||
"Tak boleh ada dua draw_ops untuk elemen <piece> (tema menyebutkan atribut "
|
||||
"draw_ops dan juga elemen <draw_ops> atau meyebutkan dua elemen tersebut "
|
||||
|
||||
#: ../src/ui/theme-parser.c:3331
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <button> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
msgstr ""
|
||||
"Tak boleh ada dua draw_ops untuk elemen <button> (tema menyebutkan atribut "
|
||||
"draw_ops dan juga elemen <draw_ops> atau meyebutkan dua elemen tersebut "
|
||||
|
||||
#: ../src/ui/theme-parser.c:3369
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <menu_icon> element (theme specified a "
|
||||
"draw_ops attribute and also a <draw_ops> element, or specified two elements)"
|
||||
msgstr ""
|
||||
"Tak boleh ada dua draw_ops untuk elemen <menu_icon> (tema menyebutkan "
|
||||
"atribut draw_ops dan juga elemen <draw_ops> atau meyebutkan dua elemen "
|
||||
"tersebut "
|
||||
|
||||
#: ../src/ui/theme-parser.c:3433
|
||||
#, c-format
|
||||
msgid "Bad version specification '%s'"
|
||||
msgstr "Spesifikasi versi '%s' jelek"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3506
|
||||
msgid ""
|
||||
"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
|
||||
"theme-2.xml"
|
||||
msgstr ""
|
||||
"Atribut \"version\" tidak dapat dipakai dalam metacity-theme-1.xml atau "
|
||||
"metacity-theme-2.xml"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3529
|
||||
#, c-format
|
||||
msgid "Theme requires version %s but latest supported theme version is %d.%d"
|
||||
msgstr "Tema memerlukan versi %s tetapi versi yang didukung adalah %d.%d"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3561
|
||||
#, c-format
|
||||
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
|
||||
msgstr "Elemen tema paling luar haruslah <metacity_theme> dan bukan <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3581
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Element <%s> is not allowed inside a name/author/date/description element"
|
||||
msgstr ""
|
||||
"Elemen <%s> tidak diperbolehkan berada elemen name/author/date/description"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3586
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <constant> element"
|
||||
msgstr "Elemen <%s> tidak boleh ada dalam elemen <constat>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3598
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Element <%s> is not allowed inside a distance/border/aspect_ratio element"
|
||||
msgstr ""
|
||||
"Elemen <%s> tidak boleh ada di dalam elemen distance/border/aspec_ratio"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3620
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a draw operation element"
|
||||
msgstr "Elemen <%s> tidak boleh ada di dalam elemen operasi gambar"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660
|
||||
#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <%s> element"
|
||||
msgstr "Elemen <%s> tidak boleh ada di dalam elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3898
|
||||
msgid "No draw_ops provided for frame piece"
|
||||
msgstr "Tak ada draw_ops yang disediakan untuk bagian frame"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3913
|
||||
msgid "No draw_ops provided for button"
|
||||
msgstr "Tak ada draw_ops yang disediakan untuk tombol"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3967
|
||||
#, c-format
|
||||
msgid "No text is allowed inside element <%s>"
|
||||
msgstr "Tak boleh ada teks di dalam elemen <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037
|
||||
#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061
|
||||
#: ../src/ui/theme-parser.c:4073
|
||||
#, c-format
|
||||
msgid "<%s> specified twice for this theme"
|
||||
msgstr "<%s> disebutkan dua kali pada tema ini"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4335
|
||||
#, c-format
|
||||
msgid "Failed to find a valid file for theme %s\n"
|
||||
msgstr "Gagal menemukan berkas yang sah untuk tema %s\n"
|
||||
|
||||
#: ../src/x11/session.c:1815
|
||||
msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
@ -1284,7 +604,7 @@ msgstr ""
|
||||
"Jendela ini tidak bisa "menyimpan setelan aktif saat ini" dan bila "
|
||||
"log masuk kali lain Anda harus menjalankannya ulang."
|
||||
|
||||
#: ../src/x11/window-props.c:515
|
||||
#: ../src/x11/window-props.c:549
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (pada %s)"
|
||||
|
795
po/pl.po
795
po/pl.po
@ -9,14 +9,14 @@
|
||||
# Marek Stępień <marcoos@aviary.pl>, 2007.
|
||||
# Wadim Dziedzic <wdziedzic@aviary.pl>, 2007.
|
||||
# Tomasz Dominikowski <dominikowski@gmail.com>, 2008-2009.
|
||||
# Piotr Drąg <piotrdrag@gmail.com>, 2010-2014.
|
||||
# Aviary.pl <gnomepl@aviary.pl>, 2007-2014.
|
||||
# Piotr Drąg <piotrdrag@gmail.com>, 2010-2015.
|
||||
# Aviary.pl <gnomepl@aviary.pl>, 2007-2015.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: mutter\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-09-03 15:55+0200\n"
|
||||
"PO-Revision-Date: 2014-09-03 15:58+0200\n"
|
||||
"POT-Creation-Date: 2015-03-05 00:23+0100\n"
|
||||
"PO-Revision-Date: 2015-03-05 00:24+0100\n"
|
||||
"Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
|
||||
"Language-Team: Polish <gnomepl@aviary.pl>\n"
|
||||
"Language: pl\n"
|
||||
@ -448,29 +448,49 @@ msgstr "Przełączenie na 6. konsolę wirtualną"
|
||||
msgid "Switch to VT 7"
|
||||
msgstr "Przełączenie na 7. konsolę wirtualną"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:412
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:8
|
||||
msgid "Switch to VT 8"
|
||||
msgstr "Przełączenie na 8. konsolę wirtualną"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:9
|
||||
msgid "Switch to VT 9"
|
||||
msgstr "Przełączenie na 9. konsolę wirtualną"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:10
|
||||
msgid "Switch to VT 10"
|
||||
msgstr "Przełączenie na 10. konsolę wirtualną"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:11
|
||||
msgid "Switch to VT 11"
|
||||
msgstr "Przełączenie na 11. konsolę wirtualną"
|
||||
|
||||
#: ../data/org.gnome.mutter.wayland.gschema.xml.in.h:12
|
||||
msgid "Switch to VT 12"
|
||||
msgstr "Przełączenie na 12. konsolę wirtualną"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:364
|
||||
msgid "Built-in display"
|
||||
msgstr "Wbudowany ekran"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:437
|
||||
#: ../src/backends/meta-monitor-manager.c:391
|
||||
msgid "Unknown"
|
||||
msgstr "Nieznany"
|
||||
|
||||
#: ../src/backends/meta-monitor-manager.c:439
|
||||
#: ../src/backends/meta-monitor-manager.c:393
|
||||
msgid "Unknown Display"
|
||||
msgstr "Nieznany ekran"
|
||||
|
||||
#. TRANSLATORS: this is a monitor vendor name, followed by a
|
||||
#. * size in inches, like 'Dell 15"'
|
||||
#.
|
||||
#: ../src/backends/meta-monitor-manager.c:447
|
||||
#: ../src/backends/meta-monitor-manager.c:401
|
||||
#, c-format
|
||||
msgid "%s %s"
|
||||
msgstr "%s %s"
|
||||
|
||||
#. This probably means that a non-WM compositor like xcompmgr is running;
|
||||
#. * we have no way to get it to exit
|
||||
#: ../src/compositor/compositor.c:443
|
||||
#: ../src/compositor/compositor.c:456
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Another compositing manager is already running on screen %i on display \"%s"
|
||||
@ -478,10 +498,6 @@ msgid ""
|
||||
msgstr ""
|
||||
"Inny menedżer składania jest już uruchomiony na podekranie %i ekranu \"%s\"."
|
||||
|
||||
#: ../src/compositor/meta-background.c:1044
|
||||
msgid "background texture could not be created from file"
|
||||
msgstr "nie można utworzyć tekstury tła z pliku"
|
||||
|
||||
#: ../src/core/bell.c:185
|
||||
msgid "Bell event"
|
||||
msgstr "Zdarzenie sygnału dźwiękowego"
|
||||
@ -509,7 +525,7 @@ msgstr "_Czekaj"
|
||||
msgid "_Force Quit"
|
||||
msgstr "_Zakończ"
|
||||
|
||||
#: ../src/core/display.c:547
|
||||
#: ../src/core/display.c:562
|
||||
#, c-format
|
||||
msgid "Failed to open X Window System display '%s'\n"
|
||||
msgstr ""
|
||||
@ -547,19 +563,6 @@ msgstr "Uruchamia jako menedżer składania Wayland"
|
||||
msgid "Run as a full display server, rather than nested"
|
||||
msgstr "Uruchamia pełny serwer wyświetlania zamiast osadzonego"
|
||||
|
||||
#: ../src/core/main.c:459
|
||||
#, c-format
|
||||
msgid "Failed to scan themes directory: %s\n"
|
||||
msgstr "Przejrzenie katalogu z motywami się nie powiodło: %s\n"
|
||||
|
||||
#: ../src/core/main.c:475
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Could not find a theme! Be sure %s exists and contains the usual themes.\n"
|
||||
msgstr ""
|
||||
"Nie można odnaleźć żadnego motywu. Proszę sprawdzić, czy katalog %s istnieje "
|
||||
"i zawiera standardowe motywy.\n"
|
||||
|
||||
#: ../src/core/mutter.c:39
|
||||
#, c-format
|
||||
msgid ""
|
||||
@ -584,749 +587,39 @@ msgstr "Wyświetla wersję"
|
||||
msgid "Mutter plugin to use"
|
||||
msgstr "Używana wtyczka programu Mutter"
|
||||
|
||||
#: ../src/core/prefs.c:2101
|
||||
#: ../src/core/prefs.c:2004
|
||||
#, c-format
|
||||
msgid "Workspace %d"
|
||||
msgstr "Obszar roboczy %d"
|
||||
|
||||
#: ../src/core/screen.c:548
|
||||
#: ../src/core/screen.c:525
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Display \"%s\" already has a window manager; try using the --replace option "
|
||||
"to replace the current window manager."
|
||||
msgstr ""
|
||||
"Na ekranie \"%s\" działa już menedżer okien. Aby zastąpić działającego "
|
||||
"menedżera okien, proszę spróbować użyć opcji --replace."
|
||||
|
||||
#: ../src/core/screen.c:607
|
||||
#, c-format
|
||||
msgid "Screen %d on display '%s' is invalid\n"
|
||||
msgstr "Podekran %d ekranu \"%s\" jest nieprawidłowy\n"
|
||||
|
||||
#: ../src/core/screen.c:564
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Screen %d on display \"%s\" already has a window manager; try using the --"
|
||||
"replace option to replace the current window manager.\n"
|
||||
msgstr ""
|
||||
"Na podekranie %d ekranu \"%s\" działa już menedżer okien. Aby zastąpić "
|
||||
"działającego menedżera okien, proszę spróbować użyć opcji --replace.\n"
|
||||
|
||||
#: ../src/core/screen.c:657
|
||||
#, c-format
|
||||
msgid "Screen %d on display \"%s\" already has a window manager\n"
|
||||
msgstr "Na podekranie %d ekranu \"%s\" działa już menedżer okien\n"
|
||||
|
||||
#: ../src/core/util.c:118
|
||||
msgid "Mutter was compiled without support for verbose mode\n"
|
||||
msgstr ""
|
||||
"Program Mutter został skompilowany bez obsługi trybu z obszerną informacją\n"
|
||||
|
||||
#. Translators: This represents the size of a window. The first number is
|
||||
#. * the width of the window and the second is the height.
|
||||
#.
|
||||
#: ../src/ui/resizepopup.c:134
|
||||
#, c-format
|
||||
msgid "%d x %d"
|
||||
msgstr "%d x %d"
|
||||
|
||||
#: ../src/ui/theme.c:233
|
||||
msgid "top"
|
||||
msgstr "góra"
|
||||
|
||||
#: ../src/ui/theme.c:235
|
||||
msgid "bottom"
|
||||
msgstr "dół"
|
||||
|
||||
#: ../src/ui/theme.c:237
|
||||
msgid "left"
|
||||
msgstr "lewa"
|
||||
|
||||
#: ../src/ui/theme.c:239
|
||||
msgid "right"
|
||||
msgstr "prawa"
|
||||
|
||||
#: ../src/ui/theme.c:267
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify \"%s\" dimension"
|
||||
msgstr "Rozmiar ramki nie określa wymiaru \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:286
|
||||
#, c-format
|
||||
msgid "frame geometry does not specify dimension \"%s\" for border \"%s\""
|
||||
msgstr "Rozmiar ramki nie określa wymiaru \"%s\" dla krawędzi \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:323
|
||||
#, c-format
|
||||
msgid "Button aspect ratio %g is not reasonable"
|
||||
msgstr ""
|
||||
"Współczynnik proporcji przycisku %g nie mieści się w rozsądnych granicach"
|
||||
|
||||
#: ../src/ui/theme.c:335
|
||||
#, c-format
|
||||
msgid "Frame geometry does not specify size of buttons"
|
||||
msgstr "Rozmiar ramki nie określa liczby przycisków"
|
||||
|
||||
#: ../src/ui/theme.c:1061
|
||||
#, c-format
|
||||
msgid "Gradients should have at least two colors"
|
||||
msgstr "Gradienty powinny się składać co najmniej z dwóch kolorów"
|
||||
|
||||
#: ../src/ui/theme.c:1211
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK custom color specification must have color name and fallback in "
|
||||
"parentheses, e.g. gtk:custom(foo,bar); could not parse \"%s\""
|
||||
msgstr ""
|
||||
"Własna specyfikacja koloru biblioteki GTK+ musi posiadać nazwę koloru i "
|
||||
"kolor zastępczy w nawiasach, np. gtk:custom(foo,bar); nie można przetworzyć "
|
||||
"\"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1227
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid character '%c' in color_name parameter of gtk:custom, only A-Za-z0-9-"
|
||||
"_ are valid"
|
||||
msgstr ""
|
||||
"Nieprawidłowy znak \"%c\" w parametrze nazwa_koloru opcji gtk:custom, tylko "
|
||||
"znaki A-Za-z0-9-_ są prawidłowe"
|
||||
|
||||
#: ../src/ui/theme.c:1241
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Gtk:custom format is \"gtk:custom(color_name,fallback)\", \"%s\" does not "
|
||||
"fit the format"
|
||||
msgstr ""
|
||||
"Formatem Gtk:custom jest \"gtk:custom(nazwa_koloru,kolor_zastępczy)\", \"%s"
|
||||
"\" nie pasuje do formatu"
|
||||
|
||||
#: ../src/ui/theme.c:1286
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have the state in brackets, e.g. gtk:fg[NORMAL] "
|
||||
"where NORMAL is the state; could not parse \"%s\""
|
||||
msgstr ""
|
||||
"Specyfikacja koloru biblioteki GTK+ musi zawierać stan w nawiasach "
|
||||
"kwadratowych, np. gtk:fg[NORMAL], gdzie NORMAL jest nazwą stanu; nie można "
|
||||
"przetworzyć \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1300
|
||||
#, c-format
|
||||
msgid ""
|
||||
"GTK color specification must have a close bracket after the state, e.g. gtk:"
|
||||
"fg[NORMAL] where NORMAL is the state; could not parse \"%s\""
|
||||
msgstr ""
|
||||
"Specyfikacja koloru biblioteki GTK+ musi po nazwie stanu zawierać zamykający "
|
||||
"nawias kwadratowy, np. gtk:fg[NORMAL], gdzie NORMAL jest nazwą stanu; nie "
|
||||
"można przetworzyć \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1311
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" in color specification"
|
||||
msgstr "Niezrozumiały stan \"%s\" w specyfikacji koloru"
|
||||
|
||||
#: ../src/ui/theme.c:1324
|
||||
#, c-format
|
||||
msgid "Did not understand color component \"%s\" in color specification"
|
||||
msgstr "Niezrozumiała definicja koloru \"%s\" w specyfikacji koloru"
|
||||
|
||||
#: ../src/ui/theme.c:1352
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Blend format is \"blend/bg_color/fg_color/alpha\", \"%s\" does not fit the "
|
||||
"format"
|
||||
msgstr ""
|
||||
"Formatem przenikania jest \"blend/bg_color/fg_color/alpha\", \"%s\" nie "
|
||||
"pasuje do formatu"
|
||||
|
||||
#: ../src/ui/theme.c:1363
|
||||
#, c-format
|
||||
msgid "Could not parse alpha value \"%s\" in blended color"
|
||||
msgstr "Nie można przetworzyć wartości alfa \"%s\" w przenikającym kolorze"
|
||||
|
||||
#: ../src/ui/theme.c:1373
|
||||
#, c-format
|
||||
msgid "Alpha value \"%s\" in blended color is not between 0.0 and 1.0"
|
||||
msgstr ""
|
||||
"Wartość alfa \"%s\" w przenikającym kolorze nie zawiera się pomiędzy 0,0 i "
|
||||
"1,0"
|
||||
|
||||
#: ../src/ui/theme.c:1419
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Shade format is \"shade/base_color/factor\", \"%s\" does not fit the format"
|
||||
msgstr ""
|
||||
"Formatem przenikania jest \"shade/base_color/factor\", \"%s\" nie pasuje do "
|
||||
"formatu"
|
||||
|
||||
#: ../src/ui/theme.c:1430
|
||||
#, c-format
|
||||
msgid "Could not parse shade factor \"%s\" in shaded color"
|
||||
msgstr ""
|
||||
"Nie można przetworzyć współczynnika przenikania \"%s\" w przenikającym "
|
||||
"kolorze"
|
||||
|
||||
#: ../src/ui/theme.c:1440
|
||||
#, c-format
|
||||
msgid "Shade factor \"%s\" in shaded color is negative"
|
||||
msgstr "Współczynnik przenikania \"%s\" w przenikającym kolorze jest ujemny"
|
||||
|
||||
#: ../src/ui/theme.c:1469
|
||||
#, c-format
|
||||
msgid "Could not parse color \"%s\""
|
||||
msgstr "Nie można przetworzyć koloru \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1778
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains character '%s' which is not allowed"
|
||||
msgstr "Wyrażenie określające współrzędne zawiera niedozwolony znak \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1805
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contains floating point number '%s' which could not be "
|
||||
"parsed"
|
||||
msgstr ""
|
||||
"Wyrażenie określające współrzędne zawiera liczbę zmiennoprzecinkową \"%s\", "
|
||||
"której nie można przetworzyć"
|
||||
|
||||
#: ../src/ui/theme.c:1819
|
||||
#, c-format
|
||||
msgid "Coordinate expression contains integer '%s' which could not be parsed"
|
||||
msgstr ""
|
||||
"Wyrażenie określające współrzędne zawiera liczbę całkowitą \"%s\", której "
|
||||
"nie można przetworzyć"
|
||||
|
||||
#: ../src/ui/theme.c:1940
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression contained unknown operator at the start of this text: "
|
||||
"\"%s\""
|
||||
msgstr ""
|
||||
"Wyrażenie określające współrzędne zawiera nieznany operator na początku "
|
||||
"tekstu: \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:1997
|
||||
#, c-format
|
||||
msgid "Coordinate expression was empty or not understood"
|
||||
msgstr ""
|
||||
"Wyrażenie określające współrzędne jest puste lub nie można go rozpoznać"
|
||||
|
||||
#: ../src/ui/theme.c:2110 ../src/ui/theme.c:2120 ../src/ui/theme.c:2154
|
||||
#, c-format
|
||||
msgid "Coordinate expression results in division by zero"
|
||||
msgstr "Wyrażenie opisujące położenie zawiera dzielenie przez zero"
|
||||
|
||||
#: ../src/ui/theme.c:2162
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression tries to use mod operator on a floating-point number"
|
||||
msgstr ""
|
||||
"Wyrażenie opisujące położenie używa operatora dzielenia modulo z liczbą "
|
||||
"zmiennoprzecinkową"
|
||||
|
||||
#: ../src/ui/theme.c:2218
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has an operator \"%s\" where an operand was expected"
|
||||
msgstr ""
|
||||
"Wyrażenie opisujące położenie zawiera operator \"%s\" w miejscu, w którym "
|
||||
"oczekiwano operandu"
|
||||
|
||||
#: ../src/ui/theme.c:2227
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an operand where an operator was expected"
|
||||
msgstr ""
|
||||
"Wyrażenie opisujące położenie zawiera operand w miejscu, w którym oczekiwano "
|
||||
"operatora"
|
||||
|
||||
#: ../src/ui/theme.c:2235
|
||||
#, c-format
|
||||
msgid "Coordinate expression ended with an operator instead of an operand"
|
||||
msgstr "Wyrażenie opisujące położenie kończy się operatorem zamiast operandem"
|
||||
|
||||
#: ../src/ui/theme.c:2245
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Coordinate expression has operator \"%c\" following operator \"%c\" with no "
|
||||
"operand in between"
|
||||
msgstr ""
|
||||
"Wyrażenie opisujące położenie zawiera operator \"%c\" bezpośrednio po "
|
||||
"operatorze \"%c\" bez rozdzielającego ich operandu"
|
||||
|
||||
#: ../src/ui/theme.c:2396 ../src/ui/theme.c:2441
|
||||
#, c-format
|
||||
msgid "Coordinate expression had unknown variable or constant \"%s\""
|
||||
msgstr ""
|
||||
"Wyrażenie opisujące położenie zawiera nieznaną zmienną lub stałą \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:2495
|
||||
#, c-format
|
||||
msgid "Coordinate expression parser overflowed its buffer."
|
||||
msgstr "Parser wyrażeń określających współrzędne przepełnił swój bufor."
|
||||
|
||||
#: ../src/ui/theme.c:2524
|
||||
#, c-format
|
||||
msgid "Coordinate expression had a close parenthesis with no open parenthesis"
|
||||
msgstr ""
|
||||
"Wyrażenie opisujące położenie zawiera nawias zamykający bez odpowiadającego "
|
||||
"mu nawiasu otwierającego"
|
||||
|
||||
#: ../src/ui/theme.c:2588
|
||||
#, c-format
|
||||
msgid "Coordinate expression had an open parenthesis with no close parenthesis"
|
||||
msgstr ""
|
||||
"Wyrażenie opisujące położenie zawiera nawias otwierający bez odpowiadającego "
|
||||
"mu nawiasu zamykającego"
|
||||
|
||||
#: ../src/ui/theme.c:2599
|
||||
#, c-format
|
||||
msgid "Coordinate expression doesn't seem to have any operators or operands"
|
||||
msgstr ""
|
||||
"Wyrażenie opisujące położenie nie zawiera żadnych operatorów ani operandów"
|
||||
|
||||
#: ../src/ui/theme.c:2812 ../src/ui/theme.c:2832 ../src/ui/theme.c:2852
|
||||
#, c-format
|
||||
msgid "Theme contained an expression that resulted in an error: %s\n"
|
||||
msgstr "Motyw zawiera wyrażenie, przy którego obliczaniu wystąpił błąd: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:4455
|
||||
#, c-format
|
||||
msgid ""
|
||||
"<button function=\"%s\" state=\"%s\" draw_ops=\"whatever\"/> must be "
|
||||
"specified for this frame style"
|
||||
msgstr ""
|
||||
"Przy tym stylu ramki należy podać <button function=\"%s\" state=\"%s\" "
|
||||
"draw_ops=\"cokolwiek\"/>"
|
||||
|
||||
#: ../src/ui/theme.c:4970 ../src/ui/theme.c:4995
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Missing <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"whatever\"/>"
|
||||
msgstr ""
|
||||
"Brak <frame state=\"%s\" resize=\"%s\" focus=\"%s\" style=\"cokolwiek\"/>"
|
||||
|
||||
#: ../src/ui/theme.c:5041
|
||||
#, c-format
|
||||
msgid "Failed to load theme \"%s\": %s\n"
|
||||
msgstr "Wczytanie motywu \"%s\" się nie powiodło: %s\n"
|
||||
|
||||
#: ../src/ui/theme.c:5177 ../src/ui/theme.c:5184 ../src/ui/theme.c:5191
|
||||
#: ../src/ui/theme.c:5198 ../src/ui/theme.c:5205
|
||||
#, c-format
|
||||
msgid "No <%s> set for theme \"%s\""
|
||||
msgstr "Nie określono elementu <%s> dla motywu \"%s\""
|
||||
|
||||
#: ../src/ui/theme.c:5213
|
||||
#, c-format
|
||||
msgid ""
|
||||
"No frame style set for window type \"%s\" in theme \"%s\", add a <window "
|
||||
"type=\"%s\" style_set=\"whatever\"/> element"
|
||||
msgstr ""
|
||||
"Przy typie okna \"%s\" w motywie \"%s\" nie ustawiono stylu ramki. Należy "
|
||||
"dodać element <window type=\"%s\" style_set=\"cokolwiek\"/>"
|
||||
|
||||
#: ../src/ui/theme.c:5620 ../src/ui/theme.c:5682 ../src/ui/theme.c:5745
|
||||
#, c-format
|
||||
msgid ""
|
||||
"User-defined constants must begin with a capital letter; \"%s\" does not"
|
||||
msgstr ""
|
||||
"Stałe definiowane przez użytkownika powinny rozpoczynać się wielką literą, "
|
||||
"natomiast \"%s\" nie spełnia tego warunku"
|
||||
|
||||
#: ../src/ui/theme.c:5628 ../src/ui/theme.c:5690 ../src/ui/theme.c:5753
|
||||
#, c-format
|
||||
msgid "Constant \"%s\" has already been defined"
|
||||
msgstr "Stała \"%s\" została już określona"
|
||||
|
||||
#. Translators: This means that an attribute which should have been found
|
||||
#. * on an XML element was not in fact found.
|
||||
#.
|
||||
#: ../src/ui/theme-parser.c:234
|
||||
#, c-format
|
||||
msgid "No \"%s\" attribute on element <%s>"
|
||||
msgstr "Brak atrybutu \"%s\" w elemencie <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:263 ../src/ui/theme-parser.c:281
|
||||
#, c-format
|
||||
msgid "Line %d character %d: %s"
|
||||
msgstr "Wiersz %d, znak %d: %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:481
|
||||
#, c-format
|
||||
msgid "Attribute \"%s\" repeated twice on the same <%s> element"
|
||||
msgstr "Atrybut \"%s\" wystąpił dwukrotnie wewnątrz jednego elementu <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:505 ../src/ui/theme-parser.c:554
|
||||
#, c-format
|
||||
msgid "Attribute \"%s\" is invalid on <%s> element in this context"
|
||||
msgstr ""
|
||||
"Atrybut \"%s\" jest nieprawidłowy wewnątrz elementu <%s> w tym kontekście"
|
||||
|
||||
#: ../src/ui/theme-parser.c:596
|
||||
#, c-format
|
||||
msgid "Could not parse \"%s\" as an integer"
|
||||
msgstr "Nie można przetworzyć \"%s\" jako liczby całkowitej"
|
||||
|
||||
#: ../src/ui/theme-parser.c:605 ../src/ui/theme-parser.c:660
|
||||
#, c-format
|
||||
msgid "Did not understand trailing characters \"%s\" in string \"%s\""
|
||||
msgstr "Nie można rozpoznać końcowych znaków \"%s\" w napisie \"%s\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:615
|
||||
#, c-format
|
||||
msgid "Integer %ld must be positive"
|
||||
msgstr "Liczba całkowita %ld musi być dodatnia"
|
||||
|
||||
#: ../src/ui/theme-parser.c:623
|
||||
#, c-format
|
||||
msgid "Integer %ld is too large, current max is %d"
|
||||
msgstr "Liczba całkowita %ld jest za duża, obecne maksimum to %d"
|
||||
|
||||
#: ../src/ui/theme-parser.c:651 ../src/ui/theme-parser.c:767
|
||||
#, c-format
|
||||
msgid "Could not parse \"%s\" as a floating point number"
|
||||
msgstr "Napis \"%s\" nie jest zapisem liczby zmiennoprzecinkowej"
|
||||
|
||||
#: ../src/ui/theme-parser.c:682 ../src/ui/theme-parser.c:710
|
||||
#, c-format
|
||||
msgid "Boolean values must be \"true\" or \"false\" not \"%s\""
|
||||
msgstr "Wartościami logicznymi są \"true\" i \"false\", a nie \"%s\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:737
|
||||
#, c-format
|
||||
msgid "Angle must be between 0.0 and 360.0, was %g\n"
|
||||
msgstr "Wartość kąta musi się mieścić pomiędzy 0,0 i 360,0, odczytano %g\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:800
|
||||
#, c-format
|
||||
msgid "Alpha must be between 0.0 (invisible) and 1.0 (fully opaque), was %g\n"
|
||||
msgstr ""
|
||||
"Wartość alfa musi się mieścić pomiędzy 0,0 (niewidoczne) i 1,0 (w pełni "
|
||||
"nieprzezroczyste), odczytano %g\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:865
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Invalid title scale \"%s\" (must be one of xx-small,x-small,small,medium,"
|
||||
"large,x-large,xx-large)\n"
|
||||
msgstr ""
|
||||
"Nieprawidłowy rozmiar tytułu \"%s\" (musi on być jedną z wartości: xx-small, "
|
||||
"x-small, small, medium, large, x-large, xx-large)\n"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1021 ../src/ui/theme-parser.c:1084
|
||||
#: ../src/ui/theme-parser.c:1118 ../src/ui/theme-parser.c:1221
|
||||
#, c-format
|
||||
msgid "<%s> name \"%s\" used a second time"
|
||||
msgstr "<%s>: użyto nazwy \"%s\" po raz drugi"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1033 ../src/ui/theme-parser.c:1130
|
||||
#: ../src/ui/theme-parser.c:1233
|
||||
#, c-format
|
||||
msgid "<%s> parent \"%s\" has not been defined"
|
||||
msgstr "<%s>: nie określono elementu nadrzędnego o nazwie \"%s\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:1143
|
||||
#, c-format
|
||||
msgid "<%s> geometry \"%s\" has not been defined"
|
||||
msgstr "<%s>: nie określono geometrii o nazwie \"%s\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:1156
|
||||
#, c-format
|
||||
msgid "<%s> must specify either a geometry or a parent that has a geometry"
|
||||
msgstr "<%s> musi albo określać geometrię, albo element nadrzędny z geometrią"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1198
|
||||
msgid "You must specify a background for an alpha value to be meaningful"
|
||||
msgstr "Aby wartość alfa miała sens, należy określić tło"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1266
|
||||
#, c-format
|
||||
msgid "Unknown type \"%s\" on <%s> element"
|
||||
msgstr "Nieznany typ \"%s\" wewnątrz elementu <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1277
|
||||
#, c-format
|
||||
msgid "Unknown style_set \"%s\" on <%s> element"
|
||||
msgstr "Nieznana wartość atrybutu \"style_set\" (%s) wewnątrz elementu <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1285
|
||||
#, c-format
|
||||
msgid "Window type \"%s\" has already been assigned a style set"
|
||||
msgstr "Z typem okna \"%s\" powiązano już zbiór stylów"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1315 ../src/ui/theme-parser.c:1379
|
||||
#: ../src/ui/theme-parser.c:1605 ../src/ui/theme-parser.c:2840
|
||||
#: ../src/ui/theme-parser.c:2886 ../src/ui/theme-parser.c:3036
|
||||
#: ../src/ui/theme-parser.c:3272 ../src/ui/theme-parser.c:3310
|
||||
#: ../src/ui/theme-parser.c:3348 ../src/ui/theme-parser.c:3386
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed below <%s>"
|
||||
msgstr "Element <%s> nie jest dopuszczalny poniżej <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1429 ../src/ui/theme-parser.c:1443
|
||||
#: ../src/ui/theme-parser.c:1488
|
||||
msgid ""
|
||||
"Cannot specify both \"button_width\"/\"button_height\" and \"aspect_ratio\" "
|
||||
"for buttons"
|
||||
msgstr ""
|
||||
"Nie można jednocześnie określać dla przycisku jego szerokości i wysokości "
|
||||
"oraz współczynnika proporcji"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1452
|
||||
#, c-format
|
||||
msgid "Distance \"%s\" is unknown"
|
||||
msgstr "Odległość \"%s\" jest nieznana"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1497
|
||||
#, c-format
|
||||
msgid "Aspect ratio \"%s\" is unknown"
|
||||
msgstr "Współczynnik proporcji \"%s\" jest nieznany"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1559
|
||||
#, c-format
|
||||
msgid "Border \"%s\" is unknown"
|
||||
msgstr "Krawędź \"%s\" jest nieznana"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1870
|
||||
#, c-format
|
||||
msgid "No \"start_angle\" or \"from\" attribute on element <%s>"
|
||||
msgstr "Brak atrybutu \"start_angle\" wewnątrz elementu <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:1877
|
||||
#, c-format
|
||||
msgid "No \"extent_angle\" or \"to\" attribute on element <%s>"
|
||||
msgstr "Brak atrybutu \"extent_angle\" wewnątrz elementu <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2117
|
||||
#, c-format
|
||||
msgid "Did not understand value \"%s\" for type of gradient"
|
||||
msgstr "Niezrozumiała wartość \"%s\" typu gradientu"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2195 ../src/ui/theme-parser.c:2570
|
||||
#, c-format
|
||||
msgid "Did not understand fill type \"%s\" for <%s> element"
|
||||
msgstr "Niezrozumiały typ wypełnienia \"%s\" elementu <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2362 ../src/ui/theme-parser.c:2445
|
||||
#: ../src/ui/theme-parser.c:2508
|
||||
#, c-format
|
||||
msgid "Did not understand state \"%s\" for <%s> element"
|
||||
msgstr "Niezrozumiały stan \"%s\" (atrybut \"state\") elementu <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2372 ../src/ui/theme-parser.c:2455
|
||||
#, c-format
|
||||
msgid "Did not understand shadow \"%s\" for <%s> element"
|
||||
msgstr "Niezrozumiały cień \"%s\" (atrybut \"shadow\") elementu <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2382
|
||||
#, c-format
|
||||
msgid "Did not understand arrow \"%s\" for <%s> element"
|
||||
msgstr "Niezrozumiała strzałka \"%s\" (atrybut \"arrow\") elementu <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2696 ../src/ui/theme-parser.c:2792
|
||||
#, c-format
|
||||
msgid "No <draw_ops> called \"%s\" has been defined"
|
||||
msgstr "Nie określono elementu <draw_ops> o nazwie \"%s\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:2708 ../src/ui/theme-parser.c:2804
|
||||
#, c-format
|
||||
msgid "Including draw_ops \"%s\" here would create a circular reference"
|
||||
msgstr ""
|
||||
"Włączenie tutaj elementu \"draw_ops\" o nazwie \"%s\" spowodowałoby "
|
||||
"zapętlone odwołanie"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2919
|
||||
#, c-format
|
||||
msgid "Unknown position \"%s\" for frame piece"
|
||||
msgstr "Nieznane położenie \"%s\" elementu ramki"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2927
|
||||
#, c-format
|
||||
msgid "Frame style already has a piece at position %s"
|
||||
msgstr "Styl ramki zawiera już element o położeniu %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2944 ../src/ui/theme-parser.c:3021
|
||||
#, c-format
|
||||
msgid "No <draw_ops> with the name \"%s\" has been defined"
|
||||
msgstr "Nie określono elementu <draw_ops> o nazwie \"%s\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:2974
|
||||
#, c-format
|
||||
msgid "Unknown function \"%s\" for button"
|
||||
msgstr "Nieznana funkcja \"%s\" powiązana z przyciskiem"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2984
|
||||
#, c-format
|
||||
msgid "Button function \"%s\" does not exist in this version (%d, need %d)"
|
||||
msgstr "Funkcja \"%s\" przycisku nie istnieje w tej wersji (%d, wymaga %d)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:2996
|
||||
#, c-format
|
||||
msgid "Unknown state \"%s\" for button"
|
||||
msgstr "Nieznany stan \"%s\" powiązany z przyciskiem"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3004
|
||||
#, c-format
|
||||
msgid "Frame style already has a button for function %s state %s"
|
||||
msgstr ""
|
||||
"Dla stylu ramki określono już przycisk, związany z funkcją %s i stanem %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3075
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for focus attribute"
|
||||
msgstr "\"%s\" nie jest prawidłową wartością atrybutu \"focus\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:3084
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for state attribute"
|
||||
msgstr "\"%s\" nie jest prawidłową wartością atrybutu \"state\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:3094
|
||||
#, c-format
|
||||
msgid "A style called \"%s\" has not been defined"
|
||||
msgstr "Nie określono stylu o nazwie \"%s\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:3115 ../src/ui/theme-parser.c:3138
|
||||
#, c-format
|
||||
msgid "\"%s\" is not a valid value for resize attribute"
|
||||
msgstr "\"%s\" nie jest prawidłową wartością atrybutu \"resize\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:3149
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized/shaded "
|
||||
"states"
|
||||
msgstr ""
|
||||
"Element <%s> nie powinien zawierać atrybutu \"resize\" przy stanie "
|
||||
"zmaksymalizowanym lub zwiniętym"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3163
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Should not have \"resize\" attribute on <%s> element for maximized states"
|
||||
msgstr ""
|
||||
"Element <%s> nie powinien zawierać atrybutu \"resize\" przy stanie "
|
||||
"zmaksymalizowanym"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3177 ../src/ui/theme-parser.c:3221
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s resize %s focus %s"
|
||||
msgstr "Określono już styl dla stanu %s, rozmiaru %s i uaktywnienia %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3188 ../src/ui/theme-parser.c:3199
|
||||
#: ../src/ui/theme-parser.c:3210 ../src/ui/theme-parser.c:3232
|
||||
#: ../src/ui/theme-parser.c:3243 ../src/ui/theme-parser.c:3254
|
||||
#, c-format
|
||||
msgid "Style has already been specified for state %s focus %s"
|
||||
msgstr "Określono już styl dla stanu %s i uaktywnienia %s"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3293
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <piece> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
msgstr ""
|
||||
"Element <piece> nie może zawierać dwóch \"draw_ops\" (motyw zawiera atrybut "
|
||||
"\"draw_ops\" i element <draw_ops> lub dwa elementy)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3331
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <button> element (theme specified a draw_ops "
|
||||
"attribute and also a <draw_ops> element, or specified two elements)"
|
||||
msgstr ""
|
||||
"Element <button> nie może zawierać dwóch \"draw_ops\" (motyw zawiera atrybut "
|
||||
"\"draw_ops\" i element <draw_ops> lub dwa elementy)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3369
|
||||
msgid ""
|
||||
"Can't have a two draw_ops for a <menu_icon> element (theme specified a "
|
||||
"draw_ops attribute and also a <draw_ops> element, or specified two elements)"
|
||||
msgstr ""
|
||||
"Element <menu_icon> nie może zawierać dwóch \"draw_ops\" (motyw zawiera "
|
||||
"atrybut \"draw_ops\" i element <draw_ops> lub dwa elementy)"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3433
|
||||
#, c-format
|
||||
msgid "Bad version specification '%s'"
|
||||
msgstr "Błędne określenie wersji \"%s\""
|
||||
|
||||
#: ../src/ui/theme-parser.c:3506
|
||||
msgid ""
|
||||
"\"version\" attribute cannot be used in metacity-theme-1.xml or metacity-"
|
||||
"theme-2.xml"
|
||||
msgstr ""
|
||||
"Atrybut \"version\" nie może być używany w plikach metacity-theme-1.xml lub "
|
||||
"metacity-theme-2.xml"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3529
|
||||
#, c-format
|
||||
msgid "Theme requires version %s but latest supported theme version is %d.%d"
|
||||
msgstr ""
|
||||
"Motyw wymaga wersji %s, ale najnowsza obsługiwana wersja motywów to %d.%d"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3561
|
||||
#, c-format
|
||||
msgid "Outermost element in theme must be <metacity_theme> not <%s>"
|
||||
msgstr "Głównym elementem motywu musi być <metacity_theme>, nie <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3581
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Element <%s> is not allowed inside a name/author/date/description element"
|
||||
msgstr ""
|
||||
"Element <%s> nie jest dopuszczalny wewnątrz elementu name/author/date/"
|
||||
"description"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3586
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <constant> element"
|
||||
msgstr "Element <%s> nie jest dopuszczalny wewnątrz elementu <constant>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3598
|
||||
#, c-format
|
||||
msgid ""
|
||||
"Element <%s> is not allowed inside a distance/border/aspect_ratio element"
|
||||
msgstr ""
|
||||
"Element <%s> nie jest dopuszczalny wewnątrz elementu distance/border/"
|
||||
"aspect_ratio"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3620
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a draw operation element"
|
||||
msgstr ""
|
||||
"Element <%s> nie jest dopuszczalny wewnątrz elementu działania rysowania"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3630 ../src/ui/theme-parser.c:3660
|
||||
#: ../src/ui/theme-parser.c:3665 ../src/ui/theme-parser.c:3670
|
||||
#, c-format
|
||||
msgid "Element <%s> is not allowed inside a <%s> element"
|
||||
msgstr "Element <%s> nie jest dopuszczalny wewnątrz elementu <%s>"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3898
|
||||
msgid "No draw_ops provided for frame piece"
|
||||
msgstr "Brak elementu \"draw_ops\" powiązanego z elementem ramki"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3913
|
||||
msgid "No draw_ops provided for button"
|
||||
msgstr "Brak elementu \"draw_ops\" powiązanego z przyciskiem"
|
||||
|
||||
#: ../src/ui/theme-parser.c:3967
|
||||
#, c-format
|
||||
msgid "No text is allowed inside element <%s>"
|
||||
msgstr "Wewnątrz elementu <%s> nie jest dopuszczalny tekst"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4025 ../src/ui/theme-parser.c:4037
|
||||
#: ../src/ui/theme-parser.c:4049 ../src/ui/theme-parser.c:4061
|
||||
#: ../src/ui/theme-parser.c:4073
|
||||
#, c-format
|
||||
msgid "<%s> specified twice for this theme"
|
||||
msgstr "<%s> określono dwukrotnie dla tego motywu"
|
||||
|
||||
#: ../src/ui/theme-parser.c:4335
|
||||
#, c-format
|
||||
msgid "Failed to find a valid file for theme %s\n"
|
||||
msgstr "Odnalezienie prawidłowego pliku dla motywu %s się nie powiodło\n"
|
||||
|
||||
#: ../src/x11/session.c:1815
|
||||
msgid ""
|
||||
"These windows do not support "save current setup" and will have to "
|
||||
"be restarted manually next time you log in."
|
||||
msgstr ""
|
||||
"Te okna nie obsługują opcji zapisu aktualnego stanu (\"save current setup"
|
||||
"\"), więc przy następnym zalogowaniu będą musiały zostać uruchomione ręcznie."
|
||||
"Te okna nie obsługują opcji zapisu obecnego stanu (\"save current setup\"), "
|
||||
"więc przy następnym zalogowaniu będą musiały zostać uruchomione ręcznie."
|
||||
|
||||
#: ../src/x11/window-props.c:515
|
||||
#: ../src/x11/window-props.c:549
|
||||
#, c-format
|
||||
msgid "%s (on %s)"
|
||||
msgstr "%s (na %s)"
|
||||
|
1284
po/pt_BR.po
1284
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
2394
po/sr@latin.po
2394
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
1306
po/zh_CN.po
1306
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
1184
po/zh_TW.po
1184
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@ -7,6 +7,7 @@ stackingdir = $(pkgdatadir)/tests/stacking
|
||||
dist_stacking_DATA = \
|
||||
tests/stacking/basic-x11.metatest \
|
||||
tests/stacking/basic-wayland.metatest \
|
||||
tests/stacking/minimized.metatest \
|
||||
tests/stacking/mixed-windows.metatest \
|
||||
tests/stacking/override-redirect.metatest
|
||||
|
||||
@ -40,11 +41,9 @@ endif
|
||||
# Some random test programs for bits of the code
|
||||
|
||||
testboxes_SOURCES = core/testboxes.c
|
||||
testgradient_SOURCES = ui/testgradient.c
|
||||
testasyncgetprop_SOURCES = x11/testasyncgetprop.c
|
||||
|
||||
noinst_PROGRAMS+=testboxes testgradient testasyncgetprop
|
||||
noinst_PROGRAMS+=testboxes testasyncgetprop
|
||||
|
||||
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
|
@ -6,6 +6,7 @@ lib_LTLIBRARIES = libmutter.la
|
||||
SUBDIRS=compositor/plugins
|
||||
|
||||
EXTRA_DIST =
|
||||
NULL =
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DCLUTTER_ENABLE_COMPOSITOR_API \
|
||||
@ -31,31 +32,37 @@ AM_CPPFLAGS = \
|
||||
-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" \
|
||||
-DMUTTER_PLUGIN_DIR=\"$(MUTTER_PLUGIN_DIR)\" \
|
||||
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
|
||||
-DXWAYLAND_PATH=\"$(XWAYLAND_PATH)\"
|
||||
-DXWAYLAND_PATH=\"$(XWAYLAND_PATH)\" \
|
||||
$(NULL)
|
||||
|
||||
mutter_built_sources = \
|
||||
$(dbus_idle_built_sources) \
|
||||
$(dbus_display_config_built_sources) \
|
||||
$(dbus_login1_built_sources) \
|
||||
mutter-enum-types.h \
|
||||
mutter-enum-types.c
|
||||
mutter-enum-types.c \
|
||||
$(NULL)
|
||||
|
||||
if HAVE_WAYLAND
|
||||
mutter_built_sources += \
|
||||
gtk-shell-protocol.c \
|
||||
gtk-shell-server-protocol.h \
|
||||
xdg-shell-protocol.c \
|
||||
xdg-shell-server-protocol.h
|
||||
xdg-shell-server-protocol.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
wayland_protocols = \
|
||||
wayland_protocols = \
|
||||
wayland/protocol/gtk-shell.xml \
|
||||
wayland/protocol/xdg-shell.xml
|
||||
wayland/protocol/xdg-shell.xml \
|
||||
$(NULL)
|
||||
|
||||
libmutter_la_SOURCES = \
|
||||
backends/meta-backend.c \
|
||||
meta/meta-backend.h \
|
||||
backends/meta-backend-private.h \
|
||||
backends/meta-barrier.c \
|
||||
backends/meta-barrier-private.h \
|
||||
backends/meta-cursor.c \
|
||||
backends/meta-cursor.h \
|
||||
backends/meta-cursor-private.h \
|
||||
@ -68,10 +75,13 @@ libmutter_la_SOURCES = \
|
||||
backends/meta-idle-monitor-private.h \
|
||||
backends/meta-idle-monitor-dbus.c \
|
||||
backends/meta-idle-monitor-dbus.h \
|
||||
backends/meta-input-settings.c \
|
||||
backends/meta-input-settings-private.h \
|
||||
backends/meta-monitor-config.c \
|
||||
backends/meta-monitor-config.h \
|
||||
backends/meta-monitor-manager.c \
|
||||
backends/meta-monitor-manager.h \
|
||||
meta/meta-monitor-manager.h \
|
||||
backends/meta-monitor-manager-private.h \
|
||||
backends/meta-monitor-manager-dummy.c \
|
||||
backends/meta-monitor-manager-dummy.h \
|
||||
backends/meta-stage.h \
|
||||
@ -80,15 +90,18 @@ libmutter_la_SOURCES = \
|
||||
backends/edid.h \
|
||||
backends/x11/meta-backend-x11.c \
|
||||
backends/x11/meta-backend-x11.h \
|
||||
backends/x11/meta-barrier-x11.c \
|
||||
backends/x11/meta-barrier-x11.h \
|
||||
backends/x11/meta-cursor-renderer-x11.c \
|
||||
backends/x11/meta-cursor-renderer-x11.h \
|
||||
backends/x11/meta-idle-monitor-xsync.c \
|
||||
backends/x11/meta-idle-monitor-xsync.h \
|
||||
backends/x11/meta-input-settings-x11.c \
|
||||
backends/x11/meta-input-settings-x11.h \
|
||||
backends/x11/meta-monitor-manager-xrandr.c \
|
||||
backends/x11/meta-monitor-manager-xrandr.h \
|
||||
core/meta-accel-parse.c \
|
||||
core/meta-accel-parse.h \
|
||||
core/barrier.c \
|
||||
meta/barrier.h \
|
||||
core/bell.c \
|
||||
core/bell.h \
|
||||
@ -109,6 +122,10 @@ libmutter_la_SOURCES = \
|
||||
compositor/meta-background-group.c \
|
||||
compositor/meta-cullable.c \
|
||||
compositor/meta-cullable.h \
|
||||
compositor/meta-dnd-actor.c \
|
||||
compositor/meta-dnd-actor-private.h \
|
||||
compositor/meta-feedback-actor.c \
|
||||
compositor/meta-feedback-actor-private.h \
|
||||
compositor/meta-module.c \
|
||||
compositor/meta-module.h \
|
||||
compositor/meta-plugin.c \
|
||||
@ -158,8 +175,6 @@ libmutter_la_SOURCES = \
|
||||
meta/errors.h \
|
||||
core/frame.c \
|
||||
core/frame.h \
|
||||
ui/gradient.c \
|
||||
meta/gradient.h \
|
||||
core/meta-gesture-tracker.c \
|
||||
core/meta-gesture-tracker-private.h \
|
||||
core/keybindings.c \
|
||||
@ -191,9 +206,6 @@ libmutter_la_SOURCES = \
|
||||
ui/ui.h \
|
||||
ui/frames.c \
|
||||
ui/frames.h \
|
||||
ui/resizepopup.c \
|
||||
ui/resizepopup.h \
|
||||
ui/theme-parser.c \
|
||||
ui/theme.c \
|
||||
meta/theme.h \
|
||||
ui/theme-private.h \
|
||||
@ -218,7 +230,8 @@ libmutter_la_SOURCES = \
|
||||
x11/window-x11-private.h \
|
||||
x11/xprops.c \
|
||||
x11/xprops.h \
|
||||
x11/mutter-Xatomtype.h
|
||||
x11/mutter-Xatomtype.h \
|
||||
$(NULL)
|
||||
|
||||
if HAVE_WAYLAND
|
||||
libmutter_la_SOURCES += \
|
||||
@ -230,12 +243,18 @@ libmutter_la_SOURCES += \
|
||||
wayland/meta-xwayland.c \
|
||||
wayland/meta-xwayland.h \
|
||||
wayland/meta-xwayland-private.h \
|
||||
wayland/meta-wayland-buffer.c \
|
||||
wayland/meta-wayland-buffer.h \
|
||||
wayland/meta-wayland-region.c \
|
||||
wayland/meta-wayland-region.h \
|
||||
wayland/meta-wayland-data-device.c \
|
||||
wayland/meta-wayland-data-device.h \
|
||||
wayland/meta-wayland-keyboard.c \
|
||||
wayland/meta-wayland-keyboard.h \
|
||||
wayland/meta-wayland-pointer.c \
|
||||
wayland/meta-wayland-pointer.h \
|
||||
wayland/meta-wayland-popup.c \
|
||||
wayland/meta-wayland-popup.h \
|
||||
wayland/meta-wayland-seat.c \
|
||||
wayland/meta-wayland-seat.h \
|
||||
wayland/meta-wayland-touch.c \
|
||||
@ -247,29 +266,35 @@ libmutter_la_SOURCES += \
|
||||
wayland/meta-wayland-outputs.c \
|
||||
wayland/meta-wayland-outputs.h \
|
||||
wayland/window-wayland.c \
|
||||
wayland/window-wayland.h
|
||||
wayland/window-wayland.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
if HAVE_NATIVE_BACKEND
|
||||
libmutter_la_SOURCES += \
|
||||
backends/native/meta-backend-native.c \
|
||||
backends/native/meta-backend-native.h \
|
||||
backends/native/meta-backend-native-private.h \
|
||||
backends/native/meta-barrier-native.c \
|
||||
backends/native/meta-barrier-native.h \
|
||||
backends/native/meta-cursor-renderer-native.c \
|
||||
backends/native/meta-cursor-renderer-native.h \
|
||||
backends/native/meta-idle-monitor-native.c \
|
||||
backends/native/meta-idle-monitor-native.h \
|
||||
backends/native/meta-input-settings-native.c \
|
||||
backends/native/meta-input-settings-native.h \
|
||||
backends/native/meta-monitor-manager-kms.c \
|
||||
backends/native/meta-monitor-manager-kms.h \
|
||||
backends/native/meta-launcher.c \
|
||||
backends/native/meta-launcher.h \
|
||||
backends/native/dbus-utils.c \
|
||||
backends/native/dbus-utils.h
|
||||
backends/native/dbus-utils.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
nodist_libmutter_la_SOURCES = \
|
||||
$(mutter_built_sources)
|
||||
nodist_libmutter_la_SOURCES = $(mutter_built_sources)
|
||||
|
||||
libmutter_la_LDFLAGS = -no-undefined
|
||||
libmutter_la_LDFLAGS = -no-undefined -export-symbols-regex "^(meta|ag)_.*"
|
||||
libmutter_la_LIBADD = $(MUTTER_LIBS) $(MUTTER_NATIVE_BACKEND_LIBS)
|
||||
|
||||
# Headers installed for plugins; introspected information will
|
||||
@ -282,7 +307,6 @@ libmutterinclude_headers = \
|
||||
meta/compositor.h \
|
||||
meta/display.h \
|
||||
meta/errors.h \
|
||||
meta/gradient.h \
|
||||
meta/group.h \
|
||||
meta/keybindings.h \
|
||||
meta/main.h \
|
||||
@ -294,6 +318,7 @@ libmutterinclude_headers = \
|
||||
meta/meta-cursor-tracker.h \
|
||||
meta/meta-idle-monitor.h \
|
||||
meta/meta-plugin.h \
|
||||
meta/meta-monitor-manager.h \
|
||||
meta/meta-shaped-texture.h \
|
||||
meta/meta-shadow-factory.h \
|
||||
meta/meta-window-actor.h \
|
||||
@ -303,7 +328,8 @@ libmutterinclude_headers = \
|
||||
meta/types.h \
|
||||
meta/util.h \
|
||||
meta/window.h \
|
||||
meta/workspace.h
|
||||
meta/workspace.h \
|
||||
$(NULL)
|
||||
|
||||
libmutterinclude_built_headers = \
|
||||
meta/meta-version.h
|
||||
@ -384,14 +410,15 @@ DISTCLEANFILES = \
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libmutter.pc
|
||||
|
||||
EXTRA_DIST += \
|
||||
$(wayland_protocols) \
|
||||
libmutter.pc.in \
|
||||
mutter-enum-types.h.in \
|
||||
mutter-enum-types.c.in \
|
||||
org.freedesktop.login1.xml \
|
||||
EXTRA_DIST += \
|
||||
$(wayland_protocols) \
|
||||
libmutter.pc.in \
|
||||
mutter-enum-types.h.in \
|
||||
mutter-enum-types.c.in \
|
||||
org.freedesktop.login1.xml \
|
||||
org.gnome.Mutter.DisplayConfig.xml \
|
||||
org.gnome.Mutter.IdleMonitor.xml
|
||||
org.gnome.Mutter.IdleMonitor.xml \
|
||||
$(NULL)
|
||||
|
||||
BUILT_SOURCES = \
|
||||
$(mutter_built_sources) \
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/meta-idle-monitor.h>
|
||||
#include "meta-cursor-renderer.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#define DEFAULT_XKB_RULES_FILE "evdev"
|
||||
#define DEFAULT_XKB_MODEL "pc105+inet"
|
||||
@ -49,8 +49,8 @@ struct _MetaBackend
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
MetaIdleMonitor *device_monitors[256];
|
||||
int device_id_max;
|
||||
GHashTable *device_monitors;
|
||||
gint current_device_id;
|
||||
};
|
||||
|
||||
struct _MetaBackendClass
|
||||
@ -107,4 +107,7 @@ void meta_backend_warp_pointer (MetaBackend *backend,
|
||||
|
||||
struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
|
||||
|
||||
void meta_backend_update_last_device (MetaBackend *backend,
|
||||
int device_id);
|
||||
|
||||
#endif /* META_BACKEND_PRIVATE_H */
|
||||
|
@ -26,14 +26,20 @@
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include "meta-backend-private.h"
|
||||
#include "meta-input-settings-private.h"
|
||||
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "meta-stage.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
#include "backends/meta-idle-monitor-private.h"
|
||||
|
||||
#include "backends/meta-monitor-manager-dummy.h"
|
||||
|
||||
static MetaBackend *_backend;
|
||||
|
||||
/**
|
||||
@ -53,6 +59,7 @@ struct _MetaBackendPrivate
|
||||
{
|
||||
MetaMonitorManager *monitor_manager;
|
||||
MetaCursorRenderer *cursor_renderer;
|
||||
MetaInputSettings *input_settings;
|
||||
|
||||
ClutterActor *stage;
|
||||
};
|
||||
@ -65,15 +72,11 @@ meta_backend_finalize (GObject *object)
|
||||
{
|
||||
MetaBackend *backend = META_BACKEND (object);
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
int i;
|
||||
|
||||
g_clear_object (&priv->monitor_manager);
|
||||
g_clear_object (&priv->input_settings);
|
||||
|
||||
for (i = 0; i <= backend->device_id_max; i++)
|
||||
{
|
||||
if (backend->device_monitors[i])
|
||||
g_object_unref (backend->device_monitors[i]);
|
||||
}
|
||||
g_hash_table_destroy (backend->device_monitors);
|
||||
|
||||
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
||||
}
|
||||
@ -108,27 +111,19 @@ static void
|
||||
create_device_monitor (MetaBackend *backend,
|
||||
int device_id)
|
||||
{
|
||||
g_assert (backend->device_monitors[device_id] == NULL);
|
||||
MetaIdleMonitor *idle_monitor;
|
||||
|
||||
backend->device_monitors[device_id] = meta_backend_create_idle_monitor (backend, device_id);
|
||||
backend->device_id_max = MAX (backend->device_id_max, device_id);
|
||||
g_assert (g_hash_table_lookup (backend->device_monitors, &device_id) == NULL);
|
||||
|
||||
idle_monitor = meta_backend_create_idle_monitor (backend, device_id);
|
||||
g_hash_table_insert (backend->device_monitors, &idle_monitor->device_id, idle_monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_device_monitor (MetaBackend *backend,
|
||||
int device_id)
|
||||
{
|
||||
g_clear_object (&backend->device_monitors[device_id]);
|
||||
|
||||
if (device_id == backend->device_id_max)
|
||||
{
|
||||
/* Reset the max device ID */
|
||||
int i, new_max = 0;
|
||||
for (i = 0; i < backend->device_id_max; i++)
|
||||
if (backend->device_monitors[i] != NULL)
|
||||
new_max = i;
|
||||
backend->device_id_max = new_max;
|
||||
}
|
||||
g_hash_table_remove (backend->device_monitors, &device_id);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -142,6 +137,55 @@ on_device_added (ClutterDeviceManager *device_manager,
|
||||
create_device_monitor (backend, device_id);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
device_is_slave_touchscreen (ClutterInputDevice *device)
|
||||
{
|
||||
return (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER &&
|
||||
clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
check_has_pointing_device (ClutterDeviceManager *manager)
|
||||
{
|
||||
const GSList *devices;
|
||||
|
||||
devices = clutter_device_manager_peek_devices (manager);
|
||||
|
||||
for (; devices; devices = devices->next)
|
||||
{
|
||||
ClutterInputDevice *device = devices->data;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||
continue;
|
||||
if (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE ||
|
||||
clutter_input_device_get_device_type (device) == CLUTTER_KEYBOARD_DEVICE)
|
||||
continue;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
check_has_slave_touchscreen (ClutterDeviceManager *manager)
|
||||
{
|
||||
const GSList *devices;
|
||||
|
||||
devices = clutter_device_manager_peek_devices (manager);
|
||||
|
||||
for (; devices; devices = devices->next)
|
||||
{
|
||||
ClutterInputDevice *device = devices->data;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER &&
|
||||
clutter_input_device_get_device_type (device) == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
on_device_removed (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *device,
|
||||
@ -151,6 +195,41 @@ on_device_removed (ClutterDeviceManager *device_manager,
|
||||
int device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
destroy_device_monitor (backend, device_id);
|
||||
|
||||
/* If the device the user last interacted goes away, check again pointer
|
||||
* visibility.
|
||||
*/
|
||||
if (backend->current_device_id == device_id)
|
||||
{
|
||||
MetaCursorTracker *cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
gboolean has_touchscreen, has_pointing_device;
|
||||
ClutterInputDeviceType device_type;
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
has_touchscreen = check_has_slave_touchscreen (device_manager);
|
||||
|
||||
if (device_type == CLUTTER_TOUCHSCREEN_DEVICE && has_touchscreen)
|
||||
{
|
||||
/* There's more touchscreens left, keep the pointer hidden */
|
||||
meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE);
|
||||
}
|
||||
else if (device_type != CLUTTER_KEYBOARD_DEVICE)
|
||||
{
|
||||
has_pointing_device = check_has_pointing_device (device_manager);
|
||||
meta_cursor_tracker_set_pointer_visible (cursor_tracker,
|
||||
has_pointing_device &&
|
||||
!has_touchscreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static MetaMonitorManager *
|
||||
create_monitor_manager (MetaBackend *backend)
|
||||
{
|
||||
if (g_getenv ("META_DUMMY_MONITORS"))
|
||||
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
|
||||
|
||||
return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -162,7 +241,7 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
clutter_actor_realize (priv->stage);
|
||||
META_BACKEND_GET_CLASS (backend)->select_stage_events (backend);
|
||||
|
||||
priv->monitor_manager = META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
|
||||
priv->monitor_manager = create_monitor_manager (backend);
|
||||
|
||||
g_signal_connect (priv->monitor_manager, "monitors-changed",
|
||||
G_CALLBACK (on_monitors_changed), backend);
|
||||
@ -170,8 +249,13 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
|
||||
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
|
||||
|
||||
backend->device_monitors = g_hash_table_new_full (g_int_hash, g_int_equal,
|
||||
NULL, (GDestroyNotify) g_object_unref);
|
||||
|
||||
{
|
||||
MetaCursorTracker *cursor_tracker;
|
||||
ClutterDeviceManager *manager;
|
||||
gboolean has_touchscreen = FALSE;
|
||||
GSList *devices, *l;
|
||||
|
||||
/* Create the core device monitor. */
|
||||
@ -189,10 +273,16 @@ meta_backend_real_post_init (MetaBackend *backend)
|
||||
{
|
||||
ClutterInputDevice *device = l->data;
|
||||
on_device_added (manager, device, backend);
|
||||
has_touchscreen |= device_is_slave_touchscreen (device);
|
||||
}
|
||||
|
||||
cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
meta_cursor_tracker_set_pointer_visible (cursor_tracker, !has_touchscreen);
|
||||
|
||||
g_slist_free (devices);
|
||||
}
|
||||
|
||||
priv->input_settings = meta_input_settings_create ();
|
||||
}
|
||||
|
||||
static MetaCursorRenderer *
|
||||
@ -260,6 +350,12 @@ meta_backend_class_init (MetaBackendClass *klass)
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_UINT);
|
||||
g_signal_new ("last-device-changed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_INT);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -281,9 +377,7 @@ MetaIdleMonitor *
|
||||
meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
int device_id)
|
||||
{
|
||||
g_return_val_if_fail (device_id >= 0 && device_id < 256, NULL);
|
||||
|
||||
return backend->device_monitors[device_id];
|
||||
return g_hash_table_lookup (backend->device_monitors, &device_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -382,6 +476,45 @@ meta_backend_get_stage (MetaBackend *backend)
|
||||
return priv->stage;
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_update_last_device (MetaBackend *backend,
|
||||
int device_id)
|
||||
{
|
||||
ClutterInputDeviceType device_type;
|
||||
MetaCursorTracker *cursor_tracker;
|
||||
ClutterDeviceManager *manager;
|
||||
ClutterInputDevice *device;
|
||||
|
||||
if (backend->current_device_id == device_id)
|
||||
return;
|
||||
|
||||
manager = clutter_device_manager_get_default ();
|
||||
device = clutter_device_manager_get_device (manager, device_id);
|
||||
|
||||
if (!device ||
|
||||
clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||
return;
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
|
||||
cursor_tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
backend->current_device_id = device_id;
|
||||
g_signal_emit_by_name (backend, "last-device-changed", device_id);
|
||||
|
||||
if (device_type == CLUTTER_KEYBOARD_DEVICE)
|
||||
return;
|
||||
|
||||
switch (device_type)
|
||||
{
|
||||
case CLUTTER_TOUCHSCREEN_DEVICE:
|
||||
meta_cursor_tracker_set_pointer_visible (cursor_tracker, FALSE);
|
||||
break;
|
||||
default:
|
||||
meta_cursor_tracker_set_pointer_visible (cursor_tracker, TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GType
|
||||
get_backend_type (void)
|
||||
{
|
||||
|
81
src/backends/meta-barrier-private.h
Normal file
81
src/backends/meta-barrier-private.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_BARRIER_PRIVATE_H
|
||||
#define META_BARRIER_PRIVATE_H
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_BARRIER_IMPL (meta_barrier_impl_get_type ())
|
||||
#define META_BARRIER_IMPL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER_IMPL, MetaBarrierImpl))
|
||||
#define META_BARRIER_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER_IMPL, MetaBarrierImplClass))
|
||||
#define META_IS_BARRIER_IMPL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER_IMPL))
|
||||
#define META_IS_BARRIER_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER_IMPL))
|
||||
#define META_BARRIER_IMPL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER_IMPL, MetaBarrierImplClass))
|
||||
|
||||
typedef struct _MetaBarrierImpl MetaBarrierImpl;
|
||||
typedef struct _MetaBarrierImplClass MetaBarrierImplClass;
|
||||
|
||||
struct _MetaBarrierImpl
|
||||
{
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
struct _MetaBarrierImplClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
gboolean (*is_active) (MetaBarrierImpl *barrier);
|
||||
void (*release) (MetaBarrierImpl *barrier,
|
||||
MetaBarrierEvent *event);
|
||||
void (*destroy) (MetaBarrierImpl *barrier);
|
||||
};
|
||||
|
||||
GType meta_barrier_impl_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void _meta_barrier_emit_hit_signal (MetaBarrier *barrier,
|
||||
MetaBarrierEvent *event);
|
||||
void _meta_barrier_emit_left_signal (MetaBarrier *barrier,
|
||||
MetaBarrierEvent *event);
|
||||
|
||||
void meta_barrier_event_unref (MetaBarrierEvent *event);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
struct _MetaBarrierPrivate
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
|
||||
MetaBarrierDirection directions;
|
||||
|
||||
MetaBarrierImpl *impl;
|
||||
};
|
||||
|
||||
#endif /* META_BARRIER_PRIVATE_H */
|
@ -10,15 +10,16 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <meta/util.h>
|
||||
#include <meta/barrier.h>
|
||||
#include "display-private.h"
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-barrier-native.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "backends/x11/meta-barrier-x11.h"
|
||||
#include "mutter-enum-types.h"
|
||||
#include "core.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaBarrier, meta_barrier, G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE (MetaBarrierImpl, meta_barrier_impl, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
@ -45,21 +46,6 @@ enum {
|
||||
|
||||
static guint obj_signals[LAST_SIGNAL];
|
||||
|
||||
struct _MetaBarrierPrivate
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
|
||||
MetaBarrierDirection directions;
|
||||
|
||||
PointerBarrier xbarrier;
|
||||
};
|
||||
|
||||
static void meta_barrier_event_unref (MetaBarrierEvent *event);
|
||||
|
||||
static void
|
||||
meta_barrier_get_property (GObject *object,
|
||||
@ -133,13 +119,11 @@ static void
|
||||
meta_barrier_dispose (GObject *object)
|
||||
{
|
||||
MetaBarrier *barrier = META_BARRIER (object);
|
||||
MetaBarrierPrivate *priv = barrier->priv;
|
||||
|
||||
if (meta_barrier_is_active (barrier))
|
||||
{
|
||||
meta_bug ("MetaBarrier wrapper %p for X barrier %ld was destroyed"
|
||||
" while the X barrier is still active.",
|
||||
barrier, priv->xbarrier);
|
||||
meta_bug ("MetaBarrier %p was destroyed while it was still active.",
|
||||
barrier);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (meta_barrier_parent_class)->dispose (object);
|
||||
@ -148,7 +132,12 @@ meta_barrier_dispose (GObject *object)
|
||||
gboolean
|
||||
meta_barrier_is_active (MetaBarrier *barrier)
|
||||
{
|
||||
return barrier->priv->xbarrier != 0;
|
||||
MetaBarrierImpl *impl = barrier->priv->impl;
|
||||
|
||||
if (impl)
|
||||
return META_BARRIER_IMPL_GET_CLASS (impl)->is_active (impl);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -165,15 +154,10 @@ void
|
||||
meta_barrier_release (MetaBarrier *barrier,
|
||||
MetaBarrierEvent *event)
|
||||
{
|
||||
#ifdef HAVE_XI23
|
||||
MetaBarrierPrivate *priv = barrier->priv;
|
||||
if (META_DISPLAY_HAS_XINPUT_23 (priv->display))
|
||||
{
|
||||
XIBarrierReleasePointer (priv->display->xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
priv->xbarrier, event->event_id);
|
||||
}
|
||||
#endif /* HAVE_XI23 */
|
||||
MetaBarrierImpl *impl = barrier->priv->impl;
|
||||
|
||||
if (impl)
|
||||
META_BARRIER_IMPL_GET_CLASS (impl)->release (impl, event);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -181,31 +165,26 @@ meta_barrier_constructed (GObject *object)
|
||||
{
|
||||
MetaBarrier *barrier = META_BARRIER (object);
|
||||
MetaBarrierPrivate *priv = barrier->priv;
|
||||
Display *dpy;
|
||||
Window root;
|
||||
|
||||
g_return_if_fail (priv->x1 == priv->x2 || priv->y1 == priv->y2);
|
||||
|
||||
if (priv->display == NULL)
|
||||
{
|
||||
g_warning ("A display must be provided when constructing a barrier.");
|
||||
return;
|
||||
}
|
||||
#if defined(HAVE_NATIVE_BACKEND)
|
||||
if (META_IS_BACKEND_NATIVE (meta_get_backend ()))
|
||||
priv->impl = meta_barrier_impl_native_new (barrier);
|
||||
#endif
|
||||
#if defined(HAVE_XI23)
|
||||
if (META_IS_BACKEND_X11 (meta_get_backend ()) &&
|
||||
!meta_is_wayland_compositor ())
|
||||
priv->impl = meta_barrier_impl_x11_new (barrier);
|
||||
#endif
|
||||
|
||||
dpy = priv->display->xdisplay;
|
||||
root = DefaultRootWindow (dpy);
|
||||
if (priv->impl == NULL)
|
||||
g_warning ("Created a non-working barrier");
|
||||
|
||||
priv->xbarrier = XFixesCreatePointerBarrier (dpy, root,
|
||||
priv->x1, priv->y1,
|
||||
priv->x2, priv->y2,
|
||||
priv->directions, 0, NULL);
|
||||
|
||||
/* Take a ref that we'll release when the XID dies inside destroy(),
|
||||
* so that the object stays alive and doesn't get GC'd. */
|
||||
/* Take a ref that we'll release in destroy() so that the object stays
|
||||
* alive while active. */
|
||||
g_object_ref (barrier);
|
||||
|
||||
g_hash_table_insert (priv->display->xids, &priv->xbarrier, barrier);
|
||||
|
||||
G_OBJECT_CLASS (meta_barrier_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
@ -306,20 +285,10 @@ meta_barrier_class_init (MetaBarrierClass *klass)
|
||||
void
|
||||
meta_barrier_destroy (MetaBarrier *barrier)
|
||||
{
|
||||
MetaBarrierPrivate *priv = barrier->priv;
|
||||
Display *dpy;
|
||||
MetaBarrierImpl *impl = barrier->priv->impl;
|
||||
|
||||
if (priv->display == NULL)
|
||||
return;
|
||||
|
||||
dpy = priv->display->xdisplay;
|
||||
|
||||
if (!meta_barrier_is_active (barrier))
|
||||
return;
|
||||
|
||||
XFixesDestroyPointerBarrier (dpy, priv->xbarrier);
|
||||
g_hash_table_remove (priv->display->xids, &priv->xbarrier);
|
||||
priv->xbarrier = 0;
|
||||
if (impl)
|
||||
return META_BARRIER_IMPL_GET_CLASS (impl)->destroy (impl);
|
||||
|
||||
g_object_unref (barrier);
|
||||
}
|
||||
@ -330,71 +299,32 @@ meta_barrier_init (MetaBarrier *barrier)
|
||||
barrier->priv = G_TYPE_INSTANCE_GET_PRIVATE (barrier, META_TYPE_BARRIER, MetaBarrierPrivate);
|
||||
}
|
||||
|
||||
#ifdef HAVE_XI23
|
||||
void
|
||||
_meta_barrier_emit_hit_signal (MetaBarrier *barrier,
|
||||
MetaBarrierEvent *event)
|
||||
{
|
||||
g_signal_emit (barrier, obj_signals[HIT], 0, event);
|
||||
}
|
||||
|
||||
void
|
||||
_meta_barrier_emit_left_signal (MetaBarrier *barrier,
|
||||
MetaBarrierEvent *event)
|
||||
{
|
||||
g_signal_emit (barrier, obj_signals[LEFT], 0, event);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_fire_event (MetaBarrier *barrier,
|
||||
XIBarrierEvent *xevent)
|
||||
meta_barrier_impl_class_init (MetaBarrierImplClass *klass)
|
||||
{
|
||||
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
|
||||
|
||||
event->ref_count = 1;
|
||||
event->event_id = xevent->eventid;
|
||||
event->time = xevent->time;
|
||||
event->dt = xevent->dtime;
|
||||
|
||||
event->x = xevent->root_x;
|
||||
event->y = xevent->root_y;
|
||||
event->dx = xevent->dx;
|
||||
event->dy = xevent->dy;
|
||||
|
||||
event->released = (xevent->flags & XIBarrierPointerReleased) != 0;
|
||||
event->grabbed = (xevent->flags & XIBarrierDeviceIsGrabbed) != 0;
|
||||
|
||||
switch (xevent->evtype)
|
||||
{
|
||||
case XI_BarrierHit:
|
||||
g_signal_emit (barrier, obj_signals[HIT], 0, event);
|
||||
break;
|
||||
case XI_BarrierLeave:
|
||||
g_signal_emit (barrier, obj_signals[LEFT], 0, event);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
meta_barrier_event_unref (event);
|
||||
klass->is_active = NULL;
|
||||
klass->release = NULL;
|
||||
klass->destroy = NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_process_barrier_event (MetaDisplay *display,
|
||||
XIEvent *event)
|
||||
static void
|
||||
meta_barrier_impl_init (MetaBarrierImpl *impl)
|
||||
{
|
||||
MetaBarrier *barrier;
|
||||
XIBarrierEvent *xev;
|
||||
|
||||
if (event == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (event->evtype)
|
||||
{
|
||||
case XI_BarrierHit:
|
||||
case XI_BarrierLeave:
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xev = (XIBarrierEvent *) event;
|
||||
barrier = g_hash_table_lookup (display->xids, &xev->barrier);
|
||||
if (barrier != NULL)
|
||||
{
|
||||
meta_barrier_fire_event (barrier, xev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif /* HAVE_XI23 */
|
||||
|
||||
static MetaBarrierEvent *
|
||||
meta_barrier_event_ref (MetaBarrierEvent *event)
|
||||
@ -406,7 +336,7 @@ meta_barrier_event_ref (MetaBarrierEvent *event)
|
||||
return event;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
meta_barrier_event_unref (MetaBarrierEvent *event)
|
||||
{
|
||||
g_return_if_fail (event != NULL);
|
@ -25,12 +25,18 @@
|
||||
#include "meta-cursor.h"
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include <gbm.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
CoglTexture2D *texture;
|
||||
struct gbm_bo *bo;
|
||||
int hot_x, hot_y;
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_bo *bo;
|
||||
#endif
|
||||
} MetaCursorImage;
|
||||
|
||||
struct _MetaCursorReference {
|
||||
@ -44,8 +50,10 @@ CoglTexture *meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor
|
||||
int *hot_x,
|
||||
int *hot_y);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_bo *meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y);
|
||||
#endif
|
||||
|
||||
#endif /* META_CURSOR_PRIVATE_H */
|
||||
|
@ -30,8 +30,6 @@
|
||||
#include <meta/screen.h>
|
||||
#include "meta-cursor.h"
|
||||
|
||||
#include <gbm.h>
|
||||
|
||||
#define META_TYPE_CURSOR_RENDERER (meta_cursor_renderer_get_type ())
|
||||
#define META_CURSOR_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER, MetaCursorRenderer))
|
||||
#define META_CURSOR_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_RENDERER, MetaCursorRendererClass))
|
||||
|
@ -27,7 +27,9 @@
|
||||
* pointer abstraction"
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <meta/main.h>
|
||||
#include <meta/util.h>
|
||||
@ -38,11 +40,10 @@
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
|
||||
|
||||
|
@ -55,9 +55,13 @@ meta_cursor_reference_ref (MetaCursorReference *self)
|
||||
static void
|
||||
meta_cursor_image_free (MetaCursorImage *image)
|
||||
{
|
||||
cogl_object_unref (image->texture);
|
||||
if (image->texture)
|
||||
cogl_object_unref (image->texture);
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
if (image->bo)
|
||||
gbm_bo_destroy (image->bo);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -139,70 +143,90 @@ load_cursor_on_client (MetaCursor cursor)
|
||||
meta_prefs_get_cursor_size ());
|
||||
}
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static void
|
||||
get_hardware_cursor_size (uint64_t *cursor_width, uint64_t *cursor_height)
|
||||
{
|
||||
MetaBackend *meta_backend = meta_get_backend ();
|
||||
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
|
||||
|
||||
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
|
||||
{
|
||||
meta_cursor_renderer_native_get_cursor_size (META_CURSOR_RENDERER_NATIVE (renderer), cursor_width, cursor_height);
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static void
|
||||
meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
|
||||
MetaCursorImage *image,
|
||||
uint8_t *pixels,
|
||||
int width,
|
||||
int height,
|
||||
uint width,
|
||||
uint height,
|
||||
int rowstride,
|
||||
uint32_t gbm_format)
|
||||
{
|
||||
if (width > 64 || height > 64)
|
||||
uint64_t cursor_width, cursor_height;
|
||||
get_hardware_cursor_size (&cursor_width, &cursor_height);
|
||||
|
||||
if (width > cursor_width || height > cursor_height)
|
||||
{
|
||||
meta_warning ("Invalid theme cursor size (must be at most 64x64)\n");
|
||||
meta_warning ("Invalid theme cursor size (must be at most %ux%u)\n",
|
||||
(unsigned int)cursor_width, (unsigned int)cursor_height);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gbm_device_is_format_supported (gbm, gbm_format,
|
||||
GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE))
|
||||
GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE))
|
||||
{
|
||||
uint8_t buf[4 * 64 * 64];
|
||||
int i;
|
||||
uint8_t buf[4 * cursor_width * cursor_height];
|
||||
uint i;
|
||||
|
||||
image->bo = gbm_bo_create (gbm, 64, 64,
|
||||
gbm_format, GBM_BO_USE_CURSOR_64X64 | GBM_BO_USE_WRITE);
|
||||
image->bo = gbm_bo_create (gbm, cursor_width, cursor_height,
|
||||
gbm_format, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE);
|
||||
|
||||
memset (buf, 0, sizeof(buf));
|
||||
for (i = 0; i < height; i++)
|
||||
memcpy (buf + i * 4 * 64, pixels + i * rowstride, width * 4);
|
||||
memcpy (buf + i * 4 * cursor_width, pixels + i * rowstride, width * 4);
|
||||
|
||||
gbm_bo_write (image->bo, buf, 64 * 64 * 4);
|
||||
gbm_bo_write (image->bo, buf, cursor_width * cursor_height * 4);
|
||||
}
|
||||
else
|
||||
meta_warning ("HW cursor for format %d not supported\n", gbm_format);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static struct gbm_device *
|
||||
get_gbm_device (void)
|
||||
{
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *meta_backend = meta_get_backend ();
|
||||
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (meta_backend);
|
||||
|
||||
if (META_IS_CURSOR_RENDERER_NATIVE (renderer))
|
||||
return meta_cursor_renderer_native_get_gbm_device (META_CURSOR_RENDERER_NATIVE (renderer));
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
|
||||
XcursorImage *xc_image)
|
||||
{
|
||||
int width, height, rowstride;
|
||||
uint width, height, rowstride;
|
||||
CoglPixelFormat cogl_format;
|
||||
uint32_t gbm_format;
|
||||
ClutterBackend *clutter_backend;
|
||||
CoglContext *cogl_context;
|
||||
struct gbm_device *gbm;
|
||||
|
||||
width = xc_image->width;
|
||||
height = xc_image->height;
|
||||
rowstride = width * 4;
|
||||
|
||||
gbm_format = GBM_FORMAT_ARGB8888;
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
cogl_format = COGL_PIXEL_FORMAT_BGRA_8888;
|
||||
#else
|
||||
@ -221,31 +245,41 @@ meta_cursor_image_load_from_xcursor_image (MetaCursorImage *image,
|
||||
(uint8_t *) xc_image->pixels,
|
||||
NULL);
|
||||
|
||||
gbm = get_gbm_device ();
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_device *gbm = get_gbm_device ();
|
||||
if (gbm)
|
||||
meta_cursor_image_load_gbm_buffer (gbm,
|
||||
image,
|
||||
(uint8_t *) xc_image->pixels,
|
||||
width, height, rowstride,
|
||||
gbm_format);
|
||||
GBM_FORMAT_ARGB8888);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
load_cursor_image (MetaCursorReference *cursor)
|
||||
{
|
||||
XcursorImage *image;
|
||||
|
||||
/* Either cursors are loaded from X cursors or buffers. Since
|
||||
* buffers are converted over immediately, we can make sure to
|
||||
* load this directly. */
|
||||
g_assert (cursor->cursor != META_CURSOR_NONE);
|
||||
|
||||
image = load_cursor_on_client (cursor->cursor);
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
meta_cursor_image_load_from_xcursor_image (&cursor->image, image);
|
||||
XcursorImageDestroy (image);
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
meta_cursor_reference_from_theme (MetaCursor cursor)
|
||||
{
|
||||
MetaCursorReference *self;
|
||||
XcursorImage *image;
|
||||
|
||||
image = load_cursor_on_client (cursor);
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
self = g_slice_new0 (MetaCursorReference);
|
||||
MetaCursorReference *self = g_slice_new0 (MetaCursorReference);
|
||||
self->ref_count = 1;
|
||||
self->cursor = cursor;
|
||||
meta_cursor_image_load_from_xcursor_image (&self->image, image);
|
||||
|
||||
XcursorImageDestroy (image);
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -256,13 +290,8 @@ meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
||||
int hot_x,
|
||||
int hot_y)
|
||||
{
|
||||
struct gbm_device *gbm = get_gbm_device ();
|
||||
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
struct wl_shm_buffer *shm_buffer;
|
||||
uint32_t gbm_format;
|
||||
int width, height;
|
||||
|
||||
image->hot_x = hot_x;
|
||||
image->hot_y = hot_y;
|
||||
@ -272,16 +301,24 @@ meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
||||
|
||||
image->texture = cogl_wayland_texture_2d_new_from_buffer (cogl_context, buffer, NULL);
|
||||
|
||||
width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
|
||||
height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
|
||||
|
||||
shm_buffer = wl_shm_buffer_get (buffer);
|
||||
if (shm_buffer)
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_device *gbm = get_gbm_device ();
|
||||
if (gbm)
|
||||
{
|
||||
if (gbm)
|
||||
uint32_t gbm_format;
|
||||
uint64_t cursor_width, cursor_height;
|
||||
uint width, height;
|
||||
|
||||
width = cogl_texture_get_width (COGL_TEXTURE (image->texture));
|
||||
height = cogl_texture_get_height (COGL_TEXTURE (image->texture));
|
||||
|
||||
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
|
||||
if (shm_buffer)
|
||||
{
|
||||
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
|
||||
|
||||
wl_shm_buffer_begin_access (shm_buffer);
|
||||
|
||||
switch (wl_shm_buffer_get_format (shm_buffer))
|
||||
{
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
@ -309,30 +346,31 @@ meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
||||
(uint8_t *) wl_shm_buffer_get_data (shm_buffer),
|
||||
width, height, rowstride,
|
||||
gbm_format);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HW cursors must be 64x64, but 64x64 is huge, and no cursor theme actually uses
|
||||
that, so themed cursors must be padded with transparent pixels to fill the
|
||||
overlay. This is trivial if we have CPU access to the data, but it's not
|
||||
possible if the buffer is in GPU memory (and possibly tiled too), so if we
|
||||
don't get the right size, we fallback to GL.
|
||||
*/
|
||||
if (width != 64 || height != 64)
|
||||
{
|
||||
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (gbm)
|
||||
wl_shm_buffer_end_access (shm_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER,
|
||||
buffer, GBM_BO_USE_CURSOR_64X64);
|
||||
/* HW cursors have a predefined size (at least 64x64), which usually is bigger than cursor theme
|
||||
size, so themed cursors must be padded with transparent pixels to fill the
|
||||
overlay. This is trivial if we have CPU access to the data, but it's not
|
||||
possible if the buffer is in GPU memory (and possibly tiled too), so if we
|
||||
don't get the right size, we fallback to GL.
|
||||
*/
|
||||
get_hardware_cursor_size (&cursor_width, &cursor_height);
|
||||
|
||||
if (width != cursor_width || height != cursor_height)
|
||||
{
|
||||
meta_warning ("Invalid cursor size (must be 64x64), falling back to software (GL) cursors\n");
|
||||
return;
|
||||
}
|
||||
|
||||
image->bo = gbm_bo_import (gbm, GBM_BO_IMPORT_WL_BUFFER, buffer, GBM_BO_USE_CURSOR);
|
||||
if (!image->bo)
|
||||
meta_warning ("Importing HW cursor from wl_buffer failed\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
@ -355,24 +393,33 @@ meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
{
|
||||
if (!cursor->image.texture)
|
||||
load_cursor_image (cursor);
|
||||
|
||||
if (hot_x)
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->image.hot_y;
|
||||
|
||||
return COGL_TEXTURE (cursor->image.texture);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
struct gbm_bo *
|
||||
meta_cursor_reference_get_gbm_bo (MetaCursorReference *cursor,
|
||||
int *hot_x,
|
||||
int *hot_y)
|
||||
{
|
||||
if (!cursor->image.bo)
|
||||
load_cursor_image (cursor);
|
||||
|
||||
if (hot_x)
|
||||
*hot_x = cursor->image.hot_x;
|
||||
if (hot_y)
|
||||
*hot_y = cursor->image.hot_y;
|
||||
return cursor->image.bo;
|
||||
}
|
||||
#endif
|
||||
|
||||
MetaCursor
|
||||
meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor)
|
||||
|
87
src/backends/meta-input-settings-private.h
Normal file
87
src/backends/meta-input-settings-private.h
Normal file
@ -0,0 +1,87 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_INPUT_SETTINGS_PRIVATE_H
|
||||
#define META_INPUT_SETTINGS_PRIVATE_H
|
||||
|
||||
#include "display-private.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#define META_TYPE_INPUT_SETTINGS (meta_input_settings_get_type ())
|
||||
#define META_INPUT_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS, MetaInputSettings))
|
||||
#define META_INPUT_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS, MetaInputSettingsClass))
|
||||
#define META_IS_INPUT_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS))
|
||||
#define META_IS_INPUT_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS))
|
||||
#define META_INPUT_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS, MetaInputSettingsClass))
|
||||
|
||||
typedef struct _MetaInputSettings MetaInputSettings;
|
||||
typedef struct _MetaInputSettingsClass MetaInputSettingsClass;
|
||||
|
||||
struct _MetaInputSettings
|
||||
{
|
||||
GObject parent_instance;
|
||||
};
|
||||
|
||||
struct _MetaInputSettingsClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* set_send_events) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopDeviceSendEvents mode);
|
||||
void (* set_matrix) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gfloat matrix[6]);
|
||||
void (* set_speed) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gdouble speed);
|
||||
void (* set_left_handed) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled);
|
||||
void (* set_tap_enabled) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled);
|
||||
void (* set_invert_scroll) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean inverted);
|
||||
void (* set_scroll_method) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadScrollMethod mode);
|
||||
void (* set_scroll_button) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
guint button);
|
||||
|
||||
void (* set_click_method) (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadClickMethod mode);
|
||||
|
||||
void (* set_keyboard_repeat) (MetaInputSettings *settings,
|
||||
gboolean repeat,
|
||||
guint delay,
|
||||
guint interval);
|
||||
};
|
||||
|
||||
GType meta_input_settings_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaInputSettings * meta_input_settings_create (void);
|
||||
|
||||
#endif /* META_INPUT_SETTINGS_PRIVATE_H */
|
867
src/backends/meta-input-settings.c
Normal file
867
src/backends/meta-input-settings.c
Normal file
@ -0,0 +1,867 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:input-settings
|
||||
* @title: MetaInputSettings
|
||||
* @short_description: Mutter input device configuration
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "meta-backend-private.h"
|
||||
#include "meta-input-settings-private.h"
|
||||
#include "x11/meta-input-settings-x11.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "native/meta-backend-native.h"
|
||||
#include "native/meta-input-settings-native.h"
|
||||
#endif
|
||||
|
||||
#include <meta/util.h>
|
||||
|
||||
typedef struct _MetaInputSettingsPrivate MetaInputSettingsPrivate;
|
||||
typedef struct _DeviceMappingInfo DeviceMappingInfo;
|
||||
|
||||
struct _DeviceMappingInfo
|
||||
{
|
||||
MetaInputSettings *input_settings;
|
||||
ClutterInputDevice *device;
|
||||
GSettings *settings;
|
||||
};
|
||||
|
||||
struct _MetaInputSettingsPrivate
|
||||
{
|
||||
ClutterDeviceManager *device_manager;
|
||||
MetaMonitorManager *monitor_manager;
|
||||
guint monitors_changed_id;
|
||||
|
||||
GSettings *mouse_settings;
|
||||
GSettings *touchpad_settings;
|
||||
GSettings *trackball_settings;
|
||||
GSettings *keyboard_settings;
|
||||
|
||||
GHashTable *mappable_devices;
|
||||
};
|
||||
|
||||
typedef void (*ConfigBoolFunc) (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean setting);
|
||||
typedef void (*ConfigDoubleFunc) (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
gdouble value);
|
||||
typedef void (*ConfigUintFunc) (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
guint value);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaInputSettings, meta_input_settings, G_TYPE_OBJECT)
|
||||
|
||||
static GSList *
|
||||
meta_input_settings_get_devices (MetaInputSettings *settings,
|
||||
ClutterInputDeviceType type)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
const GSList *devices;
|
||||
GSList *list = NULL;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (settings);
|
||||
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
||||
|
||||
while (devices)
|
||||
{
|
||||
ClutterInputDevice *device = devices->data;
|
||||
|
||||
if (clutter_input_device_get_device_type (device) == type &&
|
||||
clutter_input_device_get_device_mode (device) != CLUTTER_INPUT_MODE_MASTER)
|
||||
list = g_slist_prepend (list, device);
|
||||
|
||||
devices = devices->next;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_dispose (GObject *object)
|
||||
{
|
||||
MetaInputSettings *settings = META_INPUT_SETTINGS (object);
|
||||
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (settings);
|
||||
|
||||
g_clear_object (&priv->mouse_settings);
|
||||
g_clear_object (&priv->touchpad_settings);
|
||||
g_clear_object (&priv->trackball_settings);
|
||||
g_clear_object (&priv->keyboard_settings);
|
||||
g_clear_pointer (&priv->mappable_devices, g_hash_table_unref);
|
||||
|
||||
if (priv->monitors_changed_id && priv->monitor_manager)
|
||||
{
|
||||
g_signal_handler_disconnect (priv->monitor_manager,
|
||||
priv->monitors_changed_id);
|
||||
priv->monitors_changed_id = 0;
|
||||
}
|
||||
|
||||
g_clear_object (&priv->monitor_manager);
|
||||
|
||||
G_OBJECT_CLASS (meta_input_settings_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_device_set_bool_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
ConfigBoolFunc func,
|
||||
gboolean enabled)
|
||||
{
|
||||
func (input_settings, device, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_set_bool_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDeviceType type,
|
||||
ConfigBoolFunc func,
|
||||
gboolean enabled)
|
||||
{
|
||||
GSList *devices, *d;
|
||||
|
||||
devices = meta_input_settings_get_devices (input_settings, type);
|
||||
|
||||
for (d = devices; d; d = d->next)
|
||||
settings_device_set_bool_setting (input_settings, d->data, func, enabled);
|
||||
|
||||
g_slist_free (devices);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_device_set_double_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
ConfigDoubleFunc func,
|
||||
gdouble value)
|
||||
{
|
||||
func (input_settings, device, value);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_set_double_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDeviceType type,
|
||||
ConfigDoubleFunc func,
|
||||
gdouble value)
|
||||
{
|
||||
GSList *devices, *d;
|
||||
|
||||
devices = meta_input_settings_get_devices (input_settings, type);
|
||||
|
||||
for (d = devices; d; d = d->next)
|
||||
settings_device_set_double_setting (input_settings, d->data, func, value);
|
||||
|
||||
g_slist_free (devices);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_device_set_uint_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device,
|
||||
ConfigUintFunc func,
|
||||
guint value)
|
||||
{
|
||||
(func) (input_settings, device, value);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_set_uint_setting (MetaInputSettings *input_settings,
|
||||
ClutterInputDeviceType type,
|
||||
ConfigUintFunc func,
|
||||
guint value)
|
||||
{
|
||||
GSList *devices, *d;
|
||||
|
||||
devices = meta_input_settings_get_devices (input_settings, type);
|
||||
|
||||
for (d = devices; d; d = d->next)
|
||||
settings_device_set_uint_setting (input_settings, d->data, func, value);
|
||||
|
||||
g_slist_free (devices);
|
||||
}
|
||||
|
||||
static void
|
||||
update_touchpad_left_handed (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
GDesktopTouchpadHandedness handedness;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled = FALSE;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
handedness = g_settings_get_enum (priv->touchpad_settings, "left-handed");
|
||||
|
||||
switch (handedness)
|
||||
{
|
||||
case G_DESKTOP_TOUCHPAD_HANDEDNESS_RIGHT:
|
||||
enabled = FALSE;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT:
|
||||
enabled = TRUE;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE:
|
||||
enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (device)
|
||||
{
|
||||
g_assert (clutter_input_device_get_device_type (device) == CLUTTER_TOUCHPAD_DEVICE);
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_mouse_left_handed (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
enabled = g_settings_get_boolean (priv->mouse_settings, "left-handed");
|
||||
|
||||
if (device)
|
||||
{
|
||||
g_assert (clutter_input_device_get_device_type (device) == CLUTTER_POINTER_DEVICE);
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
GDesktopTouchpadHandedness touchpad_handedness;
|
||||
|
||||
settings_set_bool_setting (input_settings, CLUTTER_POINTER_DEVICE,
|
||||
input_settings_class->set_left_handed,
|
||||
enabled);
|
||||
|
||||
touchpad_handedness = g_settings_get_enum (priv->touchpad_settings,
|
||||
"left-handed");
|
||||
|
||||
/* Also update touchpads if they're following mouse settings */
|
||||
if (touchpad_handedness == G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE)
|
||||
update_touchpad_left_handed (input_settings, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_device_speed (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
ClutterInputDeviceType type)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
gdouble speed;
|
||||
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
speed = g_settings_get_double (settings, "speed");
|
||||
|
||||
if (device)
|
||||
settings_device_set_double_setting (input_settings, device,
|
||||
input_settings_class->set_speed,
|
||||
speed);
|
||||
else
|
||||
settings_set_double_setting (input_settings, type,
|
||||
input_settings_class->set_speed,
|
||||
speed);
|
||||
}
|
||||
|
||||
static void
|
||||
update_device_natural_scroll (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
ClutterInputDeviceType type)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
gboolean enabled;
|
||||
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
enabled = g_settings_get_boolean (settings, "natural-scroll");
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_invert_scroll,
|
||||
enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_bool_setting (input_settings, type,
|
||||
input_settings_class->set_invert_scroll,
|
||||
enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_touchpad_tap_enabled (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gboolean enabled;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
enabled = g_settings_get_boolean (priv->touchpad_settings, "tap-to-click");
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_bool_setting (input_settings, device,
|
||||
input_settings_class->set_tap_enabled,
|
||||
enabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_bool_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
input_settings_class->set_tap_enabled,
|
||||
enabled);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_touchpad_scroll_method (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
GDesktopTouchpadScrollMethod method;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
method = g_settings_get_enum (priv->touchpad_settings, "scroll-method");
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_uint_setting (input_settings, device,
|
||||
input_settings_class->set_scroll_method,
|
||||
method);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
(ConfigUintFunc) input_settings_class->set_scroll_method,
|
||||
method);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_touchpad_click_method (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
GDesktopTouchpadScrollMethod method;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
method = g_settings_get_enum (priv->touchpad_settings, "click-method");
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_uint_setting (input_settings, device,
|
||||
input_settings_class->set_click_method,
|
||||
method);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
(ConfigUintFunc) input_settings_class->set_click_method,
|
||||
method);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_touchpad_send_events (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
GDesktopDeviceSendEvents mode;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
mode = g_settings_get_enum (priv->touchpad_settings, "send-events");
|
||||
|
||||
if (device)
|
||||
{
|
||||
settings_device_set_uint_setting (input_settings, device,
|
||||
input_settings_class->set_send_events,
|
||||
mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
settings_set_uint_setting (input_settings, CLUTTER_TOUCHPAD_DEVICE,
|
||||
input_settings_class->set_send_events,
|
||||
mode);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
device_is_trackball (ClutterInputDevice *device)
|
||||
{
|
||||
gboolean is_trackball;
|
||||
char *name;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||
return FALSE;
|
||||
|
||||
name = g_ascii_strdown (clutter_input_device_get_device_name (device), -1);
|
||||
is_trackball = strstr (name, "trackball") != NULL;
|
||||
g_free (name);
|
||||
|
||||
return is_trackball;
|
||||
}
|
||||
|
||||
static void
|
||||
update_trackball_scroll_button (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
guint button;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
button = g_settings_get_uint (priv->trackball_settings, "scroll-wheel-emulation-button");
|
||||
|
||||
if (device && device_is_trackball (device))
|
||||
{
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
}
|
||||
else if (!device)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
const GSList *devices;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
||||
|
||||
while (devices)
|
||||
{
|
||||
ClutterInputDevice *device = devices->data;
|
||||
|
||||
if (device_is_trackball (device))
|
||||
input_settings_class->set_scroll_button (input_settings, device, button);
|
||||
|
||||
devices = devices->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_keyboard_repeat (MetaInputSettings *input_settings)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
guint delay, interval;
|
||||
gboolean repeat;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
repeat = g_settings_get_boolean (priv->keyboard_settings, "repeat");
|
||||
delay = g_settings_get_uint (priv->keyboard_settings, "delay");
|
||||
interval = g_settings_get_uint (priv->keyboard_settings, "repeat-interval");
|
||||
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
input_settings_class->set_keyboard_repeat (input_settings,
|
||||
repeat, delay, interval);
|
||||
}
|
||||
|
||||
static MetaOutput *
|
||||
meta_input_settings_find_output (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
guint n_values, n_outputs, i;
|
||||
MetaOutput *outputs;
|
||||
gchar **edid;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
edid = g_settings_get_strv (settings, "display");
|
||||
n_values = g_strv_length (edid);
|
||||
|
||||
if (n_values != 3)
|
||||
{
|
||||
g_warning ("EDID configuration for device '%s' "
|
||||
"is incorrect, must have 3 values",
|
||||
clutter_input_device_get_device_name (device));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!*edid[0] && !*edid[1] && !*edid[2])
|
||||
return NULL;
|
||||
|
||||
outputs = meta_monitor_manager_get_outputs (priv->monitor_manager,
|
||||
&n_outputs);
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
if (g_strcmp0 (outputs[i].vendor, edid[0]) == 0 &&
|
||||
g_strcmp0 (outputs[i].product, edid[1]) == 0 &&
|
||||
g_strcmp0 (outputs[i].serial, edid[2]) == 0)
|
||||
return &outputs[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
update_device_display (MetaInputSettings *input_settings,
|
||||
GSettings *settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
gfloat matrix[6] = { 1, 0, 0, 0, 1, 0 };
|
||||
MetaOutput *output;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
input_settings_class = META_INPUT_SETTINGS_GET_CLASS (input_settings);
|
||||
output = meta_input_settings_find_output (input_settings, settings, device);
|
||||
|
||||
if (output)
|
||||
meta_monitor_manager_get_monitor_matrix (priv->monitor_manager,
|
||||
output, matrix);
|
||||
|
||||
input_settings_class->set_matrix (input_settings, device, matrix);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_changed_cb (GSettings *settings,
|
||||
const char *key,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaInputSettings *input_settings = META_INPUT_SETTINGS (user_data);
|
||||
MetaInputSettingsPrivate *priv = meta_input_settings_get_instance_private (input_settings);
|
||||
|
||||
if (settings == priv->mouse_settings)
|
||||
{
|
||||
if (strcmp (key, "left-handed") == 0)
|
||||
update_mouse_left_handed (input_settings, NULL);
|
||||
else if (strcmp (key, "speed") == 0)
|
||||
update_device_speed (input_settings, settings, NULL,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
else if (strcmp (key, "natural-scroll") == 0)
|
||||
update_device_natural_scroll (input_settings, settings,
|
||||
NULL, CLUTTER_POINTER_DEVICE);
|
||||
}
|
||||
else if (settings == priv->touchpad_settings)
|
||||
{
|
||||
if (strcmp (key, "left-handed") == 0)
|
||||
update_touchpad_left_handed (input_settings, NULL);
|
||||
else if (strcmp (key, "speed") == 0)
|
||||
update_device_speed (input_settings, settings, NULL,
|
||||
CLUTTER_TOUCHPAD_DEVICE);
|
||||
else if (strcmp (key, "natural-scroll") == 0)
|
||||
update_device_natural_scroll (input_settings, settings,
|
||||
NULL, CLUTTER_TOUCHPAD_DEVICE);
|
||||
else if (strcmp (key, "tap-to-click") == 0)
|
||||
update_touchpad_tap_enabled (input_settings, NULL);
|
||||
else if (strcmp (key, "send-events") == 0)
|
||||
update_touchpad_send_events (input_settings, NULL);
|
||||
else if (strcmp (key, "scroll-method") == 0)
|
||||
update_touchpad_scroll_method (input_settings, NULL);
|
||||
else if (strcmp (key, "click-method") == 0)
|
||||
update_touchpad_click_method (input_settings, NULL);
|
||||
}
|
||||
else if (settings == priv->trackball_settings)
|
||||
{
|
||||
if (strcmp (key, "scroll-wheel-emulation-button") == 0)
|
||||
update_trackball_scroll_button (input_settings, NULL);
|
||||
}
|
||||
else if (settings == priv->keyboard_settings)
|
||||
{
|
||||
if (strcmp (key, "repeat") == 0 ||
|
||||
strcmp (key, "repeat-interval") == 0 ||
|
||||
strcmp (key, "delay") == 0)
|
||||
update_keyboard_repeat (input_settings);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mapped_device_changed_cb (GSettings *settings,
|
||||
const gchar *key,
|
||||
DeviceMappingInfo *info)
|
||||
{
|
||||
if (strcmp (key, "display") == 0)
|
||||
update_device_display (info->input_settings, settings, info->device);
|
||||
}
|
||||
|
||||
static GSettings *
|
||||
lookup_device_settings (ClutterInputDevice *device)
|
||||
{
|
||||
const gchar *group, *schema, *vendor, *product;
|
||||
ClutterInputDeviceType type;
|
||||
GSettings *settings;
|
||||
gchar *path;
|
||||
|
||||
type = clutter_input_device_get_device_type (device);
|
||||
|
||||
if (type == CLUTTER_TOUCHSCREEN_DEVICE)
|
||||
{
|
||||
group = "touchscreens";
|
||||
schema = "org.gnome.desktop.peripherals.touchscreen";
|
||||
}
|
||||
else if (type == CLUTTER_TABLET_DEVICE ||
|
||||
type == CLUTTER_PEN_DEVICE ||
|
||||
type == CLUTTER_ERASER_DEVICE ||
|
||||
type == CLUTTER_CURSOR_DEVICE)
|
||||
{
|
||||
group = "tablets";
|
||||
schema = "org.gnome.desktop.peripherals.tablet";
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
||||
vendor = clutter_input_device_get_vendor_id (device);
|
||||
product = clutter_input_device_get_product_id (device);
|
||||
path = g_strdup_printf ("/org/gnome/desktop/peripherals/%s/%s:%s/",
|
||||
group, vendor, product);
|
||||
|
||||
settings = g_settings_new_with_path (schema, path);
|
||||
g_free (path);
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
static void
|
||||
monitors_changed_cb (MetaMonitorManager *monitor_manager,
|
||||
MetaInputSettings *input_settings)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
ClutterInputDevice *device;
|
||||
GSettings *settings;
|
||||
GHashTableIter iter;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
g_hash_table_iter_init (&iter, priv->mappable_devices);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &device,
|
||||
(gpointer *) &settings))
|
||||
update_device_display (input_settings, settings, device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_add_mappable_device (MetaInputSettings *input_settings,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
DeviceMappingInfo *info;
|
||||
GSettings *settings;
|
||||
|
||||
settings = lookup_device_settings (device);
|
||||
|
||||
if (!settings)
|
||||
return FALSE;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
|
||||
info = g_new0 (DeviceMappingInfo, 1);
|
||||
info->input_settings = input_settings;
|
||||
info->device = device;
|
||||
info->settings = settings;
|
||||
|
||||
g_signal_connect_data (settings, "changed",
|
||||
G_CALLBACK (mapped_device_changed_cb),
|
||||
info, (GClosureNotify) g_free, 0);
|
||||
|
||||
g_hash_table_insert (priv->mappable_devices, device, settings);
|
||||
|
||||
update_device_display (input_settings, settings, device);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_device_added (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *device,
|
||||
MetaInputSettings *input_settings)
|
||||
{
|
||||
ClutterInputDeviceType type;
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||
return;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
type = clutter_input_device_get_device_type (device);
|
||||
|
||||
if (type == CLUTTER_POINTER_DEVICE)
|
||||
{
|
||||
update_mouse_left_handed (input_settings, device);
|
||||
update_device_speed (input_settings, priv->mouse_settings, device, type);
|
||||
|
||||
if (device_is_trackball (device))
|
||||
update_trackball_scroll_button (input_settings, device);
|
||||
}
|
||||
else if (type == CLUTTER_TOUCHPAD_DEVICE)
|
||||
{
|
||||
update_touchpad_left_handed (input_settings, device);
|
||||
update_touchpad_tap_enabled (input_settings, device);
|
||||
update_touchpad_scroll_method (input_settings, device);
|
||||
update_touchpad_click_method (input_settings, device);
|
||||
update_touchpad_send_events (input_settings, device);
|
||||
|
||||
update_device_speed (input_settings, priv->touchpad_settings,
|
||||
device, type);
|
||||
update_device_natural_scroll (input_settings, priv->touchpad_settings,
|
||||
device, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
check_add_mappable_device (input_settings, device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_device_removed (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *device,
|
||||
MetaInputSettings *input_settings)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
g_hash_table_remove (priv->mappable_devices, device);
|
||||
}
|
||||
|
||||
static void
|
||||
check_mappable_devices (MetaInputSettings *input_settings)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
const GSList *devices, *l;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
devices = clutter_device_manager_peek_devices (priv->device_manager);
|
||||
|
||||
for (l = devices; l; l = l->next)
|
||||
{
|
||||
ClutterInputDevice *device = l->data;
|
||||
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER)
|
||||
continue;
|
||||
|
||||
check_add_mappable_device (input_settings, device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_constructed (GObject *object)
|
||||
{
|
||||
MetaInputSettings *input_settings = META_INPUT_SETTINGS (object);
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (input_settings);
|
||||
|
||||
update_mouse_left_handed (input_settings, NULL);
|
||||
|
||||
update_touchpad_left_handed (input_settings, NULL);
|
||||
update_touchpad_tap_enabled (input_settings, NULL);
|
||||
update_touchpad_send_events (input_settings, NULL);
|
||||
|
||||
update_device_natural_scroll (input_settings, priv->touchpad_settings,
|
||||
NULL, CLUTTER_TOUCHPAD_DEVICE);
|
||||
update_device_speed (input_settings, priv->touchpad_settings, NULL,
|
||||
CLUTTER_TOUCHPAD_DEVICE);
|
||||
update_device_speed (input_settings, priv->mouse_settings, NULL,
|
||||
CLUTTER_POINTER_DEVICE);
|
||||
|
||||
update_keyboard_repeat (input_settings);
|
||||
|
||||
check_mappable_devices (input_settings);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_class_init (MetaInputSettingsClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_input_settings_dispose;
|
||||
object_class->constructed = meta_input_settings_constructed;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_init (MetaInputSettings *settings)
|
||||
{
|
||||
MetaInputSettingsPrivate *priv;
|
||||
|
||||
priv = meta_input_settings_get_instance_private (settings);
|
||||
priv->device_manager = clutter_device_manager_get_default ();
|
||||
g_signal_connect (priv->device_manager, "device-added",
|
||||
G_CALLBACK (meta_input_settings_device_added), settings);
|
||||
g_signal_connect (priv->device_manager, "device-removed",
|
||||
G_CALLBACK (meta_input_settings_device_removed), settings);
|
||||
|
||||
priv->mouse_settings = g_settings_new ("org.gnome.desktop.peripherals.mouse");
|
||||
g_signal_connect (priv->mouse_settings, "changed",
|
||||
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
||||
|
||||
priv->touchpad_settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad");
|
||||
g_signal_connect (priv->touchpad_settings, "changed",
|
||||
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
||||
|
||||
priv->trackball_settings = g_settings_new ("org.gnome.desktop.peripherals.trackball");
|
||||
g_signal_connect (priv->trackball_settings, "changed",
|
||||
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
||||
|
||||
priv->keyboard_settings = g_settings_new ("org.gnome.desktop.peripherals.keyboard");
|
||||
g_signal_connect (priv->keyboard_settings, "changed",
|
||||
G_CALLBACK (meta_input_settings_changed_cb), settings);
|
||||
|
||||
priv->mappable_devices =
|
||||
g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) g_object_unref);
|
||||
|
||||
priv->monitor_manager = g_object_ref (meta_monitor_manager_get ());
|
||||
g_signal_connect (priv->monitor_manager, "monitors-changed",
|
||||
G_CALLBACK (monitors_changed_cb), settings);
|
||||
}
|
||||
|
||||
MetaInputSettings *
|
||||
meta_input_settings_create (void)
|
||||
{
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
MetaBackend *backend;
|
||||
|
||||
backend = meta_get_backend ();
|
||||
|
||||
if (META_IS_BACKEND_NATIVE (backend))
|
||||
return g_object_new (META_TYPE_INPUT_SETTINGS_NATIVE, NULL);
|
||||
#endif
|
||||
if (!meta_is_wayland_compositor ())
|
||||
return g_object_new (META_TYPE_INPUT_SETTINGS_X11, NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "boxes-private.h"
|
||||
#include "meta-monitor-config.h"
|
||||
|
||||
#include <string.h>
|
||||
@ -67,6 +68,7 @@ typedef struct {
|
||||
} MetaOutputConfig;
|
||||
|
||||
typedef struct {
|
||||
guint refcount;
|
||||
MetaOutputKey *keys;
|
||||
MetaOutputConfig *outputs;
|
||||
unsigned int n_outputs;
|
||||
@ -77,7 +79,6 @@ struct _MetaMonitorConfig {
|
||||
|
||||
GHashTable *configs;
|
||||
MetaConfiguration *current;
|
||||
gboolean current_is_stored;
|
||||
gboolean current_is_for_laptop_lid;
|
||||
MetaConfiguration *previous;
|
||||
|
||||
@ -124,11 +125,29 @@ config_clear (MetaConfiguration *config)
|
||||
g_free (config->outputs);
|
||||
}
|
||||
|
||||
static void
|
||||
config_free (gpointer config)
|
||||
static MetaConfiguration *
|
||||
config_ref (MetaConfiguration *config)
|
||||
{
|
||||
config_clear (config);
|
||||
g_slice_free (MetaConfiguration, config);
|
||||
config->refcount++;
|
||||
return config;
|
||||
}
|
||||
|
||||
static void
|
||||
config_unref (MetaConfiguration *config)
|
||||
{
|
||||
if (--config->refcount == 0)
|
||||
{
|
||||
config_clear (config);
|
||||
g_slice_free (MetaConfiguration, config);
|
||||
}
|
||||
}
|
||||
|
||||
static MetaConfiguration *
|
||||
config_new (void)
|
||||
{
|
||||
MetaConfiguration *config = g_slice_new0 (MetaConfiguration);
|
||||
config->refcount = 1;
|
||||
return config;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
@ -220,7 +239,7 @@ meta_monitor_config_init (MetaMonitorConfig *self)
|
||||
const char *filename;
|
||||
char *path;
|
||||
|
||||
self->configs = g_hash_table_new_full (config_hash, config_equal, NULL, config_free);
|
||||
self->configs = g_hash_table_new_full (config_hash, config_equal, NULL, (GDestroyNotify) config_unref);
|
||||
|
||||
filename = g_getenv ("MUTTER_MONITOR_FILENAME");
|
||||
if (filename == NULL)
|
||||
@ -796,27 +815,6 @@ make_config_key (MetaConfiguration *key,
|
||||
key->n_outputs = o;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_config_match_current (MetaMonitorConfig *self,
|
||||
MetaMonitorManager *manager)
|
||||
{
|
||||
MetaOutput *outputs;
|
||||
unsigned n_outputs;
|
||||
MetaConfiguration key;
|
||||
gboolean ok;
|
||||
|
||||
if (self->current == NULL)
|
||||
return FALSE;
|
||||
|
||||
outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
|
||||
|
||||
make_config_key (&key, outputs, n_outputs, -1);
|
||||
ok = config_equal (&key, self->current);
|
||||
|
||||
config_clear (&key);
|
||||
return ok;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -851,73 +849,45 @@ meta_monitor_config_get_stored (MetaMonitorConfig *self,
|
||||
return stored;
|
||||
}
|
||||
|
||||
static void
|
||||
set_current (MetaMonitorConfig *self,
|
||||
MetaConfiguration *config)
|
||||
{
|
||||
g_clear_pointer (&self->previous, (GDestroyNotify) config_unref);
|
||||
self->previous = self->current;
|
||||
self->current = config_ref (config);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
apply_configuration (MetaMonitorConfig *self,
|
||||
MetaConfiguration *config,
|
||||
MetaMonitorManager *manager,
|
||||
gboolean stored)
|
||||
MetaMonitorManager *manager)
|
||||
{
|
||||
GPtrArray *crtcs, *outputs;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
crtcs = g_ptr_array_new_full (config->n_outputs, (GDestroyNotify)meta_crtc_info_free);
|
||||
outputs = g_ptr_array_new_full (config->n_outputs, (GDestroyNotify)meta_output_info_free);
|
||||
|
||||
if (!meta_monitor_config_assign_crtcs (config, manager, crtcs, outputs))
|
||||
{
|
||||
g_ptr_array_unref (crtcs);
|
||||
g_ptr_array_unref (outputs);
|
||||
if (!stored)
|
||||
config_free (config);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
goto out;
|
||||
|
||||
meta_monitor_manager_apply_configuration (manager,
|
||||
(MetaCRTCInfo**)crtcs->pdata, crtcs->len,
|
||||
(MetaOutputInfo**)outputs->pdata, outputs->len);
|
||||
|
||||
/* Stored (persistent) configurations override the previous one always.
|
||||
Also, we clear the previous configuration if the current one (which is
|
||||
about to become previous) is stored, or if the current one has
|
||||
different outputs.
|
||||
*/
|
||||
if (stored ||
|
||||
(self->current && self->current_is_stored))
|
||||
{
|
||||
if (self->previous)
|
||||
config_free (self->previous);
|
||||
self->previous = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Despite the name, config_equal() only checks the set of outputs,
|
||||
not their modes
|
||||
*/
|
||||
if (self->current && config_equal (self->current, config))
|
||||
{
|
||||
self->previous = self->current;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->current)
|
||||
config_free (self->current);
|
||||
self->previous = NULL;
|
||||
}
|
||||
}
|
||||
set_current (self, config);
|
||||
|
||||
self->current = config;
|
||||
self->current_is_stored = stored;
|
||||
/* If true, we'll be overridden at the end of this call
|
||||
inside turn_off_laptop_display()
|
||||
*/
|
||||
* inside turn_off_laptop_display / apply_configuration_with_lid */
|
||||
self->current_is_for_laptop_lid = FALSE;
|
||||
|
||||
if (self->current == self->previous)
|
||||
self->previous = NULL;
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
g_ptr_array_unref (crtcs);
|
||||
g_ptr_array_unref (outputs);
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -928,6 +898,20 @@ key_is_laptop (MetaOutputKey *key)
|
||||
g_str_has_prefix (key->connector, "eDP");
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_is_laptop (MetaOutput *output)
|
||||
{
|
||||
/* FIXME: extend with better heuristics */
|
||||
switch (output->connector_type)
|
||||
{
|
||||
case META_CONNECTOR_TYPE_eDP:
|
||||
case META_CONNECTOR_TYPE_LVDS:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
laptop_display_is_on (MetaConfiguration *config)
|
||||
{
|
||||
@ -945,6 +929,19 @@ laptop_display_is_on (MetaConfiguration *config)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
multiple_outputs_are_enabled (MetaConfiguration *config)
|
||||
{
|
||||
unsigned int i, enabled;
|
||||
|
||||
enabled = 0;
|
||||
for (i = 0; i < config->n_outputs; i++)
|
||||
if (config->outputs[i].enabled)
|
||||
enabled++;
|
||||
|
||||
return enabled > 1;
|
||||
}
|
||||
|
||||
static MetaConfiguration *
|
||||
make_laptop_lid_config (MetaConfiguration *reference)
|
||||
{
|
||||
@ -954,9 +951,9 @@ make_laptop_lid_config (MetaConfiguration *reference)
|
||||
int x_after, y_after;
|
||||
int x_offset, y_offset;
|
||||
|
||||
g_assert (reference->n_outputs > 1);
|
||||
g_assert (multiple_outputs_are_enabled (reference));
|
||||
|
||||
new = g_slice_new0 (MetaConfiguration);
|
||||
new = config_new ();
|
||||
new->n_outputs = reference->n_outputs;
|
||||
new->keys = g_new0 (MetaOutputKey, reference->n_outputs);
|
||||
new->outputs = g_new0 (MetaOutputConfig, reference->n_outputs);
|
||||
@ -973,8 +970,7 @@ make_laptop_lid_config (MetaConfiguration *reference)
|
||||
new->keys[i].product = g_strdup (current_key->product);
|
||||
new->keys[i].serial = g_strdup (current_key->serial);
|
||||
|
||||
if (g_str_has_prefix (current_key->connector, "LVDS") ||
|
||||
g_str_has_prefix (current_key->connector, "eDP"))
|
||||
if (key_is_laptop (current_key))
|
||||
{
|
||||
new->outputs[i].enabled = FALSE;
|
||||
x_after = current_output->rect.x;
|
||||
@ -1011,6 +1007,32 @@ make_laptop_lid_config (MetaConfiguration *reference)
|
||||
return new;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
apply_configuration_with_lid (MetaMonitorConfig *self,
|
||||
MetaConfiguration *config,
|
||||
MetaMonitorManager *manager)
|
||||
{
|
||||
if (self->lid_is_closed &&
|
||||
multiple_outputs_are_enabled (config) &&
|
||||
laptop_display_is_on (config))
|
||||
{
|
||||
MetaConfiguration *laptop_lid_config = make_laptop_lid_config (config);
|
||||
if (apply_configuration (self, laptop_lid_config, manager))
|
||||
{
|
||||
self->current_is_for_laptop_lid = TRUE;
|
||||
config_unref (laptop_lid_config);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
config_unref (laptop_lid_config);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
return apply_configuration (self, config, manager);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_config_apply_stored (MetaMonitorConfig *self,
|
||||
MetaMonitorManager *manager)
|
||||
@ -1023,23 +1045,7 @@ meta_monitor_config_apply_stored (MetaMonitorConfig *self,
|
||||
stored = meta_monitor_config_get_stored (self, outputs, n_outputs);
|
||||
|
||||
if (stored)
|
||||
{
|
||||
if (self->lid_is_closed &&
|
||||
stored->n_outputs > 1 &&
|
||||
laptop_display_is_on (stored))
|
||||
{
|
||||
if (apply_configuration (self, make_laptop_lid_config (stored),
|
||||
manager, FALSE))
|
||||
{
|
||||
self->current_is_for_laptop_lid = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return apply_configuration (self, stored, manager, TRUE);
|
||||
}
|
||||
return apply_configuration_with_lid (self, stored, manager);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
@ -1068,8 +1074,7 @@ find_primary_output (MetaOutput *outputs,
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
if (g_str_has_prefix (outputs[i].name, "LVDS") ||
|
||||
g_str_has_prefix (outputs[i].name, "eDP"))
|
||||
if (output_is_laptop (&outputs[i]))
|
||||
return &outputs[i];
|
||||
}
|
||||
|
||||
@ -1089,47 +1094,123 @@ find_primary_output (MetaOutput *outputs,
|
||||
return best;
|
||||
}
|
||||
|
||||
static MetaConfiguration *
|
||||
make_default_config (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
int max_width,
|
||||
int max_height)
|
||||
static void
|
||||
init_config_from_preferred_mode (MetaOutputConfig *config,
|
||||
MetaOutput *output)
|
||||
{
|
||||
unsigned i, j;
|
||||
int x, y;
|
||||
MetaConfiguration *ret;
|
||||
config->enabled = TRUE;
|
||||
config->rect.x = 0;
|
||||
config->rect.y = 0;
|
||||
config->rect.width = output->preferred_mode->width;
|
||||
config->rect.height = output->preferred_mode->height;
|
||||
config->refresh_rate = output->preferred_mode->refresh_rate;
|
||||
config->transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
config->is_primary = FALSE;
|
||||
config->is_presentation = FALSE;
|
||||
}
|
||||
|
||||
/* This function handles configuring the outputs when the driver provides a
|
||||
* suggested layout position for each output. This is done in recent versions
|
||||
* of qxl and allows displays to be aligned on the guest in the same order as
|
||||
* they are aligned on the client.
|
||||
*/
|
||||
static gboolean
|
||||
make_suggested_config (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
int max_width,
|
||||
int max_height,
|
||||
MetaConfiguration *config)
|
||||
{
|
||||
unsigned int i;
|
||||
MetaOutput *primary;
|
||||
GList *region = NULL;
|
||||
|
||||
ret = g_slice_new (MetaConfiguration);
|
||||
make_config_key (ret, outputs, n_outputs, -1);
|
||||
ret->outputs = g_new0 (MetaOutputConfig, n_outputs);
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
primary = find_primary_output (outputs, n_outputs);
|
||||
|
||||
/* Special case the simple case: one output, primary at preferred mode,
|
||||
nothing else to do */
|
||||
if (n_outputs == 1)
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
ret->outputs[0].enabled = TRUE;
|
||||
ret->outputs[0].rect.x = 0;
|
||||
ret->outputs[0].rect.y = 0;
|
||||
ret->outputs[0].rect.width = outputs[0].preferred_mode->width;
|
||||
ret->outputs[0].rect.height = outputs[0].preferred_mode->height;
|
||||
ret->outputs[0].refresh_rate = outputs[0].preferred_mode->refresh_rate;
|
||||
ret->outputs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[0].is_primary = TRUE;
|
||||
gboolean is_primary = (&outputs[i] == primary);
|
||||
|
||||
return ret;
|
||||
if (outputs[i].suggested_x < 0 || outputs[i].suggested_y < 0)
|
||||
return FALSE;
|
||||
|
||||
init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
|
||||
config->outputs[i].is_primary = is_primary;
|
||||
|
||||
config->outputs[i].rect.x = outputs[i].suggested_x;
|
||||
config->outputs[i].rect.y = outputs[i].suggested_y;
|
||||
|
||||
/* Reject the configuration if the suggested positions result in
|
||||
* overlapping displays */
|
||||
if (meta_rectangle_overlaps_with_region (region, &config->outputs[i].rect))
|
||||
{
|
||||
g_warning ("Overlapping outputs, rejecting suggested configuration");
|
||||
g_list_free (region);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
region = g_list_prepend (region, &config->outputs[i].rect);
|
||||
}
|
||||
|
||||
/* If we reach this point, this is either the first time mutter runs
|
||||
on this system ever, or we just hotplugged a new screen.
|
||||
In the latter case, search for a configuration that includes one
|
||||
less screen, then add the new one as a presentation screen
|
||||
in preferred mode.
|
||||
g_list_free (region);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
XXX: but presentation mode is not implemented in the control-center
|
||||
or in mutter core, so let's do extended for now.
|
||||
static void
|
||||
make_linear_config (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
int max_width,
|
||||
int max_height,
|
||||
MetaConfiguration *config)
|
||||
{
|
||||
MetaOutput *primary;
|
||||
unsigned i;
|
||||
int x;
|
||||
|
||||
g_return_if_fail (config != NULL);
|
||||
|
||||
primary = find_primary_output (outputs, n_outputs);
|
||||
|
||||
x = primary->preferred_mode->width;
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
gboolean is_primary = (&outputs[i] == primary);
|
||||
|
||||
init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
|
||||
config->outputs[i].is_primary = is_primary;
|
||||
|
||||
if (is_primary)
|
||||
{
|
||||
config->outputs[i].rect.x = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
config->outputs[i].rect.x = x;
|
||||
x += config->outputs[i].rect.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Search for a configuration that includes one less screen, then add the new
|
||||
* one as a presentation screen in preferred mode.
|
||||
*
|
||||
* XXX: but presentation mode is not implemented in the control-center or in
|
||||
* mutter core, so let's do extended for now.
|
||||
*/
|
||||
static gboolean
|
||||
extend_stored_config (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
int max_width,
|
||||
int max_height,
|
||||
MetaConfiguration *config)
|
||||
{
|
||||
int x, y;
|
||||
unsigned i, j;
|
||||
|
||||
x = 0;
|
||||
y = 0;
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
@ -1147,69 +1228,80 @@ make_default_config (MetaMonitorConfig *self,
|
||||
{
|
||||
if (j < i)
|
||||
{
|
||||
g_assert (output_key_equal (&ret->keys[j], &ref->keys[j]));
|
||||
ret->outputs[j] = ref->outputs[j];
|
||||
g_assert (output_key_equal (&config->keys[j], &ref->keys[j]));
|
||||
config->outputs[j] = ref->outputs[j];
|
||||
x = MAX (x, ref->outputs[j].rect.x + ref->outputs[j].rect.width);
|
||||
y = MAX (y, ref->outputs[j].rect.y + ref->outputs[j].rect.height);
|
||||
}
|
||||
else if (j > i)
|
||||
{
|
||||
g_assert (output_key_equal (&ret->keys[j], &ref->keys[j - 1]));
|
||||
ret->outputs[j] = ref->outputs[j - 1];
|
||||
g_assert (output_key_equal (&config->keys[j], &ref->keys[j - 1]));
|
||||
config->outputs[j] = ref->outputs[j - 1];
|
||||
x = MAX (x, ref->outputs[j - 1].rect.x + ref->outputs[j - 1].rect.width);
|
||||
y = MAX (y, ref->outputs[j - 1].rect.y + ref->outputs[j - 1].rect.height);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret->outputs[j].enabled = TRUE;
|
||||
ret->outputs[j].rect.x = 0;
|
||||
ret->outputs[j].rect.y = 0;
|
||||
ret->outputs[j].rect.width = outputs[0].preferred_mode->width;
|
||||
ret->outputs[j].rect.height = outputs[0].preferred_mode->height;
|
||||
ret->outputs[j].refresh_rate = outputs[0].preferred_mode->refresh_rate;
|
||||
ret->outputs[j].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[j].is_primary = FALSE;
|
||||
ret->outputs[j].is_presentation = FALSE;
|
||||
init_config_from_preferred_mode (&config->outputs[j], &outputs[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Place the new output at the right end of the screen, if it fits,
|
||||
otherwise below it, otherwise disable it (or apply_configuration will fail) */
|
||||
if (x + ret->outputs[i].rect.width <= max_width)
|
||||
ret->outputs[i].rect.x = x;
|
||||
else if (y + ret->outputs[i].rect.height <= max_height)
|
||||
ret->outputs[i].rect.y = y;
|
||||
if (x + config->outputs[i].rect.width <= max_width)
|
||||
config->outputs[i].rect.x = x;
|
||||
else if (y + config->outputs[i].rect.height <= max_height)
|
||||
config->outputs[i].rect.y = y;
|
||||
else
|
||||
ret->outputs[i].enabled = FALSE;
|
||||
config->outputs[i].enabled = FALSE;
|
||||
|
||||
return ret;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* No previous configuration found, try with a really default one, which
|
||||
is one primary that goes first and the rest to the right of it, extended.
|
||||
*/
|
||||
primary = find_primary_output (outputs, n_outputs);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
x = primary->preferred_mode->width;
|
||||
static MetaConfiguration *
|
||||
make_default_config (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs,
|
||||
int max_width,
|
||||
int max_height,
|
||||
gboolean use_stored_config)
|
||||
{
|
||||
MetaConfiguration *ret = NULL;
|
||||
unsigned i;
|
||||
|
||||
ret = config_new ();
|
||||
make_config_key (ret, outputs, n_outputs, -1);
|
||||
ret->outputs = g_new0 (MetaOutputConfig, n_outputs);
|
||||
|
||||
/* Special case the simple case: one output, primary at preferred mode,
|
||||
nothing else to do */
|
||||
if (n_outputs == 1)
|
||||
{
|
||||
init_config_from_preferred_mode (&ret->outputs[0], &outputs[0]);
|
||||
ret->outputs[0].is_primary = TRUE;
|
||||
goto check_limits;
|
||||
}
|
||||
|
||||
if (make_suggested_config (self, outputs, n_outputs, max_width, max_height, ret))
|
||||
goto check_limits;
|
||||
|
||||
if (use_stored_config &&
|
||||
extend_stored_config (self, outputs, n_outputs, max_width, max_height, ret))
|
||||
goto check_limits;
|
||||
|
||||
make_linear_config (self, outputs, n_outputs, max_width, max_height, ret);
|
||||
|
||||
check_limits:
|
||||
/* Disable outputs that would go beyond framebuffer limits */
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
MetaOutput *output = &outputs[i];
|
||||
|
||||
ret->outputs[i].enabled = TRUE;
|
||||
ret->outputs[i].rect.x = (output == primary) ? 0 : x;
|
||||
ret->outputs[i].rect.y = 0;
|
||||
ret->outputs[i].rect.width = output->preferred_mode->width;
|
||||
ret->outputs[i].rect.height = output->preferred_mode->height;
|
||||
ret->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
|
||||
ret->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].is_primary = (output == primary);
|
||||
|
||||
/* Disable outputs that would go beyond framebuffer limits */
|
||||
if (ret->outputs[i].rect.x + ret->outputs[i].rect.width > max_width)
|
||||
ret->outputs[i].enabled = FALSE;
|
||||
else if (output != primary)
|
||||
x += output->preferred_mode->width;
|
||||
if ((ret->outputs[i].rect.x + ret->outputs[i].rect.width > max_width)
|
||||
|| (ret->outputs[i].rect.y + ret->outputs[i].rect.height > max_height))
|
||||
ret->outputs[i].enabled = FALSE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1221,7 +1313,7 @@ ensure_at_least_one_output (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs,
|
||||
unsigned n_outputs)
|
||||
{
|
||||
MetaConfiguration *ret;
|
||||
MetaConfiguration *config;
|
||||
MetaOutput *primary;
|
||||
unsigned i;
|
||||
|
||||
@ -1232,34 +1324,29 @@ ensure_at_least_one_output (MetaMonitorConfig *self,
|
||||
|
||||
/* Oh no, we don't! Activate the primary one and disable everything else */
|
||||
|
||||
ret = g_slice_new (MetaConfiguration);
|
||||
make_config_key (ret, outputs, n_outputs, -1);
|
||||
ret->outputs = g_new0 (MetaOutputConfig, n_outputs);
|
||||
config = config_new ();
|
||||
make_config_key (config, outputs, n_outputs, -1);
|
||||
config->outputs = g_new0 (MetaOutputConfig, n_outputs);
|
||||
|
||||
primary = find_primary_output (outputs, n_outputs);
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
MetaOutput *output = &outputs[i];
|
||||
gboolean is_primary = (&outputs[i] == primary);
|
||||
|
||||
if (output == primary)
|
||||
if (is_primary)
|
||||
{
|
||||
ret->outputs[i].enabled = TRUE;
|
||||
ret->outputs[i].rect.x = 0;
|
||||
ret->outputs[i].rect.y = 0;
|
||||
ret->outputs[i].rect.width = output->preferred_mode->width;
|
||||
ret->outputs[i].rect.height = output->preferred_mode->height;
|
||||
ret->outputs[i].refresh_rate = output->preferred_mode->refresh_rate;
|
||||
ret->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].is_primary = TRUE;
|
||||
init_config_from_preferred_mode (&config->outputs[i], &outputs[0]);
|
||||
config->outputs[i].is_primary = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret->outputs[i].enabled = FALSE;
|
||||
config->outputs[i].enabled = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
apply_configuration (self, ret, manager, FALSE);
|
||||
apply_configuration (self, config, manager);
|
||||
config_unref (config);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1270,8 +1357,9 @@ meta_monitor_config_make_default (MetaMonitorConfig *self,
|
||||
MetaOutput *outputs;
|
||||
MetaConfiguration *default_config;
|
||||
unsigned n_outputs;
|
||||
gboolean ok;
|
||||
gboolean ok = FALSE;
|
||||
int max_width, max_height;
|
||||
gboolean use_stored_config;
|
||||
|
||||
outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
|
||||
meta_monitor_manager_get_screen_limits (manager, &max_width, &max_height);
|
||||
@ -1282,23 +1370,21 @@ meta_monitor_config_make_default (MetaMonitorConfig *self,
|
||||
return;
|
||||
}
|
||||
|
||||
default_config = make_default_config (self, outputs, n_outputs, max_width, max_height);
|
||||
/* if the device has hotplug_mode_update, it's possible that the
|
||||
* current display configuration does not match a stored configuration.
|
||||
* Since extend_existing_config() tries to build a configuration that is
|
||||
* based on a previously-stored configuration, it's quite likely that the
|
||||
* resulting config will fail. Even if it doesn't fail, it may result in
|
||||
* an unexpected configuration, so don't attempt to use a stored config
|
||||
* in this situation. */
|
||||
use_stored_config = !meta_monitor_manager_has_hotplug_mode_update (manager);
|
||||
default_config = make_default_config (self, outputs, n_outputs, max_width, max_height, use_stored_config);
|
||||
|
||||
if (default_config != NULL)
|
||||
{
|
||||
if (self->lid_is_closed &&
|
||||
default_config->n_outputs > 1 &&
|
||||
laptop_display_is_on (default_config))
|
||||
{
|
||||
ok = apply_configuration (self, make_laptop_lid_config (default_config),
|
||||
manager, FALSE);
|
||||
config_free (default_config);
|
||||
}
|
||||
else
|
||||
ok = apply_configuration (self, default_config, manager, FALSE);
|
||||
ok = apply_configuration_with_lid (self, default_config, manager);
|
||||
config_unref (default_config);
|
||||
}
|
||||
else
|
||||
ok = FALSE;
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
@ -1335,7 +1421,7 @@ meta_monitor_config_update_current (MetaMonitorConfig *self,
|
||||
|
||||
outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
|
||||
|
||||
current = g_slice_new (MetaConfiguration);
|
||||
current = config_new ();
|
||||
current->n_outputs = n_outputs;
|
||||
current->outputs = g_new0 (MetaOutputConfig, n_outputs);
|
||||
current->keys = g_new0 (MetaOutputKey, n_outputs);
|
||||
@ -1348,15 +1434,11 @@ meta_monitor_config_update_current (MetaMonitorConfig *self,
|
||||
|
||||
if (self->current && config_equal_full (current, self->current))
|
||||
{
|
||||
config_free (current);
|
||||
config_unref (current);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->current && !self->current_is_stored)
|
||||
config_free (self->current);
|
||||
|
||||
self->current = current;
|
||||
self->current_is_stored = FALSE;
|
||||
set_current (self, current);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1364,7 +1446,17 @@ meta_monitor_config_restore_previous (MetaMonitorConfig *self,
|
||||
MetaMonitorManager *manager)
|
||||
{
|
||||
if (self->previous)
|
||||
apply_configuration (self, self->previous, manager, FALSE);
|
||||
{
|
||||
/* The user chose to restore the previous configuration. In this
|
||||
* case, restore the previous configuration. */
|
||||
MetaConfiguration *prev_config = config_ref (self->previous);
|
||||
apply_configuration (self, prev_config, manager);
|
||||
config_unref (prev_config);
|
||||
|
||||
/* After this, self->previous contains the rejected configuration.
|
||||
* Since it was rejected, nuke it. */
|
||||
g_clear_pointer (&self->previous, (GDestroyNotify) config_unref);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!meta_monitor_config_apply_stored (self, manager))
|
||||
@ -1378,11 +1470,12 @@ turn_off_laptop_display (MetaMonitorConfig *self,
|
||||
{
|
||||
MetaConfiguration *new;
|
||||
|
||||
if (self->current->n_outputs == 1)
|
||||
if (!multiple_outputs_are_enabled (self->current))
|
||||
return;
|
||||
|
||||
new = make_laptop_lid_config (self->current);
|
||||
apply_configuration (self, new, manager, FALSE);
|
||||
apply_configuration (self, new, manager);
|
||||
config_unref (new);
|
||||
self->current_is_for_laptop_lid = TRUE;
|
||||
}
|
||||
|
||||
@ -1541,16 +1634,7 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
||||
void
|
||||
meta_monitor_config_make_persistent (MetaMonitorConfig *self)
|
||||
{
|
||||
if (self->current_is_stored)
|
||||
return;
|
||||
|
||||
self->current_is_stored = TRUE;
|
||||
g_hash_table_replace (self->configs, self->current, self->current);
|
||||
|
||||
if (self->previous)
|
||||
config_free (self->previous);
|
||||
self->previous = NULL;
|
||||
|
||||
g_hash_table_replace (self->configs, self->current, config_ref (self->current));
|
||||
meta_monitor_config_save (self);
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef META_MONITOR_CONFIG_H
|
||||
#define META_MONITOR_CONFIG_H
|
||||
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#define META_TYPE_MONITOR_CONFIG (meta_monitor_config_get_type ())
|
||||
#define META_MONITOR_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_CONFIG, MetaMonitorConfig))
|
||||
@ -36,9 +36,6 @@ GType meta_monitor_config_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaMonitorConfig *meta_monitor_config_new (void);
|
||||
|
||||
gboolean meta_monitor_config_match_current (MetaMonitorConfig *config,
|
||||
MetaMonitorManager *manager);
|
||||
|
||||
gboolean meta_monitor_config_apply_stored (MetaMonitorConfig *config,
|
||||
MetaMonitorManager *manager);
|
||||
|
||||
|
@ -95,6 +95,8 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
|
||||
manager->outputs[0].backlight = -1;
|
||||
manager->outputs[0].backlight_min = 0;
|
||||
manager->outputs[0].backlight_max = 0;
|
||||
manager->outputs[0].connector_type = META_CONNECTOR_TYPE_LVDS;
|
||||
manager->outputs[0].scale = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef META_MONITOR_MANAGER_DUMMY_H
|
||||
#define META_MONITOR_MANAGER_DUMMY_H
|
||||
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#define META_TYPE_MONITOR_MANAGER_DUMMY (meta_monitor_manager_dummy_get_type ())
|
||||
#define META_MONITOR_MANAGER_DUMMY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_DUMMY, MetaMonitorManagerDummy))
|
||||
|
@ -41,18 +41,17 @@
|
||||
#include "display-private.h"
|
||||
#include <meta/screen.h>
|
||||
#include "stack-tracker.h"
|
||||
#include <meta/meta-monitor-manager.h>
|
||||
|
||||
#include "meta-display-config-shared.h"
|
||||
#include "meta-dbus-display-config.h"
|
||||
#include "meta-cursor.h"
|
||||
|
||||
typedef struct _MetaMonitorManagerClass MetaMonitorManagerClass;
|
||||
typedef struct _MetaMonitorManager MetaMonitorManager;
|
||||
typedef struct _MetaMonitorConfigClass MetaMonitorConfigClass;
|
||||
typedef struct _MetaMonitorConfig MetaMonitorConfig;
|
||||
|
||||
typedef struct _MetaOutput MetaOutput;
|
||||
typedef struct _MetaCRTC MetaCRTC;
|
||||
typedef struct _MetaOutput MetaOutput;
|
||||
typedef struct _MetaMonitorMode MetaMonitorMode;
|
||||
typedef struct _MetaMonitorInfo MetaMonitorInfo;
|
||||
typedef struct _MetaCRTCInfo MetaCRTCInfo;
|
||||
@ -69,6 +68,27 @@ typedef enum {
|
||||
META_MONITOR_TRANSFORM_FLIPPED_270,
|
||||
} MetaMonitorTransform;
|
||||
|
||||
/* This matches the values in drm_mode.h */
|
||||
typedef enum {
|
||||
META_CONNECTOR_TYPE_Unknown = 0,
|
||||
META_CONNECTOR_TYPE_VGA = 1,
|
||||
META_CONNECTOR_TYPE_DVII = 2,
|
||||
META_CONNECTOR_TYPE_DVID = 3,
|
||||
META_CONNECTOR_TYPE_DVIA = 4,
|
||||
META_CONNECTOR_TYPE_Composite = 5,
|
||||
META_CONNECTOR_TYPE_SVIDEO = 6,
|
||||
META_CONNECTOR_TYPE_LVDS = 7,
|
||||
META_CONNECTOR_TYPE_Component = 8,
|
||||
META_CONNECTOR_TYPE_9PinDIN = 9,
|
||||
META_CONNECTOR_TYPE_DisplayPort = 10,
|
||||
META_CONNECTOR_TYPE_HDMIA = 11,
|
||||
META_CONNECTOR_TYPE_HDMIB = 12,
|
||||
META_CONNECTOR_TYPE_TV = 13,
|
||||
META_CONNECTOR_TYPE_eDP = 14,
|
||||
META_CONNECTOR_TYPE_VIRTUAL = 15,
|
||||
META_CONNECTOR_TYPE_DSI = 16,
|
||||
} MetaConnectorType;
|
||||
|
||||
struct _MetaOutput
|
||||
{
|
||||
/* The CRTC driving this output, NULL if the output is not enabled */
|
||||
@ -84,6 +104,8 @@ struct _MetaOutput
|
||||
CoglSubpixelOrder subpixel_order;
|
||||
int scale;
|
||||
|
||||
MetaConnectorType connector_type;
|
||||
|
||||
MetaMonitorMode *preferred_mode;
|
||||
MetaMonitorMode **modes;
|
||||
unsigned int n_modes;
|
||||
@ -116,6 +138,8 @@ struct _MetaOutput
|
||||
|
||||
/* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
|
||||
gboolean hotplug_mode_update;
|
||||
gint suggested_x;
|
||||
gint suggested_y;
|
||||
};
|
||||
|
||||
struct _MetaCRTC
|
||||
@ -297,10 +321,6 @@ struct _MetaMonitorManagerClass
|
||||
unsigned short *);
|
||||
};
|
||||
|
||||
GType meta_monitor_manager_get_type (void);
|
||||
|
||||
MetaMonitorManager *meta_monitor_manager_get (void);
|
||||
|
||||
void meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager);
|
||||
|
||||
MetaMonitorInfo *meta_monitor_manager_get_monitor_infos (MetaMonitorManager *manager,
|
||||
@ -336,14 +356,19 @@ void meta_monitor_manager_apply_configuration (MetaMonitorManager
|
||||
void meta_monitor_manager_confirm_configuration (MetaMonitorManager *manager,
|
||||
gboolean ok);
|
||||
|
||||
void meta_output_parse_edid (MetaOutput *output,
|
||||
GBytes *edid);
|
||||
|
||||
void meta_crtc_info_free (MetaCRTCInfo *info);
|
||||
void meta_output_info_free (MetaOutputInfo *info);
|
||||
|
||||
void meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
||||
int n_old_outputs);
|
||||
void meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
|
||||
int n_old_modes);
|
||||
gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager);
|
||||
void meta_monitor_manager_read_current_config (MetaMonitorManager *manager);
|
||||
void meta_monitor_manager_on_hotplug (MetaMonitorManager *manager);
|
||||
|
||||
gboolean meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
|
||||
MetaOutput *output,
|
||||
gfloat matrix[6]);
|
||||
|
||||
/* Returns true if transform causes width and height to be inverted
|
||||
This is true for the odd transforms in the enum */
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
@ -35,6 +35,7 @@
|
||||
#include <meta/main.h>
|
||||
#include "util-private.h"
|
||||
#include <meta/errors.h>
|
||||
#include "edid.h"
|
||||
#include "meta-monitor-config.h"
|
||||
#include "backends/x11/meta-monitor-manager-xrandr.h"
|
||||
#include "meta-backend-private.h"
|
||||
@ -44,10 +45,16 @@ enum {
|
||||
SIGNALS_LAST
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_POWER_SAVE_MODE,
|
||||
PROP_LAST
|
||||
/* Array index matches MetaMonitorTransform */
|
||||
static gfloat transform_matrices[][6] = {
|
||||
{ 1, 0, 0, 0, 1, 0 }, /* normal */
|
||||
{ 0, -1, 1, 1, 0, 0 }, /* 90° */
|
||||
{ -1, 0, 1, 0, -1, 1 }, /* 180° */
|
||||
{ 0, 1, 0, -1, 0, 1 }, /* 270° */
|
||||
{ -1, 0, 1, 0, 1, 0 }, /* normal flipped */
|
||||
{ 0, 1, 0, 1, 0, 0 }, /* 90° flipped */
|
||||
{ 1, 0, 0, 0, -1, 1 }, /* 180° flipped */
|
||||
{ 0, -1, 1, -1, 0, 1 }, /* 270° flipped */
|
||||
};
|
||||
|
||||
static int signals[SIGNALS_LAST];
|
||||
@ -64,14 +71,6 @@ meta_monitor_manager_init (MetaMonitorManager *manager)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
read_current_config (MetaMonitorManager *manager)
|
||||
{
|
||||
manager->serial++;
|
||||
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
|
||||
}
|
||||
|
||||
/*
|
||||
* make_logical_config:
|
||||
*
|
||||
@ -167,16 +166,44 @@ make_logical_config (MetaMonitorManager *manager)
|
||||
manager->monitor_infos = (void*)g_array_free (monitor_infos, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
power_save_mode_changed (MetaMonitorManager *manager,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaMonitorManagerClass *klass;
|
||||
int mode = meta_dbus_display_config_get_power_save_mode (META_DBUS_DISPLAY_CONFIG (manager));
|
||||
|
||||
if (mode == META_POWER_SAVE_UNSUPPORTED)
|
||||
return;
|
||||
|
||||
/* If DPMS is unsupported, force the property back. */
|
||||
if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED)
|
||||
{
|
||||
meta_dbus_display_config_set_power_save_mode (META_DBUS_DISPLAY_CONFIG (manager), META_POWER_SAVE_UNSUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
klass = META_MONITOR_MANAGER_GET_CLASS (manager);
|
||||
if (klass->set_power_save_mode)
|
||||
klass->set_power_save_mode (manager, mode);
|
||||
|
||||
manager->power_save_mode = mode;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_constructed (GObject *object)
|
||||
{
|
||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
|
||||
|
||||
g_signal_connect_object (manager, "notify::power-save-mode",
|
||||
G_CALLBACK (power_save_mode_changed), manager, 0);
|
||||
|
||||
manager->in_init = TRUE;
|
||||
|
||||
manager->config = meta_monitor_config_new ();
|
||||
|
||||
read_current_config (manager);
|
||||
meta_monitor_manager_read_current_config (manager);
|
||||
|
||||
if (!meta_monitor_config_apply_stored (manager->config, manager))
|
||||
meta_monitor_config_make_default (manager->config, manager);
|
||||
@ -189,24 +216,7 @@ meta_monitor_manager_constructed (GObject *object)
|
||||
so this is not needed.
|
||||
*/
|
||||
if (META_IS_MONITOR_MANAGER_XRANDR (manager))
|
||||
{
|
||||
MetaOutput *old_outputs;
|
||||
MetaCRTC *old_crtcs;
|
||||
MetaMonitorMode *old_modes;
|
||||
unsigned int n_old_outputs, n_old_modes;
|
||||
|
||||
old_outputs = manager->outputs;
|
||||
n_old_outputs = manager->n_outputs;
|
||||
old_modes = manager->modes;
|
||||
n_old_modes = manager->n_modes;
|
||||
old_crtcs = manager->crtcs;
|
||||
|
||||
read_current_config (manager);
|
||||
|
||||
meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
|
||||
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
|
||||
g_free (old_crtcs);
|
||||
}
|
||||
meta_monitor_manager_read_current_config (manager);
|
||||
|
||||
make_logical_config (manager);
|
||||
initialize_dbus_interface (manager);
|
||||
@ -215,23 +225,6 @@ meta_monitor_manager_constructed (GObject *object)
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_set_power_save_mode (MetaMonitorManager *manager,
|
||||
MetaPowerSave mode)
|
||||
{
|
||||
MetaMonitorManagerClass *klass;
|
||||
|
||||
if (manager->power_save_mode == META_POWER_SAVE_UNSUPPORTED ||
|
||||
mode == META_POWER_SAVE_UNSUPPORTED)
|
||||
return;
|
||||
|
||||
klass = META_MONITOR_MANAGER_GET_CLASS (manager);
|
||||
if (klass->set_power_save_mode)
|
||||
klass->set_power_save_mode (manager, mode);
|
||||
|
||||
manager->power_save_mode = mode;
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
||||
int n_old_outputs)
|
||||
{
|
||||
@ -254,7 +247,7 @@ meta_monitor_manager_free_output_array (MetaOutput *old_outputs,
|
||||
g_free (old_outputs);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
|
||||
int n_old_modes)
|
||||
{
|
||||
@ -298,44 +291,6 @@ meta_monitor_manager_dispose (GObject *object)
|
||||
G_OBJECT_CLASS (meta_monitor_manager_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaMonitorManager *self = META_MONITOR_MANAGER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_POWER_SAVE_MODE:
|
||||
meta_monitor_manager_set_power_save_mode (self, g_value_get_int (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaMonitorManager *self = META_MONITOR_MANAGER (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_POWER_SAVE_MODE:
|
||||
g_value_set_int (value, self->power_save_mode);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
meta_monitor_manager_real_read_edid (MetaMonitorManager *manager,
|
||||
MetaOutput *output)
|
||||
@ -356,8 +311,6 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructed = meta_monitor_manager_constructed;
|
||||
object_class->get_property = meta_monitor_manager_get_property;
|
||||
object_class->set_property = meta_monitor_manager_set_property;
|
||||
object_class->dispose = meta_monitor_manager_dispose;
|
||||
object_class->finalize = meta_monitor_manager_finalize;
|
||||
|
||||
@ -371,8 +324,6 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_object_class_override_property (object_class, PROP_POWER_SAVE_MODE, "power-save-mode");
|
||||
}
|
||||
|
||||
static const double known_diagonals[] = {
|
||||
@ -406,11 +357,14 @@ make_display_name (MetaMonitorManager *manager,
|
||||
char *vendor_name = NULL;
|
||||
char *ret;
|
||||
|
||||
if (g_str_has_prefix (output->name, "LVDS") ||
|
||||
g_str_has_prefix (output->name, "eDP"))
|
||||
switch (output->connector_type)
|
||||
{
|
||||
case META_CONNECTOR_TYPE_LVDS:
|
||||
case META_CONNECTOR_TYPE_eDP:
|
||||
ret = g_strdup (_("Built-in display"));
|
||||
goto out;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (output->width_mm > 0 && output->height_mm > 0)
|
||||
@ -458,6 +412,32 @@ make_display_name (MetaMonitorManager *manager,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_connector_type_name (MetaConnectorType connector_type)
|
||||
{
|
||||
switch (connector_type)
|
||||
{
|
||||
case META_CONNECTOR_TYPE_Unknown: return "Unknown";
|
||||
case META_CONNECTOR_TYPE_VGA: return "VGA";
|
||||
case META_CONNECTOR_TYPE_DVII: return "DVII";
|
||||
case META_CONNECTOR_TYPE_DVID: return "DVID";
|
||||
case META_CONNECTOR_TYPE_DVIA: return "DVIA";
|
||||
case META_CONNECTOR_TYPE_Composite: return "Composite";
|
||||
case META_CONNECTOR_TYPE_SVIDEO: return "SVIDEO";
|
||||
case META_CONNECTOR_TYPE_LVDS: return "LVDS";
|
||||
case META_CONNECTOR_TYPE_Component: return "Component";
|
||||
case META_CONNECTOR_TYPE_9PinDIN: return "9PinDIN";
|
||||
case META_CONNECTOR_TYPE_DisplayPort: return "DisplayPort";
|
||||
case META_CONNECTOR_TYPE_HDMIA: return "HDMIA";
|
||||
case META_CONNECTOR_TYPE_HDMIB: return "HDMIB";
|
||||
case META_CONNECTOR_TYPE_TV: return "TV";
|
||||
case META_CONNECTOR_TYPE_eDP: return "eDP";
|
||||
case META_CONNECTOR_TYPE_VIRTUAL: return "VIRTUAL";
|
||||
case META_CONNECTOR_TYPE_DSI: return "DSI";
|
||||
default: g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
GDBusMethodInvocation *invocation)
|
||||
@ -538,6 +518,8 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
g_variant_new_boolean (output->is_primary));
|
||||
g_variant_builder_add (&properties, "{sv}", "presentation",
|
||||
g_variant_new_boolean (output->is_presentation));
|
||||
g_variant_builder_add (&properties, "{sv}", "connector-type",
|
||||
g_variant_new_string (get_connector_type_name (output->connector_type)));
|
||||
|
||||
edid_file = manager_class->get_edid_file (manager, output);
|
||||
if (edid_file)
|
||||
@ -1125,6 +1107,13 @@ initialize_dbus_interface (MetaMonitorManager *manager)
|
||||
g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_monitor_manager_get:
|
||||
*
|
||||
* Accessor for the singleton MetaMonitorManager.
|
||||
*
|
||||
* Returns: (transfer none): The only #MetaMonitorManager there is.
|
||||
*/
|
||||
MetaMonitorManager *
|
||||
meta_monitor_manager_get (void)
|
||||
{
|
||||
@ -1199,6 +1188,31 @@ meta_monitor_manager_get_screen_limits (MetaMonitorManager *manager,
|
||||
*height = manager->max_screen_height;
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_read_current_config (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaOutput *old_outputs;
|
||||
MetaCRTC *old_crtcs;
|
||||
MetaMonitorMode *old_modes;
|
||||
unsigned int n_old_outputs, n_old_modes;
|
||||
|
||||
/* Some implementations of read_current use the existing information
|
||||
* we have available, so don't free the old configuration until after
|
||||
* read_current finishes. */
|
||||
old_outputs = manager->outputs;
|
||||
n_old_outputs = manager->n_outputs;
|
||||
old_modes = manager->modes;
|
||||
n_old_modes = manager->n_modes;
|
||||
old_crtcs = manager->crtcs;
|
||||
|
||||
manager->serial++;
|
||||
META_MONITOR_MANAGER_GET_CLASS (manager)->read_current (manager);
|
||||
|
||||
meta_monitor_manager_free_output_array (old_outputs, n_old_outputs);
|
||||
meta_monitor_manager_free_mode_array (old_modes, n_old_modes);
|
||||
g_free (old_crtcs);
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
|
||||
{
|
||||
@ -1216,3 +1230,141 @@ meta_monitor_manager_rebuild_derived (MetaMonitorManager *manager)
|
||||
g_free (old_monitor_infos);
|
||||
}
|
||||
|
||||
void
|
||||
meta_output_parse_edid (MetaOutput *meta_output,
|
||||
GBytes *edid)
|
||||
{
|
||||
MonitorInfo *parsed_edid;
|
||||
gsize len;
|
||||
|
||||
if (!edid)
|
||||
goto out;
|
||||
|
||||
parsed_edid = decode_edid (g_bytes_get_data (edid, &len));
|
||||
|
||||
if (parsed_edid)
|
||||
{
|
||||
meta_output->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
|
||||
if (parsed_edid->dsc_product_name[0])
|
||||
meta_output->product = g_strndup (parsed_edid->dsc_product_name, 14);
|
||||
else
|
||||
meta_output->product = g_strdup_printf ("0x%04x", (unsigned) parsed_edid->product_code);
|
||||
if (parsed_edid->dsc_serial_number[0])
|
||||
meta_output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
|
||||
else
|
||||
meta_output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
|
||||
|
||||
g_free (parsed_edid);
|
||||
}
|
||||
|
||||
out:
|
||||
if (!meta_output->vendor)
|
||||
{
|
||||
meta_output->vendor = g_strdup ("unknown");
|
||||
meta_output->product = g_strdup ("unknown");
|
||||
meta_output->serial = g_strdup ("unknown");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_monitor_manager_on_hotplug (MetaMonitorManager *manager)
|
||||
{
|
||||
gboolean applied_config = FALSE;
|
||||
|
||||
/* If the monitor has hotplug_mode_update (which is used by VMs), don't bother
|
||||
* applying our stored configuration, because it's likely the user just resizing
|
||||
* the window.
|
||||
*/
|
||||
if (!meta_monitor_manager_has_hotplug_mode_update (manager))
|
||||
{
|
||||
if (meta_monitor_config_apply_stored (manager->config, manager))
|
||||
applied_config = TRUE;
|
||||
}
|
||||
|
||||
/* If we haven't applied any configuration, apply the default configuration. */
|
||||
if (!applied_config)
|
||||
meta_monitor_config_make_default (manager->config, manager);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
calculate_viewport_matrix (MetaMonitorManager *manager,
|
||||
MetaOutput *output,
|
||||
gfloat viewport[6])
|
||||
{
|
||||
gfloat x, y, width, height;
|
||||
|
||||
if (!output->crtc)
|
||||
return FALSE;
|
||||
|
||||
x = (float) output->crtc->rect.x / manager->screen_width;
|
||||
y = (float) output->crtc->rect.y / manager->screen_height;
|
||||
width = (float) output->crtc->rect.width / manager->screen_width;
|
||||
height = (float) output->crtc->rect.height / manager->screen_height;
|
||||
|
||||
viewport[0] = width;
|
||||
viewport[1] = 0.0f;
|
||||
viewport[2] = x;
|
||||
viewport[3] = 0.0f;
|
||||
viewport[4] = height;
|
||||
viewport[5] = y;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
multiply_matrix (float a[6],
|
||||
float b[6],
|
||||
float res[6])
|
||||
{
|
||||
res[0] = a[0] * b[0] + a[1] * b[3];
|
||||
res[1] = a[0] * b[1] + a[1] * b[4];
|
||||
res[2] = a[0] * b[2] + a[1] * b[5] + a[2];
|
||||
res[3] = a[3] * b[0] + a[4] * b[3];
|
||||
res[4] = a[3] * b[1] + a[4] * b[4];
|
||||
res[5] = a[3] * b[2] + a[4] * b[5] + a[5];
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_monitor_manager_get_monitor_matrix (MetaMonitorManager *manager,
|
||||
MetaOutput *output,
|
||||
gfloat matrix[6])
|
||||
{
|
||||
gfloat viewport[9];
|
||||
|
||||
if (!calculate_viewport_matrix (manager, output, viewport))
|
||||
return FALSE;
|
||||
|
||||
multiply_matrix (viewport, transform_matrices[output->crtc->transform],
|
||||
matrix);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_monitor_manager_get_output_geometry:
|
||||
* @manager: A #MetaMonitorManager
|
||||
* @id: A valid #MetaOutput id
|
||||
*
|
||||
* Returns: The monitor index or -1 if @id isn't valid or the output
|
||||
* isn't associated with a logical monitor.
|
||||
*/
|
||||
gint
|
||||
meta_monitor_manager_get_monitor_for_output (MetaMonitorManager *manager,
|
||||
guint id)
|
||||
{
|
||||
MetaOutput *output;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (META_IS_MONITOR_MANAGER (manager), -1);
|
||||
g_return_val_if_fail (id < manager->n_outputs, -1);
|
||||
|
||||
output = &manager->outputs[id];
|
||||
if (!output || !output->crtc)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < manager->n_monitor_infos; i++)
|
||||
if (meta_rectangle_contains_rect (&manager->monitor_infos[i].rect,
|
||||
&output->crtc->rect))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
32
src/backends/native/meta-backend-native-private.h
Normal file
32
src/backends/native/meta-backend-native-private.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_BACKEND_NATIVE_PRIVATE_H
|
||||
#define META_BACKEND_NATIVE_PRIVATE_H
|
||||
|
||||
#include "backends/native/meta-barrier-native.h"
|
||||
|
||||
MetaBarrierManagerNative *meta_backend_native_get_barrier_manager (MetaBackendNative *native);
|
||||
|
||||
#endif /* META_BACKEND_NATIVE_PRIVATE_H */
|
@ -24,10 +24,13 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-backend-native.h"
|
||||
#include "meta-backend-native-private.h"
|
||||
|
||||
#include <meta/main.h>
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
#include "meta-backend-native.h"
|
||||
|
||||
#include "meta-barrier-native.h"
|
||||
#include "meta-idle-monitor-native.h"
|
||||
#include "meta-monitor-manager-kms.h"
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
@ -36,11 +39,42 @@
|
||||
struct _MetaBackendNativePrivate
|
||||
{
|
||||
MetaLauncher *launcher;
|
||||
|
||||
MetaBarrierManagerNative *barrier_manager;
|
||||
|
||||
GSettings *keyboard_settings;
|
||||
};
|
||||
typedef struct _MetaBackendNativePrivate MetaBackendNativePrivate;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendNative, meta_backend_native, META_TYPE_BACKEND);
|
||||
|
||||
static void
|
||||
meta_backend_native_finalize (GObject *object)
|
||||
{
|
||||
MetaBackendNative *native = META_BACKEND_NATIVE (object);
|
||||
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
|
||||
|
||||
meta_launcher_free (priv->launcher);
|
||||
|
||||
G_OBJECT_CLASS (meta_backend_native_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
constrain_to_barriers (ClutterInputDevice *device,
|
||||
guint32 time,
|
||||
float *new_x,
|
||||
float *new_y)
|
||||
{
|
||||
MetaBackendNative *native = META_BACKEND_NATIVE (meta_get_backend ());
|
||||
MetaBackendNativePrivate *priv =
|
||||
meta_backend_native_get_instance_private (native);
|
||||
|
||||
meta_barrier_manager_native_process (priv->barrier_manager,
|
||||
device,
|
||||
time,
|
||||
new_x, new_y);
|
||||
}
|
||||
|
||||
/*
|
||||
* The pointer constrain code is mostly a rip-off of the XRandR code from Xorg.
|
||||
* (from xserver/randr/rrcrtc.c, RRConstrainCursorHarder)
|
||||
@ -66,7 +100,7 @@ check_all_screen_monitors(MetaMonitorInfo *monitors,
|
||||
left = monitor->rect.x;
|
||||
right = left + monitor->rect.width;
|
||||
top = monitor->rect.y;
|
||||
bottom = left + monitor->rect.height;
|
||||
bottom = top + monitor->rect.height;
|
||||
|
||||
if ((x >= left) && (x < right) && (y >= top) && (y < bottom))
|
||||
return TRUE;
|
||||
@ -84,25 +118,25 @@ constrain_all_screen_monitors (ClutterInputDevice *device,
|
||||
{
|
||||
ClutterPoint current;
|
||||
unsigned int i;
|
||||
float cx, cy;
|
||||
|
||||
clutter_input_device_get_coords (device, NULL, ¤t);
|
||||
|
||||
cx = current.x;
|
||||
cy = current.y;
|
||||
|
||||
/* if we're trying to escape, clamp to the CRTC we're coming from */
|
||||
for (i = 0; i < n_monitors; i++)
|
||||
{
|
||||
MetaMonitorInfo *monitor = &monitors[i];
|
||||
int left, right, top, bottom;
|
||||
float nx, ny;
|
||||
|
||||
left = monitor->rect.x;
|
||||
right = left + monitor->rect.width;
|
||||
top = monitor->rect.y;
|
||||
bottom = left + monitor->rect.height;
|
||||
bottom = top + monitor->rect.height;
|
||||
|
||||
nx = current.x;
|
||||
ny = current.y;
|
||||
|
||||
if ((nx >= left) && (nx < right) && (ny >= top) && (ny < bottom))
|
||||
if ((cx >= left) && (cx < right) && (cy >= top) && (cy < bottom))
|
||||
{
|
||||
if (*x < left)
|
||||
*x = left;
|
||||
@ -130,6 +164,9 @@ pointer_constrain_callback (ClutterInputDevice *device,
|
||||
unsigned int n_monitors;
|
||||
gboolean ret;
|
||||
|
||||
/* Constrain to barriers */
|
||||
constrain_to_barriers (device, time, new_x, new_y);
|
||||
|
||||
monitor_manager = meta_monitor_manager_get ();
|
||||
monitors = meta_monitor_manager_get_monitor_infos (monitor_manager, &n_monitors);
|
||||
|
||||
@ -142,15 +179,49 @@ pointer_constrain_callback (ClutterInputDevice *device,
|
||||
constrain_all_screen_monitors(device, monitors, n_monitors, new_x, new_y);
|
||||
}
|
||||
|
||||
static void
|
||||
on_monitors_changed (MetaMonitorManager *monitor_manager,
|
||||
MetaBackend *backend)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
|
||||
MetaMonitorInfo *monitors, *primary;
|
||||
unsigned int n_monitors;
|
||||
ClutterPoint point;
|
||||
|
||||
if (!clutter_input_device_get_coords (device, NULL, &point))
|
||||
return;
|
||||
|
||||
monitors = meta_monitor_manager_get_monitor_infos (monitor_manager, &n_monitors);
|
||||
|
||||
/* if we're inside a monitor, we're fine */
|
||||
if (check_all_screen_monitors (monitors, n_monitors, point.x, point.y))
|
||||
return;
|
||||
|
||||
/* warp the pointer to the primary monitor so it isn't lost */
|
||||
primary = &monitors[meta_monitor_manager_get_primary_index (monitor_manager)];
|
||||
meta_backend_warp_pointer (backend,
|
||||
primary->rect.x + primary->rect.width / 2,
|
||||
primary->rect.y + primary->rect.height / 2);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_post_init (MetaBackend *backend)
|
||||
{
|
||||
MetaMonitorManager *monitor_manager;
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
|
||||
META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
|
||||
|
||||
clutter_evdev_set_pointer_constrain_callback (manager, pointer_constrain_callback,
|
||||
NULL, NULL);
|
||||
|
||||
monitor_manager = meta_backend_get_monitor_manager (backend);
|
||||
g_signal_connect_object (monitor_manager, "monitors-changed",
|
||||
G_CALLBACK (on_monitors_changed), backend, G_CONNECT_AFTER);
|
||||
|
||||
/* make sure the pointer is in the visible area after init */
|
||||
on_monitors_changed (monitor_manager, backend);
|
||||
}
|
||||
|
||||
static MetaIdleMonitor *
|
||||
@ -236,6 +307,9 @@ static void
|
||||
meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
||||
{
|
||||
MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = meta_backend_native_finalize;
|
||||
|
||||
backend_class->post_init = meta_backend_native_post_init;
|
||||
backend_class->create_idle_monitor = meta_backend_native_create_idle_monitor;
|
||||
@ -255,6 +329,8 @@ meta_backend_native_init (MetaBackendNative *native)
|
||||
|
||||
/* We're a display server, so start talking to weston-launch. */
|
||||
priv->launcher = meta_launcher_new ();
|
||||
|
||||
priv->barrier_manager = meta_barrier_manager_native_new ();
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -267,11 +343,20 @@ meta_activate_vt (int vt, GError **error)
|
||||
return meta_launcher_activate_vt (priv->launcher, vt, error);
|
||||
}
|
||||
|
||||
MetaBarrierManagerNative *
|
||||
meta_backend_native_get_barrier_manager (MetaBackendNative *native)
|
||||
{
|
||||
MetaBackendNativePrivate *priv =
|
||||
meta_backend_native_get_instance_private (native);
|
||||
|
||||
return priv->barrier_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_activate_session:
|
||||
*
|
||||
* Tells mutter to activate the session. When mutter is a
|
||||
* Wayland compositor, this tells logind to switch over to
|
||||
* display server, this tells logind to switch over to
|
||||
* the new session.
|
||||
*/
|
||||
gboolean
|
||||
|
744
src/backends/native/meta-barrier-native.c
Normal file
744
src/backends/native/meta-barrier-native.c
Normal file
@ -0,0 +1,744 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:barrier-native
|
||||
* @Title: MetaBarrierImplNative
|
||||
* @Short_Description: Pointer barriers implementation for the native backend
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <meta/barrier.h>
|
||||
#include <meta/util.h>
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-barrier-private.h"
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#include "backends/native/meta-backend-native-private.h"
|
||||
#include "backends/native/meta-barrier-native.h"
|
||||
|
||||
struct _MetaBarrierManagerNative
|
||||
{
|
||||
GHashTable *barriers;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
/* The barrier is active and responsive to pointer motion. */
|
||||
META_BARRIER_STATE_ACTIVE,
|
||||
|
||||
/* An intermediate state after a pointer hit the pointer barrier. */
|
||||
META_BARRIER_STATE_HIT,
|
||||
|
||||
/* The barrier was hit by a pointer and is still within the hit box and
|
||||
* has not been released.*/
|
||||
META_BARRIER_STATE_HELD,
|
||||
|
||||
/* The pointer was released by the user. If the following motion hits
|
||||
* the barrier, it will pass through. */
|
||||
META_BARRIER_STATE_RELEASE,
|
||||
|
||||
/* An intermediate state when the pointer has left the barrier. */
|
||||
META_BARRIER_STATE_LEFT,
|
||||
} MetaBarrierState;
|
||||
|
||||
struct _MetaBarrierImplNativePrivate
|
||||
{
|
||||
MetaBarrier *barrier;
|
||||
MetaBarrierManagerNative *manager;
|
||||
|
||||
gboolean is_active;
|
||||
MetaBarrierState state;
|
||||
int trigger_serial;
|
||||
guint32 last_event_time;
|
||||
MetaBarrierDirection blocked_dir;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaBarrierImplNative, meta_barrier_impl_native,
|
||||
META_TYPE_BARRIER_IMPL)
|
||||
|
||||
static int
|
||||
next_serial (void)
|
||||
{
|
||||
static int barrier_serial = 1;
|
||||
|
||||
barrier_serial++;
|
||||
|
||||
/* If it wraps, avoid 0 as it's not a valid serial. */
|
||||
if (barrier_serial == 0)
|
||||
barrier_serial++;
|
||||
|
||||
return barrier_serial;
|
||||
}
|
||||
|
||||
typedef struct _Vector2
|
||||
{
|
||||
float x, y;
|
||||
} Vector2;
|
||||
|
||||
static float
|
||||
vector2_cross_product (Vector2 a, Vector2 b)
|
||||
{
|
||||
return a.x * b.y - a.y * b.x;
|
||||
}
|
||||
|
||||
static Vector2
|
||||
vector2_add (Vector2 a, Vector2 b)
|
||||
{
|
||||
return (Vector2) {
|
||||
.x = a.x + b.x,
|
||||
.y = a.y + b.y,
|
||||
};
|
||||
}
|
||||
|
||||
static Vector2
|
||||
vector2_subtract (Vector2 a, Vector2 b)
|
||||
{
|
||||
return (Vector2) {
|
||||
.x = a.x - b.x,
|
||||
.y = a.y - b.y,
|
||||
};
|
||||
}
|
||||
|
||||
static Vector2
|
||||
vector2_multiply_constant (float c, Vector2 a)
|
||||
{
|
||||
return (Vector2) {
|
||||
.x = c * a.x,
|
||||
.y = c * a.y,
|
||||
};
|
||||
}
|
||||
|
||||
typedef struct _Line2
|
||||
{
|
||||
Vector2 a;
|
||||
Vector2 b;
|
||||
} Line2;
|
||||
|
||||
static gboolean
|
||||
lines_intersect (Line2 *line1, Line2 *line2, Vector2 *intersection)
|
||||
{
|
||||
Vector2 p = line1->a;
|
||||
Vector2 r = vector2_subtract (line1->b, line1->a);
|
||||
Vector2 q = line2->a;
|
||||
Vector2 s = vector2_subtract (line2->b, line2->a);
|
||||
float rxs;
|
||||
float sxr;
|
||||
float t;
|
||||
float u;
|
||||
|
||||
/*
|
||||
* The line (p, r) and (q, s) intersects where
|
||||
*
|
||||
* p + t r = q + u s
|
||||
*
|
||||
* Calculate t:
|
||||
*
|
||||
* (p + t r) × s = (q + u s) × s
|
||||
* p × s + t (r × s) = q × s + u (s × s)
|
||||
* p × s + t (r × s) = q × s
|
||||
* t (r × s) = q × s - p × s
|
||||
* t (r × s) = (q - p) × s
|
||||
* t = ((q - p) × s) / (r × s)
|
||||
*
|
||||
* Using the same method, for u we get:
|
||||
*
|
||||
* u = ((p - q) × r) / (s × r)
|
||||
*/
|
||||
|
||||
rxs = vector2_cross_product (r, s);
|
||||
sxr = vector2_cross_product (s, r);
|
||||
|
||||
/* If r × s = 0 then the lines are either parallel or collinear. */
|
||||
if (fabs ( rxs) < DBL_MIN)
|
||||
return FALSE;
|
||||
|
||||
t = vector2_cross_product (vector2_subtract (q, p), s) / rxs;
|
||||
u = vector2_cross_product (vector2_subtract (p, q), r) / sxr;
|
||||
|
||||
|
||||
/* The lines only intersect if 0 ≤ t ≤ 1 and 0 ≤ u ≤ 1. */
|
||||
if (t < 0.0 || t > 1.0 || u < 0.0 || u > 1.0)
|
||||
return FALSE;
|
||||
|
||||
*intersection = vector2_add (p, vector2_multiply_constant (t, r));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_barrier_horizontal (MetaBarrier *barrier)
|
||||
{
|
||||
return barrier->priv->y1 == barrier->priv->y2;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_barrier_blocking_directions (MetaBarrier *barrier,
|
||||
MetaBarrierDirection directions)
|
||||
{
|
||||
/* Barriers doesn't block parallel motions. */
|
||||
if (is_barrier_horizontal (barrier))
|
||||
{
|
||||
if ((directions & (META_BARRIER_DIRECTION_POSITIVE_Y |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_Y)) == 0)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((directions & (META_BARRIER_DIRECTION_POSITIVE_X |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_X)) == 0)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (barrier->priv->directions & directions) != directions;
|
||||
}
|
||||
|
||||
static void
|
||||
dismiss_pointer (MetaBarrierImplNative *self)
|
||||
{
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
|
||||
priv->state = META_BARRIER_STATE_LEFT;
|
||||
}
|
||||
|
||||
static Line2
|
||||
barrier_to_line (MetaBarrier *barrier)
|
||||
{
|
||||
return (Line2) {
|
||||
.a = (Vector2) {
|
||||
.x = MIN (barrier->priv->x1, barrier->priv->x2),
|
||||
.y = MIN (barrier->priv->y1, barrier->priv->y2),
|
||||
},
|
||||
.b = (Vector2) {
|
||||
.x = MAX (barrier->priv->x1, barrier->priv->x2),
|
||||
.y = MAX (barrier->priv->y1, barrier->priv->y2),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the hit box for a held motion. The hit box is a 2 px wide region
|
||||
* in the opposite direction of every direction the barrier blocks. The purpose
|
||||
* of this is to allow small movements without receiving a "left" signal. This
|
||||
* heuristic comes from the X.org pointer barrier implementation.
|
||||
*/
|
||||
static Line2
|
||||
calculate_barrier_hit_box (MetaBarrier *barrier)
|
||||
{
|
||||
Line2 hit_box = barrier_to_line (barrier);
|
||||
|
||||
if (is_barrier_horizontal (barrier))
|
||||
{
|
||||
if (is_barrier_blocking_directions (barrier,
|
||||
META_BARRIER_DIRECTION_POSITIVE_Y))
|
||||
hit_box.a.y -= 2.0f;
|
||||
if (is_barrier_blocking_directions (barrier,
|
||||
META_BARRIER_DIRECTION_NEGATIVE_Y))
|
||||
hit_box.b.y += 2.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_barrier_blocking_directions (barrier,
|
||||
META_BARRIER_DIRECTION_POSITIVE_X))
|
||||
hit_box.a.x -= 2.0f;
|
||||
if (is_barrier_blocking_directions (barrier,
|
||||
META_BARRIER_DIRECTION_NEGATIVE_X))
|
||||
hit_box.b.x += 2.0f;
|
||||
}
|
||||
|
||||
return hit_box;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_within_box (Line2 box, Vector2 point)
|
||||
{
|
||||
return (point.x >= box.a.x && point.x < box.b.x &&
|
||||
point.y >= box.a.y && point.y < box.b.y);
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_release_barrier (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaBarrierImplNative *self = key;
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
MetaBarrier *barrier = priv->barrier;
|
||||
Line2 *motion = user_data;
|
||||
Line2 hit_box;
|
||||
|
||||
if (priv->state != META_BARRIER_STATE_HELD)
|
||||
return;
|
||||
|
||||
/* Release if we end up outside barrier end points. */
|
||||
if (is_barrier_horizontal (barrier))
|
||||
{
|
||||
if (motion->b.x > MAX (barrier->priv->x1, barrier->priv->x2) ||
|
||||
motion->b.x < MIN (barrier->priv->x1, barrier->priv->x2))
|
||||
{
|
||||
dismiss_pointer (self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (motion->b.y > MAX (barrier->priv->y1, barrier->priv->y2) ||
|
||||
motion->b.y < MIN (barrier->priv->y1, barrier->priv->y2))
|
||||
{
|
||||
dismiss_pointer (self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release if we don't intersect and end up outside of hit box. */
|
||||
hit_box = calculate_barrier_hit_box (barrier);
|
||||
if (!is_within_box (hit_box, motion->b))
|
||||
{
|
||||
dismiss_pointer (self);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_release_barriers (MetaBarrierManagerNative *manager,
|
||||
float prev_x,
|
||||
float prev_y,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
Line2 motion = {
|
||||
.a = {
|
||||
.x = prev_x,
|
||||
.y = prev_y,
|
||||
},
|
||||
.b = {
|
||||
.x = x,
|
||||
.y = y,
|
||||
},
|
||||
};
|
||||
|
||||
g_hash_table_foreach (manager->barriers,
|
||||
maybe_release_barrier,
|
||||
&motion);
|
||||
}
|
||||
|
||||
typedef struct _MetaClosestBarrierData
|
||||
{
|
||||
struct
|
||||
{
|
||||
Line2 motion;
|
||||
MetaBarrierDirection directions;
|
||||
} in;
|
||||
|
||||
struct
|
||||
{
|
||||
float closest_distance_2;
|
||||
MetaBarrierImplNative *barrier_impl;
|
||||
} out;
|
||||
} MetaClosestBarrierData;
|
||||
|
||||
static void
|
||||
update_closest_barrier (gpointer key,
|
||||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaBarrierImplNative *self = key;
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
MetaBarrier *barrier = priv->barrier;
|
||||
MetaClosestBarrierData *data = user_data;
|
||||
Line2 barrier_line;
|
||||
Vector2 intersection;
|
||||
float dx, dy;
|
||||
float distance_2;
|
||||
|
||||
/* Ignore if the barrier is not blocking in any of the motions directions. */
|
||||
if (!is_barrier_blocking_directions (barrier, data->in.directions))
|
||||
return;
|
||||
|
||||
/* Ignore if the barrier released the pointer. */
|
||||
if (priv->state == META_BARRIER_STATE_RELEASE)
|
||||
return;
|
||||
|
||||
/* Ignore if we are moving away from barrier. */
|
||||
if (priv->state == META_BARRIER_STATE_HELD &&
|
||||
(data->in.directions & priv->blocked_dir) == 0)
|
||||
return;
|
||||
|
||||
/* Check if the motion intersects with the barrier, and retrieve the
|
||||
* intersection point if any. */
|
||||
barrier_line = (Line2) {
|
||||
.a = {
|
||||
.x = barrier->priv->x1,
|
||||
.y = barrier->priv->y1
|
||||
},
|
||||
.b = {
|
||||
.x = barrier->priv->x2,
|
||||
.y = barrier->priv->y2
|
||||
},
|
||||
};
|
||||
if (!lines_intersect (&barrier_line, &data->in.motion, &intersection))
|
||||
return;
|
||||
|
||||
/* Calculate the distance to the barrier and keep track of the closest
|
||||
* barrier. */
|
||||
dx = intersection.x - data->in.motion.a.x;
|
||||
dy = intersection.y - data->in.motion.a.y;
|
||||
distance_2 = dx*dx + dy*dy;
|
||||
if (data->out.barrier_impl == NULL ||
|
||||
distance_2 < data->out.closest_distance_2)
|
||||
{
|
||||
data->out.barrier_impl = self;
|
||||
data->out.closest_distance_2 = distance_2;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_closest_barrier (MetaBarrierManagerNative *manager,
|
||||
float prev_x,
|
||||
float prev_y,
|
||||
float x,
|
||||
float y,
|
||||
MetaBarrierDirection motion_dir,
|
||||
MetaBarrierImplNative **barrier_impl)
|
||||
{
|
||||
MetaClosestBarrierData closest_barrier_data;
|
||||
|
||||
closest_barrier_data = (MetaClosestBarrierData) {
|
||||
.in = {
|
||||
.motion = {
|
||||
.a = {
|
||||
.x = prev_x,
|
||||
.y = prev_y,
|
||||
},
|
||||
.b = {
|
||||
.x = x,
|
||||
.y = y,
|
||||
},
|
||||
},
|
||||
.directions = motion_dir,
|
||||
},
|
||||
};
|
||||
|
||||
g_hash_table_foreach (manager->barriers,
|
||||
update_closest_barrier,
|
||||
&closest_barrier_data);
|
||||
|
||||
if (closest_barrier_data.out.barrier_impl != NULL)
|
||||
{
|
||||
*barrier_impl = closest_barrier_data.out.barrier_impl;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct _MetaBarrierEventData
|
||||
{
|
||||
guint32 time;
|
||||
float prev_x;
|
||||
float prev_y;
|
||||
float x;
|
||||
float y;
|
||||
float dx;
|
||||
float dy;
|
||||
} MetaBarrierEventData;
|
||||
|
||||
static void
|
||||
emit_barrier_event (MetaBarrierImplNative *self,
|
||||
guint32 time,
|
||||
float prev_x,
|
||||
float prev_y,
|
||||
float x,
|
||||
float y,
|
||||
float dx,
|
||||
float dy)
|
||||
{
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
MetaBarrier *barrier = priv->barrier;
|
||||
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
|
||||
MetaBarrierState old_state = priv->state;
|
||||
|
||||
switch (priv->state)
|
||||
{
|
||||
case META_BARRIER_STATE_HIT:
|
||||
priv->state = META_BARRIER_STATE_HELD;
|
||||
priv->trigger_serial = next_serial ();
|
||||
event->dt = 0;
|
||||
|
||||
break;
|
||||
case META_BARRIER_STATE_RELEASE:
|
||||
case META_BARRIER_STATE_LEFT:
|
||||
priv->state = META_BARRIER_STATE_ACTIVE;
|
||||
|
||||
/* Intentional fall-through. */
|
||||
case META_BARRIER_STATE_HELD:
|
||||
event->dt = time - priv->last_event_time;
|
||||
|
||||
break;
|
||||
case META_BARRIER_STATE_ACTIVE:
|
||||
g_assert_not_reached (); /* Invalid state. */
|
||||
}
|
||||
|
||||
event->ref_count = 1;
|
||||
event->event_id = priv->trigger_serial;
|
||||
event->time = time;
|
||||
|
||||
event->x = x;
|
||||
event->y = y;
|
||||
event->dx = dx;
|
||||
event->dy = dy;
|
||||
|
||||
event->grabbed = priv->state == META_BARRIER_STATE_HELD;
|
||||
event->released = old_state == META_BARRIER_STATE_RELEASE;
|
||||
|
||||
priv->last_event_time = time;
|
||||
|
||||
if (priv->state == META_BARRIER_STATE_HELD)
|
||||
_meta_barrier_emit_hit_signal (barrier, event);
|
||||
else
|
||||
_meta_barrier_emit_left_signal (barrier, event);
|
||||
|
||||
meta_barrier_event_unref (event);
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_emit_barrier_event (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
MetaBarrierImplNative *self = key;
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
MetaBarrierEventData *data = user_data;
|
||||
|
||||
switch (priv->state) {
|
||||
case META_BARRIER_STATE_ACTIVE:
|
||||
break;
|
||||
case META_BARRIER_STATE_HIT:
|
||||
case META_BARRIER_STATE_HELD:
|
||||
case META_BARRIER_STATE_RELEASE:
|
||||
case META_BARRIER_STATE_LEFT:
|
||||
emit_barrier_event (self,
|
||||
data->time,
|
||||
data->prev_x,
|
||||
data->prev_y,
|
||||
data->x,
|
||||
data->y,
|
||||
data->dx,
|
||||
data->dy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clamp (x, y) to the barrier and remove clamped direction from motion_dir. */
|
||||
static void
|
||||
clamp_to_barrier (MetaBarrierImplNative *self,
|
||||
MetaBarrierDirection *motion_dir,
|
||||
float *x,
|
||||
float *y)
|
||||
{
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
MetaBarrier *barrier = priv->barrier;
|
||||
|
||||
if (is_barrier_horizontal (barrier))
|
||||
{
|
||||
if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_Y)
|
||||
*y = barrier->priv->y1;
|
||||
else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_Y)
|
||||
*y = barrier->priv->y1;
|
||||
|
||||
priv->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_Y |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_Y);
|
||||
*motion_dir &= ~(META_BARRIER_DIRECTION_POSITIVE_Y |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*motion_dir & META_BARRIER_DIRECTION_POSITIVE_X)
|
||||
*x = barrier->priv->x1;
|
||||
else if (*motion_dir & META_BARRIER_DIRECTION_NEGATIVE_X)
|
||||
*x = barrier->priv->x1;
|
||||
|
||||
priv->blocked_dir = *motion_dir & (META_BARRIER_DIRECTION_POSITIVE_X |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_X);
|
||||
*motion_dir &= ~(META_BARRIER_DIRECTION_POSITIVE_X |
|
||||
META_BARRIER_DIRECTION_NEGATIVE_X);
|
||||
}
|
||||
|
||||
priv->state = META_BARRIER_STATE_HIT;
|
||||
}
|
||||
|
||||
void
|
||||
meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
|
||||
ClutterInputDevice *device,
|
||||
guint32 time,
|
||||
float *x,
|
||||
float *y)
|
||||
{
|
||||
ClutterPoint prev_pos;
|
||||
float prev_x;
|
||||
float prev_y;
|
||||
float orig_x = *x;
|
||||
float orig_y = *y;
|
||||
MetaBarrierDirection motion_dir = 0;
|
||||
MetaBarrierEventData barrier_event_data;
|
||||
MetaBarrierImplNative *barrier_impl;
|
||||
|
||||
if (!clutter_input_device_get_coords (device, NULL, &prev_pos))
|
||||
return;
|
||||
|
||||
prev_x = prev_pos.x;
|
||||
prev_y = prev_pos.y;
|
||||
|
||||
/* Get the direction of the motion vector. */
|
||||
if (prev_x < *x)
|
||||
motion_dir |= META_BARRIER_DIRECTION_POSITIVE_X;
|
||||
else if (prev_x > *x)
|
||||
motion_dir |= META_BARRIER_DIRECTION_NEGATIVE_X;
|
||||
if (prev_y < *y)
|
||||
motion_dir |= META_BARRIER_DIRECTION_POSITIVE_Y;
|
||||
else if (prev_y > *y)
|
||||
motion_dir |= META_BARRIER_DIRECTION_NEGATIVE_Y;
|
||||
|
||||
/* Clamp to the closest barrier in any direction until either there are no
|
||||
* more barriers to clamp to or all directions have been clamped. */
|
||||
while (motion_dir != 0)
|
||||
{
|
||||
if (get_closest_barrier (manager,
|
||||
prev_x, prev_y,
|
||||
*x, *y,
|
||||
motion_dir,
|
||||
&barrier_impl))
|
||||
clamp_to_barrier (barrier_impl, &motion_dir, x, y);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
/* Potentially release active barrier movements. */
|
||||
maybe_release_barriers (manager, prev_x, prev_y, *x, *y);
|
||||
|
||||
/* Initiate or continue barrier interaction. */
|
||||
barrier_event_data = (MetaBarrierEventData) {
|
||||
.time = time,
|
||||
.prev_x = prev_x,
|
||||
.prev_y = prev_y,
|
||||
.x = *x,
|
||||
.y = *y,
|
||||
.dx = orig_x - prev_x,
|
||||
.dy = orig_y - prev_y,
|
||||
};
|
||||
|
||||
g_hash_table_foreach (manager->barriers,
|
||||
maybe_emit_barrier_event,
|
||||
&barrier_event_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_meta_barrier_impl_native_is_active (MetaBarrierImpl *impl)
|
||||
{
|
||||
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
|
||||
return priv->is_active;
|
||||
}
|
||||
|
||||
static void
|
||||
_meta_barrier_impl_native_release (MetaBarrierImpl *impl,
|
||||
MetaBarrierEvent *event)
|
||||
{
|
||||
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
|
||||
if (priv->state == META_BARRIER_STATE_HELD &&
|
||||
event->event_id == priv->trigger_serial)
|
||||
priv->state = META_BARRIER_STATE_RELEASE;
|
||||
}
|
||||
|
||||
static void
|
||||
_meta_barrier_impl_native_destroy (MetaBarrierImpl *impl)
|
||||
{
|
||||
MetaBarrierImplNative *self = META_BARRIER_IMPL_NATIVE (impl);
|
||||
MetaBarrierImplNativePrivate *priv =
|
||||
meta_barrier_impl_native_get_instance_private (self);
|
||||
|
||||
g_hash_table_remove (priv->manager->barriers, self);
|
||||
priv->is_active = FALSE;
|
||||
}
|
||||
|
||||
MetaBarrierImpl *
|
||||
meta_barrier_impl_native_new (MetaBarrier *barrier)
|
||||
{
|
||||
MetaBarrierImplNative *self;
|
||||
MetaBarrierImplNativePrivate *priv;
|
||||
MetaBackendNative *native;
|
||||
MetaBarrierManagerNative *manager;
|
||||
|
||||
self = g_object_new (META_TYPE_BARRIER_IMPL_NATIVE, NULL);
|
||||
priv = meta_barrier_impl_native_get_instance_private (self);
|
||||
|
||||
priv->barrier = barrier;
|
||||
priv->is_active = TRUE;
|
||||
|
||||
native = META_BACKEND_NATIVE (meta_get_backend ());
|
||||
manager = meta_backend_native_get_barrier_manager (native);
|
||||
priv->manager = manager;
|
||||
g_hash_table_add (manager->barriers, self);
|
||||
|
||||
return META_BARRIER_IMPL (self);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_impl_native_class_init (MetaBarrierImplNativeClass *klass)
|
||||
{
|
||||
MetaBarrierImplClass *impl_class = META_BARRIER_IMPL_CLASS (klass);
|
||||
|
||||
impl_class->is_active = _meta_barrier_impl_native_is_active;
|
||||
impl_class->release = _meta_barrier_impl_native_release;
|
||||
impl_class->destroy = _meta_barrier_impl_native_destroy;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_impl_native_init (MetaBarrierImplNative *self)
|
||||
{
|
||||
}
|
||||
|
||||
MetaBarrierManagerNative *
|
||||
meta_barrier_manager_native_new (void)
|
||||
{
|
||||
MetaBarrierManagerNative *manager;
|
||||
|
||||
manager = g_new0 (MetaBarrierManagerNative, 1);
|
||||
|
||||
manager->barriers = g_hash_table_new (NULL, NULL);
|
||||
|
||||
return manager;
|
||||
}
|
68
src/backends/native/meta-barrier-native.h
Normal file
68
src/backends/native/meta-barrier-native.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_BARRIER_NATIVE_H
|
||||
#define META_BARRIER_NATIVE_H
|
||||
|
||||
#include "backends/meta-barrier-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_BARRIER_IMPL_NATIVE (meta_barrier_impl_native_get_type ())
|
||||
#define META_BARRIER_IMPL_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER_IMPL_NATIVE, MetaBarrierImplNative))
|
||||
#define META_BARRIER_IMPL_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER_IMPL_NATIVE, MetaBarrierImplNativeClass))
|
||||
#define META_IS_BARRIER_IMPL_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER_IMPL_NATIVE))
|
||||
#define META_IS_BARRIER_IMPL_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER_IMPL_NATIVE))
|
||||
#define META_BARRIER_IMPL_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER_IMPL_NATIVE, MetaBarrierImplNativeClass))
|
||||
|
||||
typedef struct _MetaBarrierImplNative MetaBarrierImplNative;
|
||||
typedef struct _MetaBarrierImplNativeClass MetaBarrierImplNativeClass;
|
||||
typedef struct _MetaBarrierImplNativePrivate MetaBarrierImplNativePrivate;
|
||||
|
||||
typedef struct _MetaBarrierManagerNative MetaBarrierManagerNative;
|
||||
|
||||
struct _MetaBarrierImplNative
|
||||
{
|
||||
MetaBarrierImpl parent;
|
||||
};
|
||||
|
||||
struct _MetaBarrierImplNativeClass
|
||||
{
|
||||
MetaBarrierImplClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_barrier_impl_native_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaBarrierImpl *meta_barrier_impl_native_new (MetaBarrier *barrier);
|
||||
|
||||
MetaBarrierManagerNative *meta_barrier_manager_native_new (void);
|
||||
void meta_barrier_manager_native_process (MetaBarrierManagerNative *manager,
|
||||
ClutterInputDevice *device,
|
||||
guint32 time,
|
||||
float *x,
|
||||
float *y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* META_BARRIER_NATIVE_H */
|
@ -27,9 +27,17 @@
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
|
||||
#include <gbm.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#ifndef DRM_CAP_CURSOR_WIDTH
|
||||
#define DRM_CAP_CURSOR_WIDTH 0x8
|
||||
#endif
|
||||
#ifndef DRM_CAP_CURSOR_HEIGHT
|
||||
#define DRM_CAP_CURSOR_HEIGHT 0x9
|
||||
#endif
|
||||
|
||||
struct _MetaCursorRendererNativePrivate
|
||||
{
|
||||
@ -37,6 +45,9 @@ struct _MetaCursorRendererNativePrivate
|
||||
|
||||
int drm_fd;
|
||||
struct gbm_device *gbm;
|
||||
|
||||
uint64_t cursor_width;
|
||||
uint64_t cursor_height;
|
||||
};
|
||||
typedef struct _MetaCursorRendererNativePrivate MetaCursorRendererNativePrivate;
|
||||
|
||||
@ -71,17 +82,13 @@ set_crtc_cursor (MetaCursorRendererNative *native,
|
||||
{
|
||||
struct gbm_bo *bo;
|
||||
union gbm_bo_handle handle;
|
||||
int width, height;
|
||||
int hot_x, hot_y;
|
||||
|
||||
bo = meta_cursor_reference_get_gbm_bo (cursor, &hot_x, &hot_y);
|
||||
|
||||
handle = gbm_bo_get_handle (bo);
|
||||
width = gbm_bo_get_width (bo);
|
||||
height = gbm_bo_get_height (bo);
|
||||
|
||||
drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
|
||||
width, height, hot_x, hot_y);
|
||||
priv->cursor_width, priv->cursor_height, hot_x, hot_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -186,6 +193,19 @@ meta_cursor_renderer_native_init (MetaCursorRendererNative *native)
|
||||
CoglRenderer *cogl_renderer = cogl_display_get_renderer (cogl_context_get_display (ctx));
|
||||
priv->drm_fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
|
||||
priv->gbm = gbm_create_device (priv->drm_fd);
|
||||
|
||||
uint64_t width, height;
|
||||
if (drmGetCap (priv->drm_fd, DRM_CAP_CURSOR_WIDTH, &width) == 0 &&
|
||||
drmGetCap (priv->drm_fd, DRM_CAP_CURSOR_HEIGHT, &height) == 0)
|
||||
{
|
||||
priv->cursor_width = width;
|
||||
priv->cursor_height = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->cursor_width = 64;
|
||||
priv->cursor_height = 64;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -198,6 +218,16 @@ meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *native)
|
||||
return priv->gbm;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_native_get_cursor_size (MetaCursorRendererNative *native,
|
||||
uint64_t *width, uint64_t *height)
|
||||
{
|
||||
MetaCursorRendererNativePrivate *priv = meta_cursor_renderer_native_get_instance_private (native);
|
||||
|
||||
*width = priv->cursor_width;
|
||||
*height = priv->cursor_height;
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_renderer_native_force_update (MetaCursorRendererNative *native)
|
||||
{
|
||||
|
@ -50,6 +50,7 @@ struct _MetaCursorRendererNativeClass
|
||||
GType meta_cursor_renderer_native_get_type (void) G_GNUC_CONST;
|
||||
|
||||
struct gbm_device * meta_cursor_renderer_native_get_gbm_device (MetaCursorRendererNative *renderer);
|
||||
void meta_cursor_renderer_native_get_cursor_size (MetaCursorRendererNative *native, uint64_t *width, uint64_t *height);
|
||||
void meta_cursor_renderer_native_force_update (MetaCursorRendererNative *renderer);
|
||||
|
||||
#endif /* META_CURSOR_RENDERER_NATIVE_H */
|
||||
|
264
src/backends/native/meta-input-settings-native.c
Normal file
264
src/backends/native/meta-input-settings-native.c
Normal file
@ -0,0 +1,264 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <clutter/evdev/clutter-evdev.h>
|
||||
#include <libinput.h>
|
||||
|
||||
#include "meta-input-settings-native.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaInputSettingsNative, meta_input_settings_native, META_TYPE_INPUT_SETTINGS)
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_send_events (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopDeviceSendEvents mode)
|
||||
{
|
||||
enum libinput_config_send_events_mode libinput_mode;
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED:
|
||||
libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
|
||||
break;
|
||||
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
|
||||
libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
|
||||
break;
|
||||
case G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED:
|
||||
libinput_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device_config_send_events_set_mode (libinput_device, libinput_mode);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_matrix (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gfloat matrix[6])
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
if (libinput_device_config_calibration_has_matrix (libinput_device) > 0)
|
||||
libinput_device_config_calibration_set_matrix (libinput_device, matrix);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_speed (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gdouble speed)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
libinput_device_config_accel_set_speed (libinput_device,
|
||||
CLAMP (speed, -1, 1));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_left_handed (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
if (libinput_device_config_left_handed_is_available (libinput_device))
|
||||
libinput_device_config_left_handed_set (libinput_device, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_tap_enabled (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
if (libinput_device_config_tap_get_finger_count (libinput_device) > 0)
|
||||
libinput_device_config_tap_set_enabled (libinput_device,
|
||||
enabled ?
|
||||
LIBINPUT_CONFIG_TAP_ENABLED :
|
||||
LIBINPUT_CONFIG_TAP_DISABLED);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_invert_scroll (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean inverted)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
if (libinput_device_config_scroll_has_natural_scroll (libinput_device))
|
||||
libinput_device_config_scroll_set_natural_scroll_enabled (libinput_device,
|
||||
inverted);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
device_set_scroll_method (struct libinput_device *libinput_device,
|
||||
enum libinput_config_scroll_method method)
|
||||
{
|
||||
enum libinput_config_scroll_method supported;
|
||||
|
||||
supported = libinput_device_config_scroll_get_methods (libinput_device);
|
||||
|
||||
if (method & supported)
|
||||
libinput_device_config_scroll_set_method (libinput_device, method);
|
||||
|
||||
return (method & supported) != 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
device_set_click_method (struct libinput_device *libinput_device,
|
||||
enum libinput_config_click_method method)
|
||||
{
|
||||
enum libinput_config_click_method supported;
|
||||
|
||||
supported = libinput_device_config_click_get_methods (libinput_device);
|
||||
|
||||
if (method & supported)
|
||||
libinput_device_config_click_set_method (libinput_device, method);
|
||||
|
||||
return (method & supported) != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_scroll_method (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadScrollMethod mode)
|
||||
{
|
||||
enum libinput_config_scroll_method scroll_method = 0;
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_DISABLED:
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_EDGE_SCROLLING:
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING:
|
||||
scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
}
|
||||
|
||||
device_set_scroll_method (libinput_device, scroll_method);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_scroll_button (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
guint button)
|
||||
{
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
if (!device_set_scroll_method (libinput_device,
|
||||
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN))
|
||||
return;
|
||||
|
||||
libinput_device_config_scroll_set_button (libinput_device, button);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_click_method (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadClickMethod mode)
|
||||
{
|
||||
enum libinput_config_click_method click_method = 0;
|
||||
struct libinput_device *libinput_device;
|
||||
|
||||
libinput_device = clutter_evdev_input_device_get_libinput_device (device);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT:
|
||||
click_method = libinput_device_config_click_get_default_method (libinput_device);
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE:
|
||||
click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS:
|
||||
click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS:
|
||||
click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
}
|
||||
|
||||
device_set_click_method (libinput_device, click_method);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_set_keyboard_repeat (MetaInputSettings *settings,
|
||||
gboolean enabled,
|
||||
guint delay,
|
||||
guint interval)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
|
||||
clutter_evdev_set_keyboard_repeat (manager, enabled, delay, interval);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_class_init (MetaInputSettingsNativeClass *klass)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass);
|
||||
|
||||
input_settings_class->set_send_events = meta_input_settings_native_set_send_events;
|
||||
input_settings_class->set_matrix = meta_input_settings_native_set_matrix;
|
||||
input_settings_class->set_speed = meta_input_settings_native_set_speed;
|
||||
input_settings_class->set_left_handed = meta_input_settings_native_set_left_handed;
|
||||
input_settings_class->set_tap_enabled = meta_input_settings_native_set_tap_enabled;
|
||||
input_settings_class->set_invert_scroll = meta_input_settings_native_set_invert_scroll;
|
||||
input_settings_class->set_scroll_method = meta_input_settings_native_set_scroll_method;
|
||||
input_settings_class->set_scroll_button = meta_input_settings_native_set_scroll_button;
|
||||
input_settings_class->set_click_method = meta_input_settings_native_set_click_method;
|
||||
input_settings_class->set_keyboard_repeat = meta_input_settings_native_set_keyboard_repeat;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_native_init (MetaInputSettingsNative *settings)
|
||||
{
|
||||
}
|
49
src/backends/native/meta-input-settings-native.h
Normal file
49
src/backends/native/meta-input-settings-native.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_INPUT_SETTINGS_NATIVE_H
|
||||
#define META_INPUT_SETTINGS_NATIVE_H
|
||||
|
||||
#include "meta-input-settings-private.h"
|
||||
|
||||
#define META_TYPE_INPUT_SETTINGS_NATIVE (meta_input_settings_native_get_type ())
|
||||
#define META_INPUT_SETTINGS_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNative))
|
||||
#define META_INPUT_SETTINGS_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNativeClass))
|
||||
#define META_IS_INPUT_SETTINGS_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS_NATIVE))
|
||||
#define META_IS_INPUT_SETTINGS_NATIVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS_NATIVE))
|
||||
#define META_INPUT_SETTINGS_NATIVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS_NATIVE, MetaInputSettingsNativeClass))
|
||||
|
||||
typedef struct _MetaInputSettingsNative MetaInputSettingsNative;
|
||||
typedef struct _MetaInputSettingsNativeClass MetaInputSettingsNativeClass;
|
||||
|
||||
struct _MetaInputSettingsNative
|
||||
{
|
||||
MetaInputSettings parent_instance;
|
||||
};
|
||||
|
||||
struct _MetaInputSettingsNativeClass
|
||||
{
|
||||
MetaInputSettingsClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_input_settings_native_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#endif /* META_INPUT_SETTINGS_NATIVE_H */
|
@ -130,8 +130,8 @@ take_device (Login1Session *session_proxy,
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GVariant *fd_variant = NULL;
|
||||
GUnixFDList *fd_list = NULL;
|
||||
int fd = -1;
|
||||
GUnixFDList *fd_list;
|
||||
|
||||
if (!login1_session_call_take_device_sync (session_proxy,
|
||||
dev_major,
|
||||
@ -307,7 +307,7 @@ get_kms_fd (Login1Session *session_proxy,
|
||||
MetaLauncher *
|
||||
meta_launcher_new (void)
|
||||
{
|
||||
MetaLauncher *self;
|
||||
MetaLauncher *self = NULL;
|
||||
Login1Session *session_proxy;
|
||||
GError *error = NULL;
|
||||
int kms_fd;
|
||||
@ -317,14 +317,14 @@ meta_launcher_new (void)
|
||||
{
|
||||
g_warning ("Could not take control: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!get_kms_fd (session_proxy, &kms_fd))
|
||||
return NULL;
|
||||
goto out;
|
||||
|
||||
self = g_slice_new0 (MetaLauncher);
|
||||
self->session_proxy = session_proxy;
|
||||
self->session_proxy = g_object_ref (session_proxy);
|
||||
self->seat_proxy = get_seat_proxy (NULL);
|
||||
|
||||
self->session_active = TRUE;
|
||||
@ -336,6 +336,9 @@ meta_launcher_new (void)
|
||||
|
||||
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
||||
|
||||
out:
|
||||
g_object_unref (session_proxy);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-monitor-manager-kms.h"
|
||||
#include "meta-monitor-config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -38,7 +39,8 @@
|
||||
|
||||
#include <meta/main.h>
|
||||
#include <meta/errors.h>
|
||||
#include "edid.h"
|
||||
|
||||
#include <gudev/gudev.h>
|
||||
|
||||
typedef struct {
|
||||
drmModeConnector *connector;
|
||||
@ -64,10 +66,9 @@ struct _MetaMonitorManagerKms
|
||||
drmModeConnector **connectors;
|
||||
unsigned int n_connectors;
|
||||
|
||||
drmModeEncoder **encoders;
|
||||
unsigned int n_encoders;
|
||||
GUdevClient *udev;
|
||||
|
||||
drmModeEncoder *current_encoder;
|
||||
GSettings *desktop_settings;
|
||||
};
|
||||
|
||||
struct _MetaMonitorManagerKmsClass
|
||||
@ -82,12 +83,9 @@ 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);
|
||||
}
|
||||
|
||||
@ -202,7 +200,7 @@ find_properties (MetaMonitorManagerKms *manager_kms,
|
||||
strcmp (prop->name, "EDID") == 0)
|
||||
output_kms->edid_blob_id = output_kms->connector->prop_values[i];
|
||||
|
||||
drmModeFreeProperty(prop);
|
||||
drmModeFreeProperty (prop);
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,8 +222,10 @@ read_output_edid (MetaMonitorManagerKms *manager_kms,
|
||||
}
|
||||
|
||||
if (edid_blob->length > 0)
|
||||
return g_bytes_new_with_free_func (edid_blob->data, edid_blob->length,
|
||||
(GDestroyNotify)drmModeFreePropertyBlob, edid_blob);
|
||||
{
|
||||
return g_bytes_new_with_free_func (edid_blob->data, edid_blob->length,
|
||||
(GDestroyNotify)drmModeFreePropertyBlob, edid_blob);
|
||||
}
|
||||
else
|
||||
{
|
||||
drmModeFreePropertyBlob (edid_blob);
|
||||
@ -263,11 +263,77 @@ find_output_by_id (MetaOutput *outputs,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The minimum resolution at which we turn on a window-scale of 2 */
|
||||
#define HIDPI_LIMIT 192
|
||||
|
||||
/* The minimum screen height at which we turn on a window-scale of 2;
|
||||
* below this there just isn't enough vertical real estate for GNOME
|
||||
* apps to work, and it's better to just be tiny */
|
||||
#define HIDPI_MIN_HEIGHT 1200
|
||||
|
||||
/* From http://en.wikipedia.org/wiki/4K_resolution#Resolutions_of_common_formats */
|
||||
#define SMALLEST_4K_WIDTH 3656
|
||||
|
||||
/* Based on code from gnome-settings-daemon */
|
||||
static int
|
||||
compute_scale (MetaOutput *output)
|
||||
{
|
||||
int scale = 1;
|
||||
|
||||
if (!output->crtc)
|
||||
goto out;
|
||||
|
||||
/* Scaling makes no sense */
|
||||
if (output->crtc->rect.width < HIDPI_MIN_HEIGHT)
|
||||
goto out;
|
||||
|
||||
/* 4K TV */
|
||||
if (output->name != NULL && strstr(output->name, "HDMI") != NULL &&
|
||||
output->crtc->rect.width >= SMALLEST_4K_WIDTH)
|
||||
goto out;
|
||||
|
||||
/* Somebody encoded the aspect ratio (16/9 or 16/10)
|
||||
* instead of the physical size */
|
||||
if ((output->width_mm == 160 && output->height_mm == 90) ||
|
||||
(output->width_mm == 160 && output->height_mm == 100) ||
|
||||
(output->width_mm == 16 && output->height_mm == 9) ||
|
||||
(output->width_mm == 16 && output->height_mm == 10))
|
||||
goto out;
|
||||
|
||||
if (output->width_mm > 0 && output->height_mm > 0)
|
||||
{
|
||||
double dpi_x, dpi_y;
|
||||
dpi_x = (double)output->crtc->rect.width / (output->width_mm / 25.4);
|
||||
dpi_y = (double)output->crtc->rect.height / (output->height_mm / 25.4);
|
||||
/* We don't completely trust these values so both
|
||||
must be high, and never pick higher ratio than
|
||||
2 automatically */
|
||||
if (dpi_x > HIDPI_LIMIT && dpi_y > HIDPI_LIMIT)
|
||||
scale = 2;
|
||||
}
|
||||
|
||||
out:
|
||||
return scale;
|
||||
}
|
||||
|
||||
static int
|
||||
get_output_scale (MetaMonitorManager *manager,
|
||||
MetaOutput *output)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
int scale = g_settings_get_uint (manager_kms->desktop_settings, "scaling-factor");
|
||||
if (scale > 0)
|
||||
return scale;
|
||||
else
|
||||
return compute_scale (output);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
drmModeRes *resources;
|
||||
drmModeEncoder **encoders;
|
||||
GHashTable *modes;
|
||||
GHashTableIter iter;
|
||||
drmModeModeInfo *mode;
|
||||
@ -303,7 +369,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
connector = drmModeGetConnector (manager_kms->fd, resources->connectors[i]);
|
||||
manager_kms->connectors[i] = connector;
|
||||
|
||||
if (connector->connection == DRM_MODE_CONNECTED)
|
||||
if (connector && connector->connection == DRM_MODE_CONNECTED)
|
||||
{
|
||||
/* Collect all modes for this connector */
|
||||
for (j = 0; j < (unsigned)connector->count_modes; j++)
|
||||
@ -311,13 +377,9 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
}
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
encoders = g_new (drmModeEncoder *, resources->count_encoders);
|
||||
for (i = 0; i < (unsigned)resources->count_encoders; i++)
|
||||
encoders[i] = drmModeGetEncoder (manager_kms->fd, resources->encoders[i]);
|
||||
|
||||
manager->n_modes = g_hash_table_size (modes);
|
||||
manager->modes = g_new0 (MetaMonitorMode, manager->n_modes);
|
||||
@ -401,7 +463,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
connector = manager_kms->connectors[i];
|
||||
meta_output = &manager->outputs[n_actual_outputs];
|
||||
|
||||
if (connector->connection == DRM_MODE_CONNECTED)
|
||||
if (connector && connector->connection == DRM_MODE_CONNECTED)
|
||||
{
|
||||
meta_output->driver_private = output_kms = g_slice_new0 (MetaOutputKms);
|
||||
meta_output->driver_notify = (GDestroyNotify)meta_output_destroy_notify;
|
||||
@ -410,6 +472,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_output->name = make_output_name (connector);
|
||||
meta_output->width_mm = connector->mmWidth;
|
||||
meta_output->height_mm = connector->mmHeight;
|
||||
meta_output->suggested_x = -1;
|
||||
meta_output->suggested_y = -1;
|
||||
|
||||
switch (connector->subpixel)
|
||||
{
|
||||
@ -448,6 +512,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
for (j = 0; j < output_kms->n_encoders; j++)
|
||||
{
|
||||
output_kms->encoders[j] = drmModeGetEncoder (manager_kms->fd, connector->encoders[j]);
|
||||
if (!output_kms->encoders[j])
|
||||
continue;
|
||||
|
||||
/* We only list CRTCs as supported if they are supported by all encoders
|
||||
for this connectors.
|
||||
@ -504,29 +570,13 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
find_properties (manager_kms, output_kms);
|
||||
|
||||
edid = read_output_edid (manager_kms, meta_output);
|
||||
if (edid)
|
||||
{
|
||||
MonitorInfo *parsed_edid;
|
||||
gsize len;
|
||||
meta_output_parse_edid (meta_output, edid);
|
||||
g_bytes_unref (edid);
|
||||
|
||||
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);
|
||||
/* MetaConnectorType matches DRM's connector types */
|
||||
meta_output->connector_type = (MetaConnectorType) connector->connector_type;
|
||||
|
||||
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");
|
||||
}
|
||||
meta_output->scale = get_output_scale (manager, meta_output);
|
||||
|
||||
/* FIXME: backlight is a very driver specific thing unfortunately,
|
||||
every DDX does its own thing, and the dumb KMS API does not include it.
|
||||
@ -569,9 +619,10 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
|
||||
for (j = 0; j < output_kms->n_encoders; j++)
|
||||
{
|
||||
for (k = 0; k < manager_kms->n_encoders; k++)
|
||||
for (k = 0; k < (unsigned)resources->count_encoders; k++)
|
||||
{
|
||||
if (output_kms->encoders[j]->encoder_id == manager_kms->encoders[k]->encoder_id)
|
||||
if (output_kms->encoders[j] && encoders[k] &&
|
||||
output_kms->encoders[j]->encoder_id == encoders[k]->encoder_id)
|
||||
{
|
||||
output_kms->encoder_mask |= (1 << k);
|
||||
break;
|
||||
@ -618,6 +669,10 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < (unsigned)resources->count_encoders; i++)
|
||||
drmModeFreeEncoder (encoders[i]);
|
||||
g_free (encoders);
|
||||
|
||||
drmModeFreeResources (resources);
|
||||
}
|
||||
|
||||
@ -635,6 +690,9 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
MetaPowerSave mode)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
ClutterBackend *backend;
|
||||
CoglContext *cogl_context;
|
||||
CoglDisplay *cogl_display;
|
||||
uint64_t state;
|
||||
unsigned i;
|
||||
|
||||
@ -673,6 +731,14 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
meta_output->name, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
cogl_context = clutter_backend_get_cogl_context (backend);
|
||||
cogl_display = cogl_context_get_display (cogl_context);
|
||||
|
||||
for (i = 0; i < manager->n_crtcs; i++)
|
||||
cogl_kms_display_set_ignore_crtc (cogl_display, manager->crtcs[i].crtc_id,
|
||||
mode != META_POWER_SAVE_ON);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -893,6 +959,23 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
drmModeCrtcSetGamma (manager_kms->fd, crtc->crtc_id, size, red, green, blue);
|
||||
}
|
||||
|
||||
static void
|
||||
on_uevent (GUdevClient *client,
|
||||
const char *action,
|
||||
GUdevDevice *device,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (user_data);
|
||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
|
||||
|
||||
if (!g_udev_device_get_property_as_boolean (device, "HOTPLUG"))
|
||||
return;
|
||||
|
||||
meta_monitor_manager_read_current_config (manager);
|
||||
|
||||
meta_monitor_manager_on_hotplug (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
|
||||
{
|
||||
@ -907,6 +990,24 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
|
||||
cogl_renderer = cogl_display_get_renderer (cogl_display);
|
||||
|
||||
manager_kms->fd = cogl_kms_renderer_get_kms_fd (cogl_renderer);
|
||||
|
||||
const char *subsystems[2] = { "drm", NULL };
|
||||
manager_kms->udev = g_udev_client_new (subsystems);
|
||||
g_signal_connect (manager_kms->udev, "uevent",
|
||||
G_CALLBACK (on_uevent), manager_kms);
|
||||
|
||||
manager_kms->desktop_settings = g_settings_new ("org.gnome.desktop.interface");
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_dispose (GObject *object)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
|
||||
|
||||
g_clear_object (&manager_kms->udev);
|
||||
g_clear_object (&manager_kms->desktop_settings);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -925,6 +1026,7 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
|
||||
MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_monitor_manager_kms_dispose;
|
||||
object_class->finalize = meta_monitor_manager_kms_finalize;
|
||||
|
||||
manager_class->read_current = meta_monitor_manager_kms_read_current;
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef META_MONITOR_MANAGER_KMS_H
|
||||
#define META_MONITOR_MANAGER_KMS_H
|
||||
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#define META_TYPE_MONITOR_MANAGER_KMS (meta_monitor_manager_kms_get_type ())
|
||||
#define META_MONITOR_MANAGER_KMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_KMS, MetaMonitorManagerKms))
|
||||
|
@ -65,20 +65,29 @@ struct _MetaBackendX11Private
|
||||
uint8_t xkb_error_base;
|
||||
|
||||
struct xkb_keymap *keymap;
|
||||
gchar *keymap_layouts;
|
||||
gchar *keymap_variants;
|
||||
gchar *keymap_options;
|
||||
};
|
||||
typedef struct _MetaBackendX11Private MetaBackendX11Private;
|
||||
|
||||
static void apply_keymap (MetaBackendX11 *x11);
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendX11, meta_backend_x11, META_TYPE_BACKEND);
|
||||
|
||||
static void
|
||||
handle_alarm_notify (MetaBackend *backend,
|
||||
XEvent *event)
|
||||
{
|
||||
int i;
|
||||
GHashTableIter iter;
|
||||
gpointer value;
|
||||
|
||||
for (i = 0; i <= backend->device_id_max; i++)
|
||||
if (backend->device_monitors[i])
|
||||
meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*) event);
|
||||
g_hash_table_iter_init (&iter, backend->device_monitors);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &value))
|
||||
{
|
||||
MetaIdleMonitor *device_monitor = META_IDLE_MONITOR (value);
|
||||
meta_idle_monitor_xsync_handle_xevent (device_monitor, (XSyncAlarmNotifyEvent*) event);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -120,6 +129,39 @@ translate_device_event (MetaBackendX11 *x11,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
translate_crossing_event (MetaBackendX11 *x11,
|
||||
XIEnterEvent *enter_event)
|
||||
{
|
||||
/* Throw out weird events generated by grabs. */
|
||||
if (enter_event->mode == XINotifyGrab ||
|
||||
enter_event->mode == XINotifyUngrab)
|
||||
{
|
||||
enter_event->event = None;
|
||||
return;
|
||||
}
|
||||
|
||||
enter_event->event = meta_backend_x11_get_xwindow (x11);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_device_change (MetaBackendX11 *x11,
|
||||
XIEvent *event)
|
||||
{
|
||||
XIDeviceChangedEvent *device_changed;
|
||||
|
||||
if (event->evtype != XI_DeviceChanged)
|
||||
return;
|
||||
|
||||
device_changed = (XIDeviceChangedEvent *) event;
|
||||
|
||||
if (device_changed->reason != XISlaveSwitch)
|
||||
return;
|
||||
|
||||
meta_backend_update_last_device (META_BACKEND (x11),
|
||||
device_changed->sourceid);
|
||||
}
|
||||
|
||||
/* Clutter makes the assumption that there is only one X window
|
||||
* per stage, which is a valid assumption to make for a generic
|
||||
* application toolkit. As such, it will ignore any events sent
|
||||
@ -131,7 +173,32 @@ translate_device_event (MetaBackendX11 *x11,
|
||||
*/
|
||||
static void
|
||||
maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
|
||||
XEvent *event)
|
||||
XIEvent *input_event)
|
||||
{
|
||||
switch (input_event->evtype)
|
||||
{
|
||||
case XI_Motion:
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchUpdate:
|
||||
case XI_TouchEnd:
|
||||
translate_device_event (x11, (XIDeviceEvent *) input_event);
|
||||
break;
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
translate_crossing_event (x11, (XIEnterEvent *) input_event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_input_event (MetaBackendX11 *x11,
|
||||
XEvent *event)
|
||||
{
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
@ -140,21 +207,10 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
|
||||
{
|
||||
XIEvent *input_event = (XIEvent *) event->xcookie.data;
|
||||
|
||||
switch (input_event->evtype)
|
||||
{
|
||||
case XI_Motion:
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
case XI_KeyPress:
|
||||
case XI_KeyRelease:
|
||||
case XI_TouchBegin:
|
||||
case XI_TouchUpdate:
|
||||
case XI_TouchEnd:
|
||||
translate_device_event (x11, (XIDeviceEvent *) input_event);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (input_event->evtype == XI_DeviceChanged)
|
||||
handle_device_change (x11, input_event);
|
||||
else
|
||||
maybe_spoof_event_as_stage_event (x11, input_event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,7 +279,7 @@ handle_host_xevent (MetaBackend *backend,
|
||||
|
||||
if (!bypass_clutter)
|
||||
{
|
||||
maybe_spoof_event_as_stage_event (x11, event);
|
||||
handle_input_event (x11, event);
|
||||
clutter_x11_handle_event (event);
|
||||
}
|
||||
|
||||
@ -326,6 +382,17 @@ take_touch_grab (MetaBackend *backend)
|
||||
False, &mask, 1, &mods);
|
||||
}
|
||||
|
||||
static void
|
||||
on_device_added (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDevice *device,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (user_data);
|
||||
|
||||
if (clutter_input_device_get_device_type (device) == CLUTTER_KEYBOARD_DEVICE)
|
||||
apply_keymap (x11);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_post_init (MetaBackend *backend)
|
||||
{
|
||||
@ -376,6 +443,9 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
||||
meta_fatal ("X server doesn't have the XKB extension, version %d.%d or newer\n",
|
||||
XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION);
|
||||
|
||||
g_signal_connect_object (clutter_device_manager_get_default (), "device-added",
|
||||
G_CALLBACK (on_device_added), backend, 0);
|
||||
|
||||
META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
|
||||
}
|
||||
|
||||
@ -560,21 +630,22 @@ upload_xkb_description (Display *xdisplay,
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_set_keymap (MetaBackend *backend,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options)
|
||||
apply_keymap (MetaBackendX11 *x11)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
XkbRF_RulesRec *xkb_rules;
|
||||
XkbRF_VarDefsRec xkb_var_defs = { 0 };
|
||||
gchar *rules_file_path;
|
||||
|
||||
if (!priv->keymap_layouts ||
|
||||
!priv->keymap_variants ||
|
||||
!priv->keymap_options)
|
||||
return;
|
||||
|
||||
get_xkbrf_var_defs (priv->xdisplay,
|
||||
layouts,
|
||||
variants,
|
||||
options,
|
||||
priv->keymap_layouts,
|
||||
priv->keymap_variants,
|
||||
priv->keymap_options,
|
||||
&rules_file_path,
|
||||
&xkb_var_defs);
|
||||
|
||||
@ -598,6 +669,25 @@ meta_backend_x11_set_keymap (MetaBackend *backend,
|
||||
g_free (rules_file_path);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_set_keymap (MetaBackend *backend,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
g_free (priv->keymap_layouts);
|
||||
priv->keymap_layouts = g_strdup (layouts);
|
||||
g_free (priv->keymap_variants);
|
||||
priv->keymap_variants = g_strdup (variants);
|
||||
g_free (priv->keymap_options);
|
||||
priv->keymap_options = g_strdup (options);
|
||||
|
||||
apply_keymap (x11);
|
||||
}
|
||||
|
||||
static struct xkb_keymap *
|
||||
meta_backend_x11_get_keymap (MetaBackend *backend)
|
||||
{
|
||||
|
216
src/backends/x11/meta-barrier-x11.c
Normal file
216
src/backends/x11/meta-barrier-x11.c
Normal file
@ -0,0 +1,216 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014-2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:barrier-x11
|
||||
* @Title: MetaBarrierImplX11
|
||||
* @Short_Description: Pointer barriers implementation for X11
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef HAVE_XI23
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <meta/barrier.h>
|
||||
#include "backends/x11/meta-barrier-x11.h"
|
||||
#include "display-private.h"
|
||||
|
||||
struct _MetaBarrierImplX11Private
|
||||
{
|
||||
MetaBarrier *barrier;
|
||||
PointerBarrier xbarrier;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaBarrierImplX11, meta_barrier_impl_x11,
|
||||
META_TYPE_BARRIER_IMPL)
|
||||
|
||||
static gboolean
|
||||
_meta_barrier_impl_x11_is_active (MetaBarrierImpl *impl)
|
||||
{
|
||||
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
|
||||
MetaBarrierImplX11Private *priv =
|
||||
meta_barrier_impl_x11_get_instance_private (self);
|
||||
|
||||
return priv->xbarrier != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_meta_barrier_impl_x11_release (MetaBarrierImpl *impl,
|
||||
MetaBarrierEvent *event)
|
||||
{
|
||||
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
|
||||
MetaBarrierImplX11Private *priv =
|
||||
meta_barrier_impl_x11_get_instance_private (self);
|
||||
MetaDisplay *display = priv->barrier->priv->display;
|
||||
|
||||
if (META_DISPLAY_HAS_XINPUT_23 (display))
|
||||
{
|
||||
XIBarrierReleasePointer (display->xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
priv->xbarrier, event->event_id);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_meta_barrier_impl_x11_destroy (MetaBarrierImpl *impl)
|
||||
{
|
||||
MetaBarrierImplX11 *self = META_BARRIER_IMPL_X11 (impl);
|
||||
MetaBarrierImplX11Private *priv =
|
||||
meta_barrier_impl_x11_get_instance_private (self);
|
||||
MetaDisplay *display = priv->barrier->priv->display;
|
||||
Display *dpy;
|
||||
|
||||
if (display == NULL)
|
||||
return;
|
||||
|
||||
dpy = display->xdisplay;
|
||||
|
||||
if (!meta_barrier_is_active (priv->barrier))
|
||||
return;
|
||||
|
||||
XFixesDestroyPointerBarrier (dpy, priv->xbarrier);
|
||||
g_hash_table_remove (display->xids, &priv->xbarrier);
|
||||
priv->xbarrier = 0;
|
||||
}
|
||||
|
||||
MetaBarrierImpl *
|
||||
meta_barrier_impl_x11_new (MetaBarrier *barrier)
|
||||
{
|
||||
MetaBarrierImplX11 *self;
|
||||
MetaBarrierImplX11Private *priv;
|
||||
MetaDisplay *display = barrier->priv->display;
|
||||
Display *dpy;
|
||||
Window root;
|
||||
|
||||
if (display == NULL)
|
||||
{
|
||||
g_warning ("A display must be provided when constructing a barrier.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self = g_object_new (META_TYPE_BARRIER_IMPL_X11, NULL);
|
||||
priv = meta_barrier_impl_x11_get_instance_private (self);
|
||||
priv->barrier = barrier;
|
||||
|
||||
dpy = display->xdisplay;
|
||||
root = DefaultRootWindow (dpy);
|
||||
|
||||
priv->xbarrier = XFixesCreatePointerBarrier (dpy, root,
|
||||
barrier->priv->x1,
|
||||
barrier->priv->y1,
|
||||
barrier->priv->x2,
|
||||
barrier->priv->y2,
|
||||
barrier->priv->directions,
|
||||
0, NULL);
|
||||
|
||||
g_hash_table_insert (display->xids, &priv->xbarrier, barrier);
|
||||
|
||||
return META_BARRIER_IMPL (self);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_fire_xevent (MetaBarrier *barrier,
|
||||
XIBarrierEvent *xevent)
|
||||
{
|
||||
MetaBarrierEvent *event = g_slice_new0 (MetaBarrierEvent);
|
||||
|
||||
event->ref_count = 1;
|
||||
event->event_id = xevent->eventid;
|
||||
event->time = xevent->time;
|
||||
event->dt = xevent->dtime;
|
||||
|
||||
event->x = xevent->root_x;
|
||||
event->y = xevent->root_y;
|
||||
event->dx = xevent->dx;
|
||||
event->dy = xevent->dy;
|
||||
|
||||
event->released = (xevent->flags & XIBarrierPointerReleased) != 0;
|
||||
event->grabbed = (xevent->flags & XIBarrierDeviceIsGrabbed) != 0;
|
||||
|
||||
switch (xevent->evtype)
|
||||
{
|
||||
case XI_BarrierHit:
|
||||
_meta_barrier_emit_hit_signal (barrier, event);
|
||||
break;
|
||||
case XI_BarrierLeave:
|
||||
_meta_barrier_emit_left_signal (barrier, event);
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
meta_barrier_event_unref (event);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_display_process_barrier_xevent (MetaDisplay *display,
|
||||
XIEvent *event)
|
||||
{
|
||||
MetaBarrier *barrier;
|
||||
XIBarrierEvent *xev;
|
||||
|
||||
if (event == NULL)
|
||||
return FALSE;
|
||||
|
||||
switch (event->evtype)
|
||||
{
|
||||
case XI_BarrierHit:
|
||||
case XI_BarrierLeave:
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
xev = (XIBarrierEvent *) event;
|
||||
barrier = g_hash_table_lookup (display->xids, &xev->barrier);
|
||||
if (barrier != NULL)
|
||||
{
|
||||
meta_barrier_fire_xevent (barrier, xev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_impl_x11_class_init (MetaBarrierImplX11Class *klass)
|
||||
{
|
||||
MetaBarrierImplClass *impl_class = META_BARRIER_IMPL_CLASS (klass);
|
||||
|
||||
impl_class->is_active = _meta_barrier_impl_x11_is_active;
|
||||
impl_class->release = _meta_barrier_impl_x11_release;
|
||||
impl_class->destroy = _meta_barrier_impl_x11_destroy;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_barrier_impl_x11_init (MetaBarrierImplX11 *self)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* HAVE_XI23 */
|
59
src/backends/x11/meta-barrier-x11.h
Normal file
59
src/backends/x11/meta-barrier-x11.h
Normal file
@ -0,0 +1,59 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Written by:
|
||||
* Jonas Ådahl <jadahl@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef META_BARRIER_X11_H
|
||||
#define META_BARRIER_X11_H
|
||||
|
||||
#include "backends/meta-barrier-private.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define META_TYPE_BARRIER_IMPL_X11 (meta_barrier_impl_x11_get_type ())
|
||||
#define META_BARRIER_IMPL_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BARRIER_IMPL_X11, MetaBarrierImplX11))
|
||||
#define META_BARRIER_IMPL_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BARRIER_IMPL_X11, MetaBarrierImplX11Class))
|
||||
#define META_IS_BARRIER_IMPL_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BARRIER_IMPL_X11))
|
||||
#define META_IS_BARRIER_IMPL_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BARRIER_IMPL_X11))
|
||||
#define META_BARRIER_IMPL_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BARRIER_IMPL_X11, MetaBarrierImplX11Class))
|
||||
|
||||
typedef struct _MetaBarrierImplX11 MetaBarrierImplX11;
|
||||
typedef struct _MetaBarrierImplX11Class MetaBarrierImplX11Class;
|
||||
typedef struct _MetaBarrierImplX11Private MetaBarrierImplX11Private;
|
||||
|
||||
struct _MetaBarrierImplX11
|
||||
{
|
||||
MetaBarrierImpl parent;
|
||||
};
|
||||
|
||||
struct _MetaBarrierImplX11Class
|
||||
{
|
||||
MetaBarrierImplClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_barrier_impl_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
MetaBarrierImpl *meta_barrier_impl_x11_new (MetaBarrier *barrier);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* META_BARRIER_X11_H1 */
|
@ -26,6 +26,8 @@
|
||||
|
||||
#include "meta-cursor-renderer-x11.h"
|
||||
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
#include "meta-stage.h"
|
||||
|
||||
|
255
src/backends/x11/meta-input-settings-x11.c
Normal file
255
src/backends/x11/meta-input-settings-x11.c
Normal file
@ -0,0 +1,255 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
#include "meta-input-settings-x11.h"
|
||||
|
||||
#include <gdk/gdkx.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include <meta/errors.h>
|
||||
|
||||
G_DEFINE_TYPE (MetaInputSettingsX11, meta_input_settings_x11, META_TYPE_INPUT_SETTINGS)
|
||||
|
||||
static void
|
||||
change_property (ClutterInputDevice *device,
|
||||
const gchar *property,
|
||||
Atom type,
|
||||
int format,
|
||||
void *data,
|
||||
gulong nitems)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
gulong nitems_ret, bytes_after_ret;
|
||||
int rc, device_id, format_ret;
|
||||
Atom property_atom, type_ret;
|
||||
guchar *data_ret;
|
||||
|
||||
property_atom = XInternAtom (xdisplay, property, False);
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
rc = XIGetProperty (xdisplay, device_id, property_atom,
|
||||
0, 0, False, type, &type_ret, &format_ret,
|
||||
&nitems_ret, &bytes_after_ret, &data_ret);
|
||||
|
||||
meta_XFree (data_ret);
|
||||
|
||||
if (rc == Success && type_ret == type && format_ret == format)
|
||||
XIChangeProperty (xdisplay, device_id, property_atom, type,
|
||||
format, XIPropModeReplace, data, nitems);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_send_events (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopDeviceSendEvents mode)
|
||||
{
|
||||
guchar values[2] = { 0 }; /* disabled, disabled-on-external-mouse */
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED:
|
||||
values[0] = 1;
|
||||
break;
|
||||
case G_DESKTOP_DEVICE_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE:
|
||||
values[1] = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
change_property (device, "libinput Send Events Mode Enabled",
|
||||
XA_INTEGER, 8, &values, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_matrix (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gfloat matrix[6])
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
gfloat full_matrix[9] = { matrix[0], matrix[1], matrix[2],
|
||||
matrix[3], matrix[4], matrix[5],
|
||||
0, 0, 1 };
|
||||
|
||||
change_property (device, "Coordinate Transformation Matrix",
|
||||
XInternAtom (xdisplay, "FLOAT", False),
|
||||
32, &full_matrix, 9);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_speed (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gdouble speed)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
gfloat value = speed;
|
||||
|
||||
change_property (device, "libinput Accel Speed",
|
||||
XInternAtom (xdisplay, "FLOAT", False),
|
||||
32, &value, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_left_handed (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled)
|
||||
{
|
||||
guchar value = (enabled) ? 1 : 0;
|
||||
|
||||
change_property (device, "libinput Left Handed Enabled",
|
||||
XA_INTEGER, 8, &value, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_tap_enabled (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean enabled)
|
||||
{
|
||||
guchar value = (enabled) ? 1 : 0;
|
||||
|
||||
change_property (device, "libinput Tapping Enabled",
|
||||
XA_INTEGER, 8, &value, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_invert_scroll (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
gboolean inverted)
|
||||
{
|
||||
guchar value = (inverted) ? 1 : 0;
|
||||
|
||||
change_property (device, "libinput Natural Scrolling Enabled",
|
||||
XA_INTEGER, 8, &value, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_scroll_method (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadScrollMethod mode)
|
||||
{
|
||||
guchar values[3] = { 0 }; /* 2fg, edge, button. The last value is unused */
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_DISABLED:
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_EDGE_SCROLLING:
|
||||
values[1] = 1;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_SCROLL_METHOD_TWO_FINGER_SCROLLING:
|
||||
values[0] = 1;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
change_property (device, "libinput Scroll Method Enabled",
|
||||
XA_INTEGER, 8, &values, 3);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_scroll_button (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
guint button)
|
||||
{
|
||||
change_property (device, "libinput Scroll Method Enabled",
|
||||
XA_INTEGER, 32, &button, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_click_method (MetaInputSettings *settings,
|
||||
ClutterInputDevice *device,
|
||||
GDesktopTouchpadClickMethod mode)
|
||||
{
|
||||
guchar values[2] = { 0 }; /* buttonareas, clickfinger */
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_NONE:
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_AREAS:
|
||||
values[0] = 1;
|
||||
break;
|
||||
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_DEFAULT:
|
||||
/* XXX: We can't be much smarter yet, x11 doesn't expose default settings */
|
||||
case G_DESKTOP_TOUCHPAD_CLICK_METHOD_FINGERS:
|
||||
values[1] = 1;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return;
|
||||
}
|
||||
|
||||
change_property (device, "libinput Click Method Enabled",
|
||||
XA_INTEGER, 8, &values, 2);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_set_keyboard_repeat (MetaInputSettings *settings,
|
||||
gboolean enabled,
|
||||
guint delay,
|
||||
guint interval)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
XAutoRepeatOn (xdisplay);
|
||||
XkbSetAutoRepeatRate (xdisplay, XkbUseCoreKbd, delay, interval);
|
||||
}
|
||||
else
|
||||
{
|
||||
XAutoRepeatOff (xdisplay);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_class_init (MetaInputSettingsX11Class *klass)
|
||||
{
|
||||
MetaInputSettingsClass *input_settings_class = META_INPUT_SETTINGS_CLASS (klass);
|
||||
|
||||
input_settings_class->set_send_events = meta_input_settings_x11_set_send_events;
|
||||
input_settings_class->set_matrix = meta_input_settings_x11_set_matrix;
|
||||
input_settings_class->set_speed = meta_input_settings_x11_set_speed;
|
||||
input_settings_class->set_left_handed = meta_input_settings_x11_set_left_handed;
|
||||
input_settings_class->set_tap_enabled = meta_input_settings_x11_set_tap_enabled;
|
||||
input_settings_class->set_invert_scroll = meta_input_settings_x11_set_invert_scroll;
|
||||
input_settings_class->set_scroll_method = meta_input_settings_x11_set_scroll_method;
|
||||
input_settings_class->set_scroll_button = meta_input_settings_x11_set_scroll_button;
|
||||
input_settings_class->set_click_method = meta_input_settings_x11_set_click_method;
|
||||
input_settings_class->set_keyboard_repeat = meta_input_settings_x11_set_keyboard_repeat;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_input_settings_x11_init (MetaInputSettingsX11 *settings)
|
||||
{
|
||||
}
|
49
src/backends/x11/meta-input-settings-x11.h
Normal file
49
src/backends/x11/meta-input-settings-x11.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_INPUT_SETTINGS_X11_H
|
||||
#define META_INPUT_SETTINGS_X11_H
|
||||
|
||||
#include "meta-input-settings-private.h"
|
||||
|
||||
#define META_TYPE_INPUT_SETTINGS_X11 (meta_input_settings_x11_get_type ())
|
||||
#define META_INPUT_SETTINGS_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_INPUT_SETTINGS_X11, MetaInputSettingsX11))
|
||||
#define META_INPUT_SETTINGS_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_INPUT_SETTINGS_X11, MetaInputSettingsX11Class))
|
||||
#define META_IS_INPUT_SETTINGS_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_INPUT_SETTINGS_X11))
|
||||
#define META_IS_INPUT_SETTINGS_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_INPUT_SETTINGS_X11))
|
||||
#define META_INPUT_SETTINGS_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_INPUT_SETTINGS_X11, MetaInputSettingsX11Class))
|
||||
|
||||
typedef struct _MetaInputSettingsX11 MetaInputSettingsX11;
|
||||
typedef struct _MetaInputSettingsX11Class MetaInputSettingsX11Class;
|
||||
|
||||
struct _MetaInputSettingsX11
|
||||
{
|
||||
MetaInputSettings parent_instance;
|
||||
};
|
||||
|
||||
struct _MetaInputSettingsX11Class
|
||||
{
|
||||
MetaInputSettingsClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_input_settings_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#endif /* META_INPUT_SETTINGS_X11_H */
|
@ -41,7 +41,6 @@
|
||||
#include "meta-backend-x11.h"
|
||||
#include <meta/main.h>
|
||||
#include <meta/errors.h>
|
||||
#include "edid.h"
|
||||
#include "meta-monitor-config.h"
|
||||
|
||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
@ -57,7 +56,6 @@ struct _MetaMonitorManagerXrandr
|
||||
|
||||
Display *xdisplay;
|
||||
XRRScreenResources *resources;
|
||||
int time;
|
||||
int rr_event_base;
|
||||
int rr_error_base;
|
||||
};
|
||||
@ -140,11 +138,63 @@ meta_monitor_transform_from_xrandr_all (Rotation rotation)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_integer_property (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output, const char *propname,
|
||||
gint *value)
|
||||
{
|
||||
gboolean exists = FALSE;
|
||||
Atom atom, actual_type;
|
||||
int actual_format;
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *buffer;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, XA_INTEGER,
|
||||
&actual_type, &actual_format,
|
||||
&nitems, &bytes_after, &buffer);
|
||||
|
||||
exists = (actual_type == XA_INTEGER && actual_format == 32 && nitems == 1);
|
||||
|
||||
if (exists && value != NULL)
|
||||
*value = ((int*)buffer)[0];
|
||||
|
||||
XFree (buffer);
|
||||
return exists;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_property_exists (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output, const char *propname)
|
||||
{
|
||||
gboolean exists = FALSE;
|
||||
Atom atom, actual_type;
|
||||
int actual_format;
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *buffer;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, AnyPropertyType,
|
||||
&actual_type, &actual_format,
|
||||
&nitems, &bytes_after, &buffer);
|
||||
|
||||
exists = (actual_type != None);
|
||||
|
||||
XFree (buffer);
|
||||
return exists;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output, const char *propname)
|
||||
{
|
||||
gboolean value;
|
||||
gboolean value = FALSE;
|
||||
Atom atom, actual_type;
|
||||
int actual_format;
|
||||
unsigned long nitems, bytes_after;
|
||||
@ -158,12 +208,12 @@ output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
&actual_type, &actual_format,
|
||||
&nitems, &bytes_after, &buffer);
|
||||
|
||||
if (actual_type != XA_CARDINAL || actual_format != 32 ||
|
||||
nitems < 1)
|
||||
return FALSE;
|
||||
if (actual_type != XA_CARDINAL || actual_format != 32 || nitems < 1)
|
||||
goto out;
|
||||
|
||||
value = ((int*)buffer)[0];
|
||||
|
||||
out:
|
||||
XFree (buffer);
|
||||
return value;
|
||||
}
|
||||
@ -187,7 +237,7 @@ static int
|
||||
output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
gboolean value;
|
||||
int value = -1;
|
||||
Atom atom, actual_type;
|
||||
int actual_format;
|
||||
unsigned long nitems, bytes_after;
|
||||
@ -201,14 +251,17 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
&actual_type, &actual_format,
|
||||
&nitems, &bytes_after, &buffer);
|
||||
|
||||
if (actual_type != XA_INTEGER || actual_format != 32 ||
|
||||
nitems < 1)
|
||||
return -1;
|
||||
if (actual_type != XA_INTEGER || actual_format != 32 || nitems < 1)
|
||||
goto out;
|
||||
|
||||
value = ((int*)buffer)[0];
|
||||
|
||||
out:
|
||||
XFree (buffer);
|
||||
return normalize_backlight (output, value);
|
||||
if (value > 0)
|
||||
return normalize_backlight (output, value);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -327,7 +380,170 @@ static gboolean
|
||||
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
return output_get_boolean_property (manager_xrandr, output, "hotplug_mode_update");
|
||||
return output_get_property_exists (manager_xrandr, output, "hotplug_mode_update");
|
||||
}
|
||||
|
||||
static gint
|
||||
output_get_suggested_x (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
gint val;
|
||||
if (output_get_integer_property (manager_xrandr, output, "suggested X", &val))
|
||||
return val;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static gint
|
||||
output_get_suggested_y (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
gint val;
|
||||
if (output_get_integer_property (manager_xrandr, output, "suggested Y", &val))
|
||||
return val;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static MetaConnectorType
|
||||
connector_type_from_atom (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
Atom atom)
|
||||
{
|
||||
Display *xdpy = manager_xrandr->xdisplay;
|
||||
|
||||
if (atom == XInternAtom (xdpy, "HDMI", True))
|
||||
return META_CONNECTOR_TYPE_HDMIA;
|
||||
if (atom == XInternAtom (xdpy, "VGA", True))
|
||||
return META_CONNECTOR_TYPE_VGA;
|
||||
/* Doesn't have a DRM equivalent, but means an internal panel.
|
||||
* We could pick either LVDS or eDP here. */
|
||||
if (atom == XInternAtom (xdpy, "Panel", True))
|
||||
return META_CONNECTOR_TYPE_LVDS;
|
||||
if (atom == XInternAtom (xdpy, "DVI", True) || atom == XInternAtom (xdpy, "DVI-I", True))
|
||||
return META_CONNECTOR_TYPE_DVII;
|
||||
if (atom == XInternAtom (xdpy, "DVI-A", True))
|
||||
return META_CONNECTOR_TYPE_DVIA;
|
||||
if (atom == XInternAtom (xdpy, "DVI-D", True))
|
||||
return META_CONNECTOR_TYPE_DVID;
|
||||
if (atom == XInternAtom (xdpy, "DisplayPort", True))
|
||||
return META_CONNECTOR_TYPE_DisplayPort;
|
||||
|
||||
if (atom == XInternAtom (xdpy, "TV", True))
|
||||
return META_CONNECTOR_TYPE_TV;
|
||||
if (atom == XInternAtom (xdpy, "TV-Composite", True))
|
||||
return META_CONNECTOR_TYPE_Composite;
|
||||
if (atom == XInternAtom (xdpy, "TV-SVideo", True))
|
||||
return META_CONNECTOR_TYPE_SVIDEO;
|
||||
/* Another set of mismatches. */
|
||||
if (atom == XInternAtom (xdpy, "TV-SCART", True))
|
||||
return META_CONNECTOR_TYPE_TV;
|
||||
if (atom == XInternAtom (xdpy, "TV-C4", True))
|
||||
return META_CONNECTOR_TYPE_TV;
|
||||
|
||||
return META_CONNECTOR_TYPE_Unknown;
|
||||
}
|
||||
|
||||
static MetaConnectorType
|
||||
output_get_connector_type_from_prop (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
MetaConnectorType ret = META_CONNECTOR_TYPE_Unknown;
|
||||
Atom atom, actual_type, connector_type_atom;
|
||||
int actual_format;
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *buffer;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "ConnectorType", False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, XA_ATOM,
|
||||
&actual_type, &actual_format,
|
||||
&nitems, &bytes_after, &buffer);
|
||||
|
||||
if (actual_type != XA_ATOM || actual_format != 32 || nitems < 1)
|
||||
goto out;
|
||||
|
||||
connector_type_atom = ((Atom *) buffer)[0];
|
||||
ret = connector_type_from_atom (manager_xrandr, connector_type_atom);
|
||||
|
||||
out:
|
||||
meta_XFree (buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MetaConnectorType
|
||||
output_get_connector_type_from_name (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
const char *name = output->name;
|
||||
|
||||
/* drmmode_display.c, which was copy/pasted across all the FOSS
|
||||
* xf86-video-* drivers, seems to name its outputs based on the
|
||||
* connector type, so look for that....
|
||||
*
|
||||
* SNA has its own naming scheme, because what else did you expect
|
||||
* from SNA, but it's not too different, so we can thankfully use
|
||||
* that with minor changes.
|
||||
*
|
||||
* http://cgit.freedesktop.org/xorg/xserver/tree/hw/xfree86/drivers/modesetting/drmmode_display.c#n953
|
||||
* http://cgit.freedesktop.org/xorg/driver/xf86-video-intel/tree/src/sna/sna_display.c#n3486
|
||||
*/
|
||||
|
||||
if (g_str_has_prefix (name, "DVI"))
|
||||
return META_CONNECTOR_TYPE_DVII;
|
||||
if (g_str_has_prefix (name, "LVDS"))
|
||||
return META_CONNECTOR_TYPE_LVDS;
|
||||
if (g_str_has_prefix (name, "HDMI"))
|
||||
return META_CONNECTOR_TYPE_HDMIA;
|
||||
if (g_str_has_prefix (name, "VGA"))
|
||||
return META_CONNECTOR_TYPE_VGA;
|
||||
/* SNA uses DP, not DisplayPort. Test for both. */
|
||||
if (g_str_has_prefix (name, "DP") || g_str_has_prefix (name, "DisplayPort"))
|
||||
return META_CONNECTOR_TYPE_DisplayPort;
|
||||
if (g_str_has_prefix (name, "eDP"))
|
||||
return META_CONNECTOR_TYPE_eDP;
|
||||
if (g_str_has_prefix (name, "Virtual"))
|
||||
return META_CONNECTOR_TYPE_VIRTUAL;
|
||||
if (g_str_has_prefix (name, "Composite"))
|
||||
return META_CONNECTOR_TYPE_VGA;
|
||||
if (g_str_has_prefix (name, "S-video"))
|
||||
return META_CONNECTOR_TYPE_SVIDEO;
|
||||
if (g_str_has_prefix (name, "TV"))
|
||||
return META_CONNECTOR_TYPE_TV;
|
||||
if (g_str_has_prefix (name, "CTV"))
|
||||
return META_CONNECTOR_TYPE_Composite;
|
||||
if (g_str_has_prefix (name, "DSI"))
|
||||
return META_CONNECTOR_TYPE_DSI;
|
||||
if (g_str_has_prefix (name, "DIN"))
|
||||
return META_CONNECTOR_TYPE_9PinDIN;
|
||||
|
||||
return META_CONNECTOR_TYPE_Unknown;
|
||||
}
|
||||
|
||||
static MetaConnectorType
|
||||
output_get_connector_type (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
MetaConnectorType ret;
|
||||
|
||||
/* The "ConnectorType" property is considered mandatory since RandR 1.3,
|
||||
* but none of the FOSS drivers support it, because we're a bunch of
|
||||
* professional software developers.
|
||||
*
|
||||
* Try poking it first, without any expectations that it will work.
|
||||
* If it's not there, we thankfully have other bonghits to try next.
|
||||
*/
|
||||
ret = output_get_connector_type_from_prop (manager_xrandr, output);
|
||||
if (ret != META_CONNECTOR_TYPE_Unknown)
|
||||
return ret;
|
||||
|
||||
/* Fall back to heuristics based on the output name. */
|
||||
ret = output_get_connector_type_from_name (manager_xrandr, output);
|
||||
if (ret != META_CONNECTOR_TYPE_Unknown)
|
||||
return ret;
|
||||
|
||||
return META_CONNECTOR_TYPE_Unknown;
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -336,12 +552,6 @@ get_xmode_name (XRRModeInfo *xmode)
|
||||
int width = xmode->width;
|
||||
int height = xmode->height;
|
||||
|
||||
if (xmode->hSkew != 0)
|
||||
{
|
||||
width += 2 * (xmode->hSkew >> 8);
|
||||
height += 2 * (xmode->hSkew & 0xff);
|
||||
}
|
||||
|
||||
return g_strdup_printf ("%dx%d", width, height);
|
||||
}
|
||||
|
||||
@ -410,7 +620,6 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
return;
|
||||
|
||||
manager_xrandr->resources = resources;
|
||||
manager_xrandr->time = resources->configTimestamp;
|
||||
manager->n_outputs = resources->noutput;
|
||||
manager->n_crtcs = resources->ncrtc;
|
||||
manager->n_modes = resources->nmode;
|
||||
@ -479,45 +688,21 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
if (output->connection != RR_Disconnected)
|
||||
{
|
||||
GBytes *edid;
|
||||
MonitorInfo *parsed_edid;
|
||||
|
||||
meta_output->winsys_id = resources->outputs[i];
|
||||
meta_output->name = g_strdup (output->name);
|
||||
|
||||
edid = read_output_edid (manager_xrandr, meta_output->winsys_id);
|
||||
if (edid)
|
||||
{
|
||||
gsize len;
|
||||
meta_output_parse_edid (meta_output, edid);
|
||||
g_bytes_unref (edid);
|
||||
|
||||
parsed_edid = decode_edid (g_bytes_get_data (edid, &len));
|
||||
if (parsed_edid)
|
||||
{
|
||||
meta_output->vendor = g_strndup (parsed_edid->manufacturer_code, 4);
|
||||
if (parsed_edid->dsc_product_name[0])
|
||||
meta_output->product = g_strndup (parsed_edid->dsc_product_name, 14);
|
||||
else
|
||||
meta_output->product = g_strdup_printf ("0x%04x", (unsigned)parsed_edid->product_code);
|
||||
if (parsed_edid->dsc_serial_number[0])
|
||||
meta_output->serial = g_strndup (parsed_edid->dsc_serial_number, 14);
|
||||
else
|
||||
meta_output->serial = g_strdup_printf ("0x%08x", parsed_edid->serial_number);
|
||||
|
||||
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");
|
||||
}
|
||||
meta_output->width_mm = output->mm_width;
|
||||
meta_output->height_mm = output->mm_height;
|
||||
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
|
||||
meta_output->hotplug_mode_update = output_get_hotplug_mode_update (manager_xrandr, meta_output);
|
||||
meta_output->suggested_x = output_get_suggested_x (manager_xrandr, meta_output);
|
||||
meta_output->suggested_y = output_get_suggested_y (manager_xrandr, meta_output);
|
||||
meta_output->connector_type = output_get_connector_type (manager_xrandr, meta_output);
|
||||
|
||||
meta_output->n_modes = output->nmode;
|
||||
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
|
||||
@ -744,7 +929,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
XRRSetCrtcConfig (manager_xrandr->xdisplay,
|
||||
manager_xrandr->resources,
|
||||
(XID)crtc->crtc_id,
|
||||
manager_xrandr->time,
|
||||
CurrentTime,
|
||||
0, 0,
|
||||
None,
|
||||
RR_Rotate_0,
|
||||
@ -774,7 +959,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
XRRSetCrtcConfig (manager_xrandr->xdisplay,
|
||||
manager_xrandr->resources,
|
||||
(XID)crtc->crtc_id,
|
||||
manager_xrandr->time,
|
||||
CurrentTime,
|
||||
0, 0,
|
||||
None,
|
||||
RR_Rotate_0,
|
||||
@ -811,26 +996,12 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
unsigned int j, n_outputs;
|
||||
int width, height;
|
||||
Status ok;
|
||||
unsigned long old_controlled_mask;
|
||||
unsigned long new_controlled_mask;
|
||||
|
||||
mode = crtc_info->mode;
|
||||
|
||||
n_outputs = crtc_info->outputs->len;
|
||||
outputs = g_new (XID, n_outputs);
|
||||
|
||||
old_controlled_mask = 0;
|
||||
for (j = 0; j < manager->n_outputs; j++)
|
||||
{
|
||||
MetaOutput *output;
|
||||
|
||||
output = &manager->outputs[j];
|
||||
|
||||
if (output->crtc == crtc)
|
||||
old_controlled_mask |= 1UL << j;
|
||||
}
|
||||
|
||||
new_controlled_mask = 0;
|
||||
for (j = 0; j < n_outputs; j++)
|
||||
{
|
||||
MetaOutput *output;
|
||||
@ -839,25 +1010,14 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
new_controlled_mask |= 1UL << j;
|
||||
|
||||
outputs[j] = output->winsys_id;
|
||||
}
|
||||
|
||||
if (crtc->current_mode == mode &&
|
||||
crtc->rect.x == crtc_info->x &&
|
||||
crtc->rect.y == crtc_info->y &&
|
||||
crtc->transform == crtc_info->transform &&
|
||||
old_controlled_mask == new_controlled_mask)
|
||||
{
|
||||
/* No change */
|
||||
goto next;
|
||||
}
|
||||
|
||||
ok = XRRSetCrtcConfig (manager_xrandr->xdisplay,
|
||||
manager_xrandr->resources,
|
||||
(XID)crtc->crtc_id,
|
||||
manager_xrandr->time,
|
||||
CurrentTime,
|
||||
crtc_info->x, crtc_info->y,
|
||||
(XID)mode->mode_id,
|
||||
meta_monitor_transform_to_xrandr (crtc_info->transform),
|
||||
@ -865,7 +1025,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
|
||||
if (ok != Success)
|
||||
{
|
||||
meta_warning ("Configuring CRTC %d with mode %d (%d x %d @ %f) at position %d, %d and transfrom %u failed\n",
|
||||
meta_warning ("Configuring CRTC %d with mode %d (%d x %d @ %f) at position %d, %d and transform %u failed\n",
|
||||
(unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id),
|
||||
mode->width, mode->height, (float)mode->refresh_rate,
|
||||
crtc_info->x, crtc_info->y, crtc_info->transform);
|
||||
@ -998,16 +1158,6 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
XRRFreeGamma (gamma);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *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);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
|
||||
{
|
||||
@ -1067,63 +1217,26 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
|
||||
XEvent *event)
|
||||
{
|
||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
|
||||
MetaOutput *old_outputs;
|
||||
MetaCRTC *old_crtcs;
|
||||
MetaMonitorMode *old_modes;
|
||||
unsigned int n_old_outputs, n_old_modes;
|
||||
gboolean new_config;
|
||||
gboolean hotplug;
|
||||
|
||||
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);
|
||||
|
||||
new_config = manager_xrandr->resources->timestamp >=
|
||||
manager_xrandr->resources->configTimestamp;
|
||||
if (meta_monitor_manager_has_hotplug_mode_update (manager))
|
||||
meta_monitor_manager_read_current_config (manager);
|
||||
|
||||
hotplug = manager_xrandr->resources->timestamp < manager_xrandr->resources->configTimestamp;
|
||||
if (hotplug)
|
||||
{
|
||||
/* Check if the current intended configuration is a result of an
|
||||
XRandR call. Otherwise, hotplug_mode_update tells us to get
|
||||
a new preferred mode on hotplug events to handle dynamic
|
||||
guest resizing. */
|
||||
if (new_config)
|
||||
meta_monitor_manager_xrandr_rebuild_derived (manager);
|
||||
else
|
||||
meta_monitor_config_make_default (manager->config, manager);
|
||||
/* This is a hotplug event, so go ahead and build a new configuration. */
|
||||
meta_monitor_manager_on_hotplug (manager);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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 qxl and vbox drivers). */
|
||||
if (new_config || meta_monitor_config_match_current (manager->config, manager))
|
||||
meta_monitor_manager_xrandr_rebuild_derived (manager);
|
||||
else if (!meta_monitor_config_apply_stored (manager->config, manager))
|
||||
meta_monitor_config_make_default (manager->config, manager);
|
||||
/* Something else changed -- tell the world about it. */
|
||||
meta_monitor_manager_rebuild_derived (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;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
#ifndef META_MONITOR_MANAGER_XRANDR_H
|
||||
#define META_MONITOR_MANAGER_XRANDR_H
|
||||
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
#define META_TYPE_MONITOR_MANAGER_XRANDR (meta_monitor_manager_xrandr_get_type ())
|
||||
#define META_MONITOR_MANAGER_XRANDR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_MONITOR_MANAGER_XRANDR, MetaMonitorManagerXrandr))
|
||||
|
@ -23,7 +23,7 @@ struct _MetaCompositor
|
||||
guint server_time_is_monotonic_time : 1;
|
||||
guint no_mipmaps : 1;
|
||||
|
||||
ClutterActor *stage, *window_group, *top_window_group;
|
||||
ClutterActor *stage, *window_group, *top_window_group, *feedback_group;
|
||||
ClutterActor *background_actor;
|
||||
GList *windows;
|
||||
Window output;
|
||||
|
@ -185,6 +185,19 @@ meta_get_top_window_group_for_screen (MetaScreen *screen)
|
||||
return compositor->top_window_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_get_feedback_group_for_screen:
|
||||
* @screen: a #MetaScreen
|
||||
*
|
||||
* Returns: (transfer none): The feedback group corresponding to @screen
|
||||
*/
|
||||
ClutterActor *
|
||||
meta_get_feedback_group_for_screen (MetaScreen *screen)
|
||||
{
|
||||
MetaCompositor *compositor = get_compositor_for_screen (screen);
|
||||
return compositor->feedback_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_get_window_actors:
|
||||
* @screen: a #MetaScreen
|
||||
@ -478,9 +491,11 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
|
||||
compositor->window_group = meta_window_group_new (screen);
|
||||
compositor->top_window_group = meta_window_group_new (screen);
|
||||
compositor->feedback_group = meta_window_group_new (screen);
|
||||
|
||||
clutter_actor_add_child (compositor->stage, compositor->window_group);
|
||||
clutter_actor_add_child (compositor->stage, compositor->top_window_group);
|
||||
clutter_actor_add_child (compositor->stage, compositor->feedback_group);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
@ -599,6 +614,7 @@ set_unredirected_window (MetaCompositor *compositor,
|
||||
meta_window_actor_set_unredirected (window_actor, FALSE);
|
||||
}
|
||||
|
||||
meta_shape_cow_for_window (compositor, window);
|
||||
compositor->unredirected_window = window;
|
||||
|
||||
if (compositor->unredirected_window != NULL)
|
||||
@ -606,8 +622,6 @@ set_unredirected_window (MetaCompositor *compositor,
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (compositor->unredirected_window));
|
||||
meta_window_actor_set_unredirected (window_actor, TRUE);
|
||||
}
|
||||
|
||||
meta_shape_cow_for_window (compositor, compositor->unredirected_window);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -115,7 +115,7 @@ typedef enum {
|
||||
#define FRAGMENT_SHADER_CODE \
|
||||
"float t = 2.0 * length(position);\n" \
|
||||
"t = min(t, 1.0);\n" \
|
||||
"float pixel_brightness = 1 - t * vignette_sharpness;\n" \
|
||||
"float pixel_brightness = 1.0 - t * vignette_sharpness;\n" \
|
||||
"cogl_color_out.rgb = cogl_color_out.rgb * pixel_brightness;\n" \
|
||||
|
||||
typedef struct _MetaBackgroundLayer MetaBackgroundLayer;
|
||||
@ -708,6 +708,7 @@ on_background_changed (MetaBackground *background,
|
||||
MetaBackgroundActor *self)
|
||||
{
|
||||
invalidate_pipeline (self, CHANGED_BACKGROUND);
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -53,7 +53,7 @@ struct _MetaBackgroundImageCacheClass
|
||||
struct _MetaBackgroundImage
|
||||
{
|
||||
GObject parent_instance;
|
||||
char *filename;
|
||||
GFile *file;
|
||||
MetaBackgroundImageCache *cache;
|
||||
gboolean in_cache;
|
||||
gboolean loaded;
|
||||
@ -70,7 +70,7 @@ G_DEFINE_TYPE (MetaBackgroundImageCache, meta_background_image_cache, G_TYPE_OBJ
|
||||
static void
|
||||
meta_background_image_cache_init (MetaBackgroundImageCache *cache)
|
||||
{
|
||||
cache->images = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
cache->images = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -124,9 +124,17 @@ load_file (GTask *task,
|
||||
{
|
||||
GError *error = NULL;
|
||||
GdkPixbuf *pixbuf;
|
||||
GFileInputStream *stream;
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_file (image->filename,
|
||||
&error);
|
||||
stream = g_file_read (image->file, NULL, &error);
|
||||
if (stream == NULL)
|
||||
{
|
||||
g_task_return_error (task, error);
|
||||
return;
|
||||
}
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (stream), NULL, &error);
|
||||
g_object_unref (stream);
|
||||
|
||||
if (pixbuf == NULL)
|
||||
{
|
||||
@ -156,9 +164,11 @@ file_loaded (GObject *source_object,
|
||||
|
||||
if (pixbuf == NULL)
|
||||
{
|
||||
char *uri = g_file_get_uri (image->file);
|
||||
g_warning ("Failed to load background '%s': %s",
|
||||
image->filename, error->message);
|
||||
uri, error->message);
|
||||
g_clear_error (&error);
|
||||
g_free (uri);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -185,6 +195,9 @@ file_loaded (GObject *source_object,
|
||||
image->texture = texture;
|
||||
|
||||
out:
|
||||
if (pixbuf != NULL)
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
image->loaded = TRUE;
|
||||
g_signal_emit (image, signals[LOADED], 0);
|
||||
}
|
||||
@ -192,7 +205,7 @@ out:
|
||||
/**
|
||||
* meta_background_image_cache_load:
|
||||
* @cache: a #MetaBackgroundImageCache
|
||||
* @filename: filename to load
|
||||
* @file: #GFile to load
|
||||
*
|
||||
* Loads an image to use as a background, or returns a reference to an
|
||||
* image that is already in the process of loading or loaded. In either
|
||||
@ -206,23 +219,23 @@ out:
|
||||
*/
|
||||
MetaBackgroundImage *
|
||||
meta_background_image_cache_load (MetaBackgroundImageCache *cache,
|
||||
const char *filename)
|
||||
GFile *file)
|
||||
{
|
||||
MetaBackgroundImage *image;
|
||||
GTask *task;
|
||||
|
||||
g_return_val_if_fail (META_IS_BACKGROUND_IMAGE_CACHE (cache), NULL);
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
g_return_val_if_fail (file != NULL, NULL);
|
||||
|
||||
image = g_hash_table_lookup (cache->images, filename);
|
||||
image = g_hash_table_lookup (cache->images, file);
|
||||
if (image != NULL)
|
||||
return g_object_ref (image);
|
||||
|
||||
image = g_object_new (META_TYPE_BACKGROUND_IMAGE, NULL);
|
||||
image->cache = cache;
|
||||
image->in_cache = TRUE;
|
||||
image->filename = g_strdup (filename);
|
||||
g_hash_table_insert (cache->images, image->filename, image);
|
||||
image->file = g_object_ref (file);
|
||||
g_hash_table_insert (cache->images, image->file, image);
|
||||
|
||||
task = g_task_new (image, NULL, file_loaded, NULL);
|
||||
|
||||
@ -235,25 +248,25 @@ meta_background_image_cache_load (MetaBackgroundImageCache *cache,
|
||||
/**
|
||||
* meta_background_image_cache_purge:
|
||||
* @cache: a #MetaBackgroundImageCache
|
||||
* @filename: filename to remove from the cache
|
||||
* @file: file to remove from the cache
|
||||
*
|
||||
* Remove an entry from the cache; this would be used if monitoring
|
||||
* showed that the file changed.
|
||||
*/
|
||||
void
|
||||
meta_background_image_cache_purge (MetaBackgroundImageCache *cache,
|
||||
const char *filename)
|
||||
GFile *file)
|
||||
{
|
||||
MetaBackgroundImage *image;
|
||||
|
||||
g_return_if_fail (META_IS_BACKGROUND_IMAGE_CACHE (cache));
|
||||
g_return_if_fail (filename != NULL);
|
||||
g_return_if_fail (file != NULL);
|
||||
|
||||
image = g_hash_table_lookup (cache->images, filename);
|
||||
image = g_hash_table_lookup (cache->images, file);
|
||||
if (image == NULL)
|
||||
return;
|
||||
|
||||
g_hash_table_remove (cache->images, image->filename);
|
||||
g_hash_table_remove (cache->images, image->file);
|
||||
image->in_cache = FALSE;
|
||||
}
|
||||
|
||||
@ -270,12 +283,12 @@ meta_background_image_finalize (GObject *object)
|
||||
MetaBackgroundImage *image = META_BACKGROUND_IMAGE (object);
|
||||
|
||||
if (image->in_cache)
|
||||
g_hash_table_remove (image->cache->images, image->filename);
|
||||
g_hash_table_remove (image->cache->images, image->file);
|
||||
|
||||
if (image->texture)
|
||||
cogl_object_unref (image->texture);
|
||||
if (image->filename)
|
||||
g_free (image->filename);
|
||||
if (image->file)
|
||||
g_object_unref (image->file);
|
||||
|
||||
G_OBJECT_CLASS (meta_background_image_parent_class)->finalize (object);
|
||||
}
|
||||
|
@ -50,9 +50,9 @@ struct _MetaBackgroundPrivate
|
||||
ClutterColor color;
|
||||
ClutterColor second_color;
|
||||
|
||||
char *filename1;
|
||||
GFile *file1;
|
||||
MetaBackgroundImage *background_image1;
|
||||
char *filename2;
|
||||
GFile *file2;
|
||||
MetaBackgroundImage *background_image2;
|
||||
|
||||
CoglTexture *color_texture;
|
||||
@ -241,16 +241,28 @@ on_background_loaded (MetaBackgroundImage *image,
|
||||
mark_changed (self);
|
||||
}
|
||||
|
||||
static void
|
||||
set_filename (MetaBackground *self,
|
||||
char **filenamep,
|
||||
MetaBackgroundImage **imagep,
|
||||
const char *filename)
|
||||
static gboolean
|
||||
file_equal0 (GFile *file1,
|
||||
GFile *file2)
|
||||
{
|
||||
if (g_strcmp0 (filename, *filenamep) != 0)
|
||||
if (file1 == file2)
|
||||
return TRUE;
|
||||
|
||||
if ((file1 == NULL) || (file2 == NULL))
|
||||
return FALSE;
|
||||
|
||||
return g_file_equal (file1, file2);
|
||||
}
|
||||
|
||||
static void
|
||||
set_file (MetaBackground *self,
|
||||
GFile **filep,
|
||||
MetaBackgroundImage **imagep,
|
||||
GFile *file)
|
||||
{
|
||||
if (!file_equal0 (*filep, file))
|
||||
{
|
||||
g_free (*filenamep);
|
||||
*filenamep = g_strdup (filename);
|
||||
g_clear_object (filep);
|
||||
|
||||
if (*imagep)
|
||||
{
|
||||
@ -261,10 +273,12 @@ set_filename (MetaBackground *self,
|
||||
*imagep = NULL;
|
||||
}
|
||||
|
||||
if (filename)
|
||||
if (file)
|
||||
{
|
||||
MetaBackgroundImageCache *cache = meta_background_image_cache_get_default ();
|
||||
*imagep = meta_background_image_cache_load (cache, filename);
|
||||
|
||||
*filep = g_object_ref (file);
|
||||
*imagep = meta_background_image_cache_load (cache, file);
|
||||
g_signal_connect (*imagep, "loaded",
|
||||
G_CALLBACK (on_background_loaded), self);
|
||||
}
|
||||
@ -280,8 +294,8 @@ meta_background_dispose (GObject *object)
|
||||
free_color_texture (self);
|
||||
free_wallpaper_texture (self);
|
||||
|
||||
set_filename (self, &priv->filename1, &priv->background_image1, NULL);
|
||||
set_filename (self, &priv->filename2, &priv->background_image2, NULL);
|
||||
set_file (self, &priv->file1, &priv->background_image1, NULL);
|
||||
set_file (self, &priv->file2, &priv->background_image2, NULL);
|
||||
|
||||
set_screen (self, NULL);
|
||||
|
||||
@ -867,19 +881,19 @@ meta_background_set_gradient (MetaBackground *self,
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_set_filename (MetaBackground *self,
|
||||
const char *filename,
|
||||
GDesktopBackgroundStyle style)
|
||||
meta_background_set_file (MetaBackground *self,
|
||||
GFile *file,
|
||||
GDesktopBackgroundStyle style)
|
||||
{
|
||||
g_return_if_fail (META_IS_BACKGROUND (self));
|
||||
|
||||
meta_background_set_blend (self, filename, NULL, 0.0, style);
|
||||
meta_background_set_blend (self, file, NULL, 0.0, style);
|
||||
}
|
||||
|
||||
void
|
||||
meta_background_set_blend (MetaBackground *self,
|
||||
const char *filename1,
|
||||
const char *filename2,
|
||||
GFile *file1,
|
||||
GFile *file2,
|
||||
double blend_factor,
|
||||
GDesktopBackgroundStyle style)
|
||||
{
|
||||
@ -890,8 +904,8 @@ meta_background_set_blend (MetaBackground *self,
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
set_filename (self, &priv->filename1, &priv->background_image1, filename1);
|
||||
set_filename (self, &priv->filename2, &priv->background_image2, filename2);
|
||||
set_file (self, &priv->file1, &priv->background_image1, file1);
|
||||
set_file (self, &priv->file2, &priv->background_image2, file2);
|
||||
|
||||
priv->blend_factor = blend_factor;
|
||||
priv->style = style;
|
||||
|
64
src/compositor/meta-dnd-actor-private.h
Normal file
64
src/compositor/meta-dnd-actor-private.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* meta-dnd-actor-private.h: Actor for painting the DnD surface
|
||||
*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_DND_ACTOR_PRIVATE_H
|
||||
#define META_DND_ACTOR_PRIVATE_H
|
||||
|
||||
#include "meta-feedback-actor-private.h"
|
||||
|
||||
/**
|
||||
* MetaDnDActor:
|
||||
*
|
||||
* This class handles the rendering of the DnD surface
|
||||
*/
|
||||
|
||||
#define META_TYPE_DND_ACTOR (meta_dnd_actor_get_type ())
|
||||
#define META_DND_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DND_ACTOR, MetaDnDActor))
|
||||
#define META_DND_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DND_ACTOR, MetaDnDActorClass))
|
||||
#define META_IS_DND_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DND_ACTOR))
|
||||
#define META_IS_DND_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DND_ACTOR))
|
||||
#define META_DND_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DND_ACTOR, MetaDnDActorClass))
|
||||
|
||||
typedef struct _MetaDnDActor MetaDnDActor;
|
||||
typedef struct _MetaDnDActorClass MetaDnDActorClass;
|
||||
|
||||
struct _MetaDnDActorClass
|
||||
{
|
||||
/*< private >*/
|
||||
MetaFeedbackActorClass parent_class;
|
||||
};
|
||||
|
||||
struct _MetaDnDActor
|
||||
{
|
||||
MetaFeedbackActor parent;
|
||||
};
|
||||
|
||||
GType meta_dnd_actor_get_type (void);
|
||||
|
||||
ClutterActor *meta_dnd_actor_new (ClutterActor *drag_origin,
|
||||
int start_x,
|
||||
int start_y);
|
||||
|
||||
void meta_dnd_actor_drag_finish (MetaDnDActor *self,
|
||||
gboolean success);
|
||||
|
||||
#endif /* META_DND_ACTOR_PRIVATE_H */
|
231
src/compositor/meta-dnd-actor.c
Normal file
231
src/compositor/meta-dnd-actor.c
Normal file
@ -0,0 +1,231 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:meta-dnd-actor
|
||||
* @title: MetaDnDActor
|
||||
* @short_description: Actor for painting the drag and drop surface
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "meta-dnd-actor-private.h"
|
||||
|
||||
#define DRAG_FAILED_DURATION 500
|
||||
|
||||
enum {
|
||||
PROP_DRAG_ORIGIN = 1,
|
||||
PROP_DRAG_START_X,
|
||||
PROP_DRAG_START_Y
|
||||
};
|
||||
|
||||
typedef struct _MetaDnDActorPrivate MetaDnDActorPrivate;
|
||||
|
||||
struct _MetaDnDActorPrivate
|
||||
{
|
||||
ClutterActor *drag_origin;
|
||||
int drag_start_x;
|
||||
int drag_start_y;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaDnDActor, meta_dnd_actor, META_TYPE_FEEDBACK_ACTOR)
|
||||
|
||||
static void
|
||||
meta_dnd_actor_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaDnDActor *self = META_DND_ACTOR (object);
|
||||
MetaDnDActorPrivate *priv = meta_dnd_actor_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DRAG_ORIGIN:
|
||||
priv->drag_origin = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_DRAG_START_X:
|
||||
priv->drag_start_x = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_DRAG_START_Y:
|
||||
priv->drag_start_y = g_value_get_int (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_dnd_actor_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaDnDActor *self = META_DND_ACTOR (object);
|
||||
MetaDnDActorPrivate *priv = meta_dnd_actor_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DRAG_ORIGIN:
|
||||
g_value_set_object (value, priv->drag_origin);
|
||||
break;
|
||||
case PROP_DRAG_START_X:
|
||||
g_value_set_int (value, priv->drag_start_x);
|
||||
break;
|
||||
case PROP_DRAG_START_Y:
|
||||
g_value_set_int (value, priv->drag_start_y);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_dnd_actor_class_init (MetaDnDActorClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->set_property = meta_dnd_actor_set_property;
|
||||
object_class->get_property = meta_dnd_actor_get_property;
|
||||
|
||||
pspec = g_param_spec_object ("drag-origin",
|
||||
"Drag origin",
|
||||
"The origin of the DnD operation",
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DRAG_ORIGIN,
|
||||
pspec);
|
||||
|
||||
pspec = g_param_spec_int ("drag-start-x",
|
||||
"Drag start X",
|
||||
"The X axis of the drag start point",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DRAG_START_X,
|
||||
pspec);
|
||||
|
||||
pspec = g_param_spec_int ("drag-start-y",
|
||||
"Drag start Y",
|
||||
"The Y axis of the drag start point",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DRAG_START_Y,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_dnd_actor_init (MetaDnDActor *self)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_dnd_actor_new:
|
||||
*
|
||||
* Creates a new actor to draw the current drag and drop surface.
|
||||
*
|
||||
* Return value: the newly created background actor
|
||||
*/
|
||||
ClutterActor *
|
||||
meta_dnd_actor_new (ClutterActor *drag_origin,
|
||||
int drag_start_x,
|
||||
int drag_start_y)
|
||||
{
|
||||
MetaDnDActor *self;
|
||||
|
||||
self = g_object_new (META_TYPE_DND_ACTOR,
|
||||
"drag-origin", drag_origin,
|
||||
"drag-start-x", drag_start_x,
|
||||
"drag-start-y", drag_start_y,
|
||||
NULL);
|
||||
|
||||
return CLUTTER_ACTOR (self);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_failed_complete (ClutterTimeline *timeline,
|
||||
gboolean is_finished,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterActor *self = user_data;
|
||||
|
||||
clutter_actor_remove_all_children (self);
|
||||
clutter_actor_destroy (self);
|
||||
}
|
||||
|
||||
void
|
||||
meta_dnd_actor_drag_finish (MetaDnDActor *self,
|
||||
gboolean success)
|
||||
{
|
||||
MetaDnDActorPrivate *priv;
|
||||
ClutterActor *actor;
|
||||
|
||||
g_return_if_fail (META_IS_DND_ACTOR (self));
|
||||
|
||||
actor = CLUTTER_ACTOR (self);
|
||||
priv = meta_dnd_actor_get_instance_private (self);
|
||||
|
||||
if (success)
|
||||
{
|
||||
clutter_actor_remove_all_children (CLUTTER_ACTOR (self));
|
||||
clutter_actor_destroy (CLUTTER_ACTOR (self));
|
||||
}
|
||||
else
|
||||
{
|
||||
ClutterTransition *transition;
|
||||
|
||||
clutter_actor_save_easing_state (actor);
|
||||
clutter_actor_set_easing_mode (actor, CLUTTER_EASE_OUT_CUBIC);
|
||||
clutter_actor_set_easing_duration (actor, DRAG_FAILED_DURATION);
|
||||
clutter_actor_set_opacity (actor, 0);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (priv->drag_origin))
|
||||
{
|
||||
int anchor_x, anchor_y;
|
||||
ClutterPoint dest;
|
||||
|
||||
clutter_actor_get_transformed_position (priv->drag_origin,
|
||||
&dest.x, &dest.y);
|
||||
meta_feedback_actor_get_anchor (META_FEEDBACK_ACTOR (self),
|
||||
&anchor_x, &anchor_y);
|
||||
|
||||
dest.x += priv->drag_start_x - anchor_x;
|
||||
dest.y += priv->drag_start_y - anchor_y;
|
||||
clutter_actor_set_position (actor, dest.x, dest.y);
|
||||
}
|
||||
|
||||
transition = clutter_actor_get_transition (actor, "opacity");
|
||||
g_signal_connect (transition, "stopped",
|
||||
G_CALLBACK (drag_failed_complete), self);
|
||||
|
||||
clutter_actor_restore_easing_state (actor);
|
||||
}
|
||||
}
|
74
src/compositor/meta-feedback-actor-private.h
Normal file
74
src/compositor/meta-feedback-actor-private.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* meta-feedback-actor-private.h: Actor for painting user interaction feedback
|
||||
*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef META_FEEDBACK_ACTOR_PRIVATE_H
|
||||
#define META_FEEDBACK_ACTOR_PRIVATE_H
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
/**
|
||||
* MetaFeedbackActor:
|
||||
*
|
||||
* This class handles the rendering of user interaction feedback
|
||||
*/
|
||||
|
||||
#define META_TYPE_FEEDBACK_ACTOR (meta_feedback_actor_get_type ())
|
||||
#define META_FEEDBACK_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_FEEDBACK_ACTOR, MetaFeedbackActor))
|
||||
#define META_FEEDBACK_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_FEEDBACK_ACTOR, MetaFeedbackActorClass))
|
||||
#define META_IS_FEEDBACK_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_FEEDBACK_ACTOR))
|
||||
#define META_IS_FEEDBACK_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_FEEDBACK_ACTOR))
|
||||
#define META_FEEDBACK_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_FEEDBACK_ACTOR, MetaFeedbackActorClass))
|
||||
|
||||
typedef struct _MetaFeedbackActor MetaFeedbackActor;
|
||||
typedef struct _MetaFeedbackActorClass MetaFeedbackActorClass;
|
||||
|
||||
struct _MetaFeedbackActorClass
|
||||
{
|
||||
/*< private >*/
|
||||
ClutterActorClass parent_class;
|
||||
};
|
||||
|
||||
struct _MetaFeedbackActor
|
||||
{
|
||||
ClutterActor parent;
|
||||
};
|
||||
|
||||
GType meta_feedback_actor_get_type (void);
|
||||
|
||||
ClutterActor *meta_feedback_actor_new (int anchor_x,
|
||||
int anchor_y);
|
||||
|
||||
void meta_feedback_actor_set_anchor (MetaFeedbackActor *actor,
|
||||
int anchor_x,
|
||||
int anchor_y);
|
||||
void meta_feedback_actor_get_anchor (MetaFeedbackActor *actor,
|
||||
int *anchor_x,
|
||||
int *anchor_y);
|
||||
|
||||
void meta_feedback_actor_set_position (MetaFeedbackActor *self,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void meta_feedback_actor_update (MetaFeedbackActor *self,
|
||||
const ClutterEvent *event);
|
||||
|
||||
#endif /* META_FEEDBACK_ACTOR_PRIVATE_H */
|
249
src/compositor/meta-feedback-actor.c
Normal file
249
src/compositor/meta-feedback-actor.c
Normal file
@ -0,0 +1,249 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
* Copyright 2014 Red Hat, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:meta-feedback-actor
|
||||
* @title: MetaFeedbackActor
|
||||
* @short_description: Actor for painting user interaction feedback
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "display-private.h"
|
||||
#include "compositor-private.h"
|
||||
#include "meta-feedback-actor-private.h"
|
||||
|
||||
enum {
|
||||
PROP_ANCHOR_X = 1,
|
||||
PROP_ANCHOR_Y
|
||||
};
|
||||
|
||||
typedef struct _MetaFeedbackActorPrivate MetaFeedbackActorPrivate;
|
||||
|
||||
struct _MetaFeedbackActorPrivate
|
||||
{
|
||||
int anchor_x;
|
||||
int anchor_y;
|
||||
int pos_x;
|
||||
int pos_y;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaFeedbackActor, meta_feedback_actor, CLUTTER_TYPE_ACTOR)
|
||||
|
||||
static void
|
||||
meta_feedback_actor_constructed (GObject *object)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
display = meta_get_display ();
|
||||
clutter_actor_add_child (display->compositor->feedback_group,
|
||||
CLUTTER_ACTOR (object));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_feedback_actor_update_position (MetaFeedbackActor *self)
|
||||
{
|
||||
MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self);
|
||||
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (self),
|
||||
priv->pos_x - priv->anchor_x,
|
||||
priv->pos_y - priv->anchor_y);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_feedback_actor_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaFeedbackActor *self = META_FEEDBACK_ACTOR (object);
|
||||
MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ANCHOR_X:
|
||||
priv->anchor_x = g_value_get_int (value);
|
||||
meta_feedback_actor_update_position (self);
|
||||
break;
|
||||
case PROP_ANCHOR_Y:
|
||||
priv->anchor_y = g_value_get_int (value);
|
||||
meta_feedback_actor_update_position (self);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_feedback_actor_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaFeedbackActor *self = META_FEEDBACK_ACTOR (object);
|
||||
MetaFeedbackActorPrivate *priv = meta_feedback_actor_get_instance_private (self);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ANCHOR_X:
|
||||
g_value_set_int (value, priv->anchor_x);
|
||||
break;
|
||||
case PROP_ANCHOR_Y:
|
||||
g_value_set_int (value, priv->anchor_y);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_feedback_actor_class_init (MetaFeedbackActorClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class->constructed = meta_feedback_actor_constructed;
|
||||
object_class->set_property = meta_feedback_actor_set_property;
|
||||
object_class->get_property = meta_feedback_actor_get_property;
|
||||
|
||||
pspec = g_param_spec_int ("anchor-x",
|
||||
"Anchor X",
|
||||
"The X axis of the anchor point",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ANCHOR_X,
|
||||
pspec);
|
||||
|
||||
pspec = g_param_spec_int ("anchor-y",
|
||||
"Anchor Y",
|
||||
"The Y axis of the anchor point",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READWRITE);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ANCHOR_Y,
|
||||
pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_feedback_actor_init (MetaFeedbackActor *self)
|
||||
{
|
||||
clutter_actor_set_reactive (CLUTTER_ACTOR (self), FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_feedback_actor_new:
|
||||
*
|
||||
* Creates a new actor to draw the current drag and drop surface.
|
||||
*
|
||||
* Return value: the newly created background actor
|
||||
*/
|
||||
ClutterActor *
|
||||
meta_feedback_actor_new (int anchor_x,
|
||||
int anchor_y)
|
||||
{
|
||||
MetaFeedbackActor *self;
|
||||
|
||||
self = g_object_new (META_TYPE_FEEDBACK_ACTOR,
|
||||
"anchor-x", anchor_x,
|
||||
"anchor-y", anchor_y,
|
||||
NULL);
|
||||
|
||||
return CLUTTER_ACTOR (self);
|
||||
}
|
||||
|
||||
void
|
||||
meta_feedback_actor_set_anchor (MetaFeedbackActor *self,
|
||||
int anchor_x,
|
||||
int anchor_y)
|
||||
{
|
||||
MetaFeedbackActorPrivate *priv;
|
||||
|
||||
g_return_if_fail (META_IS_FEEDBACK_ACTOR (self));
|
||||
|
||||
priv = meta_feedback_actor_get_instance_private (self);
|
||||
|
||||
if (priv->anchor_x == anchor_x && priv->anchor_y == anchor_y)
|
||||
return;
|
||||
|
||||
if (priv->anchor_x != anchor_y)
|
||||
{
|
||||
priv->anchor_x = anchor_x;
|
||||
g_object_notify (G_OBJECT (self), "anchor-x");
|
||||
}
|
||||
|
||||
if (priv->anchor_y != anchor_y)
|
||||
{
|
||||
priv->anchor_y = anchor_y;
|
||||
g_object_notify (G_OBJECT (self), "anchor-y");
|
||||
}
|
||||
|
||||
meta_feedback_actor_update_position (self);
|
||||
}
|
||||
|
||||
void
|
||||
meta_feedback_actor_get_anchor (MetaFeedbackActor *self,
|
||||
int *anchor_x,
|
||||
int *anchor_y)
|
||||
{
|
||||
MetaFeedbackActorPrivate *priv;
|
||||
|
||||
g_return_if_fail (META_IS_FEEDBACK_ACTOR (self));
|
||||
|
||||
priv = meta_feedback_actor_get_instance_private (self);
|
||||
|
||||
if (anchor_x)
|
||||
*anchor_x = priv->anchor_x;
|
||||
if (anchor_y)
|
||||
*anchor_y = priv->anchor_y;
|
||||
}
|
||||
|
||||
void
|
||||
meta_feedback_actor_set_position (MetaFeedbackActor *self,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
MetaFeedbackActorPrivate *priv;
|
||||
|
||||
g_return_if_fail (META_IS_FEEDBACK_ACTOR (self));
|
||||
|
||||
priv = meta_feedback_actor_get_instance_private (self);
|
||||
priv->pos_x = x;
|
||||
priv->pos_y = y;
|
||||
|
||||
meta_feedback_actor_update_position (self);
|
||||
}
|
||||
|
||||
void
|
||||
meta_feedback_actor_update (MetaFeedbackActor *self,
|
||||
const ClutterEvent *event)
|
||||
{
|
||||
ClutterPoint point;
|
||||
|
||||
g_return_if_fail (META_IS_FEEDBACK_ACTOR (self));
|
||||
g_return_if_fail (event != NULL);
|
||||
|
||||
clutter_event_get_position (event, &point);
|
||||
meta_feedback_actor_set_position (self, point.x, point.y);
|
||||
}
|
@ -40,7 +40,7 @@
|
||||
|
||||
#include "compositor-private.h"
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
#include "meta-monitor-manager-private.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (MetaPlugin, meta_plugin, G_TYPE_OBJECT);
|
||||
|
||||
|
@ -31,6 +31,8 @@
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
#include "compositor/region-utils.h"
|
||||
|
||||
struct _MetaSurfaceActorWaylandPrivate
|
||||
{
|
||||
MetaWaylandSurface *surface;
|
||||
@ -126,12 +128,68 @@ meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor)
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_scale_texture (MetaSurfaceActorWayland *actor)
|
||||
meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (actor));
|
||||
double output_scale = meta_surface_actor_wayland_get_scale (actor);
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||
MetaShapedTexture *stex =
|
||||
meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
double texture_scale;
|
||||
|
||||
clutter_actor_set_scale (CLUTTER_ACTOR (stex), output_scale, output_scale);
|
||||
/* Given the surface's window type and what output the surface actor has the
|
||||
* largest region, scale the actor with the determined scale. */
|
||||
texture_scale = meta_surface_actor_wayland_get_scale (self);
|
||||
|
||||
/* Actor scale. */
|
||||
clutter_actor_set_scale (CLUTTER_ACTOR (stex), texture_scale, texture_scale);
|
||||
|
||||
/* Input region */
|
||||
if (surface->input_region)
|
||||
{
|
||||
cairo_region_t *scaled_input_region;
|
||||
int region_scale;
|
||||
|
||||
/* The input region from the Wayland surface is in the Wayland surface
|
||||
* coordinate space, while the surface actor input region is in the
|
||||
* physical pixel coordinate space. */
|
||||
region_scale = (int)(surface->scale * texture_scale);
|
||||
scaled_input_region = meta_region_scale (surface->input_region,
|
||||
region_scale);
|
||||
meta_surface_actor_set_input_region (META_SURFACE_ACTOR (self),
|
||||
scaled_input_region);
|
||||
cairo_region_destroy (scaled_input_region);
|
||||
}
|
||||
|
||||
/* Opaque region */
|
||||
if (surface->opaque_region)
|
||||
{
|
||||
cairo_region_t *scaled_opaque_region;
|
||||
|
||||
/* The opaque region from the Wayland surface is in Wayland surface
|
||||
* coordinate space, while the surface actor opaque region is in the
|
||||
* same coordinate space as the unscaled buffer texture. */
|
||||
scaled_opaque_region = meta_region_scale (surface->opaque_region,
|
||||
surface->scale);
|
||||
meta_surface_actor_set_opaque_region (META_SURFACE_ACTOR (self),
|
||||
scaled_opaque_region);
|
||||
cairo_region_destroy (scaled_opaque_region);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||
GList *iter;
|
||||
|
||||
meta_surface_actor_wayland_sync_state (self);
|
||||
|
||||
for (iter = surface->subsurfaces; iter != NULL; iter = iter->next)
|
||||
{
|
||||
MetaWaylandSurface *subsurf = iter->data;
|
||||
|
||||
meta_surface_actor_wayland_sync_state_recursive (
|
||||
META_SURFACE_ACTOR_WAYLAND (subsurf->surface_actor));
|
||||
}
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
|
@ -63,7 +63,10 @@ void meta_surface_actor_wayland_set_texture (MetaSurfaceActorWayland *self,
|
||||
|
||||
double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
|
||||
|
||||
void meta_surface_actor_wayland_scale_texture (MetaSurfaceActorWayland *actor);
|
||||
void meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self);
|
||||
|
||||
void meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user