Compare commits
544 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fae37222a7 | ||
![]() |
d41449b578 | ||
![]() |
34979c3fe8 | ||
![]() |
711f0c0c50 | ||
![]() |
933d05a565 | ||
![]() |
8a0da1cb07 | ||
![]() |
1445903a34 | ||
![]() |
5d9386df0c | ||
![]() |
6fd1de226b | ||
![]() |
ac099343da | ||
![]() |
bce5f3f108 | ||
![]() |
35e0982e35 | ||
![]() |
767455e8d8 | ||
![]() |
6b8dda0d00 | ||
![]() |
277df44cfb | ||
![]() |
2dded1e510 | ||
![]() |
a7b1b1da80 | ||
![]() |
de69678085 | ||
![]() |
5f7b81eb95 | ||
![]() |
f4f70afe31 | ||
![]() |
116957b339 | ||
![]() |
1af0033368 | ||
![]() |
3645c63c08 | ||
![]() |
04ddfe0a6f | ||
![]() |
ec3dc4a607 | ||
![]() |
0b98fbab0a | ||
![]() |
5b8dc37c31 | ||
![]() |
f42258327b | ||
![]() |
7d1ef3f447 | ||
![]() |
652fe57cdd | ||
![]() |
20a6243c85 | ||
![]() |
679edac9c3 | ||
![]() |
bb59b8c249 | ||
![]() |
c5c6b2257f | ||
![]() |
6acf7b06f4 | ||
![]() |
d0c004c93c | ||
![]() |
53876d2b62 | ||
![]() |
2b63b17327 | ||
![]() |
226a09b38c | ||
![]() |
527c53a2a0 | ||
![]() |
19795c1681 | ||
![]() |
1999fcaa8f | ||
![]() |
6b5ff8fd74 | ||
![]() |
821d946a72 | ||
![]() |
5f7c901727 | ||
![]() |
7b8ee4ee1e | ||
![]() |
32cf4afb04 | ||
![]() |
e0c92befd5 | ||
![]() |
827e0341ab | ||
![]() |
8627b65f8d | ||
![]() |
9c62a907c5 | ||
![]() |
a119ea96a3 | ||
![]() |
06d55bf019 | ||
![]() |
320f38de47 | ||
![]() |
7adfaceccf | ||
![]() |
67be4e2bf3 | ||
![]() |
c3e87ee896 | ||
![]() |
f2283ec634 | ||
![]() |
d06e4beb7f | ||
![]() |
e24863d175 | ||
![]() |
2de2241690 | ||
![]() |
977de8c5d4 | ||
![]() |
fb6438cdd4 | ||
![]() |
517e8f6fbd | ||
![]() |
0e758a9e65 | ||
![]() |
64a915a68d | ||
![]() |
d233238c64 | ||
![]() |
71a4fe746e | ||
![]() |
f28c7835a1 | ||
![]() |
cecf7f4bf0 | ||
![]() |
c687cf9db6 | ||
![]() |
54d2218ac2 | ||
![]() |
471e6b9e13 | ||
![]() |
f8dcea3975 | ||
![]() |
d931af33c4 | ||
![]() |
a0e3c05428 | ||
![]() |
b8c13cc426 | ||
![]() |
38253a9f73 | ||
![]() |
cbc92b847f | ||
![]() |
a5f993f269 | ||
![]() |
31361e464a | ||
![]() |
bb977c00ca | ||
![]() |
39f65f9f86 | ||
![]() |
bda2d6d1ac | ||
![]() |
1e225ecdaf | ||
![]() |
cfb85d9a9a | ||
![]() |
f88c20f335 | ||
![]() |
c98824bc9e | ||
![]() |
69a35bb85f | ||
![]() |
a3bb6c12e5 | ||
![]() |
586f118279 | ||
![]() |
31081e5dac | ||
![]() |
ef363e9d2e | ||
![]() |
9fa77acb8c | ||
![]() |
1e30db64d1 | ||
![]() |
e830b66604 | ||
![]() |
5f0fab2156 | ||
![]() |
467465c99c | ||
![]() |
e935b52e51 | ||
![]() |
879407c10c | ||
![]() |
e76be14dbb | ||
![]() |
7fa15c74b4 | ||
![]() |
c3950699bf | ||
![]() |
e6b950e31b | ||
![]() |
9440bdb1aa | ||
![]() |
e320b06aaa | ||
![]() |
b284126d3b | ||
![]() |
6858cb261f | ||
![]() |
2d6954186e | ||
![]() |
d72bf0cd5d | ||
![]() |
584460deec | ||
![]() |
e3d5969282 | ||
![]() |
249468bbea | ||
![]() |
f0f4c31d96 | ||
![]() |
27f012ffad | ||
![]() |
7d54631ebf | ||
![]() |
513628e4ad | ||
![]() |
101b215d6b | ||
![]() |
6af48de0b8 | ||
![]() |
e5c4fedd55 | ||
![]() |
2ce23072d3 | ||
![]() |
97f4eb6b75 | ||
![]() |
75cbf3d730 | ||
![]() |
bf9fdf448d | ||
![]() |
63c627ec18 | ||
![]() |
dadbd793be | ||
![]() |
75b6e917ad | ||
![]() |
ab53c0e943 | ||
![]() |
c2fe6a18ad | ||
![]() |
b7119c55a6 | ||
![]() |
d0f2c6be6d | ||
![]() |
3a535b6722 | ||
![]() |
f9a77aec3f | ||
![]() |
bee6d2b240 | ||
![]() |
9a6a189e36 | ||
![]() |
505eabb78c | ||
![]() |
b0ba325f0e | ||
![]() |
6fbd21001b | ||
![]() |
626e4965b1 | ||
![]() |
a15042b7e5 | ||
![]() |
e56f963574 | ||
![]() |
65a8f9100c | ||
![]() |
6954d23444 | ||
![]() |
6c624e1c26 | ||
![]() |
cc839029b9 | ||
![]() |
25f8eaf1ac | ||
![]() |
8fdd226b8b | ||
![]() |
6c5595fa9c | ||
![]() |
e6558f838e | ||
![]() |
57037a45b8 | ||
![]() |
c844611052 | ||
![]() |
b60e02956d | ||
![]() |
4fe66ce0a9 | ||
![]() |
4b5a503cee | ||
![]() |
817995d97f | ||
![]() |
0e7221c361 | ||
![]() |
938fb8e6c8 | ||
![]() |
fd8c49ff0a | ||
![]() |
cd84317346 | ||
![]() |
4f55e16fe9 | ||
![]() |
c30ef668de | ||
![]() |
62e0c42803 | ||
![]() |
70aee2d95e | ||
![]() |
63c7591698 | ||
![]() |
930361b988 | ||
![]() |
baadb75a5e | ||
![]() |
f28f5dc0b6 | ||
![]() |
41fdc4ac2e | ||
![]() |
177ec27cca | ||
![]() |
37652ca2cf | ||
![]() |
6c22759d29 | ||
![]() |
25b6a40ad4 | ||
![]() |
fbea59b326 | ||
![]() |
38e4906f72 | ||
![]() |
029d69919b | ||
![]() |
5e395fb676 | ||
![]() |
ac448bd42b | ||
![]() |
f55737ec06 | ||
![]() |
80de15face | ||
![]() |
32565e096d | ||
![]() |
1d8e4bdd6d | ||
![]() |
1677a068ce | ||
![]() |
a02b8441b1 | ||
![]() |
dfe1c106f2 | ||
![]() |
e49bbe2ed8 | ||
![]() |
6ee5a1437c | ||
![]() |
93a3383e60 | ||
![]() |
c9a2a561f8 | ||
![]() |
ac0b2fdc6f | ||
![]() |
46b9984414 | ||
![]() |
f9743e2174 | ||
![]() |
a3c55c2692 | ||
![]() |
692eb4d957 | ||
![]() |
826751429b | ||
![]() |
5621d3c0c7 | ||
![]() |
b5f46c9171 | ||
![]() |
166b8c042c | ||
![]() |
d34ece6f1a | ||
![]() |
679844f791 | ||
![]() |
9316256e10 | ||
![]() |
90d7737fc1 | ||
![]() |
567ca15610 | ||
![]() |
558b323485 | ||
![]() |
1a05da8296 | ||
![]() |
5df59f75cd | ||
![]() |
029673d0ee | ||
![]() |
3a57f843d5 | ||
![]() |
182a267f69 | ||
![]() |
3de40434fa | ||
![]() |
bc8328d7c2 | ||
![]() |
12c1a06e60 | ||
![]() |
b11405570a | ||
![]() |
3b85e4b2b9 | ||
![]() |
c5abf5ddbb | ||
![]() |
2a3d4b62a7 | ||
![]() |
8ff81bcc37 | ||
![]() |
7159d3bc35 | ||
![]() |
941d202938 | ||
![]() |
5ea0cf8bab | ||
![]() |
df9a5f867f | ||
![]() |
06e4778072 | ||
![]() |
92388892b3 | ||
![]() |
5d124ac00a | ||
![]() |
a57c3ae105 | ||
![]() |
55354f5c38 | ||
![]() |
379bb0a77d | ||
![]() |
39357fc242 | ||
![]() |
799de4f0f4 | ||
![]() |
c34b5c1cf0 | ||
![]() |
46361c3e28 | ||
![]() |
f9d33b2efc | ||
![]() |
2185904fcb | ||
![]() |
eb952819c2 | ||
![]() |
d7d8c92a9a | ||
![]() |
88a7790d44 | ||
![]() |
806dabe2d7 | ||
![]() |
740e7ddd69 | ||
![]() |
bee97ab6a7 | ||
![]() |
59fc17c355 | ||
![]() |
5f25ca0c3a | ||
![]() |
41b4a079c7 | ||
![]() |
e4235376d8 | ||
![]() |
043a201f90 | ||
![]() |
d1a588a94f | ||
![]() |
01b6d9bfe2 | ||
![]() |
9711d95996 | ||
![]() |
b87db00fdb | ||
![]() |
6190b65056 | ||
![]() |
10fe91d704 | ||
![]() |
36bb05b10e | ||
![]() |
a7b7213017 | ||
![]() |
031154a400 | ||
![]() |
463b50e746 | ||
![]() |
1749a85e96 | ||
![]() |
1af9e92e91 | ||
![]() |
12d0c98fb5 | ||
![]() |
817c6986a0 | ||
![]() |
7c68aaea4c | ||
![]() |
6fea46e0cf | ||
![]() |
59fa74fed1 | ||
![]() |
581335fbea | ||
![]() |
9b5d6cc008 | ||
![]() |
d0f98ec1ba | ||
![]() |
a977fcf3d0 | ||
![]() |
664f6ef420 | ||
![]() |
06a31992e3 | ||
![]() |
4e2092d593 | ||
![]() |
9755f308e5 | ||
![]() |
09610daea1 | ||
![]() |
13b7fa4eba | ||
![]() |
909a46087f | ||
![]() |
c10c8649f5 | ||
![]() |
82dce6758a | ||
![]() |
024652bfb4 | ||
![]() |
789608b637 | ||
![]() |
d05b750b8d | ||
![]() |
704cae1de3 | ||
![]() |
23b074481a | ||
![]() |
5dc8fa6690 | ||
![]() |
a9ba98686f | ||
![]() |
59382bace2 | ||
![]() |
2edf822bc6 | ||
![]() |
355621b0ab | ||
![]() |
a307e13a63 | ||
![]() |
f807207b65 | ||
![]() |
30b54aae34 | ||
![]() |
79e682bcd0 | ||
![]() |
a05ae8654c | ||
![]() |
0db172edbf | ||
![]() |
7b0930f798 | ||
![]() |
0919b37c34 | ||
![]() |
faf55c4627 | ||
![]() |
f351c5d304 | ||
![]() |
63bca17ab6 | ||
![]() |
c2abe43ee7 | ||
![]() |
1de2fd7122 | ||
![]() |
e377e82cfd | ||
![]() |
fa8174a200 | ||
![]() |
d22448731c | ||
![]() |
ef95133b1c | ||
![]() |
c068c2122d | ||
![]() |
d8c47b0abd | ||
![]() |
66eb4bc34c | ||
![]() |
bce812ecbc | ||
![]() |
02220ed6c7 | ||
![]() |
8d08851f28 | ||
![]() |
af135c0b0b | ||
![]() |
42c972735e | ||
![]() |
110c79d10e | ||
![]() |
b9d867cb86 | ||
![]() |
ea3b961e43 | ||
![]() |
bc510378b3 | ||
![]() |
0a47d135ac | ||
![]() |
ec8ed1dbb0 | ||
![]() |
203e5335ab | ||
![]() |
f1d8428650 | ||
![]() |
8d29d22e99 | ||
![]() |
9c6e527d4b | ||
![]() |
077606c057 | ||
![]() |
a615f93060 | ||
![]() |
c562657f1e | ||
![]() |
7b3922f8e9 | ||
![]() |
c14382181f | ||
![]() |
b2183dfda7 | ||
![]() |
bb92054c86 | ||
![]() |
4e4a6eb5d7 | ||
![]() |
692acbd986 | ||
![]() |
901901825c | ||
![]() |
97f2de37e1 | ||
![]() |
967b6c33df | ||
![]() |
00c7a27732 | ||
![]() |
048ba353c4 | ||
![]() |
555e2f6de2 | ||
![]() |
ff8d5281f0 | ||
![]() |
4f9b994e73 | ||
![]() |
b8b0dc5c78 | ||
![]() |
d0cafab836 | ||
![]() |
24d7c5ebe3 | ||
![]() |
dc6decefb5 | ||
![]() |
25d7e48077 | ||
![]() |
b0b8f37240 | ||
![]() |
188e4e1b92 | ||
![]() |
9d5273bb15 | ||
![]() |
3c0fae74f1 | ||
![]() |
86dae6d4c7 | ||
![]() |
d06600aeb0 | ||
![]() |
895a3d1f39 | ||
![]() |
381ef5c683 | ||
![]() |
62097897be | ||
![]() |
2d2c47ba49 | ||
![]() |
89cdfc9194 | ||
![]() |
ad60ea9e0e | ||
![]() |
a7350475e8 | ||
![]() |
f3d7c9cff9 | ||
![]() |
906cbeed61 | ||
![]() |
0fccb0fc86 | ||
![]() |
8100cefd4c | ||
![]() |
d7e99a3f86 | ||
![]() |
6af944fe2c | ||
![]() |
12fc394b92 | ||
![]() |
53814fefc1 | ||
![]() |
e87a01c80b | ||
![]() |
21d7c1a850 | ||
![]() |
e33c58297d | ||
![]() |
5350120db4 | ||
![]() |
0997cf7fee | ||
![]() |
af3aae7295 | ||
![]() |
98e219da4b | ||
![]() |
fba022cc06 | ||
![]() |
3f6c6f1dd9 | ||
![]() |
ebc2e7221b | ||
![]() |
7cb30ced23 | ||
![]() |
7b449ac56c | ||
![]() |
724953101d | ||
![]() |
8734477d52 | ||
![]() |
ec8ba4b5f9 | ||
![]() |
2250865eb6 | ||
![]() |
847a3bbee3 | ||
![]() |
410a002ddd | ||
![]() |
8766db2593 | ||
![]() |
e362227514 | ||
![]() |
da311f266d | ||
![]() |
f5a4e996a8 | ||
![]() |
a7f083897f | ||
![]() |
e2105dc721 | ||
![]() |
b64548ee1f | ||
![]() |
53425fa721 | ||
![]() |
048f035d30 | ||
![]() |
b32c837df9 | ||
![]() |
dd03a76d51 | ||
![]() |
806a666950 | ||
![]() |
b240a5e819 | ||
![]() |
fe823b3553 | ||
![]() |
d380d30ef4 | ||
![]() |
1fe5b3e7d5 | ||
![]() |
a8df208a5c | ||
![]() |
f3f3c94831 | ||
![]() |
6e06648f7a | ||
![]() |
afb41f715b | ||
![]() |
19d26dde92 | ||
![]() |
4acb902423 | ||
![]() |
626516d12e | ||
![]() |
1c94df2553 | ||
![]() |
43762da9d3 | ||
![]() |
266166a2d6 | ||
![]() |
3a0af0faae | ||
![]() |
0890eaa3fe | ||
![]() |
d4058d947b | ||
![]() |
b704659899 | ||
![]() |
0a9187a6e9 | ||
![]() |
31db32e826 | ||
![]() |
c2ea650b3c | ||
![]() |
969131f00e | ||
![]() |
c98090c061 | ||
![]() |
3168d3b5e6 | ||
![]() |
efcd7d86e7 | ||
![]() |
04449923bd | ||
![]() |
47b3336ffa | ||
![]() |
0f37c1b58e | ||
![]() |
a3747725ed | ||
![]() |
c448650a60 | ||
![]() |
c45f616fdc | ||
![]() |
9402691aaa | ||
![]() |
cbffbb0be0 | ||
![]() |
9df5b17940 | ||
![]() |
feae23506b | ||
![]() |
6408e59c7c | ||
![]() |
47d72680ff | ||
![]() |
6513cbb470 | ||
![]() |
50b81fe4b9 | ||
![]() |
f38c1f6ab4 | ||
![]() |
f159611fab | ||
![]() |
f1a7231ac2 | ||
![]() |
21991a7edb | ||
![]() |
3f1b6ddc8f | ||
![]() |
aa84813400 | ||
![]() |
dd243813e1 | ||
![]() |
d8c2933c58 | ||
![]() |
2b798511de | ||
![]() |
6c37f6e601 | ||
![]() |
92e9f3d467 | ||
![]() |
05419b8450 | ||
![]() |
e215c07439 | ||
![]() |
5b7dff7a57 | ||
![]() |
1a3aa75385 | ||
![]() |
41880778b5 | ||
![]() |
ecb4e09ec5 | ||
![]() |
d02505852d | ||
![]() |
3941dc7537 | ||
![]() |
e790c45303 | ||
![]() |
ae4e553ddb | ||
![]() |
809568280b | ||
![]() |
4053c92abf | ||
![]() |
56906a29e0 | ||
![]() |
2c0ad5bef7 | ||
![]() |
4a7939268c | ||
![]() |
80266d3071 | ||
![]() |
8e5cfccf49 | ||
![]() |
dcf64ca167 | ||
![]() |
f93fc1506b | ||
![]() |
4ee8fb8154 | ||
![]() |
446b75907e | ||
![]() |
550f1989ff | ||
![]() |
91a6f42345 | ||
![]() |
e97cae0eb3 | ||
![]() |
8640982e68 | ||
![]() |
480a853263 | ||
![]() |
b05953d960 | ||
![]() |
3a0de6a4f1 | ||
![]() |
fb9f22c02f | ||
![]() |
10ac1000f7 | ||
![]() |
c81a0dede2 | ||
![]() |
fc8a2b8a42 | ||
![]() |
2ae0a72dad | ||
![]() |
5b17c72047 | ||
![]() |
8d9653dece | ||
![]() |
e2b7b26f28 | ||
![]() |
ff2eb77fcd | ||
![]() |
0588399ac7 | ||
![]() |
71544fbf4e | ||
![]() |
c8f3820956 | ||
![]() |
f57b0726a0 | ||
![]() |
da175bca52 | ||
![]() |
33cb7f4a2c | ||
![]() |
7732447abc | ||
![]() |
c49c37999c | ||
![]() |
91f35d6a01 | ||
![]() |
549df04ed8 | ||
![]() |
4334135c52 | ||
![]() |
03c4de5590 | ||
![]() |
7a109a18af | ||
![]() |
d9b72b0f43 | ||
![]() |
a7ea54bd7d | ||
![]() |
df642b96e2 | ||
![]() |
f56cc1f733 | ||
![]() |
f5bff4b7f3 | ||
![]() |
bbfdf5dd2a | ||
![]() |
9b95eda42a | ||
![]() |
2d225a3386 | ||
![]() |
7b3cdc8f96 | ||
![]() |
b6f9500ccc | ||
![]() |
ea354e96cb | ||
![]() |
098c8908ed | ||
![]() |
ab632e36a5 | ||
![]() |
1427d20922 | ||
![]() |
aed671810c | ||
![]() |
324d7d720d | ||
![]() |
413e39ecbb | ||
![]() |
2ca2c18c2a | ||
![]() |
01cd4b2ba0 | ||
![]() |
bca210db45 | ||
![]() |
66d6f73af2 | ||
![]() |
bc8799d7d7 | ||
![]() |
fd5c14550a | ||
![]() |
a5cca5296c | ||
![]() |
f4ef4b79f9 | ||
![]() |
6c7a51378f | ||
![]() |
9c4908b44a | ||
![]() |
afaab8aef2 | ||
![]() |
845fdda22c | ||
![]() |
fa29a1a99e | ||
![]() |
f9bffae9fd | ||
![]() |
31c925c602 | ||
![]() |
5d310e06ba | ||
![]() |
25a16c3379 | ||
![]() |
730ed6f75f | ||
![]() |
a6601e92aa | ||
![]() |
f3a2bb7779 | ||
![]() |
73e2d7049a | ||
![]() |
a6353944f6 | ||
![]() |
43d6088ebb | ||
![]() |
e3001794f2 | ||
![]() |
e97ca325e6 | ||
![]() |
c9c6645284 | ||
![]() |
57bb297450 | ||
![]() |
06ca99c3a3 | ||
![]() |
4b5593c67f | ||
![]() |
acb3dc6754 | ||
![]() |
4c21a46452 | ||
![]() |
900ae2c1fa | ||
![]() |
01b6445708 | ||
![]() |
292d502205 | ||
![]() |
adf2e44a82 | ||
![]() |
b075d576a0 |
35
.cvsignore
35
.cvsignore
@@ -1,35 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
confdefs.h
|
||||
config.cache
|
||||
config.guess
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
configure.scan
|
||||
libtool
|
||||
ltconfig
|
||||
ltmain.sh
|
||||
stamp-h
|
||||
stamp-h.in
|
||||
stamp-h1
|
||||
stamp.h
|
||||
version.h
|
||||
config.h.in
|
||||
install-sh
|
||||
missing
|
||||
mkinstalldirs
|
||||
INSTALL
|
||||
intl
|
||||
ABOUT-NLS
|
||||
COPYING
|
||||
intltool-*
|
||||
metacity.spec
|
||||
autom4te.cache
|
||||
compile
|
||||
depcomp
|
||||
omf.make
|
||||
xmldocs.make
|
34
.gitignore
vendored
34
.gitignore
vendored
@@ -3,6 +3,7 @@ Makefile.in
|
||||
Makefile.in.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
build-aux
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
@@ -19,11 +20,11 @@ libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
.deps
|
||||
src/50-mutter-navigation.xml
|
||||
src/50-mutter-system.xml
|
||||
src/50-mutter-windows.xml
|
||||
src/mutter.desktop
|
||||
src/mutter-wayland.desktop
|
||||
50-mutter-navigation.xml
|
||||
50-mutter-system.xml
|
||||
50-mutter-windows.xml
|
||||
mutter.desktop
|
||||
mutter-wayland.desktop
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
@@ -32,10 +33,6 @@ src/mutter-wayland.desktop
|
||||
*.swp
|
||||
*.gir
|
||||
*.typelib
|
||||
tidy-enum-types.[ch]
|
||||
tidy-marshal.[ch]
|
||||
stamp-tidy-enum-types.h
|
||||
stamp-tidy-marshal.h
|
||||
stamp-h1
|
||||
*.gmo
|
||||
*.make
|
||||
@@ -44,11 +41,9 @@ stamp-it
|
||||
.intltool-merge-cache
|
||||
POTFILES
|
||||
po/*.pot
|
||||
50-metacity-desktop-key.xml
|
||||
50-metacity-key.xml
|
||||
libmutter.pc
|
||||
mutter
|
||||
mutter-launch
|
||||
mutter-restart-helper
|
||||
org.gnome.mutter.gschema.valid
|
||||
org.gnome.mutter.gschema.xml
|
||||
org.gnome.mutter.wayland.gschema.valid
|
||||
@@ -57,19 +52,6 @@ testasyncgetprop
|
||||
testboxes
|
||||
testgradient
|
||||
m4/*
|
||||
mutter-grayscale
|
||||
mutter-mag
|
||||
mutter-message
|
||||
mutter-window-demo
|
||||
focus-window
|
||||
test-attached
|
||||
test-focus
|
||||
test-gravity
|
||||
test-resizing
|
||||
test-size-hints
|
||||
# We can't say just "wm-tester" here or it will ignore the directory
|
||||
# rather than the binary
|
||||
src/wm-tester/wm-tester
|
||||
INSTALL
|
||||
mkinstalldirs
|
||||
src/mutter-enum-types.[ch]
|
||||
@@ -78,12 +60,14 @@ src/mutter-marshal.[ch]
|
||||
src/stamp-mutter-marshal.h
|
||||
src/meta-dbus-display-config.[ch]
|
||||
src/meta-dbus-idle-monitor.[ch]
|
||||
src/meta-dbus-login1.[ch]
|
||||
src/gtk-shell-protocol.c
|
||||
src/gtk-shell-server-protocol.h
|
||||
src/xdg-shell-protocol.c
|
||||
src/xdg-shell-server-protocol.h
|
||||
src/xserver-protocol.c
|
||||
src/xserver-server-protocol.h
|
||||
src/meta/meta-version.h
|
||||
doc/reference/*.args
|
||||
doc/reference/*.bak
|
||||
doc/reference/*.hierarchy
|
||||
|
11
Makefile.am
11
Makefile.am
@@ -1,10 +1,13 @@
|
||||
|
||||
SUBDIRS=src po doc
|
||||
SUBDIRS = data src po doc
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
||||
DISTCLEANFILES = intltool-extract intltool-merge intltool-update po/stamp-it po/.intltool-merge-cache
|
||||
DISTCLEANFILES = \
|
||||
intltool-extract \
|
||||
intltool-merge \
|
||||
intltool-update \
|
||||
po/stamp-it \
|
||||
po/.intltool-merge-cache
|
||||
|
||||
DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
|
||||
|
77
NEWS
77
NEWS
@@ -1,3 +1,80 @@
|
||||
3.13.90
|
||||
=======
|
||||
* Only call XSync() once per frame [Rui; #728464]
|
||||
* Update capabilities on device list changes [Carlos; #733563]
|
||||
* Make use of GLSL optional [Adel; #733623]
|
||||
* Handle gestures and touch events on wayland [Carlos; #733631]
|
||||
* Add support for unminimize compositor effects [Cosimo; #733789]
|
||||
* Always set the frame background to None [Giovanni; #734054]
|
||||
* Add backend methods to handle keymaps [Rui; #734301]
|
||||
* Actually mark revalidated MetaTextureTower levels as valid [Owen; #734400]
|
||||
* Rely on explicit -backward switcher keybindings instead of <shift>-magic
|
||||
[Christophe; #732295, #732385]
|
||||
* Misc. bug fixes and cleanups [Rui, Adel, Christophe; #727178, #734852,
|
||||
#734960]
|
||||
|
||||
Contributors:
|
||||
Emmanuele Bassi, Giovanni Campagna, Cosimo Cecchi, Piotr Drąg,
|
||||
Christophe Fergeau, Adel Gadllah, Carlos Garnacho, Rui Matos,
|
||||
Florian Müllner, Jasper St. Pierre, Rico Tzschichholz, Olav Vitters,
|
||||
Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Kjartan Maraas [nb], Inaki Larranaga Murgoitio [eu], Lasse Liehu [fi],
|
||||
ngoswami [as], Daniel Mustieles [es]
|
||||
|
||||
3.13.4
|
||||
======
|
||||
* Fix move/resize operations for wayland clients [Marek; #731237]
|
||||
* Add ::first-frame signal to MetaWindowActor [Owen; #732343]
|
||||
* Handle keysyms without the XF86 prefix [Owen; #727993]
|
||||
* Add touch gesture support [Carlos]
|
||||
* Fix a deadlock when exiting [Owen; #733068]
|
||||
* Add framework for restarting the compositor with nice visuals
|
||||
[Owen; #733026]
|
||||
* Toggle seat capabilities on VT switch [Carlos; #733563]
|
||||
* Misc bug fixes [Florian, Owen; #732695, #732350]
|
||||
|
||||
Contributors:
|
||||
Tom Beckmann, Giovanni Campagna, Marek Chalupa, Adel Gadllah,
|
||||
Carlos Garnacho, Florian Müllner, Jasper St. Pierre, Rico Tzschichholz,
|
||||
Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Yuri Myasoedov [ru], Fran Diéguez [gl], Aurimas Černius [lt], MarMav [el],
|
||||
Enrico Nicoletto [pt_BR]
|
||||
|
||||
3.13.3
|
||||
======
|
||||
* Improve behavior of window buttons with compositor menus [Florian; #731058]
|
||||
* Implement touch support on wayland [Carlos; #724442]
|
||||
* Update window shadows [Nikita; #731866]
|
||||
* Keep windows on the preferred output [Florian; #731760]
|
||||
* Misc bug fixes [Jonas, Florian, Jasper; #729601, #730681, #731353, #731332,
|
||||
#730527, #662962]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Nikita Churaev, Carlos Garnacho, Florian Müllner,
|
||||
Jasper St. Pierre, Rico Tzschichholz
|
||||
|
||||
3.13.2
|
||||
======
|
||||
* Add basic HiDPI support on wayland [Adel; #728902]
|
||||
* Fix crash when monitors change during suspend [Giovanni; #725637]
|
||||
* Replace mutter-launch with logind integration [Jasper; #724604]
|
||||
* Move window menu into the compositor [Jasper; #726352]
|
||||
* Fix delayed focus-follows-mouse support [Florian; #730541]
|
||||
* Support fallback app menu in window decorations [Florian; #730752]
|
||||
* Misc. bug fixes and cleanups [Giovanni, Jonas, Jasper; #729732, #729602,
|
||||
#726714]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Giovanni Campagna, Adel Gadllah, Florian Müllner,
|
||||
Jasper St. Pierre, Rico Tzschichholz
|
||||
|
||||
Translations:
|
||||
Pau Iranzo [ca], Daniel Mustieles [es]
|
||||
|
||||
3.13.1
|
||||
======
|
||||
* Fix opacity values from _NET_WM_WINDOW_OPACITY [Nirbheek; #727874]
|
||||
|
@@ -5,7 +5,7 @@ srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
PKG_NAME="mutter"
|
||||
REQUIRED_AUTOMAKE_VERSION=1.10
|
||||
REQUIRED_AUTOMAKE_VERSION=1.11
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
&& test -d $srcdir/src) || {
|
||||
|
92
configure.ac
92
configure.ac
@@ -1,9 +1,8 @@
|
||||
AC_PREREQ(2.50)
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_PREREQ(2.62)
|
||||
|
||||
m4_define([mutter_major_version], [3])
|
||||
m4_define([mutter_minor_version], [13])
|
||||
m4_define([mutter_micro_version], [1])
|
||||
m4_define([mutter_micro_version], [90])
|
||||
|
||||
m4_define([mutter_version],
|
||||
[mutter_major_version.mutter_minor_version.mutter_micro_version])
|
||||
@@ -14,6 +13,7 @@ AC_INIT([mutter], [mutter_version],
|
||||
[http://bugzilla.gnome.org/enter_bug.cgi?product=mutter])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_SRCDIR(src/core/display.c)
|
||||
AC_CONFIG_HEADERS(config.h)
|
||||
|
||||
@@ -40,12 +40,14 @@ GETTEXT_PACKAGE=mutter
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Name of default gettext domain])
|
||||
|
||||
IT_PROG_INTLTOOL([0.34.90])
|
||||
LT_PREREQ([2.2.6])
|
||||
LT_INIT([disable-static])
|
||||
IT_PROG_INTLTOOL([0.41])
|
||||
AC_PROG_CC
|
||||
AC_ISC_POSIX
|
||||
AC_PROG_CC_C_O
|
||||
AC_PROG_INSTALL
|
||||
AC_HEADER_STDC
|
||||
AC_LIBTOOL_WIN32_DLL
|
||||
AM_PROG_LIBTOOL
|
||||
PKG_PROG_PKG_CONFIG([0.21])
|
||||
|
||||
# Sets GLIB_GENMARSHAL and GLIB_MKENUMS
|
||||
AM_PATH_GLIB_2_0()
|
||||
@@ -70,15 +72,22 @@ CLUTTER_PACKAGE=clutter-1.0
|
||||
|
||||
MUTTER_PC_MODULES="
|
||||
gtk+-3.0 >= 3.9.11
|
||||
gio-2.0 >= 2.25.10
|
||||
gio-unix-2.0 >= 2.25.10
|
||||
pango >= 1.2.0
|
||||
cairo >= 1.10.0
|
||||
gsettings-desktop-schemas >= 3.7.3
|
||||
xcomposite >= 0.2 xfixes xext xdamage xi >= 1.6.0
|
||||
$CLUTTER_PACKAGE >= 1.17.5
|
||||
xcursor
|
||||
$CLUTTER_PACKAGE >= 1.19.5
|
||||
clutter-egl-1.0
|
||||
cogl-1.0 >= 1.17.1
|
||||
libinput
|
||||
upower-glib >= 0.99.0
|
||||
gnome-desktop-3.0
|
||||
xkbfile
|
||||
xkeyboard-config
|
||||
xkbcommon-x11
|
||||
xcb-randr
|
||||
"
|
||||
|
||||
GLIB_GSETTINGS
|
||||
@@ -107,37 +116,12 @@ AC_ARG_WITH(libcanberra,
|
||||
[disable the use of libcanberra for playing sounds]),,
|
||||
with_libcanberra=auto)
|
||||
|
||||
AC_ARG_ENABLE(xsync,
|
||||
AC_HELP_STRING([--disable-xsync],
|
||||
[disable mutter's use of the XSync extension]),,
|
||||
enable_xsync=auto)
|
||||
|
||||
AC_ARG_ENABLE(shape,
|
||||
AC_HELP_STRING([--disable-shape],
|
||||
[disable mutter's use of the shaped window extension]),,
|
||||
enable_shape=auto)
|
||||
|
||||
## Wayland support requires the xserver.xml protocol extension found in the weston
|
||||
## repository but since there aren't currently established conventions for
|
||||
## installing and discovering these we simply require a location to be given
|
||||
## explicitly...
|
||||
AC_ARG_WITH([wayland-protocols],
|
||||
[AS_HELP_STRING([--with-wayland-protocols], [Location for wayland extension protocol specs])],
|
||||
[
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_WITH([xwayland-path],
|
||||
[AS_HELP_STRING([--with-xwayland-path], [Absolute path for an X Wayland server])],
|
||||
[XWAYLAND_PATH="$withval"],
|
||||
[XWAYLAND_PATH="$bindir/Xwayland"])
|
||||
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
|
||||
## here we get the flags we'll actually use
|
||||
# GRegex requires Glib-2.14.0
|
||||
PKG_CHECK_MODULES(ALL, glib-2.0 >= 2.14.0)
|
||||
PKG_CHECK_MODULES(MUTTER_LAUNCH, libdrm libsystemd-login)
|
||||
|
||||
# Unconditionally use this dir to avoid a circular dep with gnomecc
|
||||
GNOME_KEYBINDINGS_KEYSDIR="${datadir}/gnome-control-center/keybindings"
|
||||
@@ -202,17 +186,26 @@ if test x$found_introspection != xno; then
|
||||
AC_SUBST(META_GIR)
|
||||
fi
|
||||
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES xcursor"
|
||||
|
||||
AC_PATH_PROG([WAYLAND_SCANNER],[wayland-scanner],[no])
|
||||
AS_IF([test "x$WAYLAND_SCANNER" = "xno"],
|
||||
AC_MSG_ERROR([Could not find wayland-scanner in your PATH, required for parsing wayland extension protocols]))
|
||||
AC_SUBST([WAYLAND_SCANNER])
|
||||
AC_SUBST(XWAYLAND_PATH)
|
||||
|
||||
MUTTER_PC_MODULES="$MUTTER_PC_MODULES clutter-wayland-1.0 clutter-wayland-compositor-1.0 clutter-egl-1.0 wayland-server libdrm"
|
||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
||||
|
||||
PKG_CHECK_MODULES(MUTTER_NATIVE_BACKEND, [libdrm libsystemd], [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])
|
||||
|
||||
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_DEFINE([HAVE_WAYLAND],[1],[Define if you want to enable Wayland support])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_WAYLAND],[test $have_wayland = yes])
|
||||
|
||||
PKG_CHECK_EXISTS([xi >= 1.6.99.1],
|
||||
AC_DEFINE([HAVE_XI23],[1],[Define if you have support for XInput 2.3 or greater]))
|
||||
|
||||
@@ -249,16 +242,8 @@ if test x$have_xinerama = xno; then
|
||||
AC_MSG_ERROR([Xinerama extension was not found])
|
||||
fi
|
||||
|
||||
found_xkb=no
|
||||
AC_CHECK_LIB(X11, XkbQueryExtension,
|
||||
[AC_CHECK_HEADER(X11/XKBlib.h,
|
||||
found_xkb=yes)],
|
||||
, $ALL_X_LIBS)
|
||||
|
||||
if test "x$found_xkb" = "xyes"; then
|
||||
AC_DEFINE(HAVE_XKB, , [Have keyboard extension library])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED([XKB_BASE], ["`$PKG_CONFIG --variable xkb_base xkeyboard-config`"],
|
||||
[XKB base dir])
|
||||
|
||||
RANDR_LIBS=
|
||||
found_randr=no
|
||||
@@ -304,17 +289,6 @@ fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_SM, test "$found_sm" = "yes")
|
||||
|
||||
HOST_ALIAS=$host_alias
|
||||
AC_SUBST(HOST_ALIAS)
|
||||
|
||||
AC_PATH_PROG(GDK_PIXBUF_CSOURCE, gdk-pixbuf-csource, no)
|
||||
|
||||
if test x"$GDK_PIXBUF_CSOURCE" = xno; then
|
||||
AC_MSG_ERROR([gdk-pixbuf-csource executable not found in your path - should be installed with GTK])
|
||||
fi
|
||||
|
||||
AC_SUBST(GDK_PIXBUF_CSOURCE)
|
||||
|
||||
AC_PATH_PROG(ZENITY, zenity, no)
|
||||
if test x"$ZENITY" = xno; then
|
||||
AC_MSG_ERROR([zenity not found in your path - needed for dialogs])
|
||||
@@ -397,6 +371,7 @@ changequote([,])dnl
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
data/Makefile
|
||||
doc/Makefile
|
||||
doc/man/Makefile
|
||||
doc/reference/Makefile
|
||||
@@ -404,6 +379,7 @@ doc/reference/meta-docs.sgml
|
||||
src/Makefile
|
||||
src/libmutter.pc
|
||||
src/compositor/plugins/Makefile
|
||||
src/meta/meta-version.h
|
||||
po/Makefile.in
|
||||
])
|
||||
|
||||
|
@@ -45,26 +45,68 @@
|
||||
_description="Move window one monitor down" />
|
||||
|
||||
<KeyListEntry name="switch-applications"
|
||||
reverse-entry="switch-applications-backward"
|
||||
_description="Switch applications"/>
|
||||
|
||||
<KeyListEntry name="switch-applications-backward"
|
||||
reverse-entry="switch-applications"
|
||||
hidden="true"
|
||||
_description="Switch to previous application"/>
|
||||
|
||||
<KeyListEntry name="switch-windows"
|
||||
reverse-entry="switch-windows-backward"
|
||||
_description="Switch windows"/>
|
||||
|
||||
<KeyListEntry name="switch-windows-backward"
|
||||
reverse-entry="switch-windows"
|
||||
hidden="true"
|
||||
_description="Switch to previous window"/>
|
||||
|
||||
<KeyListEntry name="switch-group"
|
||||
reverse-entry="switch-group-backward"
|
||||
_description="Switch windows of an application"/>
|
||||
|
||||
<KeyListEntry name="switch-group-backward"
|
||||
reverse-entry="switch-group"
|
||||
hidden="true"
|
||||
_description="Switch to previous window of an application"/>
|
||||
|
||||
<KeyListEntry name="switch-panels"
|
||||
reverse-entry="switch-panels-backward"
|
||||
_description="Switch system controls"/>
|
||||
|
||||
<KeyListEntry name="switch-panels-backward"
|
||||
reverse-entry="switch-panels"
|
||||
hidden="true"
|
||||
_description="Switch to previous system control"/>
|
||||
|
||||
<KeyListEntry name="cycle-windows"
|
||||
reverse-entry="cycle-windows-backward"
|
||||
_description="Switch windows directly"/>
|
||||
|
||||
<KeyListEntry name="cycle-windows-backward"
|
||||
reverse-entry="cycle-windows"
|
||||
hidden="true"
|
||||
_description="Switch directly to previous window"/>
|
||||
|
||||
<KeyListEntry name="cycle-group"
|
||||
reverse-entry="cycle-group-backward"
|
||||
_description="Switch windows of an app directly"/>
|
||||
|
||||
<KeyListEntry name="cycle-group-backward"
|
||||
reverse-entry="cycle-group"
|
||||
hidden="true"
|
||||
_description="Switch directly to previous window of an app"/>
|
||||
|
||||
<KeyListEntry name="cycle-panels"
|
||||
reverse-entry="cycle-panels-backward"
|
||||
_description="Switch system controls directly"/>
|
||||
|
||||
<KeyListEntry name="cycle-panels-backward"
|
||||
reverse-entry="cycle-panels"
|
||||
hidden="true"
|
||||
_description="Switch directly to previous system control"/>
|
||||
|
||||
<KeyListEntry name="show-desktop"
|
||||
_description="Hide all normal windows"/>
|
||||
|
@@ -1,3 +1,36 @@
|
||||
defaultcursordir = $(datadir)/mutter/cursors
|
||||
desktopfiles_in_files = \
|
||||
mutter.desktop.in \
|
||||
mutter-wayland.desktop.in
|
||||
desktopfilesdir = $(datadir)/applications
|
||||
desktopfiles_DATA = $(desktopfiles_in_files:.desktop.in=.desktop)
|
||||
|
||||
dist_defaultcursor_DATA = left_ptr.png
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
xml_in_files = \
|
||||
50-mutter-navigation.xml.in \
|
||||
50-mutter-system.xml.in \
|
||||
50-mutter-windows.xml.in
|
||||
xmldir = $(GNOME_KEYBINDINGS_KEYSDIR)
|
||||
xml_DATA = $(xml_in_files:.xml.in=.xml)
|
||||
|
||||
gschema_in_files = \
|
||||
org.gnome.mutter.gschema.xml.in \
|
||||
org.gnome.mutter.wayland.gschema.xml.in
|
||||
gsettings_SCHEMAS = $(gschema_in_files:.xml.in=.xml)
|
||||
|
||||
@INTLTOOL_XML_NOMERGE_RULE@
|
||||
@GSETTINGS_RULES@
|
||||
|
||||
convertdir = $(datadir)/GConf/gsettings
|
||||
convert_DATA = mutter-schemas.convert
|
||||
|
||||
CLEANFILES = \
|
||||
$(desktopfiles_DATA) \
|
||||
$(gsettings_SCHEMAS) \
|
||||
$(xml_DATA)
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(convert_DATA) \
|
||||
$(desktopfiles_in_files) \
|
||||
$(gschema_in_files) \
|
||||
$(xml_in_files)
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1,7 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
_Name=Mutter (wayland compositor)
|
||||
Exec=mutter-launch -- mutter --wayland --display-server
|
||||
Exec=mutter --wayland --display-server
|
||||
NoDisplay=true
|
||||
# name of loadable control center module
|
||||
X-GNOME-WMSettingsModule=metacity
|
@@ -79,8 +79,6 @@ IGNORE_HFILES= \
|
||||
iconcache.h \
|
||||
inlinepixbufs.h \
|
||||
keybindings-private.h \
|
||||
menu.h \
|
||||
metaaccellabel.h \
|
||||
meta-background-actor-private.h \
|
||||
meta-background-group-private.h \
|
||||
meta-module.h \
|
||||
|
@@ -300,6 +300,7 @@ MetaPluginVersion
|
||||
META_PLUGIN_DECLARE
|
||||
meta_plugin_switch_workspace_completed
|
||||
meta_plugin_minimize_completed
|
||||
meta_plugin_unminimize_completed
|
||||
meta_plugin_maximize_completed
|
||||
meta_plugin_unmaximize_completed
|
||||
meta_plugin_map_completed
|
||||
@@ -555,7 +556,7 @@ meta_window_is_monitor_sized
|
||||
meta_window_is_override_redirect
|
||||
meta_window_is_skip_taskbar
|
||||
meta_window_get_rect
|
||||
meta_window_get_input_rect
|
||||
meta_window_get_buffer_rect
|
||||
meta_window_get_frame_rect
|
||||
meta_window_get_outer_rect
|
||||
meta_window_client_rect_to_frame_rect
|
||||
|
@@ -23,7 +23,8 @@ environment.</description>
|
||||
<download-page rdf:resource="http://download.gnome.org/sources/mutter/" />
|
||||
<bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=mutter" />
|
||||
|
||||
<category rdf:resource="http://api.gnome.org/doap-extensions#desktop" />
|
||||
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
|
||||
<programming-language>C</programming-language>
|
||||
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
|
@@ -1,8 +1,11 @@
|
||||
# List of source files containing translatable strings.
|
||||
# Please keep this file sorted alphabetically.
|
||||
src/50-mutter-navigation.xml.in
|
||||
src/50-mutter-system.xml.in
|
||||
src/50-mutter-windows.xml.in
|
||||
data/50-mutter-navigation.xml.in
|
||||
data/50-mutter-system.xml.in
|
||||
data/50-mutter-windows.xml.in
|
||||
data/mutter.desktop.in
|
||||
data/org.gnome.mutter.gschema.xml.in
|
||||
data/org.gnome.mutter.wayland.gschema.xml.in
|
||||
src/backends/meta-monitor-manager.c
|
||||
src/compositor/compositor.c
|
||||
src/compositor/meta-background.c
|
||||
@@ -18,12 +21,7 @@ src/core/prefs.c
|
||||
src/core/screen.c
|
||||
src/core/util.c
|
||||
src/core/window.c
|
||||
src/mutter.desktop.in
|
||||
src/org.gnome.mutter.gschema.xml.in
|
||||
src/org.gnome.mutter.wayland.gschema.xml.in
|
||||
src/ui/frames.c
|
||||
src/ui/menu.c
|
||||
src/ui/metaaccellabel.c
|
||||
src/ui/resizepopup.c
|
||||
src/ui/theme.c
|
||||
src/ui/theme-parser.c
|
||||
|
@@ -1,2 +1 @@
|
||||
src/metacity.schemas.in
|
||||
|
||||
data/mutter-wayland.desktop.in
|
||||
|
1283
po/pt_BR.po
1283
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
162
src/Makefile.am
162
src/Makefile.am
@@ -5,36 +5,36 @@ lib_LTLIBRARIES = libmutter.la
|
||||
|
||||
SUBDIRS=compositor/plugins
|
||||
|
||||
INCLUDES= \
|
||||
AM_CPPFLAGS = \
|
||||
-DCLUTTER_ENABLE_COMPOSITOR_API \
|
||||
-DCLUTTER_ENABLE_EXPERIMENTAL_API \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_API \
|
||||
-DCOGL_ENABLE_EXPERIMENTAL_2_0_API \
|
||||
-DCLUTTER_DISABLE_DEPRECATION_WARNINGS \
|
||||
-DCOGL_DISABLE_DEPRECATION_WARNINGS \
|
||||
$(MUTTER_CFLAGS) \
|
||||
$(MUTTER_NATIVE_BACKEND_CFLAGS) \
|
||||
-I$(builddir) \
|
||||
-I$(srcdir) \
|
||||
-I$(srcdir)/backends \
|
||||
-I$(srcdir)/core \
|
||||
-I$(srcdir)/ui \
|
||||
-I$(srcdir)/compositor \
|
||||
-DMUTTER_LIBEXECDIR=\"$(libexecdir)\" \
|
||||
-DHOST_ALIAS=\"@HOST_ALIAS@\" \
|
||||
-DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" \
|
||||
-DMUTTER_LOCALEDIR=\"$(localedir)\" \
|
||||
-DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" \
|
||||
-DMUTTER_DATADIR=\"$(datadir)\" \
|
||||
-DG_LOG_DOMAIN=\"mutter\" \
|
||||
-DSN_API_NOT_YET_FROZEN=1 \
|
||||
-DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION) \
|
||||
-DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION) \
|
||||
-DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION) \
|
||||
-DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) \
|
||||
-DMUTTER_PKGLIBDIR=\"$(pkglibdir)\" \
|
||||
-DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\" \
|
||||
-DMUTTER_PLUGIN_DIR=\"$(MUTTER_PLUGIN_DIR)\" \
|
||||
-DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
|
||||
-DXWAYLAND_PATH='"@XWAYLAND_PATH@"'
|
||||
-DXWAYLAND_PATH=\"$(XWAYLAND_PATH)\"
|
||||
|
||||
mutter_built_sources = \
|
||||
$(dbus_idle_built_sources) \
|
||||
$(dbus_display_config_built_sources) \
|
||||
$(dbus_login1_built_sources) \
|
||||
mutter-enum-types.h \
|
||||
mutter-enum-types.c \
|
||||
gtk-shell-protocol.c \
|
||||
@@ -48,7 +48,7 @@ wayland_protocols = \
|
||||
|
||||
libmutter_la_SOURCES = \
|
||||
backends/meta-backend.c \
|
||||
backends/meta-backend.h \
|
||||
meta/meta-backend.h \
|
||||
backends/meta-backend-private.h \
|
||||
backends/meta-cursor.c \
|
||||
backends/meta-cursor.h \
|
||||
@@ -68,20 +68,14 @@ libmutter_la_SOURCES = \
|
||||
backends/meta-monitor-manager.h \
|
||||
backends/meta-monitor-manager-dummy.c \
|
||||
backends/meta-monitor-manager-dummy.h \
|
||||
backends/meta-stage.h \
|
||||
backends/meta-stage.c \
|
||||
backends/edid-parse.c \
|
||||
backends/edid.h \
|
||||
backends/native/meta-backend-native.c \
|
||||
backends/native/meta-backend-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-monitor-manager-kms.c \
|
||||
backends/native/meta-monitor-manager-kms.h \
|
||||
backends/native/meta-launcher.c \
|
||||
backends/native/meta-launcher.h \
|
||||
backends/x11/meta-backend-x11.c \
|
||||
backends/x11/meta-backend-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-monitor-manager-xrandr.c \
|
||||
@@ -120,10 +114,6 @@ libmutter_la_SOURCES = \
|
||||
compositor/meta-surface-actor.h \
|
||||
compositor/meta-surface-actor-x11.c \
|
||||
compositor/meta-surface-actor-x11.h \
|
||||
compositor/meta-surface-actor-wayland.c \
|
||||
compositor/meta-surface-actor-wayland.h \
|
||||
compositor/meta-stage.h \
|
||||
compositor/meta-stage.c \
|
||||
compositor/meta-texture-rectangle.c \
|
||||
compositor/meta-texture-rectangle.h \
|
||||
compositor/meta-texture-tower.c \
|
||||
@@ -161,6 +151,8 @@ libmutter_la_SOURCES = \
|
||||
core/frame.h \
|
||||
ui/gradient.c \
|
||||
meta/gradient.h \
|
||||
core/meta-gesture-tracker.c \
|
||||
core/meta-gesture-tracker-private.h \
|
||||
core/keybindings.c \
|
||||
core/keybindings-private.h \
|
||||
core/main.c \
|
||||
@@ -172,6 +164,7 @@ libmutter_la_SOURCES = \
|
||||
core/screen-private.h \
|
||||
meta/screen.h \
|
||||
meta/types.h \
|
||||
core/restart.c \
|
||||
core/stack.c \
|
||||
core/stack.h \
|
||||
core/stack-tracker.c \
|
||||
@@ -189,10 +182,6 @@ libmutter_la_SOURCES = \
|
||||
ui/ui.h \
|
||||
ui/frames.c \
|
||||
ui/frames.h \
|
||||
ui/menu.c \
|
||||
ui/menu.h \
|
||||
ui/metaaccellabel.c \
|
||||
ui/metaaccellabel.h \
|
||||
ui/resizepopup.c \
|
||||
ui/resizepopup.h \
|
||||
ui/theme-parser.c \
|
||||
@@ -204,6 +193,8 @@ libmutter_la_SOURCES = \
|
||||
x11/iconcache.h \
|
||||
x11/async-getprop.c \
|
||||
x11/async-getprop.h \
|
||||
x11/events.c \
|
||||
x11/events.h \
|
||||
x11/group-private.h \
|
||||
x11/group-props.c \
|
||||
x11/group-props.h \
|
||||
@@ -218,7 +209,12 @@ libmutter_la_SOURCES = \
|
||||
x11/window-x11-private.h \
|
||||
x11/xprops.c \
|
||||
x11/xprops.h \
|
||||
x11/mutter-Xatomtype.h \
|
||||
x11/mutter-Xatomtype.h
|
||||
|
||||
if HAVE_WAYLAND
|
||||
libmutter_la_SOURCES += \
|
||||
compositor/meta-surface-actor-wayland.c \
|
||||
compositor/meta-surface-actor-wayland.h \
|
||||
wayland/meta-wayland.c \
|
||||
wayland/meta-wayland.h \
|
||||
wayland/meta-wayland-private.h \
|
||||
@@ -233,6 +229,8 @@ libmutter_la_SOURCES = \
|
||||
wayland/meta-wayland-pointer.h \
|
||||
wayland/meta-wayland-seat.c \
|
||||
wayland/meta-wayland-seat.h \
|
||||
wayland/meta-wayland-touch.c \
|
||||
wayland/meta-wayland-touch.h \
|
||||
wayland/meta-wayland-surface.c \
|
||||
wayland/meta-wayland-surface.h \
|
||||
wayland/meta-wayland-types.h \
|
||||
@@ -241,16 +239,33 @@ libmutter_la_SOURCES = \
|
||||
wayland/meta-wayland-outputs.h \
|
||||
wayland/window-wayland.c \
|
||||
wayland/window-wayland.h
|
||||
endif
|
||||
|
||||
if HAVE_NATIVE_BACKEND
|
||||
libmutter_la_SOURCES += \
|
||||
backends/native/meta-backend-native.c \
|
||||
backends/native/meta-backend-native.h \
|
||||
backends/native/meta-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-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
|
||||
endif
|
||||
|
||||
nodist_libmutter_la_SOURCES = \
|
||||
$(mutter_built_sources)
|
||||
|
||||
libmutter_la_LDFLAGS = -no-undefined
|
||||
libmutter_la_LIBADD = $(MUTTER_LIBS)
|
||||
libmutter_la_LIBADD = $(MUTTER_LIBS) $(MUTTER_NATIVE_BACKEND_LIBS)
|
||||
|
||||
# Headers installed for plugins; introspected information will
|
||||
# be extracted into Mutter-<version>.gir
|
||||
libmutterinclude_base_headers = \
|
||||
libmutterinclude_headers = \
|
||||
meta/barrier.h \
|
||||
meta/boxes.h \
|
||||
meta/common.h \
|
||||
@@ -262,6 +277,7 @@ libmutterinclude_base_headers = \
|
||||
meta/group.h \
|
||||
meta/keybindings.h \
|
||||
meta/main.h \
|
||||
meta/meta-backend.h \
|
||||
meta/meta-background-actor.h \
|
||||
meta/meta-background-group.h \
|
||||
meta/meta-background.h \
|
||||
@@ -279,6 +295,13 @@ libmutterinclude_base_headers = \
|
||||
meta/window.h \
|
||||
meta/workspace.h
|
||||
|
||||
libmutterinclude_built_headers = \
|
||||
meta/meta-version.h
|
||||
|
||||
libmutterinclude_base_headers = \
|
||||
$(libmutterinclude_headers) \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
# Excluded from scanning for introspection but installed
|
||||
# atomnames.h: macros cause problems for scanning process
|
||||
libmutterinclude_extra_headers = \
|
||||
@@ -287,26 +310,20 @@ libmutterinclude_extra_headers = \
|
||||
libmutterincludedir = $(includedir)/mutter/meta
|
||||
|
||||
libmutterinclude_HEADERS = \
|
||||
$(libmutterinclude_base_headers) \
|
||||
$(libmutterinclude_headers) \
|
||||
$(libmutterinclude_extra_headers)
|
||||
|
||||
nodist_libmutterinclude_HEADERS = \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
bin_PROGRAMS=mutter
|
||||
|
||||
mutter_SOURCES = core/mutter.c
|
||||
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
|
||||
bin_PROGRAMS+=mutter-launch
|
||||
|
||||
mutter_launch_SOURCES = \
|
||||
backends/native/weston-launch.c \
|
||||
backends/native/weston-launch.h
|
||||
|
||||
mutter_launch_CFLAGS = $(MUTTER_LAUNCH_CFLAGS) -DLIBDIR=\"$(libdir)\"
|
||||
mutter_launch_LDFLAGS = $(MUTTER_LAUNCH_LIBS) -lpam
|
||||
|
||||
install-exec-hook:
|
||||
-chown root $(DESTDIR)$(bindir)/mutter-launch
|
||||
-chmod u+s $(DESTDIR)$(bindir)/mutter-launch
|
||||
libexec_PROGRAMS = mutter-restart-helper
|
||||
mutter_restart_helper_SOURCES = core/restart-helper.c
|
||||
mutter_restart_helper_LDADD = $(MUTTER_LIBS)
|
||||
|
||||
if HAVE_INTROSPECTION
|
||||
include $(INTROSPECTION_MAKEFILE)
|
||||
@@ -331,7 +348,7 @@ INTROSPECTION_GIRS = Meta-$(api_version).gir
|
||||
Meta-$(api_version).gir: libmutter.la
|
||||
@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0 Cogl-1.0
|
||||
@META_GIR@_EXPORT_PACKAGES = libmutter
|
||||
@META_GIR@_CFLAGS = $(INCLUDES)
|
||||
@META_GIR@_CFLAGS = $(AM_CPPFLAGS)
|
||||
@META_GIR@_LIBS = libmutter.la
|
||||
@META_GIR@_FILES = \
|
||||
mutter-enum-types.h \
|
||||
@@ -351,60 +368,32 @@ testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
|
||||
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
desktopfilesdir=$(datadir)/applications
|
||||
desktopfiles_in_files=mutter.desktop.in
|
||||
desktopfiles_files=$(desktopfiles_in_files:.desktop.in=.desktop)
|
||||
desktopfiles_DATA = $(desktopfiles_files)
|
||||
|
||||
xmldir = @GNOME_KEYBINDINGS_KEYSDIR@
|
||||
xml_in_files = \
|
||||
50-mutter-navigation.xml.in \
|
||||
50-mutter-system.xml.in \
|
||||
50-mutter-windows.xml.in
|
||||
xml_DATA = $(xml_in_files:.xml.in=.xml)
|
||||
|
||||
dbus_idle_built_sources = meta-dbus-idle-monitor.c meta-dbus-idle-monitor.h
|
||||
|
||||
gsettings_SCHEMAS = org.gnome.mutter.gschema.xml org.gnome.mutter.wayland.gschema.xml
|
||||
@INTLTOOL_XML_NOMERGE_RULE@
|
||||
@GSETTINGS_RULES@
|
||||
|
||||
convertdir = $(datadir)/GConf/gsettings
|
||||
convert_DATA = mutter-schemas.convert
|
||||
|
||||
CLEANFILES = \
|
||||
mutter.desktop \
|
||||
mutter-wm.desktop \
|
||||
org.gnome.mutter.gschema.xml \
|
||||
org.gnome.mutter.wayland.gschema.xml \
|
||||
$(xml_DATA) \
|
||||
$(mutter_built_sources) \
|
||||
$(typelib_DATA) \
|
||||
$(gir_DATA)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
DISTCLEANFILES = \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libmutter.pc
|
||||
|
||||
EXTRA_DIST=$(desktopfiles_files) \
|
||||
$(wmproperties_files) \
|
||||
$(IMAGES) \
|
||||
$(desktopfiles_in_files) \
|
||||
$(wmproperties_in_files) \
|
||||
$(xml_in_files) \
|
||||
EXTRA_DIST = \
|
||||
$(wayland_protocols) \
|
||||
org.gnome.mutter.gschema.xml.in \
|
||||
org.gnome.mutter.wayland.gschema.xml.in \
|
||||
mutter-schemas.convert \
|
||||
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
|
||||
|
||||
BUILT_SOURCES = $(mutter_built_sources)
|
||||
BUILT_SOURCES = \
|
||||
$(mutter_built_sources) \
|
||||
$(libmutterinclude_built_headers)
|
||||
|
||||
MUTTER_STAMP_FILES = stamp-mutter-enum-types.h
|
||||
CLEANFILES += $(MUTTER_STAMP_FILES)
|
||||
|
||||
@@ -444,6 +433,15 @@ $(dbus_idle_built_sources) : Makefile.am org.gnome.Mutter.IdleMonitor.xml
|
||||
--c-generate-object-manager \
|
||||
$(srcdir)/org.gnome.Mutter.IdleMonitor.xml
|
||||
|
||||
dbus_login1_built_sources = meta-dbus-login1.c meta-dbus-login1.h
|
||||
|
||||
$(dbus_login1_built_sources) : Makefile.am org.freedesktop.login1.xml
|
||||
$(AM_V_GEN)gdbus-codegen \
|
||||
--interface-prefix org.freedesktop.login1 \
|
||||
--c-namespace Login1 \
|
||||
--generate-c-code meta-dbus-login1 \
|
||||
$(srcdir)/org.freedesktop.login1.xml
|
||||
|
||||
%-protocol.c : $(srcdir)/wayland/protocol/%.xml
|
||||
$(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
|
||||
%-server-protocol.h : $(srcdir)/wayland/protocol/%.xml
|
||||
|
@@ -179,7 +179,7 @@ decode_display_parameters (const uchar *edid, MonitorInfo *info)
|
||||
else if (edid[0x16] == 0)
|
||||
{
|
||||
info->width_mm = -1;
|
||||
info->height_mm = -1;
|
||||
info->height_mm = -1;
|
||||
info->aspect_ratio = 100.0 / (edid[0x15] + 99);
|
||||
}
|
||||
else if (edid[0x15] == 0)
|
||||
@@ -267,7 +267,7 @@ decode_color_characteristics (const uchar *edid, MonitorInfo *info)
|
||||
static int
|
||||
decode_established_timings (const uchar *edid, MonitorInfo *info)
|
||||
{
|
||||
static const Timing established[][8] =
|
||||
static const Timing established[][8] =
|
||||
{
|
||||
{
|
||||
{ 800, 600, 60 },
|
||||
|
@@ -1,9 +1,9 @@
|
||||
/* edid.h
|
||||
*
|
||||
* Copyright 2007, 2008, Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* This file is part of the Gnome Library.
|
||||
*
|
||||
*
|
||||
* The Gnome Library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -13,12 +13,12 @@
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
* write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*
|
||||
* Author: Soren Sandmann <sandmann@redhat.com>
|
||||
*/
|
||||
|
||||
@@ -177,7 +177,7 @@ struct MonitorInfo
|
||||
DetailedTiming detailed_timings[4]; /* If monitor has a preferred
|
||||
* mode, it is the first one
|
||||
* (whether it has, is
|
||||
* determined by the
|
||||
* determined by the
|
||||
* preferred_timing_includes
|
||||
* bit.
|
||||
*/
|
||||
|
@@ -28,7 +28,15 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "meta-backend.h"
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/meta-idle-monitor.h>
|
||||
#include "meta-cursor-renderer.h"
|
||||
#include "meta-monitor-manager.h"
|
||||
|
||||
#define DEFAULT_XKB_RULES_FILE "evdev"
|
||||
#define DEFAULT_XKB_MODEL "pc105+inet"
|
||||
|
||||
#define META_TYPE_BACKEND (meta_backend_get_type ())
|
||||
#define META_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKEND, MetaBackend))
|
||||
@@ -62,6 +70,41 @@ struct _MetaBackendClass
|
||||
gboolean (* ungrab_device) (MetaBackend *backend,
|
||||
int device_id,
|
||||
uint32_t timestamp);
|
||||
|
||||
void (* warp_pointer) (MetaBackend *backend,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void (* set_keymap) (MetaBackend *backend,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options);
|
||||
|
||||
struct xkb_keymap * (* get_keymap) (MetaBackend *backend);
|
||||
|
||||
void (* lock_layout_group) (MetaBackend *backend,
|
||||
guint idx);
|
||||
|
||||
void (* update_screen_size) (MetaBackend *backend, int width, int height);
|
||||
void (* select_stage_events) (MetaBackend *backend);
|
||||
};
|
||||
|
||||
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
int device_id);
|
||||
MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend);
|
||||
MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
|
||||
|
||||
gboolean meta_backend_grab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
uint32_t timestamp);
|
||||
gboolean meta_backend_ungrab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
uint32_t timestamp);
|
||||
|
||||
void meta_backend_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
struct xkb_keymap * meta_backend_get_keymap (MetaBackend *backend);
|
||||
|
||||
#endif /* META_BACKEND_PRIVATE_H */
|
||||
|
@@ -24,16 +24,25 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-backend.h"
|
||||
#include <meta/meta-backend.h>
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
#include "meta-stage.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-backend-native.h"
|
||||
#endif
|
||||
|
||||
static MetaBackend *_backend;
|
||||
|
||||
/**
|
||||
* meta_get_backend:
|
||||
*
|
||||
* Accessor for the singleton MetaBackend.
|
||||
*
|
||||
* Returns: (transfer none): The only #MetaBackend there is.
|
||||
*/
|
||||
MetaBackend *
|
||||
meta_get_backend (void)
|
||||
{
|
||||
@@ -44,6 +53,8 @@ struct _MetaBackendPrivate
|
||||
{
|
||||
MetaMonitorManager *monitor_manager;
|
||||
MetaCursorRenderer *cursor_renderer;
|
||||
|
||||
ClutterActor *stage;
|
||||
};
|
||||
typedef struct _MetaBackendPrivate MetaBackendPrivate;
|
||||
|
||||
@@ -67,13 +78,41 @@ meta_backend_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_sync_screen_size (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
int width, height;
|
||||
|
||||
meta_monitor_manager_get_screen_size (priv->monitor_manager, &width, &height);
|
||||
|
||||
META_BACKEND_GET_CLASS (backend)->update_screen_size (backend, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
on_monitors_changed (MetaMonitorManager *monitors,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaBackend *backend = META_BACKEND (user_data);
|
||||
meta_backend_sync_screen_size (backend);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_real_post_init (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
|
||||
priv->stage = meta_stage_new ();
|
||||
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);
|
||||
|
||||
g_signal_connect (priv->monitor_manager, "monitors-changed",
|
||||
G_CALLBACK (on_monitors_changed), backend);
|
||||
meta_backend_sync_screen_size (backend);
|
||||
|
||||
priv->cursor_renderer = META_BACKEND_GET_CLASS (backend)->create_cursor_renderer (backend);
|
||||
}
|
||||
|
||||
static MetaCursorRenderer *
|
||||
@@ -100,6 +139,21 @@ meta_backend_real_ungrab_device (MetaBackend *backend,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_real_update_screen_size (MetaBackend *backend,
|
||||
int width, int height)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
|
||||
clutter_actor_set_size (priv->stage, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_real_select_stage_events (MetaBackend *backend)
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_class_init (MetaBackendClass *klass)
|
||||
{
|
||||
@@ -111,6 +165,15 @@ meta_backend_class_init (MetaBackendClass *klass)
|
||||
klass->create_cursor_renderer = meta_backend_real_create_cursor_renderer;
|
||||
klass->grab_device = meta_backend_real_grab_device;
|
||||
klass->ungrab_device = meta_backend_real_ungrab_device;
|
||||
klass->update_screen_size = meta_backend_real_update_screen_size;
|
||||
klass->select_stage_events = meta_backend_real_select_stage_events;
|
||||
|
||||
g_signal_new ("keymap-changed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -142,6 +205,9 @@ meta_backend_post_init (MetaBackend *backend)
|
||||
META_BACKEND_GET_CLASS (backend)->post_init (backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_idle_monitor: (skip)
|
||||
*/
|
||||
MetaIdleMonitor *
|
||||
meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
int device_id)
|
||||
@@ -157,6 +223,9 @@ meta_backend_get_idle_monitor (MetaBackend *backend,
|
||||
return backend->device_monitors[device_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_monitor_manager: (skip)
|
||||
*/
|
||||
MetaMonitorManager *
|
||||
meta_backend_get_monitor_manager (MetaBackend *backend)
|
||||
{
|
||||
@@ -165,6 +234,9 @@ meta_backend_get_monitor_manager (MetaBackend *backend)
|
||||
return priv->monitor_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_cursor_renderer: (skip)
|
||||
*/
|
||||
MetaCursorRenderer *
|
||||
meta_backend_get_cursor_renderer (MetaBackend *backend)
|
||||
{
|
||||
@@ -173,6 +245,9 @@ meta_backend_get_cursor_renderer (MetaBackend *backend)
|
||||
return priv->cursor_renderer;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_grab_device: (skip)
|
||||
*/
|
||||
gboolean
|
||||
meta_backend_grab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
@@ -181,6 +256,9 @@ meta_backend_grab_device (MetaBackend *backend,
|
||||
return META_BACKEND_GET_CLASS (backend)->grab_device (backend, device_id, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_ungrab_device: (skip)
|
||||
*/
|
||||
gboolean
|
||||
meta_backend_ungrab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
@@ -189,6 +267,58 @@ meta_backend_ungrab_device (MetaBackend *backend,
|
||||
return META_BACKEND_GET_CLASS (backend)->ungrab_device (backend, device_id, timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_warp_pointer: (skip)
|
||||
*/
|
||||
void
|
||||
meta_backend_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
META_BACKEND_GET_CLASS (backend)->warp_pointer (backend, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_set_keymap (MetaBackend *backend,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options)
|
||||
{
|
||||
META_BACKEND_GET_CLASS (backend)->set_keymap (backend, layouts, variants, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_keymap: (skip)
|
||||
*/
|
||||
struct xkb_keymap *
|
||||
meta_backend_get_keymap (MetaBackend *backend)
|
||||
|
||||
{
|
||||
return META_BACKEND_GET_CLASS (backend)->get_keymap (backend);
|
||||
}
|
||||
|
||||
void
|
||||
meta_backend_lock_layout_group (MetaBackend *backend,
|
||||
guint idx)
|
||||
{
|
||||
META_BACKEND_GET_CLASS (backend)->lock_layout_group (backend, idx);
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_backend_get_stage:
|
||||
* @backend: A #MetaBackend
|
||||
*
|
||||
* Gets the global #ClutterStage that's managed by this backend.
|
||||
*
|
||||
* Returns: (transfer none): the #ClutterStage
|
||||
*/
|
||||
ClutterActor *
|
||||
meta_backend_get_stage (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
|
||||
return priv->stage;
|
||||
}
|
||||
|
||||
static GType
|
||||
get_backend_type (void)
|
||||
{
|
||||
@@ -197,7 +327,7 @@ get_backend_type (void)
|
||||
return META_TYPE_BACKEND_X11;
|
||||
#endif
|
||||
|
||||
#if defined(CLUTTER_WINDOWING_EGL)
|
||||
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
|
||||
return META_TYPE_BACKEND_NATIVE;
|
||||
#endif
|
||||
@@ -261,6 +391,9 @@ static GSourceFuncs event_funcs = {
|
||||
event_dispatch
|
||||
};
|
||||
|
||||
/**
|
||||
* meta_clutter_init: (skip)
|
||||
*/
|
||||
void
|
||||
meta_clutter_init (void)
|
||||
{
|
||||
|
@@ -27,20 +27,21 @@
|
||||
#include "meta-cursor-renderer.h"
|
||||
#include "meta-cursor-private.h"
|
||||
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "meta-stage.h"
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
struct _MetaCursorRendererPrivate
|
||||
{
|
||||
int current_x, current_y;
|
||||
MetaRectangle current_rect;
|
||||
|
||||
MetaCursorReference *displayed_cursor;
|
||||
gboolean handled_by_backend;
|
||||
};
|
||||
typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
|
||||
|
||||
@@ -50,26 +51,23 @@ static void
|
||||
queue_redraw (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
ClutterActor *stage = compositor->stage;
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
|
||||
/* During early initialization, we can have no stage */
|
||||
if (!stage)
|
||||
return;
|
||||
|
||||
/* If we're not using a MetaStage, quit early */
|
||||
if (!META_IS_STAGE (stage))
|
||||
return;
|
||||
|
||||
meta_stage_set_cursor (META_STAGE (stage),
|
||||
priv->displayed_cursor,
|
||||
&priv->current_rect);
|
||||
if (priv->handled_by_backend)
|
||||
meta_stage_set_cursor (META_STAGE (stage), NULL, &priv->current_rect);
|
||||
else
|
||||
meta_stage_set_cursor (META_STAGE (stage), priv->displayed_cursor, &priv->current_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
meta_cursor_renderer_real_update_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
queue_redraw (renderer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -87,6 +85,8 @@ static void
|
||||
update_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
|
||||
gboolean handled_by_backend;
|
||||
gboolean should_redraw = FALSE;
|
||||
|
||||
if (priv->displayed_cursor)
|
||||
{
|
||||
@@ -108,7 +108,18 @@ update_cursor (MetaCursorRenderer *renderer)
|
||||
priv->current_rect.height = 0;
|
||||
}
|
||||
|
||||
META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
|
||||
handled_by_backend = META_CURSOR_RENDERER_GET_CLASS (renderer)->update_cursor (renderer);
|
||||
if (handled_by_backend != priv->handled_by_backend)
|
||||
{
|
||||
priv->handled_by_backend = handled_by_backend;
|
||||
should_redraw = TRUE;
|
||||
}
|
||||
|
||||
if (!handled_by_backend)
|
||||
should_redraw = TRUE;
|
||||
|
||||
if (should_redraw)
|
||||
queue_redraw (renderer);
|
||||
}
|
||||
|
||||
MetaCursorRenderer *
|
||||
|
@@ -51,7 +51,7 @@ struct _MetaCursorRendererClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* update_cursor) (MetaCursorRenderer *renderer);
|
||||
gboolean (* update_cursor) (MetaCursorRenderer *renderer);
|
||||
};
|
||||
|
||||
GType meta_cursor_renderer_get_type (void) G_GNUC_CONST;
|
||||
|
@@ -23,8 +23,6 @@
|
||||
#define META_CURSOR_TRACKER_PRIVATE_H
|
||||
|
||||
#include <meta/meta-cursor-tracker.h>
|
||||
#include <wayland-server.h>
|
||||
#include <gbm.h>
|
||||
|
||||
#include "meta-cursor.h"
|
||||
#include "meta-cursor-renderer.h"
|
||||
@@ -32,28 +30,13 @@
|
||||
struct _MetaCursorTracker {
|
||||
GObject parent_instance;
|
||||
|
||||
MetaScreen *screen;
|
||||
MetaCursorRenderer *renderer;
|
||||
|
||||
gboolean is_showing;
|
||||
|
||||
/* The cursor tracker stores the cursor for the current grab
|
||||
* operation, the cursor for the window with pointer focus, and
|
||||
* the cursor for the root window, which contains either the
|
||||
* default arrow cursor or the 'busy' hourglass if we're launching
|
||||
* an app.
|
||||
*
|
||||
* We choose the first one available -- if there's a grab cursor,
|
||||
* we choose that cursor, if there's window cursor, we choose that,
|
||||
* otherwise we choose the root cursor.
|
||||
*
|
||||
* The displayed_cursor contains the chosen cursor.
|
||||
*/
|
||||
MetaCursorReference *displayed_cursor;
|
||||
|
||||
MetaCursorReference *grab_cursor;
|
||||
|
||||
/* Wayland clients can set a NULL buffer as their cursor
|
||||
/* Wayland clients can set a NULL buffer as their cursor
|
||||
* explicitly, which means that we shouldn't display anything.
|
||||
* So, we can't simply store a NULL in window_cursor to
|
||||
* determine an unset window cursor; we need an extra boolean.
|
||||
@@ -62,6 +45,9 @@ struct _MetaCursorTracker {
|
||||
MetaCursorReference *window_cursor;
|
||||
|
||||
MetaCursorReference *root_cursor;
|
||||
|
||||
/* The cursor from the X11 server. */
|
||||
MetaCursorReference *xfixes_cursor;
|
||||
};
|
||||
|
||||
struct _MetaCursorTrackerClass {
|
||||
@@ -71,8 +57,6 @@ struct _MetaCursorTrackerClass {
|
||||
gboolean meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
XEvent *xevent);
|
||||
|
||||
void meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor);
|
||||
void meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor);
|
||||
void meta_cursor_tracker_unset_window_cursor (MetaCursorTracker *tracker);
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright 2013 Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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/>.
|
||||
*
|
||||
@@ -34,25 +34,21 @@
|
||||
#include <meta/errors.h>
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
|
||||
#include "meta-backend.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "screen-private.h"
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaCursorTracker, meta_cursor_tracker, G_TYPE_OBJECT);
|
||||
|
||||
enum {
|
||||
CURSOR_CHANGED,
|
||||
LAST_SIGNAL
|
||||
CURSOR_CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
@@ -60,14 +56,16 @@ static guint signals[LAST_SIGNAL];
|
||||
static MetaCursorReference *
|
||||
get_displayed_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
if (!tracker->is_showing)
|
||||
return NULL;
|
||||
|
||||
if (tracker->grab_cursor)
|
||||
return tracker->grab_cursor;
|
||||
|
||||
if (tracker->has_window_cursor)
|
||||
return tracker->window_cursor;
|
||||
if (meta_display_windows_are_interactable (display))
|
||||
{
|
||||
if (tracker->has_window_cursor)
|
||||
return tracker->window_cursor;
|
||||
}
|
||||
|
||||
return tracker->root_cursor;
|
||||
}
|
||||
@@ -97,11 +95,9 @@ sync_cursor (MetaCursorTracker *tracker)
|
||||
static void
|
||||
meta_cursor_tracker_init (MetaCursorTracker *self)
|
||||
{
|
||||
/* (JS) Best (?) that can be assumed since XFixes doesn't provide a way of
|
||||
detecting if the system mouse cursor is showing or not.
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
|
||||
On wayland we start with the cursor showing
|
||||
*/
|
||||
self->renderer = meta_backend_get_cursor_renderer (backend);
|
||||
self->is_showing = TRUE;
|
||||
}
|
||||
|
||||
@@ -134,47 +130,9 @@ meta_cursor_tracker_class_init (MetaCursorTrackerClass *klass)
|
||||
}
|
||||
|
||||
static MetaCursorTracker *
|
||||
make_wayland_cursor_tracker (MetaScreen *screen)
|
||||
meta_cursor_tracker_new (void)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaWaylandCompositor *compositor;
|
||||
MetaCursorTracker *self;
|
||||
|
||||
self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
|
||||
self->screen = screen;
|
||||
self->renderer = meta_backend_get_cursor_renderer (backend);
|
||||
|
||||
compositor = meta_wayland_compositor_get_default ();
|
||||
compositor->seat->pointer.cursor_tracker = self;
|
||||
meta_cursor_tracker_update_position (self, 0, 0);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static MetaCursorTracker *
|
||||
make_x11_cursor_tracker (MetaScreen *screen)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaCursorTracker *self;
|
||||
|
||||
self = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
|
||||
self->screen = screen;
|
||||
self->renderer = meta_backend_get_cursor_renderer (backend);
|
||||
|
||||
XFixesSelectCursorInput (screen->display->xdisplay,
|
||||
screen->xroot,
|
||||
XFixesDisplayCursorNotifyMask);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
static MetaCursorTracker *
|
||||
meta_cursor_tracker_new (MetaScreen *screen)
|
||||
{
|
||||
if (meta_is_wayland_compositor ())
|
||||
return make_wayland_cursor_tracker (screen);
|
||||
else
|
||||
return make_x11_cursor_tracker (screen);
|
||||
return g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
|
||||
}
|
||||
|
||||
static MetaCursorTracker *_cursor_tracker;
|
||||
@@ -191,7 +149,7 @@ MetaCursorTracker *
|
||||
meta_cursor_tracker_get_for_screen (MetaScreen *screen)
|
||||
{
|
||||
if (!_cursor_tracker)
|
||||
_cursor_tracker = meta_cursor_tracker_new (screen);
|
||||
_cursor_tracker = meta_cursor_tracker_new ();
|
||||
|
||||
return _cursor_tracker;
|
||||
}
|
||||
@@ -212,19 +170,20 @@ gboolean
|
||||
meta_cursor_tracker_handle_xevent (MetaCursorTracker *tracker,
|
||||
XEvent *xevent)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
XFixesCursorNotifyEvent *notify_event;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
return FALSE;
|
||||
|
||||
if (xevent->xany.type != tracker->screen->display->xfixes_event_base + XFixesCursorNotify)
|
||||
if (xevent->xany.type != display->xfixes_event_base + XFixesCursorNotify)
|
||||
return FALSE;
|
||||
|
||||
notify_event = (XFixesCursorNotifyEvent *)xevent;
|
||||
if (notify_event->subtype != XFixesDisplayCursorNotify)
|
||||
return FALSE;
|
||||
|
||||
set_window_cursor (tracker, FALSE, NULL);
|
||||
g_clear_pointer (&tracker->xfixes_cursor, meta_cursor_reference_unref);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -248,16 +207,17 @@ meta_cursor_reference_take_texture (CoglTexture2D *texture,
|
||||
static void
|
||||
ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
XFixesCursorImage *cursor_image;
|
||||
CoglTexture2D *sprite;
|
||||
guint8 *cursor_data;
|
||||
gboolean free_cursor_data;
|
||||
CoglContext *ctx;
|
||||
|
||||
if (tracker->has_window_cursor)
|
||||
if (tracker->xfixes_cursor)
|
||||
return;
|
||||
|
||||
cursor_image = XFixesGetCursorImage (tracker->screen->display->xdisplay);
|
||||
cursor_image = XFixesGetCursorImage (display->xdisplay);
|
||||
if (!cursor_image)
|
||||
return;
|
||||
|
||||
@@ -304,7 +264,7 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
MetaCursorReference *cursor = meta_cursor_reference_take_texture (sprite,
|
||||
cursor_image->xhot,
|
||||
cursor_image->yhot);
|
||||
set_window_cursor (tracker, TRUE, cursor);
|
||||
tracker->xfixes_cursor = cursor;
|
||||
}
|
||||
XFree (cursor_image);
|
||||
}
|
||||
@@ -317,13 +277,22 @@ ensure_xfixes_cursor (MetaCursorTracker *tracker)
|
||||
CoglTexture *
|
||||
meta_cursor_tracker_get_sprite (MetaCursorTracker *tracker)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
|
||||
g_return_val_if_fail (META_IS_CURSOR_TRACKER (tracker), NULL);
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
ensure_xfixes_cursor (tracker);
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
cursor = tracker->displayed_cursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_xfixes_cursor (tracker);
|
||||
cursor = tracker->xfixes_cursor;
|
||||
}
|
||||
|
||||
if (tracker->displayed_cursor)
|
||||
return meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, NULL, NULL);
|
||||
if (cursor)
|
||||
return meta_cursor_reference_get_cogl_texture (cursor, NULL, NULL);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
@@ -340,13 +309,22 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
MetaCursorReference *cursor;
|
||||
|
||||
g_return_if_fail (META_IS_CURSOR_TRACKER (tracker));
|
||||
|
||||
if (!meta_is_wayland_compositor ())
|
||||
ensure_xfixes_cursor (tracker);
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
cursor = tracker->displayed_cursor;
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_xfixes_cursor (tracker);
|
||||
cursor = tracker->xfixes_cursor;
|
||||
}
|
||||
|
||||
if (tracker->displayed_cursor)
|
||||
meta_cursor_reference_get_cogl_texture (tracker->displayed_cursor, x, y);
|
||||
if (cursor)
|
||||
meta_cursor_reference_get_cogl_texture (cursor, x, y);
|
||||
else
|
||||
{
|
||||
if (x)
|
||||
@@ -356,17 +334,6 @@ meta_cursor_tracker_get_hot (MetaCursorTracker *tracker,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_grab_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor)
|
||||
{
|
||||
g_clear_pointer (&tracker->grab_cursor, meta_cursor_reference_unref);
|
||||
if (cursor)
|
||||
tracker->grab_cursor = meta_cursor_reference_ref (cursor);
|
||||
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
|
||||
void
|
||||
meta_cursor_tracker_set_window_cursor (MetaCursorTracker *tracker,
|
||||
MetaCursorReference *cursor)
|
||||
@@ -466,19 +433,7 @@ meta_cursor_tracker_set_pointer_visible (MetaCursorTracker *tracker,
|
||||
return;
|
||||
tracker->is_showing = visible;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (visible)
|
||||
XFixesShowCursor (tracker->screen->display->xdisplay,
|
||||
tracker->screen->xroot);
|
||||
else
|
||||
XFixesHideCursor (tracker->screen->display->xdisplay,
|
||||
tracker->screen->xroot);
|
||||
}
|
||||
sync_cursor (tracker);
|
||||
}
|
||||
|
||||
MetaCursorReference *
|
||||
|
@@ -27,8 +27,11 @@
|
||||
|
||||
#include "display-private.h"
|
||||
#include "screen-private.h"
|
||||
#include "meta-backend.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
#include "backends/native/meta-cursor-renderer-native.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -36,7 +39,9 @@
|
||||
#include <X11/extensions/Xfixes.h>
|
||||
#include <X11/Xcursor/Xcursor.h>
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include <cogl/cogl-wayland-server.h>
|
||||
#endif
|
||||
|
||||
MetaCursorReference *
|
||||
meta_cursor_reference_ref (MetaCursorReference *self)
|
||||
@@ -171,13 +176,15 @@ meta_cursor_image_load_gbm_buffer (struct gbm_device *gbm,
|
||||
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));
|
||||
else
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -242,6 +249,7 @@ meta_cursor_reference_from_theme (MetaCursor cursor)
|
||||
return self;
|
||||
}
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
static void
|
||||
meta_cursor_image_load_from_buffer (MetaCursorImage *image,
|
||||
struct wl_resource *buffer,
|
||||
@@ -340,6 +348,7 @@ meta_cursor_reference_from_buffer (struct wl_resource *buffer,
|
||||
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
CoglTexture *
|
||||
meta_cursor_reference_get_cogl_texture (MetaCursorReference *cursor,
|
||||
|
@@ -28,13 +28,15 @@ MetaCursorReference * meta_cursor_reference_ref (MetaCursorReference *cursor);
|
||||
void meta_cursor_reference_unref (MetaCursorReference *cursor);
|
||||
|
||||
#include <meta/common.h>
|
||||
#include <wayland-server.h>
|
||||
|
||||
MetaCursorReference * meta_cursor_reference_from_theme (MetaCursor cursor);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include <wayland-server.h>
|
||||
MetaCursorReference * meta_cursor_reference_from_buffer (struct wl_resource *buffer,
|
||||
int hot_x,
|
||||
int hot_y);
|
||||
#endif
|
||||
|
||||
MetaCursor meta_cursor_reference_get_meta_cursor (MetaCursorReference *cursor);
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -11,7 +11,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
|
@@ -180,6 +180,9 @@ create_monitor_skeleton (GDBusObjectManagerServer *manager,
|
||||
meta_dbus_object_skeleton_set_idle_monitor (object, skeleton);
|
||||
|
||||
g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
|
||||
|
||||
g_object_unref (skeleton);
|
||||
g_object_unref (object);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright 2013 Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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/>.
|
||||
*
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright 2013 Red Hat, Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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/>.
|
||||
*
|
||||
@@ -38,7 +38,7 @@
|
||||
#include <meta/meta-idle-monitor.h>
|
||||
#include "meta-idle-monitor-private.h"
|
||||
#include "meta-idle-monitor-dbus.h"
|
||||
#include "meta-backend.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
G_STATIC_ASSERT(sizeof(unsigned long) == sizeof(gpointer));
|
||||
|
||||
@@ -210,9 +210,9 @@ make_watch (MetaIdleMonitor *monitor,
|
||||
* meta_idle_monitor_add_idle_watch:
|
||||
* @monitor: A #MetaIdleMonitor
|
||||
* @interval_msec: The idletime interval, in milliseconds
|
||||
* @callback: (allow-none): The callback to call when the user has
|
||||
* @callback: (nullable): The callback to call when the user has
|
||||
* accumulated @interval_msec milliseconds of idle time.
|
||||
* @user_data: (allow-none): The user data to pass to the callback
|
||||
* @user_data: (nullable): The user data to pass to the callback
|
||||
* @notify: A #GDestroyNotify
|
||||
*
|
||||
* Returns: a watch id
|
||||
@@ -252,9 +252,9 @@ meta_idle_monitor_add_idle_watch (MetaIdleMonitor *monitor,
|
||||
/**
|
||||
* meta_idle_monitor_add_user_active_watch:
|
||||
* @monitor: A #MetaIdleMonitor
|
||||
* @callback: (allow-none): The callback to call when the user is
|
||||
* @callback: (nullable): The callback to call when the user is
|
||||
* active again.
|
||||
* @user_data: (allow-none): The user data to pass to the callback
|
||||
* @user_data: (nullable): The user data to pass to the callback
|
||||
* @notify: A #GDestroyNotify
|
||||
*
|
||||
* Returns: a watch id
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003 Red Hat Inc.
|
||||
* Some ICCCM manager selection code derived from fvwm2,
|
||||
@@ -8,7 +8,7 @@
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -18,7 +18,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -60,7 +60,7 @@ typedef struct {
|
||||
gboolean enabled;
|
||||
MetaRectangle rect;
|
||||
float refresh_rate;
|
||||
enum wl_output_transform transform;
|
||||
MetaMonitorTransform transform;
|
||||
|
||||
gboolean is_primary;
|
||||
gboolean is_presentation;
|
||||
@@ -78,6 +78,7 @@ struct _MetaMonitorConfig {
|
||||
GHashTable *configs;
|
||||
MetaConfiguration *current;
|
||||
gboolean current_is_stored;
|
||||
gboolean current_is_for_laptop_lid;
|
||||
MetaConfiguration *previous;
|
||||
|
||||
GFile *file;
|
||||
@@ -570,7 +571,7 @@ is_all_whitespace (const char *text,
|
||||
gsize text_len)
|
||||
{
|
||||
gsize i;
|
||||
|
||||
|
||||
for (i = 0; i < text_len; i++)
|
||||
if (!g_ascii_isspace (text[i]))
|
||||
return FALSE;
|
||||
@@ -655,20 +656,20 @@ handle_text (GMarkupParseContext *context,
|
||||
else if (strcmp (parser->output_field, "rotation") == 0)
|
||||
{
|
||||
if (strncmp (text, "normal", text_len) == 0)
|
||||
parser->output.transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
parser->output.transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
else if (strncmp (text, "left", text_len) == 0)
|
||||
parser->output.transform = WL_OUTPUT_TRANSFORM_90;
|
||||
parser->output.transform = META_MONITOR_TRANSFORM_90;
|
||||
else if (strncmp (text, "upside_down", text_len) == 0)
|
||||
parser->output.transform = WL_OUTPUT_TRANSFORM_180;
|
||||
parser->output.transform = META_MONITOR_TRANSFORM_180;
|
||||
else if (strncmp (text, "right", text_len) == 0)
|
||||
parser->output.transform = WL_OUTPUT_TRANSFORM_270;
|
||||
parser->output.transform = META_MONITOR_TRANSFORM_270;
|
||||
else
|
||||
g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
|
||||
"Invalid rotation type %.*s", (int)text_len, text);
|
||||
}
|
||||
else if (strcmp (parser->output_field, "reflect_x") == 0)
|
||||
parser->output.transform += read_bool (text, text_len, error) ?
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED : 0;
|
||||
META_MONITOR_TRANSFORM_FLIPPED : 0;
|
||||
else if (strcmp (parser->output_field, "reflect_y") == 0)
|
||||
{
|
||||
/* FIXME (look at the rotation map in monitor.c) */
|
||||
@@ -877,7 +878,8 @@ apply_configuration (MetaMonitorConfig *self,
|
||||
|
||||
/* 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.
|
||||
about to become previous) is stored, or if the current one has
|
||||
different outputs.
|
||||
*/
|
||||
if (stored ||
|
||||
(self->current && self->current_is_stored))
|
||||
@@ -888,11 +890,27 @@ apply_configuration (MetaMonitorConfig *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
self->previous = self->current;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
*/
|
||||
self->current_is_for_laptop_lid = FALSE;
|
||||
|
||||
if (self->current == self->previous)
|
||||
self->previous = NULL;
|
||||
@@ -1009,8 +1027,16 @@ meta_monitor_config_apply_stored (MetaMonitorConfig *self,
|
||||
if (self->lid_is_closed &&
|
||||
stored->n_outputs > 1 &&
|
||||
laptop_display_is_on (stored))
|
||||
return apply_configuration (self, make_laptop_lid_config (stored),
|
||||
manager, FALSE);
|
||||
{
|
||||
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);
|
||||
}
|
||||
@@ -1089,7 +1115,7 @@ make_default_config (MetaMonitorConfig *self,
|
||||
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 = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
ret->outputs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[0].is_primary = TRUE;
|
||||
|
||||
return ret;
|
||||
@@ -1141,7 +1167,7 @@ make_default_config (MetaMonitorConfig *self,
|
||||
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 = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
ret->outputs[j].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[j].is_primary = FALSE;
|
||||
ret->outputs[j].is_presentation = FALSE;
|
||||
}
|
||||
@@ -1176,7 +1202,7 @@ make_default_config (MetaMonitorConfig *self,
|
||||
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 = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].is_primary = (output == primary);
|
||||
|
||||
/* Disable outputs that would go beyond framebuffer limits */
|
||||
@@ -1224,7 +1250,7 @@ ensure_at_least_one_output (MetaMonitorConfig *self,
|
||||
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 = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
ret->outputs[i].is_primary = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -1357,6 +1383,7 @@ turn_off_laptop_display (MetaMonitorConfig *self,
|
||||
|
||||
new = make_laptop_lid_config (self->current);
|
||||
apply_configuration (self, new, manager, FALSE);
|
||||
self->current_is_for_laptop_lid = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1376,7 +1403,7 @@ power_client_changed_cb (UpClient *client,
|
||||
|
||||
if (is_closed)
|
||||
turn_off_laptop_display (self, manager);
|
||||
else
|
||||
else if (self->current_is_for_laptop_lid)
|
||||
meta_monitor_config_restore_previous (self, manager);
|
||||
}
|
||||
}
|
||||
@@ -1485,7 +1512,7 @@ meta_monitor_config_save (MetaMonitorConfig *self)
|
||||
output->rect.x,
|
||||
output->rect.y,
|
||||
rotation_map[output->transform & 0x3],
|
||||
output->transform >= WL_OUTPUT_TRANSFORM_FLIPPED ? "yes" : "no",
|
||||
output->transform >= META_MONITOR_TRANSFORM_FLIPPED ? "yes" : "no",
|
||||
output->is_primary ? "yes" : "no",
|
||||
output->is_presentation ? "yes" : "no");
|
||||
}
|
||||
@@ -1594,13 +1621,13 @@ output_supports_mode (MetaOutput *output,
|
||||
}
|
||||
|
||||
static gboolean
|
||||
crtc_assignment_assign (CrtcAssignment *assign,
|
||||
MetaCRTC *crtc,
|
||||
MetaMonitorMode *mode,
|
||||
int x,
|
||||
int y,
|
||||
enum wl_output_transform transform,
|
||||
MetaOutput *output)
|
||||
crtc_assignment_assign (CrtcAssignment *assign,
|
||||
MetaCRTC *crtc,
|
||||
MetaMonitorMode *mode,
|
||||
int x,
|
||||
int y,
|
||||
MetaMonitorTransform transform,
|
||||
MetaOutput *output)
|
||||
{
|
||||
MetaCRTCInfo *info = g_hash_table_lookup (assign->info, crtc);
|
||||
|
||||
|
@@ -27,7 +27,7 @@
|
||||
|
||||
#include "meta-monitor-manager-dummy.h"
|
||||
|
||||
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
|
||||
struct _MetaMonitorManagerDummy
|
||||
{
|
||||
@@ -66,8 +66,8 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
|
||||
manager->crtcs[0].rect.width = manager->modes[0].width;
|
||||
manager->crtcs[0].rect.height = manager->modes[0].height;
|
||||
manager->crtcs[0].current_mode = &manager->modes[0];
|
||||
manager->crtcs[0].transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
manager->crtcs[0].all_transforms = ALL_WL_TRANSFORMS;
|
||||
manager->crtcs[0].transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
manager->crtcs[0].all_transforms = ALL_TRANSFORMS;
|
||||
manager->crtcs[0].is_dirty = FALSE;
|
||||
manager->crtcs[0].logical_monitor = NULL;
|
||||
|
||||
@@ -75,7 +75,7 @@ meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
|
||||
manager->n_outputs = 1;
|
||||
|
||||
manager->outputs[0].crtc = &manager->crtcs[0];
|
||||
manager->outputs[0].output_id = 1;
|
||||
manager->outputs[0].winsys_id = 1;
|
||||
manager->outputs[0].name = g_strdup ("LVDS");
|
||||
manager->outputs[0].vendor = g_strdup ("MetaProducts Inc.");
|
||||
manager->outputs[0].product = g_strdup ("unknown");
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003 Red Hat Inc.
|
||||
* Some ICCCM manager selection code derived from fvwm2,
|
||||
@@ -8,7 +8,7 @@
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -18,7 +18,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <meta/errors.h>
|
||||
#include "meta-monitor-config.h"
|
||||
#include "backends/x11/meta-monitor-manager-xrandr.h"
|
||||
#include "meta-backend.h"
|
||||
#include "meta-backend-private.h"
|
||||
|
||||
enum {
|
||||
CONFIRM_DISPLAY_CHANGE,
|
||||
@@ -125,7 +125,7 @@ make_logical_config (MetaMonitorManager *manager)
|
||||
*/
|
||||
info.is_presentation = TRUE;
|
||||
info.in_fullscreen = -1;
|
||||
info.output_id = 0;
|
||||
info.winsys_id = 0;
|
||||
|
||||
g_array_append_val (monitor_infos, info);
|
||||
|
||||
@@ -156,8 +156,8 @@ make_logical_config (MetaMonitorManager *manager)
|
||||
info->is_primary = info->is_primary || output->is_primary;
|
||||
info->is_presentation = info->is_presentation && output->is_presentation;
|
||||
|
||||
if (output->is_primary || info->output_id == 0)
|
||||
info->output_id = output->output_id;
|
||||
if (output->is_primary || info->winsys_id == 0)
|
||||
info->winsys_id = output->winsys_id;
|
||||
|
||||
if (info->is_primary)
|
||||
manager->primary_monitor_index = info->number;
|
||||
@@ -477,7 +477,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
GVariantBuilder transforms;
|
||||
|
||||
g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
|
||||
for (j = 0; j <= WL_OUTPUT_TRANSFORM_FLIPPED_270; j++)
|
||||
for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++)
|
||||
if (crtc->all_transforms & (1 << j))
|
||||
g_variant_builder_add (&transforms, "u", j);
|
||||
|
||||
@@ -560,7 +560,7 @@ meta_monitor_manager_handle_get_resources (MetaDBusDisplayConfig *skeleton,
|
||||
|
||||
g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
|
||||
i, /* ID */
|
||||
(gint64)output->output_id,
|
||||
(gint64)output->winsys_id,
|
||||
(int)(output->crtc ? output->crtc - manager->crtcs : -1),
|
||||
&crtcs,
|
||||
output->name,
|
||||
@@ -667,7 +667,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
int new_mode, x, y;
|
||||
int new_screen_width, new_screen_height;
|
||||
guint transform;
|
||||
guint output_id;
|
||||
guint output_index;
|
||||
GPtrArray *crtc_infos, *output_infos;
|
||||
|
||||
if (serial != manager->serial)
|
||||
@@ -694,7 +694,6 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
MetaOutput *first_output;
|
||||
MetaCRTC *crtc;
|
||||
MetaMonitorMode *mode;
|
||||
guint output_id;
|
||||
|
||||
crtc_info = g_slice_new (MetaCRTCInfo);
|
||||
crtc_info->outputs = g_ptr_array_new ();
|
||||
@@ -756,8 +755,8 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
crtc_info->y = 0;
|
||||
}
|
||||
|
||||
if (transform < WL_OUTPUT_TRANSFORM_NORMAL ||
|
||||
transform > WL_OUTPUT_TRANSFORM_FLIPPED_270 ||
|
||||
if (transform < META_MONITOR_TRANSFORM_NORMAL ||
|
||||
transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
|
||||
((crtc->all_transforms & (1 << transform)) == 0))
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
@@ -768,18 +767,18 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
crtc_info->transform = transform;
|
||||
|
||||
first_output = NULL;
|
||||
while (g_variant_iter_loop (nested_outputs, "u", &output_id))
|
||||
while (g_variant_iter_loop (nested_outputs, "u", &output_index))
|
||||
{
|
||||
MetaOutput *output;
|
||||
|
||||
if (output_id >= manager->n_outputs)
|
||||
if (output_index >= manager->n_outputs)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid output id");
|
||||
return TRUE;
|
||||
}
|
||||
output = &manager->outputs[output_id];
|
||||
output = &manager->outputs[output_index];
|
||||
|
||||
if (!output_can_config (output, crtc, mode))
|
||||
{
|
||||
@@ -824,12 +823,12 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
}
|
||||
|
||||
g_variant_iter_init (&output_iter, outputs);
|
||||
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_id, &properties))
|
||||
while (g_variant_iter_loop (&output_iter, "(u@a{sv})", &output_index, &properties))
|
||||
{
|
||||
MetaOutputInfo *output_info;
|
||||
gboolean primary, presentation;
|
||||
|
||||
if (output_id >= manager->n_outputs)
|
||||
if (output_index >= manager->n_outputs)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_INVALID_ARGS,
|
||||
@@ -838,7 +837,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
}
|
||||
|
||||
output_info = g_slice_new0 (MetaOutputInfo);
|
||||
output_info->output = &manager->outputs[output_id];
|
||||
output_info->output = &manager->outputs[output_index];
|
||||
|
||||
if (g_variant_lookup (properties, "primary", "b", &primary))
|
||||
output_info->is_primary = primary;
|
||||
@@ -852,7 +851,7 @@ meta_monitor_manager_handle_apply_configuration (MetaDBusDisplayConfig *skeleto
|
||||
/* If we were in progress of making a persistent change and we see a
|
||||
new request, it's likely that the old one failed in some way, so
|
||||
don't save it, but also don't queue for restoring it.
|
||||
*/
|
||||
*/
|
||||
if (manager->persistent_timeout_id && persistent)
|
||||
{
|
||||
g_source_remove (manager->persistent_timeout_id);
|
||||
@@ -909,7 +908,7 @@ static gboolean
|
||||
meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
|
||||
GDBusMethodInvocation *invocation,
|
||||
guint serial,
|
||||
guint output_id,
|
||||
guint output_index,
|
||||
gint value)
|
||||
{
|
||||
MetaMonitorManager *manager = META_MONITOR_MANAGER (skeleton);
|
||||
@@ -923,14 +922,14 @@ meta_monitor_manager_handle_change_backlight (MetaDBusDisplayConfig *skeleton,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (output_id >= manager->n_outputs)
|
||||
if (output_index >= manager->n_outputs)
|
||||
{
|
||||
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
|
||||
G_DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid output id");
|
||||
return TRUE;
|
||||
}
|
||||
output = &manager->outputs[output_id];
|
||||
output = &manager->outputs[output_index];
|
||||
|
||||
if (value < 0 || value > 100)
|
||||
{
|
||||
|
@@ -12,12 +12,12 @@
|
||||
* at MetaScreen instead.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -27,7 +27,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -41,8 +41,6 @@
|
||||
#include "display-private.h"
|
||||
#include <meta/screen.h>
|
||||
#include "stack-tracker.h"
|
||||
#include "ui.h"
|
||||
#include <wayland-server.h>
|
||||
|
||||
#include "meta-display-config-shared.h"
|
||||
#include "meta-dbus-display-config.h"
|
||||
@@ -60,12 +58,23 @@ typedef struct _MetaMonitorInfo MetaMonitorInfo;
|
||||
typedef struct _MetaCRTCInfo MetaCRTCInfo;
|
||||
typedef struct _MetaOutputInfo MetaOutputInfo;
|
||||
|
||||
typedef enum {
|
||||
META_MONITOR_TRANSFORM_NORMAL,
|
||||
META_MONITOR_TRANSFORM_90,
|
||||
META_MONITOR_TRANSFORM_180,
|
||||
META_MONITOR_TRANSFORM_270,
|
||||
META_MONITOR_TRANSFORM_FLIPPED,
|
||||
META_MONITOR_TRANSFORM_FLIPPED_90,
|
||||
META_MONITOR_TRANSFORM_FLIPPED_180,
|
||||
META_MONITOR_TRANSFORM_FLIPPED_270,
|
||||
} MetaMonitorTransform;
|
||||
|
||||
struct _MetaOutput
|
||||
{
|
||||
/* The CRTC driving this output, NULL if the output is not enabled */
|
||||
MetaCRTC *crtc;
|
||||
/* The low-level ID of this output, used to apply back configuration */
|
||||
glong output_id;
|
||||
glong winsys_id;
|
||||
char *name;
|
||||
char *vendor;
|
||||
char *product;
|
||||
@@ -73,6 +82,7 @@ struct _MetaOutput
|
||||
int width_mm;
|
||||
int height_mm;
|
||||
CoglSubpixelOrder subpixel_order;
|
||||
int scale;
|
||||
|
||||
MetaMonitorMode *preferred_mode;
|
||||
MetaMonitorMode **modes;
|
||||
@@ -113,7 +123,7 @@ struct _MetaCRTC
|
||||
glong crtc_id;
|
||||
MetaRectangle rect;
|
||||
MetaMonitorMode *current_mode;
|
||||
enum wl_output_transform transform;
|
||||
MetaMonitorTransform transform;
|
||||
unsigned int all_transforms;
|
||||
|
||||
/* Only used to build the logical configuration
|
||||
@@ -161,14 +171,14 @@ struct _MetaMonitorInfo
|
||||
gboolean in_fullscreen;
|
||||
|
||||
/* The primary or first output for this monitor, 0 if we can't figure out.
|
||||
It can be matched to an output_id of a MetaOutput.
|
||||
It can be matched to a winsys_id of a MetaOutput.
|
||||
|
||||
This is used as an opaque token on reconfiguration when switching from
|
||||
clone to extened, to decide on what output the windows should go next
|
||||
(it's an attempt to keep windows on the same monitor, and preferably on
|
||||
the primary one).
|
||||
*/
|
||||
glong output_id;
|
||||
glong winsys_id;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -184,7 +194,7 @@ struct _MetaCRTCInfo {
|
||||
MetaMonitorMode *mode;
|
||||
int x;
|
||||
int y;
|
||||
enum wl_output_transform transform;
|
||||
MetaMonitorTransform transform;
|
||||
GPtrArray *outputs;
|
||||
};
|
||||
|
||||
@@ -338,7 +348,7 @@ gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorMana
|
||||
/* Returns true if transform causes width and height to be inverted
|
||||
This is true for the odd transforms in the enum */
|
||||
static inline gboolean
|
||||
meta_monitor_transform_is_rotated (enum wl_output_transform transform)
|
||||
meta_monitor_transform_is_rotated (MetaMonitorTransform transform)
|
||||
{
|
||||
return (transform % 2);
|
||||
}
|
||||
|
@@ -25,12 +25,11 @@
|
||||
#include "meta-stage.h"
|
||||
|
||||
#include "meta-cursor-private.h"
|
||||
#include "meta-backend.h"
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/util.h>
|
||||
|
||||
struct _MetaStagePrivate {
|
||||
CoglPipeline *pipeline;
|
||||
gboolean should_paint_cursor;
|
||||
|
||||
MetaCursorReference *cursor;
|
||||
|
107
src/backends/native/dbus-utils.c
Normal file
107
src/backends/native/dbus-utils.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/* -*- 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.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "dbus-utils.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/* Stolen from tp_escape_as_identifier, from tp-glib,
|
||||
* which follows the same escaping convention as systemd.
|
||||
*/
|
||||
static inline gboolean
|
||||
_esc_ident_bad (gchar c, gboolean is_first)
|
||||
{
|
||||
return ((c < 'a' || c > 'z') &&
|
||||
(c < 'A' || c > 'Z') &&
|
||||
(c < '0' || c > '9' || is_first));
|
||||
}
|
||||
|
||||
static gchar *
|
||||
escape_dbus_component (const gchar *name)
|
||||
{
|
||||
gboolean bad = FALSE;
|
||||
size_t len = 0;
|
||||
GString *op;
|
||||
const gchar *ptr, *first_ok;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
/* fast path for empty name */
|
||||
if (name[0] == '\0')
|
||||
return g_strdup ("_");
|
||||
|
||||
for (ptr = name; *ptr; ptr++)
|
||||
{
|
||||
if (_esc_ident_bad (*ptr, ptr == name))
|
||||
{
|
||||
bad = TRUE;
|
||||
len += 3;
|
||||
}
|
||||
else
|
||||
len++;
|
||||
}
|
||||
|
||||
/* fast path if it's clean */
|
||||
if (!bad)
|
||||
return g_strdup (name);
|
||||
|
||||
/* If strictly less than ptr, first_ok is the first uncopied safe character.
|
||||
*/
|
||||
first_ok = name;
|
||||
op = g_string_sized_new (len);
|
||||
for (ptr = name; *ptr; ptr++)
|
||||
{
|
||||
if (_esc_ident_bad (*ptr, ptr == name))
|
||||
{
|
||||
/* copy preceding safe characters if any */
|
||||
if (first_ok < ptr)
|
||||
{
|
||||
g_string_append_len (op, first_ok, ptr - first_ok);
|
||||
}
|
||||
/* escape the unsafe character */
|
||||
g_string_append_printf (op, "_%02x", (unsigned char)(*ptr));
|
||||
/* restart after it */
|
||||
first_ok = ptr + 1;
|
||||
}
|
||||
}
|
||||
/* copy trailing safe characters if any */
|
||||
if (first_ok < ptr)
|
||||
{
|
||||
g_string_append_len (op, first_ok, ptr - first_ok);
|
||||
}
|
||||
return g_string_free (op, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
get_escaped_dbus_path (const char *prefix,
|
||||
const char *component)
|
||||
{
|
||||
char *escaped_component = escape_dbus_component (component);
|
||||
char *path = g_strconcat (prefix, "/", escaped_component, NULL);
|
||||
|
||||
g_free (escaped_component);
|
||||
return path;
|
||||
}
|
32
src/backends/native/dbus-utils.h
Normal file
32
src/backends/native/dbus-utils.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/* -*- 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.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#ifndef DBUS_UTILS_H
|
||||
#define DBUS_UTILS_H
|
||||
|
||||
char *
|
||||
get_escaped_dbus_path (const char *prefix,
|
||||
const char *component);
|
||||
|
||||
#endif /* DBUS_UTILS_H */
|
@@ -174,6 +174,63 @@ meta_backend_native_create_cursor_renderer (MetaBackend *backend)
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_NATIVE, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
ClutterInputDevice *device = clutter_device_manager_get_core_device (manager, CLUTTER_POINTER_DEVICE);
|
||||
|
||||
/* XXX */
|
||||
guint32 time_ = 0;
|
||||
|
||||
clutter_evdev_warp_pointer (device, time_, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_set_keymap (MetaBackend *backend,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
struct xkb_rule_names names;
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_context *context;
|
||||
|
||||
names.rules = DEFAULT_XKB_RULES_FILE;
|
||||
names.model = DEFAULT_XKB_MODEL;
|
||||
names.layout = layouts;
|
||||
names.variant = variants;
|
||||
names.options = options;
|
||||
|
||||
context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||
keymap = xkb_keymap_new_from_names (context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_context_unref (context);
|
||||
|
||||
clutter_evdev_set_keyboard_map (manager, keymap);
|
||||
|
||||
g_signal_emit_by_name (backend, "keymap-changed", 0);
|
||||
|
||||
xkb_keymap_unref (keymap);
|
||||
}
|
||||
|
||||
static struct xkb_keymap *
|
||||
meta_backend_native_get_keymap (MetaBackend *backend)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
return clutter_evdev_get_keyboard_map (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_lock_layout_group (MetaBackend *backend,
|
||||
guint idx)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
clutter_evdev_set_keyboard_layout_index (manager, idx);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
||||
{
|
||||
@@ -183,6 +240,11 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
|
||||
backend_class->create_idle_monitor = meta_backend_native_create_idle_monitor;
|
||||
backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
|
||||
backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer;
|
||||
|
||||
backend_class->warp_pointer = meta_backend_native_warp_pointer;
|
||||
backend_class->set_keymap = meta_backend_native_set_keymap;
|
||||
backend_class->get_keymap = meta_backend_native_get_keymap;
|
||||
backend_class->lock_layout_group = meta_backend_native_lock_layout_group;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -120,7 +120,7 @@ update_hw_cursor (MetaCursorRendererNative *native,
|
||||
|
||||
set_crtc_cursor (native, &crtcs[i], crtc_cursor, force);
|
||||
|
||||
if (cursor)
|
||||
if (crtc_cursor)
|
||||
{
|
||||
drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
|
||||
cursor_rect->x - crtc_rect->x,
|
||||
@@ -140,7 +140,7 @@ should_have_hw_cursor (MetaCursorRenderer *renderer)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
static gboolean
|
||||
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
|
||||
@@ -148,10 +148,7 @@ meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer)
|
||||
|
||||
priv->has_hw_cursor = should_have_hw_cursor (renderer);
|
||||
update_hw_cursor (native, FALSE);
|
||||
|
||||
/* Fall back to the stage-based cursor if we don't have HW cursors. */
|
||||
if (!priv->has_hw_cursor)
|
||||
META_CURSOR_RENDERER_CLASS (meta_cursor_renderer_native_parent_class)->update_cursor (renderer);
|
||||
return priv->has_hw_cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -20,9 +20,8 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-launcher.h"
|
||||
#include "weston-launch.h"
|
||||
|
||||
#include <gio/gunixfdmessage.h>
|
||||
#include <gio/gunixfdlist.h>
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <clutter/egl/clutter-egl.h>
|
||||
@@ -30,167 +29,59 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <malloc.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "backends/meta-backend.h"
|
||||
#include <systemd/sd-login.h>
|
||||
|
||||
#include "dbus-utils.h"
|
||||
#include "meta-dbus-login1.h"
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "meta-cursor-renderer-native.h"
|
||||
|
||||
struct _MetaLauncher
|
||||
{
|
||||
GSocket *weston_launch;
|
||||
Login1Session *session_proxy;
|
||||
Login1Seat *seat_proxy;
|
||||
|
||||
gboolean vt_switched;
|
||||
|
||||
GMainContext *nested_context;
|
||||
GMainLoop *nested_loop;
|
||||
|
||||
GSource *inner_source;
|
||||
GSource *outer_source;
|
||||
gboolean session_active;
|
||||
};
|
||||
|
||||
static void handle_request_vt_switch (MetaLauncher *self);
|
||||
|
||||
static gboolean
|
||||
request_vt_switch_idle (gpointer user_data)
|
||||
static Login1Session *
|
||||
get_session_proxy (GCancellable *cancellable)
|
||||
{
|
||||
handle_request_vt_switch (user_data);
|
||||
char *proxy_path;
|
||||
char *session_id;
|
||||
Login1Session *session_proxy;
|
||||
|
||||
return FALSE;
|
||||
if (sd_pid_get_session (getpid (), &session_id) < 0)
|
||||
return NULL;
|
||||
|
||||
proxy_path = get_escaped_dbus_path ("/org/freedesktop/login1/session", session_id);
|
||||
|
||||
session_proxy = login1_session_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
proxy_path,
|
||||
cancellable, NULL);
|
||||
free (proxy_path);
|
||||
|
||||
return session_proxy;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
send_message_to_wl (MetaLauncher *self,
|
||||
void *message,
|
||||
gsize size,
|
||||
GSocketControlMessage *out_cmsg,
|
||||
GSocketControlMessage **in_cmsg,
|
||||
GError **error)
|
||||
static Login1Seat *
|
||||
get_seat_proxy (GCancellable *cancellable)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
GInputVector in_iov = { &reply, sizeof (reply) };
|
||||
GOutputVector out_iov = { message, size };
|
||||
GSocketControlMessage *out_all_cmsg[2];
|
||||
GSocketControlMessage **in_all_cmsg;
|
||||
int flags = 0;
|
||||
int i;
|
||||
|
||||
out_all_cmsg[0] = out_cmsg;
|
||||
out_all_cmsg[1] = NULL;
|
||||
if (g_socket_send_message (self->weston_launch, NULL,
|
||||
&out_iov, 1,
|
||||
out_all_cmsg, -1,
|
||||
flags, NULL, error) != (gssize)size)
|
||||
return FALSE;
|
||||
|
||||
if (g_socket_receive_message (self->weston_launch, NULL,
|
||||
&in_iov, 1,
|
||||
&in_all_cmsg, NULL,
|
||||
&flags, NULL, error) != sizeof (reply))
|
||||
return FALSE;
|
||||
|
||||
while (reply.header.opcode != ((struct weston_launcher_message*)message)->opcode)
|
||||
{
|
||||
guint id;
|
||||
|
||||
/* There were events queued */
|
||||
g_assert ((reply.header.opcode & WESTON_LAUNCHER_EVENT) == WESTON_LAUNCHER_EVENT);
|
||||
|
||||
/* This can never happen, because the only time mutter-launch can queue
|
||||
this event is after confirming a VT switch, and we don't make requests
|
||||
during that time.
|
||||
|
||||
Note that getting this event would be really bad, because we would be
|
||||
in the wrong loop/context.
|
||||
*/
|
||||
g_assert (reply.header.opcode != WESTON_LAUNCHER_SERVER_VT_ENTER);
|
||||
|
||||
switch (reply.header.opcode)
|
||||
{
|
||||
case WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH:
|
||||
id = g_idle_add (request_vt_switch_idle, self);
|
||||
g_source_set_name_by_id (id, "[mutter] request_vt_switch_idle");
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
if (g_socket_receive_message (self->weston_launch, NULL,
|
||||
&in_iov, 1,
|
||||
NULL, NULL,
|
||||
&flags, NULL, error) != sizeof (reply))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (reply.ret != 0)
|
||||
{
|
||||
if (reply.ret == -1)
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Got failure from weston-launch");
|
||||
else
|
||||
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-reply.ret),
|
||||
"Got failure from weston-launch: %s", strerror (-reply.ret));
|
||||
|
||||
for (i = 0; in_all_cmsg && in_all_cmsg[i]; i++)
|
||||
g_object_unref (in_all_cmsg[i]);
|
||||
g_free (in_all_cmsg);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (in_all_cmsg && in_all_cmsg[0])
|
||||
{
|
||||
for (i = 1; in_all_cmsg[i]; i++)
|
||||
g_object_unref (in_all_cmsg[i]);
|
||||
*in_cmsg = in_all_cmsg[0];
|
||||
}
|
||||
|
||||
g_free (in_all_cmsg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
meta_launcher_open_device (MetaLauncher *self,
|
||||
const char *name,
|
||||
int flags,
|
||||
GError **error)
|
||||
{
|
||||
struct weston_launcher_open *message;
|
||||
GSocketControlMessage *cmsg;
|
||||
gboolean ok;
|
||||
gsize size;
|
||||
int *fds, n_fd;
|
||||
int ret;
|
||||
|
||||
size = sizeof (struct weston_launcher_open) + strlen (name) + 1;
|
||||
message = g_malloc (size);
|
||||
message->header.opcode = WESTON_LAUNCHER_OPEN;
|
||||
message->flags = flags;
|
||||
strcpy (message->path, name);
|
||||
message->path[strlen(name)] = 0;
|
||||
|
||||
ok = send_message_to_wl (self, message, size, NULL, &cmsg, error);
|
||||
|
||||
if (ok)
|
||||
{
|
||||
g_assert (G_IS_UNIX_FD_MESSAGE (cmsg));
|
||||
|
||||
fds = g_unix_fd_message_steal_fds (G_UNIX_FD_MESSAGE (cmsg), &n_fd);
|
||||
g_assert (n_fd == 1);
|
||||
|
||||
ret = fds[0];
|
||||
g_free (fds);
|
||||
g_object_unref (cmsg);
|
||||
}
|
||||
else
|
||||
ret = -1;
|
||||
|
||||
g_free (message);
|
||||
return ret;
|
||||
return login1_seat_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
"org.freedesktop.login1",
|
||||
"/org/freedesktop/login1/seat/self",
|
||||
cancellable, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -206,17 +97,18 @@ session_unpause (void)
|
||||
cogl_kms_display_queue_modes_reset (cogl_display);
|
||||
|
||||
clutter_evdev_reclaim_devices ();
|
||||
clutter_egl_thaw_master_clock ();
|
||||
|
||||
{
|
||||
MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaCursorRenderer *renderer = meta_backend_get_cursor_renderer (backend);
|
||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||
|
||||
/* When we mode-switch back, we need to immediately queue a redraw
|
||||
* in case nothing else queued one for us, and force the cursor to
|
||||
* update. */
|
||||
|
||||
clutter_actor_queue_redraw (compositor->stage);
|
||||
clutter_actor_queue_redraw (stage);
|
||||
meta_cursor_renderer_native_force_update (META_CURSOR_RENDERER_NATIVE (renderer));
|
||||
}
|
||||
}
|
||||
@@ -225,6 +117,92 @@ static void
|
||||
session_pause (void)
|
||||
{
|
||||
clutter_evdev_release_devices ();
|
||||
clutter_egl_freeze_master_clock ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
take_device (Login1Session *session_proxy,
|
||||
int dev_major,
|
||||
int dev_minor,
|
||||
int *out_fd,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GVariant *fd_variant = NULL;
|
||||
int fd = -1;
|
||||
GUnixFDList *fd_list;
|
||||
|
||||
if (!login1_session_call_take_device_sync (session_proxy,
|
||||
dev_major,
|
||||
dev_minor,
|
||||
NULL,
|
||||
&fd_variant,
|
||||
NULL, /* paused */
|
||||
&fd_list,
|
||||
cancellable,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
fd = g_unix_fd_list_get (fd_list, g_variant_get_handle (fd_variant), error);
|
||||
if (fd == -1)
|
||||
goto out;
|
||||
|
||||
*out_fd = fd;
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
if (fd_variant)
|
||||
g_variant_unref (fd_variant);
|
||||
if (fd_list)
|
||||
g_object_unref (fd_list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_device_info_from_path (const char *path,
|
||||
int *out_major,
|
||||
int *out_minor)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
int r;
|
||||
struct stat st;
|
||||
|
||||
r = stat (path, &st);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
if (!S_ISCHR (st.st_mode))
|
||||
goto out;
|
||||
|
||||
*out_major = major (st.st_rdev);
|
||||
*out_minor = minor (st.st_rdev);
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_device_info_from_fd (int fd,
|
||||
int *out_major,
|
||||
int *out_minor)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
int r;
|
||||
struct stat st;
|
||||
|
||||
r = fstat (fd, &st);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
if (!S_ISCHR (st.st_mode))
|
||||
goto out;
|
||||
|
||||
*out_major = major (st.st_rdev);
|
||||
*out_minor = minor (st.st_rdev);
|
||||
ret = TRUE;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -233,169 +211,151 @@ on_evdev_device_open (const char *path,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
MetaLauncher *launcher = user_data;
|
||||
MetaLauncher *self = user_data;
|
||||
int fd;
|
||||
int major, minor;
|
||||
|
||||
return meta_launcher_open_device (launcher, path, flags, error);
|
||||
if (!get_device_info_from_path (path, &major, &minor))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_NOT_FOUND,
|
||||
"Could not get device info for path %s: %m", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!take_device (self->session_proxy, major, minor, &fd, NULL, error))
|
||||
return -1;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void
|
||||
on_evdev_device_close (int fd,
|
||||
gpointer user_data)
|
||||
{
|
||||
close (fd);
|
||||
MetaLauncher *self = user_data;
|
||||
int major, minor;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!get_device_info_from_fd (fd, &major, &minor))
|
||||
{
|
||||
g_warning ("Could not get device info for fd %d: %m", fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!login1_session_call_release_device_sync (self->session_proxy,
|
||||
major, minor,
|
||||
NULL, &error))
|
||||
{
|
||||
g_warning ("Could not release device %d,%d: %s", major, minor, error->message);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_vt_enter (MetaLauncher *launcher)
|
||||
sync_active (MetaLauncher *self)
|
||||
{
|
||||
g_assert (launcher->vt_switched);
|
||||
|
||||
g_main_loop_quit (launcher->nested_loop);
|
||||
|
||||
session_unpause ();
|
||||
}
|
||||
|
||||
static void
|
||||
handle_request_vt_switch (MetaLauncher *launcher)
|
||||
{
|
||||
struct weston_launcher_message message;
|
||||
GError *error;
|
||||
gboolean ok;
|
||||
|
||||
session_pause ();
|
||||
|
||||
message.opcode = WESTON_LAUNCHER_CONFIRM_VT_SWITCH;
|
||||
|
||||
error = NULL;
|
||||
ok = send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, &error);
|
||||
if (!ok) {
|
||||
g_warning ("Failed to acknowledge VT switch: %s", error->message);
|
||||
g_error_free (error);
|
||||
gboolean active = login1_session_get_active (LOGIN1_SESSION (self->session_proxy));
|
||||
|
||||
if (active == self->session_active)
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert (!launcher->vt_switched);
|
||||
launcher->vt_switched = TRUE;
|
||||
self->session_active = active;
|
||||
|
||||
/* We can't do anything at this point, because we don't
|
||||
have input devices and we don't have the DRM master,
|
||||
so let's run a nested busy loop until the VT is reentered */
|
||||
g_main_loop_run (launcher->nested_loop);
|
||||
if (active)
|
||||
session_unpause ();
|
||||
else
|
||||
session_pause ();
|
||||
}
|
||||
|
||||
g_assert (launcher->vt_switched);
|
||||
launcher->vt_switched = FALSE;
|
||||
|
||||
session_unpause ();
|
||||
static void
|
||||
on_active_changed (Login1Session *session,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaLauncher *self = user_data;
|
||||
sync_active (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_socket_readable (GSocket *socket,
|
||||
GIOCondition condition,
|
||||
gpointer user_data)
|
||||
get_kms_fd (Login1Session *session_proxy,
|
||||
int *fd_out)
|
||||
{
|
||||
MetaLauncher *launcher = user_data;
|
||||
struct weston_launcher_event event;
|
||||
gssize read;
|
||||
GError *error;
|
||||
int major, minor;
|
||||
int fd;
|
||||
GError *error = NULL;
|
||||
|
||||
if ((condition & G_IO_IN) == 0)
|
||||
return TRUE;
|
||||
|
||||
error = NULL;
|
||||
read = g_socket_receive (socket, (char*)&event, sizeof(event), NULL, &error);
|
||||
if (read < (gssize)sizeof(event))
|
||||
/* XXX -- use udev to find the DRM master device */
|
||||
if (!get_device_info_from_path ("/dev/dri/card0", &major, &minor))
|
||||
{
|
||||
g_warning ("Error reading from weston-launcher socket: %s", error->message);
|
||||
g_warning ("Could not stat /dev/dri/card0: %m");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!take_device (session_proxy, major, minor, &fd, NULL, &error))
|
||||
{
|
||||
g_warning ("Could not open DRM device: %s\n", error->message);
|
||||
g_error_free (error);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (event.header.opcode)
|
||||
{
|
||||
case WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH:
|
||||
handle_request_vt_switch (launcher);
|
||||
break;
|
||||
|
||||
case WESTON_LAUNCHER_SERVER_VT_ENTER:
|
||||
handle_vt_enter (launcher);
|
||||
break;
|
||||
}
|
||||
*fd_out = fd;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
env_get_fd (const char *env)
|
||||
{
|
||||
const char *value;
|
||||
|
||||
value = g_getenv (env);
|
||||
|
||||
if (value == NULL)
|
||||
return -1;
|
||||
else
|
||||
return g_ascii_strtoll (value, NULL, 10);
|
||||
}
|
||||
|
||||
MetaLauncher *
|
||||
meta_launcher_new (void)
|
||||
{
|
||||
MetaLauncher *self = g_slice_new0 (MetaLauncher);
|
||||
MetaLauncher *self;
|
||||
Login1Session *session_proxy;
|
||||
GError *error = NULL;
|
||||
int launch_fd;
|
||||
int kms_fd;
|
||||
|
||||
launch_fd = env_get_fd ("WESTON_LAUNCHER_SOCK");
|
||||
if (launch_fd < 0)
|
||||
g_error ("Invalid mutter-launch socket");
|
||||
session_proxy = get_session_proxy (NULL);
|
||||
if (!login1_session_call_take_control_sync (session_proxy, FALSE, NULL, &error))
|
||||
{
|
||||
g_warning ("Could not take control: %s", error->message);
|
||||
g_error_free (error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->weston_launch = g_socket_new_from_fd (launch_fd, NULL);
|
||||
if (!get_kms_fd (session_proxy, &kms_fd))
|
||||
return NULL;
|
||||
|
||||
self->nested_context = g_main_context_new ();
|
||||
self->nested_loop = g_main_loop_new (self->nested_context, FALSE);
|
||||
self = g_slice_new0 (MetaLauncher);
|
||||
self->session_proxy = session_proxy;
|
||||
self->seat_proxy = get_seat_proxy (NULL);
|
||||
|
||||
self->outer_source = g_socket_create_source (self->weston_launch, G_IO_IN, NULL);
|
||||
g_source_set_callback (self->outer_source, (GSourceFunc)on_socket_readable, self, NULL);
|
||||
g_source_attach (self->outer_source, NULL);
|
||||
g_source_unref (self->outer_source);
|
||||
|
||||
self->inner_source = g_socket_create_source (self->weston_launch, G_IO_IN, NULL);
|
||||
g_source_set_callback (self->inner_source, (GSourceFunc)on_socket_readable, self, NULL);
|
||||
g_source_attach (self->inner_source, self->nested_context);
|
||||
g_source_unref (self->inner_source);
|
||||
|
||||
kms_fd = meta_launcher_open_device (self, "/dev/dri/card0", O_RDWR, &error);
|
||||
if (error)
|
||||
g_error ("Failed to open /dev/dri/card0: %s", error->message);
|
||||
self->session_active = TRUE;
|
||||
|
||||
clutter_egl_set_kms_fd (kms_fd);
|
||||
clutter_evdev_set_device_callbacks (on_evdev_device_open,
|
||||
on_evdev_device_close,
|
||||
self);
|
||||
|
||||
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
meta_launcher_free (MetaLauncher *launcher)
|
||||
meta_launcher_free (MetaLauncher *self)
|
||||
{
|
||||
g_source_destroy (launcher->outer_source);
|
||||
g_source_destroy (launcher->inner_source);
|
||||
|
||||
g_main_loop_unref (launcher->nested_loop);
|
||||
g_main_context_unref (launcher->nested_context);
|
||||
|
||||
g_object_unref (launcher->weston_launch);
|
||||
|
||||
g_slice_free (MetaLauncher, launcher);
|
||||
g_object_unref (self->seat_proxy);
|
||||
g_object_unref (self->session_proxy);
|
||||
g_slice_free (MetaLauncher, self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_launcher_activate_session (MetaLauncher *launcher,
|
||||
GError **error)
|
||||
{
|
||||
return meta_launcher_activate_vt (launcher, -1, error);
|
||||
if (!login1_session_call_activate_sync (launcher->session_proxy, NULL, error))
|
||||
return FALSE;
|
||||
|
||||
sync_active (launcher);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -403,10 +363,5 @@ meta_launcher_activate_vt (MetaLauncher *launcher,
|
||||
signed char vt,
|
||||
GError **error)
|
||||
{
|
||||
struct weston_launcher_activate_vt message;
|
||||
|
||||
message.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
|
||||
message.vt = vt;
|
||||
|
||||
return send_message_to_wl (launcher, &message, sizeof (message), NULL, NULL, error);
|
||||
return login1_seat_call_switch_to_sync (launcher->seat_proxy, vt, NULL, error);
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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
|
||||
@@ -40,8 +40,6 @@
|
||||
#include <meta/errors.h>
|
||||
#include "edid.h"
|
||||
|
||||
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
|
||||
typedef struct {
|
||||
drmModeConnector *connector;
|
||||
|
||||
@@ -259,7 +257,7 @@ find_output_by_id (MetaOutput *outputs,
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
if (outputs[i].output_id == id)
|
||||
if (outputs[i].winsys_id == id)
|
||||
return &outputs[i];
|
||||
|
||||
return NULL;
|
||||
@@ -363,9 +361,9 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_crtc->rect.width = crtc->width;
|
||||
meta_crtc->rect.height = crtc->height;
|
||||
meta_crtc->is_dirty = FALSE;
|
||||
meta_crtc->transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
meta_crtc->transform = META_MONITOR_TRANSFORM_NORMAL;
|
||||
/* FIXME: implement! */
|
||||
meta_crtc->all_transforms = 1 << WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
meta_crtc->all_transforms = 1 << META_MONITOR_TRANSFORM_NORMAL;
|
||||
|
||||
if (crtc->mode_valid)
|
||||
{
|
||||
@@ -408,7 +406,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_output->driver_private = output_kms = g_slice_new0 (MetaOutputKms);
|
||||
meta_output->driver_notify = (GDestroyNotify)meta_output_destroy_notify;
|
||||
|
||||
meta_output->output_id = connector->connector_id;
|
||||
meta_output->winsys_id = connector->connector_id;
|
||||
meta_output->name = make_output_name (connector);
|
||||
meta_output->width_mm = connector->mmWidth;
|
||||
meta_output->height_mm = connector->mmHeight;
|
||||
@@ -491,7 +489,7 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
|
||||
meta_output->crtc = NULL;
|
||||
|
||||
old_output = find_output_by_id (old_outputs, n_old_outputs,
|
||||
meta_output->output_id);
|
||||
meta_output->winsys_id);
|
||||
if (old_output)
|
||||
{
|
||||
meta_output->is_primary = old_output->is_primary;
|
||||
@@ -667,7 +665,7 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
|
||||
if (output_kms->dpms_prop_id != 0)
|
||||
{
|
||||
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->output_id,
|
||||
int ok = drmModeConnectorSetProperty(manager_kms->fd, meta_output->winsys_id,
|
||||
output_kms->dpms_prop_id, state);
|
||||
|
||||
if (ok < 0)
|
||||
@@ -748,7 +746,7 @@ meta_monitor_manager_kms_apply_configuration (MetaMonitorManager *manager,
|
||||
{
|
||||
MetaOutput *output = g_ptr_array_index (crtc_info->outputs, j);
|
||||
|
||||
connectors[j] = output->output_id;
|
||||
connectors[j] = output->winsys_id;
|
||||
|
||||
output->is_dirty = TRUE;
|
||||
output->crtc = crtc;
|
||||
|
@@ -1,711 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Benjamin Franzke
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The copyright holders make
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <error.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/signalfd.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <termios.h>
|
||||
#include <linux/vt.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/kd.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include <systemd/sd-login.h>
|
||||
|
||||
#include "weston-launch.h"
|
||||
|
||||
#define MAX_ARGV_SIZE 256
|
||||
#define DRM_MAJOR 226
|
||||
|
||||
enum vt_state {
|
||||
VT_HAS_VT,
|
||||
VT_PENDING_CONFIRM,
|
||||
VT_NOT_HAVE_VT,
|
||||
};
|
||||
|
||||
struct weston_launch {
|
||||
int tty;
|
||||
int ttynr;
|
||||
int sock[2];
|
||||
struct passwd *pw;
|
||||
|
||||
int signalfd;
|
||||
|
||||
pid_t child;
|
||||
int verbose;
|
||||
|
||||
struct termios terminal_attributes;
|
||||
int kb_mode;
|
||||
enum vt_state vt_state;
|
||||
unsigned vt;
|
||||
|
||||
int drm_fd;
|
||||
};
|
||||
|
||||
union cmsg_data { unsigned char b[4]; int fd; };
|
||||
|
||||
static void quit (struct weston_launch *wl, int status);
|
||||
|
||||
static int
|
||||
weston_launch_allowed(struct weston_launch *wl)
|
||||
{
|
||||
char *session, *seat;
|
||||
int err;
|
||||
|
||||
if (getuid() == 0)
|
||||
return 1;
|
||||
|
||||
err = sd_pid_get_session(getpid(), &session);
|
||||
if (err == 0 && session) {
|
||||
if (sd_session_is_active(session) &&
|
||||
sd_session_get_seat(session, &seat) == 0) {
|
||||
free(seat);
|
||||
free(session);
|
||||
return 1;
|
||||
}
|
||||
free(session);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
setup_launcher_socket(struct weston_launch *wl)
|
||||
{
|
||||
if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, wl->sock) < 0)
|
||||
error(1, errno, "socketpair failed");
|
||||
|
||||
fcntl(wl->sock[0], F_SETFD, O_CLOEXEC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
setup_signals(struct weston_launch *wl)
|
||||
{
|
||||
int ret;
|
||||
sigset_t mask;
|
||||
struct sigaction sa;
|
||||
|
||||
memset(&sa, 0, sizeof sa);
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
|
||||
ret = sigaction(SIGCHLD, &sa, NULL);
|
||||
assert(ret == 0);
|
||||
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
|
||||
ret = sigemptyset(&mask);
|
||||
assert(ret == 0);
|
||||
sigaddset(&mask, SIGCHLD);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGTERM);
|
||||
sigaddset(&mask, SIGUSR1);
|
||||
ret = sigprocmask(SIG_BLOCK, &mask, NULL);
|
||||
assert(ret == 0);
|
||||
|
||||
wl->signalfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC);
|
||||
if (wl->signalfd < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
setenv_fd(const char *env, int fd)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
snprintf(buf, sizeof buf, "%d", fd);
|
||||
setenv(env, buf, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
handle_confirm_vt_switch(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
|
||||
reply.header.opcode = WESTON_LAUNCHER_CONFIRM_VT_SWITCH;
|
||||
reply.ret = -1;
|
||||
|
||||
if (wl->vt_state != VT_PENDING_CONFIRM) {
|
||||
error(0, 0, "unexpected CONFIRM_VT_SWITCH");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (wl->drm_fd != -1) {
|
||||
int ret;
|
||||
|
||||
ret = drmDropMaster(wl->drm_fd);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to drop DRM master: %m\n");
|
||||
} else if (wl->verbose) {
|
||||
fprintf(stderr, "dropped DRM master for VT switch\n");
|
||||
}
|
||||
}
|
||||
|
||||
wl->vt_state = VT_NOT_HAVE_VT;
|
||||
ioctl(wl->tty, VT_RELDISP, 1);
|
||||
|
||||
if (wl->verbose)
|
||||
fprintf(stderr, "mutter-launcher: confirmed VT switch\n");
|
||||
|
||||
reply.ret = 0;
|
||||
|
||||
out:
|
||||
do {
|
||||
len = send(wl->sock[0], &reply, sizeof reply, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_activate_vt(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
struct weston_launcher_activate_vt *message;
|
||||
unsigned vt;
|
||||
|
||||
reply.header.opcode = WESTON_LAUNCHER_ACTIVATE_VT;
|
||||
reply.ret = -1;
|
||||
|
||||
if (len != sizeof(*message)) {
|
||||
error(0, 0, "missing value in activate_vt request");
|
||||
goto out;
|
||||
}
|
||||
|
||||
message = msg->msg_iov->iov_base;
|
||||
|
||||
/* Negative values mean that we're activating our own VT */
|
||||
if (message->vt > 0)
|
||||
vt = message->vt;
|
||||
else
|
||||
vt = wl->vt;
|
||||
|
||||
reply.ret = ioctl(wl->tty, VT_ACTIVATE, vt);
|
||||
if (reply.ret < 0)
|
||||
reply.ret = -errno;
|
||||
|
||||
if (wl->verbose)
|
||||
fprintf(stderr, "mutter-launch: activate VT, ret: %d\n", reply.ret);
|
||||
|
||||
out:
|
||||
do {
|
||||
len = send(wl->sock[0], &reply, sizeof reply, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
handle_open(struct weston_launch *wl, struct msghdr *msg, ssize_t len)
|
||||
{
|
||||
struct weston_launcher_reply reply;
|
||||
int fd = -1;
|
||||
char control[CMSG_SPACE(sizeof(fd))];
|
||||
struct cmsghdr *cmsg;
|
||||
struct stat s;
|
||||
struct msghdr nmsg;
|
||||
struct iovec iov;
|
||||
struct weston_launcher_open *message;
|
||||
union cmsg_data *data;
|
||||
int dev_major;
|
||||
|
||||
reply.header.opcode = WESTON_LAUNCHER_OPEN;
|
||||
reply.ret = -1;
|
||||
|
||||
message = msg->msg_iov->iov_base;
|
||||
if ((size_t)len < sizeof(*message))
|
||||
goto err0;
|
||||
|
||||
/* Ensure path is null-terminated */
|
||||
((char *) message)[len-1] = '\0';
|
||||
|
||||
if (stat(message->path, &s) < 0) {
|
||||
reply.ret = -errno;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
dev_major = major(s.st_rdev);
|
||||
|
||||
if (dev_major != INPUT_MAJOR &&
|
||||
dev_major != DRM_MAJOR) {
|
||||
fprintf(stderr, "Device %s is not an input or DRM device\n",
|
||||
message->path);
|
||||
reply.ret = -EPERM;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (dev_major == DRM_MAJOR && wl->drm_fd != -1) {
|
||||
fprintf(stderr, "Already have a DRM device open\n");
|
||||
reply.ret = -EPERM;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
fd = open(message->path, message->flags);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error opening device %s: %m\n",
|
||||
message->path);
|
||||
reply.ret = -errno;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
if (dev_major == DRM_MAJOR) {
|
||||
wl->drm_fd = fd;
|
||||
}
|
||||
|
||||
err0:
|
||||
memset(&nmsg, 0, sizeof nmsg);
|
||||
nmsg.msg_iov = &iov;
|
||||
nmsg.msg_iovlen = 1;
|
||||
if (fd != -1) {
|
||||
nmsg.msg_control = control;
|
||||
nmsg.msg_controllen = sizeof control;
|
||||
cmsg = CMSG_FIRSTHDR(&nmsg);
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
|
||||
data = (union cmsg_data *) CMSG_DATA(cmsg);
|
||||
data->fd = fd;
|
||||
nmsg.msg_controllen = cmsg->cmsg_len;
|
||||
reply.ret = 0;
|
||||
}
|
||||
iov.iov_base = &reply;
|
||||
iov.iov_len = sizeof reply;
|
||||
|
||||
if (wl->verbose)
|
||||
fprintf(stderr, "mutter-launch: opened %s: ret: %d, fd: %d\n",
|
||||
message->path, reply.ret, fd);
|
||||
do {
|
||||
len = sendmsg(wl->sock[0], &nmsg, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
|
||||
close(fd);
|
||||
|
||||
if (len < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
handle_socket_msg(struct weston_launch *wl)
|
||||
{
|
||||
char control[CMSG_SPACE(sizeof(int))];
|
||||
char buf[BUFSIZ];
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
int ret = -1;
|
||||
ssize_t len;
|
||||
struct weston_launcher_message *message;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = sizeof buf;
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = control;
|
||||
msg.msg_controllen = sizeof control;
|
||||
|
||||
do {
|
||||
len = recvmsg(wl->sock[0], &msg, 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
|
||||
if (len < 1)
|
||||
return -1;
|
||||
|
||||
message = (void *) buf;
|
||||
switch (message->opcode) {
|
||||
case WESTON_LAUNCHER_OPEN:
|
||||
ret = handle_open(wl, &msg, len);
|
||||
break;
|
||||
case WESTON_LAUNCHER_CONFIRM_VT_SWITCH:
|
||||
ret = handle_confirm_vt_switch(wl, &msg, len);
|
||||
break;
|
||||
case WESTON_LAUNCHER_ACTIVATE_VT:
|
||||
ret = handle_activate_vt(wl, &msg, len);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
tty_reset(struct weston_launch *wl)
|
||||
{
|
||||
struct vt_mode mode = { 0 };
|
||||
|
||||
if (ioctl(wl->tty, KDSKBMODE, wl->kb_mode))
|
||||
fprintf(stderr, "failed to restore keyboard mode: %m\n");
|
||||
|
||||
if (ioctl(wl->tty, KDSETMODE, KD_TEXT))
|
||||
fprintf(stderr, "failed to set KD_TEXT mode on tty: %m\n");
|
||||
|
||||
if (tcsetattr(wl->tty, TCSANOW, &wl->terminal_attributes) < 0)
|
||||
fprintf(stderr, "could not restore terminal to canonical mode\n");
|
||||
|
||||
mode.mode = VT_AUTO;
|
||||
if (ioctl(wl->tty, VT_SETMODE, &mode) < 0)
|
||||
fprintf(stderr, "could not reset vt handling\n");
|
||||
}
|
||||
|
||||
static void
|
||||
quit(struct weston_launch *wl, int status)
|
||||
{
|
||||
if (wl->child > 0)
|
||||
kill(wl->child, SIGKILL);
|
||||
|
||||
close(wl->signalfd);
|
||||
close(wl->sock[0]);
|
||||
|
||||
if (wl->drm_fd > 0)
|
||||
close(wl->drm_fd);
|
||||
|
||||
tty_reset(wl);
|
||||
|
||||
exit(status);
|
||||
}
|
||||
|
||||
static int
|
||||
handle_vt_switch(struct weston_launch *wl)
|
||||
{
|
||||
struct weston_launcher_event message;
|
||||
ssize_t len;
|
||||
|
||||
if (wl->vt_state == VT_HAS_VT) {
|
||||
wl->vt_state = VT_PENDING_CONFIRM;
|
||||
message.header.opcode = WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH;
|
||||
} else if (wl->vt_state == VT_NOT_HAVE_VT) {
|
||||
wl->vt_state = VT_HAS_VT;
|
||||
ioctl(wl->tty, VT_RELDISP, VT_ACKACQ);
|
||||
|
||||
if (wl->drm_fd != -1) {
|
||||
int ret;
|
||||
|
||||
ret = drmSetMaster(wl->drm_fd);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "failed to become DRM master: %m\n");
|
||||
/* This is very, very bad, and the compositor will crash soon,
|
||||
but oh well... */
|
||||
} else if (wl->verbose) {
|
||||
fprintf(stderr, "became DRM master after VT switch\n");
|
||||
}
|
||||
}
|
||||
|
||||
message.header.opcode = WESTON_LAUNCHER_SERVER_VT_ENTER;
|
||||
} else
|
||||
return -1;
|
||||
|
||||
message.detail = 0;
|
||||
|
||||
do {
|
||||
len = send(wl->sock[0], &message, sizeof(message), 0);
|
||||
} while (len < 0 && errno == EINTR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
handle_signal(struct weston_launch *wl)
|
||||
{
|
||||
struct signalfd_siginfo sig;
|
||||
int pid, status, ret;
|
||||
|
||||
if (read(wl->signalfd, &sig, sizeof sig) != sizeof sig) {
|
||||
error(0, errno, "reading signalfd failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (sig.ssi_signo) {
|
||||
case SIGCHLD:
|
||||
pid = waitpid(-1, &status, 0);
|
||||
if (pid == wl->child) {
|
||||
wl->child = 0;
|
||||
if (WIFEXITED(status))
|
||||
ret = WEXITSTATUS(status);
|
||||
else if (WIFSIGNALED(status))
|
||||
/*
|
||||
* If weston dies because of signal N, we
|
||||
* return 10+N. This is distinct from
|
||||
* weston-launch dying because of a signal
|
||||
* (128+N).
|
||||
*/
|
||||
ret = 10 + WTERMSIG(status);
|
||||
else
|
||||
ret = 0;
|
||||
quit(wl, ret);
|
||||
}
|
||||
break;
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
if (wl->child)
|
||||
kill(wl->child, sig.ssi_signo);
|
||||
break;
|
||||
case SIGUSR1:
|
||||
return handle_vt_switch(wl);
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
setup_tty(struct weston_launch *wl)
|
||||
{
|
||||
struct stat buf;
|
||||
struct termios raw_attributes;
|
||||
struct vt_mode mode = { 0 };
|
||||
char *session;
|
||||
char path[PATH_MAX];
|
||||
int ok;
|
||||
|
||||
ok = sd_pid_get_session(getpid(), &session);
|
||||
if (ok < 0)
|
||||
error(1, -ok, "could not determine current session");
|
||||
|
||||
ok = sd_session_get_vt(session, &wl->vt);
|
||||
if (ok < 0)
|
||||
error(1, -ok, "could not determine current TTY");
|
||||
|
||||
snprintf(path, PATH_MAX, "/dev/tty%u", wl->vt);
|
||||
wl->tty = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
|
||||
|
||||
if (wl->tty < 0)
|
||||
error(1, errno, "failed to open tty");
|
||||
|
||||
if (fstat(wl->tty, &buf) < 0)
|
||||
error(1, errno, "stat %s failed", path);
|
||||
|
||||
if (major(buf.st_rdev) != TTY_MAJOR)
|
||||
error(1, 0, "invalid tty device: %s", path);
|
||||
|
||||
wl->ttynr = minor(buf.st_rdev);
|
||||
|
||||
if (tcgetattr(wl->tty, &wl->terminal_attributes) < 0)
|
||||
error(1, errno, "could not get terminal attributes");
|
||||
|
||||
/* Ignore control characters and disable echo */
|
||||
raw_attributes = wl->terminal_attributes;
|
||||
cfmakeraw(&raw_attributes);
|
||||
|
||||
/* Fix up line endings to be normal (cfmakeraw hoses them) */
|
||||
raw_attributes.c_oflag |= OPOST | OCRNL;
|
||||
/* Don't generate ttou signals */
|
||||
raw_attributes.c_oflag &= ~TOSTOP;
|
||||
|
||||
if (tcsetattr(wl->tty, TCSANOW, &raw_attributes) < 0)
|
||||
error(1, errno, "could not put terminal into raw mode");
|
||||
|
||||
ioctl(wl->tty, KDGKBMODE, &wl->kb_mode);
|
||||
ok = ioctl(wl->tty, KDSKBMODE, K_OFF);
|
||||
if (ok < 0) {
|
||||
ok = ioctl(wl->tty, KDSKBMODE, K_RAW);
|
||||
if (ok < 0)
|
||||
error(1, errno, "failed to set keyboard mode on tty");
|
||||
}
|
||||
|
||||
ok = ioctl(wl->tty, KDSETMODE, KD_GRAPHICS);
|
||||
if (ok < 0)
|
||||
error(1, errno, "failed to set KD_GRAPHICS mode on tty");
|
||||
|
||||
wl->vt_state = VT_HAS_VT;
|
||||
mode.mode = VT_PROCESS;
|
||||
mode.relsig = SIGUSR1;
|
||||
mode.acqsig = SIGUSR1;
|
||||
ok = ioctl(wl->tty, VT_SETMODE, &mode);
|
||||
if (ok < 0)
|
||||
error(1, errno, "failed to take control of vt handling");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
drop_privileges(struct weston_launch *wl)
|
||||
{
|
||||
if (setgid(wl->pw->pw_gid) < 0 ||
|
||||
#ifdef HAVE_INITGROUPS
|
||||
initgroups(wl->pw->pw_name, wl->pw->pw_gid) < 0 ||
|
||||
#endif
|
||||
setuid(wl->pw->pw_uid) < 0)
|
||||
error(1, errno, "dropping privileges failed");
|
||||
}
|
||||
|
||||
static void
|
||||
launch_compositor(struct weston_launch *wl, int argc, char *argv[])
|
||||
{
|
||||
char command[PATH_MAX];
|
||||
char *child_argv[MAX_ARGV_SIZE];
|
||||
sigset_t mask;
|
||||
int i;
|
||||
|
||||
if (wl->verbose)
|
||||
printf("weston-launch: spawned weston with pid: %d\n", getpid());
|
||||
|
||||
drop_privileges(wl);
|
||||
|
||||
setenv_fd("WESTON_LAUNCHER_SOCK", wl->sock[1]);
|
||||
setenv("LD_LIBRARY_PATH", LIBDIR, 1);
|
||||
unsetenv("DISPLAY");
|
||||
|
||||
/* Do not give our signal mask to the new process. */
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGTERM);
|
||||
sigaddset(&mask, SIGCHLD);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGUSR1);
|
||||
sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
||||
|
||||
snprintf (command, PATH_MAX, "%s \"$@\"", argv[0]);
|
||||
|
||||
child_argv[0] = wl->pw->pw_shell;
|
||||
child_argv[1] = "-l";
|
||||
child_argv[2] = "-c";
|
||||
child_argv[3] = command;
|
||||
for (i = 0; i < argc; ++i)
|
||||
child_argv[4 + i] = argv[i];
|
||||
child_argv[4 + i] = NULL;
|
||||
|
||||
execv(child_argv[0], child_argv);
|
||||
error(1, errno, "exec failed");
|
||||
}
|
||||
|
||||
static void
|
||||
help(const char *name)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [args...] [-- [weston args..]]\n", name);
|
||||
fprintf(stderr, " -u, --user Start session as specified username\n");
|
||||
fprintf(stderr, " -v, --verbose Be verbose\n");
|
||||
fprintf(stderr, " -h, --help Display this help message\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct weston_launch wl;
|
||||
int i, c;
|
||||
struct option opts[] = {
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ 0, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
memset(&wl, 0, sizeof wl);
|
||||
wl.drm_fd = -1;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "u:t::vh", opts, &i)) != -1) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
wl.verbose = 1;
|
||||
break;
|
||||
case 'h':
|
||||
help("mutter-launch");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((argc - optind) > (MAX_ARGV_SIZE - 6))
|
||||
error(1, E2BIG, "Too many arguments to pass to weston");
|
||||
|
||||
if (optind >= argc)
|
||||
error(1, 0, "Expected program argument");
|
||||
|
||||
wl.pw = getpwuid(getuid());
|
||||
if (wl.pw == NULL)
|
||||
error(1, errno, "failed to get username");
|
||||
|
||||
if (!weston_launch_allowed(&wl))
|
||||
error(1, 0, "Permission denied. You must run from an active and local (systemd) session.");
|
||||
|
||||
if (setup_tty(&wl) < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
if (setup_launcher_socket(&wl) < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
if (setup_signals(&wl) < 0)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
wl.child = fork();
|
||||
if (wl.child == -1) {
|
||||
error(1, errno, "fork failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (wl.child == 0)
|
||||
launch_compositor(&wl, argc - optind, argv + optind);
|
||||
|
||||
close(wl.sock[1]);
|
||||
|
||||
while (1) {
|
||||
struct pollfd fds[2];
|
||||
int n;
|
||||
|
||||
fds[0].fd = wl.sock[0];
|
||||
fds[0].events = POLLIN;
|
||||
fds[1].fd = wl.signalfd;
|
||||
fds[1].events = POLLIN;
|
||||
|
||||
n = poll(fds, 2, -1);
|
||||
if (n < 0)
|
||||
error(0, errno, "poll failed");
|
||||
if (fds[0].revents & POLLIN)
|
||||
handle_socket_msg(&wl);
|
||||
if (fds[1].revents)
|
||||
handle_signal(&wl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2012 Benjamin Franzke
|
||||
* 2013 Red Hat, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software and
|
||||
* its documentation for any purpose is hereby granted without fee, provided
|
||||
* that the above copyright notice appear in all copies and that both that
|
||||
* copyright notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of the copyright holders not be used in
|
||||
* advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. The copyright holders make
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _WESTON_LAUNCH_H_
|
||||
#define _WESTON_LAUNCH_H_
|
||||
|
||||
enum weston_launcher_message_type {
|
||||
WESTON_LAUNCHER_REQUEST,
|
||||
WESTON_LAUNCHER_EVENT,
|
||||
};
|
||||
|
||||
enum weston_launcher_opcode {
|
||||
WESTON_LAUNCHER_OPEN = (1 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_ACTIVATE_VT = (2 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
WESTON_LAUNCHER_CONFIRM_VT_SWITCH = (3 << 1 | WESTON_LAUNCHER_REQUEST),
|
||||
};
|
||||
|
||||
enum weston_launcher_server_opcode {
|
||||
WESTON_LAUNCHER_SERVER_REQUEST_VT_SWITCH = (1 << 1 | WESTON_LAUNCHER_EVENT),
|
||||
WESTON_LAUNCHER_SERVER_VT_ENTER = (2 << 1 | WESTON_LAUNCHER_EVENT),
|
||||
};
|
||||
|
||||
struct weston_launcher_message {
|
||||
int opcode;
|
||||
};
|
||||
|
||||
struct weston_launcher_open {
|
||||
struct weston_launcher_message header;
|
||||
int flags;
|
||||
char path[0];
|
||||
};
|
||||
|
||||
struct weston_launcher_activate_vt {
|
||||
struct weston_launcher_message header;
|
||||
signed char vt;
|
||||
};
|
||||
|
||||
struct weston_launcher_reply {
|
||||
struct weston_launcher_message header;
|
||||
int ret;
|
||||
};
|
||||
|
||||
struct weston_launcher_event {
|
||||
struct weston_launcher_message header;
|
||||
int detail; /* unused, but makes sure replies and events are serialized the same */
|
||||
};
|
||||
|
||||
#endif
|
@@ -24,18 +24,24 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
|
||||
#include <X11/extensions/sync.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/XKBrules.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <xkbcommon/xkbcommon-x11.h>
|
||||
|
||||
#include "meta-idle-monitor-xsync.h"
|
||||
#include "meta-monitor-manager-xrandr.h"
|
||||
#include "backends/meta-monitor-manager-dummy.h"
|
||||
#include "meta-cursor-renderer-x11.h"
|
||||
|
||||
#include "meta-cursor-tracker-private.h"
|
||||
#include "meta-cursor.h"
|
||||
#include <meta/util.h>
|
||||
#include "display-private.h"
|
||||
#include "compositor/compositor-private.h"
|
||||
@@ -44,6 +50,7 @@ struct _MetaBackendX11Private
|
||||
{
|
||||
/* The host X11 display */
|
||||
Display *xdisplay;
|
||||
xcb_connection_t *xcb;
|
||||
GSource *source;
|
||||
|
||||
int xsync_event_base;
|
||||
@@ -52,6 +59,12 @@ struct _MetaBackendX11Private
|
||||
int xinput_opcode;
|
||||
int xinput_event_base;
|
||||
int xinput_error_base;
|
||||
Time latest_evtime;
|
||||
|
||||
uint8_t xkb_event_base;
|
||||
uint8_t xkb_error_base;
|
||||
|
||||
struct xkb_keymap *keymap;
|
||||
};
|
||||
typedef struct _MetaBackendX11Private MetaBackendX11Private;
|
||||
|
||||
@@ -68,21 +81,12 @@ handle_alarm_notify (MetaBackend *backend,
|
||||
meta_idle_monitor_xsync_handle_xevent (backend->device_monitors[i], (XSyncAlarmNotifyEvent*) event);
|
||||
}
|
||||
|
||||
static Window
|
||||
get_stage_window (MetaBackendX11 *x11)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
ClutterStage *stage = CLUTTER_STAGE (compositor->stage);
|
||||
|
||||
return clutter_x11_get_stage_window (stage);
|
||||
}
|
||||
|
||||
static void
|
||||
translate_device_event (MetaBackendX11 *x11,
|
||||
XIDeviceEvent *device_event)
|
||||
{
|
||||
Window stage_window = get_stage_window (x11);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
Window stage_window = meta_backend_x11_get_xwindow (x11);
|
||||
|
||||
if (device_event->event != stage_window)
|
||||
{
|
||||
@@ -99,6 +103,21 @@ translate_device_event (MetaBackendX11 *x11,
|
||||
device_event->event_x = device_event->root_x;
|
||||
device_event->event_y = device_event->root_y;
|
||||
}
|
||||
|
||||
if (!device_event->send_event && device_event->time != CurrentTime)
|
||||
{
|
||||
if (device_event->time < priv->latest_evtime)
|
||||
{
|
||||
/* Emulated pointer events received after XIRejectTouch is received
|
||||
* on a passive touch grab will contain older timestamps, update those
|
||||
* so we dont get InvalidTime at grabs.
|
||||
*/
|
||||
device_event->time = priv->latest_evtime;
|
||||
}
|
||||
|
||||
/* Update the internal latest evtime, for any possible later use */
|
||||
priv->latest_evtime = device_event->time;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clutter makes the assumption that there is only one X window
|
||||
@@ -128,6 +147,9 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
|
||||
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:
|
||||
@@ -136,6 +158,21 @@ maybe_spoof_event_as_stage_event (MetaBackendX11 *x11,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
keymap_changed (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
if (priv->keymap)
|
||||
{
|
||||
xkb_keymap_unref (priv->keymap);
|
||||
priv->keymap = NULL;
|
||||
}
|
||||
|
||||
g_signal_emit_by_name (backend, "keymap-changed", 0);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_host_xevent (MetaBackend *backend,
|
||||
XEvent *event)
|
||||
@@ -146,24 +183,49 @@ handle_host_xevent (MetaBackend *backend,
|
||||
|
||||
XGetEventData (priv->xdisplay, &event->xcookie);
|
||||
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
|
||||
if (display)
|
||||
{
|
||||
MetaCompositor *compositor = display->compositor;
|
||||
if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
|
||||
bypass_clutter = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (event->type == (priv->xsync_event_base + XSyncAlarmNotify))
|
||||
handle_alarm_notify (backend, event);
|
||||
|
||||
if (event->type == priv->xkb_event_base)
|
||||
{
|
||||
XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event;
|
||||
|
||||
if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID)
|
||||
{
|
||||
switch (xkb_ev->xkb_type)
|
||||
{
|
||||
case XkbNewKeyboardNotify:
|
||||
case XkbMapNotify:
|
||||
keymap_changed (backend);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
|
||||
if (META_IS_MONITOR_MANAGER_XRANDR (manager) &&
|
||||
meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event))
|
||||
{
|
||||
bypass_clutter = TRUE;
|
||||
goto out;
|
||||
}
|
||||
bypass_clutter = TRUE;
|
||||
}
|
||||
|
||||
maybe_spoof_event_as_stage_event (x11, event);
|
||||
|
||||
out:
|
||||
if (!bypass_clutter)
|
||||
clutter_x11_handle_event (event);
|
||||
{
|
||||
maybe_spoof_event_as_stage_event (x11, event);
|
||||
clutter_x11_handle_event (event);
|
||||
}
|
||||
|
||||
XFreeEventData (priv->xdisplay, &event->xcookie);
|
||||
}
|
||||
@@ -246,6 +308,24 @@ x_event_source_new (MetaBackend *backend)
|
||||
return source;
|
||||
}
|
||||
|
||||
static void
|
||||
take_touch_grab (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits };
|
||||
XIGrabModifiers mods = { XIAnyModifier, 0 };
|
||||
|
||||
XISetMask (mask.mask, XI_TouchBegin);
|
||||
XISetMask (mask.mask, XI_TouchUpdate);
|
||||
XISetMask (mask.mask, XI_TouchEnd);
|
||||
|
||||
XIGrabTouchBegin (priv->xdisplay, META_VIRTUAL_CORE_POINTER_ID,
|
||||
DefaultRootWindow (priv->xdisplay),
|
||||
False, &mask, 1, &mods);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_post_init (MetaBackend *backend)
|
||||
{
|
||||
@@ -283,6 +363,19 @@ meta_backend_x11_post_init (MetaBackend *backend)
|
||||
meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
|
||||
}
|
||||
|
||||
take_touch_grab (backend);
|
||||
|
||||
priv->xcb = XGetXCBConnection (priv->xdisplay);
|
||||
if (!xkb_x11_setup_xkb_extension (priv->xcb,
|
||||
XKB_X11_MIN_MAJOR_XKB_VERSION,
|
||||
XKB_X11_MIN_MINOR_XKB_VERSION,
|
||||
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
|
||||
NULL, NULL,
|
||||
&priv->xkb_event_base,
|
||||
&priv->xkb_error_base))
|
||||
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);
|
||||
|
||||
META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
|
||||
}
|
||||
|
||||
@@ -307,6 +400,12 @@ meta_backend_x11_create_monitor_manager (MetaBackend *backend)
|
||||
return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
|
||||
}
|
||||
|
||||
static MetaCursorRenderer *
|
||||
meta_backend_x11_create_cursor_renderer (MetaBackend *backend)
|
||||
{
|
||||
return g_object_new (META_TYPE_CURSOR_RENDERER_X11, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_backend_x11_grab_device (MetaBackend *backend,
|
||||
int device_id,
|
||||
@@ -318,6 +417,9 @@ meta_backend_x11_grab_device (MetaBackend *backend,
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
int ret;
|
||||
|
||||
if (timestamp != CurrentTime)
|
||||
timestamp = MAX (timestamp, priv->latest_evtime);
|
||||
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
@@ -326,14 +428,10 @@ meta_backend_x11_grab_device (MetaBackend *backend,
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
XISetMask (mask.mask, XI_KeyRelease);
|
||||
|
||||
MetaCursorTracker *tracker = meta_cursor_tracker_get_for_screen (NULL);
|
||||
MetaCursorReference *cursor_ref = meta_cursor_tracker_get_displayed_cursor (tracker);
|
||||
MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref);
|
||||
|
||||
ret = XIGrabDevice (priv->xdisplay, device_id,
|
||||
get_stage_window (x11),
|
||||
meta_backend_x11_get_xwindow (x11),
|
||||
timestamp,
|
||||
meta_cursor_create_x_cursor (priv->xdisplay, cursor),
|
||||
None,
|
||||
XIGrabModeAsync, XIGrabModeAsync,
|
||||
False, /* owner_events */
|
||||
&mask);
|
||||
@@ -355,6 +453,214 @@ meta_backend_x11_ungrab_device (MetaBackend *backend,
|
||||
return (ret == Success);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_warp_pointer (MetaBackend *backend,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
XIWarpPointer (priv->xdisplay,
|
||||
META_VIRTUAL_CORE_POINTER_ID,
|
||||
None,
|
||||
meta_backend_x11_get_xwindow (x11),
|
||||
0, 0, 0, 0,
|
||||
x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
get_xkbrf_var_defs (Display *xdisplay,
|
||||
const char *layouts,
|
||||
const char *variants,
|
||||
const char *options,
|
||||
char **rules_p,
|
||||
XkbRF_VarDefsRec *var_defs)
|
||||
{
|
||||
char *rules = NULL;
|
||||
|
||||
/* Get it from the X property or fallback on defaults */
|
||||
if (!XkbRF_GetNamesProp (xdisplay, &rules, var_defs) || !rules)
|
||||
{
|
||||
rules = strdup (DEFAULT_XKB_RULES_FILE);
|
||||
var_defs->model = strdup (DEFAULT_XKB_MODEL);
|
||||
var_defs->layout = NULL;
|
||||
var_defs->variant = NULL;
|
||||
var_defs->options = NULL;
|
||||
}
|
||||
|
||||
/* Swap in our new options... */
|
||||
free (var_defs->layout);
|
||||
var_defs->layout = strdup (layouts);
|
||||
free (var_defs->variant);
|
||||
var_defs->variant = strdup (variants);
|
||||
free (var_defs->options);
|
||||
var_defs->options = strdup (options);
|
||||
|
||||
/* Sometimes, the property is a file path, and sometimes it's
|
||||
not. Normalize it so it's always a file path. */
|
||||
if (rules[0] == '/')
|
||||
*rules_p = g_strdup (rules);
|
||||
else
|
||||
*rules_p = g_build_filename (XKB_BASE, "rules", rules, NULL);
|
||||
|
||||
free (rules);
|
||||
}
|
||||
|
||||
static void
|
||||
free_xkbrf_var_defs (XkbRF_VarDefsRec *var_defs)
|
||||
{
|
||||
free (var_defs->model);
|
||||
free (var_defs->layout);
|
||||
free (var_defs->variant);
|
||||
free (var_defs->options);
|
||||
}
|
||||
|
||||
static void
|
||||
free_xkb_component_names (XkbComponentNamesRec *p)
|
||||
{
|
||||
free (p->keymap);
|
||||
free (p->keycodes);
|
||||
free (p->types);
|
||||
free (p->compat);
|
||||
free (p->symbols);
|
||||
free (p->geometry);
|
||||
}
|
||||
|
||||
static void
|
||||
upload_xkb_description (Display *xdisplay,
|
||||
const gchar *rules_file_path,
|
||||
XkbRF_VarDefsRec *var_defs,
|
||||
XkbComponentNamesRec *comp_names)
|
||||
{
|
||||
XkbDescRec *xkb_desc;
|
||||
gchar *rules_file;
|
||||
|
||||
/* Upload it to the X server using the same method as setxkbmap */
|
||||
xkb_desc = XkbGetKeyboardByName (xdisplay,
|
||||
XkbUseCoreKbd,
|
||||
comp_names,
|
||||
XkbGBN_AllComponentsMask,
|
||||
XkbGBN_AllComponentsMask &
|
||||
(~XkbGBN_GeometryMask), True);
|
||||
if (!xkb_desc)
|
||||
{
|
||||
g_warning ("Couldn't upload new XKB keyboard description");
|
||||
return;
|
||||
}
|
||||
|
||||
XkbFreeKeyboard (xkb_desc, 0, True);
|
||||
|
||||
rules_file = g_path_get_basename (rules_file_path);
|
||||
|
||||
if (!XkbRF_SetNamesProp (xdisplay, rules_file, var_defs))
|
||||
g_warning ("Couldn't update the XKB root window property");
|
||||
|
||||
g_free (rules_file);
|
||||
}
|
||||
|
||||
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);
|
||||
XkbRF_RulesRec *xkb_rules;
|
||||
XkbRF_VarDefsRec xkb_var_defs = { 0 };
|
||||
gchar *rules_file_path;
|
||||
|
||||
get_xkbrf_var_defs (priv->xdisplay,
|
||||
layouts,
|
||||
variants,
|
||||
options,
|
||||
&rules_file_path,
|
||||
&xkb_var_defs);
|
||||
|
||||
xkb_rules = XkbRF_Load (rules_file_path, NULL, True, True);
|
||||
if (xkb_rules)
|
||||
{
|
||||
XkbComponentNamesRec xkb_comp_names = { 0 };
|
||||
|
||||
XkbRF_GetComponents (xkb_rules, &xkb_var_defs, &xkb_comp_names);
|
||||
upload_xkb_description (priv->xdisplay, rules_file_path, &xkb_var_defs, &xkb_comp_names);
|
||||
|
||||
free_xkb_component_names (&xkb_comp_names);
|
||||
XkbRF_Free (xkb_rules, True);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_warning ("Couldn't load XKB rules");
|
||||
}
|
||||
|
||||
free_xkbrf_var_defs (&xkb_var_defs);
|
||||
g_free (rules_file_path);
|
||||
}
|
||||
|
||||
static struct xkb_keymap *
|
||||
meta_backend_x11_get_keymap (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
if (priv->keymap == NULL)
|
||||
{
|
||||
struct xkb_context *context = xkb_context_new (XKB_CONTEXT_NO_FLAGS);
|
||||
priv->keymap = xkb_x11_keymap_new_from_device (context,
|
||||
priv->xcb,
|
||||
xkb_x11_get_core_keyboard_device_id (priv->xcb),
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_context_unref (context);
|
||||
}
|
||||
|
||||
return priv->keymap;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_lock_layout_group (MetaBackend *backend,
|
||||
guint idx)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
|
||||
XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, idx);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_update_screen_size (MetaBackend *backend,
|
||||
int width, int height)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
Window xwin = meta_backend_x11_get_xwindow (x11);
|
||||
XResizeWindow (priv->xdisplay, xwin, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_select_stage_events (MetaBackend *backend)
|
||||
{
|
||||
MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
|
||||
MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
|
||||
Window xwin = meta_backend_x11_get_xwindow (x11);
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
XISetMask (mask.mask, XI_KeyRelease);
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
XISetMask (mask.mask, XI_FocusIn);
|
||||
XISetMask (mask.mask, XI_FocusOut);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
XIClearMask (mask.mask, XI_TouchBegin);
|
||||
XIClearMask (mask.mask, XI_TouchEnd);
|
||||
XIClearMask (mask.mask, XI_TouchUpdate);
|
||||
XISelectEvents (priv->xdisplay, xwin, &mask, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||
{
|
||||
@@ -363,9 +669,15 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
|
||||
backend_class->post_init = meta_backend_x11_post_init;
|
||||
backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor;
|
||||
backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager;
|
||||
|
||||
backend_class->create_cursor_renderer = meta_backend_x11_create_cursor_renderer;
|
||||
backend_class->grab_device = meta_backend_x11_grab_device;
|
||||
backend_class->ungrab_device = meta_backend_x11_ungrab_device;
|
||||
backend_class->warp_pointer = meta_backend_x11_warp_pointer;
|
||||
backend_class->set_keymap = meta_backend_x11_set_keymap;
|
||||
backend_class->get_keymap = meta_backend_x11_get_keymap;
|
||||
backend_class->lock_layout_group = meta_backend_x11_lock_layout_group;
|
||||
backend_class->update_screen_size = meta_backend_x11_update_screen_size;
|
||||
backend_class->select_stage_events = meta_backend_x11_select_stage_events;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -383,3 +695,9 @@ meta_backend_x11_get_xdisplay (MetaBackendX11 *x11)
|
||||
return priv->xdisplay;
|
||||
}
|
||||
|
||||
Window
|
||||
meta_backend_x11_get_xwindow (MetaBackendX11 *x11)
|
||||
{
|
||||
ClutterActor *stage = meta_backend_get_stage (META_BACKEND (x11));
|
||||
return clutter_x11_get_stage_window (CLUTTER_STAGE (stage));
|
||||
}
|
||||
|
@@ -53,4 +53,6 @@ GType meta_backend_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
Display * meta_backend_x11_get_xdisplay (MetaBackendX11 *backend);
|
||||
|
||||
Window meta_backend_x11_get_xwindow (MetaBackendX11 *backend);
|
||||
|
||||
#endif /* META_BACKEND_X11_H */
|
||||
|
99
src/backends/x11/meta-cursor-renderer-x11.c
Normal file
99
src/backends/x11/meta-cursor-renderer-x11.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/* -*- 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.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "meta-cursor-renderer-x11.h"
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
#include "meta-stage.h"
|
||||
|
||||
struct _MetaCursorRendererX11Private
|
||||
{
|
||||
gboolean server_cursor_visible;
|
||||
};
|
||||
typedef struct _MetaCursorRendererX11Private MetaCursorRendererX11Private;
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererX11, meta_cursor_renderer_x11, META_TYPE_CURSOR_RENDERER);
|
||||
|
||||
static gboolean
|
||||
meta_cursor_renderer_x11_update_cursor (MetaCursorRenderer *renderer)
|
||||
{
|
||||
MetaCursorRendererX11 *x11 = META_CURSOR_RENDERER_X11 (renderer);
|
||||
MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11);
|
||||
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Window xwindow = meta_backend_x11_get_xwindow (backend);
|
||||
|
||||
if (xwindow == None)
|
||||
return FALSE;
|
||||
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
|
||||
MetaCursorReference *cursor_ref = meta_cursor_renderer_get_cursor (renderer);
|
||||
gboolean has_server_cursor = FALSE;
|
||||
|
||||
if (cursor_ref)
|
||||
{
|
||||
MetaCursor cursor = meta_cursor_reference_get_meta_cursor (cursor_ref);
|
||||
if (cursor != META_CURSOR_NONE)
|
||||
{
|
||||
Cursor xcursor = meta_cursor_create_x_cursor (xdisplay, cursor);
|
||||
XDefineCursor (xdisplay, xwindow, xcursor);
|
||||
XFlush (xdisplay);
|
||||
XFreeCursor (xdisplay, xcursor);
|
||||
|
||||
has_server_cursor = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_server_cursor != priv->server_cursor_visible)
|
||||
{
|
||||
if (has_server_cursor)
|
||||
XFixesShowCursor (xdisplay, xwindow);
|
||||
else
|
||||
XFixesHideCursor (xdisplay, xwindow);
|
||||
|
||||
priv->server_cursor_visible = has_server_cursor;
|
||||
}
|
||||
|
||||
return priv->server_cursor_visible;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_x11_class_init (MetaCursorRendererX11Class *klass)
|
||||
{
|
||||
MetaCursorRendererClass *renderer_class = META_CURSOR_RENDERER_CLASS (klass);
|
||||
|
||||
renderer_class->update_cursor = meta_cursor_renderer_x11_update_cursor;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_cursor_renderer_x11_init (MetaCursorRendererX11 *x11)
|
||||
{
|
||||
MetaCursorRendererX11Private *priv = meta_cursor_renderer_x11_get_instance_private (x11);
|
||||
|
||||
/* XFixes has no way to retrieve the current cursor visibility. */
|
||||
priv->server_cursor_visible = TRUE;
|
||||
}
|
52
src/backends/x11/meta-cursor-renderer-x11.h
Normal file
52
src/backends/x11/meta-cursor-renderer-x11.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* -*- 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.
|
||||
*
|
||||
* Written by:
|
||||
* Jasper St. Pierre <jstpierre@mecheye.net>
|
||||
*/
|
||||
|
||||
#ifndef META_CURSOR_RENDERER_X11_H
|
||||
#define META_CURSOR_RENDERER_X11_H
|
||||
|
||||
#include "meta-cursor-renderer.h"
|
||||
|
||||
#define META_TYPE_CURSOR_RENDERER_X11 (meta_cursor_renderer_x11_get_type ())
|
||||
#define META_CURSOR_RENDERER_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11))
|
||||
#define META_CURSOR_RENDERER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class))
|
||||
#define META_IS_CURSOR_RENDERER_X11(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_CURSOR_RENDERER_X11))
|
||||
#define META_IS_CURSOR_RENDERER_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_CURSOR_RENDERER_X11))
|
||||
#define META_CURSOR_RENDERER_X11_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_CURSOR_RENDERER_X11, MetaCursorRendererX11Class))
|
||||
|
||||
typedef struct _MetaCursorRendererX11 MetaCursorRendererX11;
|
||||
typedef struct _MetaCursorRendererX11Class MetaCursorRendererX11Class;
|
||||
|
||||
struct _MetaCursorRendererX11
|
||||
{
|
||||
MetaCursorRenderer parent;
|
||||
};
|
||||
|
||||
struct _MetaCursorRendererX11Class
|
||||
{
|
||||
MetaCursorRendererClass parent_class;
|
||||
};
|
||||
|
||||
GType meta_cursor_renderer_x11_get_type (void) G_GNUC_CONST;
|
||||
|
||||
#endif /* META_CURSOR_RENDERER_X11_H */
|
@@ -1,6 +1,6 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||
* Copyright (C) 2002, 2003 Red Hat Inc.
|
||||
* Some ICCCM manager selection code derived from fvwm2,
|
||||
@@ -8,7 +8,7 @@
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
* Copyright (C) 2013 Red Hat Inc.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -18,7 +18,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -35,6 +35,8 @@
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/extensions/dpms.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <xcb/randr.h>
|
||||
|
||||
#include "meta-backend-x11.h"
|
||||
#include <meta/main.h>
|
||||
@@ -42,7 +44,7 @@
|
||||
#include "edid.h"
|
||||
#include "meta-monitor-config.h"
|
||||
|
||||
#define ALL_WL_TRANSFORMS ((1 << (WL_OUTPUT_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
#define ALL_TRANSFORMS ((1 << (META_MONITOR_TRANSFORM_FLIPPED_270 + 1)) - 1)
|
||||
|
||||
/* Look for DPI_FALLBACK in:
|
||||
* http://git.gnome.org/browse/gnome-settings-daemon/tree/plugins/xsettings/gsd-xsettings-manager.c
|
||||
@@ -67,31 +69,31 @@ struct _MetaMonitorManagerXrandrClass
|
||||
|
||||
G_DEFINE_TYPE (MetaMonitorManagerXrandr, meta_monitor_manager_xrandr, META_TYPE_MONITOR_MANAGER);
|
||||
|
||||
static enum wl_output_transform
|
||||
wl_transform_from_xrandr (Rotation rotation)
|
||||
static MetaMonitorTransform
|
||||
meta_monitor_transform_from_xrandr (Rotation rotation)
|
||||
{
|
||||
static const enum wl_output_transform y_reflected_map[4] = {
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED_180,
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED_90,
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED,
|
||||
WL_OUTPUT_TRANSFORM_FLIPPED_270
|
||||
static const MetaMonitorTransform y_reflected_map[4] = {
|
||||
META_MONITOR_TRANSFORM_FLIPPED_180,
|
||||
META_MONITOR_TRANSFORM_FLIPPED_90,
|
||||
META_MONITOR_TRANSFORM_FLIPPED,
|
||||
META_MONITOR_TRANSFORM_FLIPPED_270
|
||||
};
|
||||
enum wl_output_transform ret;
|
||||
MetaMonitorTransform ret;
|
||||
|
||||
switch (rotation & 0x7F)
|
||||
{
|
||||
default:
|
||||
case RR_Rotate_0:
|
||||
ret = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
ret = META_MONITOR_TRANSFORM_NORMAL;
|
||||
break;
|
||||
case RR_Rotate_90:
|
||||
ret = WL_OUTPUT_TRANSFORM_90;
|
||||
ret = META_MONITOR_TRANSFORM_90;
|
||||
break;
|
||||
case RR_Rotate_180:
|
||||
ret = WL_OUTPUT_TRANSFORM_180;
|
||||
ret = META_MONITOR_TRANSFORM_180;
|
||||
break;
|
||||
case RR_Rotate_270:
|
||||
ret = WL_OUTPUT_TRANSFORM_270;
|
||||
ret = META_MONITOR_TRANSFORM_270;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -105,42 +107,42 @@ wl_transform_from_xrandr (Rotation rotation)
|
||||
|
||||
#define ALL_ROTATIONS (RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270)
|
||||
|
||||
static unsigned int
|
||||
wl_transform_from_xrandr_all (Rotation rotation)
|
||||
static MetaMonitorTransform
|
||||
meta_monitor_transform_from_xrandr_all (Rotation rotation)
|
||||
{
|
||||
unsigned ret;
|
||||
|
||||
/* Handle the common cases first (none or all) */
|
||||
if (rotation == 0 || rotation == RR_Rotate_0)
|
||||
return (1 << WL_OUTPUT_TRANSFORM_NORMAL);
|
||||
return (1 << META_MONITOR_TRANSFORM_NORMAL);
|
||||
|
||||
/* All rotations and one reflection -> all of them by composition */
|
||||
if ((rotation & ALL_ROTATIONS) &&
|
||||
((rotation & RR_Reflect_X) || (rotation & RR_Reflect_Y)))
|
||||
return ALL_WL_TRANSFORMS;
|
||||
return ALL_TRANSFORMS;
|
||||
|
||||
ret = 1 << WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
ret = 1 << META_MONITOR_TRANSFORM_NORMAL;
|
||||
if (rotation & RR_Rotate_90)
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_90;
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_90;
|
||||
if (rotation & RR_Rotate_180)
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_180;
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_180;
|
||||
if (rotation & RR_Rotate_270)
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_270;
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_270;
|
||||
if (rotation & (RR_Rotate_0 | RR_Reflect_X))
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED;
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED;
|
||||
if (rotation & (RR_Rotate_90 | RR_Reflect_X))
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_90;
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_90;
|
||||
if (rotation & (RR_Rotate_180 | RR_Reflect_X))
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_180;
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_180;
|
||||
if (rotation & (RR_Rotate_270 | RR_Reflect_X))
|
||||
ret |= 1 << WL_OUTPUT_TRANSFORM_FLIPPED_270;
|
||||
ret |= 1 << META_MONITOR_TRANSFORM_FLIPPED_270;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
output_get_boolean_property (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output, const char *propname)
|
||||
{
|
||||
gboolean value;
|
||||
Atom atom, actual_type;
|
||||
@@ -148,9 +150,9 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *buffer;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False);
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->output_id,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, XA_CARDINAL,
|
||||
&actual_type, &actual_format,
|
||||
@@ -166,6 +168,13 @@ output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
return value;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
output_get_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
return output_get_boolean_property (manager_xrandr, output, "_MUTTER_PRESENTATION_OUTPUT");
|
||||
}
|
||||
|
||||
static int
|
||||
normalize_backlight (MetaOutput *output,
|
||||
int hw_value)
|
||||
@@ -186,7 +195,7 @@ output_get_backlight_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
|
||||
XRRGetOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->output_id,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
0, G_MAXLONG, False, False, XA_INTEGER,
|
||||
&actual_type, &actual_format,
|
||||
@@ -207,30 +216,34 @@ output_get_backlight_limits_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
MetaOutput *output)
|
||||
{
|
||||
Atom atom;
|
||||
XRRPropertyInfo *info;
|
||||
xcb_connection_t *xcb_conn;
|
||||
xcb_randr_query_output_property_reply_t *reply;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
|
||||
info = XRRQueryOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->output_id,
|
||||
atom);
|
||||
|
||||
if (info == NULL)
|
||||
{
|
||||
meta_verbose ("could not get output property for %s\n", output->name);
|
||||
return;
|
||||
}
|
||||
xcb_conn = XGetXCBConnection (manager_xrandr->xdisplay);
|
||||
reply = xcb_randr_query_output_property_reply (xcb_conn,
|
||||
xcb_randr_query_output_property (xcb_conn,
|
||||
(xcb_randr_output_t) output->winsys_id,
|
||||
(xcb_atom_t) atom),
|
||||
NULL);
|
||||
|
||||
if (!info->range || info->num_values != 2)
|
||||
/* This can happen on systems without backlights. */
|
||||
if (reply == NULL)
|
||||
return;
|
||||
|
||||
if (!reply->range || reply->length != 2)
|
||||
{
|
||||
meta_verbose ("backlight %s was not range\n", output->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
output->backlight_min = info->values[0];
|
||||
output->backlight_max = info->values[1];
|
||||
int32_t *values = xcb_randr_query_output_property_valid_values (reply);
|
||||
output->backlight_min = values[0];
|
||||
output->backlight_max = values[1];
|
||||
|
||||
out:
|
||||
XFree (info);
|
||||
free (reply);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -272,31 +285,31 @@ get_edid_property (Display *dpy,
|
||||
}
|
||||
|
||||
XFree (prop);
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static GBytes *
|
||||
read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
XID output_id)
|
||||
XID winsys_id)
|
||||
{
|
||||
Atom edid_atom;
|
||||
guint8 *result;
|
||||
gsize len;
|
||||
|
||||
edid_atom = XInternAtom (manager_xrandr->xdisplay, "EDID", FALSE);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, output_id, edid_atom, &len);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
edid_atom = XInternAtom (manager_xrandr->xdisplay, "EDID_DATA", FALSE);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, output_id, edid_atom, &len);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
edid_atom = XInternAtom (manager_xrandr->xdisplay, "XFree86_DDC_EDID1_RAWDATA", FALSE);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, output_id, edid_atom, &len);
|
||||
result = get_edid_property (manager_xrandr->xdisplay, winsys_id, edid_atom, &len);
|
||||
}
|
||||
|
||||
if (result)
|
||||
@@ -312,26 +325,11 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
|
||||
static gboolean
|
||||
output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
XID output_id)
|
||||
MetaOutput *output)
|
||||
{
|
||||
Atom atom;
|
||||
XRRPropertyInfo *info;
|
||||
gboolean result = FALSE;
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "hotplug_mode_update", False);
|
||||
info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id,
|
||||
atom);
|
||||
|
||||
if (info)
|
||||
{
|
||||
result = TRUE;
|
||||
XFree (info);
|
||||
}
|
||||
|
||||
return result;
|
||||
return output_get_boolean_property (manager_xrandr, output, "hotplug_mode_update");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
{
|
||||
@@ -434,8 +432,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
meta_crtc->rect.width = crtc->width;
|
||||
meta_crtc->rect.height = crtc->height;
|
||||
meta_crtc->is_dirty = FALSE;
|
||||
meta_crtc->transform = wl_transform_from_xrandr (crtc->rotation);
|
||||
meta_crtc->all_transforms = wl_transform_from_xrandr_all (crtc->rotations);
|
||||
meta_crtc->transform = meta_monitor_transform_from_xrandr (crtc->rotation);
|
||||
meta_crtc->all_transforms = meta_monitor_transform_from_xrandr_all (crtc->rotations);
|
||||
|
||||
for (j = 0; j < (unsigned)resources->nmode; j++)
|
||||
{
|
||||
@@ -467,10 +465,10 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
GBytes *edid;
|
||||
MonitorInfo *parsed_edid;
|
||||
|
||||
meta_output->output_id = resources->outputs[i];
|
||||
meta_output->winsys_id = resources->outputs[i];
|
||||
meta_output->name = g_strdup (output->name);
|
||||
|
||||
edid = read_output_edid (manager_xrandr, meta_output->output_id);
|
||||
edid = read_output_edid (manager_xrandr, meta_output->winsys_id);
|
||||
if (edid)
|
||||
{
|
||||
gsize len;
|
||||
@@ -503,8 +501,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
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->output_id);
|
||||
meta_output->hotplug_mode_update = output_get_hotplug_mode_update (manager_xrandr, meta_output);
|
||||
|
||||
meta_output->n_modes = output->nmode;
|
||||
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
|
||||
@@ -556,7 +553,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
meta_output->possible_clones[j] = GINT_TO_POINTER (output->clones[j]);
|
||||
}
|
||||
|
||||
meta_output->is_primary = ((XID)meta_output->output_id == primary_output);
|
||||
meta_output->is_primary = ((XID)meta_output->winsys_id == primary_output);
|
||||
meta_output->is_presentation = output_get_presentation_xrandr (manager_xrandr, meta_output);
|
||||
output_get_backlight_limits_xrandr (manager_xrandr, meta_output);
|
||||
|
||||
@@ -589,7 +586,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
|
||||
|
||||
for (k = 0; k < manager->n_outputs; k++)
|
||||
{
|
||||
if (clone == (XID)manager->outputs[k].output_id)
|
||||
if (clone == (XID)manager->outputs[k].winsys_id)
|
||||
{
|
||||
meta_output->possible_clones[j] = &manager->outputs[k];
|
||||
break;
|
||||
@@ -605,7 +602,7 @@ meta_monitor_manager_xrandr_read_edid (MetaMonitorManager *manager,
|
||||
{
|
||||
MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
|
||||
|
||||
return read_output_edid (manager_xrandr, output->output_id);
|
||||
return read_output_edid (manager_xrandr, output->winsys_id);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -637,25 +634,25 @@ meta_monitor_manager_xrandr_set_power_save_mode (MetaMonitorManager *manager,
|
||||
}
|
||||
|
||||
static Rotation
|
||||
wl_transform_to_xrandr (enum wl_output_transform transform)
|
||||
meta_monitor_transform_to_xrandr (MetaMonitorTransform transform)
|
||||
{
|
||||
switch (transform)
|
||||
{
|
||||
case WL_OUTPUT_TRANSFORM_NORMAL:
|
||||
case META_MONITOR_TRANSFORM_NORMAL:
|
||||
return RR_Rotate_0;
|
||||
case WL_OUTPUT_TRANSFORM_90:
|
||||
case META_MONITOR_TRANSFORM_90:
|
||||
return RR_Rotate_90;
|
||||
case WL_OUTPUT_TRANSFORM_180:
|
||||
case META_MONITOR_TRANSFORM_180:
|
||||
return RR_Rotate_180;
|
||||
case WL_OUTPUT_TRANSFORM_270:
|
||||
case META_MONITOR_TRANSFORM_270:
|
||||
return RR_Rotate_270;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED:
|
||||
case META_MONITOR_TRANSFORM_FLIPPED:
|
||||
return RR_Reflect_X | RR_Rotate_0;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_90:
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_90:
|
||||
return RR_Reflect_X | RR_Rotate_90;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_180:
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_180:
|
||||
return RR_Reflect_X | RR_Rotate_180;
|
||||
case WL_OUTPUT_TRANSFORM_FLIPPED_270:
|
||||
case META_MONITOR_TRANSFORM_FLIPPED_270:
|
||||
return RR_Reflect_X | RR_Rotate_270;
|
||||
}
|
||||
|
||||
@@ -672,7 +669,7 @@ output_set_presentation_xrandr (MetaMonitorManagerXrandr *manager_xrandr,
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "_MUTTER_PRESENTATION_OUTPUT", False);
|
||||
XRRChangeOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->output_id,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
XA_CARDINAL, 32, PropModeReplace,
|
||||
(unsigned char*) &value, 1);
|
||||
@@ -828,7 +825,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
output->crtc = crtc;
|
||||
new_controlled_mask |= 1UL << j;
|
||||
|
||||
outputs[j] = output->output_id;
|
||||
outputs[j] = output->winsys_id;
|
||||
}
|
||||
|
||||
if (crtc->current_mode == mode &&
|
||||
@@ -847,7 +844,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
manager_xrandr->time,
|
||||
crtc_info->x, crtc_info->y,
|
||||
(XID)mode->mode_id,
|
||||
wl_transform_to_xrandr (crtc_info->transform),
|
||||
meta_monitor_transform_to_xrandr (crtc_info->transform),
|
||||
outputs, n_outputs);
|
||||
|
||||
if (ok != Success)
|
||||
@@ -891,7 +888,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
{
|
||||
XRRSetOutputPrimary (manager_xrandr->xdisplay,
|
||||
DefaultRootWindow (manager_xrandr->xdisplay),
|
||||
(XID)output_info->output->output_id);
|
||||
(XID)output_info->output->winsys_id);
|
||||
}
|
||||
|
||||
output_set_presentation_xrandr (manager_xrandr,
|
||||
@@ -918,6 +915,7 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
|
||||
}
|
||||
|
||||
XUngrabServer (manager_xrandr->xdisplay);
|
||||
XFlush (manager_xrandr->xdisplay);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -933,7 +931,7 @@ meta_monitor_manager_xrandr_change_backlight (MetaMonitorManager *manager,
|
||||
|
||||
atom = XInternAtom (manager_xrandr->xdisplay, "Backlight", False);
|
||||
XRRChangeOutputProperty (manager_xrandr->xdisplay,
|
||||
(XID)output->output_id,
|
||||
(XID)output->winsys_id,
|
||||
atom,
|
||||
XA_INTEGER, 32, PropModeReplace,
|
||||
(unsigned char *) &hw_value, 1);
|
||||
|
@@ -22,53 +22,11 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include "cogl-utils.h"
|
||||
|
||||
/**
|
||||
* meta_create_color_texture_4ub:
|
||||
* @red: red component
|
||||
* @green: green component
|
||||
* @blue: blue component
|
||||
* @alpha: alpha component
|
||||
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE;
|
||||
* %COGL_TEXTURE_NO_SLICING is useful if the texture will be
|
||||
* repeated to create a constant color fill, since hardware
|
||||
* repeat can't be used for a sliced texture.
|
||||
*
|
||||
* Creates a texture that is a single pixel with the specified
|
||||
* unpremultiplied color components.
|
||||
*
|
||||
* Return value: (transfer full): a newly created Cogl texture
|
||||
*/
|
||||
CoglTexture *
|
||||
meta_create_color_texture_4ub (guint8 red,
|
||||
guint8 green,
|
||||
guint8 blue,
|
||||
guint8 alpha,
|
||||
CoglTextureFlags flags)
|
||||
{
|
||||
CoglColor color;
|
||||
guint8 pixel[4];
|
||||
|
||||
cogl_color_init_from_4ub (&color, red, green, blue, alpha);
|
||||
cogl_color_premultiply (&color);
|
||||
|
||||
pixel[0] = cogl_color_get_red_byte (&color);
|
||||
pixel[1] = cogl_color_get_green_byte (&color);
|
||||
pixel[2] = cogl_color_get_blue_byte (&color);
|
||||
pixel[3] = cogl_color_get_alpha_byte (&color);
|
||||
|
||||
return cogl_texture_new_from_data (1, 1,
|
||||
flags,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
4, pixel);
|
||||
}
|
||||
|
||||
|
||||
/* Based on gnome-shell/src/st/st-private.c:_st_create_texture_material.c */
|
||||
|
||||
/**
|
||||
* meta_create_texture_pipeline:
|
||||
* @src_texture: (allow-none): texture to use initially for the layer
|
||||
* @src_texture: (nullable): texture to use initially for the layer
|
||||
*
|
||||
* Creates a pipeline with a single layer. Using a common template
|
||||
* makes it easier for Cogl to share a shader for different uses in
|
||||
|
@@ -23,11 +23,6 @@
|
||||
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
CoglTexture * meta_create_color_texture_4ub (guint8 red,
|
||||
guint8 green,
|
||||
guint8 blue,
|
||||
guint8 alpha,
|
||||
CoglTextureFlags flags);
|
||||
CoglPipeline * meta_create_texture_pipeline (CoglTexture *texture);
|
||||
|
||||
#endif /* __META_COGL_UTILS_H__ */
|
||||
|
@@ -38,6 +38,8 @@ struct _MetaCompositor
|
||||
gint switch_workspace_in_progress;
|
||||
|
||||
MetaPluginManager *plugin_mgr;
|
||||
|
||||
gboolean frame_has_updated_xsurfaces;
|
||||
};
|
||||
|
||||
/* Wait 2ms after vblank before starting to draw next frame */
|
||||
|
@@ -67,20 +67,19 @@
|
||||
#include <meta/compositor-mutter.h>
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/main.h>
|
||||
#include <meta/meta-backend.h>
|
||||
#include <meta/meta-background-actor.h>
|
||||
#include <meta/meta-background-group.h>
|
||||
#include <meta/meta-shadow-factory.h>
|
||||
#include "meta-window-actor-private.h"
|
||||
#include "meta-window-group.h"
|
||||
#include "meta-stage.h"
|
||||
#include "window-private.h" /* to check window->hidden */
|
||||
#include "display-private.h" /* for meta_display_lookup_x_window() */
|
||||
#include "display-private.h" /* for meta_display_lookup_x_window() and meta_display_cancel_touch() */
|
||||
#include "util-private.h"
|
||||
#include "frame.h"
|
||||
#include <X11/extensions/shape.h>
|
||||
#include <X11/extensions/Xcomposite.h>
|
||||
|
||||
#include "backends/meta-backend.h"
|
||||
#include "backends/x11/meta-backend-x11.h"
|
||||
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
@@ -88,19 +87,7 @@
|
||||
static gboolean
|
||||
is_modal (MetaDisplay *display)
|
||||
{
|
||||
return display->grab_op == META_GRAB_OP_COMPOSITOR;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
composite_at_least_version (MetaDisplay *display, int maj, int min)
|
||||
{
|
||||
static int major = -1;
|
||||
static int minor = -1;
|
||||
|
||||
if (major == -1)
|
||||
meta_display_get_compositor_version (display, &major, &minor);
|
||||
|
||||
return (major > maj || (major == maj && minor >= min));
|
||||
return display->event_route == META_EVENT_ROUTE_COMPOSITOR_GRAB;
|
||||
}
|
||||
|
||||
static void sync_actor_stacking (MetaCompositor *compositor);
|
||||
@@ -146,33 +133,8 @@ process_damage (MetaCompositor *compositor,
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_process_x11_damage (window_actor, event);
|
||||
}
|
||||
|
||||
static Window
|
||||
get_output_window (MetaCompositor *compositor)
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Display *xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
Window output;
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
output = XCompositeGetOverlayWindow (xdisplay, DefaultRootWindow (xdisplay));
|
||||
|
||||
meta_core_add_old_event_mask (xdisplay, output, &mask);
|
||||
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
XISetMask (mask.mask, XI_KeyRelease);
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
XISetMask (mask.mask, XI_FocusIn);
|
||||
XISetMask (mask.mask, XI_FocusOut);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
XISelectEvents (xdisplay, output, &mask, 1);
|
||||
|
||||
return output;
|
||||
compositor->frame_has_updated_xsurfaces = TRUE;
|
||||
}
|
||||
|
||||
/* compat helper */
|
||||
@@ -381,12 +343,20 @@ meta_begin_modal_for_plugin (MetaCompositor *compositor,
|
||||
return FALSE;
|
||||
|
||||
display->grab_op = META_GRAB_OP_COMPOSITOR;
|
||||
display->event_route = META_EVENT_ROUTE_COMPOSITOR_GRAB;
|
||||
display->grab_window = NULL;
|
||||
display->grab_have_pointer = TRUE;
|
||||
display->grab_have_keyboard = TRUE;
|
||||
|
||||
g_signal_emit_by_name (display, "grab-op-begin",
|
||||
meta_plugin_get_screen (plugin),
|
||||
display->grab_window, display->grab_op);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
{
|
||||
meta_display_sync_wayland_input_focus (display);
|
||||
meta_display_cancel_touch (display);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -401,7 +371,12 @@ meta_end_modal_for_plugin (MetaCompositor *compositor,
|
||||
|
||||
g_return_if_fail (is_modal (display));
|
||||
|
||||
g_signal_emit_by_name (display, "grab-op-end",
|
||||
meta_plugin_get_screen (plugin),
|
||||
display->grab_window, display->grab_op);
|
||||
|
||||
display->grab_op = META_GRAB_OP_NONE;
|
||||
display->event_route = META_EVENT_ROUTE_NORMAL;
|
||||
display->grab_window = NULL;
|
||||
display->grab_have_pointer = FALSE;
|
||||
display->grab_have_keyboard = FALSE;
|
||||
@@ -423,8 +398,10 @@ after_stage_paint (ClutterStage *stage,
|
||||
for (l = compositor->windows; l; l = l->next)
|
||||
meta_window_actor_post_paint (l->data);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (meta_is_wayland_compositor ())
|
||||
meta_wayland_compositor_paint_finished (meta_wayland_compositor_get_default ());
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -476,62 +453,24 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
MetaDisplay *display = compositor->display;
|
||||
Display *xdisplay = display->xdisplay;
|
||||
MetaScreen *screen = display->screen;
|
||||
Window xwin = 0;
|
||||
gint width, height;
|
||||
|
||||
meta_screen_set_cm_selection (display->screen);
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
MetaWaylandCompositor *wayland_compositor = meta_wayland_compositor_get_default ();
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
compositor->stage = meta_backend_get_stage (backend);
|
||||
}
|
||||
|
||||
compositor->stage = meta_stage_new ();
|
||||
clutter_actor_show (compositor->stage);
|
||||
|
||||
wayland_compositor->stage = compositor->stage;
|
||||
|
||||
meta_screen_get_size (screen, &width, &height);
|
||||
clutter_actor_set_size (compositor->stage, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
compositor->stage = clutter_stage_new ();
|
||||
|
||||
meta_screen_get_size (screen, &width, &height);
|
||||
clutter_actor_realize (compositor->stage);
|
||||
|
||||
xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage));
|
||||
|
||||
XResizeWindow (xdisplay, xwin, width, height);
|
||||
|
||||
{
|
||||
MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ());
|
||||
Display *backend_xdisplay = meta_backend_x11_get_xdisplay (backend);
|
||||
unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
|
||||
XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
|
||||
|
||||
meta_core_add_old_event_mask (backend_xdisplay, xwin, &mask);
|
||||
|
||||
XISetMask (mask.mask, XI_KeyPress);
|
||||
XISetMask (mask.mask, XI_KeyRelease);
|
||||
XISetMask (mask.mask, XI_ButtonPress);
|
||||
XISetMask (mask.mask, XI_ButtonRelease);
|
||||
XISetMask (mask.mask, XI_Enter);
|
||||
XISetMask (mask.mask, XI_Leave);
|
||||
XISetMask (mask.mask, XI_FocusIn);
|
||||
XISetMask (mask.mask, XI_FocusOut);
|
||||
XISetMask (mask.mask, XI_Motion);
|
||||
XIClearMask (mask.mask, XI_TouchBegin);
|
||||
XIClearMask (mask.mask, XI_TouchEnd);
|
||||
XIClearMask (mask.mask, XI_TouchUpdate);
|
||||
XISelectEvents (backend_xdisplay, xwin, &mask, 1);
|
||||
}
|
||||
}
|
||||
|
||||
clutter_stage_set_paint_callback (CLUTTER_STAGE (compositor->stage),
|
||||
after_stage_paint,
|
||||
compositor,
|
||||
NULL);
|
||||
/* We use connect_after() here to accomodate code in GNOME Shell that,
|
||||
* when benchmarking drawing performance, connects to ::after-paint
|
||||
* and calls glFinish(). The timing information from that will be
|
||||
* more accurate if we hold off until that completes before we signal
|
||||
* apps to begin drawing the next frame. If there are no other
|
||||
* connections to ::after-paint, connect() vs. connect_after() doesn't
|
||||
* matter.
|
||||
*/
|
||||
g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint",
|
||||
G_CALLBACK (after_stage_paint), compositor);
|
||||
|
||||
clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY);
|
||||
|
||||
@@ -550,15 +489,20 @@ meta_compositor_manage (MetaCompositor *compositor)
|
||||
}
|
||||
else
|
||||
{
|
||||
compositor->output = get_output_window (compositor);
|
||||
Window xwin;
|
||||
|
||||
compositor->output = screen->composite_overlay_window;
|
||||
|
||||
xwin = meta_backend_x11_get_xwindow (META_BACKEND_X11 (meta_get_backend ()));
|
||||
|
||||
XReparentWindow (xdisplay, xwin, compositor->output, 0, 0);
|
||||
|
||||
meta_empty_stage_input_region (screen);
|
||||
|
||||
/* Make sure there isn't any left-over output shape on the
|
||||
/* Make sure there isn't any left-over output shape on the
|
||||
* overlay window by setting the whole screen to be an
|
||||
* output region.
|
||||
*
|
||||
*
|
||||
* Note: there doesn't seem to be any real chance of that
|
||||
* because the X server will destroy the overlay window
|
||||
* when the last client using it exits.
|
||||
@@ -595,7 +539,7 @@ meta_compositor_unmanage (MetaCompositor *compositor)
|
||||
/**
|
||||
* meta_shape_cow_for_window:
|
||||
* @compositor: A #MetaCompositor
|
||||
* @window: (allow-none): A #MetaWindow to shape the COW for
|
||||
* @window: (nullable): A #MetaWindow to shape the COW for
|
||||
*
|
||||
* Sets an bounding shape on the COW so that the given window
|
||||
* is exposed. If @window is %NULL it clears the shape again.
|
||||
@@ -691,12 +635,11 @@ meta_compositor_remove_window (MetaCompositor *compositor,
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_set_updates_frozen (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
gboolean updates_frozen)
|
||||
meta_compositor_sync_updates_frozen (MetaCompositor *compositor,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
meta_window_actor_set_updates_frozen (window_actor, updates_frozen);
|
||||
meta_window_actor_sync_updates_frozen (window_actor);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -746,9 +689,9 @@ meta_compositor_window_surface_changed (MetaCompositor *compositor,
|
||||
|
||||
/**
|
||||
* meta_compositor_process_event: (skip)
|
||||
* @compositor:
|
||||
* @event:
|
||||
* @window:
|
||||
* @compositor:
|
||||
* @event:
|
||||
* @window:
|
||||
*
|
||||
*/
|
||||
gboolean
|
||||
@@ -756,9 +699,6 @@ meta_compositor_process_event (MetaCompositor *compositor,
|
||||
XEvent *event,
|
||||
MetaWindow *window)
|
||||
{
|
||||
if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event))
|
||||
return TRUE;
|
||||
|
||||
if (!meta_is_wayland_compositor () &&
|
||||
event->type == meta_display_get_damage_event_base (compositor->display) + XDamageNotify)
|
||||
{
|
||||
@@ -1046,43 +986,6 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor,
|
||||
meta_window_actor_sync_actor_geometry (window_actor, did_placement);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_sync_screen_size (MetaCompositor *compositor,
|
||||
guint width,
|
||||
guint height)
|
||||
{
|
||||
MetaDisplay *display = compositor->display;
|
||||
|
||||
if (meta_is_wayland_compositor ())
|
||||
{
|
||||
/* FIXME: when we support a sliced stage, this is the place to do it
|
||||
But! This is not the place to apply KMS config, here we only
|
||||
notify Clutter/Cogl/GL that the framebuffer sizes changed.
|
||||
|
||||
And because for now clutter does not do sliced, we use one
|
||||
framebuffer the size of the whole screen, and when running on
|
||||
bare metal MetaMonitorManager will do the necessary tricks to
|
||||
show the right portions on the right screens.
|
||||
*/
|
||||
|
||||
clutter_actor_set_size (compositor->stage, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
Display *xdisplay;
|
||||
Window xwin;
|
||||
|
||||
xdisplay = meta_display_get_xdisplay (display);
|
||||
xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage));
|
||||
|
||||
XResizeWindow (xdisplay, xwin, width, height);
|
||||
}
|
||||
|
||||
meta_verbose ("Changed size for stage on screen %d to %dx%d\n",
|
||||
meta_screen_get_screen_number (display->screen),
|
||||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
frame_callback (CoglOnscreen *onscreen,
|
||||
CoglFrameEvent event,
|
||||
@@ -1153,6 +1056,33 @@ pre_paint_windows (MetaCompositor *compositor)
|
||||
|
||||
for (l = compositor->windows; l; l = l->next)
|
||||
meta_window_actor_pre_paint (l->data);
|
||||
|
||||
if (compositor->frame_has_updated_xsurfaces)
|
||||
{
|
||||
/* We need to make sure that any X drawing that happens before
|
||||
* the XDamageSubtract() for each window above is visible to
|
||||
* subsequent GL rendering; the only standardized way to do this
|
||||
* is EXT_x11_sync_object, which isn't yet widely available. For
|
||||
* now, we count on details of Xorg and the open source drivers,
|
||||
* and hope for the best otherwise.
|
||||
*
|
||||
* Xorg and open source driver specifics:
|
||||
*
|
||||
* The X server makes sure to flush drawing to the kernel before
|
||||
* sending out damage events, but since we use
|
||||
* DamageReportBoundingBox there may be drawing between the last
|
||||
* damage event and the XDamageSubtract() that needs to be
|
||||
* flushed as well.
|
||||
*
|
||||
* Xorg always makes sure that drawing is flushed to the kernel
|
||||
* before writing events or responses to the client, so any
|
||||
* round trip request at this point is sufficient to flush the
|
||||
* GLX buffers.
|
||||
*/
|
||||
XSync (compositor->display->xdisplay, False);
|
||||
|
||||
compositor->frame_has_updated_xsurfaces = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -1183,11 +1113,7 @@ meta_compositor_new (MetaDisplay *display)
|
||||
{
|
||||
MetaCompositor *compositor;
|
||||
|
||||
if (!composite_at_least_version (display, 0, 3))
|
||||
return NULL;
|
||||
|
||||
compositor = g_new0 (MetaCompositor, 1);
|
||||
|
||||
compositor->display = display;
|
||||
|
||||
if (g_getenv("META_DISABLE_MIPMAPS"))
|
||||
@@ -1356,3 +1282,22 @@ meta_compositor_hide_tile_preview (MetaCompositor *compositor)
|
||||
{
|
||||
meta_plugin_manager_hide_tile_preview (compositor->plugin_mgr);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_show_window_menu (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
meta_plugin_manager_show_window_menu (compositor->plugin_mgr, window, menu, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_compositor_show_window_menu_for_rect (MetaCompositor *compositor,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
meta_plugin_manager_show_window_menu_for_rect (compositor->plugin_mgr, window, menu, rect);
|
||||
}
|
||||
|
@@ -185,7 +185,7 @@ cullable_iface_init (MetaCullableInterface *iface)
|
||||
* meta_background_actor_get_clip_region:
|
||||
* @self: a #MetaBackgroundActor
|
||||
*
|
||||
* Return value (transfer full): a #cairo_region_t that represents the part of
|
||||
* Return value (transfer none): a #cairo_region_t that represents the part of
|
||||
* the background not obscured by other #MetaBackgroundActor or
|
||||
* #MetaWindowActor objects.
|
||||
*/
|
||||
@@ -193,24 +193,5 @@ cairo_region_t *
|
||||
meta_background_actor_get_clip_region (MetaBackgroundActor *self)
|
||||
{
|
||||
MetaBackgroundActorPrivate *priv = self->priv;
|
||||
ClutterActorBox content_box;
|
||||
cairo_rectangle_int_t content_area = { 0 };
|
||||
cairo_region_t *clip_region;
|
||||
|
||||
g_return_val_if_fail (META_IS_BACKGROUND_ACTOR (self), NULL);
|
||||
|
||||
if (!priv->clip_region)
|
||||
return NULL;
|
||||
|
||||
clutter_actor_get_content_box (CLUTTER_ACTOR (self), &content_box);
|
||||
|
||||
content_area.x = content_box.x1;
|
||||
content_area.y = content_box.y1;
|
||||
content_area.width = content_box.x2 - content_box.x1;
|
||||
content_area.height = content_box.y2 - content_box.y1;
|
||||
|
||||
clip_region = cairo_region_create_rectangle (&content_area);
|
||||
cairo_region_intersect (clip_region, priv->clip_region);
|
||||
|
||||
return clip_region;
|
||||
return priv->clip_region;
|
||||
}
|
||||
|
@@ -288,6 +288,26 @@ get_wrap_mode (MetaBackground *self)
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
texture_has_alpha (CoglTexture *texture)
|
||||
{
|
||||
if (!texture)
|
||||
return FALSE;
|
||||
|
||||
switch (cogl_texture_get_components (texture))
|
||||
{
|
||||
case COGL_TEXTURE_COMPONENTS_A:
|
||||
case COGL_TEXTURE_COMPONENTS_RGBA:
|
||||
return TRUE;
|
||||
case COGL_TEXTURE_COMPONENTS_RG:
|
||||
case COGL_TEXTURE_COMPONENTS_RGB:
|
||||
case COGL_TEXTURE_COMPONENTS_DEPTH:
|
||||
return FALSE;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterPaintNode *
|
||||
meta_background_paint_node_new (MetaBackground *self,
|
||||
ClutterActor *actor)
|
||||
@@ -296,6 +316,7 @@ meta_background_paint_node_new (MetaBackground *self,
|
||||
ClutterPaintNode *node;
|
||||
guint8 opacity;
|
||||
guint8 color_component;
|
||||
gboolean needs_blending;
|
||||
|
||||
opacity = clutter_actor_get_paint_opacity (actor);
|
||||
color_component = (guint8) (0.5 + opacity * priv->brightness);
|
||||
@@ -308,6 +329,13 @@ meta_background_paint_node_new (MetaBackground *self,
|
||||
|
||||
node = clutter_pipeline_node_new (priv->pipeline);
|
||||
|
||||
needs_blending = (opacity < 255) || (texture_has_alpha (priv->texture));
|
||||
|
||||
if (needs_blending)
|
||||
cogl_pipeline_set_blend (priv->pipeline, "RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))", NULL);
|
||||
else
|
||||
cogl_pipeline_set_blend (priv->pipeline, "RGBA = ADD (SRC_COLOR, 0)", NULL);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -382,8 +410,6 @@ meta_background_paint_content (ClutterContent *content,
|
||||
if (priv->texture == NULL)
|
||||
return;
|
||||
|
||||
node = meta_background_paint_node_new (self, actor);
|
||||
|
||||
clutter_actor_get_content_box (actor, &actor_box);
|
||||
|
||||
/* First figure out where on the monitor the texture is supposed to be painted.
|
||||
@@ -413,12 +439,14 @@ meta_background_paint_content (ClutterContent *content,
|
||||
clip_region = meta_background_actor_get_clip_region (META_BACKGROUND_ACTOR (actor));
|
||||
|
||||
if (clip_region != NULL)
|
||||
{
|
||||
cairo_region_intersect (paintable_region, clip_region);
|
||||
cairo_region_destroy (clip_region);
|
||||
}
|
||||
cairo_region_intersect (paintable_region, clip_region);
|
||||
}
|
||||
|
||||
if (cairo_region_is_empty (paintable_region))
|
||||
goto out;
|
||||
|
||||
node = meta_background_paint_node_new (self, actor);
|
||||
|
||||
/* Finally, split the paintable region up into distinct areas
|
||||
* and paint each area one by one
|
||||
*/
|
||||
@@ -441,10 +469,11 @@ meta_background_paint_content (ClutterContent *content,
|
||||
|
||||
clutter_paint_node_add_texture_rectangle (node, &texture_rectangle, tx1, ty1, tx2, ty2);
|
||||
}
|
||||
cairo_region_destroy (paintable_region);
|
||||
|
||||
clutter_paint_node_add_child (root, node);
|
||||
clutter_paint_node_unref (node);
|
||||
|
||||
out:
|
||||
cairo_region_destroy (paintable_region);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -498,7 +527,8 @@ set_brightness (MetaBackground *self,
|
||||
|
||||
priv->brightness = brightness;
|
||||
|
||||
if (priv->effects & META_BACKGROUND_EFFECTS_VIGNETTE)
|
||||
if (clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL) &&
|
||||
priv->effects & META_BACKGROUND_EFFECTS_VIGNETTE)
|
||||
{
|
||||
ensure_pipeline (self);
|
||||
cogl_pipeline_set_uniform_1f (priv->pipeline,
|
||||
@@ -506,6 +536,14 @@ set_brightness (MetaBackground *self,
|
||||
"brightness"),
|
||||
priv->brightness);
|
||||
}
|
||||
else
|
||||
{
|
||||
ensure_pipeline (self);
|
||||
CoglColor blend_color;
|
||||
cogl_color_init_from_4f (&blend_color, brightness, brightness, brightness, 1.0);
|
||||
cogl_pipeline_set_layer_combine (priv->pipeline, 1, "RGB=MODULATE(PREVIOUS, CONSTANT) A=REPLACE(PREVIOUS)", NULL);
|
||||
cogl_pipeline_set_layer_combine_constant (priv->pipeline, 1, &blend_color);
|
||||
}
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (self));
|
||||
|
||||
@@ -523,6 +561,9 @@ set_vignette_sharpness (MetaBackground *self,
|
||||
|
||||
priv->vignette_sharpness = sharpness;
|
||||
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
return;
|
||||
|
||||
if (priv->effects & META_BACKGROUND_EFFECTS_VIGNETTE)
|
||||
{
|
||||
ensure_pipeline (self);
|
||||
@@ -543,6 +584,9 @@ add_vignette (MetaBackground *self)
|
||||
MetaBackgroundPrivate *priv = self->priv;
|
||||
static CoglSnippet *snippet = NULL;
|
||||
|
||||
if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
|
||||
return;
|
||||
|
||||
ensure_pipeline (self);
|
||||
|
||||
/* Cogl automatically caches pipelines with no eviction policy,
|
||||
@@ -770,6 +814,8 @@ meta_background_load_gradient (MetaBackground *self,
|
||||
ClutterColor *color,
|
||||
ClutterColor *second_color)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
MetaBackgroundPrivate *priv = self->priv;
|
||||
CoglTexture *texture;
|
||||
guint width, height;
|
||||
@@ -799,18 +845,17 @@ meta_background_load_gradient (MetaBackground *self,
|
||||
pixels[0] = color->red;
|
||||
pixels[1] = color->green;
|
||||
pixels[2] = color->blue;
|
||||
pixels[3] = color->alpha;
|
||||
pixels[3] = 0xFF;
|
||||
pixels[4] = second_color->red;
|
||||
pixels[5] = second_color->green;
|
||||
pixels[6] = second_color->blue;
|
||||
pixels[7] = second_color->alpha;
|
||||
pixels[7] = 0xFF;
|
||||
|
||||
texture = cogl_texture_new_from_data (width, height,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
4,
|
||||
pixels);
|
||||
texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, width, height,
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
4,
|
||||
pixels,
|
||||
NULL));
|
||||
set_texture (self, COGL_TEXTURE (texture));
|
||||
}
|
||||
|
||||
@@ -828,10 +873,13 @@ void
|
||||
meta_background_load_color (MetaBackground *self,
|
||||
ClutterColor *color)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
MetaBackgroundPrivate *priv = self->priv;
|
||||
CoglTexture *texture;
|
||||
ClutterActor *stage = meta_get_stage_for_screen (priv->screen);
|
||||
ClutterColor stage_color;
|
||||
uint8_t pixels[4];
|
||||
|
||||
ensure_pipeline (self);
|
||||
|
||||
@@ -844,11 +892,16 @@ meta_background_load_color (MetaBackground *self,
|
||||
color = &stage_color;
|
||||
}
|
||||
|
||||
texture = meta_create_color_texture_4ub (color->red,
|
||||
color->green,
|
||||
color->blue,
|
||||
0xff,
|
||||
COGL_TEXTURE_NO_SLICING);
|
||||
pixels[0] = color->red;
|
||||
pixels[1] = color->green;
|
||||
pixels[2] = color->blue;
|
||||
pixels[3] = 0xFF;
|
||||
|
||||
texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, 1, 1,
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
4,
|
||||
pixels,
|
||||
NULL));
|
||||
set_texture (self, COGL_TEXTURE (texture));
|
||||
}
|
||||
|
||||
@@ -946,6 +999,8 @@ meta_background_load_file_finish (MetaBackground *self,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
GTask *task;
|
||||
LoadFileTaskData *task_data;
|
||||
CoglTexture *texture;
|
||||
@@ -954,6 +1009,7 @@ meta_background_load_file_finish (MetaBackground *self,
|
||||
guchar *pixels;
|
||||
gboolean has_alpha;
|
||||
gboolean loaded = FALSE;
|
||||
CoglPixelFormat pixel_format;
|
||||
|
||||
g_return_val_if_fail (g_task_is_valid (result, self), FALSE);
|
||||
|
||||
@@ -972,15 +1028,13 @@ meta_background_load_file_finish (MetaBackground *self,
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
|
||||
|
||||
texture = cogl_texture_new_from_data (width,
|
||||
height,
|
||||
COGL_TEXTURE_NO_ATLAS,
|
||||
has_alpha ?
|
||||
COGL_PIXEL_FORMAT_RGBA_8888 :
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
row_stride,
|
||||
pixels);
|
||||
pixel_format = has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888;
|
||||
|
||||
texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, width, height,
|
||||
pixel_format,
|
||||
row_stride,
|
||||
pixels,
|
||||
NULL));
|
||||
|
||||
if (texture == NULL)
|
||||
{
|
||||
|
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include <meta/meta-plugin.h>
|
||||
#include <meta/meta-version.h>
|
||||
#include "meta-module.h"
|
||||
|
||||
#include <gmodule.h>
|
||||
@@ -68,7 +69,7 @@ meta_module_load (GTypeModule *gmodule)
|
||||
(gpointer *)(void *)®ister_type) &&
|
||||
info && register_type)
|
||||
{
|
||||
if (info->version_api != MUTTER_PLUGIN_API_VERSION)
|
||||
if (info->version_api != META_PLUGIN_API_VERSION)
|
||||
g_warning ("Plugin API mismatch for [%s]", priv->path);
|
||||
else
|
||||
{
|
||||
|
@@ -170,6 +170,15 @@ meta_plugin_manager_event_simple (MetaPluginManager *plugin_mgr,
|
||||
klass->minimize (plugin, actor);
|
||||
}
|
||||
break;
|
||||
case META_PLUGIN_UNMINIMIZE:
|
||||
if (klass->unminimize)
|
||||
{
|
||||
retval = TRUE;
|
||||
meta_plugin_manager_kill_window_effects (plugin_mgr,
|
||||
actor);
|
||||
klass->unminimize (plugin, actor);
|
||||
}
|
||||
break;
|
||||
case META_PLUGIN_MAP:
|
||||
if (klass->map)
|
||||
{
|
||||
@@ -356,3 +365,38 @@ meta_plugin_manager_hide_tile_preview (MetaPluginManager *plugin_mgr)
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_manager_show_window_menu (MetaPluginManager *plugin_mgr,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
MetaPlugin *plugin = plugin_mgr->plugin;
|
||||
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
|
||||
MetaDisplay *display = plugin_mgr->compositor->display;
|
||||
|
||||
if (display->display_opening)
|
||||
return;
|
||||
|
||||
if (klass->show_window_menu)
|
||||
klass->show_window_menu (plugin, window, menu, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *plugin_mgr,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
MetaPlugin *plugin = plugin_mgr->plugin;
|
||||
MetaPluginClass *klass = META_PLUGIN_GET_CLASS (plugin);
|
||||
MetaDisplay *display = plugin_mgr->compositor->display;
|
||||
|
||||
if (display->display_opening)
|
||||
return;
|
||||
|
||||
if (klass->show_window_menu_for_rect)
|
||||
klass->show_window_menu_for_rect (plugin, window, menu, rect);
|
||||
}
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#define META_PLUGIN_MAP (1<<3)
|
||||
#define META_PLUGIN_DESTROY (1<<4)
|
||||
#define META_PLUGIN_SWITCH_WORKSPACE (1<<5)
|
||||
#define META_PLUGIN_UNMINIMIZE (1<<6)
|
||||
|
||||
#define META_PLUGIN_ALL_EFFECTS (~0)
|
||||
|
||||
@@ -80,4 +81,17 @@ gboolean meta_plugin_manager_show_tile_preview (MetaPluginManager *mgr,
|
||||
MetaRectangle *tile_rect,
|
||||
int tile_monitor_number);
|
||||
gboolean meta_plugin_manager_hide_tile_preview (MetaPluginManager *mgr);
|
||||
|
||||
void meta_plugin_manager_show_window_menu (MetaPluginManager *mgr,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
int x,
|
||||
int y);
|
||||
|
||||
void meta_plugin_manager_show_window_menu_for_rect (MetaPluginManager *mgr,
|
||||
MetaWindow *window,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect);
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -110,6 +110,13 @@ meta_plugin_minimize_completed (MetaPlugin *plugin,
|
||||
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_MINIMIZE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_unminimize_completed (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor)
|
||||
{
|
||||
meta_plugin_window_effect_completed (plugin, actor, META_PLUGIN_UNMINIMIZE);
|
||||
}
|
||||
|
||||
void
|
||||
meta_plugin_maximize_completed (MetaPlugin *plugin,
|
||||
MetaWindowActor *actor)
|
||||
|
@@ -121,17 +121,17 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
||||
/* The first element in this array also defines the default parameters
|
||||
* for newly created classes */
|
||||
MetaShadowClassInfo default_shadow_classes[] = {
|
||||
{ "normal", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "dialog", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "modal_dialog", { 6, -1, 0, 1, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "normal", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "dialog", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "modal_dialog", { 3, -1, 0, 1, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "utility", { 3, -1, 0, 1, 128 }, { 3, -1, 0, 1, 32 } },
|
||||
{ "border", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "menu", { 6, -1, 0, 3, 128 }, { 3, -1, 0, 0, 32 } },
|
||||
{ "border", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 3, 32 } },
|
||||
{ "menu", { 3, -1, 0, 3, 128 }, { 3, -1, 0, 0, 32 } },
|
||||
|
||||
{ "popup-menu", { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } },
|
||||
{ "popup-menu", { 1, 0, 0, 1, 128 }, { 1, -1, 0, 1, 128 } },
|
||||
|
||||
{ "dropdown-menu", { 1, 10, 0, 1, 128 }, { 1, 10, 0, 1, 128 } },
|
||||
{ "attached", { 1, -1, 0, 1, 128 }, { 1, -1, 0, 1, 128 } }
|
||||
{ "attached", { 1, 0, 0, 1, 128 }, { 1, -1, 0, 1, 128 } }
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaShadowFactory, meta_shadow_factory, G_TYPE_OBJECT);
|
||||
@@ -189,7 +189,7 @@ meta_shadow_unref (MetaShadow *shadow)
|
||||
* @window_y: y position of the region to paint a shadow for
|
||||
* @window_width: actual width of the region to paint a shadow for
|
||||
* @window_height: actual height of the region to paint a shadow for
|
||||
* @clip: (allow-none): if non-%NULL specifies the visible portion
|
||||
* @clip: (nullable): if non-%NULL specifies the visible portion
|
||||
* of the shadow.
|
||||
* @clip_strictly: if %TRUE, drawing will be clipped strictly
|
||||
* to @clip, otherwise, it will be only used to optimize
|
||||
@@ -496,7 +496,12 @@ get_box_filter_size (int radius)
|
||||
static int
|
||||
get_shadow_spread (int radius)
|
||||
{
|
||||
int d = get_box_filter_size (radius);
|
||||
int d;
|
||||
|
||||
if (radius == 0)
|
||||
return 0;
|
||||
|
||||
d = get_box_filter_size (radius);
|
||||
|
||||
if (d % 2 == 1)
|
||||
return 3 * (d / 2);
|
||||
@@ -536,7 +541,7 @@ blur_xspan (guchar *row,
|
||||
* be well predicted and there are enough different possibilities
|
||||
* that trying to write this as a series of unconditional loops
|
||||
* is hard and not an obvious win. The main slow down here seems
|
||||
* to be the integer division for pixel; one possible optimization
|
||||
* to be the integer division per pixel; one possible optimization
|
||||
* would be to accumulate into two 16-bit integer buffers and
|
||||
* only divide down after all three passes. (SSE parallel implementation
|
||||
* of the divide step is possible.)
|
||||
@@ -544,27 +549,27 @@ blur_xspan (guchar *row,
|
||||
for (i = x0 - d + offset; i < x1 + offset; i++)
|
||||
{
|
||||
if (i >= 0 && i < row_width)
|
||||
sum += row[i];
|
||||
sum += row[i];
|
||||
|
||||
if (i >= x0 + offset)
|
||||
{
|
||||
if (i >= d)
|
||||
sum -= row[i - d];
|
||||
{
|
||||
if (i >= d)
|
||||
sum -= row[i - d];
|
||||
|
||||
tmp_buffer[i - offset] = (sum + d / 2) / d;
|
||||
}
|
||||
tmp_buffer[i - offset] = (sum + d / 2) / d;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(row + x0, tmp_buffer + x0, x1 - x0);
|
||||
memcpy (row + x0, tmp_buffer + x0, x1 - x0);
|
||||
}
|
||||
|
||||
static void
|
||||
blur_rows (cairo_region_t *convolve_region,
|
||||
int x_offset,
|
||||
int y_offset,
|
||||
guchar *buffer,
|
||||
int buffer_width,
|
||||
int buffer_height,
|
||||
guchar *buffer,
|
||||
int buffer_width,
|
||||
int buffer_height,
|
||||
int d)
|
||||
{
|
||||
int i, j;
|
||||
@@ -581,30 +586,30 @@ blur_rows (cairo_region_t *convolve_region,
|
||||
cairo_region_get_rectangle (convolve_region, i, &rect);
|
||||
|
||||
for (j = y_offset + rect.y; j < y_offset + rect.y + rect.height; j++)
|
||||
{
|
||||
guchar *row = buffer + j * buffer_width;
|
||||
int x0 = x_offset + rect.x;
|
||||
int x1 = x0 + rect.width;
|
||||
{
|
||||
guchar *row = buffer + j * buffer_width;
|
||||
int x0 = x_offset + rect.x;
|
||||
int x1 = x0 + rect.width;
|
||||
|
||||
/* We want to produce a symmetric blur that spreads a pixel
|
||||
* equally far to the left and right. If d is odd that happens
|
||||
* naturally, but for d even, we approximate by using a blur
|
||||
* on either side and then a centered blur of size d + 1.
|
||||
* (techique also from the SVG specification)
|
||||
* (technique also from the SVG specification)
|
||||
*/
|
||||
if (d % 2 == 1)
|
||||
{
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 1);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, -1);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d + 1, 0);
|
||||
}
|
||||
}
|
||||
if (d % 2 == 1)
|
||||
{
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, 1);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d, -1);
|
||||
blur_xspan (row, tmp_buffer, buffer_width, x0, x1, d + 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free (tmp_buffer);
|
||||
@@ -629,7 +634,7 @@ fade_bytes (guchar *bytes,
|
||||
*/
|
||||
static guchar *
|
||||
flip_buffer (guchar *buffer,
|
||||
int width,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
/* Working in blocks increases cache efficiency, compared to reading
|
||||
@@ -641,33 +646,33 @@ flip_buffer (guchar *buffer,
|
||||
int i0, j0;
|
||||
|
||||
for (j0 = 0; j0 < height; j0 += BLOCK_SIZE)
|
||||
for (i0 = 0; i0 <= j0; i0 += BLOCK_SIZE)
|
||||
{
|
||||
int max_j = MIN(j0 + BLOCK_SIZE, height);
|
||||
int max_i = MIN(i0 + BLOCK_SIZE, width);
|
||||
int i, j;
|
||||
for (i0 = 0; i0 <= j0; i0 += BLOCK_SIZE)
|
||||
{
|
||||
int max_j = MIN(j0 + BLOCK_SIZE, height);
|
||||
int max_i = MIN(i0 + BLOCK_SIZE, width);
|
||||
int i, j;
|
||||
|
||||
if (i0 == j0)
|
||||
{
|
||||
for (j = j0; j < max_j; j++)
|
||||
for (i = i0; i < j; i++)
|
||||
{
|
||||
guchar tmp = buffer[j * width + i];
|
||||
buffer[j * width + i] = buffer[i * width + j];
|
||||
buffer[i * width + j] = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = j0; j < max_j; j++)
|
||||
for (i = i0; i < max_i; i++)
|
||||
{
|
||||
guchar tmp = buffer[j * width + i];
|
||||
buffer[j * width + i] = buffer[i * width + j];
|
||||
buffer[i * width + j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i0 == j0)
|
||||
{
|
||||
for (j = j0; j < max_j; j++)
|
||||
for (i = i0; i < j; i++)
|
||||
{
|
||||
guchar tmp = buffer[j * width + i];
|
||||
buffer[j * width + i] = buffer[i * width + j];
|
||||
buffer[i * width + j] = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = j0; j < max_j; j++)
|
||||
for (i = i0; i < max_i; i++)
|
||||
{
|
||||
guchar tmp = buffer[j * width + i];
|
||||
buffer[j * width + i] = buffer[i * width + j];
|
||||
buffer[i * width + j] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
@@ -678,15 +683,15 @@ flip_buffer (guchar *buffer,
|
||||
|
||||
for (i0 = 0; i0 < width; i0 += BLOCK_SIZE)
|
||||
for (j0 = 0; j0 < height; j0 += BLOCK_SIZE)
|
||||
{
|
||||
int max_j = MIN(j0 + BLOCK_SIZE, height);
|
||||
int max_i = MIN(i0 + BLOCK_SIZE, width);
|
||||
int i, j;
|
||||
{
|
||||
int max_j = MIN(j0 + BLOCK_SIZE, height);
|
||||
int max_i = MIN(i0 + BLOCK_SIZE, width);
|
||||
int i, j;
|
||||
|
||||
for (i = i0; i < max_i; i++)
|
||||
for (j = j0; j < max_j; j++)
|
||||
new_buffer[i * height + j] = buffer[j * width + i];
|
||||
}
|
||||
new_buffer[i * height + j] = buffer[j * width + i];
|
||||
}
|
||||
|
||||
g_free (buffer);
|
||||
|
||||
@@ -699,6 +704,8 @@ static void
|
||||
make_shadow (MetaShadow *shadow,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
int d = get_box_filter_size (shadow->key.radius);
|
||||
int spread = get_shadow_spread (shadow->key.radius);
|
||||
cairo_rectangle_int_t extents;
|
||||
@@ -758,7 +765,7 @@ make_shadow (MetaShadow *shadow,
|
||||
|
||||
cairo_region_get_rectangle (region, k, &rect);
|
||||
for (j = y_offset + rect.y; j < y_offset + rect.y + rect.height; j++)
|
||||
memset (buffer + buffer_width * j + x_offset + rect.x, 255, rect.width);
|
||||
memset (buffer + buffer_width * j + x_offset + rect.x, 255, rect.width);
|
||||
}
|
||||
|
||||
/* Step 2: swap rows and columns */
|
||||
@@ -788,15 +795,15 @@ make_shadow (MetaShadow *shadow,
|
||||
* in the case of top_fade >= 0. We also account for padding at the left for symmetry
|
||||
* though that doesn't currently occur.
|
||||
*/
|
||||
shadow->texture = cogl_texture_new_from_data (shadow->outer_border_left + extents.width + shadow->outer_border_right,
|
||||
shadow->outer_border_top + extents.height + shadow->outer_border_bottom,
|
||||
COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
buffer_width,
|
||||
(buffer +
|
||||
(y_offset - shadow->outer_border_top) * buffer_width +
|
||||
(x_offset - shadow->outer_border_left)));
|
||||
shadow->texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx,
|
||||
shadow->outer_border_left + extents.width + shadow->outer_border_right,
|
||||
shadow->outer_border_top + extents.height + shadow->outer_border_bottom,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
buffer_width,
|
||||
(buffer +
|
||||
(y_offset - shadow->outer_border_top) * buffer_width +
|
||||
(x_offset - shadow->outer_border_left)),
|
||||
NULL));
|
||||
|
||||
cairo_region_destroy (row_convolve_region);
|
||||
cairo_region_destroy (column_convolve_region);
|
||||
|
@@ -32,8 +32,6 @@
|
||||
ClutterActor *meta_shaped_texture_new (void);
|
||||
void meta_shaped_texture_set_texture (MetaShapedTexture *stex,
|
||||
CoglTexture *texture);
|
||||
gboolean meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *stex,
|
||||
cairo_rectangle_int_t *unobscured_bounds);
|
||||
gboolean meta_shaped_texture_is_obscured (MetaShapedTexture *self);
|
||||
|
||||
#endif
|
||||
|
@@ -65,6 +65,14 @@ G_DEFINE_TYPE_WITH_CODE (MetaShapedTexture, meta_shaped_texture, CLUTTER_TYPE_AC
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), META_TYPE_SHAPED_TEXTURE, \
|
||||
MetaShapedTexturePrivate))
|
||||
|
||||
enum {
|
||||
SIZE_CHANGED,
|
||||
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
struct _MetaShapedTexturePrivate
|
||||
{
|
||||
MetaTextureTower *paint_tower;
|
||||
@@ -97,6 +105,13 @@ meta_shaped_texture_class_init (MetaShapedTextureClass *klass)
|
||||
actor_class->paint = meta_shaped_texture_paint;
|
||||
actor_class->get_paint_volume = meta_shaped_texture_get_paint_volume;
|
||||
|
||||
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MetaShapedTexturePrivate));
|
||||
}
|
||||
|
||||
@@ -249,22 +264,20 @@ set_cogl_texture (MetaShapedTexture *stex,
|
||||
cogl_object_ref (cogl_tex);
|
||||
width = cogl_texture_get_width (COGL_TEXTURE (cogl_tex));
|
||||
height = cogl_texture_get_height (COGL_TEXTURE (cogl_tex));
|
||||
|
||||
if (width != priv->tex_width ||
|
||||
height != priv->tex_height)
|
||||
{
|
||||
priv->tex_width = width;
|
||||
priv->tex_height = height;
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* size changed to 0 going to an invalid handle */
|
||||
priv->tex_width = 0;
|
||||
priv->tex_height = 0;
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
if (priv->tex_width != width ||
|
||||
priv->tex_height != height)
|
||||
{
|
||||
priv->tex_width = width;
|
||||
priv->tex_height = height;
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (stex));
|
||||
g_signal_emit (stex, signals[SIZE_CHANGED], 0);
|
||||
}
|
||||
|
||||
/* NB: We don't queue a redraw of the actor here because we don't
|
||||
@@ -497,37 +510,63 @@ meta_shaped_texture_get_preferred_height (ClutterActor *self,
|
||||
*natural_height_p = priv->tex_height;
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
effective_unobscured_region (MetaShapedTexture *self)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv = self->priv;
|
||||
ClutterActor *parent = clutter_actor_get_parent (CLUTTER_ACTOR (self));
|
||||
|
||||
if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self)))
|
||||
return NULL;
|
||||
|
||||
while (parent && !META_IS_WINDOW_ACTOR (parent))
|
||||
parent = clutter_actor_get_parent (parent);
|
||||
|
||||
if (parent && clutter_actor_has_mapped_clones (parent))
|
||||
return NULL;
|
||||
|
||||
return priv->unobscured_region;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_unobscured_bounds (MetaShapedTexture *self,
|
||||
cairo_rectangle_int_t *unobscured_bounds)
|
||||
{
|
||||
cairo_region_t *unobscured_region = effective_unobscured_region (self);
|
||||
|
||||
if (unobscured_region)
|
||||
{
|
||||
cairo_region_get_extents (unobscured_region, unobscured_bounds);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_shaped_texture_get_paint_volume (ClutterActor *actor,
|
||||
ClutterPaintVolume *volume)
|
||||
{
|
||||
MetaShapedTexture *self = META_SHAPED_TEXTURE (actor);
|
||||
ClutterActorBox box;
|
||||
cairo_rectangle_int_t unobscured_bounds;
|
||||
|
||||
if (!clutter_paint_volume_set_from_allocation (volume, actor))
|
||||
if (!clutter_actor_has_allocation (actor))
|
||||
return FALSE;
|
||||
|
||||
if (meta_shaped_texture_get_unobscured_bounds (self, &unobscured_bounds))
|
||||
clutter_actor_get_allocation_box (actor, &box);
|
||||
|
||||
if (get_unobscured_bounds (self, &unobscured_bounds))
|
||||
{
|
||||
ClutterVertex origin;
|
||||
cairo_rectangle_int_t bounds;
|
||||
|
||||
/* I hate ClutterPaintVolume so much... */
|
||||
clutter_paint_volume_get_origin (volume, &origin);
|
||||
bounds.x = origin.x;
|
||||
bounds.y = origin.y;
|
||||
bounds.width = clutter_paint_volume_get_width (volume);
|
||||
bounds.height = clutter_paint_volume_get_height (volume);
|
||||
|
||||
gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
|
||||
|
||||
origin.x = bounds.x;
|
||||
origin.y = bounds.y;
|
||||
clutter_paint_volume_set_origin (volume, &origin);
|
||||
clutter_paint_volume_set_width (volume, bounds.width);
|
||||
clutter_paint_volume_set_height (volume, bounds.height);
|
||||
box.x1 = MAX (unobscured_bounds.x, box.x1);
|
||||
box.x2 = MIN (unobscured_bounds.x + unobscured_bounds.width, box.x2);
|
||||
box.y1 = MAX (unobscured_bounds.y, box.y1);
|
||||
box.y2 = MIN (unobscured_bounds.y + unobscured_bounds.height, box.y2);
|
||||
}
|
||||
box.x2 = MAX (box.x2, box.x1);
|
||||
box.y2 = MAX (box.y2, box.y1);
|
||||
|
||||
clutter_paint_volume_union_box (volume, &box);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -573,39 +612,6 @@ meta_shaped_texture_set_mask_texture (MetaShapedTexture *stex,
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stex));
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
effective_unobscured_region (MetaShapedTexture *self)
|
||||
{
|
||||
MetaShapedTexturePrivate *priv = self->priv;
|
||||
ClutterActor *parent = clutter_actor_get_parent (CLUTTER_ACTOR (self));
|
||||
|
||||
if (clutter_actor_has_mapped_clones (CLUTTER_ACTOR (self)))
|
||||
return NULL;
|
||||
|
||||
while (parent && !META_IS_WINDOW_ACTOR (parent))
|
||||
parent = clutter_actor_get_parent (parent);
|
||||
|
||||
if (parent && clutter_actor_has_mapped_clones (parent))
|
||||
return NULL;
|
||||
|
||||
return priv->unobscured_region;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_shaped_texture_get_unobscured_bounds (MetaShapedTexture *self,
|
||||
cairo_rectangle_int_t *unobscured_bounds)
|
||||
{
|
||||
cairo_region_t *unobscured_region = effective_unobscured_region (self);
|
||||
|
||||
if (unobscured_region)
|
||||
{
|
||||
cairo_region_get_extents (unobscured_region, unobscured_bounds);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_shaped_texture_is_obscured (MetaShapedTexture *self)
|
||||
{
|
||||
|
@@ -108,6 +108,62 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
get_output_scale (int winsys_id)
|
||||
{
|
||||
MetaMonitorManager *monitor_manager = meta_monitor_manager_get ();
|
||||
MetaOutput *outputs;
|
||||
guint n_outputs, i;
|
||||
int output_scale = 1;
|
||||
|
||||
outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
|
||||
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
if (outputs[i].winsys_id == winsys_id)
|
||||
{
|
||||
output_scale = outputs[i].scale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return output_scale;
|
||||
}
|
||||
|
||||
double
|
||||
meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor)
|
||||
{
|
||||
MetaSurfaceActorWaylandPrivate *priv = meta_surface_actor_wayland_get_instance_private (actor);
|
||||
MetaWaylandSurface *surface = priv->surface;
|
||||
MetaWindow *window = surface->window;
|
||||
int output_scale = 1;
|
||||
|
||||
while (surface)
|
||||
{
|
||||
if (surface->window)
|
||||
{
|
||||
window = surface->window;
|
||||
break;
|
||||
}
|
||||
surface = surface->sub.parent;
|
||||
}
|
||||
|
||||
/* XXX: We do not handle x11 clients yet */
|
||||
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
|
||||
output_scale = get_output_scale (window->monitor->winsys_id);
|
||||
|
||||
return (double)output_scale / (double)priv->surface->scale;
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_scale_texture (MetaSurfaceActorWayland *actor)
|
||||
{
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (actor));
|
||||
double output_scale = meta_surface_actor_wayland_get_scale (actor);
|
||||
|
||||
clutter_actor_set_scale (CLUTTER_ACTOR (stex), output_scale, output_scale);
|
||||
}
|
||||
|
||||
static MetaWindow *
|
||||
meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
|
||||
{
|
||||
@@ -116,6 +172,42 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
|
||||
return priv->surface->window;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_get_preferred_width (ClutterActor *self,
|
||||
gfloat for_height,
|
||||
gfloat *min_width_p,
|
||||
gfloat *natural_width_p)
|
||||
{
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
double scale = meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (self));
|
||||
|
||||
clutter_actor_get_preferred_width (CLUTTER_ACTOR (stex), for_height, min_width_p, natural_width_p);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p *= scale;
|
||||
|
||||
if (natural_width_p)
|
||||
*natural_width_p *= scale;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_get_preferred_height (ClutterActor *self,
|
||||
gfloat for_width,
|
||||
gfloat *min_height_p,
|
||||
gfloat *natural_height_p)
|
||||
{
|
||||
MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
double scale = meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (self));
|
||||
|
||||
clutter_actor_get_preferred_height (CLUTTER_ACTOR (stex), for_width, min_height_p, natural_height_p);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p *= scale;
|
||||
|
||||
if (natural_height_p)
|
||||
*natural_height_p *= scale;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_wayland_dispose (GObject *object)
|
||||
{
|
||||
@@ -130,8 +222,12 @@ static void
|
||||
meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
|
||||
{
|
||||
MetaSurfaceActorClass *surface_actor_class = META_SURFACE_ACTOR_CLASS (klass);
|
||||
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
actor_class->get_preferred_width = meta_surface_actor_wayland_get_preferred_width;
|
||||
actor_class->get_preferred_height = meta_surface_actor_wayland_get_preferred_height;
|
||||
|
||||
surface_actor_class->process_damage = meta_surface_actor_wayland_process_damage;
|
||||
surface_actor_class->pre_paint = meta_surface_actor_wayland_pre_paint;
|
||||
surface_actor_class->is_visible = meta_surface_actor_wayland_is_visible;
|
||||
|
@@ -61,6 +61,9 @@ MetaWaylandSurface * meta_surface_actor_wayland_get_surface (MetaSurfaceActorWay
|
||||
void meta_surface_actor_wayland_set_buffer (MetaSurfaceActorWayland *self,
|
||||
MetaWaylandBuffer *buffer);
|
||||
|
||||
double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
|
||||
|
||||
void meta_surface_actor_wayland_scale_texture (MetaSurfaceActorWayland *actor);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __META_SURFACE_ACTOR_WAYLAND_H__ */
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include "window-private.h"
|
||||
#include "meta-shaped-texture-private.h"
|
||||
#include "meta-cullable.h"
|
||||
#include "x11/window-x11.h"
|
||||
|
||||
struct _MetaSurfaceActorX11Private
|
||||
{
|
||||
@@ -143,7 +144,7 @@ update_pixmap (MetaSurfaceActorX11 *self)
|
||||
if (priv->pixmap == None)
|
||||
{
|
||||
Pixmap new_pixmap;
|
||||
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
|
||||
Window xwindow = meta_window_x11_get_toplevel_xwindow (priv->window);
|
||||
|
||||
meta_error_trap_push (display);
|
||||
new_pixmap = XCompositeNameWindowPixmap (xdisplay, xwindow);
|
||||
@@ -238,26 +239,6 @@ meta_surface_actor_x11_pre_paint (MetaSurfaceActor *actor)
|
||||
XDamageSubtract (xdisplay, priv->damage, None, None);
|
||||
meta_error_trap_pop (display);
|
||||
|
||||
/* We need to make sure that any X drawing that happens before the
|
||||
* XDamageSubtract() above is visible to subsequent GL rendering;
|
||||
* the only standardized way to do this is EXT_x11_sync_object,
|
||||
* which isn't yet widely available. For now, we count on details
|
||||
* of Xorg and the open source drivers, and hope for the best
|
||||
* otherwise.
|
||||
*
|
||||
* Xorg and open source driver specifics:
|
||||
*
|
||||
* The X server makes sure to flush drawing to the kernel before
|
||||
* sending out damage events, but since we use DamageReportBoundingBox
|
||||
* there may be drawing between the last damage event and the
|
||||
* XDamageSubtract() that needs to be flushed as well.
|
||||
*
|
||||
* Xorg always makes sure that drawing is flushed to the kernel
|
||||
* before writing events or responses to the client, so any round trip
|
||||
* request at this point is sufficient to flush the GLX buffers.
|
||||
*/
|
||||
XSync (xdisplay, False);
|
||||
|
||||
priv->received_damage = FALSE;
|
||||
}
|
||||
|
||||
@@ -312,7 +293,7 @@ sync_unredirected (MetaSurfaceActorX11 *self)
|
||||
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
|
||||
MetaDisplay *display = priv->display;
|
||||
Display *xdisplay = meta_display_get_xdisplay (display);
|
||||
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
|
||||
Window xwindow = meta_window_x11_get_toplevel_xwindow (priv->window);
|
||||
|
||||
meta_error_trap_push (display);
|
||||
|
||||
@@ -404,7 +385,7 @@ create_damage (MetaSurfaceActorX11 *self)
|
||||
{
|
||||
MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
|
||||
Display *xdisplay = meta_display_get_xdisplay (priv->display);
|
||||
Window xwindow = meta_window_get_toplevel_xwindow (priv->window);
|
||||
Window xwindow = meta_window_x11_get_toplevel_xwindow (priv->window);
|
||||
|
||||
priv->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox);
|
||||
}
|
||||
|
@@ -36,20 +36,13 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MetaSurfaceActor, meta_surface_actor, CLUTTER_
|
||||
|
||||
enum {
|
||||
REPAINT_SCHEDULED,
|
||||
SIZE_CHANGED,
|
||||
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
gboolean
|
||||
meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
|
||||
cairo_rectangle_int_t *unobscured_bounds)
|
||||
{
|
||||
MetaSurfaceActorPrivate *priv = self->priv;
|
||||
return meta_shaped_texture_get_unobscured_bounds (priv->texture, unobscured_bounds);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_pick (ClutterActor *actor,
|
||||
const ClutterColor *color)
|
||||
@@ -128,6 +121,13 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[SIZE_CHANGED] = g_signal_new ("size-changed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (MetaSurfaceActorPrivate));
|
||||
}
|
||||
|
||||
@@ -152,6 +152,14 @@ cullable_iface_init (MetaCullableInterface *iface)
|
||||
iface->reset_culling = meta_surface_actor_reset_culling;
|
||||
}
|
||||
|
||||
static void
|
||||
texture_size_changed (MetaShapedTexture *texture,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaSurfaceActor *actor = META_SURFACE_ACTOR (user_data);
|
||||
g_signal_emit (actor, signals[SIZE_CHANGED], 0);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_actor_init (MetaSurfaceActor *self)
|
||||
{
|
||||
@@ -162,6 +170,8 @@ meta_surface_actor_init (MetaSurfaceActor *self)
|
||||
MetaSurfaceActorPrivate);
|
||||
|
||||
priv->texture = META_SHAPED_TEXTURE (meta_shaped_texture_new ());
|
||||
g_signal_connect_object (priv->texture, "size-changed",
|
||||
G_CALLBACK (texture_size_changed), self, 0);
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->texture));
|
||||
}
|
||||
|
||||
|
@@ -55,8 +55,6 @@ MetaShapedTexture *meta_surface_actor_get_texture (MetaSurfaceActor *self);
|
||||
MetaWindow *meta_surface_actor_get_window (MetaSurfaceActor *self);
|
||||
|
||||
gboolean meta_surface_actor_is_obscured (MetaSurfaceActor *self);
|
||||
gboolean meta_surface_actor_get_unobscured_bounds (MetaSurfaceActor *self,
|
||||
cairo_rectangle_int_t *unobscured_bounds);
|
||||
|
||||
void meta_surface_actor_set_input_region (MetaSurfaceActor *self,
|
||||
cairo_region_t *region);
|
||||
|
@@ -378,8 +378,8 @@ texture_tower_create_texture (MetaTextureTower *tower,
|
||||
}
|
||||
|
||||
static void
|
||||
texture_tower_revalidate_fbo (MetaTextureTower *tower,
|
||||
int level)
|
||||
texture_tower_revalidate (MetaTextureTower *tower,
|
||||
int level)
|
||||
{
|
||||
CoglTexture *source_texture = tower->textures[level - 1];
|
||||
int source_texture_width = cogl_texture_get_width (source_texture);
|
||||
@@ -425,13 +425,9 @@ texture_tower_revalidate_fbo (MetaTextureTower *tower,
|
||||
(2. * invalid->y2) / source_texture_height);
|
||||
|
||||
cogl_object_unref (pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
texture_tower_revalidate (MetaTextureTower *tower,
|
||||
int level)
|
||||
{
|
||||
texture_tower_revalidate_fbo (tower, level);
|
||||
tower->invalid[level].x1 = tower->invalid[level].x2 = 0;
|
||||
tower->invalid[level].y1 = tower->invalid[level].y2 = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -51,8 +51,7 @@ void meta_window_actor_update_shape (MetaWindowActor *self);
|
||||
void meta_window_actor_update_opacity (MetaWindowActor *self);
|
||||
void meta_window_actor_mapped (MetaWindowActor *self);
|
||||
void meta_window_actor_unmapped (MetaWindowActor *self);
|
||||
void meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
||||
gboolean updates_frozen);
|
||||
void meta_window_actor_sync_updates_frozen (MetaWindowActor *self);
|
||||
void meta_window_actor_queue_frame_drawn (MetaWindowActor *self,
|
||||
gboolean no_delay_frame);
|
||||
|
||||
|
@@ -33,8 +33,18 @@
|
||||
#include "meta-surface-actor.h"
|
||||
#include "meta-surface-actor-x11.h"
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
#include "meta-surface-actor-wayland.h"
|
||||
#endif
|
||||
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
|
||||
typedef enum {
|
||||
INITIALLY_FROZEN,
|
||||
DRAWING_FIRST_FRAME,
|
||||
EMITTED_FIRST_FRAME
|
||||
} FirstFrameState;
|
||||
|
||||
struct _MetaWindowActorPrivate
|
||||
{
|
||||
MetaWindow *window;
|
||||
@@ -69,7 +79,7 @@ struct _MetaWindowActorPrivate
|
||||
gint64 frame_drawn_time;
|
||||
|
||||
guint repaint_scheduled_id;
|
||||
guint allocation_changed_id;
|
||||
guint size_changed_id;
|
||||
|
||||
/*
|
||||
* These need to be counters rather than flags, since more plugins
|
||||
@@ -77,6 +87,7 @@ struct _MetaWindowActorPrivate
|
||||
* might be dubious, but we have to at least handle it correctly.
|
||||
*/
|
||||
gint minimize_in_progress;
|
||||
gint unminimize_in_progress;
|
||||
gint maximize_in_progress;
|
||||
gint unmaximize_in_progress;
|
||||
gint map_in_progress;
|
||||
@@ -103,6 +114,7 @@ struct _MetaWindowActorPrivate
|
||||
guint no_shadow : 1;
|
||||
|
||||
guint updates_frozen : 1;
|
||||
guint first_frame_state : 2; /* FirstFrameState */
|
||||
};
|
||||
|
||||
typedef struct _FrameData FrameData;
|
||||
@@ -114,6 +126,14 @@ struct _FrameData
|
||||
gint64 frame_drawn_time;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
FIRST_FRAME,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_META_WINDOW = 1,
|
||||
@@ -180,6 +200,31 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
||||
actor_class->paint = meta_window_actor_paint;
|
||||
actor_class->get_paint_volume = meta_window_actor_get_paint_volume;
|
||||
|
||||
/**
|
||||
* MetaWindowActor::first-frame:
|
||||
* @actor: the #MetaWindowActor instance
|
||||
*
|
||||
* The ::first-frame signal will be emitted the first time a frame
|
||||
* of window contents has been drawn by the application and Mutter
|
||||
* has had the chance to drawn that frame to the screen. If the
|
||||
* window starts off initially hidden, obscured, or on on a
|
||||
* different workspace, the ::first-frame signal will be emitted
|
||||
* even though the user doesn't see the contents.
|
||||
*
|
||||
* MetaDisplay::window-created is a good place to connect to this
|
||||
* signal - at that point, the MetaWindowActor for the window
|
||||
* exists, but the window has reliably not yet been drawn.
|
||||
* Connecting to an existing window that has already been drawn to
|
||||
* the screen is not useful.
|
||||
*/
|
||||
signals[FIRST_FRAME] =
|
||||
g_signal_new ("first-frame",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
pspec = g_param_spec_object ("meta-window",
|
||||
"MetaWindow",
|
||||
"The displayed MetaWindow",
|
||||
@@ -231,12 +276,11 @@ window_appears_focused_notify (MetaWindow *mw,
|
||||
}
|
||||
|
||||
static void
|
||||
surface_allocation_changed_notify (ClutterActor *actor,
|
||||
const ClutterActorBox *allocation,
|
||||
ClutterAllocationFlags flags,
|
||||
MetaWindowActor *self)
|
||||
surface_size_changed (MetaSurfaceActor *actor,
|
||||
gpointer user_data)
|
||||
{
|
||||
meta_window_actor_sync_actor_geometry (self, FALSE);
|
||||
MetaWindowActor *self = META_WINDOW_ACTOR (user_data);
|
||||
|
||||
meta_window_actor_update_shape (self);
|
||||
}
|
||||
|
||||
@@ -305,6 +349,9 @@ meta_window_actor_thaw (MetaWindowActor *self)
|
||||
if (priv->freeze_count > 0)
|
||||
return;
|
||||
|
||||
if (priv->first_frame_state == INITIALLY_FROZEN)
|
||||
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
||||
|
||||
if (priv->surface)
|
||||
meta_surface_actor_set_frozen (priv->surface, FALSE);
|
||||
|
||||
@@ -325,9 +372,8 @@ set_surface (MetaWindowActor *self,
|
||||
if (priv->surface)
|
||||
{
|
||||
g_signal_handler_disconnect (priv->surface, priv->repaint_scheduled_id);
|
||||
g_signal_handler_disconnect (priv->surface, priv->size_changed_id);
|
||||
priv->repaint_scheduled_id = 0;
|
||||
g_signal_handler_disconnect (priv->surface, priv->allocation_changed_id);
|
||||
priv->allocation_changed_id = 0;
|
||||
clutter_actor_remove_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
||||
g_object_unref (priv->surface);
|
||||
}
|
||||
@@ -339,14 +385,17 @@ set_surface (MetaWindowActor *self,
|
||||
g_object_ref_sink (priv->surface);
|
||||
priv->repaint_scheduled_id = g_signal_connect (priv->surface, "repaint-scheduled",
|
||||
G_CALLBACK (surface_repaint_scheduled), self);
|
||||
priv->allocation_changed_id = g_signal_connect (priv->surface, "allocation-changed",
|
||||
G_CALLBACK (surface_allocation_changed_notify), self);
|
||||
priv->size_changed_id = g_signal_connect (priv->surface, "size-changed",
|
||||
G_CALLBACK (surface_size_changed), self);
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (self), CLUTTER_ACTOR (priv->surface));
|
||||
|
||||
/* If the previous surface actor was frozen, start out
|
||||
* frozen as well... */
|
||||
meta_surface_actor_set_frozen (priv->surface, priv->freeze_count > 0);
|
||||
|
||||
if (!is_frozen (self) && priv->first_frame_state == INITIALLY_FROZEN)
|
||||
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
||||
|
||||
meta_window_actor_update_shape (self);
|
||||
}
|
||||
}
|
||||
@@ -549,6 +598,18 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self,
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
|
||||
cairo_region_get_extents (priv->shape_region, bounds);
|
||||
|
||||
#ifdef HAVE_WAYLAND
|
||||
if (META_IS_SURFACE_ACTOR_WAYLAND (priv->surface))
|
||||
{
|
||||
double scale = priv->surface ?
|
||||
meta_surface_actor_wayland_get_scale (META_SURFACE_ACTOR_WAYLAND (priv->surface)) : 1.;
|
||||
bounds->x *= scale;
|
||||
bounds->y *= scale;
|
||||
bounds->width *= scale;
|
||||
bounds->height *= scale;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -656,25 +717,16 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
|
||||
{
|
||||
MetaWindowActor *self = META_WINDOW_ACTOR (actor);
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
cairo_rectangle_int_t unobscured_bounds, bounds;
|
||||
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
||||
ClutterVertex origin;
|
||||
|
||||
/* The paint volume is computed before paint functions are called
|
||||
* so our bounds might not be updated yet. Force an update. */
|
||||
meta_window_actor_handle_updates (self);
|
||||
|
||||
meta_window_actor_get_shape_bounds (self, &bounds);
|
||||
|
||||
if (priv->surface)
|
||||
{
|
||||
if (meta_surface_actor_get_unobscured_bounds (priv->surface, &unobscured_bounds))
|
||||
gdk_rectangle_intersect (&bounds, &unobscured_bounds, &bounds);
|
||||
}
|
||||
|
||||
if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
|
||||
{
|
||||
cairo_rectangle_int_t shadow_bounds;
|
||||
ClutterActorBox shadow_box;
|
||||
|
||||
/* We could compute an full clip region as we do for the window
|
||||
* texture, but the shadow is relatively cheap to draw, and
|
||||
@@ -684,16 +736,24 @@ meta_window_actor_get_paint_volume (ClutterActor *actor,
|
||||
*/
|
||||
|
||||
meta_window_actor_get_shadow_bounds (self, appears_focused, &shadow_bounds);
|
||||
gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
|
||||
shadow_box.x1 = shadow_bounds.x;
|
||||
shadow_box.x2 = shadow_bounds.x + shadow_bounds.width;
|
||||
shadow_box.y1 = shadow_bounds.y;
|
||||
shadow_box.y2 = shadow_bounds.y + shadow_bounds.height;
|
||||
|
||||
clutter_paint_volume_union_box (volume, &shadow_box);
|
||||
}
|
||||
|
||||
origin.x = bounds.x;
|
||||
origin.y = bounds.y;
|
||||
origin.z = 0.0f;
|
||||
clutter_paint_volume_set_origin (volume, &origin);
|
||||
if (priv->surface)
|
||||
{
|
||||
const ClutterPaintVolume *child_volume;
|
||||
|
||||
clutter_paint_volume_set_width (volume, bounds.width);
|
||||
clutter_paint_volume_set_height (volume, bounds.height);
|
||||
child_volume = clutter_actor_get_transformed_paint_volume (CLUTTER_ACTOR (priv->surface), actor);
|
||||
if (!child_volume)
|
||||
return FALSE;
|
||||
|
||||
clutter_paint_volume_union (volume, child_volume);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -735,9 +795,11 @@ meta_window_actor_has_shadow (MetaWindowActor *self)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Add shadows to override redirect windows (e.g., Gtk menus).
|
||||
* Add shadows to override redirect windows on X11 unless the toolkit
|
||||
* indicates that it is handling shadows itself (e.g., Gtk menus).
|
||||
*/
|
||||
if (priv->window->override_redirect)
|
||||
if (priv->window->override_redirect &&
|
||||
!priv->window->has_custom_frame_extents)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
@@ -840,7 +902,7 @@ queue_send_frame_messages_timeout (MetaWindowActor *self)
|
||||
outputs = meta_monitor_manager_get_outputs (monitor_manager, &n_outputs);
|
||||
for (i = 0; i < n_outputs; i++)
|
||||
{
|
||||
if (outputs[i].output_id == window->monitor->output_id && outputs[i].crtc)
|
||||
if (outputs[i].winsys_id == window->monitor->winsys_id && outputs[i].crtc)
|
||||
{
|
||||
refresh_rate = outputs[i].crtc->current_mode->refresh_rate;
|
||||
break;
|
||||
@@ -949,6 +1011,9 @@ start_simple_effect (MetaWindowActor *self,
|
||||
case META_PLUGIN_MINIMIZE:
|
||||
counter = &priv->minimize_in_progress;
|
||||
break;
|
||||
case META_PLUGIN_UNMINIMIZE:
|
||||
counter = &priv->unminimize_in_progress;
|
||||
break;
|
||||
case META_PLUGIN_MAP:
|
||||
counter = &priv->map_in_progress;
|
||||
break;
|
||||
@@ -1019,6 +1084,16 @@ meta_window_actor_effect_completed (MetaWindowActor *self,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case META_PLUGIN_UNMINIMIZE:
|
||||
{
|
||||
priv->unminimize_in_progress--;
|
||||
if (priv->unminimize_in_progress < 0)
|
||||
{
|
||||
g_warning ("Error in unminimize accounting.");
|
||||
priv->unminimize_in_progress = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case META_PLUGIN_MAP:
|
||||
/*
|
||||
* Make sure that the actor is at the correct place in case
|
||||
@@ -1139,7 +1214,7 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaRectangle window_rect;
|
||||
|
||||
meta_window_get_input_rect (priv->window, &window_rect);
|
||||
meta_window_get_buffer_rect (priv->window, &window_rect);
|
||||
|
||||
/* When running as a Wayland compositor we catch size changes when new
|
||||
* buffers are attached */
|
||||
@@ -1184,8 +1259,7 @@ meta_window_actor_show (MetaWindowActor *self,
|
||||
event = META_PLUGIN_MAP;
|
||||
break;
|
||||
case META_COMP_EFFECT_UNMINIMIZE:
|
||||
/* FIXME: should have META_PLUGIN_UNMINIMIZE */
|
||||
event = META_PLUGIN_MAP;
|
||||
event = META_PLUGIN_UNMINIMIZE;
|
||||
break;
|
||||
case META_COMP_EFFECT_NONE:
|
||||
break;
|
||||
@@ -1313,7 +1387,12 @@ meta_window_actor_new (MetaWindow *window)
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (priv->window));
|
||||
meta_window_actor_sync_updates_frozen (self);
|
||||
|
||||
if (is_frozen (self))
|
||||
priv->first_frame_state = INITIALLY_FROZEN;
|
||||
else
|
||||
priv->first_frame_state = DRAWING_FIRST_FRAME;
|
||||
|
||||
/* If a window doesn't start off with updates frozen, we should
|
||||
* we should send a _NET_WM_FRAME_DRAWN immediately after the first drawn.
|
||||
@@ -1583,6 +1662,8 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
cairo_rectangle_int_t *client_area,
|
||||
cairo_region_t *shape_region)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *ctx = clutter_backend_get_cogl_context (backend);
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
guchar *mask_data;
|
||||
guint tex_width, tex_height;
|
||||
@@ -1645,10 +1726,7 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
|
||||
if (meta_texture_rectangle_check (paint_tex))
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
CoglContext *context = clutter_backend_get_cogl_context (backend);
|
||||
|
||||
mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (context, tex_width, tex_height));
|
||||
mask_texture = COGL_TEXTURE (cogl_texture_rectangle_new_with_size (ctx, tex_width, tex_height));
|
||||
cogl_texture_set_components (mask_texture, COGL_TEXTURE_COMPONENTS_A);
|
||||
cogl_texture_set_region (mask_texture,
|
||||
0, 0, /* src_x/y */
|
||||
@@ -1660,15 +1738,9 @@ build_and_scan_frame_mask (MetaWindowActor *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Note: we don't allow slicing for this texture because we
|
||||
* need to use it with multi-texturing which doesn't support
|
||||
* sliced textures */
|
||||
mask_texture = cogl_texture_new_from_data (tex_width, tex_height,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
stride,
|
||||
mask_data);
|
||||
mask_texture = COGL_TEXTURE (cogl_texture_2d_new_from_data (ctx, tex_width, tex_height,
|
||||
COGL_PIXEL_FORMAT_A_8,
|
||||
stride, mask_data, NULL));
|
||||
}
|
||||
|
||||
meta_shaped_texture_set_mask_texture (stex, mask_texture);
|
||||
@@ -1897,6 +1969,12 @@ meta_window_actor_post_paint (MetaWindowActor *self)
|
||||
do_send_frame_drawn (self, priv->frames->data);
|
||||
priv->needs_frame_drawn = FALSE;
|
||||
}
|
||||
|
||||
if (priv->first_frame_state == DRAWING_FIRST_FRAME)
|
||||
{
|
||||
priv->first_frame_state = EMITTED_FIRST_FRAME;
|
||||
g_signal_emit (self, signals[FIRST_FRAME], 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2009,7 +2087,7 @@ meta_window_actor_update_opacity (MetaWindowActor *self)
|
||||
clutter_actor_set_opacity (CLUTTER_ACTOR (priv->surface), window->opacity);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
||||
gboolean updates_frozen)
|
||||
{
|
||||
@@ -2026,3 +2104,12 @@ meta_window_actor_set_updates_frozen (MetaWindowActor *self,
|
||||
meta_window_actor_thaw (self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_sync_updates_frozen (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv = self->priv;
|
||||
MetaWindow *window = priv->window;
|
||||
|
||||
meta_window_actor_set_updates_frozen (self, meta_window_updates_are_frozen (window));
|
||||
}
|
||||
|
@@ -1,12 +1,22 @@
|
||||
|
||||
pkglibdir=@MUTTER_PLUGIN_DIR@
|
||||
pkglibdir = $(MUTTER_PLUGIN_DIR)
|
||||
|
||||
INCLUDES=@MUTTER_CFLAGS@ -I $(top_srcdir)/src -DMUTTER_LIBEXECDIR=\"$(libexecdir)\" -DHOST_ALIAS=\"@HOST_ALIAS@\" -DMUTTER_LOCALEDIR=\"$(prefix)/@DATADIRNAME@/locale\" -DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" -DMUTTER_DATADIR=\"$(datadir)\" -DG_LOG_DOMAIN=\"mutter\" -DSN_API_NOT_YET_FROZEN=1 -DMUTTER_MAJOR_VERSION=$(MUTTER_MAJOR_VERSION) -DMUTTER_MINOR_VERSION=$(MUTTER_MINOR_VERSION) -DMUTTER_MICRO_VERSION=$(MUTTER_MICRO_VERSION) -DMUTTER_PLUGIN_API_VERSION=$(MUTTER_PLUGIN_API_VERSION) -DMUTTER_PLUGIN_DIR=\"@MUTTER_PLUGIN_DIR@\"
|
||||
AM_CPPFLAGS = \
|
||||
$(MUTTER_CFLAGS) \
|
||||
-I$(top_builddir)/src \
|
||||
-I$(top_srcdir)/src \
|
||||
-DMUTTER_LIBEXECDIR=\"$(libexecdir)\" \
|
||||
-DMUTTER_LOCALEDIR=\"$(localedir)\" \
|
||||
-DMUTTER_PKGDATADIR=\"$(pkgdatadir)\" \
|
||||
-DMUTTER_DATADIR=\"$(datadir)\" \
|
||||
-DG_LOG_DOMAIN=\"mutter\" \
|
||||
-DSN_API_NOT_YET_FROZEN=1 \
|
||||
-DMUTTER_PLUGIN_DIR=\"$(MUTTER_PLUGIN_DIR)\"
|
||||
|
||||
default_la_CFLAGS = -fPIC
|
||||
default_la_SOURCES = default.c
|
||||
default_la_LDFLAGS = -module -avoid-version -no-undefined
|
||||
default_la_LIBADD = @CLUTTER_LIBS@
|
||||
default_la_LIBADD = $(CLUTTER_LIBS)
|
||||
|
||||
pkglib_LTLIBRARIES = default.la
|
||||
|
||||
|
@@ -121,7 +121,7 @@ meta_region_builder_finish (MetaRegionBuilder *builder)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* MetaRegionIterator */
|
||||
|
||||
@@ -171,7 +171,7 @@ meta_region_iterator_next (MetaRegionIterator *iter)
|
||||
iter->line_end = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_expanded_rect (MetaRegionBuilder *builder,
|
||||
int x,
|
||||
|
148
src/core/bell.c
148
src/core/bell.c
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter visual bell */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2002 Sun Microsystems Inc.
|
||||
* Copyright (C) 2005, 2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -15,7 +15,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -69,12 +69,9 @@
|
||||
*
|
||||
* If the configure script found we had no XKB, this does not exist.
|
||||
*/
|
||||
#ifdef HAVE_XKB
|
||||
static void
|
||||
bell_flash_fullscreen (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
bell_flash_fullscreen (MetaDisplay *display)
|
||||
{
|
||||
g_assert (xkb_ev->xkb_type == XkbBellNotify);
|
||||
meta_compositor_flash_screen (display->compositor, display->screen);
|
||||
}
|
||||
|
||||
@@ -96,7 +93,7 @@ bell_flash_fullscreen (MetaDisplay *display,
|
||||
* Bug: This is the parallel to bell_flash_window_frame(), so it should
|
||||
* really be called meta_bell_unflash_window_frame().
|
||||
*/
|
||||
static gboolean
|
||||
static gboolean
|
||||
bell_unflash_frame (gpointer data)
|
||||
{
|
||||
MetaFrame *frame = (MetaFrame *) data;
|
||||
@@ -139,30 +136,17 @@ bell_flash_window_frame (MetaWindow *window)
|
||||
* @display: The display the bell event came in on
|
||||
* @xkb_ev: The bell event we just received
|
||||
*
|
||||
* Flashes the frame of the focussed window. If there is no focussed window,
|
||||
* Flashes the frame of the focused window. If there is no focused window,
|
||||
* flashes the screen.
|
||||
*/
|
||||
static void
|
||||
bell_flash_frame (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
bell_flash_frame (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent *) xkb_ev;
|
||||
MetaWindow *window;
|
||||
|
||||
g_assert (xkb_ev->xkb_type == XkbBellNotify);
|
||||
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
|
||||
if (!window && (display->focus_window))
|
||||
{
|
||||
window = display->focus_window;
|
||||
}
|
||||
if (window && window->frame)
|
||||
{
|
||||
bell_flash_window_frame (window);
|
||||
}
|
||||
else /* revert to fullscreen flash if there's no focussed window */
|
||||
{
|
||||
bell_flash_fullscreen (display, xkb_ev);
|
||||
}
|
||||
bell_flash_window_frame (window);
|
||||
else
|
||||
bell_flash_fullscreen (display);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,69 +156,73 @@ bell_flash_frame (MetaDisplay *display,
|
||||
*
|
||||
* Gives the user some kind of visual bell substitute, in response to a
|
||||
* bell event. What this is depends on the "visual bell type" pref.
|
||||
*
|
||||
* If the configure script found we had no XKB, this does not exist.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Bug: This should be merged with meta_bell_notify().
|
||||
*/
|
||||
static void
|
||||
bell_visual_notify (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
bell_visual_notify (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
switch (meta_prefs_get_visual_bell_type ())
|
||||
switch (meta_prefs_get_visual_bell_type ())
|
||||
{
|
||||
case G_DESKTOP_VISUAL_BELL_FULLSCREEN_FLASH:
|
||||
bell_flash_fullscreen (display, xkb_ev);
|
||||
bell_flash_fullscreen (display);
|
||||
break;
|
||||
case G_DESKTOP_VISUAL_BELL_FRAME_FLASH:
|
||||
bell_flash_frame (display, xkb_ev); /* does nothing yet */
|
||||
bell_flash_frame (display, window);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
bell_audible_notify (MetaDisplay *display,
|
||||
MetaWindow *window)
|
||||
{
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
ca_proplist *p;
|
||||
int res;
|
||||
|
||||
ca_proplist_create (&p);
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_ID, "bell-window-system");
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event"));
|
||||
ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent");
|
||||
|
||||
if (window)
|
||||
{
|
||||
ca_proplist_sets (p, CA_PROP_WINDOW_NAME, window->title);
|
||||
ca_proplist_setf (p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long)window->xwindow);
|
||||
ca_proplist_sets (p, CA_PROP_APPLICATION_NAME, window->res_name);
|
||||
ca_proplist_setf (p, CA_PROP_APPLICATION_PROCESS_ID, "%d", window->net_wm_pid);
|
||||
}
|
||||
|
||||
res = ca_context_play_full (ca_gtk_context_get (), 1, p, NULL, NULL);
|
||||
|
||||
ca_proplist_destroy (p);
|
||||
|
||||
return res == CA_SUCCESS || res == CA_ERROR_DISABLED;
|
||||
#endif /* HAVE_LIBCANBERRA */
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_bell_notify (MetaDisplay *display,
|
||||
meta_bell_notify (MetaDisplay *display,
|
||||
XkbAnyEvent *xkb_ev)
|
||||
{
|
||||
MetaWindow *window;
|
||||
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev;
|
||||
|
||||
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
|
||||
if (!window && display->focus_window && display->focus_window->frame)
|
||||
window = display->focus_window;
|
||||
|
||||
/* flash something */
|
||||
if (meta_prefs_get_visual_bell ())
|
||||
bell_visual_notify (display, xkb_ev);
|
||||
bell_visual_notify (display, window);
|
||||
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
if (meta_prefs_bell_is_audible ())
|
||||
{
|
||||
ca_proplist *p;
|
||||
XkbBellNotifyEvent *xkb_bell_event = (XkbBellNotifyEvent*) xkb_ev;
|
||||
MetaWindow *window;
|
||||
int res;
|
||||
|
||||
ca_proplist_create (&p);
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_ID, "bell-window-system");
|
||||
ca_proplist_sets (p, CA_PROP_EVENT_DESCRIPTION, _("Bell event"));
|
||||
ca_proplist_sets (p, CA_PROP_CANBERRA_CACHE_CONTROL, "permanent");
|
||||
|
||||
window = meta_display_lookup_x_window (display, xkb_bell_event->window);
|
||||
if (!window && (display->focus_window) && (display->focus_window->frame))
|
||||
window = display->focus_window;
|
||||
|
||||
if (window)
|
||||
if (!bell_audible_notify (display, window))
|
||||
{
|
||||
ca_proplist_sets (p, CA_PROP_WINDOW_NAME, window->title);
|
||||
ca_proplist_setf (p, CA_PROP_WINDOW_X11_XID, "%lu", (unsigned long)window->xwindow);
|
||||
ca_proplist_sets (p, CA_PROP_APPLICATION_NAME, window->res_name);
|
||||
ca_proplist_setf (p, CA_PROP_APPLICATION_PROCESS_ID, "%d", window->net_wm_pid);
|
||||
}
|
||||
|
||||
/* First, we try to play a real sound ... */
|
||||
res = ca_context_play_full (ca_gtk_context_get (), 1, p, NULL, NULL);
|
||||
|
||||
ca_proplist_destroy (p);
|
||||
|
||||
if (res != CA_SUCCESS && res != CA_ERROR_DISABLED)
|
||||
{
|
||||
/* ...and in case that failed we use the classic X11 bell. */
|
||||
/* Force a classic bell if the libcanberra bell failed. */
|
||||
XkbForceDeviceBell (display->xdisplay,
|
||||
xkb_bell_event->device,
|
||||
xkb_bell_event->bell_class,
|
||||
@@ -242,14 +230,11 @@ meta_bell_notify (MetaDisplay *display,
|
||||
xkb_bell_event->percent);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_LIBCANBERRA */
|
||||
}
|
||||
#endif /* HAVE_XKB */
|
||||
|
||||
void
|
||||
meta_bell_set_audible (MetaDisplay *display, gboolean audible)
|
||||
{
|
||||
#ifdef HAVE_XKB
|
||||
#ifdef HAVE_LIBCANBERRA
|
||||
/* When we are playing sounds using libcanberra support, we handle the
|
||||
* bell whether its an audible bell or a visible bell */
|
||||
@@ -262,28 +247,26 @@ meta_bell_set_audible (MetaDisplay *display, gboolean audible)
|
||||
XkbUseCoreKbd,
|
||||
XkbAudibleBellMask,
|
||||
enable_system_bell ? XkbAudibleBellMask : 0);
|
||||
#endif /* HAVE_XKB */
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_bell_init (MetaDisplay *display)
|
||||
{
|
||||
#ifdef HAVE_XKB
|
||||
int xkb_base_error_type, xkb_opcode;
|
||||
|
||||
if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
|
||||
&display->xkb_base_event_type,
|
||||
&xkb_base_error_type,
|
||||
if (!XkbQueryExtension (display->xdisplay, &xkb_opcode,
|
||||
&display->xkb_base_event_type,
|
||||
&xkb_base_error_type,
|
||||
NULL, NULL))
|
||||
{
|
||||
display->xkb_base_event_type = -1;
|
||||
g_message ("could not find XKB extension.");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
unsigned int mask = XkbBellNotifyMask;
|
||||
gboolean visual_bell_auto_reset = FALSE;
|
||||
gboolean visual_bell_auto_reset = FALSE;
|
||||
/* TRUE if and when non-broken version is available */
|
||||
XkbSelectEvents (display->xdisplay,
|
||||
XkbUseCoreKbd,
|
||||
@@ -298,20 +281,17 @@ meta_bell_init (MetaDisplay *display)
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_bell_shutdown (MetaDisplay *display)
|
||||
{
|
||||
#ifdef HAVE_XKB
|
||||
/* TODO: persist initial bell state in display, reset here */
|
||||
XkbChangeEnabledControls (display->xdisplay,
|
||||
XkbUseCoreKbd,
|
||||
XkbAudibleBellMask,
|
||||
XkbAudibleBellMask);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,6 +306,6 @@ meta_bell_shutdown (MetaDisplay *display)
|
||||
void
|
||||
meta_bell_notify_frame_destroy (MetaFrame *frame)
|
||||
{
|
||||
if (frame->is_flashing)
|
||||
if (frame->is_flashing)
|
||||
g_source_remove_by_funcs_user_data (&g_timeout_funcs, frame);
|
||||
}
|
||||
|
@@ -1,8 +1,8 @@
|
||||
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2002 Sun Microsystems 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
|
||||
@@ -12,23 +12,20 @@
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#ifdef HAVE_XKB
|
||||
#include <X11/XKBlib.h>
|
||||
#endif
|
||||
#include "display-private.h"
|
||||
#include "frame.h"
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
/**
|
||||
* meta_bell_notify:
|
||||
* @display: The display the bell event came in on
|
||||
* @xkb_ev: The bell event we just received
|
||||
* @xkb_ev: The bell event we just received
|
||||
*
|
||||
* Gives the user some kind of visual bell; in fact, this is our response
|
||||
* to any kind of bell request, but we set it up so that we only get
|
||||
@@ -37,7 +34,6 @@
|
||||
* If the configure script found we had no XKB, this does not exist.
|
||||
*/
|
||||
void meta_bell_notify (MetaDisplay *display, XkbAnyEvent *xkb_ev);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* meta_bell_set_audible:
|
||||
@@ -61,12 +57,6 @@ void meta_bell_set_audible (MetaDisplay *display, gboolean audible);
|
||||
* to send us bell notifications, and then also switching
|
||||
* off the audible bell if we're using a visual one ourselves.
|
||||
*
|
||||
* Unlike most X extensions we use, we only initialise XKB here
|
||||
* (rather than in main()). It's possible that XKB is not
|
||||
* installed at all, but if that was known at build time
|
||||
* we will have HAVE_XKB undefined, which will cause this
|
||||
* function to be a no-op.
|
||||
*
|
||||
* \bug There is a line of code that's never run that tells
|
||||
* XKB to reset the bell status after we quit. Bill H said
|
||||
* (<http://bugzilla.gnome.org/show_bug.cgi?id=99886#c12>)
|
||||
|
@@ -2,9 +2,9 @@
|
||||
|
||||
/* Simple box operations */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2005, 2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -43,7 +43,7 @@ typedef enum
|
||||
* region_to_string: (RECT_LENGTH+strlen(separator_string)) *
|
||||
* g_list_length (region)
|
||||
* edge_to_string: EDGE_LENGTH
|
||||
* edge_list_to_...: (EDGE_LENGTH+strlen(separator_string)) *
|
||||
* edge_list_to_...: (EDGE_LENGTH+strlen(separator_string)) *
|
||||
* g_list_length (edge_list)
|
||||
*/
|
||||
#define RECT_LENGTH 27
|
||||
@@ -181,7 +181,7 @@ void meta_rectangle_find_linepoint_closest_to_point (double x1, double y1,
|
||||
/* Return whether an edge overlaps or is adjacent to the rectangle in the
|
||||
* nonzero-width dimension of the edge.
|
||||
*/
|
||||
gboolean meta_rectangle_edge_aligns (const MetaRectangle *rect,
|
||||
gboolean meta_rectangle_edge_aligns (const MetaRectangle *rect,
|
||||
const MetaEdge *edge);
|
||||
|
||||
/* Compare two edges, so that sorting functions can put a list of edges in
|
||||
|
113
src/core/boxes.c
113
src/core/boxes.c
@@ -6,14 +6,14 @@
|
||||
* @Short_Description: Simple box operations
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2005, 2006 Elijah Newren
|
||||
* [meta_rectangle_intersect() is copyright the GTK+ Team according to Havoc,
|
||||
* see gdkrectangle.c. As far as Havoc knows, he probably wrote
|
||||
* meta_rectangle_equal(), and I'm guessing it's (C) Red Hat. So...]
|
||||
* Copyright (C) 1995-2000 GTK+ Team
|
||||
* Copyright (C) 2002 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
|
||||
@@ -23,7 +23,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -69,7 +69,7 @@ meta_rectangle_to_string (const MetaRectangle *rect,
|
||||
* Should be more than enough space. Note that of this space, the
|
||||
* trailing \0 will be overwritten for all but the last rectangle.
|
||||
*/
|
||||
g_snprintf (output, RECT_LENGTH, "%d,%d +%d,%d",
|
||||
g_snprintf (output, RECT_LENGTH, "%d,%d +%d,%d",
|
||||
rect->x, rect->y, rect->width, rect->height);
|
||||
|
||||
return output;
|
||||
@@ -96,7 +96,7 @@ meta_rectangle_region_to_string (GList *region,
|
||||
while (tmp)
|
||||
{
|
||||
MetaRectangle *rect = tmp->data;
|
||||
g_snprintf (rect_string, RECT_LENGTH, "[%d,%d +%d,%d]",
|
||||
g_snprintf (rect_string, RECT_LENGTH, "[%d,%d +%d,%d]",
|
||||
rect->x, rect->y, rect->width, rect->height);
|
||||
cur = g_stpcpy (cur, rect_string);
|
||||
tmp = tmp->next;
|
||||
@@ -118,7 +118,7 @@ meta_rectangle_edge_to_string (const MetaEdge *edge,
|
||||
* Plus 2 for parenthesis, 4 for 2 more numbers, 2 more commas, and
|
||||
* 2 more spaces, for a total of 10 more.
|
||||
*/
|
||||
g_snprintf (output, EDGE_LENGTH, "[%d,%d +%d,%d], %2d, %2d",
|
||||
g_snprintf (output, EDGE_LENGTH, "[%d,%d +%d,%d], %2d, %2d",
|
||||
edge->rect.x, edge->rect.y, edge->rect.width, edge->rect.height,
|
||||
edge->side_type, edge->edge_type);
|
||||
|
||||
@@ -150,7 +150,7 @@ meta_rectangle_edge_list_to_string (GList *edge_list,
|
||||
{
|
||||
MetaEdge *edge = tmp->data;
|
||||
MetaRectangle *rect = &edge->rect;
|
||||
g_snprintf (rect_string, EDGE_LENGTH, "([%d,%d +%d,%d], %2d, %2d)",
|
||||
g_snprintf (rect_string, EDGE_LENGTH, "([%d,%d +%d,%d], %2d, %2d)",
|
||||
rect->x, rect->y, rect->width, rect->height,
|
||||
edge->side_type, edge->edge_type);
|
||||
cur = g_stpcpy (cur, rect_string);
|
||||
@@ -210,7 +210,7 @@ meta_rectangle_intersect (const MetaRectangle *src1,
|
||||
dest_y = MAX (src1->y, src2->y);
|
||||
dest_w = MIN (src1->x + src1->width, src2->x + src2->width) - dest_x;
|
||||
dest_h = MIN (src1->y + src1->height, src2->y + src2->height) - dest_y;
|
||||
|
||||
|
||||
if (dest_w > 0 && dest_h > 0)
|
||||
{
|
||||
dest->x = dest_x;
|
||||
@@ -320,7 +320,7 @@ gboolean
|
||||
meta_rectangle_contains_rect (const MetaRectangle *outer_rect,
|
||||
const MetaRectangle *inner_rect)
|
||||
{
|
||||
return
|
||||
return
|
||||
inner_rect->x >= outer_rect->x &&
|
||||
inner_rect->y >= outer_rect->y &&
|
||||
inner_rect->x + inner_rect->width <= outer_rect->x + outer_rect->width &&
|
||||
@@ -339,7 +339,7 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
|
||||
* boxes.h has a good comment, but I'm not sure if the below info is also
|
||||
* helpful on top of that (or whether it has superfluous info).
|
||||
*/
|
||||
|
||||
|
||||
/* These formulas may look overly simplistic at first but you can work
|
||||
* everything out with a left_frame_with, right_frame_width,
|
||||
* border_width, and old and new client area widths (instead of old total
|
||||
@@ -389,7 +389,7 @@ meta_rectangle_resize_with_gravity (const MetaRectangle *old_rect,
|
||||
break;
|
||||
}
|
||||
rect->width = new_width;
|
||||
|
||||
|
||||
/* Next, the y direction */
|
||||
switch (gravity)
|
||||
{
|
||||
@@ -546,6 +546,26 @@ compare_rect_areas (gconstpointer a, gconstpointer b)
|
||||
return b_area - a_area; /* positive ret value denotes b > a, ... */
|
||||
}
|
||||
|
||||
/* ... and another helper for get_minimal_spanning_set_for_region()... */
|
||||
static gboolean
|
||||
check_strut_align (MetaStrut *strut, const MetaRectangle *rect)
|
||||
{
|
||||
/* Check whether @strut actually aligns to the side of @rect it claims */
|
||||
switch (strut->side)
|
||||
{
|
||||
case META_SIDE_TOP:
|
||||
return BOX_TOP (strut->rect) <= BOX_TOP (*rect);
|
||||
case META_SIDE_BOTTOM:
|
||||
return BOX_BOTTOM (strut->rect) >= BOX_BOTTOM (*rect);
|
||||
case META_SIDE_LEFT:
|
||||
return BOX_LEFT (strut->rect) <= BOX_LEFT (*rect);
|
||||
case META_SIDE_RIGHT:
|
||||
return BOX_RIGHT (strut->rect) >= BOX_RIGHT (*rect);
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_rectangle_get_minimal_spanning_set_for_region:
|
||||
* @basic_rect: Input rectangle
|
||||
@@ -629,8 +649,9 @@ meta_rectangle_get_minimal_spanning_set_for_region (
|
||||
|
||||
for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
|
||||
{
|
||||
GList *rect_iter;
|
||||
MetaRectangle *strut_rect = &((MetaStrut*)strut_iter->data)->rect;
|
||||
GList *rect_iter;
|
||||
MetaStrut *strut = (MetaStrut*)strut_iter->data;
|
||||
MetaRectangle *strut_rect = &strut->rect;
|
||||
|
||||
tmp_list = ret;
|
||||
ret = NULL;
|
||||
@@ -638,7 +659,9 @@ meta_rectangle_get_minimal_spanning_set_for_region (
|
||||
while (rect_iter)
|
||||
{
|
||||
MetaRectangle *rect = (MetaRectangle*) rect_iter->data;
|
||||
if (!meta_rectangle_overlap (rect, strut_rect))
|
||||
|
||||
if (!meta_rectangle_overlap (strut_rect, rect) ||
|
||||
!check_strut_align (strut, basic_rect))
|
||||
ret = g_list_prepend (ret, rect);
|
||||
else
|
||||
{
|
||||
@@ -764,7 +787,7 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
|
||||
*/
|
||||
g_assert ((direction == META_DIRECTION_HORIZONTAL) ^
|
||||
(direction == META_DIRECTION_VERTICAL ));
|
||||
|
||||
|
||||
if (direction == META_DIRECTION_HORIZONTAL)
|
||||
{
|
||||
rect->x = expand_to->x;
|
||||
@@ -776,12 +799,12 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
|
||||
rect->height = expand_to->height;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Run over all struts */
|
||||
for (strut_iter = all_struts; strut_iter; strut_iter = strut_iter->next)
|
||||
{
|
||||
MetaStrut *strut = (MetaStrut*) strut_iter->data;
|
||||
|
||||
|
||||
/* Skip struts that don't overlap */
|
||||
if (!meta_rectangle_overlap (&strut->rect, rect))
|
||||
continue;
|
||||
@@ -822,7 +845,7 @@ meta_rectangle_expand_to_avoiding_struts (MetaRectangle *rect,
|
||||
void
|
||||
meta_rectangle_free_list_and_elements (GList *filled_list)
|
||||
{
|
||||
g_list_foreach (filled_list,
|
||||
g_list_foreach (filled_list,
|
||||
(void (*)(gpointer,gpointer))&g_free, /* ew, for ugly */
|
||||
NULL);
|
||||
g_list_free (filled_list);
|
||||
@@ -900,20 +923,20 @@ meta_rectangle_clamp_to_fit_into_region (const GList *spanning_rects,
|
||||
{
|
||||
MetaRectangle *compare_rect = temp->data;
|
||||
int maximal_overlap_amount_for_compare;
|
||||
|
||||
|
||||
/* If x is fixed and the entire width of rect doesn't fit in compare,
|
||||
* skip this rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_X) &&
|
||||
(compare_rect->x > rect->x ||
|
||||
(compare_rect->x > rect->x ||
|
||||
compare_rect->x + compare_rect->width < rect->x + rect->width))
|
||||
continue;
|
||||
|
||||
|
||||
/* If y is fixed and the entire height of rect doesn't fit in compare,
|
||||
* skip this rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_Y) &&
|
||||
(compare_rect->y > rect->y ||
|
||||
(compare_rect->y > rect->y ||
|
||||
compare_rect->y + compare_rect->height < rect->y + rect->height))
|
||||
continue;
|
||||
|
||||
@@ -970,20 +993,20 @@ meta_rectangle_clip_to_region (const GList *spanning_rects,
|
||||
MetaRectangle *compare_rect = temp->data;
|
||||
MetaRectangle overlap;
|
||||
int maximal_overlap_amount_for_compare;
|
||||
|
||||
|
||||
/* If x is fixed and the entire width of rect doesn't fit in compare,
|
||||
* skip the rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_X) &&
|
||||
(compare_rect->x > rect->x ||
|
||||
(compare_rect->x > rect->x ||
|
||||
compare_rect->x + compare_rect->width < rect->x + rect->width))
|
||||
continue;
|
||||
|
||||
|
||||
/* If y is fixed and the entire height of rect doesn't fit in compare,
|
||||
* skip the rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_Y) &&
|
||||
(compare_rect->y > rect->y ||
|
||||
(compare_rect->y > rect->y ||
|
||||
compare_rect->y + compare_rect->height < rect->y + rect->height))
|
||||
continue;
|
||||
|
||||
@@ -1043,26 +1066,26 @@ meta_rectangle_shove_into_region (const GList *spanning_rects,
|
||||
/* First, find best rectangle from spanning_rects to which we will shove
|
||||
* rect into.
|
||||
*/
|
||||
|
||||
|
||||
for (temp = spanning_rects; temp; temp = temp->next)
|
||||
{
|
||||
MetaRectangle *compare_rect = temp->data;
|
||||
int maximal_overlap_amount_for_compare;
|
||||
int dist_to_compare;
|
||||
|
||||
|
||||
/* If x is fixed and the entire width of rect doesn't fit in compare,
|
||||
* skip this rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_X) &&
|
||||
(compare_rect->x > rect->x ||
|
||||
(compare_rect->x > rect->x ||
|
||||
compare_rect->x + compare_rect->width < rect->x + rect->width))
|
||||
continue;
|
||||
|
||||
|
||||
/* If y is fixed and the entire height of rect doesn't fit in compare,
|
||||
* skip this rectangle.
|
||||
*/
|
||||
if ((fixed_directions & FIXED_DIRECTION_Y) &&
|
||||
(compare_rect->y > rect->y ||
|
||||
(compare_rect->y > rect->y ||
|
||||
compare_rect->y + compare_rect->height < rect->y + rect->height))
|
||||
continue;
|
||||
|
||||
@@ -1218,7 +1241,7 @@ meta_rectangle_edge_aligns (const MetaRectangle *rect, const MetaEdge *edge)
|
||||
}
|
||||
|
||||
static GList*
|
||||
get_rect_minus_overlap (const GList *rect_in_list,
|
||||
get_rect_minus_overlap (const GList *rect_in_list,
|
||||
MetaRectangle *overlap)
|
||||
{
|
||||
MetaRectangle *temp;
|
||||
@@ -1263,7 +1286,7 @@ get_rect_minus_overlap (const GList *rect_in_list,
|
||||
}
|
||||
|
||||
static GList*
|
||||
replace_rect_with_list (GList *old_element,
|
||||
replace_rect_with_list (GList *old_element,
|
||||
GList *new_list)
|
||||
{
|
||||
GList *ret;
|
||||
@@ -1475,7 +1498,7 @@ rectangle_and_edge_intersection (const MetaRectangle *rect,
|
||||
overlap->edge_type = -1;
|
||||
overlap->side_type = -1;
|
||||
|
||||
/* Figure out what the intersection is */
|
||||
/* Figure out what the intersection is */
|
||||
result->x = MAX (rect->x, rect2->x);
|
||||
result->y = MAX (rect->y, rect2->y);
|
||||
result->width = MIN (BOX_RIGHT (*rect), BOX_RIGHT (*rect2)) - result->x;
|
||||
@@ -1546,7 +1569,7 @@ rectangle_and_edge_intersection (const MetaRectangle *rect,
|
||||
* TOP<->BOTTOM).
|
||||
*/
|
||||
static GList*
|
||||
add_edges (GList *cur_edges,
|
||||
add_edges (GList *cur_edges,
|
||||
const MetaRectangle *rect,
|
||||
gboolean rect_is_internal)
|
||||
{
|
||||
@@ -1560,23 +1583,23 @@ add_edges (GList *cur_edges,
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
temp_edge->side_type =
|
||||
temp_edge->side_type =
|
||||
rect_is_internal ? META_SIDE_LEFT : META_SIDE_RIGHT;
|
||||
temp_edge->rect.width = 0;
|
||||
break;
|
||||
case 1:
|
||||
temp_edge->side_type =
|
||||
temp_edge->side_type =
|
||||
rect_is_internal ? META_SIDE_RIGHT : META_SIDE_LEFT;
|
||||
temp_edge->rect.x += temp_edge->rect.width;
|
||||
temp_edge->rect.width = 0;
|
||||
break;
|
||||
case 2:
|
||||
temp_edge->side_type =
|
||||
temp_edge->side_type =
|
||||
rect_is_internal ? META_SIDE_TOP : META_SIDE_BOTTOM;
|
||||
temp_edge->rect.height = 0;
|
||||
break;
|
||||
case 3:
|
||||
temp_edge->side_type =
|
||||
temp_edge->side_type =
|
||||
rect_is_internal ? META_SIDE_BOTTOM : META_SIDE_TOP;
|
||||
temp_edge->rect.y += temp_edge->rect.height;
|
||||
temp_edge->rect.height = 0;
|
||||
@@ -1593,8 +1616,8 @@ add_edges (GList *cur_edges,
|
||||
* edges to cur_list. Return cur_list when finished.
|
||||
*/
|
||||
static GList*
|
||||
split_edge (GList *cur_list,
|
||||
const MetaEdge *old_edge,
|
||||
split_edge (GList *cur_list,
|
||||
const MetaEdge *old_edge,
|
||||
const MetaEdge *remove)
|
||||
{
|
||||
MetaEdge *temp_edge;
|
||||
@@ -1653,7 +1676,7 @@ split_edge (GList *cur_list,
|
||||
* if and how rect and edge intersect.
|
||||
*/
|
||||
static void
|
||||
fix_up_edges (MetaRectangle *rect, MetaEdge *edge,
|
||||
fix_up_edges (MetaRectangle *rect, MetaEdge *edge,
|
||||
GList **strut_edges, GList **edge_splits,
|
||||
gboolean *edge_needs_removal)
|
||||
{
|
||||
@@ -1777,7 +1800,7 @@ meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
|
||||
{
|
||||
GList *ret;
|
||||
GList *fixed_strut_rects;
|
||||
GList *edge_iter;
|
||||
GList *edge_iter;
|
||||
const GList *strut_rect_iter;
|
||||
|
||||
/* The algorithm is basically as follows:
|
||||
@@ -1817,7 +1840,7 @@ meta_rectangle_find_onscreen_edges (const MetaRectangle *basic_rect,
|
||||
GList *splits_of_cur_edge = NULL;
|
||||
gboolean edge_needs_removal = FALSE;
|
||||
|
||||
fix_up_edges (strut_rect, cur_edge,
|
||||
fix_up_edges (strut_rect, cur_edge,
|
||||
&new_strut_edges, &splits_of_cur_edge,
|
||||
&edge_needs_removal);
|
||||
|
||||
@@ -1981,7 +2004,7 @@ meta_rectangle_find_nonintersected_monitor_edges (
|
||||
for (; all_struts; all_struts = all_struts->next)
|
||||
temp_rects = g_slist_prepend (temp_rects,
|
||||
&((MetaStrut*)all_struts->data)->rect);
|
||||
ret = meta_rectangle_remove_intersections_with_boxes_from_edges (ret,
|
||||
ret = meta_rectangle_remove_intersections_with_boxes_from_edges (ret,
|
||||
temp_rects);
|
||||
g_slist_free (temp_rects);
|
||||
|
||||
|
@@ -42,7 +42,7 @@
|
||||
// "constrain_whatever".
|
||||
// 3) Add your function to the all_constraints and all_constraint_names
|
||||
// arrays (the latter of which is for debugging purposes)
|
||||
//
|
||||
//
|
||||
// An example constraint function, constrain_whatever:
|
||||
//
|
||||
// /* constrain_whatever does the following:
|
||||
@@ -246,7 +246,7 @@ do_all_constraints (MetaWindow *window,
|
||||
/* Log how the constraint modified the position */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"info->current is %d,%d +%d,%d after %s\n",
|
||||
info->current.x, info->current.y,
|
||||
info->current.x, info->current.y,
|
||||
info->current.width, info->current.height,
|
||||
constraint->name);
|
||||
}
|
||||
@@ -275,11 +275,6 @@ meta_window_constrain (MetaWindow *window,
|
||||
ConstraintPriority priority = PRIORITY_MINIMUM;
|
||||
gboolean satisfied = FALSE;
|
||||
|
||||
/* WARNING: orig and new specify positions and sizes of the inner window,
|
||||
* not the outer. This is a common gotcha since half the constraints
|
||||
* deal with inner window position/size and half deal with outer. See
|
||||
* doc/how-constraints-works.txt for more information.
|
||||
*/
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Constraining %s in move from %d,%d %dx%d to %d,%d %dx%d\n",
|
||||
window->desc,
|
||||
@@ -287,7 +282,7 @@ meta_window_constrain (MetaWindow *window,
|
||||
new->x, new->y, new->width, new->height);
|
||||
|
||||
setup_constraint_info (&info,
|
||||
window,
|
||||
window,
|
||||
flags,
|
||||
resize_gravity,
|
||||
orig,
|
||||
@@ -300,7 +295,7 @@ meta_window_constrain (MetaWindow *window,
|
||||
/* Individually enforce all the high-enough priority constraints */
|
||||
do_all_constraints (window, &info, priority, !check_only);
|
||||
|
||||
/* Check if all high-enough priority constraints are simultaneously
|
||||
/* Check if all high-enough priority constraints are simultaneously
|
||||
* satisfied
|
||||
*/
|
||||
satisfied = do_all_constraints (window, &info, priority, check_only);
|
||||
@@ -403,37 +398,12 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
}
|
||||
|
||||
cur_workspace = window->screen->active_workspace;
|
||||
info->usable_screen_region =
|
||||
info->usable_screen_region =
|
||||
meta_workspace_get_onscreen_region (cur_workspace);
|
||||
info->usable_monitor_region =
|
||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||
info->usable_monitor_region =
|
||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||
monitor_info->number);
|
||||
|
||||
/* Workaround braindead legacy apps that don't know how to
|
||||
* fullscreen themselves properly - don't get fooled by
|
||||
* windows which hide their titlebar when maximized or which are
|
||||
* client decorated; that's not the same as fullscreen, even
|
||||
* if there are no struts making the workarea smaller than
|
||||
* the monitor.
|
||||
*/
|
||||
if (meta_prefs_get_force_fullscreen() &&
|
||||
window->client_type != META_WINDOW_CLIENT_TYPE_WAYLAND &&
|
||||
!window->hide_titlebar_when_maximized &&
|
||||
(window->decorated || !meta_window_is_client_decorated (window)) &&
|
||||
meta_rectangle_equal (new, &monitor_info->rect) &&
|
||||
window->has_fullscreen_func &&
|
||||
!window->fullscreen)
|
||||
{
|
||||
/*
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
*/
|
||||
meta_warning (
|
||||
"Treating resize request of legacy application %s as a "
|
||||
"fullscreen request\n",
|
||||
window->desc);
|
||||
meta_window_make_fullscreen_internal (window);
|
||||
}
|
||||
|
||||
/* Log all this information for debugging */
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"Setting up constraint info:\n"
|
||||
@@ -446,7 +416,7 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
" work_area_monitor: %d,%d +%d,%d\n"
|
||||
" entire_monitor : %d,%d +%d,%d\n",
|
||||
info->orig.x, info->orig.y, info->orig.width, info->orig.height,
|
||||
info->current.x, info->current.y,
|
||||
info->current.x, info->current.y,
|
||||
info->current.width, info->current.height,
|
||||
(info->action_type == ACTION_MOVE) ? "Move" :
|
||||
(info->action_type == ACTION_RESIZE) ? "Resize" :
|
||||
@@ -459,7 +429,7 @@ setup_constraint_info (ConstraintInfo *info,
|
||||
(info->fixed_directions == FIXED_DIRECTION_Y) ? "Y fixed" :
|
||||
"Freakin' Invalid Stupid",
|
||||
info->work_area_monitor.x, info->work_area_monitor.y,
|
||||
info->work_area_monitor.width,
|
||||
info->work_area_monitor.width,
|
||||
info->work_area_monitor.height,
|
||||
info->entire_monitor.x, info->entire_monitor.y,
|
||||
info->entire_monitor.width, info->entire_monitor.height);
|
||||
@@ -507,12 +477,10 @@ place_window_if_needed(MetaWindow *window,
|
||||
monitor_info->number,
|
||||
&info->work_area_monitor);
|
||||
cur_workspace = window->screen->active_workspace;
|
||||
info->usable_monitor_region =
|
||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||
info->usable_monitor_region =
|
||||
meta_workspace_get_onmonitor_region (cur_workspace,
|
||||
monitor_info->number);
|
||||
|
||||
meta_window_frame_rect_to_client_rect (window, &placed_rect, &placed_rect);
|
||||
|
||||
info->current.x = placed_rect.x;
|
||||
info->current.y = placed_rect.y;
|
||||
|
||||
@@ -544,14 +512,14 @@ place_window_if_needed(MetaWindow *window,
|
||||
.083 * info->work_area_monitor.height;
|
||||
}
|
||||
|
||||
/* idle_move_resize() uses the user_rect, so make sure it uses the
|
||||
* placed coordinates (bug #556696).
|
||||
/* idle_move_resize() uses the unconstrained_rect, so make sure it
|
||||
* uses the placed coordinates (bug #556696).
|
||||
*/
|
||||
window->user_rect = info->current;
|
||||
window->unconstrained_rect = info->current;
|
||||
|
||||
if (window->maximize_horizontally_after_placement ||
|
||||
window->maximize_vertically_after_placement)
|
||||
meta_window_maximize_internal (window,
|
||||
meta_window_maximize_internal (window,
|
||||
(window->maximize_horizontally_after_placement ?
|
||||
META_MAXIMIZE_HORIZONTAL : 0 ) |
|
||||
(window->maximize_vertically_after_placement ?
|
||||
@@ -620,7 +588,7 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
window->require_fully_onscreen =
|
||||
meta_rectangle_contained_in_region (info->usable_screen_region,
|
||||
&info->current);
|
||||
if (old ^ window->require_fully_onscreen)
|
||||
if (old != window->require_fully_onscreen)
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"require_fully_onscreen for %s toggled to %s\n",
|
||||
window->desc,
|
||||
@@ -633,10 +601,10 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
window->require_on_single_monitor =
|
||||
meta_rectangle_contained_in_region (info->usable_monitor_region,
|
||||
&info->current);
|
||||
if (old ^ window->require_on_single_monitor)
|
||||
if (old != window->require_on_single_monitor)
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"require_on_single_monitor for %s toggled to %s\n",
|
||||
window->desc,
|
||||
window->desc,
|
||||
window->require_on_single_monitor ? "TRUE" : "FALSE");
|
||||
|
||||
/* Update whether we want future constraint runs to require the
|
||||
@@ -644,18 +612,15 @@ update_onscreen_requirements (MetaWindow *window,
|
||||
*/
|
||||
if (window->frame && window->decorated)
|
||||
{
|
||||
MetaFrameBorders borders;
|
||||
MetaRectangle titlebar_rect;
|
||||
|
||||
meta_frame_calc_borders (window->frame, &borders);
|
||||
meta_window_get_titlebar_rect (window, &titlebar_rect);
|
||||
|
||||
titlebar_rect = info->current;
|
||||
titlebar_rect.height = borders.visible.top;
|
||||
old = window->require_titlebar_visible;
|
||||
window->require_titlebar_visible =
|
||||
meta_rectangle_overlaps_with_region (info->usable_screen_region,
|
||||
&titlebar_rect);
|
||||
if (old ^ window->require_titlebar_visible)
|
||||
if (old != window->require_titlebar_visible)
|
||||
meta_topic (META_DEBUG_GEOMETRY,
|
||||
"require_titlebar_visible for %s toggled to %s\n",
|
||||
window->desc,
|
||||
@@ -910,38 +875,41 @@ constrain_size_increments (MetaWindow *window,
|
||||
int new_width, new_height;
|
||||
gboolean constraint_already_satisfied;
|
||||
MetaRectangle *start_rect;
|
||||
MetaRectangle client_rect;
|
||||
|
||||
if (priority > PRIORITY_SIZE_HINTS_INCREMENTS)
|
||||
return TRUE;
|
||||
|
||||
/* Determine whether constraint applies; exit if it doesn't */
|
||||
if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
|
||||
if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
|
||||
META_WINDOW_TILED_SIDE_BY_SIDE (window) ||
|
||||
info->action_type == ACTION_MOVE)
|
||||
return TRUE;
|
||||
|
||||
meta_window_frame_rect_to_client_rect (window, &info->current, &client_rect);
|
||||
|
||||
/* Determine whether constraint is already satisfied; exit if it is */
|
||||
bh = window->size_hints.base_height;
|
||||
hi = window->size_hints.height_inc;
|
||||
bw = window->size_hints.base_width;
|
||||
wi = window->size_hints.width_inc;
|
||||
extra_height = (info->current.height - bh) % hi;
|
||||
extra_width = (info->current.width - bw) % wi;
|
||||
extra_height = (client_rect.height - bh) % hi;
|
||||
extra_width = (client_rect.width - bw) % wi;
|
||||
/* ignore size increments for maximized windows */
|
||||
if (window->maximized_horizontally)
|
||||
extra_width *= 0;
|
||||
if (window->maximized_vertically)
|
||||
extra_height *= 0;
|
||||
/* constraint is satisfied iff there is no extra height or width */
|
||||
constraint_already_satisfied =
|
||||
constraint_already_satisfied =
|
||||
(extra_height == 0 && extra_width == 0);
|
||||
|
||||
if (check_only || constraint_already_satisfied)
|
||||
return constraint_already_satisfied;
|
||||
|
||||
/*** Enforce constraint ***/
|
||||
new_width = info->current.width - extra_width;
|
||||
new_height = info->current.height - extra_height;
|
||||
new_width = client_rect.width - extra_width;
|
||||
new_height = client_rect.height - extra_height;
|
||||
|
||||
/* Adjusting down instead of up (as done in the above two lines) may
|
||||
* violate minimum size constraints; fix the adjustment if this
|
||||
@@ -952,6 +920,14 @@ constrain_size_increments (MetaWindow *window,
|
||||
if (new_height < window->size_hints.min_height)
|
||||
new_height += ((window->size_hints.min_height - new_height)/hi + 1)*hi;
|
||||
|
||||
{
|
||||
client_rect.width = new_width;
|
||||
client_rect.height = new_height;
|
||||
meta_window_client_rect_to_frame_rect (window, &client_rect, &client_rect);
|
||||
new_width = client_rect.width;
|
||||
new_height = client_rect.height;
|
||||
}
|
||||
|
||||
/* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
|
||||
* See bug 448183
|
||||
*/
|
||||
@@ -959,10 +935,10 @@ constrain_size_increments (MetaWindow *window,
|
||||
start_rect = &info->current;
|
||||
else
|
||||
start_rect = &info->orig;
|
||||
|
||||
|
||||
/* Resize to the new size */
|
||||
meta_rectangle_resize_with_gravity (start_rect,
|
||||
&info->current,
|
||||
&info->current,
|
||||
info->resize_gravity,
|
||||
new_width,
|
||||
new_height);
|
||||
@@ -1007,7 +983,7 @@ constrain_size_limits (MetaWindow *window,
|
||||
/*** Enforce constraint ***/
|
||||
new_width = CLAMP (info->current.width, min_size.width, max_size.width);
|
||||
new_height = CLAMP (info->current.height, min_size.height, max_size.height);
|
||||
|
||||
|
||||
/* Figure out what original rect to pass to meta_rectangle_resize_with_gravity
|
||||
* See bug 448183
|
||||
*/
|
||||
@@ -1015,9 +991,9 @@ constrain_size_limits (MetaWindow *window,
|
||||
start_rect = &info->current;
|
||||
else
|
||||
start_rect = &info->orig;
|
||||
|
||||
|
||||
meta_rectangle_resize_with_gravity (start_rect,
|
||||
&info->current,
|
||||
&info->current,
|
||||
info->resize_gravity,
|
||||
new_width,
|
||||
new_height);
|
||||
@@ -1047,7 +1023,7 @@ constrain_aspect_ratio (MetaWindow *window,
|
||||
(double)window->size_hints.max_aspect.y;
|
||||
constraints_are_inconsistent = minr > maxr;
|
||||
if (constraints_are_inconsistent ||
|
||||
META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
|
||||
META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
|
||||
META_WINDOW_TILED_SIDE_BY_SIDE (window) ||
|
||||
info->action_type == ACTION_MOVE)
|
||||
return TRUE;
|
||||
@@ -1087,7 +1063,7 @@ constrain_aspect_ratio (MetaWindow *window,
|
||||
fudge = 1;
|
||||
break;
|
||||
}
|
||||
constraint_already_satisfied =
|
||||
constraint_already_satisfied =
|
||||
info->current.width - (info->current.height * minr ) > -minr*fudge &&
|
||||
info->current.width - (info->current.height * maxr ) < maxr*fudge;
|
||||
if (check_only || constraint_already_satisfied)
|
||||
@@ -1151,7 +1127,7 @@ constrain_aspect_ratio (MetaWindow *window,
|
||||
start_rect = &info->orig;
|
||||
|
||||
meta_rectangle_resize_with_gravity (start_rect,
|
||||
&info->current,
|
||||
&info->current,
|
||||
info->resize_gravity,
|
||||
new_width,
|
||||
new_height);
|
||||
@@ -1199,7 +1175,7 @@ do_screen_and_monitor_relative_constraints (
|
||||
exit_early = TRUE;
|
||||
|
||||
/* Determine whether constraint is already satisfied; exit if it is */
|
||||
constraint_satisfied =
|
||||
constraint_satisfied =
|
||||
meta_rectangle_contained_in_region (region_spanning_rectangles,
|
||||
&info->current);
|
||||
if (exit_early || constraint_satisfied || check_only)
|
||||
@@ -1238,7 +1214,7 @@ constrain_to_single_monitor (MetaWindow *window,
|
||||
return TRUE;
|
||||
|
||||
/* Exit early if we know the constraint won't apply--note that this constraint
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* "onscreen" by their own strut) and we can't apply it to frameless windows
|
||||
* or else users will be unable to move windows such as XMMS across monitors.
|
||||
*/
|
||||
@@ -1251,7 +1227,7 @@ constrain_to_single_monitor (MetaWindow *window,
|
||||
return TRUE;
|
||||
|
||||
/* Have a helper function handle the constraint for us */
|
||||
return do_screen_and_monitor_relative_constraints (window,
|
||||
return do_screen_and_monitor_relative_constraints (window,
|
||||
info->usable_monitor_region,
|
||||
info,
|
||||
check_only);
|
||||
@@ -1267,18 +1243,18 @@ constrain_fully_onscreen (MetaWindow *window,
|
||||
return TRUE;
|
||||
|
||||
/* Exit early if we know the constraint won't apply--note that this constraint
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* "onscreen" by their own strut).
|
||||
*/
|
||||
if (window->type == META_WINDOW_DESKTOP ||
|
||||
window->type == META_WINDOW_DOCK ||
|
||||
window->fullscreen ||
|
||||
!window->require_fully_onscreen ||
|
||||
!window->require_fully_onscreen ||
|
||||
info->is_user_action)
|
||||
return TRUE;
|
||||
|
||||
/* Have a helper function handle the constraint for us */
|
||||
return do_screen_and_monitor_relative_constraints (window,
|
||||
return do_screen_and_monitor_relative_constraints (window,
|
||||
info->usable_screen_region,
|
||||
info,
|
||||
check_only);
|
||||
@@ -1306,7 +1282,7 @@ constrain_titlebar_visible (MetaWindow *window,
|
||||
info->is_user_action && !window->display->grab_frame_action;
|
||||
|
||||
/* Exit early if we know the constraint won't apply--note that this constraint
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* "onscreen" by their own strut).
|
||||
*/
|
||||
if (window->type == META_WINDOW_DESKTOP ||
|
||||
@@ -1350,13 +1326,13 @@ constrain_titlebar_visible (MetaWindow *window,
|
||||
*/
|
||||
meta_rectangle_expand_region_conditionally (info->usable_screen_region,
|
||||
horiz_amount_offscreen,
|
||||
horiz_amount_offscreen,
|
||||
horiz_amount_offscreen,
|
||||
0, /* Don't let titlebar off */
|
||||
bottom_amount,
|
||||
horiz_amount_onscreen,
|
||||
vert_amount_onscreen);
|
||||
retval =
|
||||
do_screen_and_monitor_relative_constraints (window,
|
||||
do_screen_and_monitor_relative_constraints (window,
|
||||
info->usable_screen_region,
|
||||
info,
|
||||
check_only);
|
||||
@@ -1386,7 +1362,7 @@ constrain_partially_onscreen (MetaWindow *window,
|
||||
return TRUE;
|
||||
|
||||
/* Exit early if we know the constraint won't apply--note that this constraint
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* is only meant for normal windows (e.g. we don't want docks to be shoved
|
||||
* "onscreen" by their own strut).
|
||||
*/
|
||||
if (window->type == META_WINDOW_DESKTOP ||
|
||||
@@ -1428,13 +1404,13 @@ constrain_partially_onscreen (MetaWindow *window,
|
||||
*/
|
||||
meta_rectangle_expand_region_conditionally (info->usable_screen_region,
|
||||
horiz_amount_offscreen,
|
||||
horiz_amount_offscreen,
|
||||
horiz_amount_offscreen,
|
||||
top_amount,
|
||||
bottom_amount,
|
||||
horiz_amount_onscreen,
|
||||
vert_amount_onscreen);
|
||||
retval =
|
||||
do_screen_and_monitor_relative_constraints (window,
|
||||
do_screen_and_monitor_relative_constraints (window,
|
||||
info->usable_screen_region,
|
||||
info,
|
||||
check_only);
|
||||
|
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter size/position constraints */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -15,7 +15,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
|
363
src/core/core.c
363
src/core/core.c
@@ -2,11 +2,11 @@
|
||||
|
||||
/* Mutter interface used by GTK+ UI to talk to core */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -16,7 +16,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -29,6 +29,9 @@
|
||||
#include <meta/errors.h>
|
||||
#include "util-private.h"
|
||||
|
||||
#include "x11/window-x11.h"
|
||||
#include "x11/window-x11-private.h"
|
||||
|
||||
/* Looks up the MetaWindow representing the frame of the given X window.
|
||||
* Used as a helper function by a bunch of the functions below.
|
||||
*
|
||||
@@ -46,7 +49,7 @@ get_window (Display *xdisplay,
|
||||
{
|
||||
MetaDisplay *display;
|
||||
MetaWindow *window;
|
||||
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
window = meta_display_lookup_x_window (display, frame_xwindow);
|
||||
|
||||
@@ -69,6 +72,8 @@ meta_core_get (Display *xdisplay,
|
||||
|
||||
MetaDisplay *display = meta_display_for_x_display (xdisplay);
|
||||
MetaWindow *window = meta_display_lookup_x_window (display, xwindow);
|
||||
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
|
||||
MetaWindowX11Private *priv = window_x11->priv;
|
||||
|
||||
va_start (args, xwindow);
|
||||
|
||||
@@ -86,78 +91,53 @@ meta_core_get (Display *xdisplay,
|
||||
*/
|
||||
|
||||
if (request != META_CORE_WINDOW_HAS_FRAME &&
|
||||
(window == NULL || window->frame == NULL)) {
|
||||
meta_bug ("No such frame window 0x%lx!\n", xwindow);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (request != META_CORE_GET_END) {
|
||||
|
||||
gpointer answer = va_arg (args, gpointer);
|
||||
|
||||
switch (request) {
|
||||
case META_CORE_WINDOW_HAS_FRAME:
|
||||
*((gboolean*)answer) = window != NULL && window->frame != NULL;
|
||||
if (!*((gboolean*)answer)) goto out; /* see above */
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_WIDTH:
|
||||
*((gint*)answer) = window->rect.width;
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_HEIGHT:
|
||||
*((gint*)answer) = window->rect.height;
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_XWINDOW:
|
||||
*((Window*)answer) = window->xwindow;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_FLAGS:
|
||||
*((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
|
||||
break;
|
||||
case META_CORE_GET_FRAME_TYPE:
|
||||
*((MetaFrameType*)answer) = meta_window_get_frame_type (window);
|
||||
break;
|
||||
case META_CORE_GET_MINI_ICON:
|
||||
*((GdkPixbuf**)answer) = window->mini_icon;
|
||||
break;
|
||||
case META_CORE_GET_ICON:
|
||||
*((GdkPixbuf**)answer) = window->icon;
|
||||
break;
|
||||
case META_CORE_GET_X:
|
||||
meta_window_get_position (window, (int*)answer, NULL);
|
||||
break;
|
||||
case META_CORE_GET_Y:
|
||||
meta_window_get_position (window, NULL, (int*)answer);
|
||||
break;
|
||||
case META_CORE_GET_FRAME_WORKSPACE:
|
||||
*((gint*)answer) = meta_window_get_net_wm_desktop (window);
|
||||
break;
|
||||
case META_CORE_GET_FRAME_X:
|
||||
*((gint*)answer) = window->frame->rect.x;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_Y:
|
||||
*((gint*)answer) = window->frame->rect.y;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_WIDTH:
|
||||
*((gint*)answer) = window->frame->rect.width;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_HEIGHT:
|
||||
*((gint*)answer) = window->frame->rect.height;
|
||||
break;
|
||||
case META_CORE_GET_THEME_VARIANT:
|
||||
*((char**)answer) = window->gtk_theme_variant;
|
||||
break;
|
||||
case META_CORE_GET_SCREEN_WIDTH:
|
||||
*((gint*)answer) = window->screen->rect.width;
|
||||
break;
|
||||
case META_CORE_GET_SCREEN_HEIGHT:
|
||||
*((gint*)answer) = window->screen->rect.height;
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_warning("Unknown window information request: %d\n", request);
|
||||
(window == NULL || window->frame == NULL))
|
||||
{
|
||||
meta_bug ("No such frame window 0x%lx!\n", xwindow);
|
||||
goto out;
|
||||
}
|
||||
|
||||
request = va_arg (args, MetaCoreGetType);
|
||||
}
|
||||
while (request != META_CORE_GET_END)
|
||||
{
|
||||
gpointer answer = va_arg (args, gpointer);
|
||||
|
||||
switch (request)
|
||||
{
|
||||
case META_CORE_WINDOW_HAS_FRAME:
|
||||
*((gboolean*)answer) = window != NULL && window->frame != NULL;
|
||||
if (!*((gboolean*)answer)) goto out; /* see above */
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_WIDTH:
|
||||
*((gint*)answer) = priv->client_rect.width;
|
||||
break;
|
||||
case META_CORE_GET_CLIENT_HEIGHT:
|
||||
*((gint*)answer) = priv->client_rect.height;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_FLAGS:
|
||||
*((MetaFrameFlags*)answer) = meta_frame_get_flags (window->frame);
|
||||
break;
|
||||
case META_CORE_GET_FRAME_TYPE:
|
||||
*((MetaFrameType*)answer) = meta_window_get_frame_type (window);
|
||||
break;
|
||||
case META_CORE_GET_MINI_ICON:
|
||||
*((GdkPixbuf**)answer) = window->mini_icon;
|
||||
break;
|
||||
case META_CORE_GET_ICON:
|
||||
*((GdkPixbuf**)answer) = window->icon;
|
||||
break;
|
||||
case META_CORE_GET_FRAME_RECT:
|
||||
meta_window_get_frame_rect (window, ((MetaRectangle*)answer));
|
||||
break;
|
||||
case META_CORE_GET_THEME_VARIANT:
|
||||
*((char**)answer) = window->gtk_theme_variant;
|
||||
break;
|
||||
|
||||
default:
|
||||
meta_warning("Unknown window information request: %d\n", request);
|
||||
}
|
||||
|
||||
request = va_arg (args, MetaCoreGetType);
|
||||
}
|
||||
|
||||
out:
|
||||
va_end (args);
|
||||
@@ -173,38 +153,6 @@ meta_core_queue_frame_resize (Display *xdisplay,
|
||||
meta_window_frame_size_changed (window);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_move (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_move (window, TRUE, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_resize (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int gravity,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_resize_with_gravity (window, TRUE, width, height, gravity);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_user_raise (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
meta_window_raise (window);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
lower_window_and_transients (MetaWindow *window,
|
||||
gpointer data)
|
||||
@@ -221,21 +169,21 @@ lower_window_and_transients (MetaWindow *window,
|
||||
* (Borrowed from window.c.)
|
||||
*/
|
||||
if (window->screen->active_workspace &&
|
||||
meta_window_located_on_workspace (window,
|
||||
meta_window_located_on_workspace (window,
|
||||
window->screen->active_workspace))
|
||||
{
|
||||
GList* link;
|
||||
link = g_list_find (window->screen->active_workspace->mru_list,
|
||||
link = g_list_find (window->screen->active_workspace->mru_list,
|
||||
window);
|
||||
g_assert (link);
|
||||
|
||||
window->screen->active_workspace->mru_list =
|
||||
window->screen->active_workspace->mru_list =
|
||||
g_list_remove_link (window->screen->active_workspace->mru_list,
|
||||
link);
|
||||
g_list_free (link);
|
||||
|
||||
window->screen->active_workspace->mru_list =
|
||||
g_list_append (window->screen->active_workspace->mru_list,
|
||||
window->screen->active_workspace->mru_list =
|
||||
g_list_append (window->screen->active_workspace->mru_list,
|
||||
window);
|
||||
}
|
||||
}
|
||||
@@ -267,7 +215,7 @@ meta_core_user_focus (Display *xdisplay,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
|
||||
meta_window_focus (window, timestamp);
|
||||
}
|
||||
|
||||
@@ -355,7 +303,7 @@ meta_core_delete (Display *xdisplay,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
|
||||
meta_window_delete (window, timestamp);
|
||||
}
|
||||
|
||||
@@ -375,7 +323,7 @@ meta_core_shade (Display *xdisplay,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
|
||||
meta_window_shade (window, timestamp);
|
||||
}
|
||||
|
||||
@@ -428,134 +376,36 @@ meta_core_change_workspace (Display *xdisplay,
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp)
|
||||
meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
MetaWindowMenuType menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
meta_window_focus (window, timestamp);
|
||||
|
||||
meta_window_show_menu (window, root_x, root_y, button, timestamp);
|
||||
meta_window_show_menu (window, menu, root_x, root_y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_get_menu_accelerator (MetaMenuOp menu_op,
|
||||
int workspace,
|
||||
unsigned int *keysym,
|
||||
MetaVirtualModifier *modifiers)
|
||||
meta_core_show_window_menu_for_rect (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect,
|
||||
guint32 timestamp)
|
||||
{
|
||||
const char *name;
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
|
||||
name = NULL;
|
||||
|
||||
switch (menu_op)
|
||||
{
|
||||
case META_MENU_OP_NONE:
|
||||
/* No keybinding for this one */
|
||||
break;
|
||||
case META_MENU_OP_DELETE:
|
||||
name = "close";
|
||||
break;
|
||||
case META_MENU_OP_MINIMIZE:
|
||||
name = "minimize";
|
||||
break;
|
||||
case META_MENU_OP_UNMAXIMIZE:
|
||||
name = "unmaximize";
|
||||
break;
|
||||
case META_MENU_OP_MAXIMIZE:
|
||||
name = "maximize";
|
||||
break;
|
||||
case META_MENU_OP_UNSHADE:
|
||||
case META_MENU_OP_SHADE:
|
||||
name = "toggle_shaded";
|
||||
break;
|
||||
case META_MENU_OP_UNSTICK:
|
||||
case META_MENU_OP_STICK:
|
||||
name = "toggle-on-all-workspaces";
|
||||
break;
|
||||
case META_MENU_OP_ABOVE:
|
||||
case META_MENU_OP_UNABOVE:
|
||||
name = "toggle-above";
|
||||
break;
|
||||
case META_MENU_OP_WORKSPACES:
|
||||
switch (workspace)
|
||||
{
|
||||
case 1:
|
||||
name = "move-to-workspace-1";
|
||||
break;
|
||||
case 2:
|
||||
name = "move-to-workspace-2";
|
||||
break;
|
||||
case 3:
|
||||
name = "move-to-workspace-3";
|
||||
break;
|
||||
case 4:
|
||||
name = "move-to-workspace-4";
|
||||
break;
|
||||
case 5:
|
||||
name = "move-to-workspace-5";
|
||||
break;
|
||||
case 6:
|
||||
name = "move-to-workspace-6";
|
||||
break;
|
||||
case 7:
|
||||
name = "move-to-workspace-7";
|
||||
break;
|
||||
case 8:
|
||||
name = "move-to-workspace-8";
|
||||
break;
|
||||
case 9:
|
||||
name = "move-to-workspace-9";
|
||||
break;
|
||||
case 10:
|
||||
name = "move-to-workspace-10";
|
||||
break;
|
||||
case 11:
|
||||
name = "move-to-workspace-11";
|
||||
break;
|
||||
case 12:
|
||||
name = "move-to-workspace-12";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case META_MENU_OP_MOVE:
|
||||
name = "begin-move";
|
||||
break;
|
||||
case META_MENU_OP_RESIZE:
|
||||
name = "begin-resize";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_LEFT:
|
||||
name = "move-to-workspace-left";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_RIGHT:
|
||||
name = "move-to-workspace-right";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_UP:
|
||||
name = "move-to-workspace-up";
|
||||
break;
|
||||
case META_MENU_OP_MOVE_DOWN:
|
||||
name = "move-to-workspace-down";
|
||||
break;
|
||||
case META_MENU_OP_RECOVER:
|
||||
/* No keybinding for this one */
|
||||
break;
|
||||
}
|
||||
if (meta_prefs_get_raise_on_click ())
|
||||
meta_window_raise (window);
|
||||
meta_window_focus (window, timestamp);
|
||||
|
||||
if (name)
|
||||
{
|
||||
meta_prefs_get_window_binding (name, keysym, modifiers);
|
||||
}
|
||||
else
|
||||
{
|
||||
*keysym = 0;
|
||||
*modifiers = 0;
|
||||
}
|
||||
meta_window_show_menu_for_rect (window, menu, rect);
|
||||
}
|
||||
|
||||
const char*
|
||||
@@ -586,12 +436,12 @@ meta_core_begin_grab_op (Display *xdisplay,
|
||||
MetaWindow *window = get_window (xdisplay, frame_xwindow);
|
||||
MetaDisplay *display;
|
||||
MetaScreen *screen;
|
||||
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
screen = display->screen;
|
||||
|
||||
g_assert (screen != NULL);
|
||||
|
||||
|
||||
return meta_display_begin_grab_op (display, screen, window,
|
||||
op, pointer_already_grabbed,
|
||||
frame_action,
|
||||
@@ -604,7 +454,7 @@ meta_core_end_grab_op (Display *xdisplay,
|
||||
guint32 timestamp)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
meta_display_end_grab_op (display, timestamp);
|
||||
@@ -614,7 +464,7 @@ MetaGrabOp
|
||||
meta_core_get_grab_op (Display *xdisplay)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
return display->grab_op;
|
||||
@@ -625,7 +475,7 @@ meta_core_grab_buttons (Display *xdisplay,
|
||||
Window frame_xwindow)
|
||||
{
|
||||
MetaDisplay *display;
|
||||
|
||||
|
||||
display = meta_display_for_x_display (xdisplay);
|
||||
|
||||
meta_verbose ("Grabbing buttons on frame 0x%lx\n", frame_xwindow);
|
||||
@@ -645,46 +495,5 @@ meta_core_set_screen_cursor (Display *xdisplay,
|
||||
void
|
||||
meta_invalidate_default_icons (void)
|
||||
{
|
||||
MetaDisplay *display = meta_get_display ();
|
||||
GSList *windows;
|
||||
GSList *l;
|
||||
|
||||
if (display == NULL)
|
||||
return; /* We can validly be called before the display is opened. */
|
||||
|
||||
windows = meta_display_list_windows (display, META_LIST_DEFAULT);
|
||||
for (l = windows; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWindow *window = (MetaWindow*)l->data;
|
||||
|
||||
if (window->icon_cache.origin == USING_FALLBACK_ICON)
|
||||
{
|
||||
meta_icon_cache_free (&(window->icon_cache));
|
||||
meta_window_update_icon_now (window);
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_free (windows);
|
||||
}
|
||||
|
||||
void
|
||||
meta_core_add_old_event_mask (Display *xdisplay,
|
||||
Window xwindow,
|
||||
XIEventMask *mask)
|
||||
{
|
||||
XIEventMask *prev;
|
||||
gint n_masks, i, j;
|
||||
|
||||
prev = XIGetSelectedEvents (xdisplay, xwindow, &n_masks);
|
||||
|
||||
for (i = 0; i < n_masks; i++)
|
||||
{
|
||||
if (prev[i].deviceid != XIAllMasterDevices)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < MIN (mask->mask_len, prev[i].mask_len); j++)
|
||||
mask->mask[j] |= prev[i].mask[j];
|
||||
}
|
||||
|
||||
XFree (prev);
|
||||
/* XXX: Actually invalidate the icons when they're used. */
|
||||
}
|
||||
|
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter interface used by GTK+ UI to talk to core */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2005 Elijah Newren
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -15,7 +15,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -26,6 +26,7 @@
|
||||
/* Don't include core headers here */
|
||||
#include <gdk/gdkx.h>
|
||||
#include <meta/common.h>
|
||||
#include <meta/boxes.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -33,21 +34,12 @@ typedef enum
|
||||
META_CORE_WINDOW_HAS_FRAME,
|
||||
META_CORE_GET_CLIENT_WIDTH,
|
||||
META_CORE_GET_CLIENT_HEIGHT,
|
||||
META_CORE_GET_CLIENT_XWINDOW,
|
||||
META_CORE_GET_FRAME_FLAGS,
|
||||
META_CORE_GET_FRAME_TYPE,
|
||||
META_CORE_GET_MINI_ICON,
|
||||
META_CORE_GET_ICON,
|
||||
META_CORE_GET_X,
|
||||
META_CORE_GET_Y,
|
||||
META_CORE_GET_FRAME_WORKSPACE,
|
||||
META_CORE_GET_FRAME_X,
|
||||
META_CORE_GET_FRAME_Y,
|
||||
META_CORE_GET_FRAME_WIDTH,
|
||||
META_CORE_GET_FRAME_HEIGHT,
|
||||
META_CORE_GET_FRAME_RECT,
|
||||
META_CORE_GET_THEME_VARIANT,
|
||||
META_CORE_GET_SCREEN_WIDTH,
|
||||
META_CORE_GET_SCREEN_HEIGHT,
|
||||
} MetaCoreGetType;
|
||||
|
||||
/* General information function about the given window. Pass in a sequence of
|
||||
@@ -56,8 +48,8 @@ typedef enum
|
||||
* For example:
|
||||
*
|
||||
* meta_core_get (my_display, my_window,
|
||||
* META_CORE_GET_X, &x,
|
||||
* META_CORE_GET_Y, &y,
|
||||
* META_CORE_GET_FRAME_WIDTH, &width,
|
||||
* META_CORE_GET_FRAME_HEIGHT, &height,
|
||||
* META_CORE_GET_END);
|
||||
*
|
||||
* If the window doesn't have a frame, this will raise a meta_bug. To suppress
|
||||
@@ -93,19 +85,6 @@ void meta_core_get (Display *xdisplay,
|
||||
void meta_core_queue_frame_resize (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
|
||||
/* Move as a result of user operation */
|
||||
void meta_core_user_move (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int x,
|
||||
int y);
|
||||
void meta_core_user_resize (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int gravity,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
void meta_core_user_raise (Display *xdisplay,
|
||||
Window frame_xwindow);
|
||||
void meta_core_user_lower_and_unfocus (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
guint32 timestamp);
|
||||
@@ -153,17 +132,18 @@ const char* meta_core_get_workspace_name_with_index (Display *xdisplay,
|
||||
Window xroot,
|
||||
int index);
|
||||
|
||||
void meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
int root_x,
|
||||
int root_y,
|
||||
int button,
|
||||
guint32 timestamp);
|
||||
void meta_core_show_window_menu (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
MetaWindowMenuType menu,
|
||||
int root_x,
|
||||
int root_y,
|
||||
guint32 timestamp);
|
||||
|
||||
void meta_core_get_menu_accelerator (MetaMenuOp menu_op,
|
||||
int workspace,
|
||||
unsigned int *keysym,
|
||||
MetaVirtualModifier *modifiers);
|
||||
void meta_core_show_window_menu_for_rect (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
MetaWindowMenuType menu,
|
||||
MetaRectangle *rect,
|
||||
guint32 timestamp);
|
||||
|
||||
gboolean meta_core_begin_grab_op (Display *xdisplay,
|
||||
Window frame_xwindow,
|
||||
@@ -189,8 +169,4 @@ void meta_core_set_screen_cursor (Display *xdisplay,
|
||||
|
||||
void meta_invalidate_default_icons (void);
|
||||
|
||||
void meta_core_add_old_event_mask (Display *xdisplay,
|
||||
Window xwindow,
|
||||
XIEventMask *mask);
|
||||
|
||||
#endif
|
||||
|
@@ -2,10 +2,10 @@
|
||||
|
||||
/* Mutter window deletion */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001, 2002 Havoc Pennington
|
||||
* Copyright (C) 2004 Elijah Newren
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -15,7 +15,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -37,49 +37,70 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
|
||||
static void meta_window_present_delete_dialog (MetaWindow *window,
|
||||
guint32 timestamp);
|
||||
|
||||
static void
|
||||
delete_ping_reply_func (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
void *user_data)
|
||||
{
|
||||
meta_topic (META_DEBUG_PING, "Got reply to delete ping for %s\n", window->desc);
|
||||
|
||||
/* we do nothing */
|
||||
}
|
||||
|
||||
static void
|
||||
dialog_exited (GPid pid, int status, gpointer user_data)
|
||||
{
|
||||
MetaWindow *ours = (MetaWindow*) user_data;
|
||||
MetaWindow *window = user_data;
|
||||
|
||||
ours->dialog_pid = -1;
|
||||
window->dialog_pid = -1;
|
||||
|
||||
/* exit status of 1 means the user pressed "Force Quit" */
|
||||
if (WIFEXITED (status) && WEXITSTATUS (status) == 1)
|
||||
meta_window_kill (ours);
|
||||
meta_window_kill (window);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_ping_timeout_func (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
void *user_data)
|
||||
present_existing_delete_dialog (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Presenting existing ping dialog for %s\n",
|
||||
window->desc);
|
||||
|
||||
if (window->dialog_pid >= 0)
|
||||
{
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
|
||||
/* Activate transient for window that belongs to
|
||||
* mutter-dialog
|
||||
*/
|
||||
|
||||
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
if (w->transient_for == window && w->res_class &&
|
||||
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
|
||||
{
|
||||
meta_window_activate (w, timestamp);
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_slist_free (windows);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_delete_dialog (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
char *window_title;
|
||||
gchar *window_content, *tmp;
|
||||
GPid dialog_pid;
|
||||
|
||||
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Got delete ping timeout for %s\n",
|
||||
window->desc);
|
||||
|
||||
if (window->dialog_pid >= 0)
|
||||
{
|
||||
meta_window_present_delete_dialog (window, timestamp);
|
||||
present_existing_delete_dialog (window, timestamp);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -128,15 +149,33 @@ delete_ping_timeout_func (MetaWindow *window,
|
||||
g_child_watch_add (dialog_pid, dialog_exited, window);
|
||||
}
|
||||
|
||||
static void
|
||||
kill_delete_dialog (MetaWindow *window)
|
||||
{
|
||||
if (window->dialog_pid > -1)
|
||||
kill (window->dialog_pid, SIGTERM);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_set_alive (MetaWindow *window,
|
||||
gboolean is_alive)
|
||||
{
|
||||
if (window->is_alive == is_alive)
|
||||
return;
|
||||
|
||||
window->is_alive = is_alive;
|
||||
|
||||
if (window->is_alive)
|
||||
kill_delete_dialog (window);
|
||||
else
|
||||
show_delete_dialog (window, CurrentTime);
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_check_alive (MetaWindow *window,
|
||||
guint32 timestamp)
|
||||
{
|
||||
meta_display_ping_window (window,
|
||||
timestamp,
|
||||
delete_ping_reply_func,
|
||||
delete_ping_timeout_func,
|
||||
NULL);
|
||||
meta_display_ping_window (window, timestamp);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -149,7 +188,7 @@ meta_window_delete (MetaWindow *window,
|
||||
|
||||
if (window->has_focus)
|
||||
{
|
||||
/* FIXME Clean this up someday
|
||||
/* FIXME Clean this up someday
|
||||
* http://bugzilla.gnome.org/show_bug.cgi?id=108706
|
||||
*/
|
||||
#if 0
|
||||
@@ -191,39 +230,3 @@ meta_window_free_delete_dialog (MetaWindow *window)
|
||||
window->dialog_pid = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp)
|
||||
{
|
||||
meta_topic (META_DEBUG_PING,
|
||||
"Presenting existing ping dialog for %s\n",
|
||||
window->desc);
|
||||
|
||||
if (window->dialog_pid >= 0)
|
||||
{
|
||||
GSList *windows;
|
||||
GSList *tmp;
|
||||
|
||||
/* Activate transient for window that belongs to
|
||||
* mutter-dialog
|
||||
*/
|
||||
|
||||
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
|
||||
tmp = windows;
|
||||
while (tmp != NULL)
|
||||
{
|
||||
MetaWindow *w = tmp->data;
|
||||
|
||||
if (w->transient_for == window && w->res_class &&
|
||||
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
|
||||
{
|
||||
meta_window_activate (w, timestamp);
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
g_slist_free (windows);
|
||||
}
|
||||
}
|
||||
|
@@ -2,12 +2,12 @@
|
||||
|
||||
/* Mutter X display handler */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2001 Havoc Pennington
|
||||
* Copyright (C) 2002 Red Hat, Inc.
|
||||
* Copyright (C) 2003 Rob Adams
|
||||
* Copyright (C) 2004-2006 Elijah Newren
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
@@ -17,7 +17,7 @@
|
||||
* 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/>.
|
||||
*/
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <meta/boxes.h>
|
||||
#include <meta/display.h>
|
||||
#include "keybindings-private.h"
|
||||
#include "meta-gesture-tracker-private.h"
|
||||
#include <meta/prefs.h>
|
||||
#include <meta/barrier.h>
|
||||
#include <clutter/clutter.h>
|
||||
@@ -53,10 +54,6 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
|
||||
|
||||
typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
|
||||
|
||||
typedef void (* MetaWindowPingFunc) (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
gpointer user_data);
|
||||
|
||||
typedef enum {
|
||||
META_LIST_DEFAULT = 0, /* normal windows */
|
||||
META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
|
||||
@@ -82,10 +79,28 @@ typedef enum {
|
||||
META_TILE_MAXIMIZED
|
||||
} MetaTileMode;
|
||||
|
||||
typedef enum {
|
||||
/* Normal interaction where you're interacting with windows.
|
||||
* Events go to windows normally. */
|
||||
META_EVENT_ROUTE_NORMAL,
|
||||
|
||||
/* In a compositor grab operation. All events go to the
|
||||
* compositor plugin. */
|
||||
META_EVENT_ROUTE_COMPOSITOR_GRAB,
|
||||
|
||||
/* A Wayland application has a popup open. All events go to
|
||||
* the Wayland application. */
|
||||
META_EVENT_ROUTE_WAYLAND_POPUP,
|
||||
|
||||
/* In a window operation like moving or resizing. All events
|
||||
* goes to MetaWindow, but not to the actual client window. */
|
||||
META_EVENT_ROUTE_WINDOW_OP,
|
||||
} MetaEventRoute;
|
||||
|
||||
struct _MetaDisplay
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
|
||||
char *name;
|
||||
Display *xdisplay;
|
||||
|
||||
@@ -143,21 +158,19 @@ struct _MetaDisplay
|
||||
* multiple events with the same serial.
|
||||
*/
|
||||
guint focused_by_us : 1;
|
||||
|
||||
|
||||
/*< private-ish >*/
|
||||
MetaScreen *screen;
|
||||
GHashTable *xids;
|
||||
GHashTable *wayland_windows;
|
||||
|
||||
int server_grab_count;
|
||||
|
||||
/* serials of leave/unmap events that may
|
||||
* correspond to an enter event we should
|
||||
* ignore
|
||||
*/
|
||||
unsigned long ignored_crossing_serials[N_IGNORED_CROSSING_SERIALS];
|
||||
Window ungrab_should_not_cause_focus_window;
|
||||
|
||||
|
||||
guint32 current_time;
|
||||
|
||||
/* We maintain a sequence counter, incremented for each #MetaWindow
|
||||
@@ -179,13 +192,12 @@ struct _MetaDisplay
|
||||
guint autoraise_timeout_id;
|
||||
MetaWindow* autoraise_window;
|
||||
|
||||
/* Alt+click button grabs */
|
||||
ClutterModifierType window_grab_modifiers;
|
||||
|
||||
/* Event routing */
|
||||
MetaEventRoute event_route;
|
||||
|
||||
/* current window operation */
|
||||
MetaGrabOp grab_op;
|
||||
MetaWindow *grab_window;
|
||||
Window grab_xwindow;
|
||||
int grab_button;
|
||||
int grab_anchor_root_x;
|
||||
int grab_anchor_root_y;
|
||||
@@ -206,35 +218,18 @@ struct _MetaDisplay
|
||||
GTimeVal grab_last_moveresize_time;
|
||||
MetaEdgeResistanceData *grab_edge_resistance_data;
|
||||
unsigned int grab_last_user_action_was_snap;
|
||||
guint32 grab_timestamp;
|
||||
|
||||
/* we use property updates as sentinels for certain window focus events
|
||||
* to avoid some race conditions on EnterNotify events
|
||||
*/
|
||||
int sentinel_counter;
|
||||
|
||||
#ifdef HAVE_XKB
|
||||
int xkb_base_event_type;
|
||||
guint32 last_bell_time;
|
||||
#endif
|
||||
int grab_resize_timeout_id;
|
||||
|
||||
/* Keybindings stuff */
|
||||
GHashTable *key_bindings;
|
||||
GHashTable *key_bindings_index;
|
||||
int min_keycode;
|
||||
int max_keycode;
|
||||
KeySym *keymap;
|
||||
int keysyms_per_keycode;
|
||||
unsigned int ignored_modifier_mask;
|
||||
unsigned int hyper_mask;
|
||||
unsigned int super_mask;
|
||||
unsigned int meta_mask;
|
||||
MetaKeyCombo overlay_key_combo;
|
||||
gboolean overlay_key_only_pressed;
|
||||
MetaKeyCombo *iso_next_group_combos;
|
||||
int n_iso_next_group_combos;
|
||||
|
||||
MetaKeyBindingManager key_binding_manager;
|
||||
|
||||
/* Monitor cache */
|
||||
unsigned int monitor_cache_invalidated : 1;
|
||||
|
||||
@@ -247,10 +242,6 @@ struct _MetaDisplay
|
||||
/* Managed by group.c */
|
||||
GHashTable *groups_by_leader;
|
||||
|
||||
/* currently-active window menu if any */
|
||||
MetaWindowMenu *window_menu;
|
||||
MetaWindow *window_with_menu;
|
||||
|
||||
/* Managed by window-props.c */
|
||||
MetaWindowPropHooks *prop_hooks_table;
|
||||
GHashTable *prop_hooks;
|
||||
@@ -262,6 +253,9 @@ struct _MetaDisplay
|
||||
/* Managed by compositor.c */
|
||||
MetaCompositor *compositor;
|
||||
|
||||
MetaGestureTracker *gesture_tracker;
|
||||
ClutterEventSequence *pointer_emulating_sequence;
|
||||
|
||||
int composite_event_base;
|
||||
int composite_error_base;
|
||||
int composite_major_version;
|
||||
@@ -320,8 +314,6 @@ struct _MetaDisplayClass
|
||||
gboolean meta_display_open (void);
|
||||
void meta_display_close (MetaDisplay *display,
|
||||
guint32 timestamp);
|
||||
void meta_display_grab (MetaDisplay *display);
|
||||
void meta_display_ungrab (MetaDisplay *display);
|
||||
|
||||
void meta_display_unmanage_windows_for_screen (MetaDisplay *display,
|
||||
MetaScreen *screen,
|
||||
@@ -367,9 +359,7 @@ MetaDisplay* meta_get_display (void);
|
||||
Cursor meta_display_create_x_cursor (MetaDisplay *display,
|
||||
MetaCursor cursor);
|
||||
|
||||
void meta_display_set_grab_op_cursor (MetaDisplay *display,
|
||||
MetaGrabOp op,
|
||||
guint32 timestamp);
|
||||
void meta_display_update_cursor (MetaDisplay *display);
|
||||
|
||||
void meta_display_check_threshold_reached (MetaDisplay *display,
|
||||
int x,
|
||||
@@ -399,26 +389,17 @@ const char* meta_event_detail_to_string (int d);
|
||||
void meta_display_queue_retheme_all_windows (MetaDisplay *display);
|
||||
void meta_display_retheme_all (void);
|
||||
|
||||
void meta_display_ping_window (MetaWindow *window,
|
||||
guint32 timestamp,
|
||||
MetaWindowPingFunc ping_reply_func,
|
||||
MetaWindowPingFunc ping_timeout_func,
|
||||
void *user_data);
|
||||
void meta_display_pong_for_serial (MetaDisplay *display,
|
||||
guint32 serial);
|
||||
void meta_display_ping_window (MetaWindow *window,
|
||||
guint32 serial);
|
||||
void meta_display_pong_for_serial (MetaDisplay *display,
|
||||
guint32 serial);
|
||||
|
||||
int meta_resize_gravity_from_grab_op (MetaGrabOp op);
|
||||
|
||||
gboolean meta_grab_op_is_moving (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_resizing (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_moving_or_resizing (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_mouse (MetaGrabOp op);
|
||||
gboolean meta_grab_op_is_keyboard (MetaGrabOp op);
|
||||
gboolean meta_grab_op_should_block_wayland (MetaGrabOp op);
|
||||
|
||||
void meta_display_devirtualize_modifiers (MetaDisplay *display,
|
||||
MetaVirtualModifier modifiers,
|
||||
unsigned int *mask);
|
||||
|
||||
void meta_display_increment_focus_sentinel (MetaDisplay *display);
|
||||
void meta_display_decrement_focus_sentinel (MetaDisplay *display);
|
||||
@@ -456,4 +437,20 @@ void meta_display_sanity_check_timestamps (MetaDisplay *display,
|
||||
gboolean meta_display_timestamp_too_old (MetaDisplay *display,
|
||||
guint32 *timestamp);
|
||||
|
||||
void meta_display_remove_pending_pings_for_window (MetaDisplay *display,
|
||||
MetaWindow *window);
|
||||
|
||||
MetaGestureTracker * meta_display_get_gesture_tracker (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_show_restart_message (MetaDisplay *display,
|
||||
const char *message);
|
||||
gboolean meta_display_request_restart (MetaDisplay *display);
|
||||
|
||||
void meta_restart_init (void);
|
||||
void meta_restart_finish (void);
|
||||
|
||||
void meta_display_cancel_touch (MetaDisplay *display);
|
||||
|
||||
gboolean meta_display_windows_are_interactable (MetaDisplay *display);
|
||||
|
||||
#endif
|
||||
|
1334
src/core/display.c
1334
src/core/display.c
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user