Compare commits
1295 Commits
3.22.3
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
255a7afe73 | |||
3649795108 | |||
36b9551f92 | |||
6abe4703c7 | |||
69ca584168 | |||
8ee14a7cb7 | |||
909dbafd67 | |||
d5203f170e | |||
2a45b7de7c | |||
62c67be4c8 | |||
0332b7394e | |||
15f41c9f68 | |||
2a38601b42 | |||
d7bdc1591f | |||
bd36764b4d | |||
473bf38753 | |||
f7747e4d4f | |||
e8dc2acfca | |||
cf734999fb | |||
c9c3283540 | |||
d2a8cdfd7c | |||
3e85ac8131 | |||
5f83d9a5c8 | |||
ac20bf2000 | |||
3561082aba | |||
e34c330f66 | |||
7655e09d00 | |||
be069fb8ae | |||
a30166a547 | |||
0f9c6aef99 | |||
332d55f7f6 | |||
98d7024288 | |||
82564772dc | |||
33c2a38ff7 | |||
52fdd24467 | |||
2319cd9c40 | |||
3b4319a87c | |||
20176d0395 | |||
762a3f89a9 | |||
822c2666f5 | |||
b412e6c493 | |||
ae26cd0774 | |||
3104d697c0 | |||
0b3a1c9c31 | |||
423c5f8e77 | |||
3bbff94878 | |||
4ef886f51e | |||
22485ba36f | |||
8df2a1452c | |||
b12c92e206 | |||
70036429bd | |||
44502be560 | |||
8cf42cd06c | |||
b5328c977e | |||
4339b23dd0 | |||
a95cbd0aca | |||
6df2b7af55 | |||
c01b099dbd | |||
2d80fd02e7 | |||
bb65854065 | |||
bc05e49eba | |||
773b8384fa | |||
7fdac6d310 | |||
f6cd87734d | |||
01a0fa9437 | |||
657417a578 | |||
4af00ae296 | |||
84e575be77 | |||
7945ee5beb | |||
b6f5bab212 | |||
5ad34e0efb | |||
a1c34aad09 | |||
98dfd5b887 | |||
17a745bf81 | |||
85bbd82ae8 | |||
deda7a5235 | |||
96141e28f9 | |||
e6109cfc22 | |||
3684f6b0ac | |||
31b5059068 | |||
ebff7fd7f4 | |||
6e415353e3 | |||
67917db45f | |||
8286557a05 | |||
63e2c0329f | |||
06c357d781 | |||
2f260edf19 | |||
a5fd9a6e2f | |||
4e6114b14d | |||
65630d6310 | |||
b8a81128e0 | |||
19e55b9a8c | |||
9ea9352c93 | |||
817a76a7f5 | |||
cb40049ec1 | |||
481e87032c | |||
bf5ac39d46 | |||
47856d9701 | |||
06429b12e2 | |||
419fb81d40 | |||
f1bbe5c251 | |||
27fef44d48 | |||
00b8ca7aeb | |||
675d429ba0 | |||
f4d754c934 | |||
8ae79182c1 | |||
712ec30cd9 | |||
7a41483ea0 | |||
b4d642be52 | |||
0bf0e5780c | |||
d7c5e57134 | |||
67bf936ef8 | |||
15b7b40ea8 | |||
81bff3eba6 | |||
da3fd8f7fb | |||
6e125d9d04 | |||
80705018f9 | |||
f39dacd451 | |||
33c070cdd5 | |||
8d2f794bd3 | |||
1458dc394a | |||
c93877abb5 | |||
ef0efc9589 | |||
09cdf39b68 | |||
a6ccbbfe68 | |||
e502adfa04 | |||
8dd377da38 | |||
03a12f9458 | |||
061f69f2a2 | |||
4d5e1f690d | |||
f3203f0330 | |||
d27e6921d6 | |||
c459ad7932 | |||
5ee825c081 | |||
1ead513b66 | |||
9ed236bd67 | |||
a1517cae1c | |||
542502be53 | |||
203a0b37ed | |||
b6477a826d | |||
95adc45b71 | |||
f20daf567d | |||
4345906663 | |||
d714a94d97 | |||
514c7028f4 | |||
44624736c5 | |||
0162cdf8ef | |||
7e17dd0098 | |||
704b73b041 | |||
bd5e36cf0e | |||
dbf56e24cb | |||
0371897e22 | |||
cc5fe05c4d | |||
d8f13f6b4c | |||
a2959510e5 | |||
c8fbd4bee8 | |||
d5631f793e | |||
d4d160a186 | |||
4719c3f31e | |||
1f5a2d6029 | |||
19bf4cf4f8 | |||
6f59e4858e | |||
aec85281ba | |||
b22875aae9 | |||
962712ddc2 | |||
de29627855 | |||
54dcff3aa2 | |||
bcd5882081 | |||
69f56578a3 | |||
c00e092456 | |||
a8cee14417 | |||
8a89b0007c | |||
6934b83f44 | |||
37aab9280a | |||
49e8bc8a52 | |||
abd6b7affd | |||
748223b896 | |||
c75eac27a8 | |||
ac502c921d | |||
134765c634 | |||
5149d6eb40 | |||
006cdac531 | |||
61bc1a7d6f | |||
86ab3878e7 | |||
f2d0e5021a | |||
6d8286614f | |||
70fcf745b8 | |||
589e999049 | |||
d8f2f583e6 | |||
db866eb052 | |||
d092e913d6 | |||
6147be3dff | |||
57f55d486d | |||
6be56de140 | |||
206ca43c91 | |||
f8f1bcfa9e | |||
91df801ffb | |||
97f142d1cc | |||
5ea3a4ecbb | |||
fbd5a74a0b | |||
58bb61e161 | |||
dbd053020a | |||
c063d43be8 | |||
35b77a61c8 | |||
32547d2eff | |||
dc37ee2782 | |||
371e5df568 | |||
cc4e007148 | |||
c0d9b08ef9 | |||
d99cd279d2 | |||
d670a1aa78 | |||
76b396846d | |||
bd0105ba8d | |||
6dcce19932 | |||
cc40a885ef | |||
513c278077 | |||
ac8ee9a08c | |||
952c1fefa2 | |||
18b8f9bfed | |||
f08417b618 | |||
62c9713361 | |||
efd7a4af5e | |||
3a914a915e | |||
aa6561a3b1 | |||
9eb9623288 | |||
8c988aa632 | |||
13cf19e0b6 | |||
eac0e253e1 | |||
7346419295 | |||
3e77f6704b | |||
01e27a4366 | |||
4e3b26d2ed | |||
5f05112b9a | |||
6cf7d2d47f | |||
1139ace244 | |||
bd9a300801 | |||
2d090f9232 | |||
1c8aebd811 | |||
31eafba93a | |||
5eacdf7af7 | |||
ca638d1354 | |||
f12e6ad4f1 | |||
0bbda3ad87 | |||
dd43d04d42 | |||
383ac76d00 | |||
e59ca14f6c | |||
7917b083cb | |||
2b3040d04f | |||
6cc48d8cbb | |||
798026498d | |||
49f029571c | |||
290b257288 | |||
2b60fb0144 | |||
7f5f5eb847 | |||
44269e6a1d | |||
70dfe8c97d | |||
072afa5fa3 | |||
519a0fd93d | |||
5f132f3975 | |||
1546989845 | |||
1923db97c1 | |||
db32047a5d | |||
b505eb261e | |||
1a1db9ef8d | |||
b1587f0716 | |||
93e450f37c | |||
fc713ecb70 | |||
500c13ab6f | |||
050267fe74 | |||
ce25a0171c | |||
b7518c8651 | |||
62dedfbef3 | |||
4508978ea5 | |||
c533a06e93 | |||
5d3b4f0134 | |||
4cf340ae9b | |||
053ac03f01 | |||
28a9439209 | |||
cf4b5efdd1 | |||
3067dab84c | |||
1790320ba3 | |||
f45df4265d | |||
bcbcd6a68c | |||
b1a0bf8916 | |||
6c18bae83c | |||
d0531966eb | |||
989a47ee8c | |||
03be6b687b | |||
32c22d375a | |||
bdf3f49a82 | |||
356b4b0dc5 | |||
3fc2ea8297 | |||
06d976e853 | |||
96ebd1c214 | |||
fa28481736 | |||
76b064cffc | |||
333b5d12a0 | |||
aa73504d95 | |||
32305b453d | |||
7d5e08c843 | |||
dc0fc65229 | |||
428af6d213 | |||
2ffe597617 | |||
0461eed0cb | |||
ca1bacc212 | |||
2229365ca8 | |||
8c367364b6 | |||
58909da425 | |||
ff32bf467c | |||
c5572d3095 | |||
e706bcdf73 | |||
d9ebcbd55c | |||
240b13aa74 | |||
97635d6f84 | |||
6c21a22e4d | |||
0add6f62b6 | |||
049418cd03 | |||
3ee1999c70 | |||
e4b8920688 | |||
eb236649fc | |||
0a36a4545f | |||
180985018b | |||
c86c5d6905 | |||
c2fad2dc7c | |||
1196b7bde4 | |||
19eddfd756 | |||
ed280ef4ac | |||
b6200ac3ff | |||
626621a53a | |||
fb3a64491e | |||
294f9419f7 | |||
a37956c95f | |||
89f5ca3301 | |||
07745b3082 | |||
054c25f693 | |||
01de04d8c9 | |||
08e4cb54a8 | |||
c71faffb71 | |||
91e3a0b3a9 | |||
5fa8f78434 | |||
ab5ac21104 | |||
0ebea2be9c | |||
6f54bab0a8 | |||
5d7deab6da | |||
35fcf4a4ae | |||
74565380aa | |||
fa37496ffb | |||
cc772ddd61 | |||
4d2647cdbc | |||
3caefd8fda | |||
12381d57d1 | |||
4ad8c4b86b | |||
dbd2827ca1 | |||
1a78557e0b | |||
2e99963087 | |||
4d763e1828 | |||
a17b343c21 | |||
556136dacc | |||
a8c80ccece | |||
f044511037 | |||
b31e545c9d | |||
fad5657eda | |||
eaf9ccde39 | |||
f9c625924e | |||
64cb735abf | |||
c85f322b20 | |||
76096a725b | |||
6eb7d13894 | |||
7928b25ebf | |||
78e6258b44 | |||
c9259c2b15 | |||
492d2eb573 | |||
376dcd3b92 | |||
60781bc6c2 | |||
2d8827cb0c | |||
802f7dcd30 | |||
e62cfd9043 | |||
cbcf6a4f23 | |||
b0e42d3f6e | |||
18eb66de06 | |||
b32cccddf9 | |||
362e26b3e2 | |||
5c53284bde | |||
e45d7f70e8 | |||
70edc7dda4 | |||
3244ed37a9 | |||
406359bba1 | |||
8b23dd915f | |||
7e1f65405f | |||
c1683073f1 | |||
18ec86bd90 | |||
315a6f43d7 | |||
7603bb5fd5 | |||
d53b79f8c3 | |||
f534452c6a | |||
0f6b83e7df | |||
16a6aef5a7 | |||
518fb9fb5e | |||
547ace3cf8 | |||
a4ba38ee78 | |||
e32d52b9b8 | |||
de40ced8b4 | |||
cfee58798e | |||
7ea01693a7 | |||
e0d839aea2 | |||
d3efd73429 | |||
2db5505216 | |||
f44b6c772a | |||
f64fab1d2d | |||
39bc2e0333 | |||
5bb6f0ad8b | |||
903537a2a0 | |||
1db937826c | |||
c1fe1c5d6b | |||
a62e9f99a2 | |||
9817a6aa47 | |||
8185373bd4 | |||
18c41aefc9 | |||
32917f1922 | |||
7a843e1fd1 | |||
0e154ccf76 | |||
120db06c60 | |||
e76ab05d45 | |||
43eeb009ce | |||
9000eef49d | |||
e198c8452b | |||
aea66ddff6 | |||
a5f4ffa58c | |||
a1c39e142d | |||
e76a0f564c | |||
8307d9c4de | |||
1dbf6b096b | |||
6fe71ecc01 | |||
57e58eaf2a | |||
00a5db71cf | |||
c7fa57cd28 | |||
8f2c86d79e | |||
56f1da5c66 | |||
30a205c0e3 | |||
98d77d37d0 | |||
0853fb940a | |||
6dd819a61e | |||
39aae19ed7 | |||
20749e5dbd | |||
99e1cd549d | |||
efdbeb7c1b | |||
ea4dbd14bc | |||
838df4b00b | |||
b6110ba8dc | |||
fd763ad857 | |||
e3d59832c5 | |||
2c85bb4178 | |||
8493777961 | |||
4e7405aca9 | |||
34207ba509 | |||
6dc499f305 | |||
92e2242cf0 | |||
ea214fbe0f | |||
487b8a0430 | |||
8b060342bd | |||
27d6c063ad | |||
0e62b71959 | |||
2c3f79829e | |||
5d2b0bc0cc | |||
7e3a780dcd | |||
1035200f26 | |||
8532b10290 | |||
f0c6c4eb1f | |||
ba194bd19e | |||
a35274ddb7 | |||
ab541e3e0f | |||
67ce04993e | |||
22cdc8f414 | |||
8b022a5595 | |||
7a1393ba26 | |||
5ed954e6de | |||
96572fbe6a | |||
4ab47e72e5 | |||
70e0fd0b45 | |||
26cd031be8 | |||
743e8cc249 | |||
2bf7974076 | |||
9c16e4e2f3 | |||
07f6c85cc7 | |||
d4968e10e5 | |||
bd3817198e | |||
5b5737f65e | |||
5af8753171 | |||
8bef74f441 | |||
f1a42b0f97 | |||
95682a9494 | |||
ef41867303 | |||
8d4b03ce87 | |||
06263354a5 | |||
aa30e11c8b | |||
65bca8e008 | |||
068791f6c1 | |||
cbc4563b30 | |||
f381d7c3bf | |||
0a8d8128b3 | |||
46135d4f0f | |||
7ba44e7945 | |||
dd4ad4efc4 | |||
807658e972 | |||
8499a29d0a | |||
283eedef90 | |||
ce515c5389 | |||
83440614bc | |||
a93661f9e1 | |||
216f7631de | |||
361bf847af | |||
46f54eb3d9 | |||
bc47c6cc4f | |||
8bfdfa1f46 | |||
999542c915 | |||
cb38e9c4a2 | |||
42c56c2460 | |||
e2d904c32b | |||
fa9c09feee | |||
3f6a2d02fd | |||
5b37901b57 | |||
2df4ccd1cd | |||
dcd15e6145 | |||
2a318eb3f2 | |||
522eec00cd | |||
be11c32815 | |||
24c91d95de | |||
7562eb6006 | |||
0aa7405a2a | |||
a119e58773 | |||
8a32b42172 | |||
94a15404da | |||
fefede5b51 | |||
5be00f23be | |||
bdbd2e96de | |||
7785a57f8a | |||
cf01e26b2f | |||
6e46ad9f3a | |||
921b18f713 | |||
53175e8788 | |||
920541fa26 | |||
9d8922764c | |||
97f2c7c161 | |||
38235bc145 | |||
3ce3a5a952 | |||
3005a400ca | |||
34e7134db2 | |||
12710dc644 | |||
a10ad577a7 | |||
d3c559a917 | |||
1e7628a3ef | |||
d5a85997f2 | |||
5a37e0e1ef | |||
00f6a74397 | |||
c9439107c1 | |||
ba65664cbd | |||
3da0730a31 | |||
98fcd616a3 | |||
06d0989014 | |||
c248feb3c1 | |||
3f2c5ca9bd | |||
520c56fe53 | |||
d3a670b043 | |||
6eca267eee | |||
fdefe776d3 | |||
bba8776184 | |||
e075242801 | |||
0f9686fb5a | |||
168479862d | |||
483ed98777 | |||
14fe6e9c95 | |||
6584d06bb5 | |||
92a53f08f4 | |||
a81d4aed7a | |||
517488ef67 | |||
33f1706634 | |||
5685449e15 | |||
a6d67b164a | |||
f950380202 | |||
a4270fa7ac | |||
35c9280fb6 | |||
8b92ad1d4b | |||
0d6e3fd675 | |||
b140e7fbeb | |||
6c0f107db0 | |||
61950755ec | |||
bc3162460f | |||
27a4f9f862 | |||
88f2441330 | |||
ab04286c6b | |||
e8a62861c9 | |||
9ac87b36c1 | |||
ce7819949f | |||
12792f99a0 | |||
66996dee4b | |||
2f45e88f06 | |||
c1439e141e | |||
dceb0f1f1f | |||
a7915ff8ae | |||
420a712ad5 | |||
9a47e5c832 | |||
dbc63430d8 | |||
0f861cecac | |||
586f9666d7 | |||
05a2331052 | |||
9f8bee7781 | |||
d9505315da | |||
c9937faf1e | |||
98606bc046 | |||
49096f0530 | |||
ff6eb86bb4 | |||
c735eab216 | |||
299aa9759c | |||
35e9020f4c | |||
6d4234e300 | |||
0457870ff1 | |||
a52c4c2795 | |||
bb8c388a37 | |||
46cb506f8f | |||
ce20c964a6 | |||
e3f76e9482 | |||
b894fbd9ff | |||
2ca0871724 | |||
dd12f569d9 | |||
c54377e3ba | |||
346acaf7f6 | |||
3343a199c2 | |||
1fb3c9f8bf | |||
b7b5fb293d | |||
1455c402b9 | |||
4c1fe4c30d | |||
9b97a44760 | |||
26fa7b8f6a | |||
7486783692 | |||
9929efb65e | |||
5db48faca4 | |||
b0c54b6675 | |||
d8354cb153 | |||
9a348aa859 | |||
fe6e24ddbd | |||
7e330bd65f | |||
3f9c5823cb | |||
2bdd97e067 | |||
32fd1e8c08 | |||
e126b6ed16 | |||
4d8cb5408b | |||
f852d2b0eb | |||
5c3b27d02f | |||
ead6556b50 | |||
4afa66fe41 | |||
408292959e | |||
2d8d9dea97 | |||
f38c90961a | |||
aa47374d0e | |||
5aee5048ba | |||
0e3f80d238 | |||
ef13ee4488 | |||
8b5d34b24a | |||
c614a2db28 | |||
7360f51ee8 | |||
6ae42f3845 | |||
26b66826dc | |||
6d082bf442 | |||
aad2280309 | |||
e3d5bc077d | |||
777963eeb6 | |||
4cc5b25493 | |||
49c5228655 | |||
85638c1b19 | |||
2507e53d04 | |||
a9c1c6d9fb | |||
0a8e108f10 | |||
859b01fc39 | |||
e42206cc43 | |||
41eea5a942 | |||
197401fbf8 | |||
9ab338d7b6 | |||
aa5d8ac68c | |||
0adc56779f | |||
67eb289a6a | |||
dfc4d0d523 | |||
5f2bb43061 | |||
fef81cd628 | |||
3e8d0204bd | |||
b2a530b326 | |||
5ab116a87f | |||
10b0351a59 | |||
b64c69e4bc | |||
c2e49f1bb5 | |||
a3d63d0ac0 | |||
88cae8bd3d | |||
a6ec2b1d42 | |||
ca600973ba | |||
4b8dd51c4d | |||
56c468a2ef | |||
10b30eaba5 | |||
328e3f8f4f | |||
7bd69f0b32 | |||
538e402d71 | |||
9af6ec78ab | |||
41e22ab592 | |||
1303c626b1 | |||
7eea82d3d7 | |||
80e5955918 | |||
ce989976fa | |||
529e5adb2e | |||
a70ae50ca9 | |||
74882b2502 | |||
5f49bda591 | |||
edab8c3a4c | |||
8153c5b544 | |||
a4cef8586c | |||
9b9bb9cf86 | |||
dc5b2e396c | |||
d23275bc76 | |||
48e820235e | |||
2d3c56b089 | |||
85b2e59e7e | |||
e1950ed76f | |||
7938f41c11 | |||
9f41bdb086 | |||
8457e2bad6 | |||
4d7329a7e2 | |||
b4120a75e0 | |||
b19e4592df | |||
e9c9ee844c | |||
f5f0ff0a2f | |||
68dacb531b | |||
dd82f4afcd | |||
fc010e0edc | |||
5132ea64be | |||
82325cbcfd | |||
fb5ebffb8d | |||
94d843b80e | |||
c32e2d17d9 | |||
2b05748d5c | |||
cd775929bf | |||
7303a78b06 | |||
07b8cc0773 | |||
1bb0e18042 | |||
05bc2e2331 | |||
3b097c7e77 | |||
0bc312a54b | |||
2718699ccc | |||
be175558c3 | |||
df39a7d0fd | |||
43cdf81f6b | |||
183f4b0c13 | |||
38a772bce7 | |||
dd451547a5 | |||
270da95cbc | |||
76198e0b3b | |||
efc190789f | |||
81e99c2680 | |||
755755a2f3 | |||
4b23eb064c | |||
498200776c | |||
27b949d6ba | |||
27ea62a79d | |||
cf1edff9ed | |||
5cb5baa7d4 | |||
d620189ae3 | |||
bc041e02b3 | |||
4b4c2b1afa | |||
05d15f8885 | |||
561d71b8ae | |||
177e47952a | |||
374bb630f0 | |||
fe5138dfc4 | |||
68a9675d42 | |||
020e0bb2ac | |||
b47de58edd | |||
24195d8d15 | |||
3a7c37c60a | |||
c69d5d978c | |||
2f30098ab5 | |||
e146428038 | |||
5758401443 | |||
f241bdba93 | |||
410d66ca37 | |||
f2309cdb55 | |||
3887d25dbc | |||
d6d01c85a6 | |||
d0bfb94ff0 | |||
2b1537cdf5 | |||
d3362a6f05 | |||
9cf8aa4584 | |||
c76eedd794 | |||
9131f26cae | |||
8ed0dda40d | |||
0fd9e38175 | |||
891cab3bb3 | |||
454bd88d27 | |||
3ced749c89 | |||
69b6479502 | |||
a641b59f22 | |||
704bd4c331 | |||
229ac9c9dc | |||
e435cf301f | |||
0608ae2d4e | |||
3f107da479 | |||
813de50eba | |||
a4cb1f0f7a | |||
612432ac3e | |||
47a01013b1 | |||
69e7ad4402 | |||
c214eb15bf | |||
e6eac46629 | |||
de61da16ae | |||
bdcb395b33 | |||
1caa7f7627 | |||
5b4a96e3a3 | |||
15dd23a323 | |||
04d7fcf60d | |||
9755cd469c | |||
1bdadfa3e1 | |||
20fcb88632 | |||
6791d1b8e2 | |||
6c8b103a7b | |||
95d0117784 | |||
740436ab4d | |||
89fbf1e1d2 | |||
c391cefd71 | |||
52af529950 | |||
c30cb069f5 | |||
99a0b43f28 | |||
af4017de49 | |||
d804ecbd95 | |||
1ad3382bff | |||
9787b1cfd5 | |||
0ac2eba4d3 | |||
17c54c6e03 | |||
dd14e1cebc | |||
1e2266aa47 | |||
472a434212 | |||
7c226462e0 | |||
93c6a869ec | |||
9d914091f5 | |||
afcc1bf512 | |||
8a29c51b73 | |||
d38c4c1f2d | |||
2091df3856 | |||
744b4dcb7c | |||
0c64c35a8a | |||
57acbc53fb | |||
ac68631f4c | |||
8163ca6821 | |||
094e0356e8 | |||
63450d69d3 | |||
0952409de4 | |||
1c54c7a1bb | |||
f25f14351c | |||
691e7951ea | |||
7eaeba520a | |||
9a5b94a340 | |||
079b125430 | |||
770a5a5bff | |||
0548c9e7d5 | |||
68a6cc5976 | |||
2035f2f2e2 | |||
1892a6b0c4 | |||
b464004bb3 | |||
ea4438284f | |||
d050fdb17f | |||
9003a42df3 | |||
9e8ee491e6 | |||
3b46345db4 | |||
6b2a111428 | |||
bc56971e18 | |||
fcc0288f0c | |||
4e03e89869 | |||
4e17017501 | |||
63bc86cd43 | |||
ee32ca3efe | |||
a393a614a1 | |||
753e9c65a1 | |||
409c92a68f | |||
53a93deafc | |||
3a374a6db5 | |||
aec4b4af97 | |||
2392432780 | |||
0d5274b3b7 | |||
42c0809216 | |||
420311b463 | |||
efae039ad9 | |||
e60dfd5b23 | |||
df45c50d0b | |||
8f691c28f3 | |||
a77da353f3 | |||
70a4f59960 | |||
ac813d5285 | |||
5d3e7d6ffd | |||
5b378ea648 | |||
ea04ff5d46 | |||
982ad7361b | |||
10dfe2059b | |||
61e9594f63 | |||
2d8eaa082f | |||
29b240e883 | |||
e081bb3921 | |||
ad24967d78 | |||
90d83b4bb9 | |||
eb3ff3f44a | |||
db14e6099e | |||
5aa02c0378 | |||
73b2b30a1d | |||
cf6b7bcb79 | |||
4b86af839f | |||
f434f88c0c | |||
cdedd017d6 | |||
a48c9d6cd9 | |||
1039386e10 | |||
944339f6a5 | |||
4cfcd4bce0 | |||
4f386e5131 | |||
3ace913aed | |||
8f2daed9e0 | |||
c5dc0f4a2e | |||
615587cd06 | |||
df068a3649 | |||
7967ceee98 | |||
979bc4390a | |||
e20e60783a | |||
38c5a1610e | |||
572610d01e | |||
21b2eff334 | |||
35388fb33c | |||
aa5738c777 | |||
f7ffb1790f | |||
65e9c89ed9 | |||
5fafaf92df | |||
4e4b24e7a8 | |||
542ed1d024 | |||
eda0f45ab5 | |||
4fdc551209 | |||
58043cbc8b | |||
09fa27cd09 | |||
d8ee96c6cb | |||
3821ed162b | |||
1f20e82a96 | |||
1079850621 | |||
aab5f7c42b | |||
f8a6c27791 | |||
95e9fa10ef | |||
89871e04aa | |||
1705a26fc7 | |||
95c924460a | |||
97b1a8dfc8 | |||
fbcc8fae77 | |||
3d2cb7f1ef | |||
fc9a24824a | |||
383ba566bd | |||
d200868459 | |||
690b232258 | |||
e078838774 | |||
1b03dd6704 | |||
1171c4f16d | |||
a9f139cab6 | |||
5ba38a4ab6 | |||
8f5a0ec83d | |||
bb2e8ff09a | |||
1fe10f09d7 | |||
328b4d24c6 | |||
4b2d4a0169 | |||
3564b5845e | |||
2907b234c9 | |||
e1ffe15d94 | |||
1b0a3f11f9 | |||
b202f5d094 | |||
cd5c52b550 | |||
46d516cb04 | |||
4d0a886c45 | |||
5db3eebfbb | |||
36ee6f656a | |||
966725fcb4 | |||
90923903ae | |||
191525cdb4 | |||
2d18b18fe5 | |||
ead62f1901 | |||
f97b2d49f5 | |||
827db6f7c7 | |||
91c6a144da | |||
cb86745245 | |||
6b384dc8d1 | |||
a25915f4f9 | |||
92a7690e19 | |||
1372690c7f | |||
bd2ca79a48 | |||
6d64123849 | |||
042a95ef98 | |||
2d3af657e7 | |||
4ebc55f2b3 | |||
7c80e80a92 | |||
4c5ec5dfa8 | |||
c995c0ad1f | |||
d870ed4317 | |||
9950b4de75 | |||
7e3fbfbdd2 | |||
ff453c1143 | |||
efd9d467f2 | |||
07ce981cb0 | |||
5af848d991 | |||
fff7da2a96 | |||
d6fc41b73e | |||
9d38ffa6e3 | |||
8bcdf9ba61 | |||
938891a2e2 | |||
45c9786434 | |||
cfbc4fe4d0 | |||
dae5f06069 | |||
1ff9bbd59c | |||
cc838ead8b | |||
9a123847e0 | |||
1f0659d516 | |||
4f31b53521 | |||
962e1d5a69 | |||
57f80f091f | |||
9c79a1631d | |||
c7853730ed | |||
2cd78bffd9 | |||
1597b357a1 | |||
73524cadd4 | |||
6fa8238ebf | |||
1c6eef48f1 | |||
1fdf2ac746 | |||
3ae9feef0c | |||
e9a8208607 | |||
e357b4a46a | |||
097ca01411 | |||
e8197e8e05 | |||
7fc6b8a746 | |||
0fd9c00580 | |||
4a51a1dfe5 | |||
9fb8abf840 | |||
449320cd23 | |||
12b69dbabb | |||
4652bde3d7 | |||
9b4e1903e1 | |||
702facbc91 | |||
339340df34 | |||
1ad386bc28 | |||
28a8c714ea | |||
c9f18bfef3 | |||
20cd885443 | |||
3f994646f2 | |||
f45e7703ba | |||
1ee0412177 | |||
4b33f05eda | |||
81923410f6 | |||
f19cb6a610 | |||
cde1a730e8 | |||
d6efdfab4b | |||
f7b6271d86 | |||
8d1be7ffc0 | |||
a0af7e94a6 | |||
f607b03456 | |||
644ee666f6 | |||
ee0677a021 | |||
0b4d80d74f | |||
1a2b493d17 | |||
9ceeddd952 | |||
e1849ccbfa | |||
6262b46928 | |||
8752f40792 | |||
8c5600e81b | |||
4c1b48d0cc | |||
536ae8430b | |||
aaddf44d45 | |||
0c42faf34d | |||
be13d0f8ee | |||
81438eebef | |||
b70187c2d9 | |||
c041851fa5 | |||
b59a8b1de3 | |||
e3b9fe7e58 | |||
0177ab45af | |||
bc951557e8 | |||
2c32d94e1d | |||
5d9e2d8d2e | |||
0637537355 | |||
63ed134165 | |||
a6f464a600 | |||
0a0c49af71 | |||
3c6d688c87 | |||
5d66a13397 | |||
ff633f295e | |||
310064601c | |||
78799e58d2 | |||
4fa8b74dc7 | |||
bf8b4e9927 | |||
f48acd8448 | |||
d0c9d2dc7b | |||
d9a0f2a88d | |||
4e812410cc | |||
0873e3812b | |||
7eac28189b | |||
1650c35e38 | |||
156c478ccb | |||
10e6eae0dd | |||
f519093f89 | |||
8a8ab6c673 | |||
9e28303588 | |||
6776329cf5 | |||
2e4c516d43 | |||
d920eaba4a | |||
376a76a082 | |||
c6d940d3b2 | |||
95c101a0ba | |||
239671f882 | |||
12150c1ca7 | |||
a251675cc0 | |||
d188949101 | |||
d3920ddb67 | |||
bc5077f623 | |||
68f3b5849a | |||
6de3e4a07e | |||
1fb0e8e9bb | |||
20b8743f21 | |||
016359ede2 | |||
410bad88a8 | |||
c98bab8327 | |||
a422d6fe08 | |||
98ee85ce82 | |||
5a8509f895 | |||
06770b0dd4 | |||
af616c96d4 | |||
f5b2d79f3b | |||
d644993a74 | |||
2df4ebff47 | |||
9337d18468 | |||
317b734dcc | |||
e35ac9be8d | |||
6dbb524b9f | |||
a3f0bf3ff8 | |||
ecf796f82b | |||
0a4fb008f3 | |||
79fd91ec35 | |||
e659b07c39 | |||
441b854d41 | |||
c936056663 | |||
e22bbd4b14 | |||
103df63023 | |||
36f2d5b0f1 | |||
920cc15ea9 | |||
842ff5d6aa | |||
e1b10769e5 | |||
4177d4f9f4 | |||
9b64e09a24 | |||
f5a70aa1e2 | |||
2df35d636e | |||
f7fd018cf8 | |||
405aa8fb9e | |||
0a826da330 | |||
139bed73f8 | |||
778f92e170 | |||
5a43cc5cf9 | |||
81b11929f7 | |||
46b8624833 | |||
76012506ff | |||
1ab6ac2996 | |||
c98d5448ec | |||
cfafb0bfca | |||
71077d582b | |||
5eb5f72434 | |||
7f49b5144b | |||
e8380d11c4 | |||
ff5a7ba9b9 | |||
c50ae726a9 | |||
2b59b4c793 | |||
0249993377 | |||
d9a9844005 | |||
227187f1f1 | |||
77384ffa9a | |||
1956a6ae76 | |||
5df5b00927 | |||
1d280d8fa1 | |||
9c03e78505 | |||
4af62438f2 | |||
0aa6d9782c | |||
c2e72823fc | |||
d829fa19d2 | |||
76b6cc02d6 | |||
8acfa0a79c | |||
2ed7ca5b6a | |||
5774fcdd80 | |||
eed4dab0fc | |||
f5bdf75f70 | |||
1f0ce80fb4 | |||
7c31fb2450 | |||
11783ffdd0 | |||
41c96921d6 | |||
23455985cd | |||
659c987335 | |||
ecc1f56009 | |||
18b9cf8a85 | |||
934184e236 | |||
b735bdcf2f | |||
f692eb3677 | |||
b1597b4291 | |||
faa96444b5 | |||
78c121eb10 | |||
cb6adc45d1 | |||
59b4b5e9e8 | |||
ad784501a6 | |||
68d690225a | |||
8f716772c2 | |||
da21f02eb9 | |||
4ce7d3a772 | |||
77b7ecfd04 | |||
da1c1d9c22 | |||
f7cd6af9c6 | |||
678ebbb7f6 | |||
87d6e45da5 | |||
80c61c4b3b | |||
4547c6e9f3 | |||
cde622b8e1 | |||
8b810193dd | |||
22f019826c | |||
7fa3f41df2 | |||
f99a086444 | |||
925b1aec64 | |||
be5c2ebcb5 | |||
ae73e9d84d | |||
af920851ca | |||
ea4dbdd66f | |||
ff9753688f | |||
b35b531f00 | |||
6257f1195b | |||
b252771a8f | |||
75c3f0ffba | |||
bd83873a7f | |||
cea7d629d9 | |||
1831a1dd9b | |||
9abf6892c4 | |||
674a48335d | |||
db9d8fcc90 | |||
15db18901c | |||
4cfc21d49d | |||
cf0a453d32 | |||
4186833df7 | |||
30fa764c90 | |||
236417be38 | |||
2641b364e8 | |||
fb5e591bc9 | |||
bfb46ff850 | |||
2012eab842 | |||
9ecb488437 | |||
4295fdb892 | |||
998d921d41 | |||
d491063110 | |||
e2bfaf0751 | |||
f1e1a5ff06 | |||
ef2000053a | |||
8a7876ded5 | |||
b50da46f43 | |||
8b0e9706ca | |||
1d4a5a7520 | |||
8290e1f09a | |||
89672fad04 | |||
1cb9cfe11d | |||
280e297afe | |||
fc8de3d0c8 | |||
3e2555667f | |||
1ecadb6e57 | |||
2abee91dbc | |||
68645df3a3 | |||
d2f79afc1a | |||
8a6fa726d3 | |||
a3d7ae6214 | |||
c0c132a320 | |||
0dfb5d3ef7 | |||
6480a7ee4a | |||
6cc8450f8e | |||
7ae4b28bda | |||
bb8e6afae6 | |||
d7f61e48ac | |||
9de6de5802 | |||
6e7057426e | |||
5306d36522 | |||
7990182f56 | |||
93a6be08a5 | |||
d5d5084151 | |||
d3cff9a962 | |||
133bbdfefa | |||
a8c3470cf2 | |||
578e527869 | |||
312f215fc3 | |||
d639c28e3b | |||
c3f7259cbb | |||
56e8f98c13 | |||
c2217373df | |||
4a3781d7db | |||
911a838c3a | |||
c6106f90d4 | |||
ed52e17886 |
17
.gitignore
vendored
17
.gitignore
vendored
@ -55,6 +55,7 @@ mutter-restart-helper
|
||||
mutter-test-client
|
||||
mutter-test-runner
|
||||
mutter-test-unit-tests
|
||||
mutter-test-headless-start-test
|
||||
mutter-all.test
|
||||
org.gnome.mutter.gschema.valid
|
||||
org.gnome.mutter.gschema.xml
|
||||
@ -71,6 +72,8 @@ src/stamp-meta-enum-types.h
|
||||
src/meta-dbus-display-config.[ch]
|
||||
src/meta-dbus-idle-monitor.[ch]
|
||||
src/meta-dbus-login1.[ch]
|
||||
src/meta-dbus-remote-desktop.[ch]
|
||||
src/meta-dbus-screen-cast.[ch]
|
||||
src/gtk-primary-selection-protocol.c
|
||||
src/gtk-primary-selection-server-protocol.h
|
||||
src/gtk-shell-protocol.c
|
||||
@ -85,7 +88,20 @@ src/pointer-constraints-unstable-v*-protocol.c
|
||||
src/pointer-constraints-unstable-v*-server-protocol.h
|
||||
src/xdg-foreign-unstable-v*-protocol.c
|
||||
src/xdg-foreign-unstable-v*-server-protocol.h
|
||||
src/xdg-output-unstable-v1-protocol.c
|
||||
src/xdg-output-unstable-v1-server-protocol.h
|
||||
src/xwayland-keyboard-grab-unstable-v1-protocol.c
|
||||
src/xwayland-keyboard-grab-unstable-v1-server-protocol.h
|
||||
src/tablet-unstable-v*-protocol.c
|
||||
src/tablet-unstable-v*-server-protocol.h
|
||||
src/keyboard-shortcuts-inhibit-unstable-v*-protocol.c
|
||||
src/keyboard-shortcuts-inhibit-unstable-v*-server-protocol.h
|
||||
src/linux-dmabuf-unstable-v*-protocol.c
|
||||
src/linux-dmabuf-unstable-v*-server-protocol.h
|
||||
src/xdg-shell-protocol.c
|
||||
src/xdg-shell-server-protocol.h
|
||||
src/meta/meta-version.h
|
||||
src/libmutter-*.pc
|
||||
doc/reference/*.args
|
||||
doc/reference/*.bak
|
||||
doc/reference/*.hierarchy
|
||||
@ -111,3 +127,4 @@ ltsugar.m4
|
||||
ltversion.m4
|
||||
lt~obsolete.m4
|
||||
.dirstamp
|
||||
**/tags.*
|
||||
|
440
NEWS
440
NEWS
@ -1,47 +1,441 @@
|
||||
3.22.3
|
||||
3.29.2
|
||||
======
|
||||
* Fix switching between two finger- and edge scrolling on wayland [Rui; #771744]
|
||||
* Fix frequent freezes in multihead setups on wayland [Rui; #774557]
|
||||
* Preserve root window mask on XSelectionRequest [Olivier; #776128]
|
||||
* Fix window menu placement with HiDPI [Jonas; #776055]
|
||||
* Fix size change animations on wayland [Georges; #780292]
|
||||
* Handle touch events on server-side titlebars [Carlos; #770185]
|
||||
* Misc. bug fixes [Florian, Olivier, Jonas, Georges; #134, #124, !96, #138,
|
||||
!102, #781471, #150]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Florian Müllner,
|
||||
Georges Basile Stavracas Neto, Marco Trevisan (Treviño), Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Daniel Șerbănescu [ro], Marcos Lans [gl], Dz Chen [zh_CN]
|
||||
|
||||
3.29.1
|
||||
======
|
||||
* Fix various input-method regressions [Carlos, Olivier; #65, #74, #66, #112]
|
||||
* Fix wayland build on FreeBSD [Ting-Wei; #792280, #792717]
|
||||
* Fix swapped colors in screenshots (again) [Carlos; #72]
|
||||
* Allow building with elogind [Rasmus; !46]
|
||||
* Consider display rotation for cursor [Olivier; #85]
|
||||
* Fall back to non-modifier GBM surfaces [Daniel; #84]
|
||||
* Take inhibitors into account for monitoring idle [Bastien; #705942]
|
||||
* Misc. bug fixes [handsome-feng, Olivier, Mario, Jonas; !45, #83, #104,
|
||||
gnome-shell#157, #130, #21]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, handsome-feng, Yussuf Khalil,
|
||||
Ting-Wei Lan, Aleksandr Mezin, Alberts Muktupāvels,
|
||||
Georges Basile Stavracas Neto, Bastien Nocera, Benjamin Otte,
|
||||
Mario Sanchez Prada, Daniel Stone, Ray Strode, Rasmus Thomsen,
|
||||
Marco Trevisan (Treviño), Daniel van Vugt
|
||||
|
||||
Translators:
|
||||
Emin Tufan Çetin [tr], Dušan Kazik [sk], Matej Urbančič [sl]
|
||||
|
||||
3.28.0
|
||||
======
|
||||
* Fix xdg-foreign regression [Carlos; #63]
|
||||
|
||||
Contributors:
|
||||
Carlos Garnacho, Georges Basile Stavracas Neto
|
||||
|
||||
Translators:
|
||||
Marek Cernocky [cs], Ask Hjorth Larsen [da], Chao-Hsiung Liao [zh_TW],
|
||||
Anders Jonsson [sv], Mart Raudsepp [et]
|
||||
|
||||
3.27.92
|
||||
=======
|
||||
* Fix use of modifiers with multi-GPU systems [Louis-Francis; #18]
|
||||
* Add xdg-shell stable support [Jonas; #791938]
|
||||
* Fix scaling of icons in titlebar buttons [Egmont; #23]
|
||||
* Implement missing wacom functionality on X11 [Carlos; #48]
|
||||
* Force 8-bit RGB config [Jonas; #2]
|
||||
* Misc. bug fixes [Jonas, Olivier, Robert; #6, #27, #792203]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Egmont Koblinger, Robert Mader,
|
||||
Bastien Nocera, Louis-Francis Ratté-Boulianne
|
||||
|
||||
Translators:
|
||||
Daniel Mustieles [es], Марко Костић [sr], Милош Поповић [sr@latin],
|
||||
Fran Dieguez [gl], Balázs Úr [hu], Gwan-gyeong Mun [ko], Rūdolfs Mazurs [lv],
|
||||
Milo Casagrande [it], Mario Blättermann [de], GNOME Translation Robot [gd,
|
||||
nl], Claude Paroz [fr], Aurimas Černius [lt]
|
||||
|
||||
3.27.91
|
||||
=======
|
||||
* Fix handling of trackball settings on wayland [Carlos; #787804]
|
||||
* Apply font settings on wayland [Daniel; #645433]
|
||||
* Fix keybindings getting mixed up with some layouts [Jonas; #789300]
|
||||
* Fix bluetooth mouse cursor disappearing after idle [Benoit; #761067]
|
||||
* Support platforms that export EGL_KHR_platform_gbm [memeka; #780668]
|
||||
* Add keyboard accessibility support on wayland [Olivier; #788564]
|
||||
* Fix missing cursor when using screen magnifier [Carlos; #754806]
|
||||
* Fix external monitor shutting off on wayland when lid closes [Jonas; #788915]
|
||||
* Add xdg-output support [Olivier; #787363]
|
||||
* Add Xwayland grab keyboard support [Olivier; #783342]
|
||||
* Allow shortcut inhibition of the super key [Olivier; #790627]
|
||||
* Take "panel orientation" drm_connector property into account [Hans; #782294]
|
||||
* Fix focus window ending up below other windows on wayland [Olivier; #780820]
|
||||
* Fix maximized windows restoring to a tiny size on wayland [Olivier; #783901]
|
||||
* Fix tap-and-drag setting on X11 [Jonas; #775755]
|
||||
* Fix handling of single-touch devices on wayland [Carlos; #792005]
|
||||
* Support tiled/compressed buffers [Daniel; #785779]
|
||||
* Port screencast support to pipewire 0.1.8 [Jonas; #792854]
|
||||
* Add support for third stylus button on newer tablets [Jason; #790033]
|
||||
* Fix background corruption regression on nvidia [Jonas; #739178]
|
||||
* Misc. bug fixes [Jonas, Rui, Michael, Marco, Carlos, Olivier, Philip, Piotr,
|
||||
Ting-Wei, Daniel, Jeremy, Hans, Florian, Ray, Jeff, George, Gwan-gyeong;
|
||||
#789153, #788493, #784314, #789227, #789223, #789277, #782344, #789552,
|
||||
#789553, #788695, #789984, #788764, #789386, #784545, #790336, #790358,
|
||||
#791022, #791006, #789070, #772218, #791383, #791809, #776220, #791916,
|
||||
#792281, #790309, #791371, #792527, #792599, #788834, #792765, #792062,
|
||||
#645460, #792853, !2, #792818, #8, #12, #789501, #10, #789961, #13, !15, #1,
|
||||
#26, #28, #35, #36, #38]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Jeremy Bicha, Michael Catanzaro, Piotr Drąg, Olivier Fourdan,
|
||||
Carlos Garnacho, Jason Gerecke, Hans de Goede, Benoit Gschwind,
|
||||
Peter Hutterer, George Kiagiadakis, Ting-Wei Lan, Rui Matos, memeka,
|
||||
Florian Müllner, Gwan-gyeong Mun, Jeremy Nickurak, Marc-Antoine Perennou,
|
||||
Jeff Smith, Daniel Stone, Ray Strode, Marco Trevisan (Treviño),
|
||||
Daniel van Vugt, Philip Withnall
|
||||
|
||||
Translators:
|
||||
Khaled Hosny [ar], Kjartan Maraas [nb], Piotr Drąg [pl],
|
||||
Rafael Fontenelle [pt_BR], Christian Kirbach [de], Anders Jonsson [sv],
|
||||
Charles Monzat [fr], Marek Cernocky [cs], Muhammet Kara [tr],
|
||||
Milo Casagrande [it], Pawan Chitrakar [ne], Yosef Or Boczko [he],
|
||||
Kukuh Syafaat [id], Daniel Mustieles [es], Fabio Tomat [fur],
|
||||
Kristjan SCHMIDT [eo], Balázs Úr [hu], Andika Triwidada [id],
|
||||
Fran Dieguez [gl], gogo [hr]
|
||||
|
||||
3.27.1
|
||||
======
|
||||
* Work with clients that require older linux_dmabuf protocol [Daniel; #788558]
|
||||
* Support hybrid GPU systems [Jonas; #785381]
|
||||
* Prevent crash when closing maximized windows [Jonni; #788666]
|
||||
* Use the correct monitor for HiDPI scaling of shell chrome [Jonas; #788820]
|
||||
* Fix unredirection of fullscreen windows [Rui, Jonas; #788493]
|
||||
* Fix list of supported monitor scales on X11 [Jonas; #788901]
|
||||
* Misc. bug fixes [Florian, Jonas, Marco; #788572, #788569, #788607, #788860,
|
||||
#788921]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner, Daniel Stone,
|
||||
Marco Trevisan, Jonni Westphalen
|
||||
|
||||
Translations:
|
||||
Xavi Ivars [ca@valencia]
|
||||
|
||||
3.26.1
|
||||
======
|
||||
* Fix crash when respawning shortcut inhibitor dialog [Olivier; #787568]
|
||||
* Fix crash during monitor configuration migration [Carlos, Jonas; #787668]
|
||||
* Fix multihead regressions in X11 session [Jonas; #787477]
|
||||
* Fix screen rotation regressions [Hans; #787836]
|
||||
* Fix keybindings not being resolved with non-latin layouts [Jonas; #787016]
|
||||
* Support snap packages for sandboxed app IDs [Marco; #788217]
|
||||
* Fix crash when reconnecting tablet device [Jason; #787649]
|
||||
* Support running headless [Jonas; #730551, #787637]
|
||||
* Support _NET_RESTACK_WINDOW and ConfigureRequest siblings [Vasilis; #786365]
|
||||
* Fix monitor layout not being remembered across sessions [Jonas; #787629]
|
||||
* Make sure to export _NET_NUMBER_OF_DESKTOPS [Florian; #760651]
|
||||
* Allow resizing of tiled windows [Georges, Florian; #645153]
|
||||
* Export tiling information to clients [Georges; #751857]
|
||||
* Misc. bug fixes [Jonas, Florian, Jeremy, Rico; #787570, #787715, #787953,
|
||||
#788049, #788199, #788292, #788197]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Andrea Azzarone, Georges Basile Stavracas Neto, Hans de Goede,
|
||||
Olivier Fourdan, Carlos Garnacho, Jason Gerecke, Vasilis Liaskovitis,
|
||||
Rui Matos, Florian Müllner, Jeremy Soller, Marco Trevisan, Rico Tzschichholz
|
||||
|
||||
Translations:
|
||||
Matej Urbančič [sl], gogo [hr], Cheng-Chia Tseng [zh_TW]
|
||||
|
||||
3.26.0
|
||||
======
|
||||
Contributors:
|
||||
Florian Müllner
|
||||
|
||||
Translations:
|
||||
Trần Ngọc Quân [vi], Inaki Larranaga Murgoitio [eu], Jordi Mas [ca],
|
||||
Anders Jonsson [sv], Alexander Shopov [bg], Ask Hjorth Larsen [da],
|
||||
Jean-Baptiste Holcroft [fr], A S Alam [pa]
|
||||
|
||||
3.25.92
|
||||
=======
|
||||
* Add screencast and remote desktop support [Jonas; #784199]
|
||||
* Support running with no attached monitors [Jonas; #730551]
|
||||
* Add a vertical gradient effect to background actor [Alessandro; #786618]
|
||||
* Misc. bug fixes [Mario, Daniel, Piotr, Jonas, Bastien; #786619, #786677,
|
||||
#772218, #786918, #760670]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Alessandro Bono, Piotr Drąg, Bastien Nocera,
|
||||
Mario Sanchez Prada, Daniel Stone
|
||||
|
||||
Translations:
|
||||
Marek Cernocky [cs], Aurimas Černius [lt], Piotr Drąg [pl],
|
||||
Fran Dieguez [gl], gogo [hr], Dušan Kazik [sk], Milo Casagrande [it],
|
||||
Jordi Mas [ca], Cheng-Chia Tseng [zh_TW], Марко Костић [sr],
|
||||
Милош Поповић [sr@latin], Rūdolfs Mazurs [lv], Matej Urbančič [sl],
|
||||
Ask Hjorth Larsen [da], Piotr Drąg [it, lt], Jiri Grönroos [fi],
|
||||
Emin Tufan Çetin [tr], Wolfgang Stöggl [de], Kukuh Syafaat [id],
|
||||
Yuras Shumovich [be], Changwoo Ryu [ko], Alexander Shopov [bg],
|
||||
Rafael Fontenelle [pt_BR], Balázs Úr [hu]
|
||||
|
||||
3.25.91
|
||||
=======
|
||||
* Reduce memory use of suspended instances [Jonas; #786299]
|
||||
* Make supported scales determination saner [Rui; #786474]
|
||||
* Fix crash on inhibit-shortcuts dialog reponse [Jonas; #786385]
|
||||
* Support libinput's tag-and-drag setting [freeroot; #775755]
|
||||
* Avoid overlapping keybindings with multiple layouts [Jonas; #786408]
|
||||
* Fix non-transformed cursor on rotated monitors [Jonas; #786023]
|
||||
* Avoid unnecessary work during background painting [Alessandro; #783512]
|
||||
* Misc. bug fixes [Alberts, Jonas, Mario; #691611, #786300, #777732, #786568]
|
||||
|
||||
Contributors:
|
||||
freeroot, Jonas Ådahl, Alessandro Bono, Carlos Garnacho, Rui Matos,
|
||||
Alberts Muktupāvels, Mario Sanchez Prada
|
||||
|
||||
Translations:
|
||||
Muhammet Kara [tr], Claude Paroz [fr], Мирослав Николић [sr, sr@latin],
|
||||
Pawan Chitrakar [ne], Kukuh Syafaat [id]
|
||||
|
||||
3.25.90
|
||||
=======
|
||||
* Add zwp_linux_dmabuf_v1 support [Daniel; #785262]
|
||||
* Add (x)wayland shortcut inhibitor support [Olivier; #783342]
|
||||
* Misc. bug fixes [Daniel, Carlos, Cosimo; #785263, #785347, #767805]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Cosimo Cecchi, Olivier Fourdan, Carlos Garnacho, Daniel Stone
|
||||
|
||||
Translations:
|
||||
Fabio Tomat [fur], Kukuh Syafaat [id], Aurimas Černius [lt],
|
||||
Daniel Mustieles [es], Baurzhan Muftakhidinov [kk], Jordi Mas [ca],
|
||||
Matej Urbančič [sl], Marek Cernocky [cs], gogo [hr], Fran Dieguez [gl],
|
||||
Balázs Meskó [hu]
|
||||
|
||||
3.25.4
|
||||
======
|
||||
* Do not throttle motion events on tablet tools [Carlos; #783535]
|
||||
* Handle left-handed mode on pen/eraser devices [Carlos; #782027]
|
||||
* Add wl_surface.damage_buffer() support [Jonas; #784080]
|
||||
* Fix crash when moving across on-adjacent monitors [Jonas; #783630]
|
||||
* Fix window moving/resizing via tablet tools [Jason; #777333]
|
||||
* Support fractional monitor scaling [Jonas, Marco; #765011]
|
||||
* Keep override-redirect windows stacked on top [Rui; #780485]
|
||||
* Implement tablet rings/strips configuration [Carlos; #782033]
|
||||
* Support tablet wheel events on wayland [Jason; #783716]
|
||||
* Move g-s-d xrandr functionality into mutter [Rui; #781906]
|
||||
* Misc. bug fixes [Florian, Jason, Miguel, Carlos, Jonas; #783502, #784009,
|
||||
#784223, #784272, #784402, #784881, #762083, #784867, #781723]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Miguel A. Vico, Emmanuele Bassi, Carlos Garnacho, Jason Gerecke,
|
||||
Rui Matos, Florian Müllner, Marco Trevisan (Treviño)
|
||||
|
||||
3.25.3
|
||||
======
|
||||
* Ignore hotplug-mode-update value on startup [Marco; #783073]
|
||||
* Implement configurable monitor scales on X11 [Jonas; #777732]
|
||||
* Fix handling of tiled monitors [Jonas; #781723]
|
||||
* Handle multiple keycodes for keysym [Christian; #781223]
|
||||
* Consider subsurfaces when grabbing [mindtree; #781811]
|
||||
* Fix logic for HiPDPI scaling of TV outputs [Christian; #777347]
|
||||
* Fix handling of left-handed mode on pen/eraser devices [Carlos; #782027]
|
||||
* Fix output cycling in non-display-attached tablets [Carlos; #782032]
|
||||
* Fix wacom cursor offset on wayland [Jason; #784009]
|
||||
* Handle EXIF orientation of backgrounds [Silvère; #783125]
|
||||
* Misc. bug fixes [Piotr, Tim, Bastien, Jonas, Florian, Benoit, Carlos; #772218,
|
||||
#783161, #780407, #783113, #783293, #783505, #781703]
|
||||
|
||||
Contributors:
|
||||
mitchmindtree, Jonas Ådahl, Ikey Doherty, Piotr Drąg, Carlos Garnacho,
|
||||
Jason Gerecke, Benoit Gschwind, Christian Kellner, Silvère Latchurié,
|
||||
Tim Lunn, Florian Müllner, Bastien Nocera, Marco Trevisan (Treviño)
|
||||
|
||||
Translations:
|
||||
Fabio Tomat [fur], Kukuh Syafaat [id], Khaled Hosny [ar],
|
||||
Daniel Mustieles [es]
|
||||
|
||||
3.25.2
|
||||
======
|
||||
* Fix frame updates on hide-titlebar-when-maximized changes [Florian; #781862]
|
||||
* Fix accessible screen coordinates on X11 [Florian; #781902]
|
||||
* Use less CPU when rendering fast-updating windows [Carlos, Emmanuele; #782344]
|
||||
* Compute geometry of clients that don't set one explicitly [Olivier; #782213]
|
||||
* Fix copy+paste of UTF8 strings between X11 and wayland [Carlos; #782472]
|
||||
* Fix non-wayland builds [Chris; #780533]
|
||||
* Add plugin vfunc to implement a custom force-quit dialog [Carlos; #711619]
|
||||
* Fix swapped red and blue channels in CoglTexture data [Carlos; #779234
|
||||
* Fix build where libtool's link_all_deplibs defaults to 'no' [Marco; #782821]
|
||||
* Fix glitches when opening a window maximized [Olivier; #781353, #782183]
|
||||
* Fix wrong cursor after window underneath the pointer changed [Carlos; #755164]
|
||||
* Implement support for disable-while-typing option [Evan; #764852]
|
||||
* Emit size-change signal when tiling [Alessandro; #782968]
|
||||
* Misc. bug fixes [Nigel, Matthias, Jonas; #759085, #780215, #782156, #782152]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Emmanuele Bassi, Alessandro Bono, Olivier Fourdan,
|
||||
Carlos Garnacho, Matthias Liertzer, Florian Müllner, Nigel Taylor,
|
||||
Marco Trevisan (Treviño), Chris Vine, Evan Welsh
|
||||
|
||||
Translations:
|
||||
Fabio Tomat [fur], Jordi Mas [ca], Mario Blättermann [de],
|
||||
Emin Tufan Çetin [tr], Balázs Úr [hu]
|
||||
|
||||
3.25.1
|
||||
======
|
||||
* Always sync window geometry on state changes [Jonas; #780292]
|
||||
* Use EGL instead of GLX when drawing using GLES [Jonas; #771636]
|
||||
* Fix HiDPI detection on vertical monitor layouts [Carlos; #777687]
|
||||
* Get double-click timing from desktop mouse settings [Armin; #771576]
|
||||
* Scale relative motion deltas with monitor scale [Jonas, Carlos; #778119]
|
||||
* Use texture fallback when setting hardware cursor fails [Jente; #770020]
|
||||
* Fix lock-up when using additional theme variants [Shantanu; #780254]
|
||||
* Rework low-level monitor configuration [Jonas; #777732]
|
||||
* Fix building with GLES2 instead of GL [Mario; #781398]
|
||||
* Misc. bug fixes [Jonas, Piotr, Philip; #780304, #772218, #781242, #781391]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Philip Chimento, Piotr Drąg, Carlos Garnacho, Shantanu Goel,
|
||||
Jente Hidskes, Armin Krezović, Rui Matos, Florian Müllner, Mario Sanchez Prada
|
||||
|
||||
Translations:
|
||||
Yuras Shumovich [be], Yosef Or Boczko [he], Tom Tryfonidis [el],
|
||||
Fabio Tomat [fur], Kukuh Syafaat [id]
|
||||
|
||||
3.24.0
|
||||
======
|
||||
|
||||
Translations:
|
||||
Yuri Myasoedov [ru], Rūdolfs Mazurs [lv], Jordi Mas [ca]
|
||||
|
||||
3.23.92
|
||||
=======
|
||||
* Properly handle EGLOutput acquire errors [Jonas, Miguel; #779112]
|
||||
* Fix crash when a window closes during Alt+Tab [Rui; #779483]
|
||||
* Implement DnD handling code in wayland [Hyungwon; #765003]
|
||||
* Fix fallout from pixel conversion optimization in 3.23.91 [Carlos; #779234]
|
||||
* Fix mouse input stopping to work in applications [Carlos; #763246]
|
||||
* Fix DnD between QT5 and GTK3 applications on wayland [Carlos; #779757]
|
||||
* Make EDID reading less fragile [Jonas; #779837]
|
||||
* Add support for tablet grouping [Carlos; #779986]
|
||||
* Misc. bug fixes and cleanups [Rui, Jonas; #779436, #779001, #779745]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Miguel A. Vico, Olivier Fourdan, Carlos Garnacho,
|
||||
Hyungwon Hwang, Rui Matos
|
||||
|
||||
Translations:
|
||||
Chao-Hsiung Liao [zh_TW], Sveinn í Felli [is], Ask Hjorth Larsen [da],
|
||||
Changwoo Ryu [ko], Aurimas Černius [lt], GNOME Translation Robot [gd],
|
||||
Marek Černocký [cs], Fran Dieguez [gl], Dušan Kazik [sk]
|
||||
|
||||
3.23.91
|
||||
=======
|
||||
* Give libinput read-only access to /sys [Carlos; #778472]
|
||||
* Allow edge-scrolling without 2-finger-scroll capable devices [Rui; #778554]
|
||||
* Fullscreen windows on the requested monitor on wayland [Rui; #772525]
|
||||
* Implement threaded swap_event fallback for NVIDIA driver [Owen; #779039]
|
||||
* Avoid pixel conversions when storing textures from cairo [Carlos; #779234]
|
||||
* Misc. bug fixes [Piotr, Rui, Florian; #772218, #776919, #778831, #642652]
|
||||
|
||||
Contributors:
|
||||
Piotr Drąg, Carlos Garnacho, Rui Matos, Florian Müllner, Owen W. Taylor
|
||||
|
||||
Translations:
|
||||
Inaki Larranaga Murgoitio [eu], Daniel Mustieles [es], Claude Paroz [fr],
|
||||
Mario Blättermann [de], Kjartan Maraas [nb], Piotr Drąg [pl],
|
||||
Andika Triwidada [id], Anders Jonsson [sv], Milo Casagrande [it],
|
||||
Fabio Tomat [fur], Rafael Fontenelle [pt_BR],
|
||||
Мирослав Николић [sr, sr@latin], Balázs Meskó [hu], Chao-Hsiung Liao [zh_TW]
|
||||
|
||||
3.23.90
|
||||
=======
|
||||
* Fix window menu placement with HiDPI [Jonas; #776055]
|
||||
* Improve EGLStream support [Jonas; #773629]
|
||||
* Start moving low-level monitor configuration into mutter [Jonas; #777732]
|
||||
* Fix erroneous key event repeats [Rui; #774989]
|
||||
* Don't hardcode seat ID in ClutterDeviceManager [Carlos; #778092]
|
||||
* Fix "ghost" cursors in multi-monitor setups [Jonas; #771056]
|
||||
* Use eglGetPlatformDisplay [Adam; #772422]
|
||||
* Fix erratic raise_or_lower behavior [Jose; #705200]
|
||||
* Extend tablet device checks [Carlos; #773779]
|
||||
* Fix coordinate mapping of absolute devices [Carlos; #774115]
|
||||
* Show OSD on tablet mode switches [Carlos; #771098]
|
||||
* Make mutter libs parallel installable [Jonas; #777317]
|
||||
* Only apply keymap when not running nested [Jonas; #777800]
|
||||
* Set right scale for tablet tool cursors on HiDPI [Carlos; #778474]
|
||||
* Allow edge-scrolling without 2fg-scroll capable devices [Rui; #778554]
|
||||
* Misc. bug fixes [Jonas, Rui, Carlos, Peter; #771297, #774135, #775986,
|
||||
#777691, #777470, #778262, #776919]
|
||||
* Adjust server-side shadows to match Adwaita [Juraj; #744667]
|
||||
* Misc. bug fixes [Jonas, Bastien, Carlos, Peter, Lionel, Jeremy, Florian;
|
||||
#774891, #777389, #777691, #778262, #776543, #778684, #778699, #744667]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Peter Hutterer, Adam Jackson,
|
||||
Jose Marino, Rui Matos
|
||||
Jonas Ådahl, Jeremy Bicha, Piotr Drąg, Juraj Fiala, Carlos Garnacho,
|
||||
Peter Hutterer, Adam Jackson, Lionel Landwerlin, Jose Marino, Rui Matos,
|
||||
Florian Müllner, Bastien Nocera
|
||||
|
||||
Translations:
|
||||
Mandy Wang [zh_CN]
|
||||
Kjartan Maraas [nb], Mandy Wang [zh_CN], Marek Černocký [cs],
|
||||
Anders Jonsson [sv], Dušan Kazik [sk], Piotr Drąg [pl], Matej Urbančič [sl]
|
||||
|
||||
3.22.2
|
||||
3.23.3
|
||||
======
|
||||
* Fix frequent freezes in multihead setups on wayland [Rui; #774557]
|
||||
* Preserve root window mask on XSelectionRequest [Olivier; #776128]
|
||||
* Misc. bug fixes [Carlos, Florian, Rui, Olivier; #775478, #774891, #775986,
|
||||
#776036]
|
||||
|
||||
Contributors:
|
||||
Olivier Fourdan, Carlos Garnacho, Rui Matos, Florian Müllner
|
||||
|
||||
3.23.2
|
||||
======
|
||||
* Stack docks below other windows on fullscreen monitors [Rui; #772937]
|
||||
* Fix popup grabs blocking screen lock on wayland [Rui; #771235]
|
||||
* Handle touchpad pinch gestures with more than two fingers [Carlos; #765937]
|
||||
* Implement drawing tablet support on X11 [Carlos; #773779]
|
||||
* Fix some Wine games starting minimized [Carlos; #774333]
|
||||
* Fix switching between two finger- and edge scrolling on wayland [Rui; #771744]
|
||||
* Implement support for EGLStream/EGLDevice [Jonas; #773629]
|
||||
* Add size_changed vfunc to handle async client size changes [Rui; #770345]
|
||||
* Change focus window on clicks with any modifiers [Rui; #746642]
|
||||
* Misc. bug fixes and cleanups [Carlos, Daniel, Jonas, Rui; #771067, #774330, #774613,
|
||||
#771297, #774135, #774827, #774923]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Carlos Garnacho, Rui Matos, Florian Müllner, Daniel Stone
|
||||
|
||||
Translations:
|
||||
Kjartan Maraas [nb]
|
||||
|
||||
3.23.1
|
||||
======
|
||||
* Fix handling of Escape shortcut in force-quit dialog [Landry; #737109]
|
||||
* Improve pointer constraints support [Jonas; #771859]
|
||||
* Really fix framebuffer capture origin offset [Rui; #771502]
|
||||
* Fix session going into idle mode immediately on startup [Rui; #772839]
|
||||
* Fix mirror mode with stage views [Rui; #773115]
|
||||
* Improve pointer constraints support [Jonas; #771859]
|
||||
* Stack docks below other windows on fullscreen monitors [Rui; #772937]
|
||||
* Fix switching between two finger- and edge scrolling on wayland [Rui; #771744]
|
||||
* Fix popup grabs blocking screen lock on wayland [Rui; #771235]
|
||||
* Fix various crashes on wayland [Jonas; #771646, #771858]
|
||||
* Fix various placement issues on wayland [Jonas, Sjoerd, Olivier; #768039,
|
||||
#771841, #773141, #772729]
|
||||
* Fall back to X with connectors spread across multiple GPUs [Ray; #771442]
|
||||
* Fix various crashes on wayland [Jonas, Carlos; #771646, #771858, #772929]
|
||||
* Fix various placement issues on wayland [Olivier, Jonas, Sjoerd; #772729,
|
||||
#768039, #771841, #771841, #773141]
|
||||
* Misc. bug fixes [Rui, Jonas, Olivier; #771019, #773116, #772914, #773210]
|
||||
|
||||
Contributors:
|
||||
Jonas Ådahl, Olivier Fourdan, Rui Matos, Sjoerd Simons
|
||||
Jonas Ådahl, Olivier Fourdan, Carlos Garnacho, Rui Matos, Landry MINOZA,
|
||||
Sjoerd Simons, Ray Strode
|
||||
|
||||
Translations:
|
||||
Theppitak Karoonboonyanan [th], Kjartan Maraas [nb], liushuyu [zh_CN],
|
||||
YunQiang Su [zh_CN]
|
||||
Theppitak Karoonboonyanan [th], Kjartan Maraas [nb], Hannie Dumoleyn [nl],
|
||||
liushuyu [zh_CN]
|
||||
|
||||
3.22.1
|
||||
======
|
||||
|
25
autogen.sh
25
autogen.sh
@ -6,16 +6,23 @@ test -z "$srcdir" && srcdir=.
|
||||
|
||||
REQUIRED_AUTOMAKE_VERSION=1.11
|
||||
|
||||
(test -f $srcdir/configure.ac \
|
||||
&& test -d $srcdir/src) || {
|
||||
olddir="$(pwd)"
|
||||
|
||||
cd "${srcdir}"
|
||||
|
||||
(test -f configure.ac \
|
||||
&& test -d src) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
echo " top-level metacity directory"
|
||||
echo " top-level mutter directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
which gnome-autogen.sh || {
|
||||
echo "You need to install gnome-common from GNOME Subversion (or from"
|
||||
echo "your distribution's package manager)."
|
||||
exit 1
|
||||
}
|
||||
. gnome-autogen.sh
|
||||
aclocal --install || exit 1
|
||||
intltoolize --force --copy --automake || exit 1
|
||||
autoreconf --verbose --force --install || exit 1
|
||||
|
||||
cd "${olddir}"
|
||||
|
||||
if [ "$NOCONFIGURE" = "" ]; then
|
||||
"${srcdir}/configure" "$@" || exit 1
|
||||
fi
|
||||
|
@ -25,6 +25,7 @@ AM_CPPFLAGS = \
|
||||
-I$(top_builddir)/clutter \
|
||||
-I$(top_srcdir)/../cogl \
|
||||
-I$(top_builddir)/../cogl \
|
||||
-I$(top_builddir)/../cogl/cogl \
|
||||
$(CLUTTER_DEPRECATED_CFLAGS) \
|
||||
$(CLUTTER_DEBUG_CFLAGS) \
|
||||
$(CLUTTER_HIDDEN_VISIBILITY_CFLAGS) \
|
||||
@ -36,7 +37,7 @@ AM_CFLAGS = $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS)
|
||||
INTROSPECTION_GIRS =
|
||||
|
||||
# the base include path for headers
|
||||
clutter_base_includedir = $(includedir)/mutter/clutter-$(CLUTTER_API_VERSION)
|
||||
clutter_base_includedir = $(includedir)/mutter/clutter-$(LIBMUTTER_API_VERSION)
|
||||
clutter_includedir = $(clutter_base_includedir)/clutter
|
||||
clutter_deprecateddir = $(clutter_base_includedir)/clutter/deprecated
|
||||
|
||||
@ -86,6 +87,8 @@ source_h = \
|
||||
clutter-image.h \
|
||||
clutter-input-device.h \
|
||||
clutter-input-device-tool.h \
|
||||
clutter-input-focus.h \
|
||||
clutter-input-method.h \
|
||||
clutter-interval.h \
|
||||
clutter-keyframe-transition.h \
|
||||
clutter-keysyms.h \
|
||||
@ -112,7 +115,6 @@ source_h = \
|
||||
clutter-snap-constraint.h \
|
||||
clutter-stage.h \
|
||||
clutter-stage-manager.h \
|
||||
clutter-stage-view.h \
|
||||
clutter-tap-action.h \
|
||||
clutter-test-utils.h \
|
||||
clutter-texture.h \
|
||||
@ -169,6 +171,8 @@ source_c = \
|
||||
clutter-image.c \
|
||||
clutter-input-device.c \
|
||||
clutter-input-device-tool.c \
|
||||
clutter-input-focus.c \
|
||||
clutter-input-method.c \
|
||||
clutter-virtual-input-device.c \
|
||||
clutter-interval.c \
|
||||
clutter-keyframe-transition.c \
|
||||
@ -198,7 +202,6 @@ source_c = \
|
||||
clutter-snap-constraint.c \
|
||||
clutter-stage.c \
|
||||
clutter-stage-manager.c \
|
||||
clutter-stage-view.c \
|
||||
clutter-stage-window.c \
|
||||
clutter-tap-action.c \
|
||||
clutter-test-utils.c \
|
||||
@ -230,6 +233,8 @@ source_h_priv = \
|
||||
clutter-flatten-effect.h \
|
||||
clutter-gesture-action-private.h \
|
||||
clutter-id-pool.h \
|
||||
clutter-input-focus-private.h \
|
||||
clutter-input-method-private.h \
|
||||
clutter-master-clock.h \
|
||||
clutter-master-clock-default.h \
|
||||
clutter-offscreen-effect-private.h \
|
||||
@ -240,6 +245,7 @@ source_h_priv = \
|
||||
clutter-settings-private.h \
|
||||
clutter-stage-manager-private.h \
|
||||
clutter-stage-private.h \
|
||||
clutter-stage-view.h \
|
||||
clutter-stage-window.h \
|
||||
$(NULL)
|
||||
|
||||
@ -248,6 +254,7 @@ source_c_priv = \
|
||||
clutter-easing.c \
|
||||
clutter-event-translator.c \
|
||||
clutter-id-pool.c \
|
||||
clutter-stage-view.c \
|
||||
$(NULL)
|
||||
|
||||
# deprecated installed headers
|
||||
@ -355,7 +362,7 @@ EXTRA_DIST += clutter-version.h.in clutter-version.h
|
||||
# key symbol update script
|
||||
EXTRA_DIST += clutter-keysyms-update.pl
|
||||
|
||||
pc_files += mutter-clutter-$(CLUTTER_API_VERSION).pc
|
||||
pc_files += mutter-clutter-$(LIBMUTTER_API_VERSION).pc
|
||||
|
||||
# in order to be compatible with Clutter < 1.10, when we shipped a single
|
||||
# shared library whose name was determined by the single backend it
|
||||
@ -387,6 +394,7 @@ x11_source_c = \
|
||||
x11/clutter-keymap-x11.c \
|
||||
x11/clutter-stage-x11.c \
|
||||
x11/clutter-x11-texture-pixmap.c \
|
||||
x11/clutter-xkb-a11y-x11.c \
|
||||
$(NULL)
|
||||
|
||||
x11_source_h = \
|
||||
@ -401,6 +409,7 @@ x11_source_h_priv = \
|
||||
x11/clutter-keymap-x11.h \
|
||||
x11/clutter-settings-x11.h \
|
||||
x11/clutter-stage-x11.h \
|
||||
x11/clutter-xkb-a11y-x11.h \
|
||||
$(NULL)
|
||||
|
||||
x11_source_c_priv = \
|
||||
@ -413,11 +422,13 @@ x11_source_c_priv = \
|
||||
x11_source_c += \
|
||||
x11/clutter-device-manager-xi2.c \
|
||||
x11/clutter-input-device-xi2.c \
|
||||
x11/clutter-input-device-tool-xi2.c \
|
||||
$(NULL)
|
||||
|
||||
x11_source_h_priv += \
|
||||
x11/clutter-device-manager-xi2.h \
|
||||
x11/clutter-input-device-xi2.h \
|
||||
x11/clutter-input-device-tool-xi2.h \
|
||||
$(NULL)
|
||||
|
||||
x11_source_c += \
|
||||
@ -439,10 +450,10 @@ x11_introspection = $(x11_source_c) $(x11_source_h)
|
||||
clutterx11_includedir = $(clutter_includedir)/x11
|
||||
clutterx11_include_HEADERS = $(x11_source_h)
|
||||
|
||||
mutter-clutter-x11-$(CLUTTER_API_VERSION).pc: mutter-clutter-$(CLUTTER_API_VERSION).pc
|
||||
mutter-clutter-x11-@LIBMUTTER_API_VERSION@.pc: mutter-clutter-$(LIBMUTTER_API_VERSION).pc
|
||||
$(QUIET_GEN)cp -f $< $(@F)
|
||||
|
||||
pc_files += mutter-clutter-x11-$(CLUTTER_API_VERSION).pc
|
||||
pc_files += mutter-clutter-x11-$(LIBMUTTER_API_VERSION).pc
|
||||
|
||||
# Shared cogl backend files
|
||||
cogl_source_h =
|
||||
@ -580,17 +591,17 @@ nodist_clutter_include_HEADERS = clutter-config.h $(built_source_h)
|
||||
clutter_deprecated_HEADERS = $(deprecated_h)
|
||||
|
||||
mutterlibdir = $(libdir)/mutter
|
||||
mutterlib_LTLIBRARIES = libmutter-clutter-@CLUTTER_API_VERSION@.la
|
||||
mutterlib_LTLIBRARIES = libmutter-clutter-@LIBMUTTER_API_VERSION@.la
|
||||
|
||||
libmutter_clutter_@CLUTTER_API_VERSION@_la_LIBADD = \
|
||||
libmutter_clutter_@LIBMUTTER_API_VERSION@_la_LIBADD = \
|
||||
$(LIBM) \
|
||||
$(CLUTTER_LIBS) \
|
||||
$(top_builddir)/../cogl/cogl/libmutter-cogl.la \
|
||||
$(top_builddir)/../cogl/cogl-pango/libmutter-cogl-pango.la \
|
||||
$(top_builddir)/../cogl/cogl-path/libmutter-cogl-path.la \
|
||||
$(top_builddir)/../cogl/cogl/libmutter-cogl-$(LIBMUTTER_API_VERSION).la \
|
||||
$(top_builddir)/../cogl/cogl-pango/libmutter-cogl-pango-$(LIBMUTTER_API_VERSION).la \
|
||||
$(top_builddir)/../cogl/cogl-path/libmutter-cogl-path-$(LIBMUTTER_API_VERSION).la \
|
||||
$(NULL)
|
||||
|
||||
libmutter_clutter_@CLUTTER_API_VERSION@_la_SOURCES = \
|
||||
libmutter_clutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
|
||||
$(backend_source_c) \
|
||||
$(backend_source_h) \
|
||||
$(backend_source_c_priv) \
|
||||
@ -608,12 +619,12 @@ libmutter_clutter_@CLUTTER_API_VERSION@_la_SOURCES = \
|
||||
$(cally_sources_private) \
|
||||
$(NULL)
|
||||
|
||||
nodist_libmutter_clutter_@CLUTTER_API_VERSION@_la_SOURCES = \
|
||||
nodist_libmutter_clutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
|
||||
$(backend_source_built) \
|
||||
$(built_source_c) \
|
||||
$(built_source_h)
|
||||
|
||||
libmutter_clutter_@CLUTTER_API_VERSION@_la_LDFLAGS = \
|
||||
libmutter_clutter_@LIBMUTTER_API_VERSION@_la_LDFLAGS = \
|
||||
$(CLUTTER_LINK_FLAGS) \
|
||||
$(CLUTTER_LT_LDFLAGS) \
|
||||
-export-dynamic \
|
||||
@ -627,13 +638,13 @@ install-exec-local:
|
||||
rm -f $$lib.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION); \
|
||||
) ; \
|
||||
(cd $(DESTDIR)$(mutterlibdir) && \
|
||||
{ ln -s -f libmutter-clutter-$(CLUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib.0 || \
|
||||
{ rm -f $$lib.0 && ln -s libmutter-clutter-1.0.so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib.0; }; \
|
||||
{ ln -s -f libmutter-clutter-$(LIBMUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib.0 || \
|
||||
{ rm -f $$lib.0 && ln -s libmutter-clutter-$(LIBMUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib.0; }; \
|
||||
} \
|
||||
) ; \
|
||||
(cd $(DESTDIR)$(mutterlibdir) && \
|
||||
{ ln -s -f libmutter-clutter-$(CLUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib || \
|
||||
{ rm -f $$lib && ln -s libmutter-clutter-1.0.so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib; }; \
|
||||
{ ln -s -f libmutter-clutter-$(LIBMUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib || \
|
||||
{ rm -f $$lib && ln -s libmutter-clutter-$(LIBMUTTER_API_VERSION).so.0.$(CLUTTER_LT_CURRENT).$(CLUTTER_LT_REVISION) $$lib; }; \
|
||||
} \
|
||||
) ; \
|
||||
done
|
||||
@ -641,59 +652,65 @@ install-exec-local:
|
||||
# gobject-introspection rules
|
||||
-include $(INTROSPECTION_MAKEFILE)
|
||||
|
||||
INTROSPECTION_SCANNER_ARGS = --add-include-path=$(top_builddir)/../cogl/cogl --add-include-path=$(top_builddir)/../cogl/cogl-pango
|
||||
INTROSPECTION_COMPILER_ARGS = --includedir=$(top_builddir)/../cogl/cogl --includedir=$(top_builddir)/../cogl/cogl-pango
|
||||
INTROSPECTION_SCANNER_ARGS = \
|
||||
--add-include-path=$(top_builddir)/../cogl/cogl \
|
||||
--add-include-path=$(top_builddir)/../cogl/cogl-pango
|
||||
INTROSPECTION_COMPILER_ARGS = \
|
||||
--includedir=$(top_builddir)/../cogl/cogl \
|
||||
--includedir=$(top_builddir)/../cogl/cogl-pango
|
||||
INTROSPECTION_SCANNER_ENV = \
|
||||
PKG_CONFIG_PATH=$(top_builddir)/../cogl/cogl/:$(top_builddir)/../cogl/cogl-pango/:$${PKG_CONFIG_PATH}
|
||||
|
||||
Clutter-@CLUTTER_API_VERSION@.gir: libmutter-clutter-@CLUTTER_API_VERSION@.la Makefile
|
||||
Clutter-@LIBMUTTER_API_VERSION@.gir: libmutter-clutter-@LIBMUTTER_API_VERSION@.la Makefile
|
||||
|
||||
Clutter_@CLUTTER_API_VERSION_AM@_gir_NAMESPACE = Clutter
|
||||
Clutter_@CLUTTER_API_VERSION_AM@_gir_VERSION = @CLUTTER_API_VERSION@
|
||||
Clutter_@CLUTTER_API_VERSION_AM@_gir_LIBS = libmutter-clutter-@CLUTTER_API_VERSION@.la
|
||||
Clutter_@CLUTTER_API_VERSION_AM@_gir_FILES = \
|
||||
Clutter_@LIBMUTTER_API_VERSION@_gir_NAMESPACE = Clutter
|
||||
Clutter_@LIBMUTTER_API_VERSION@_gir_VERSION = @LIBMUTTER_API_VERSION@
|
||||
Clutter_@LIBMUTTER_API_VERSION@_gir_LIBS = libmutter-clutter-@LIBMUTTER_API_VERSION@.la
|
||||
Clutter_@LIBMUTTER_API_VERSION@_gir_FILES = \
|
||||
$(clutter_include_HEADERS) \
|
||||
$(clutter_deprecated_HEADERS) \
|
||||
$(nodist_clutter_include_HEADERS) \
|
||||
$(source_c) \
|
||||
$(deprecated_c) \
|
||||
$(built_source_c)
|
||||
Clutter_@CLUTTER_API_VERSION_AM@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
|
||||
Clutter_@CLUTTER_API_VERSION_AM@_gir_INCLUDES = GL-1.0 GObject-2.0 cairo-1.0 Cogl-1.0 CoglPango-1.0 Atk-1.0 Json-1.0
|
||||
Clutter_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS = \
|
||||
Clutter_@LIBMUTTER_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
|
||||
Clutter_@LIBMUTTER_API_VERSION@_gir_INCLUDES = GL-1.0 GObject-2.0 cairo-1.0 Cogl-@LIBMUTTER_API_VERSION@ CoglPango-@LIBMUTTER_API_VERSION@ Atk-1.0 Json-1.0
|
||||
Clutter_@LIBMUTTER_API_VERSION@_gir_SCANNERFLAGS = \
|
||||
--warn-all \
|
||||
--c-include='clutter/clutter.h' \
|
||||
--pkg-export=mutter-clutter-@CLUTTER_API_VERSION@
|
||||
--pkg-export=mutter-clutter-@LIBMUTTER_API_VERSION@
|
||||
|
||||
INTROSPECTION_GIRS += Clutter-@CLUTTER_API_VERSION@.gir
|
||||
INTROSPECTION_GIRS += Clutter-@LIBMUTTER_API_VERSION@.gir
|
||||
|
||||
Cally-@CLUTTER_API_VERSION@.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir
|
||||
Cally-@LIBMUTTER_API_VERSION@.gir: Makefile Clutter-@LIBMUTTER_API_VERSION@.gir
|
||||
|
||||
Cally_@CLUTTER_API_VERSION_AM@_gir_NAMESPACE = Cally
|
||||
Cally_@CLUTTER_API_VERSION_AM@_gir_VERSION = @CLUTTER_API_VERSION@
|
||||
Cally_@CLUTTER_API_VERSION_AM@_gir_LIBS = libmutter-clutter-@CLUTTER_API_VERSION@.la
|
||||
Cally_@CLUTTER_API_VERSION_AM@_gir_FILES = $(cally_sources_h) $(cally_sources_c)
|
||||
Cally_@CLUTTER_API_VERSION_AM@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
|
||||
Cally_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS = \
|
||||
Cally_@LIBMUTTER_API_VERSION@_gir_NAMESPACE = Cally
|
||||
Cally_@LIBMUTTER_API_VERSION@_gir_VERSION = @LIBMUTTER_API_VERSION@
|
||||
Cally_@LIBMUTTER_API_VERSION@_gir_LIBS = libmutter-clutter-@LIBMUTTER_API_VERSION@.la
|
||||
Cally_@LIBMUTTER_API_VERSION@_gir_FILES = $(cally_sources_h) $(cally_sources_c)
|
||||
Cally_@LIBMUTTER_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
|
||||
Cally_@LIBMUTTER_API_VERSION@_gir_SCANNERFLAGS = \
|
||||
--warn-all \
|
||||
--c-include='cally/cally.h' \
|
||||
--pkg-export=mutter-cally-@CLUTTER_API_VERSION@ \
|
||||
--include-uninstalled=$(top_builddir)/clutter/Clutter-@CLUTTER_API_VERSION@.gir
|
||||
--pkg-export=mutter-clutter-@LIBMUTTER_API_VERSION@ \
|
||||
--include-uninstalled=$(top_builddir)/clutter/Clutter-@LIBMUTTER_API_VERSION@.gir
|
||||
|
||||
INTROSPECTION_GIRS += Cally-@CLUTTER_API_VERSION@.gir
|
||||
INTROSPECTION_GIRS += Cally-@LIBMUTTER_API_VERSION@.gir
|
||||
|
||||
ClutterX11-@CLUTTER_API_VERSION@.gir: Makefile Clutter-@CLUTTER_API_VERSION@.gir
|
||||
ClutterX11-@LIBMUTTER_API_VERSION@.gir: Makefile Clutter-@LIBMUTTER_API_VERSION@.gir
|
||||
|
||||
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_NAMESPACE = ClutterX11
|
||||
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_INCLUDES = xlib-2.0
|
||||
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_LIBS = libmutter-clutter-@CLUTTER_API_VERSION@.la
|
||||
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_FILES = $(x11_introspection)
|
||||
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
|
||||
ClutterX11_@CLUTTER_API_VERSION_AM@_gir_SCANNERFLAGS = \
|
||||
ClutterX11_@LIBMUTTER_API_VERSION@_gir_NAMESPACE = ClutterX11
|
||||
ClutterX11_@LIBMUTTER_API_VERSION@_gir_INCLUDES = xlib-2.0
|
||||
ClutterX11_@LIBMUTTER_API_VERSION@_gir_LIBS = libmutter-clutter-@LIBMUTTER_API_VERSION@.la
|
||||
ClutterX11_@LIBMUTTER_API_VERSION@_gir_FILES = $(x11_introspection)
|
||||
ClutterX11_@LIBMUTTER_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(CLUTTER_CFLAGS)
|
||||
ClutterX11_@LIBMUTTER_API_VERSION@_gir_SCANNERFLAGS = \
|
||||
--warn-all \
|
||||
--c-include='clutter/x11/clutter-x11.h' \
|
||||
--pkg-export=mutter-clutter-x11-@CLUTTER_API_VERSION@ \
|
||||
--include-uninstalled=$(top_builddir)/clutter/Clutter-@CLUTTER_API_VERSION@.gir
|
||||
--pkg-export=mutter-clutter-x11-@LIBMUTTER_API_VERSION@ \
|
||||
--include-uninstalled=$(top_builddir)/clutter/Clutter-@LIBMUTTER_API_VERSION@.gir
|
||||
|
||||
INTROSPECTION_GIRS += ClutterX11-@CLUTTER_API_VERSION@.gir
|
||||
INTROSPECTION_GIRS += ClutterX11-@LIBMUTTER_API_VERSION@.gir
|
||||
|
||||
# INTROSPECTION_GIRDIR/INTROSPECTION_TYPELIBDIR aren't the right place to
|
||||
# install anything - we need to install inside our prefix.
|
||||
|
@ -34,6 +34,7 @@ stamp-marshal: $(marshal_list)
|
||||
$(AM_V_GEN)$(GLIB_GENMARSHAL) \
|
||||
--prefix=$(glib_marshal_prefix) \
|
||||
--header \
|
||||
--valist-marshallers \
|
||||
$(marshal_list) > xgen-mh \
|
||||
&& (cmp -s xgen-mh $(marshal_h) || cp -f xgen-mh $(marshal_h)) \
|
||||
&& rm -f xgen-mh \
|
||||
@ -43,10 +44,11 @@ $(marshal_h): stamp-marshal
|
||||
@true
|
||||
|
||||
$(marshal_c): $(marshal_h)
|
||||
$(AM_V_GEN)(echo "#include \"$(marshal_h)\"" ; \
|
||||
$(GLIB_GENMARSHAL) \
|
||||
$(AM_V_GEN)$(GLIB_GENMARSHAL) \
|
||||
--prefix=$(glib_marshal_prefix) \
|
||||
--body \
|
||||
$(marshal_list)) > xgen-mc \
|
||||
&& cp xgen-mc $(marshal_c) \
|
||||
--valist-marshallers \
|
||||
--prototypes \
|
||||
$(marshal_list) > xgen-mc \
|
||||
&& (cmp -s xgen-mc $(marshal_c) || cp -f xgen-mc $(marshal_c)) \
|
||||
&& rm -f xgen-mc
|
||||
|
@ -781,7 +781,7 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
|
||||
"position of the stage");
|
||||
}
|
||||
else
|
||||
#else
|
||||
#endif
|
||||
{
|
||||
static gboolean yet_warned = FALSE;
|
||||
|
||||
@ -793,7 +793,6 @@ _cally_actor_get_top_level_origin (ClutterActor *actor,
|
||||
"atk_component_get_extents() with ATK_XY_SCREEN.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (xp)
|
||||
*xp = x;
|
||||
|
@ -214,6 +214,8 @@ cally_util_simulate_snooper_install (void)
|
||||
G_CALLBACK (cally_util_stage_added_cb), cally_key_snooper);
|
||||
g_signal_connect (G_OBJECT (stage_manager), "stage-removed",
|
||||
G_CALLBACK (cally_util_stage_removed_cb), cally_key_snooper);
|
||||
|
||||
g_slist_free (stage_list);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2656,7 +2656,15 @@ _clutter_actor_signal_queue_redraw (ClutterActor *self,
|
||||
_clutter_actor_queue_redraw_on_clones (self);
|
||||
|
||||
/* calls klass->queue_redraw in default handler */
|
||||
g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin);
|
||||
if (g_signal_has_handler_pending (self, actor_signals[QUEUE_REDRAW],
|
||||
0, TRUE))
|
||||
{
|
||||
g_signal_emit (self, actor_signals[QUEUE_REDRAW], 0, origin);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLUTTER_ACTOR_GET_CLASS (self)->queue_redraw (self, origin);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2813,7 +2821,7 @@ _clutter_actor_fully_transform_vertices (ClutterActor *self,
|
||||
/* Note: we pass NULL as the ancestor because we don't just want the modelview
|
||||
* that gets us to stage coordinates, we want to go all the way to eye
|
||||
* coordinates */
|
||||
_clutter_actor_apply_relative_transformation_matrix (self, NULL, &modelview);
|
||||
_clutter_actor_get_relative_transformation_matrix (self, NULL, &modelview);
|
||||
|
||||
/* Fetch the projection and viewport */
|
||||
_clutter_stage_get_projection_matrix (CLUTTER_STAGE (stage), &projection);
|
||||
@ -4015,7 +4023,11 @@ clutter_actor_continue_paint (ClutterActor *self)
|
||||
clutter_paint_node_unref (dummy);
|
||||
|
||||
/* XXX:2.0 - Call the paint() virtual directly */
|
||||
g_signal_emit (self, actor_signals[PAINT], 0);
|
||||
if (g_signal_has_handler_pending (self, actor_signals[PAINT],
|
||||
0, TRUE))
|
||||
g_signal_emit (self, actor_signals[PAINT], 0);
|
||||
else
|
||||
CLUTTER_ACTOR_GET_CLASS (self)->paint (self);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4029,7 +4041,11 @@ clutter_actor_continue_paint (ClutterActor *self)
|
||||
*
|
||||
* XXX:2.0 - Call the pick() virtual directly
|
||||
*/
|
||||
g_signal_emit (self, actor_signals[PICK], 0, &col);
|
||||
if (g_signal_has_handler_pending (self, actor_signals[PICK],
|
||||
0, TRUE))
|
||||
g_signal_emit (self, actor_signals[PICK], 0, &col);
|
||||
else
|
||||
CLUTTER_ACTOR_GET_CLASS (self)->pick (self, &col);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -58,6 +58,8 @@ struct _ClutterBackend
|
||||
gint32 units_serial;
|
||||
|
||||
GList *event_translators;
|
||||
|
||||
ClutterInputMethod *input_method;
|
||||
};
|
||||
|
||||
struct _ClutterBackendClass
|
||||
@ -100,6 +102,8 @@ struct _ClutterBackendClass
|
||||
|
||||
PangoDirection (* get_keymap_direction) (ClutterBackend *backend);
|
||||
|
||||
void (* bell_notify) (ClutterBackend *backend);
|
||||
|
||||
/* signals */
|
||||
void (* resolution_changed) (ClutterBackend *backend);
|
||||
void (* font_changed) (ClutterBackend *backend);
|
||||
|
@ -127,6 +127,7 @@ clutter_backend_finalize (GObject *gobject)
|
||||
|
||||
g_free (backend->font_name);
|
||||
clutter_backend_set_font_options (backend, NULL);
|
||||
g_clear_object (&backend->input_method);
|
||||
|
||||
G_OBJECT_CLASS (clutter_backend_parent_class)->finalize (gobject);
|
||||
}
|
||||
@ -1363,3 +1364,41 @@ clutter_set_allowed_drivers (const char *drivers)
|
||||
|
||||
allowed_drivers = g_strdup (drivers);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_backend_bell_notify (ClutterBackend *backend)
|
||||
{
|
||||
ClutterBackendClass *klass;
|
||||
|
||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||
if (klass->bell_notify)
|
||||
klass->bell_notify (backend);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_backend_get_input_method:
|
||||
* @backend: the #CLutterBackend
|
||||
*
|
||||
* Returns the input method used by Clutter
|
||||
*
|
||||
* Returns: (transfer none): the input method
|
||||
**/
|
||||
ClutterInputMethod *
|
||||
clutter_backend_get_input_method (ClutterBackend *backend)
|
||||
{
|
||||
return backend->input_method;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_backend_set_input_method:
|
||||
* @backend: the #ClutterBackend
|
||||
* @method: the input method
|
||||
*
|
||||
* Sets the input method to be used by Clutter
|
||||
**/
|
||||
void
|
||||
clutter_backend_set_input_method (ClutterBackend *backend,
|
||||
ClutterInputMethod *method)
|
||||
{
|
||||
g_set_object (&backend->input_method, method);
|
||||
}
|
||||
|
@ -74,6 +74,15 @@ const cairo_font_options_t * clutter_backend_get_font_options (Clutter
|
||||
CLUTTER_AVAILABLE_IN_1_8
|
||||
CoglContext * clutter_backend_get_cogl_context (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_backend_bell_notify (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
ClutterInputMethod * clutter_backend_get_input_method (ClutterBackend *backend);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_backend_set_input_method (ClutterBackend *backend,
|
||||
ClutterInputMethod *method);
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_BACKEND_H__ */
|
||||
|
@ -324,7 +324,7 @@ _clutter_bezier_init (ClutterBezier *b,
|
||||
* triggers, we need to change those two functions a bit.
|
||||
*/
|
||||
if (b->ax > 0x1fff || b->bx > 0x1fff || b->cx > 0x1fff)
|
||||
g_warning ("Calculated coefficents will result in multiplication "
|
||||
g_warning ("Calculated coefficients will result in multiplication "
|
||||
"overflow in clutter_bezier_t2x and clutter_bezier_t2y.");
|
||||
|
||||
/*
|
||||
|
@ -76,9 +76,6 @@ struct _ClutterCanvasPrivate
|
||||
gboolean dirty;
|
||||
|
||||
CoglBitmap *buffer;
|
||||
|
||||
int scale_factor;
|
||||
guint scale_factor_set : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -87,8 +84,6 @@ enum
|
||||
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT,
|
||||
PROP_SCALE_FACTOR,
|
||||
PROP_SCALE_FACTOR_SET,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
@ -185,11 +180,6 @@ clutter_canvas_set_property (GObject *gobject,
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
clutter_canvas_set_scale_factor (CLUTTER_CANVAS (gobject),
|
||||
g_value_get_int (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@ -214,17 +204,6 @@ clutter_canvas_get_property (GObject *gobject,
|
||||
g_value_set_int (value, priv->height);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR:
|
||||
if (priv->scale_factor_set)
|
||||
g_value_set_int (value, priv->scale_factor);
|
||||
else
|
||||
g_value_set_int (value, -1);
|
||||
break;
|
||||
|
||||
case PROP_SCALE_FACTOR_SET:
|
||||
g_value_set_boolean (value, priv->scale_factor_set);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@ -268,46 +247,6 @@ clutter_canvas_class_init (ClutterCanvasClass *klass)
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterCanvas:scale-factor-set:
|
||||
*
|
||||
* Whether the #ClutterCanvas:scale-factor property is set.
|
||||
*
|
||||
* If the #ClutterCanvas:scale-factor-set property is %FALSE
|
||||
* then #ClutterCanvas will use the #ClutterSettings:window-scaling-factor
|
||||
* property.
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
obj_props[PROP_SCALE_FACTOR_SET] =
|
||||
g_param_spec_boolean ("scale-factor-set",
|
||||
P_("Scale Factor Set"),
|
||||
P_("Whether the scale-factor property is set"),
|
||||
FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterCanvas:scale-factor:
|
||||
*
|
||||
* The scaling factor to be applied to the Cairo surface used for
|
||||
* drawing.
|
||||
*
|
||||
* If #ClutterCanvas:scale-factor is set to a negative value, the
|
||||
* value of the #ClutterSettings:window-scaling-factor property is
|
||||
* used instead.
|
||||
*
|
||||
* Use #ClutterCanvas:scale-factor-set to check if the scale factor
|
||||
* is set.
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
obj_props[PROP_SCALE_FACTOR] =
|
||||
g_param_spec_int ("scale-factor",
|
||||
P_("Scale Factor"),
|
||||
P_("The scaling factor for the surface"),
|
||||
-1, 1000,
|
||||
-1,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClutterCanvas::draw:
|
||||
@ -354,7 +293,6 @@ clutter_canvas_init (ClutterCanvas *self)
|
||||
|
||||
self->priv->width = -1;
|
||||
self->priv->height = -1;
|
||||
self->priv->scale_factor = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -397,7 +335,6 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
|
||||
gboolean mapped_buffer;
|
||||
unsigned char *data;
|
||||
CoglBuffer *buffer;
|
||||
int window_scale = 1;
|
||||
gboolean res;
|
||||
cairo_t *cr;
|
||||
|
||||
@ -405,20 +342,11 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
|
||||
|
||||
priv->dirty = TRUE;
|
||||
|
||||
if (priv->scale_factor_set)
|
||||
window_scale = priv->scale_factor;
|
||||
else
|
||||
g_object_get (clutter_settings_get_default (),
|
||||
"window-scaling-factor", &window_scale,
|
||||
NULL);
|
||||
real_width = priv->width;
|
||||
real_height = priv->height;
|
||||
|
||||
real_width = priv->width * window_scale;
|
||||
real_height = priv->height * window_scale;
|
||||
|
||||
CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d (real: %d x %d, scale: %d)",
|
||||
priv->width, priv->height,
|
||||
real_width, real_height,
|
||||
window_scale);
|
||||
CLUTTER_NOTE (MISC, "Creating Cairo surface with size %d x %d",
|
||||
priv->width, priv->height);
|
||||
|
||||
if (priv->buffer == NULL)
|
||||
{
|
||||
@ -461,8 +389,6 @@ clutter_canvas_emit_draw (ClutterCanvas *self)
|
||||
mapped_buffer = FALSE;
|
||||
}
|
||||
|
||||
cairo_surface_set_device_scale (surface, window_scale, window_scale);
|
||||
|
||||
self->priv->cr = cr = cairo_create (surface);
|
||||
|
||||
g_signal_emit (self, canvas_signals[DRAW], 0,
|
||||
@ -636,81 +562,3 @@ clutter_canvas_set_size (ClutterCanvas *canvas,
|
||||
|
||||
return clutter_canvas_invalidate_internal (canvas, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_canvas_set_scale_factor:
|
||||
* @canvas: a #ClutterCanvas
|
||||
* @scale: the scale factor, or -1 for the default
|
||||
*
|
||||
* Sets the scaling factor for the Cairo surface used by @canvas.
|
||||
*
|
||||
* This function should rarely be used.
|
||||
*
|
||||
* The default scaling factor of a #ClutterCanvas content uses the
|
||||
* #ClutterSettings:window-scaling-factor property, which is set by
|
||||
* the windowing system. By using this function it is possible to
|
||||
* override that setting.
|
||||
*
|
||||
* Changing the scale factor will invalidate the @canvas.
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
void
|
||||
clutter_canvas_set_scale_factor (ClutterCanvas *canvas,
|
||||
int scale)
|
||||
{
|
||||
ClutterCanvasPrivate *priv;
|
||||
GObject *obj;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
|
||||
g_return_if_fail (scale != 0);
|
||||
|
||||
priv = canvas->priv;
|
||||
|
||||
if (scale < 0)
|
||||
{
|
||||
if (!priv->scale_factor_set)
|
||||
return;
|
||||
|
||||
priv->scale_factor_set = FALSE;
|
||||
priv->scale_factor = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (priv->scale_factor_set && priv->scale_factor == scale)
|
||||
return;
|
||||
|
||||
priv->scale_factor_set = TRUE;
|
||||
priv->scale_factor = scale;
|
||||
}
|
||||
|
||||
clutter_content_invalidate (CLUTTER_CONTENT (canvas));
|
||||
|
||||
obj = G_OBJECT (canvas);
|
||||
|
||||
g_object_notify_by_pspec (obj, obj_props[PROP_SCALE_FACTOR]);
|
||||
g_object_notify_by_pspec (obj, obj_props[PROP_SCALE_FACTOR_SET]);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_canvas_get_scale_factor:
|
||||
* @canvas: a #ClutterCanvas
|
||||
*
|
||||
* Retrieves the scaling factor of @canvas, as set using
|
||||
* clutter_canvas_set_scale_factor().
|
||||
*
|
||||
* Return value: the scaling factor, or -1 if the @canvas
|
||||
* uses the default from #ClutterSettings
|
||||
*
|
||||
* Since: 1.18
|
||||
*/
|
||||
int
|
||||
clutter_canvas_get_scale_factor (ClutterCanvas *canvas)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_CANVAS (canvas), -1);
|
||||
|
||||
if (!canvas->priv->scale_factor_set)
|
||||
return -1;
|
||||
|
||||
return canvas->priv->scale_factor;
|
||||
}
|
||||
|
@ -54,6 +54,7 @@
|
||||
struct _ClutterClonePrivate
|
||||
{
|
||||
ClutterActor *clone_source;
|
||||
gulong source_destroy_id;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClutterClone, clutter_clone, CLUTTER_TYPE_ACTOR)
|
||||
@ -376,6 +377,13 @@ clutter_clone_new (ClutterActor *source)
|
||||
return g_object_new (CLUTTER_TYPE_CLONE, "source", source, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
on_source_destroyed (ClutterActor *source,
|
||||
ClutterClone *self)
|
||||
{
|
||||
clutter_clone_set_source_internal (self, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_clone_set_source_internal (ClutterClone *self,
|
||||
ClutterActor *source)
|
||||
@ -387,6 +395,8 @@ clutter_clone_set_source_internal (ClutterClone *self,
|
||||
|
||||
if (priv->clone_source != NULL)
|
||||
{
|
||||
g_signal_handler_disconnect (priv->clone_source, priv->source_destroy_id);
|
||||
priv->source_destroy_id = 0;
|
||||
_clutter_actor_detach_clone (priv->clone_source, CLUTTER_ACTOR (self));
|
||||
g_object_unref (priv->clone_source);
|
||||
priv->clone_source = NULL;
|
||||
@ -396,6 +406,8 @@ clutter_clone_set_source_internal (ClutterClone *self,
|
||||
{
|
||||
priv->clone_source = g_object_ref (source);
|
||||
_clutter_actor_attach_clone (priv->clone_source, CLUTTER_ACTOR (self));
|
||||
priv->source_destroy_id = g_signal_connect (priv->clone_source, "destroy",
|
||||
G_CALLBACK (on_source_destroyed), self);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_SOURCE]);
|
||||
|
@ -48,7 +48,7 @@
|
||||
#include "clutter-debug.h"
|
||||
|
||||
/* XXX - keep in sync with the ClutterStaticColor enumeration order */
|
||||
static const ClutterColor const static_colors[] = {
|
||||
static const ClutterColor static_colors[] = {
|
||||
/* CGA/EGA color palette */
|
||||
{ 0xff, 0xff, 0xff, 0xff }, /* white */
|
||||
{ 0x00, 0x00, 0x00, 0xff }, /* black */
|
||||
|
@ -145,6 +145,9 @@ struct _ClutterInputDevice
|
||||
guint is_enabled : 1;
|
||||
};
|
||||
|
||||
typedef void (*ClutterEmitInputDeviceEvent) (ClutterEvent *event,
|
||||
ClutterInputDevice *device);
|
||||
|
||||
struct _ClutterInputDeviceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
@ -154,6 +157,20 @@ struct _ClutterInputDeviceClass
|
||||
guint *evdev_keycode);
|
||||
void (* update_from_tool) (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool);
|
||||
|
||||
gboolean (* is_mode_switch_button) (ClutterInputDevice *device,
|
||||
guint group,
|
||||
guint button);
|
||||
gint (* get_group_n_modes) (ClutterInputDevice *device,
|
||||
gint group);
|
||||
|
||||
gboolean (* is_grouped) (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device);
|
||||
|
||||
/* Keyboard accessbility */
|
||||
void (* process_kbd_a11y_event) (ClutterEvent *event,
|
||||
ClutterInputDevice *device,
|
||||
ClutterEmitInputDeviceEvent emit_event_func);
|
||||
};
|
||||
|
||||
/* Platform-dependent interface */
|
||||
|
@ -48,11 +48,15 @@
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-virtual-input-device.h"
|
||||
#include "clutter-input-device-tool.h"
|
||||
|
||||
struct _ClutterDeviceManagerPrivate
|
||||
{
|
||||
/* back-pointer to the backend */
|
||||
ClutterBackend *backend;
|
||||
|
||||
/* Keyboard a11y */
|
||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -70,6 +74,9 @@ enum
|
||||
{
|
||||
DEVICE_ADDED,
|
||||
DEVICE_REMOVED,
|
||||
TOOL_CHANGED,
|
||||
KBD_A11Y_MASK_CHANGED,
|
||||
KBD_A11Y_FLAGS_CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
@ -184,6 +191,56 @@ clutter_device_manager_class_init (ClutterDeviceManagerClass *klass)
|
||||
_clutter_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_INPUT_DEVICE);
|
||||
|
||||
manager_signals[TOOL_CHANGED] =
|
||||
g_signal_new (I_("tool-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__OBJECT_OBJECT,
|
||||
G_TYPE_NONE, 2,
|
||||
CLUTTER_TYPE_INPUT_DEVICE,
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL);
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager::kbd-a11y-mods-state-changed:
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @latched_mask: the latched modifier mask from stickykeys
|
||||
* @locked_mask: the locked modifier mask from stickykeys
|
||||
*
|
||||
* The ::kbd-a11y-mods-state-changed signal is emitted each time either the
|
||||
* latched modifiers mask or locked modifiers mask are changed as the
|
||||
* result of keyboard accessibilty's sticky keys operations.
|
||||
*/
|
||||
manager_signals[KBD_A11Y_MASK_CHANGED] =
|
||||
g_signal_new (I_("kbd-a11y-mods-state-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__UINT_UINT,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_UINT);
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager::kbd-a11y-flags-changed:
|
||||
* @manager: the #ClutterDeviceManager that emitted the signal
|
||||
* @settings_flags: the new ClutterKeyboardA11yFlags configuration
|
||||
* @changed_mask: the ClutterKeyboardA11yFlags changed
|
||||
*
|
||||
* The ::kbd-a11y-flags-changed signal is emitted each time the
|
||||
* ClutterKeyboardA11yFlags configuration is changed as the result of
|
||||
* keyboard accessibilty operations.
|
||||
*/
|
||||
manager_signals[KBD_A11Y_FLAGS_CHANGED] =
|
||||
g_signal_new (I_("kbd-a11y-flags-changed"),
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__UINT_UINT,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_UINT);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -459,6 +516,21 @@ clutter_device_manager_create_virtual_device (ClutterDeviceManager *device_man
|
||||
device_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_device_manager_supported_virtua_device_types: (skip)
|
||||
*/
|
||||
ClutterVirtualDeviceType
|
||||
clutter_device_manager_get_supported_virtual_device_types (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
ClutterDeviceManagerClass *manager_class;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager),
|
||||
CLUTTER_VIRTUAL_DEVICE_TYPE_NONE);
|
||||
|
||||
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
|
||||
return manager_class->get_supported_virtual_device_types (device_manager);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_device_manager_compress_motion (ClutterDeviceManager *device_manager,
|
||||
ClutterEvent *event,
|
||||
@ -475,3 +547,43 @@ _clutter_device_manager_compress_motion (ClutterDeviceManager *device_manager,
|
||||
|
||||
manager_class->compress_motion (device_manager, event, to_discard);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
are_kbd_a11y_settings_equal (ClutterKbdA11ySettings *a,
|
||||
ClutterKbdA11ySettings *b)
|
||||
{
|
||||
return (a->controls == b->controls &&
|
||||
a->slowkeys_delay == b->slowkeys_delay &&
|
||||
a->debounce_delay == b->debounce_delay &&
|
||||
a->timeout_delay == b->timeout_delay &&
|
||||
a->mousekeys_init_delay == b->mousekeys_init_delay &&
|
||||
a->mousekeys_max_speed == b->mousekeys_max_speed &&
|
||||
a->mousekeys_accel_time == b->mousekeys_accel_time);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings)
|
||||
{
|
||||
ClutterDeviceManagerClass *manager_class;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
if (are_kbd_a11y_settings_equal (&device_manager->priv->kbd_a11y_settings, settings))
|
||||
return;
|
||||
|
||||
device_manager->priv->kbd_a11y_settings = *settings;
|
||||
|
||||
manager_class = CLUTTER_DEVICE_MANAGER_GET_CLASS (device_manager);
|
||||
if (manager_class->apply_kbd_a11y_settings)
|
||||
manager_class->apply_kbd_a11y_settings (device_manager, settings);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager));
|
||||
|
||||
*settings = device_manager->priv->kbd_a11y_settings;
|
||||
}
|
||||
|
@ -44,6 +44,35 @@ typedef struct _ClutterDeviceManager ClutterDeviceManager;
|
||||
typedef struct _ClutterDeviceManagerPrivate ClutterDeviceManagerPrivate;
|
||||
typedef struct _ClutterDeviceManagerClass ClutterDeviceManagerClass;
|
||||
|
||||
/**
|
||||
* ClutterVirtualDeviceType:
|
||||
*/
|
||||
typedef enum _ClutterVirtualDeviceType
|
||||
{
|
||||
CLUTTER_VIRTUAL_DEVICE_TYPE_NONE = 0,
|
||||
CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD = 1 << 0,
|
||||
CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER = 1 << 1,
|
||||
CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN = 1 << 2,
|
||||
} ClutterVirtualDeviceType;
|
||||
|
||||
/**
|
||||
* ClutterKbdA11ySettings:
|
||||
*
|
||||
* The #ClutterKbdA11ySettings structure contains keyboard accessibility
|
||||
* settings
|
||||
*
|
||||
*/
|
||||
typedef struct _ClutterKbdA11ySettings
|
||||
{
|
||||
ClutterKeyboardA11yFlags controls;
|
||||
gint slowkeys_delay;
|
||||
gint debounce_delay;
|
||||
gint timeout_delay;
|
||||
gint mousekeys_init_delay;
|
||||
gint mousekeys_max_speed;
|
||||
gint mousekeys_accel_time;
|
||||
} ClutterKbdA11ySettings;
|
||||
|
||||
/**
|
||||
* ClutterDeviceManager:
|
||||
*
|
||||
@ -83,12 +112,15 @@ struct _ClutterDeviceManagerClass
|
||||
ClutterInputDevice *device);
|
||||
void (* select_stage_events) (ClutterDeviceManager *manager,
|
||||
ClutterStage *stage);
|
||||
ClutterVirtualInputDevice *(* create_virtual_device) (ClutterDeviceManager *manager,
|
||||
ClutterVirtualInputDevice *(* create_virtual_device) (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDeviceType device_type);
|
||||
ClutterVirtualDeviceType (* get_supported_virtual_device_types) (ClutterDeviceManager *device_manager);
|
||||
void (* compress_motion) (ClutterDeviceManager *device_manger,
|
||||
ClutterEvent *event,
|
||||
const ClutterEvent *to_discard);
|
||||
|
||||
/* Keyboard accessbility */
|
||||
void (* apply_kbd_a11y_settings) (ClutterDeviceManager *device_manger,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
/* padding */
|
||||
gpointer _padding[6];
|
||||
};
|
||||
@ -114,6 +146,16 @@ CLUTTER_AVAILABLE_IN_ALL
|
||||
ClutterVirtualInputDevice *clutter_device_manager_create_virtual_device (ClutterDeviceManager *device_manager,
|
||||
ClutterInputDeviceType device_type);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
ClutterVirtualDeviceType clutter_device_manager_get_supported_virtual_device_types (ClutterDeviceManager *device_manager);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_device_manager_set_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_device_manager_get_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_DEVICE_MANAGER_H__ */
|
||||
|
@ -396,6 +396,43 @@ typedef enum {
|
||||
CLUTTER_MODIFIER_MASK = 0x5c001fff
|
||||
} ClutterModifierType;
|
||||
|
||||
/**
|
||||
* ClutterKeyboardA11yFlags:
|
||||
* @CLUTTER_A11Y_KEYBOARD_ENABLED:
|
||||
* @CLUTTER_A11Y_TIMEOUT_ENABLED:
|
||||
* @CLUTTER_A11Y_MOUSE_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT:
|
||||
* @CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT:
|
||||
* @CLUTTER_A11Y_BOUNCE_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT:
|
||||
* @CLUTTER_A11Y_TOGGLE_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_STICKY_KEYS_ENABLED:
|
||||
* @CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF:
|
||||
* @CLUTTER_A11Y_STICKY_KEYS_BEEP:
|
||||
* @CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP:
|
||||
*
|
||||
* Keyboard accessibility features applied to a ClutterInputDevice keyboard.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
CLUTTER_A11Y_KEYBOARD_ENABLED = 1 << 0,
|
||||
CLUTTER_A11Y_TIMEOUT_ENABLED = 1 << 1,
|
||||
CLUTTER_A11Y_MOUSE_KEYS_ENABLED = 1 << 2,
|
||||
CLUTTER_A11Y_SLOW_KEYS_ENABLED = 1 << 3,
|
||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS = 1 << 4,
|
||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT = 1 << 5,
|
||||
CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT = 1 << 6,
|
||||
CLUTTER_A11Y_BOUNCE_KEYS_ENABLED = 1 << 7,
|
||||
CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT = 1 << 8,
|
||||
CLUTTER_A11Y_TOGGLE_KEYS_ENABLED = 1 << 9,
|
||||
CLUTTER_A11Y_STICKY_KEYS_ENABLED = 1 << 10,
|
||||
CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF = 1 << 11,
|
||||
CLUTTER_A11Y_STICKY_KEYS_BEEP = 1 << 12,
|
||||
CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP = 1 << 13,
|
||||
} ClutterKeyboardA11yFlags;
|
||||
|
||||
/**
|
||||
* ClutterActorFlags:
|
||||
* @CLUTTER_ACTOR_MAPPED: the actor will be painted (is visible, and inside
|
||||
@ -730,8 +767,9 @@ typedef enum { /*< prefix=CLUTTER_DRAG >*/
|
||||
* Since: 0.6
|
||||
*/
|
||||
typedef enum { /*< flags prefix=CLUTTER_EVENT >*/
|
||||
CLUTTER_EVENT_NONE = 0,
|
||||
CLUTTER_EVENT_FLAG_SYNTHETIC = 1 << 0
|
||||
CLUTTER_EVENT_NONE = 0,
|
||||
CLUTTER_EVENT_FLAG_SYNTHETIC = 1 << 0,
|
||||
CLUTTER_EVENT_FLAG_INPUT_METHOD = 1 << 1
|
||||
} ClutterEventFlags;
|
||||
|
||||
/**
|
||||
@ -1536,6 +1574,41 @@ typedef enum {
|
||||
CLUTTER_INPUT_DEVICE_MAPPING_RELATIVE,
|
||||
} ClutterInputDeviceMapping;
|
||||
|
||||
typedef enum {
|
||||
CLUTTER_INPUT_CONTENT_HINT_COMPLETION = 1 << 0,
|
||||
CLUTTER_INPUT_CONTENT_HINT_SPELLCHECK = 1 << 1,
|
||||
CLUTTER_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION = 1 << 2,
|
||||
CLUTTER_INPUT_CONTENT_HINT_LOWERCASE = 1 << 3,
|
||||
CLUTTER_INPUT_CONTENT_HINT_UPPERCASE = 1 << 4,
|
||||
CLUTTER_INPUT_CONTENT_HINT_TITLECASE = 1 << 5,
|
||||
CLUTTER_INPUT_CONTENT_HINT_HIDDEN_TEXT = 1 << 6,
|
||||
CLUTTER_INPUT_CONTENT_HINT_SENSITIVE_DATA = 1 << 7,
|
||||
CLUTTER_INPUT_CONTENT_HINT_LATIN = 1 << 8,
|
||||
CLUTTER_INPUT_CONTENT_HINT_MULTILINE = 1 << 9,
|
||||
} ClutterInputContentHintFlags;
|
||||
|
||||
typedef enum {
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_NORMAL,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_ALPHA,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_DIGITS,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_NUMBER,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_PHONE,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_URL,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_EMAIL,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_NAME,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_PASSWORD,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_DATE,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_TIME,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_DATETIME,
|
||||
CLUTTER_INPUT_CONTENT_PURPOSE_TERMINAL,
|
||||
} ClutterInputContentPurpose;
|
||||
|
||||
typedef enum {
|
||||
CLUTTER_INPUT_PANEL_STATE_OFF,
|
||||
CLUTTER_INPUT_PANEL_STATE_ON,
|
||||
CLUTTER_INPUT_PANEL_STATE_TOGGLE,
|
||||
} ClutterInputPanelState;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_ENUMS_H__ */
|
||||
|
@ -1990,22 +1990,28 @@ clutter_event_remove_filter (guint id)
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_event_get_gesture_swipe_finger_count:
|
||||
* @event: a touchpad swipe event
|
||||
* clutter_event_get_touchpad_gesture_finger_count:
|
||||
* @event: a touchpad swipe/pinch event
|
||||
*
|
||||
* Returns the number of fingers that is triggering the touchpad gesture.
|
||||
*
|
||||
* Returns: the number of fingers swiping.
|
||||
* Returns: the number of fingers in the gesture.
|
||||
*
|
||||
* Since: 1.24
|
||||
**/
|
||||
guint
|
||||
clutter_event_get_gesture_swipe_finger_count (const ClutterEvent *event)
|
||||
clutter_event_get_touchpad_gesture_finger_count (const ClutterEvent *event)
|
||||
{
|
||||
g_return_val_if_fail (event != NULL, 0);
|
||||
g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_SWIPE, 0);
|
||||
g_return_val_if_fail (event->type == CLUTTER_TOUCHPAD_SWIPE ||
|
||||
event->type == CLUTTER_TOUCHPAD_PINCH, 0);
|
||||
|
||||
return event->touchpad_swipe.n_fingers;
|
||||
if (event->type == CLUTTER_TOUCHPAD_SWIPE)
|
||||
return event->touchpad_swipe.n_fingers;
|
||||
else if (event->type == CLUTTER_TOUCHPAD_PINCH)
|
||||
return event->touchpad_pinch.n_fingers;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2173,3 +2179,61 @@ clutter_event_get_mode_group (const ClutterEvent *event)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_event_get_pad_event_details:
|
||||
* @event: a pad event
|
||||
* @number: (out) (optional): ring/strip/button number
|
||||
* @mode: (out) (optional): pad mode as per the event
|
||||
* @value: (out) (optional): event axis value
|
||||
*
|
||||
* Returns the details of a pad event.
|
||||
*
|
||||
* Returns: #TRUE if event details could be obtained
|
||||
**/
|
||||
gboolean
|
||||
clutter_event_get_pad_event_details (const ClutterEvent *event,
|
||||
guint *number,
|
||||
guint *mode,
|
||||
gdouble *value)
|
||||
{
|
||||
guint n, m;
|
||||
gdouble v;
|
||||
|
||||
g_return_val_if_fail (event != NULL, FALSE);
|
||||
g_return_val_if_fail (event->type == CLUTTER_PAD_BUTTON_PRESS ||
|
||||
event->type == CLUTTER_PAD_BUTTON_RELEASE ||
|
||||
event->type == CLUTTER_PAD_RING ||
|
||||
event->type == CLUTTER_PAD_STRIP, FALSE);
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case CLUTTER_PAD_BUTTON_PRESS:
|
||||
case CLUTTER_PAD_BUTTON_RELEASE:
|
||||
n = event->pad_button.button;
|
||||
m = event->pad_button.mode;
|
||||
v = 0.0;
|
||||
break;
|
||||
case CLUTTER_PAD_RING:
|
||||
n = event->pad_ring.ring_number;
|
||||
m = event->pad_ring.mode;
|
||||
v = event->pad_ring.angle;
|
||||
break;
|
||||
case CLUTTER_PAD_STRIP:
|
||||
n = event->pad_strip.strip_number;
|
||||
m = event->pad_strip.mode;
|
||||
v = event->pad_strip.value;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (number)
|
||||
*number = n;
|
||||
if (mode)
|
||||
*mode = m;
|
||||
if (value)
|
||||
*value = v;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -459,6 +459,7 @@ struct _ClutterTouchpadPinchEvent
|
||||
gfloat dy;
|
||||
gfloat angle_delta;
|
||||
gfloat scale;
|
||||
guint n_fingers;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -507,6 +508,7 @@ struct _ClutterPadButtonEvent
|
||||
guint32 button;
|
||||
guint32 group;
|
||||
ClutterInputDevice *device;
|
||||
guint32 mode;
|
||||
};
|
||||
|
||||
struct _ClutterPadStripEvent
|
||||
@ -522,6 +524,7 @@ struct _ClutterPadStripEvent
|
||||
guint32 strip_number;
|
||||
guint32 group;
|
||||
gdouble value;
|
||||
guint32 mode;
|
||||
};
|
||||
|
||||
struct _ClutterPadRingEvent
|
||||
@ -537,6 +540,7 @@ struct _ClutterPadRingEvent
|
||||
guint32 ring_number;
|
||||
guint32 group;
|
||||
gdouble angle;
|
||||
guint32 mode;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -752,7 +756,7 @@ CLUTTER_AVAILABLE_IN_1_2
|
||||
const ClutterEvent * clutter_get_current_event (void);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_1_24
|
||||
guint clutter_event_get_gesture_swipe_finger_count (const ClutterEvent *event);
|
||||
guint clutter_event_get_touchpad_gesture_finger_count (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_1_24
|
||||
gdouble clutter_event_get_gesture_pinch_angle_delta (const ClutterEvent *event);
|
||||
@ -774,6 +778,12 @@ ClutterScrollFinishFlags clutter_event_get_scroll_finish_flags (const Clut
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
guint clutter_event_get_mode_group (const ClutterEvent *event);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
gboolean clutter_event_get_pad_event_details (const ClutterEvent *event,
|
||||
guint *number,
|
||||
guint *mode,
|
||||
gdouble *value);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -2175,6 +2175,63 @@ clutter_input_device_get_n_mode_groups (ClutterInputDevice *device)
|
||||
return device->n_mode_groups;
|
||||
}
|
||||
|
||||
gint
|
||||
clutter_input_device_get_group_n_modes (ClutterInputDevice *device,
|
||||
gint group)
|
||||
{
|
||||
ClutterInputDeviceClass *device_class;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), 0);
|
||||
g_return_val_if_fail (clutter_input_device_get_device_type (device) ==
|
||||
CLUTTER_PAD_DEVICE, 0);
|
||||
g_return_val_if_fail (group >= 0, 0);
|
||||
|
||||
device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device);
|
||||
|
||||
if (device_class->get_group_n_modes)
|
||||
return device_class->get_group_n_modes (device, group);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_input_device_is_mode_switch_button (ClutterInputDevice *device,
|
||||
guint group,
|
||||
guint button)
|
||||
{
|
||||
ClutterInputDeviceClass *device_class;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
||||
g_return_val_if_fail (clutter_input_device_get_device_type (device) ==
|
||||
CLUTTER_PAD_DEVICE, FALSE);
|
||||
|
||||
device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device);
|
||||
|
||||
if (device_class->is_mode_switch_button)
|
||||
return device_class->is_mode_switch_button (device, group, button);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint
|
||||
clutter_input_device_get_mode_switch_button_group (ClutterInputDevice *device,
|
||||
guint button)
|
||||
{
|
||||
gint group;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), -1);
|
||||
g_return_val_if_fail (clutter_input_device_get_device_type (device) ==
|
||||
CLUTTER_PAD_DEVICE, -1);
|
||||
|
||||
for (group = 0; group < device->n_mode_groups; group++)
|
||||
{
|
||||
if (clutter_input_device_is_mode_switch_button (device, group, button))
|
||||
return group;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
clutter_input_device_get_device_node (ClutterInputDevice *device)
|
||||
{
|
||||
@ -2186,10 +2243,15 @@ clutter_input_device_get_device_node (ClutterInputDevice *device)
|
||||
ClutterInputDeviceMapping
|
||||
clutter_input_device_get_mapping_mode (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterInputDeviceType device_type;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device),
|
||||
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE);
|
||||
g_return_val_if_fail (clutter_input_device_get_device_type (device) ==
|
||||
CLUTTER_TABLET_DEVICE,
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
g_return_val_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
|
||||
device_type == CLUTTER_PEN_DEVICE ||
|
||||
device_type == CLUTTER_ERASER_DEVICE,
|
||||
CLUTTER_INPUT_DEVICE_MAPPING_ABSOLUTE);
|
||||
|
||||
return device->mapping_mode;
|
||||
@ -2199,9 +2261,14 @@ void
|
||||
clutter_input_device_set_mapping_mode (ClutterInputDevice *device,
|
||||
ClutterInputDeviceMapping mapping)
|
||||
{
|
||||
ClutterInputDeviceType device_type;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
|
||||
g_return_if_fail (clutter_input_device_get_device_type (device) ==
|
||||
CLUTTER_TABLET_DEVICE);
|
||||
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
g_return_if_fail (device_type == CLUTTER_TABLET_DEVICE ||
|
||||
device_type == CLUTTER_PEN_DEVICE ||
|
||||
device_type == CLUTTER_ERASER_DEVICE);
|
||||
|
||||
if (device->mapping_mode == mapping)
|
||||
return;
|
||||
@ -2209,3 +2276,13 @@ clutter_input_device_set_mapping_mode (ClutterInputDevice *device,
|
||||
device->mapping_mode = mapping;
|
||||
g_object_notify (G_OBJECT (device), "mapping-mode");
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_input_device_is_grouped (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), FALSE);
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (other_device), FALSE);
|
||||
|
||||
return CLUTTER_INPUT_DEVICE_GET_CLASS (device)->is_grouped (device, other_device);
|
||||
}
|
||||
|
@ -147,6 +147,18 @@ gint clutter_input_device_get_n_strips (ClutterInputDev
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
gint clutter_input_device_get_n_mode_groups (ClutterInputDevice *device);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
gint clutter_input_device_get_group_n_modes (ClutterInputDevice *device,
|
||||
gint group);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
gboolean clutter_input_device_is_mode_switch_button (ClutterInputDevice *device,
|
||||
guint group,
|
||||
guint button);
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
gint clutter_input_device_get_mode_switch_button_group (ClutterInputDevice *device,
|
||||
guint button);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
const gchar * clutter_input_device_get_device_node (ClutterInputDevice *device);
|
||||
|
||||
@ -156,6 +168,9 @@ ClutterInputDeviceMapping clutter_input_device_get_mapping_mode (ClutterInputDev
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_input_device_set_mapping_mode (ClutterInputDevice *device,
|
||||
ClutterInputDeviceMapping mapping);
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
gboolean clutter_input_device_is_grouped (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
40
clutter/clutter/clutter-input-focus-private.h
Normal file
40
clutter/clutter/clutter-input-focus-private.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2017,2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_FOCUS_PRIVATE_H__
|
||||
#define __CLUTTER_INPUT_FOCUS_PRIVATE_H__
|
||||
|
||||
void clutter_input_focus_focus_in (ClutterInputFocus *focus,
|
||||
ClutterInputMethod *method);
|
||||
void clutter_input_focus_focus_out (ClutterInputFocus *focus);
|
||||
|
||||
void clutter_input_focus_commit (ClutterInputFocus *focus,
|
||||
const gchar *text);
|
||||
void clutter_input_focus_delete_surrounding (ClutterInputFocus *focus,
|
||||
guint offset,
|
||||
guint len);
|
||||
void clutter_input_focus_request_surrounding (ClutterInputFocus *focus);
|
||||
|
||||
void clutter_input_focus_set_preedit_text (ClutterInputFocus *focus,
|
||||
const gchar *preedit,
|
||||
guint cursor);
|
||||
|
||||
#endif /* __CLUTTER_INPUT_FOCUS_PRIVATE_H__ */
|
243
clutter/clutter/clutter-input-focus.c
Normal file
243
clutter/clutter/clutter-input-focus.c
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (C) 2017,2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter/clutter-input-focus.h"
|
||||
#include "clutter/clutter-input-focus-private.h"
|
||||
#include "clutter/clutter-input-method-private.h"
|
||||
|
||||
typedef struct _ClutterInputFocusPrivate ClutterInputFocusPrivate;
|
||||
|
||||
struct _ClutterInputFocusPrivate
|
||||
{
|
||||
ClutterInputMethod *im;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterInputFocus, clutter_input_focus, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
clutter_input_focus_real_focus_in (ClutterInputFocus *focus,
|
||||
ClutterInputMethod *im)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
priv->im = im;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_focus_real_focus_out (ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
priv->im = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_focus_class_init (ClutterInputFocusClass *klass)
|
||||
{
|
||||
klass->focus_in = clutter_input_focus_real_focus_in;
|
||||
klass->focus_out = clutter_input_focus_real_focus_out;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_focus_init (ClutterInputFocus *focus)
|
||||
{
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_input_focus_is_focused (ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
return !!priv->im;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_reset (ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
g_return_if_fail (clutter_input_focus_is_focused (focus));
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
clutter_input_method_reset (priv->im);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_cursor_location (ClutterInputFocus *focus,
|
||||
const ClutterRect *rect)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
g_return_if_fail (clutter_input_focus_is_focused (focus));
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
clutter_input_method_set_cursor_location (priv->im, rect);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_surrounding (ClutterInputFocus *focus,
|
||||
const gchar *text,
|
||||
guint cursor,
|
||||
guint anchor)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
g_return_if_fail (clutter_input_focus_is_focused (focus));
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
clutter_input_method_set_surrounding (priv->im, text, cursor, anchor);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_content_hints (ClutterInputFocus *focus,
|
||||
ClutterInputContentHintFlags hints)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
g_return_if_fail (clutter_input_focus_is_focused (focus));
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
clutter_input_method_set_content_hints (priv->im, hints);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_content_purpose (ClutterInputFocus *focus,
|
||||
ClutterInputContentPurpose purpose)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
g_return_if_fail (clutter_input_focus_is_focused (focus));
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
clutter_input_method_set_content_purpose (priv->im, purpose);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_input_focus_filter_key_event (ClutterInputFocus *focus,
|
||||
const ClutterKeyEvent *key)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_FOCUS (focus), FALSE);
|
||||
g_return_val_if_fail (clutter_input_focus_is_focused (focus), FALSE);
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
return clutter_input_method_filter_key_event (priv->im, key);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_can_show_preedit (ClutterInputFocus *focus,
|
||||
gboolean can_show_preedit)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
g_return_if_fail (clutter_input_focus_is_focused (focus));
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
clutter_input_method_set_can_show_preedit (priv->im, can_show_preedit);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_request_toggle_input_panel (ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterInputFocusPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
g_return_if_fail (clutter_input_focus_is_focused (focus));
|
||||
|
||||
priv = clutter_input_focus_get_instance_private (focus);
|
||||
|
||||
clutter_input_method_toggle_input_panel (priv->im);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_focus_in (ClutterInputFocus *focus,
|
||||
ClutterInputMethod *im)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->focus_in (focus, im);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_focus_out (ClutterInputFocus *focus)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
|
||||
CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->focus_out (focus);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_commit (ClutterInputFocus *focus,
|
||||
const gchar *text)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
|
||||
CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->commit_text (focus, text);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_delete_surrounding (ClutterInputFocus *focus,
|
||||
guint offset,
|
||||
guint len)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
|
||||
CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->delete_surrounding (focus, offset, len);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_request_surrounding (ClutterInputFocus *focus)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
|
||||
CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->request_surrounding (focus);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_focus_set_preedit_text (ClutterInputFocus *focus,
|
||||
const gchar *preedit,
|
||||
guint cursor)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
|
||||
CLUTTER_INPUT_FOCUS_GET_CLASS (focus)->set_preedit_text (focus, preedit, cursor);
|
||||
}
|
83
clutter/clutter/clutter-input-focus.h
Normal file
83
clutter/clutter/clutter-input-focus.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2017,2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_FOCUS_H__
|
||||
#define __CLUTTER_INPUT_FOCUS_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_FOCUS (clutter_input_focus_get_type ())
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterInputFocus, clutter_input_focus,
|
||||
CLUTTER, INPUT_FOCUS, GObject)
|
||||
|
||||
struct _ClutterInputFocusClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
GTypeInterface iface;
|
||||
|
||||
void (* focus_in) (ClutterInputFocus *focus,
|
||||
ClutterInputMethod *input_method);
|
||||
void (* focus_out) (ClutterInputFocus *focus);
|
||||
|
||||
void (* request_surrounding) (ClutterInputFocus *focus);
|
||||
void (* delete_surrounding) (ClutterInputFocus *focus,
|
||||
guint offset,
|
||||
guint len);
|
||||
void (* commit_text) (ClutterInputFocus *focus,
|
||||
const gchar *text);
|
||||
|
||||
void (* set_preedit_text) (ClutterInputFocus *focus,
|
||||
const gchar *preedit,
|
||||
guint cursor);
|
||||
};
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
gboolean clutter_input_focus_is_focused (ClutterInputFocus *focus);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_reset (ClutterInputFocus *focus);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_set_cursor_location (ClutterInputFocus *focus,
|
||||
const ClutterRect *rect);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_set_surrounding (ClutterInputFocus *focus,
|
||||
const gchar *text,
|
||||
guint cursor,
|
||||
guint anchor);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_set_content_hints (ClutterInputFocus *focus,
|
||||
ClutterInputContentHintFlags hint);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_set_content_purpose (ClutterInputFocus *focus,
|
||||
ClutterInputContentPurpose purpose);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
gboolean clutter_input_focus_filter_key_event (ClutterInputFocus *focus,
|
||||
const ClutterKeyEvent *key);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_set_can_show_preedit (ClutterInputFocus *focus,
|
||||
gboolean can_show_preedit);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_focus_request_toggle_input_panel (ClutterInputFocus *focus);
|
||||
|
||||
#endif /* __CLUTTER_INPUT_FOCUS_H__ */
|
46
clutter/clutter/clutter-input-method-private.h
Normal file
46
clutter/clutter/clutter-input-method-private.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2017,2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_METHOD_PRIVATE_H__
|
||||
#define __CLUTTER_INPUT_METHOD_PRIVATE_H__
|
||||
|
||||
ClutterInputFocus * clutter_input_method_get_focus (ClutterInputMethod *method);
|
||||
|
||||
void clutter_input_method_reset (ClutterInputMethod *method);
|
||||
|
||||
void clutter_input_method_set_cursor_location (ClutterInputMethod *method,
|
||||
const ClutterRect *rect);
|
||||
void clutter_input_method_set_surrounding (ClutterInputMethod *method,
|
||||
const gchar *text,
|
||||
guint cursor,
|
||||
guint anchor);
|
||||
void clutter_input_method_set_content_hints (ClutterInputMethod *method,
|
||||
ClutterInputContentHintFlags hints);
|
||||
void clutter_input_method_set_content_purpose (ClutterInputMethod *method,
|
||||
ClutterInputContentPurpose purpose);
|
||||
void clutter_input_method_set_can_show_preedit (ClutterInputMethod *method,
|
||||
gboolean can_show_preedit);
|
||||
gboolean clutter_input_method_filter_key_event (ClutterInputMethod *method,
|
||||
const ClutterKeyEvent *key);
|
||||
|
||||
void clutter_input_method_toggle_input_panel (ClutterInputMethod *method);
|
||||
|
||||
#endif /* __CLUTTER_INPUT_METHOD_PRIVATE_H__ */
|
444
clutter/clutter/clutter-input-method.c
Normal file
444
clutter/clutter/clutter-input-method.c
Normal file
@ -0,0 +1,444 @@
|
||||
/*
|
||||
* Copyright (C) 2017,2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#include "clutter-build-config.h"
|
||||
|
||||
#include "clutter-private.h"
|
||||
#include "clutter/clutter-input-method.h"
|
||||
#include "clutter/clutter-input-method-private.h"
|
||||
#include "clutter/clutter-input-focus-private.h"
|
||||
|
||||
typedef struct _ClutterInputMethodPrivate ClutterInputMethodPrivate;
|
||||
|
||||
struct _ClutterInputMethodPrivate
|
||||
{
|
||||
ClutterInputFocus *focus;
|
||||
ClutterInputContentHintFlags content_hints;
|
||||
ClutterInputContentPurpose content_purpose;
|
||||
gboolean can_show_preedit;
|
||||
};
|
||||
|
||||
enum {
|
||||
COMMIT,
|
||||
DELETE_SURROUNDING,
|
||||
REQUEST_SURROUNDING,
|
||||
INPUT_PANEL_STATE,
|
||||
CURSOR_LOCATION_CHANGED,
|
||||
N_SIGNALS,
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_CONTENT_HINTS,
|
||||
PROP_CONTENT_PURPOSE,
|
||||
PROP_CAN_SHOW_PREEDIT,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
static GParamSpec *pspecs[N_PROPS] = { 0 };
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (ClutterInputMethod, clutter_input_method, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
set_content_hints (ClutterInputMethod *im,
|
||||
ClutterInputContentHintFlags content_hints)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
priv->content_hints = content_hints;
|
||||
CLUTTER_INPUT_METHOD_GET_CLASS (im)->update_content_hints (im, content_hints);
|
||||
}
|
||||
|
||||
static void
|
||||
set_content_purpose (ClutterInputMethod *im,
|
||||
ClutterInputContentPurpose content_purpose)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
priv->content_purpose = content_purpose;
|
||||
CLUTTER_INPUT_METHOD_GET_CLASS (im)->update_content_purpose (im,
|
||||
content_purpose);
|
||||
}
|
||||
|
||||
static void
|
||||
set_can_show_preedit (ClutterInputMethod *im,
|
||||
gboolean can_show_preedit)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
priv->can_show_preedit = can_show_preedit;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_method_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT_HINTS:
|
||||
set_content_hints (CLUTTER_INPUT_METHOD (object),
|
||||
g_value_get_flags (value));
|
||||
break;
|
||||
case PROP_CONTENT_PURPOSE:
|
||||
set_content_purpose (CLUTTER_INPUT_METHOD (object),
|
||||
g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_CAN_SHOW_PREEDIT:
|
||||
set_can_show_preedit (CLUTTER_INPUT_METHOD (object),
|
||||
g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_method_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
ClutterInputMethod *im;
|
||||
|
||||
im = CLUTTER_INPUT_METHOD (object);
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_CONTENT_HINTS:
|
||||
g_value_set_flags (value, priv->content_hints);
|
||||
break;
|
||||
case PROP_CONTENT_PURPOSE:
|
||||
g_value_set_enum (value, priv->content_purpose);
|
||||
break;
|
||||
case PROP_CAN_SHOW_PREEDIT:
|
||||
g_value_set_boolean (value, priv->can_show_preedit);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_method_class_init (ClutterInputMethodClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->set_property = clutter_input_method_set_property;
|
||||
object_class->get_property = clutter_input_method_get_property;
|
||||
|
||||
signals[COMMIT] =
|
||||
g_signal_new ("commit",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||
signals[DELETE_SURROUNDING] =
|
||||
g_signal_new ("delete-surrounding",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
|
||||
signals[REQUEST_SURROUNDING] =
|
||||
g_signal_new ("request-surrounding",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
signals[INPUT_PANEL_STATE] =
|
||||
g_signal_new ("input-panel-state",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
CLUTTER_TYPE_INPUT_PANEL_STATE);
|
||||
signals[CURSOR_LOCATION_CHANGED] =
|
||||
g_signal_new ("cursor-location-changed",
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 1, CLUTTER_TYPE_RECT);
|
||||
|
||||
pspecs[PROP_CONTENT_HINTS] =
|
||||
g_param_spec_flags ("content-hints",
|
||||
P_("Content hints"),
|
||||
P_("Content hints"),
|
||||
CLUTTER_TYPE_INPUT_CONTENT_HINT_FLAGS, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
pspecs[PROP_CONTENT_PURPOSE] =
|
||||
g_param_spec_enum ("content-purpose",
|
||||
P_("Content purpose"),
|
||||
P_("Content purpose"),
|
||||
CLUTTER_TYPE_INPUT_CONTENT_PURPOSE, 0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
pspecs[PROP_CAN_SHOW_PREEDIT] =
|
||||
g_param_spec_boolean ("can-show-preedit",
|
||||
P_("Can show preedit"),
|
||||
P_("Can show preedit"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, pspecs);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_method_init (ClutterInputMethod *im)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_focus_in (ClutterInputMethod *im,
|
||||
ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
ClutterInputMethodClass *klass;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_FOCUS (focus));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
|
||||
if (priv->focus == focus)
|
||||
return;
|
||||
|
||||
if (priv->focus)
|
||||
clutter_input_method_focus_out (im);
|
||||
|
||||
g_set_object (&priv->focus, focus);
|
||||
|
||||
if (focus)
|
||||
{
|
||||
klass = CLUTTER_INPUT_METHOD_GET_CLASS (im);
|
||||
klass->focus_in (im, focus);
|
||||
|
||||
clutter_input_focus_focus_in (priv->focus, im);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_focus_out (ClutterInputMethod *im)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
ClutterInputMethodClass *klass;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
|
||||
if (!priv->focus)
|
||||
return;
|
||||
|
||||
clutter_input_focus_focus_out (priv->focus);
|
||||
g_clear_object (&priv->focus);
|
||||
|
||||
klass = CLUTTER_INPUT_METHOD_GET_CLASS (im);
|
||||
klass->focus_out (im);
|
||||
|
||||
g_signal_emit (im, signals[INPUT_PANEL_STATE],
|
||||
0, CLUTTER_INPUT_PANEL_STATE_OFF);
|
||||
}
|
||||
|
||||
ClutterInputFocus *
|
||||
clutter_input_method_get_focus (ClutterInputMethod *im)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
return priv->focus;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_commit (ClutterInputMethod *im,
|
||||
const gchar *text)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
if (priv->focus)
|
||||
clutter_input_focus_commit (priv->focus, text);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_delete_surrounding (ClutterInputMethod *im,
|
||||
guint offset,
|
||||
guint len)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
if (priv->focus)
|
||||
clutter_input_focus_delete_surrounding (priv->focus, offset, len);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_request_surrounding (ClutterInputMethod *im)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
if (priv->focus)
|
||||
clutter_input_focus_request_surrounding (priv->focus);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_input_method_set_preedit_text:
|
||||
* @im: a #ClutterInputMethod
|
||||
* @preedit: (nullable): the preedit text, or %NULL
|
||||
* @cursor: the cursor
|
||||
*
|
||||
* Sets the preedit text on the current input focus.
|
||||
**/
|
||||
void
|
||||
clutter_input_method_set_preedit_text (ClutterInputMethod *im,
|
||||
const gchar *preedit,
|
||||
guint cursor)
|
||||
{
|
||||
ClutterInputMethodPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
priv = clutter_input_method_get_instance_private (im);
|
||||
if (priv->focus)
|
||||
clutter_input_focus_set_preedit_text (priv->focus, preedit, cursor);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_notify_key_event (ClutterInputMethod *im,
|
||||
const ClutterEvent *event,
|
||||
gboolean filtered)
|
||||
{
|
||||
if (!filtered)
|
||||
{
|
||||
ClutterEvent *copy;
|
||||
|
||||
/* XXX: we rely on the IM implementation to notify back of
|
||||
* key events in the exact same order they were given.
|
||||
*/
|
||||
copy = clutter_event_copy (event);
|
||||
clutter_event_set_flags (copy, clutter_event_get_flags (event) |
|
||||
CLUTTER_EVENT_FLAG_INPUT_METHOD);
|
||||
clutter_event_set_source_device (copy, clutter_event_get_device (copy));
|
||||
clutter_event_put (copy);
|
||||
clutter_event_free (copy);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_toggle_input_panel (ClutterInputMethod *im)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
g_signal_emit (im, signals[INPUT_PANEL_STATE], 0,
|
||||
CLUTTER_INPUT_PANEL_STATE_TOGGLE);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_reset (ClutterInputMethod *im)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
CLUTTER_INPUT_METHOD_GET_CLASS (im)->reset (im);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_set_cursor_location (ClutterInputMethod *im,
|
||||
const ClutterRect *rect)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
CLUTTER_INPUT_METHOD_GET_CLASS (im)->set_cursor_location (im, rect);
|
||||
|
||||
g_signal_emit (im, signals[CURSOR_LOCATION_CHANGED], 0, rect);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_set_surrounding (ClutterInputMethod *im,
|
||||
const gchar *text,
|
||||
guint cursor,
|
||||
guint anchor)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
CLUTTER_INPUT_METHOD_GET_CLASS (im)->set_surrounding (im, text,
|
||||
cursor, anchor);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_set_content_hints (ClutterInputMethod *im,
|
||||
ClutterInputContentHintFlags hints)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
g_object_set (G_OBJECT (im), "content-hints", hints, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_set_content_purpose (ClutterInputMethod *im,
|
||||
ClutterInputContentPurpose purpose)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
g_object_set (G_OBJECT (im), "content-purpose", purpose, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_method_set_can_show_preedit (ClutterInputMethod *im,
|
||||
gboolean can_show_preedit)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_METHOD (im));
|
||||
|
||||
g_object_set (G_OBJECT (im), "can-show-preedit", can_show_preedit, NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_input_method_filter_key_event (ClutterInputMethod *im,
|
||||
const ClutterKeyEvent *key)
|
||||
{
|
||||
ClutterInputMethodClass *im_class = CLUTTER_INPUT_METHOD_GET_CLASS (im);
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_METHOD (im), FALSE);
|
||||
g_return_val_if_fail (key != NULL, FALSE);
|
||||
|
||||
if (clutter_event_get_flags ((ClutterEvent *) key) & CLUTTER_EVENT_FLAG_INPUT_METHOD)
|
||||
return FALSE;
|
||||
if (!im_class->filter_key_event)
|
||||
return FALSE;
|
||||
|
||||
return im_class->filter_key_event (im, (const ClutterEvent *) key);
|
||||
}
|
88
clutter/clutter/clutter-input-method.h
Normal file
88
clutter/clutter/clutter-input-method.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2017,2018 Red Hat
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_METHOD_H__
|
||||
#define __CLUTTER_INPUT_METHOD_H__
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_METHOD (clutter_input_method_get_type ())
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
G_DECLARE_DERIVABLE_TYPE (ClutterInputMethod, clutter_input_method,
|
||||
CLUTTER, INPUT_METHOD, GObject)
|
||||
|
||||
typedef struct _ClutterInputMethodClass ClutterInputMethodClass;
|
||||
|
||||
struct _ClutterInputMethodClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
void (* focus_in) (ClutterInputMethod *im,
|
||||
ClutterInputFocus *actor);
|
||||
void (* focus_out) (ClutterInputMethod *im);
|
||||
|
||||
void (* reset) (ClutterInputMethod *im);
|
||||
|
||||
void (* set_cursor_location) (ClutterInputMethod *im,
|
||||
const ClutterRect *rect);
|
||||
void (* set_surrounding) (ClutterInputMethod *im,
|
||||
const gchar *text,
|
||||
guint cursor,
|
||||
guint anchor);
|
||||
void (* update_content_hints) (ClutterInputMethod *im,
|
||||
ClutterInputContentHintFlags hint);
|
||||
void (* update_content_purpose) (ClutterInputMethod *im,
|
||||
ClutterInputContentPurpose purpose);
|
||||
|
||||
gboolean (* filter_key_event) (ClutterInputMethod *im,
|
||||
const ClutterEvent *key);
|
||||
};
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_focus_in (ClutterInputMethod *im,
|
||||
ClutterInputFocus *focus);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_focus_out (ClutterInputMethod *im);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_commit (ClutterInputMethod *im,
|
||||
const gchar *text);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_delete_surrounding (ClutterInputMethod *im,
|
||||
guint offset,
|
||||
guint len);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_request_surrounding (ClutterInputMethod *im);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_set_preedit_text (ClutterInputMethod *im,
|
||||
const gchar *preedit,
|
||||
guint cursor);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_notify_key_event (ClutterInputMethod *im,
|
||||
const ClutterEvent *event,
|
||||
gboolean filtered);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_input_method_request_toggle_input_panel (ClutterInputMethod *im);
|
||||
|
||||
#endif /* __CLUTTER_INPUT_METHOD_H__ */
|
@ -2089,6 +2089,21 @@ emit_keyboard_event (ClutterEvent *event,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
process_key_event (ClutterEvent *event,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_GET_CLASS (device);
|
||||
|
||||
if (device_class->process_kbd_a11y_event)
|
||||
{
|
||||
device_class->process_kbd_a11y_event (event, device, emit_keyboard_event);
|
||||
return;
|
||||
}
|
||||
|
||||
emit_keyboard_event (event, device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_off_stage (ClutterActor *stage,
|
||||
gfloat x,
|
||||
@ -2176,7 +2191,7 @@ _clutter_process_event_details (ClutterActor *stage,
|
||||
}
|
||||
}
|
||||
|
||||
emit_keyboard_event (event, device);
|
||||
process_key_event (event, device);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -17,12 +17,14 @@ VOID:BOXED,FLAGS
|
||||
VOID:INT
|
||||
VOID:INT64,INT64,FLOAT,BOOLEAN
|
||||
VOID:INT,INT
|
||||
VOID:INT,POINTER
|
||||
VOID:FLOAT,FLOAT
|
||||
VOID:INT,INT,INT,INT
|
||||
VOID:OBJECT
|
||||
VOID:OBJECT,FLAGS
|
||||
VOID:OBJECT,FLOAT,FLOAT
|
||||
VOID:OBJECT,FLOAT,FLOAT,FLAGS
|
||||
VOID:OBJECT,OBJECT
|
||||
VOID:OBJECT,PARAM
|
||||
VOID:OBJECT,POINTER
|
||||
VOID:OBJECT,UINT
|
||||
|
@ -40,6 +40,12 @@ gboolean _clutter_get_sync_to_vblank (void);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
int64_t clutter_stage_get_frame_counter (ClutterStage *stage);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_stage_capture_into (ClutterStage *stage,
|
||||
gboolean paint,
|
||||
cairo_rectangle_int_t *rect,
|
||||
uint8_t *data);
|
||||
|
||||
#undef __CLUTTER_H_INSIDE__
|
||||
|
||||
#endif /* __CLUTTER_MUTTER_H__ */
|
||||
|
@ -77,9 +77,7 @@ struct _ClutterSettings
|
||||
|
||||
guint password_hint_time;
|
||||
|
||||
gint window_scaling_factor;
|
||||
gint unscaled_font_dpi;
|
||||
guint fixed_scaling_factor : 1;
|
||||
};
|
||||
|
||||
struct _ClutterSettingsClass
|
||||
@ -112,7 +110,6 @@ enum
|
||||
|
||||
PROP_PASSWORD_HINT_TIME,
|
||||
|
||||
PROP_WINDOW_SCALING_FACTOR,
|
||||
PROP_UNSCALED_FONT_DPI,
|
||||
|
||||
PROP_LAST
|
||||
@ -355,14 +352,6 @@ clutter_settings_set_property (GObject *gobject,
|
||||
self->password_hint_time = g_value_get_uint (value);
|
||||
break;
|
||||
|
||||
case PROP_WINDOW_SCALING_FACTOR:
|
||||
if (!self->fixed_scaling_factor)
|
||||
{
|
||||
self->window_scaling_factor = g_value_get_int (value);
|
||||
self->fixed_scaling_factor = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_UNSCALED_FONT_DPI:
|
||||
self->font_dpi = g_value_get_int (value);
|
||||
settings_update_resolution (self);
|
||||
@ -382,14 +371,7 @@ clutter_settings_set_property_internal (ClutterSettings *self,
|
||||
|
||||
property = g_intern_string (property);
|
||||
|
||||
if (property == I_("window-scaling-factor") &&
|
||||
self->fixed_scaling_factor)
|
||||
return;
|
||||
|
||||
g_object_set_property (G_OBJECT (self), property, value);
|
||||
|
||||
if (property == I_("window-scaling-factor"))
|
||||
self->fixed_scaling_factor = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -446,10 +428,6 @@ clutter_settings_get_property (GObject *gobject,
|
||||
g_value_set_uint (value, self->password_hint_time);
|
||||
break;
|
||||
|
||||
case PROP_WINDOW_SCALING_FACTOR:
|
||||
g_value_set_int (value, self->window_scaling_factor);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec);
|
||||
break;
|
||||
@ -677,14 +655,6 @@ clutter_settings_class_init (ClutterSettingsClass *klass)
|
||||
500,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
obj_props[PROP_WINDOW_SCALING_FACTOR] =
|
||||
g_param_spec_int ("window-scaling-factor",
|
||||
P_("Window Scaling Factor"),
|
||||
P_("The scaling factor to be applied to windows"),
|
||||
1, G_MAXINT,
|
||||
1,
|
||||
CLUTTER_PARAM_READWRITE);
|
||||
|
||||
obj_props[PROP_FONTCONFIG_TIMESTAMP] =
|
||||
g_param_spec_uint ("fontconfig-timestamp",
|
||||
P_("Fontconfig configuration timestamp"),
|
||||
@ -722,8 +692,6 @@ clutter_settings_class_init (ClutterSettingsClass *klass)
|
||||
static void
|
||||
clutter_settings_init (ClutterSettings *self)
|
||||
{
|
||||
const char *scale_str;
|
||||
|
||||
self->resolution = -1.0;
|
||||
|
||||
self->font_dpi = -1;
|
||||
@ -742,18 +710,6 @@ clutter_settings_init (ClutterSettings *self)
|
||||
self->xft_rgba = NULL;
|
||||
|
||||
self->long_press_duration = 500;
|
||||
|
||||
/* if the scaling factor was set by the environment we ignore
|
||||
* any explicit setting
|
||||
*/
|
||||
scale_str = g_getenv ("CLUTTER_SCALE");
|
||||
if (scale_str != NULL)
|
||||
{
|
||||
self->window_scaling_factor = atol (scale_str);
|
||||
self->fixed_scaling_factor = TRUE;
|
||||
}
|
||||
else
|
||||
self->window_scaling_factor = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "clutter/clutter-stage-view.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
#include <math.h>
|
||||
|
||||
enum
|
||||
{
|
||||
@ -28,6 +29,7 @@ enum
|
||||
PROP_LAYOUT,
|
||||
PROP_FRAMEBUFFER,
|
||||
PROP_OFFSCREEN,
|
||||
PROP_SCALE,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
@ -37,6 +39,7 @@ static GParamSpec *obj_props[PROP_LAST];
|
||||
typedef struct _ClutterStageViewPrivate
|
||||
{
|
||||
cairo_rectangle_int_t layout;
|
||||
float scale;
|
||||
CoglFramebuffer *framebuffer;
|
||||
|
||||
CoglOffscreen *offscreen;
|
||||
@ -141,6 +144,15 @@ clutter_stage_view_blit_offscreen (ClutterStageView *view,
|
||||
cogl_framebuffer_pop_matrix (priv->framebuffer);
|
||||
}
|
||||
|
||||
float
|
||||
clutter_stage_view_get_scale (ClutterStageView *view)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
return priv->scale;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_stage_view_is_dirty_viewport (ClutterStageView *view)
|
||||
{
|
||||
@ -179,16 +191,24 @@ clutter_stage_view_set_dirty_projection (ClutterStageView *view,
|
||||
priv->dirty_projection = dirty;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view,
|
||||
CoglMatrix *matrix)
|
||||
{
|
||||
ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view);
|
||||
|
||||
view_class->get_offscreen_transformation_matrix (view, matrix);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_transform_to_onscreen (ClutterStageView *view,
|
||||
gfloat *x,
|
||||
gfloat *y)
|
||||
{
|
||||
ClutterStageViewClass *view_class = CLUTTER_STAGE_VIEW_GET_CLASS (view);
|
||||
gfloat z = 0, w = 1;
|
||||
CoglMatrix matrix;
|
||||
|
||||
view_class->get_offscreen_transformation_matrix (view, &matrix);
|
||||
clutter_stage_view_get_offscreen_transformation_matrix (view, &matrix);
|
||||
cogl_matrix_get_inverse (&matrix, &matrix);
|
||||
cogl_matrix_transform_point (&matrix, x, y, &z, &w);
|
||||
}
|
||||
@ -221,6 +241,9 @@ clutter_stage_view_get_property (GObject *object,
|
||||
case PROP_OFFSCREEN:
|
||||
g_value_set_boxed (value, priv->offscreen);
|
||||
break;
|
||||
case PROP_SCALE:
|
||||
g_value_set_float (value, priv->scale);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -245,10 +268,27 @@ clutter_stage_view_set_property (GObject *object,
|
||||
break;
|
||||
case PROP_FRAMEBUFFER:
|
||||
priv->framebuffer = g_value_dup_boxed (value);
|
||||
#ifndef G_DISABLE_CHECKS
|
||||
if (priv->framebuffer)
|
||||
{
|
||||
int fb_width, fb_height;
|
||||
|
||||
fb_width = cogl_framebuffer_get_width (priv->framebuffer);
|
||||
fb_height = cogl_framebuffer_get_height (priv->framebuffer);
|
||||
|
||||
g_warn_if_fail (fabsf (roundf (fb_width / priv->scale) -
|
||||
fb_width / priv->scale) < FLT_EPSILON);
|
||||
g_warn_if_fail (fabsf (roundf (fb_height / priv->scale) -
|
||||
fb_height / priv->scale) < FLT_EPSILON);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case PROP_OFFSCREEN:
|
||||
priv->offscreen = g_value_dup_boxed (value);
|
||||
break;
|
||||
case PROP_SCALE:
|
||||
priv->scale = g_value_get_float (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -276,6 +316,7 @@ clutter_stage_view_init (ClutterStageView *view)
|
||||
|
||||
priv->dirty_viewport = TRUE;
|
||||
priv->dirty_projection = TRUE;
|
||||
priv->scale = 1.0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -296,6 +337,7 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
||||
"The view layout on the screen",
|
||||
CAIRO_GOBJECT_TYPE_RECTANGLE_INT,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_FRAMEBUFFER] =
|
||||
@ -304,6 +346,7 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
||||
"The front buffer of the view",
|
||||
COGL_TYPE_HANDLE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_OFFSCREEN] =
|
||||
@ -312,7 +355,16 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
||||
"Framebuffer used as intermediate buffer",
|
||||
COGL_TYPE_HANDLE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_SCALE] =
|
||||
g_param_spec_float ("scale",
|
||||
"View scale",
|
||||
"The view scale",
|
||||
0.5, G_MAXFLOAT, 1.0,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
|
||||
|
@ -60,6 +60,9 @@ void clutter_stage_view_transform_to_onscreen (ClutterStageView *vie
|
||||
void clutter_stage_view_blit_offscreen (ClutterStageView *view,
|
||||
const cairo_rectangle_int_t *clip);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
float clutter_stage_view_get_scale (ClutterStageView *view);
|
||||
|
||||
gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
|
||||
|
||||
void clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
|
||||
@ -70,4 +73,8 @@ gboolean clutter_stage_view_is_dirty_projection (ClutterStageView *view);
|
||||
void clutter_stage_view_set_dirty_projection (ClutterStageView *view,
|
||||
gboolean dirty);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_stage_view_get_offscreen_transformation_matrix (ClutterStageView *view,
|
||||
CoglMatrix *matrix);
|
||||
|
||||
#endif /* __CLUTTER_STAGE_VIEW_H__ */
|
||||
|
@ -303,33 +303,6 @@ _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_window_set_scale_factor (ClutterStageWindow *window,
|
||||
int factor)
|
||||
{
|
||||
ClutterStageWindowIface *iface;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE_WINDOW (window));
|
||||
|
||||
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
if (iface->set_scale_factor != NULL)
|
||||
iface->set_scale_factor (window, factor);
|
||||
}
|
||||
|
||||
int
|
||||
_clutter_stage_window_get_scale_factor (ClutterStageWindow *window)
|
||||
{
|
||||
ClutterStageWindowIface *iface;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), 1);
|
||||
|
||||
iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
|
||||
if (iface->get_scale_factor != NULL)
|
||||
return iface->get_scale_factor (window);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
GList *
|
||||
_clutter_stage_window_get_views (ClutterStageWindow *window)
|
||||
{
|
||||
|
@ -83,9 +83,6 @@ struct _ClutterStageWindowIface
|
||||
|
||||
gboolean (* can_clip_redraws) (ClutterStageWindow *stage_window);
|
||||
|
||||
void (* set_scale_factor) (ClutterStageWindow *stage_window,
|
||||
int factor);
|
||||
int (* get_scale_factor) (ClutterStageWindow *stage_window);
|
||||
GList *(* get_views) (ClutterStageWindow *stage_window);
|
||||
int64_t (* get_frame_counter) (ClutterStageWindow *stage_window);
|
||||
void (* finish_frame) (ClutterStageWindow *stage_window);
|
||||
@ -140,10 +137,6 @@ void _clutter_stage_window_get_dirty_pixel (ClutterStageWin
|
||||
|
||||
gboolean _clutter_stage_window_can_clip_redraws (ClutterStageWindow *window);
|
||||
|
||||
void _clutter_stage_window_set_scale_factor (ClutterStageWindow *window,
|
||||
int factor);
|
||||
int _clutter_stage_window_get_scale_factor (ClutterStageWindow *window);
|
||||
|
||||
GList * _clutter_stage_window_get_views (ClutterStageWindow *window);
|
||||
|
||||
void _clutter_stage_window_finish_frame (ClutterStageWindow *window);
|
||||
|
@ -161,6 +161,7 @@ struct _ClutterStagePrivate
|
||||
guint accept_focus : 1;
|
||||
guint motion_events_enabled : 1;
|
||||
guint has_custom_perspective : 1;
|
||||
guint stage_was_relayout : 1;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -364,7 +365,6 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
float new_width, new_height;
|
||||
float width, height;
|
||||
cairo_rectangle_int_t window_size;
|
||||
int scale_factor;
|
||||
|
||||
if (priv->impl == NULL)
|
||||
return;
|
||||
@ -465,11 +465,6 @@ clutter_stage_allocate (ClutterActor *self,
|
||||
*/
|
||||
_clutter_stage_window_get_geometry (priv->impl, &window_size);
|
||||
|
||||
scale_factor = _clutter_stage_window_get_scale_factor (priv->impl);
|
||||
|
||||
window_size.width *= scale_factor;
|
||||
window_size.height *= scale_factor;
|
||||
|
||||
cogl_onscreen_clutter_backend_set_size (window_size.width,
|
||||
window_size.height);
|
||||
|
||||
@ -630,15 +625,13 @@ clutter_stage_do_paint_view (ClutterStage *stage,
|
||||
float clip_poly[8];
|
||||
float viewport[4];
|
||||
cairo_rectangle_int_t geom;
|
||||
int window_scale;
|
||||
|
||||
_clutter_stage_window_get_geometry (priv->impl, &geom);
|
||||
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
|
||||
|
||||
viewport[0] = priv->viewport[0] * window_scale;
|
||||
viewport[1] = priv->viewport[1] * window_scale;
|
||||
viewport[2] = priv->viewport[2] * window_scale;
|
||||
viewport[3] = priv->viewport[3] * window_scale;
|
||||
viewport[0] = priv->viewport[0];
|
||||
viewport[1] = priv->viewport[1];
|
||||
viewport[2] = priv->viewport[2];
|
||||
viewport[3] = priv->viewport[3];
|
||||
|
||||
if (!clip)
|
||||
{
|
||||
@ -646,16 +639,14 @@ clutter_stage_do_paint_view (ClutterStage *stage,
|
||||
clip = &view_layout;
|
||||
}
|
||||
|
||||
clip_poly[0] = MAX (clip->x * window_scale, 0);
|
||||
clip_poly[1] = MAX (clip->y * window_scale, 0);
|
||||
clip_poly[0] = MAX (clip->x, 0);
|
||||
clip_poly[1] = MAX (clip->y, 0);
|
||||
|
||||
clip_poly[2] = MIN ((clip->x + clip->width) * window_scale,
|
||||
geom.width * window_scale);
|
||||
clip_poly[2] = MIN (clip->x + clip->width, geom.width);
|
||||
clip_poly[3] = clip_poly[1];
|
||||
|
||||
clip_poly[4] = clip_poly[2];
|
||||
clip_poly[5] = MIN ((clip->y + clip->height) * window_scale,
|
||||
geom.height * window_scale);
|
||||
clip_poly[5] = MIN (clip->y + clip->height, geom.height);
|
||||
|
||||
clip_poly[6] = clip_poly[0];
|
||||
clip_poly[7] = clip_poly[5];
|
||||
@ -971,6 +962,7 @@ _clutter_stage_process_queued_events (ClutterStage *stage)
|
||||
ClutterEvent *next_event;
|
||||
ClutterInputDevice *device;
|
||||
ClutterInputDevice *next_device;
|
||||
ClutterInputDeviceType device_type;
|
||||
gboolean check_device = FALSE;
|
||||
|
||||
event = l->data;
|
||||
@ -986,8 +978,16 @@ _clutter_stage_process_queued_events (ClutterStage *stage)
|
||||
if (device != NULL && next_device != NULL)
|
||||
check_device = TRUE;
|
||||
|
||||
/* Skip consecutive motion events coming from the same device */
|
||||
if (priv->throttle_motion_events && next_event != NULL)
|
||||
device_type = clutter_input_device_get_device_type (device);
|
||||
|
||||
/* Skip consecutive motion events coming from the same device,
|
||||
* except those of tablet tools, since users of these events
|
||||
* want no precision loss.
|
||||
*/
|
||||
if (priv->throttle_motion_events && next_event != NULL &&
|
||||
device_type != CLUTTER_TABLET_DEVICE &&
|
||||
device_type != CLUTTER_PEN_DEVICE &&
|
||||
device_type != CLUTTER_ERASER_DEVICE)
|
||||
{
|
||||
if (event->type == CLUTTER_MOTION &&
|
||||
(next_event->type == CLUTTER_MOTION ||
|
||||
@ -1069,6 +1069,7 @@ _clutter_stage_maybe_relayout (ClutterActor *actor)
|
||||
if (!CLUTTER_ACTOR_IN_RELAYOUT (stage))
|
||||
{
|
||||
priv->relayout_pending = FALSE;
|
||||
priv->stage_was_relayout = TRUE;
|
||||
|
||||
CLUTTER_NOTE (ACTOR, "Recomputing layout");
|
||||
|
||||
@ -1139,6 +1140,58 @@ clutter_stage_do_redraw (ClutterStage *stage)
|
||||
stage);
|
||||
}
|
||||
|
||||
static GSList *
|
||||
_clutter_stage_check_updated_pointers (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
ClutterDeviceManager *device_manager;
|
||||
GSList *updating = NULL;
|
||||
const GSList *devices;
|
||||
cairo_rectangle_int_t clip;
|
||||
ClutterPoint point;
|
||||
gboolean has_clip;
|
||||
|
||||
has_clip = _clutter_stage_window_get_redraw_clip_bounds (priv->impl, &clip);
|
||||
|
||||
device_manager = clutter_device_manager_get_default ();
|
||||
devices = clutter_device_manager_peek_devices (device_manager);
|
||||
|
||||
for (; devices != NULL; devices = devices->next)
|
||||
{
|
||||
ClutterInputDevice *dev = devices->data;
|
||||
|
||||
if (clutter_input_device_get_device_mode (dev) !=
|
||||
CLUTTER_INPUT_MODE_MASTER)
|
||||
continue;
|
||||
|
||||
switch (clutter_input_device_get_device_type (dev))
|
||||
{
|
||||
case CLUTTER_POINTER_DEVICE:
|
||||
case CLUTTER_TABLET_DEVICE:
|
||||
case CLUTTER_PEN_DEVICE:
|
||||
case CLUTTER_ERASER_DEVICE:
|
||||
case CLUTTER_CURSOR_DEVICE:
|
||||
if (!clutter_input_device_get_coords (dev, NULL, &point))
|
||||
continue;
|
||||
|
||||
if (!has_clip ||
|
||||
(point.x >= clip.x && point.x < clip.x + clip.width &&
|
||||
point.y >= clip.y && point.y < clip.y + clip.height))
|
||||
updating = g_slist_prepend (updating, dev);
|
||||
break;
|
||||
default:
|
||||
/* Any other devices don't need checking, either because they
|
||||
* don't have x/y coordinates, or because they're implicitly
|
||||
* grabbed on an actor by default as it's the case of
|
||||
* touch(screens).
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return updating;
|
||||
}
|
||||
|
||||
/**
|
||||
* _clutter_stage_do_update:
|
||||
* @stage: A #ClutterStage
|
||||
@ -1151,6 +1204,10 @@ gboolean
|
||||
_clutter_stage_do_update (ClutterStage *stage)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
gboolean stage_was_relayout = priv->stage_was_relayout;
|
||||
GSList *pointers = NULL;
|
||||
|
||||
priv->stage_was_relayout = FALSE;
|
||||
|
||||
/* if the stage is being destroyed, or if the destruction already
|
||||
* happened and we don't have an StageWindow any more, then we
|
||||
@ -1171,6 +1228,9 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
if (!priv->redraw_pending)
|
||||
return FALSE;
|
||||
|
||||
if (stage_was_relayout)
|
||||
pointers = _clutter_stage_check_updated_pointers (stage);
|
||||
|
||||
clutter_stage_maybe_finish_queue_redraws (stage);
|
||||
|
||||
clutter_stage_do_redraw (stage);
|
||||
@ -1188,6 +1248,12 @@ _clutter_stage_do_update (ClutterStage *stage)
|
||||
}
|
||||
#endif /* CLUTTER_ENABLE_DEBUG */
|
||||
|
||||
while (pointers)
|
||||
{
|
||||
_clutter_input_device_update (pointers->data, NULL, TRUE);
|
||||
pointers = g_slist_delete_link (pointers, pointers);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1378,19 +1444,19 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
|
||||
gint dirty_y;
|
||||
gint read_x;
|
||||
gint read_y;
|
||||
int window_scale;
|
||||
float fb_width, fb_height;
|
||||
int viewport_offset_x;
|
||||
int viewport_offset_y;
|
||||
float fb_scale;
|
||||
float viewport_offset_x;
|
||||
float viewport_offset_y;
|
||||
|
||||
priv = stage->priv;
|
||||
|
||||
context = _clutter_context_get_default ();
|
||||
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
fb_width = view_layout.width;
|
||||
fb_height = view_layout.height;
|
||||
fb_width = view_layout.width * fb_scale;
|
||||
fb_height = view_layout.height * fb_scale;
|
||||
cogl_push_framebuffer (fb);
|
||||
|
||||
/* needed for when a context switch happens */
|
||||
@ -1400,38 +1466,39 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
|
||||
* picking to not work at all, so setting it the whole framebuffer content
|
||||
* for now. */
|
||||
cogl_framebuffer_push_scissor_clip (fb, 0, 0,
|
||||
view_layout.width,
|
||||
view_layout.height);
|
||||
view_layout.width * fb_scale,
|
||||
view_layout.height * fb_scale);
|
||||
|
||||
_clutter_stage_window_get_dirty_pixel (priv->impl, view, &dirty_x, &dirty_y);
|
||||
|
||||
if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
|
||||
{
|
||||
CLUTTER_NOTE (PICK, "Pushing pick scissor clip x: %d, y: %d, 1x1",
|
||||
dirty_x * window_scale,
|
||||
dirty_y * window_scale);
|
||||
cogl_framebuffer_push_scissor_clip (fb, dirty_x * window_scale, dirty_y * window_scale, 1, 1);
|
||||
(int) dirty_x * fb_scale,
|
||||
(int) dirty_y * fb_scale);
|
||||
cogl_framebuffer_push_scissor_clip (fb, dirty_x * fb_scale, dirty_y * fb_scale, 1, 1);
|
||||
}
|
||||
|
||||
viewport_offset_x = x * window_scale - dirty_x * window_scale;
|
||||
viewport_offset_y = y * window_scale - dirty_y * window_scale;
|
||||
viewport_offset_x = x * fb_scale - dirty_x * fb_scale;
|
||||
viewport_offset_y = y * fb_scale - dirty_y * fb_scale;
|
||||
CLUTTER_NOTE (PICK, "Setting viewport to %f, %f, %f, %f",
|
||||
priv->viewport[0] * window_scale - viewport_offset_x,
|
||||
priv->viewport[1] * window_scale - viewport_offset_y,
|
||||
priv->viewport[2] * window_scale,
|
||||
priv->viewport[3] * window_scale);
|
||||
cogl_set_viewport (priv->viewport[0] * window_scale - viewport_offset_x,
|
||||
priv->viewport[1] * window_scale - viewport_offset_y,
|
||||
priv->viewport[2] * window_scale,
|
||||
priv->viewport[3] * window_scale);
|
||||
priv->viewport[0] * fb_scale - viewport_offset_x,
|
||||
priv->viewport[1] * fb_scale - viewport_offset_y,
|
||||
priv->viewport[2] * fb_scale,
|
||||
priv->viewport[3] * fb_scale);
|
||||
cogl_framebuffer_set_viewport (fb,
|
||||
priv->viewport[0] * fb_scale - viewport_offset_x,
|
||||
priv->viewport[1] * fb_scale - viewport_offset_y,
|
||||
priv->viewport[2] * fb_scale,
|
||||
priv->viewport[3] * fb_scale);
|
||||
|
||||
read_x = dirty_x * window_scale;
|
||||
read_y = dirty_y * window_scale;
|
||||
read_x = dirty_x * fb_scale;
|
||||
read_y = dirty_y * fb_scale;
|
||||
|
||||
CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d",
|
||||
CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d s: %d",
|
||||
x, y,
|
||||
view_layout.width, view_layout.height,
|
||||
view_layout.x, view_layout.y);
|
||||
view_layout.x, view_layout.y, fb_scale);
|
||||
|
||||
cogl_color_init_from_4ub (&stage_pick_id, 255, 255, 255, 255);
|
||||
cogl_clear (&stage_pick_id, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH);
|
||||
@ -2186,8 +2253,8 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
||||
g_signal_new (I_("presented"),
|
||||
G_TYPE_FROM_CLASS (gobject_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL, NULL,
|
||||
0, NULL, NULL,
|
||||
_clutter_marshal_VOID__INT_POINTER,
|
||||
G_TYPE_NONE, 2,
|
||||
G_TYPE_INT, G_TYPE_POINTER);
|
||||
|
||||
@ -2210,7 +2277,6 @@ clutter_stage_init (ClutterStage *self)
|
||||
ClutterStagePrivate *priv;
|
||||
ClutterStageWindow *impl;
|
||||
ClutterBackend *backend;
|
||||
int window_scale = 1;
|
||||
GError *error;
|
||||
|
||||
/* a stage is a top-level object */
|
||||
@ -2228,7 +2294,6 @@ clutter_stage_init (ClutterStage *self)
|
||||
{
|
||||
_clutter_stage_set_window (self, impl);
|
||||
_clutter_stage_window_get_geometry (priv->impl, &geom);
|
||||
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2282,8 +2347,8 @@ clutter_stage_init (ClutterStage *self)
|
||||
priv->perspective.aspect,
|
||||
priv->perspective.z_near,
|
||||
50, /* distance to 2d plane */
|
||||
geom.width * window_scale,
|
||||
geom.height * window_scale);
|
||||
geom.width,
|
||||
geom.height);
|
||||
|
||||
|
||||
/* FIXME - remove for 2.0 */
|
||||
@ -3412,16 +3477,6 @@ clutter_stage_ensure_viewport (ClutterStage *stage)
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_apply_scale (ClutterStage *stage)
|
||||
{
|
||||
int factor;
|
||||
|
||||
factor = _clutter_stage_window_get_scale_factor (stage->priv->impl);
|
||||
if (factor != 1)
|
||||
cogl_matrix_scale (&stage->priv->view, factor, factor, 1.f);
|
||||
}
|
||||
|
||||
# define _DEG_TO_RAD(d) ((d) * ((float) G_PI / 180.0f))
|
||||
|
||||
/* This calculates a distance into the view frustum to position the
|
||||
@ -3563,14 +3618,15 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
|
||||
ClutterStageView *view)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
CoglFramebuffer *fb = clutter_stage_view_get_framebuffer (view);
|
||||
|
||||
if (clutter_stage_view_is_dirty_viewport (view))
|
||||
{
|
||||
cairo_rectangle_int_t view_layout;
|
||||
ClutterPerspective perspective;
|
||||
int window_scale;
|
||||
int viewport_offset_x;
|
||||
int viewport_offset_y;
|
||||
float fb_scale;
|
||||
float viewport_offset_x;
|
||||
float viewport_offset_y;
|
||||
float z_2d;
|
||||
|
||||
CLUTTER_NOTE (PAINT,
|
||||
@ -3578,15 +3634,16 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
|
||||
priv->viewport[2],
|
||||
priv->viewport[3]);
|
||||
|
||||
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
viewport_offset_x = view_layout.x * window_scale;
|
||||
viewport_offset_y = view_layout.y * window_scale;
|
||||
cogl_set_viewport (priv->viewport[0] * window_scale - viewport_offset_x,
|
||||
priv->viewport[1] * window_scale - viewport_offset_y,
|
||||
priv->viewport[2] * window_scale,
|
||||
priv->viewport[3] * window_scale);
|
||||
viewport_offset_x = view_layout.x * fb_scale;
|
||||
viewport_offset_y = view_layout.y * fb_scale;
|
||||
cogl_framebuffer_set_viewport (fb,
|
||||
priv->viewport[0] * fb_scale - viewport_offset_x,
|
||||
priv->viewport[1] * fb_scale - viewport_offset_y,
|
||||
priv->viewport[2] * fb_scale,
|
||||
priv->viewport[3] * fb_scale);
|
||||
|
||||
perspective = priv->perspective;
|
||||
|
||||
@ -3617,17 +3674,15 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
|
||||
perspective.aspect,
|
||||
perspective.z_near,
|
||||
z_2d,
|
||||
priv->viewport[2] * window_scale,
|
||||
priv->viewport[3] * window_scale);
|
||||
|
||||
clutter_stage_apply_scale (stage);
|
||||
priv->viewport[2],
|
||||
priv->viewport[3]);
|
||||
|
||||
clutter_stage_view_set_dirty_viewport (view, FALSE);
|
||||
}
|
||||
|
||||
if (clutter_stage_view_is_dirty_projection (view))
|
||||
{
|
||||
cogl_set_projection_matrix (&priv->projection);
|
||||
cogl_framebuffer_set_projection_matrix (fb, &priv->projection);
|
||||
|
||||
clutter_stage_view_set_dirty_projection (view, FALSE);
|
||||
}
|
||||
@ -4635,23 +4690,6 @@ clutter_stage_skip_sync_delay (ClutterStage *stage)
|
||||
_clutter_stage_window_schedule_update (stage_window, -1);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_set_scale_factor (ClutterStage *stage,
|
||||
int factor)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
|
||||
if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
|
||||
return;
|
||||
|
||||
if (priv->impl == NULL)
|
||||
return;
|
||||
|
||||
_clutter_stage_window_set_scale_factor (priv->impl, factor);
|
||||
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
}
|
||||
|
||||
int64_t
|
||||
clutter_stage_get_frame_counter (ClutterStage *stage)
|
||||
{
|
||||
@ -4685,18 +4723,22 @@ capture_view (ClutterStage *stage,
|
||||
int stride;
|
||||
CoglBitmap *bitmap;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
float view_scale;
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
|
||||
if (paint)
|
||||
{
|
||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||
cogl_push_framebuffer (framebuffer);
|
||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||
clutter_stage_do_paint_view (stage, view, rect);
|
||||
}
|
||||
|
||||
view_scale = clutter_stage_view_get_scale (view);
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
rect->width, rect->height);
|
||||
rect->width * view_scale,
|
||||
rect->height * view_scale);
|
||||
cairo_surface_set_device_scale (image, view_scale, view_scale);
|
||||
|
||||
data = cairo_image_surface_get_data (image);
|
||||
stride = cairo_image_surface_get_stride (image);
|
||||
@ -4704,7 +4746,8 @@ capture_view (ClutterStage *stage,
|
||||
backend = clutter_get_default_backend ();
|
||||
context = clutter_backend_get_cogl_context (backend);
|
||||
bitmap = cogl_bitmap_new_for_data (context,
|
||||
rect->width, rect->height,
|
||||
rect->width * view_scale,
|
||||
rect->height * view_scale,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
stride,
|
||||
data);
|
||||
@ -4712,8 +4755,8 @@ capture_view (ClutterStage *stage,
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
|
||||
rect->x - view_layout.x,
|
||||
rect->y - view_layout.y,
|
||||
(rect->x - view_layout.x) * view_scale,
|
||||
(rect->y - view_layout.y) * view_scale,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
bitmap);
|
||||
|
||||
@ -4770,3 +4813,93 @@ clutter_stage_capture (ClutterStage *stage,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
capture_view_into (ClutterStage *stage,
|
||||
gboolean paint,
|
||||
ClutterStageView *view,
|
||||
cairo_rectangle_int_t *rect,
|
||||
uint8_t *data,
|
||||
int stride)
|
||||
{
|
||||
CoglFramebuffer *framebuffer;
|
||||
ClutterBackend *backend;
|
||||
CoglContext *context;
|
||||
CoglBitmap *bitmap;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
|
||||
if (paint)
|
||||
{
|
||||
cogl_push_framebuffer (framebuffer);
|
||||
_clutter_stage_maybe_setup_viewport (stage, view);
|
||||
clutter_stage_do_paint_view (stage, view, rect);
|
||||
}
|
||||
|
||||
backend = clutter_get_default_backend ();
|
||||
context = clutter_backend_get_cogl_context (backend);
|
||||
bitmap = cogl_bitmap_new_for_data (context,
|
||||
rect->width, rect->height,
|
||||
CLUTTER_CAIRO_FORMAT_ARGB32,
|
||||
stride,
|
||||
data);
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
|
||||
rect->x - view_layout.x,
|
||||
rect->y - view_layout.y,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
bitmap);
|
||||
|
||||
if (paint)
|
||||
cogl_pop_framebuffer ();
|
||||
|
||||
cogl_object_unref (bitmap);
|
||||
}
|
||||
|
||||
static ClutterStageView *
|
||||
get_view_at_rect (ClutterStage *stage,
|
||||
cairo_rectangle_int_t *rect)
|
||||
{
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
GList *views = _clutter_stage_window_get_views (priv->impl);
|
||||
GList *l;
|
||||
|
||||
for (l = views; l; l = l->next)
|
||||
{
|
||||
ClutterStageView *view = l->data;
|
||||
cairo_rectangle_int_t view_layout;
|
||||
cairo_region_t *region;
|
||||
cairo_rectangle_int_t view_capture_rect;
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
region = cairo_region_create_rectangle (&view_layout);
|
||||
cairo_region_intersect_rectangle (region, rect);
|
||||
cairo_region_get_extents (region, &view_capture_rect);
|
||||
cairo_region_destroy (region);
|
||||
|
||||
if (view_capture_rect.width == 0 || view_capture_rect.height == 0)
|
||||
continue;
|
||||
|
||||
g_assert (view_capture_rect.width == rect->width &&
|
||||
view_capture_rect.height == rect->height);
|
||||
return view;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_capture_into (ClutterStage *stage,
|
||||
gboolean paint,
|
||||
cairo_rectangle_int_t *rect,
|
||||
uint8_t *data)
|
||||
{
|
||||
ClutterStageView *view;
|
||||
int bpp = 4;
|
||||
|
||||
view = get_view_at_rect (stage, rect);
|
||||
capture_view_into (stage, paint, view, rect, data, rect->width * bpp);
|
||||
}
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "clutter-units.h"
|
||||
#include "clutter-paint-volume-private.h"
|
||||
#include "clutter-scriptable.h"
|
||||
#include "clutter-input-focus.h"
|
||||
|
||||
/* cursor width in pixels */
|
||||
#define DEFAULT_CURSOR_SIZE 2
|
||||
@ -98,6 +99,12 @@ struct _LayoutCache
|
||||
guint age;
|
||||
};
|
||||
|
||||
struct _ClutterTextInputFocus
|
||||
{
|
||||
ClutterInputFocus parent_instance;
|
||||
ClutterText *text;
|
||||
};
|
||||
|
||||
struct _ClutterTextPrivate
|
||||
{
|
||||
PangoFontDescription *font_desc;
|
||||
@ -176,6 +183,10 @@ struct _ClutterTextPrivate
|
||||
/* Signal handler for when the :text-direction changes */
|
||||
guint direction_changed_id;
|
||||
|
||||
ClutterInputFocus *input_focus;
|
||||
ClutterInputContentHintFlags input_hints;
|
||||
ClutterInputContentPurpose input_purpose;
|
||||
|
||||
/* bitfields */
|
||||
guint alignment : 2;
|
||||
guint wrap : 1;
|
||||
@ -236,6 +247,8 @@ enum
|
||||
PROP_SINGLE_LINE_MODE,
|
||||
PROP_SELECTED_TEXT_COLOR,
|
||||
PROP_SELECTED_TEXT_COLOR_SET,
|
||||
PROP_INPUT_HINTS,
|
||||
PROP_INPUT_PURPOSE,
|
||||
|
||||
PROP_LAST
|
||||
};
|
||||
@ -269,6 +282,112 @@ static const ClutterColor default_selected_text_color = { 0, 0, 0, 255 };
|
||||
static ClutterAnimatableIface *parent_animatable_iface = NULL;
|
||||
static ClutterScriptableIface *parent_scriptable_iface = NULL;
|
||||
|
||||
/* ClutterTextInputFocus */
|
||||
#define CLUTTER_TYPE_TEXT_INPUT_FOCUS (clutter_text_input_focus_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (ClutterTextInputFocus, clutter_text_input_focus,
|
||||
CLUTTER, TEXT_INPUT_FOCUS, ClutterInputFocus)
|
||||
G_DEFINE_TYPE (ClutterTextInputFocus, clutter_text_input_focus,
|
||||
CLUTTER_TYPE_INPUT_FOCUS)
|
||||
|
||||
static void
|
||||
clutter_text_input_focus_request_surrounding (ClutterInputFocus *focus)
|
||||
{
|
||||
ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text;
|
||||
ClutterTextBuffer *buffer;
|
||||
const gchar *text;
|
||||
gint anchor_pos, cursor_pos;
|
||||
|
||||
buffer = clutter_text_get_buffer (clutter_text);
|
||||
text = clutter_text_buffer_get_text (buffer);
|
||||
|
||||
cursor_pos = clutter_text_get_cursor_position (clutter_text);
|
||||
if (cursor_pos < 0)
|
||||
cursor_pos = clutter_text_buffer_get_length (buffer);
|
||||
|
||||
anchor_pos = clutter_text_get_selection_bound (clutter_text);
|
||||
if (anchor_pos < 0)
|
||||
anchor_pos = cursor_pos;
|
||||
|
||||
clutter_input_focus_set_surrounding (focus, text,
|
||||
g_utf8_offset_to_pointer (text, cursor_pos) - text,
|
||||
g_utf8_offset_to_pointer (text, anchor_pos) - text);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_input_focus_delete_surrounding (ClutterInputFocus *focus,
|
||||
guint offset,
|
||||
guint len)
|
||||
{
|
||||
ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text;
|
||||
|
||||
if (clutter_text_get_editable (clutter_text))
|
||||
clutter_text_delete_text (clutter_text, offset, len);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_input_focus_commit_text (ClutterInputFocus *focus,
|
||||
const gchar *text)
|
||||
{
|
||||
ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text;
|
||||
|
||||
if (clutter_text_get_editable (clutter_text))
|
||||
{
|
||||
clutter_text_delete_selection (clutter_text);
|
||||
clutter_text_insert_text (clutter_text, text,
|
||||
clutter_text_get_cursor_position (clutter_text));
|
||||
clutter_text_set_preedit_string (clutter_text, NULL, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_input_focus_set_preedit_text (ClutterInputFocus *focus,
|
||||
const gchar *preedit_text,
|
||||
guint cursor_pos)
|
||||
{
|
||||
ClutterText *clutter_text = CLUTTER_TEXT_INPUT_FOCUS (focus)->text;
|
||||
|
||||
if (clutter_text_get_editable (clutter_text))
|
||||
{
|
||||
PangoAttrList *list;
|
||||
|
||||
list = pango_attr_list_new ();
|
||||
pango_attr_list_insert (list, pango_attr_underline_new (PANGO_UNDERLINE_SINGLE));
|
||||
clutter_text_set_preedit_string (clutter_text,
|
||||
preedit_text, list,
|
||||
cursor_pos);
|
||||
pango_attr_list_unref (list);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_input_focus_class_init (ClutterTextInputFocusClass *klass)
|
||||
{
|
||||
ClutterInputFocusClass *focus_class = CLUTTER_INPUT_FOCUS_CLASS (klass);
|
||||
|
||||
focus_class->request_surrounding = clutter_text_input_focus_request_surrounding;
|
||||
focus_class->delete_surrounding = clutter_text_input_focus_delete_surrounding;
|
||||
focus_class->commit_text = clutter_text_input_focus_commit_text;
|
||||
focus_class->set_preedit_text = clutter_text_input_focus_set_preedit_text;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_input_focus_init (ClutterTextInputFocus *focus)
|
||||
{
|
||||
}
|
||||
|
||||
static ClutterInputFocus *
|
||||
clutter_text_input_focus_new (ClutterText *text)
|
||||
{
|
||||
ClutterTextInputFocus *focus;
|
||||
|
||||
focus = g_object_new (CLUTTER_TYPE_TEXT_INPUT_FOCUS, NULL);
|
||||
focus->text = text;
|
||||
|
||||
return CLUTTER_INPUT_FOCUS (focus);
|
||||
}
|
||||
|
||||
/* ClutterText */
|
||||
static void clutter_scriptable_iface_init (ClutterScriptableIface *iface);
|
||||
static void clutter_animatable_iface_init (ClutterAnimatableIface *iface);
|
||||
|
||||
@ -1009,6 +1128,22 @@ clutter_text_position_to_coords (ClutterText *self,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
update_cursor_location (ClutterText *self)
|
||||
{
|
||||
ClutterTextPrivate *priv = self->priv;
|
||||
ClutterRect rect;
|
||||
float x, y;
|
||||
|
||||
if (!priv->editable)
|
||||
return;
|
||||
|
||||
rect = priv->cursor_rect;
|
||||
clutter_actor_get_transformed_position (CLUTTER_ACTOR (self), &x, &y);
|
||||
clutter_rect_offset (&rect, x, y);
|
||||
clutter_input_focus_set_cursor_location (priv->input_focus, &rect);
|
||||
}
|
||||
|
||||
static inline void
|
||||
clutter_text_ensure_cursor_position (ClutterText *self)
|
||||
{
|
||||
@ -1057,6 +1192,8 @@ clutter_text_ensure_cursor_position (ClutterText *self)
|
||||
g_signal_emit (self, text_signals[CURSOR_EVENT], 0, &cursor_pos);
|
||||
|
||||
g_signal_emit (self, text_signals[CURSOR_CHANGED], 0);
|
||||
|
||||
update_cursor_location (self);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1503,6 +1640,8 @@ clutter_text_finalize (GObject *gobject)
|
||||
clutter_text_set_buffer (self, NULL);
|
||||
g_free (priv->font_name);
|
||||
|
||||
g_clear_object (&priv->input_focus);
|
||||
|
||||
G_OBJECT_CLASS (clutter_text_parent_class)->finalize (gobject);
|
||||
}
|
||||
|
||||
@ -1859,6 +1998,7 @@ clutter_text_press (ClutterActor *actor,
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
|
||||
clutter_actor_grab_key_focus (actor);
|
||||
clutter_input_focus_request_toggle_input_panel (priv->input_focus);
|
||||
|
||||
/* if the actor is empty we just reset everything and not
|
||||
* set up the dragging of the selection since there's nothing
|
||||
@ -2084,10 +2224,17 @@ clutter_text_key_press (ClutterActor *actor,
|
||||
pool = clutter_binding_pool_find (g_type_name (CLUTTER_TYPE_TEXT));
|
||||
g_assert (pool != NULL);
|
||||
|
||||
if (!(event->flags & CLUTTER_EVENT_FLAG_INPUT_METHOD) &&
|
||||
clutter_input_focus_is_focused (priv->input_focus) &&
|
||||
clutter_input_focus_filter_key_event (priv->input_focus, event))
|
||||
return CLUTTER_EVENT_STOP;
|
||||
|
||||
/* we allow passing synthetic events that only contain
|
||||
* the Unicode value and not the key symbol
|
||||
* the Unicode value and not the key symbol, unless they
|
||||
* contain the input method flag.
|
||||
*/
|
||||
if (event->keyval == 0 && (event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC))
|
||||
if (event->keyval == 0 && (event->flags & CLUTTER_EVENT_FLAG_SYNTHETIC) &&
|
||||
!(event->flags & CLUTTER_EVENT_FLAG_INPUT_METHOD))
|
||||
res = FALSE;
|
||||
else
|
||||
res = clutter_binding_pool_activate (pool, event->keyval,
|
||||
@ -2141,6 +2288,20 @@ clutter_text_key_press (ClutterActor *actor,
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_text_key_release (ClutterActor *actor,
|
||||
ClutterKeyEvent *event)
|
||||
{
|
||||
ClutterText *self = CLUTTER_TEXT (actor);
|
||||
ClutterTextPrivate *priv = self->priv;
|
||||
|
||||
if (clutter_input_focus_is_focused (priv->input_focus) &&
|
||||
clutter_input_focus_filter_key_event (priv->input_focus, event))
|
||||
return CLUTTER_EVENT_STOP;
|
||||
|
||||
return CLUTTER_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_compute_layout_offsets (ClutterText *self,
|
||||
PangoLayout *layout,
|
||||
@ -2663,6 +2824,18 @@ static void
|
||||
clutter_text_key_focus_in (ClutterActor *actor)
|
||||
{
|
||||
ClutterTextPrivate *priv = CLUTTER_TEXT (actor)->priv;
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
if (method && priv->editable)
|
||||
{
|
||||
clutter_input_method_focus_in (method, priv->input_focus);
|
||||
clutter_input_focus_set_content_purpose (priv->input_focus,
|
||||
priv->input_purpose);
|
||||
clutter_input_focus_set_content_hints (priv->input_focus,
|
||||
priv->input_hints);
|
||||
update_cursor_location (CLUTTER_TEXT (actor));
|
||||
}
|
||||
|
||||
priv->has_focus = TRUE;
|
||||
|
||||
@ -2673,9 +2846,17 @@ static void
|
||||
clutter_text_key_focus_out (ClutterActor *actor)
|
||||
{
|
||||
ClutterTextPrivate *priv = CLUTTER_TEXT (actor)->priv;
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
|
||||
priv->has_focus = FALSE;
|
||||
|
||||
if (priv->editable && clutter_input_focus_is_focused (priv->input_focus))
|
||||
{
|
||||
clutter_text_set_preedit_string (CLUTTER_TEXT (actor), NULL, NULL, 0);
|
||||
clutter_input_method_focus_out (method);
|
||||
}
|
||||
|
||||
clutter_text_queue_redraw (actor);
|
||||
}
|
||||
|
||||
@ -3369,6 +3550,7 @@ clutter_text_class_init (ClutterTextClass *klass)
|
||||
actor_class->get_preferred_height = clutter_text_get_preferred_height;
|
||||
actor_class->allocate = clutter_text_allocate;
|
||||
actor_class->key_press_event = clutter_text_key_press;
|
||||
actor_class->key_release_event = clutter_text_key_release;
|
||||
actor_class->button_press_event = clutter_text_button_press;
|
||||
actor_class->button_release_event = clutter_text_button_release;
|
||||
actor_class->motion_event = clutter_text_motion;
|
||||
@ -3869,6 +4051,22 @@ clutter_text_class_init (ClutterTextClass *klass)
|
||||
obj_props[PROP_SELECTED_TEXT_COLOR_SET] = pspec;
|
||||
g_object_class_install_property (gobject_class, PROP_SELECTED_TEXT_COLOR_SET, pspec);
|
||||
|
||||
pspec = g_param_spec_flags ("input-hints",
|
||||
P_("Input hints"),
|
||||
P_("Input hints"),
|
||||
CLUTTER_TYPE_INPUT_CONTENT_HINT_FLAGS,
|
||||
0, CLUTTER_PARAM_READWRITE);
|
||||
obj_props[PROP_INPUT_HINTS] = pspec;
|
||||
g_object_class_install_property (gobject_class, PROP_INPUT_HINTS, pspec);
|
||||
|
||||
pspec = g_param_spec_enum ("input-purpose",
|
||||
P_("Input purpose"),
|
||||
P_("Input purpose"),
|
||||
CLUTTER_TYPE_INPUT_CONTENT_PURPOSE,
|
||||
0, CLUTTER_PARAM_READWRITE);
|
||||
obj_props[PROP_INPUT_PURPOSE] = pspec;
|
||||
g_object_class_install_property (gobject_class, PROP_INPUT_PURPOSE, pspec);
|
||||
|
||||
/**
|
||||
* ClutterText::text-changed:
|
||||
* @self: the #ClutterText that emitted the signal
|
||||
@ -4169,6 +4367,8 @@ clutter_text_init (ClutterText *self)
|
||||
g_signal_connect (self, "notify::text-direction",
|
||||
G_CALLBACK (clutter_text_direction_changed_cb),
|
||||
NULL);
|
||||
|
||||
priv->input_focus = clutter_text_input_focus_new (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4315,6 +4515,27 @@ buffer_deleted_text (ClutterTextBuffer *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_text_queue_redraw_or_relayout (ClutterText *self)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (self);
|
||||
gfloat preferred_width;
|
||||
gfloat preferred_height;
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
|
||||
/* we're using our private implementations here to avoid the caching done by ClutterActor */
|
||||
clutter_text_get_preferred_width (actor, -1, NULL, &preferred_width);
|
||||
clutter_text_get_preferred_height (actor, preferred_width, NULL, &preferred_height);
|
||||
|
||||
if (clutter_actor_has_allocation (actor) &&
|
||||
(fabsf (preferred_width - clutter_actor_get_width (actor)) > 0.001 ||
|
||||
fabsf (preferred_height - clutter_actor_get_height (actor)) > 0.001))
|
||||
clutter_actor_queue_relayout (actor);
|
||||
else
|
||||
clutter_text_queue_redraw (actor);
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_notify_text (ClutterTextBuffer *buffer,
|
||||
GParamSpec *spec,
|
||||
@ -4322,9 +4543,7 @@ buffer_notify_text (ClutterTextBuffer *buffer,
|
||||
{
|
||||
g_object_freeze_notify (G_OBJECT (self));
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
|
||||
g_signal_emit (self, text_signals[TEXT_CHANGED], 0);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_TEXT]);
|
||||
@ -4459,6 +4678,8 @@ void
|
||||
clutter_text_set_editable (ClutterText *self,
|
||||
gboolean editable)
|
||||
{
|
||||
ClutterBackend *backend = clutter_get_default_backend ();
|
||||
ClutterInputMethod *method = clutter_backend_get_input_method (backend);
|
||||
ClutterTextPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
||||
@ -4469,6 +4690,14 @@ clutter_text_set_editable (ClutterText *self,
|
||||
{
|
||||
priv->editable = editable;
|
||||
|
||||
if (method)
|
||||
{
|
||||
if (!priv->editable && clutter_input_focus_is_focused (priv->input_focus))
|
||||
clutter_input_method_focus_out (method);
|
||||
else if (priv->has_focus)
|
||||
clutter_input_method_focus_in (method, priv->input_focus);
|
||||
}
|
||||
|
||||
clutter_text_queue_redraw (CLUTTER_ACTOR (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_EDITABLE]);
|
||||
@ -4666,8 +4895,7 @@ clutter_text_set_cursor_visible (ClutterText *self,
|
||||
{
|
||||
priv->cursor_visible = cursor_visible;
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CURSOR_VISIBLE]);
|
||||
}
|
||||
@ -5568,9 +5796,7 @@ clutter_text_set_line_alignment (ClutterText *self,
|
||||
{
|
||||
priv->alignment = alignment;
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_LINE_ALIGNMENT]);
|
||||
}
|
||||
@ -5625,9 +5851,7 @@ clutter_text_set_use_markup (ClutterText *self,
|
||||
if (setting)
|
||||
clutter_text_set_markup_internal (self, text);
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5674,9 +5898,7 @@ clutter_text_set_justify (ClutterText *self,
|
||||
{
|
||||
priv->justify = justify;
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_JUSTIFY]);
|
||||
}
|
||||
@ -6243,8 +6465,7 @@ clutter_text_set_preedit_string (ClutterText *self,
|
||||
priv->preedit_set = TRUE;
|
||||
}
|
||||
|
||||
clutter_text_dirty_cache (self);
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
|
||||
clutter_text_queue_redraw_or_relayout (self);
|
||||
}
|
||||
|
||||
|
||||
@ -6298,3 +6519,53 @@ clutter_text_get_cursor_rect (ClutterText *self,
|
||||
|
||||
*rect = self->priv->cursor_rect;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_text_set_input_hints (ClutterText *self,
|
||||
ClutterInputContentHintFlags hints)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
||||
|
||||
self->priv->input_hints = hints;
|
||||
|
||||
if (clutter_input_focus_is_focused (self->priv->input_focus))
|
||||
clutter_input_focus_set_content_hints (self->priv->input_focus, hints);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_HINTS]);
|
||||
}
|
||||
|
||||
ClutterInputContentHintFlags
|
||||
clutter_text_get_input_hints (ClutterText *self)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0);
|
||||
|
||||
return self->priv->input_hints;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_text_set_input_purpose (ClutterText *self,
|
||||
ClutterInputContentPurpose purpose)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_TEXT (self));
|
||||
|
||||
self->priv->input_purpose = purpose;
|
||||
|
||||
if (clutter_input_focus_is_focused (self->priv->input_focus))
|
||||
clutter_input_focus_set_content_purpose (self->priv->input_focus, purpose);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_INPUT_PURPOSE]);
|
||||
}
|
||||
|
||||
ClutterInputContentPurpose
|
||||
clutter_text_get_input_purpose (ClutterText *self)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TEXT (self), 0);
|
||||
|
||||
return self->priv->input_purpose;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_text_has_preedit (ClutterText *self)
|
||||
{
|
||||
g_return_val_if_fail (CLUTTER_IS_TEXT (self), FALSE);
|
||||
|
||||
return self->priv->preedit_set;
|
||||
}
|
||||
|
@ -302,6 +302,20 @@ void clutter_text_get_layout_offsets (ClutterText *
|
||||
gint *x,
|
||||
gint *y);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_text_set_input_hints (ClutterText *self,
|
||||
ClutterInputContentHintFlags hints);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_text_set_input_purpose (ClutterText *self,
|
||||
ClutterInputContentPurpose purpose);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
ClutterInputContentHintFlags clutter_text_get_input_hints (ClutterText *self);
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
ClutterInputContentPurpose clutter_text_get_input_purpose (ClutterText *self);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
gboolean clutter_text_has_preedit (ClutterText *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_TEXT_H__ */
|
||||
|
@ -97,6 +97,9 @@ typedef struct _ClutterInputDeviceTool ClutterInputDeviceTool;
|
||||
typedef struct _ClutterInputDevice ClutterInputDevice;
|
||||
typedef struct _ClutterVirtualInputDevice ClutterVirtualInputDevice;
|
||||
|
||||
typedef struct _ClutterInputMethod ClutterInputMethod;
|
||||
typedef struct _ClutterInputFocus ClutterInputFocus;
|
||||
|
||||
typedef CoglMatrix ClutterMatrix;
|
||||
|
||||
typedef union _ClutterEvent ClutterEvent;
|
||||
|
@ -312,7 +312,7 @@ G_BEGIN_DECLS
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
const guint clutter_major_version;
|
||||
extern const guint clutter_major_version;
|
||||
|
||||
/**
|
||||
* clutter_minor_version:
|
||||
@ -326,7 +326,7 @@ const guint clutter_major_version;
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
const guint clutter_minor_version;
|
||||
extern const guint clutter_minor_version;
|
||||
|
||||
/**
|
||||
* clutter_micro_version:
|
||||
@ -340,7 +340,7 @@ const guint clutter_minor_version;
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
const guint clutter_micro_version;
|
||||
extern const guint clutter_micro_version;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -115,6 +115,74 @@ clutter_virtual_input_device_notify_keyval (ClutterVirtualInputDevice *virtual_d
|
||||
klass->notify_keyval (virtual_device, time_us, keyval, key_state);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_virtual_input_device_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
ClutterVirtualInputDeviceClass *klass =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
|
||||
|
||||
klass->notify_discrete_scroll (virtual_device, time_us,
|
||||
direction, scroll_source);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_virtual_input_device_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
{
|
||||
ClutterVirtualInputDeviceClass *klass =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
|
||||
|
||||
klass->notify_scroll_continuous (virtual_device, time_us,
|
||||
dx, dy, scroll_source, finish_flags);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_virtual_input_device_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
ClutterVirtualInputDeviceClass *klass =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
|
||||
|
||||
klass->notify_touch_down (virtual_device, time_us,
|
||||
slot, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_virtual_input_device_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
ClutterVirtualInputDeviceClass *klass =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
|
||||
|
||||
klass->notify_touch_motion (virtual_device, time_us,
|
||||
slot, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_virtual_input_device_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int slot)
|
||||
{
|
||||
ClutterVirtualInputDeviceClass *klass =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_GET_CLASS (virtual_device);
|
||||
|
||||
klass->notify_touch_up (virtual_device, time_us,
|
||||
slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_virtual_input_device_get_manager:
|
||||
* @virtual_device: a virtual device
|
||||
|
@ -76,6 +76,34 @@ struct _ClutterVirtualInputDeviceClass
|
||||
uint64_t time_us,
|
||||
uint32_t keyval,
|
||||
ClutterKeyState key_state);
|
||||
|
||||
void (*notify_discrete_scroll) (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source);
|
||||
|
||||
void (*notify_scroll_continuous) (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags);
|
||||
|
||||
void (*notify_touch_down) (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y);
|
||||
|
||||
void (*notify_touch_motion) (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y);
|
||||
|
||||
void (*notify_touch_up) (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int slot);
|
||||
};
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
@ -108,6 +136,39 @@ void clutter_virtual_input_device_notify_keyval (ClutterVirtualInputDevice *virt
|
||||
uint32_t keyval,
|
||||
ClutterKeyState key_state);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_virtual_input_device_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_virtual_input_device_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_virtual_input_device_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_virtual_input_device_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_virtual_input_device_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int slot);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
ClutterDeviceManager * clutter_virtual_input_device_get_manager (ClutterVirtualInputDevice *virtual_device);
|
||||
|
||||
|
@ -72,6 +72,8 @@
|
||||
#include "clutter-image.h"
|
||||
#include "clutter-input-device.h"
|
||||
#include "clutter-input-device-tool.h"
|
||||
#include "clutter-input-method.h"
|
||||
#include "clutter-input-focus.h"
|
||||
#include "clutter-interval.h"
|
||||
#include "clutter-keyframe-transition.h"
|
||||
#include "clutter-keysyms.h"
|
||||
|
@ -51,7 +51,9 @@
|
||||
|
||||
typedef struct _ClutterStageViewCoglPrivate
|
||||
{
|
||||
/* Stores a list of previous damaged areas in the stage coordinate space */
|
||||
/*
|
||||
* List of previous damaged areas in stage view framebuffer coordinate space.
|
||||
*/
|
||||
#define DAMAGE_HISTORY_MAX 16
|
||||
#define DAMAGE_HISTORY(x) ((x) & (DAMAGE_HISTORY_MAX - 1))
|
||||
cairo_rectangle_int_t damage_history[DAMAGE_HISTORY_MAX];
|
||||
@ -435,13 +437,20 @@ fill_current_damage_history_and_step (ClutterStageView *view)
|
||||
ClutterStageViewCoglPrivate *view_priv =
|
||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||
cairo_rectangle_int_t view_rect;
|
||||
cairo_rectangle_int_t *current_damage;
|
||||
float fb_scale;
|
||||
cairo_rectangle_int_t *current_fb_damage;
|
||||
|
||||
current_damage =
|
||||
current_fb_damage =
|
||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index)];
|
||||
clutter_stage_view_get_layout (view, &view_rect);
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
|
||||
*current_damage = view_rect;
|
||||
*current_fb_damage = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = view_rect.width * fb_scale,
|
||||
.height = view_rect.height * fb_scale
|
||||
};
|
||||
view_priv->damage_index++;
|
||||
}
|
||||
|
||||
@ -481,6 +490,40 @@ transform_swap_region_to_onscreen (ClutterStageView *view,
|
||||
};
|
||||
}
|
||||
|
||||
static void
|
||||
calculate_scissor_region (cairo_rectangle_int_t *fb_clip_region,
|
||||
int subpixel_compensation,
|
||||
int fb_width,
|
||||
int fb_height,
|
||||
cairo_rectangle_int_t *out_scissor_rect)
|
||||
{
|
||||
int scissor_x;
|
||||
int scissor_y;
|
||||
int scissor_width;
|
||||
int scissor_height;
|
||||
|
||||
scissor_x = fb_clip_region->x;
|
||||
scissor_y = fb_clip_region->y;
|
||||
scissor_width = fb_clip_region->width;
|
||||
scissor_height = fb_clip_region->height;
|
||||
|
||||
if (fb_clip_region->x > 0)
|
||||
scissor_x += subpixel_compensation;
|
||||
if (fb_clip_region->y > 0)
|
||||
scissor_y += subpixel_compensation;
|
||||
if (fb_clip_region->x + fb_clip_region->width < fb_width)
|
||||
scissor_width -= 2 * subpixel_compensation;
|
||||
if (fb_clip_region->y + fb_clip_region->height < fb_height)
|
||||
scissor_height -= 2 * subpixel_compensation;
|
||||
|
||||
*out_scissor_rect = (cairo_rectangle_int_t) {
|
||||
.x = scissor_x,
|
||||
.y = scissor_y,
|
||||
.width = scissor_width,
|
||||
.height = scissor_height
|
||||
};
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
ClutterStageView *view)
|
||||
@ -501,13 +544,18 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
ClutterActor *wrapper;
|
||||
cairo_rectangle_int_t redraw_clip;
|
||||
cairo_rectangle_int_t swap_region;
|
||||
cairo_rectangle_int_t clip_region;
|
||||
cairo_rectangle_int_t fb_clip_region;
|
||||
gboolean clip_region_empty;
|
||||
int window_scale;
|
||||
float fb_scale;
|
||||
int subpixel_compensation = 0;
|
||||
int fb_width, fb_height;
|
||||
|
||||
wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_rect);
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
fb_width = cogl_framebuffer_get_width (fb);
|
||||
fb_height = cogl_framebuffer_get_height (fb);
|
||||
|
||||
can_blit_sub_buffer =
|
||||
cogl_is_onscreen (fb) &&
|
||||
@ -542,11 +590,24 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
cogl_onscreen_get_frame_counter (COGL_ONSCREEN (fb)) > 3)
|
||||
{
|
||||
may_use_clipped_redraw = TRUE;
|
||||
clip_region = redraw_clip;
|
||||
|
||||
if (fb_scale != floorf (fb_scale))
|
||||
subpixel_compensation = ceilf (fb_scale);
|
||||
|
||||
fb_clip_region = (cairo_rectangle_int_t) {
|
||||
.x = (floorf ((redraw_clip.x - view_rect.x) * fb_scale) -
|
||||
subpixel_compensation),
|
||||
.y = (floorf ((redraw_clip.y - view_rect.y) * fb_scale) -
|
||||
subpixel_compensation),
|
||||
.width = (ceilf (redraw_clip.width * fb_scale) +
|
||||
(2 * subpixel_compensation)),
|
||||
.height = (ceilf (redraw_clip.height * fb_scale) +
|
||||
(2 * subpixel_compensation))
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
clip_region = (cairo_rectangle_int_t){ 0 };
|
||||
fb_clip_region = (cairo_rectangle_int_t) { 0 };
|
||||
}
|
||||
|
||||
if (may_use_clipped_redraw &&
|
||||
@ -555,9 +616,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
else
|
||||
use_clipped_redraw = FALSE;
|
||||
|
||||
clip_region_empty = may_use_clipped_redraw && clip_region.width == 0;
|
||||
|
||||
window_scale = _clutter_stage_window_get_scale_factor (stage_window);
|
||||
clip_region_empty = may_use_clipped_redraw && fb_clip_region.width == 0;
|
||||
|
||||
swap_with_damage = FALSE;
|
||||
if (has_buffer_age)
|
||||
@ -565,34 +624,44 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
if (use_clipped_redraw && !clip_region_empty)
|
||||
{
|
||||
int age, i;
|
||||
cairo_rectangle_int_t *current_damage =
|
||||
cairo_rectangle_int_t *current_fb_damage =
|
||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index++)];
|
||||
|
||||
age = cogl_onscreen_get_buffer_age (COGL_ONSCREEN (fb));
|
||||
|
||||
if (valid_buffer_age (view_cogl, age))
|
||||
{
|
||||
*current_damage = clip_region;
|
||||
cairo_rectangle_int_t damage_region;
|
||||
|
||||
*current_fb_damage = fb_clip_region;
|
||||
|
||||
for (i = 1; i <= age; i++)
|
||||
{
|
||||
cairo_rectangle_int_t *damage =
|
||||
cairo_rectangle_int_t *fb_damage =
|
||||
&view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - i - 1)];
|
||||
|
||||
_clutter_util_rectangle_union (&clip_region, damage, &clip_region);
|
||||
_clutter_util_rectangle_union (&fb_clip_region,
|
||||
fb_damage,
|
||||
&fb_clip_region);
|
||||
}
|
||||
|
||||
/* Update the bounding redraw clip state with the extra damage. */
|
||||
damage_region = (cairo_rectangle_int_t) {
|
||||
.x = view_rect.x + floorf (fb_clip_region.x / fb_scale),
|
||||
.y = view_rect.y + floorf (fb_clip_region.y / fb_scale),
|
||||
.width = ceilf (fb_clip_region.width / fb_scale),
|
||||
.height = ceilf (fb_clip_region.height / fb_scale)
|
||||
};
|
||||
_clutter_util_rectangle_union (&stage_cogl->bounding_redraw_clip,
|
||||
&clip_region,
|
||||
&damage_region,
|
||||
&stage_cogl->bounding_redraw_clip);
|
||||
|
||||
CLUTTER_NOTE (CLIPPING, "Reusing back buffer(age=%d) - repairing region: x=%d, y=%d, width=%d, height=%d\n",
|
||||
age,
|
||||
clip_region.x,
|
||||
clip_region.y,
|
||||
clip_region.width,
|
||||
clip_region.height);
|
||||
fb_clip_region.x,
|
||||
fb_clip_region.y,
|
||||
fb_clip_region.width,
|
||||
fb_clip_region.height);
|
||||
|
||||
swap_with_damage = TRUE;
|
||||
}
|
||||
@ -600,7 +669,12 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
{
|
||||
CLUTTER_NOTE (CLIPPING, "Invalid back buffer(age=%d): forcing full redraw\n", age);
|
||||
use_clipped_redraw = FALSE;
|
||||
*current_damage = view_rect;
|
||||
*current_fb_damage = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = view_rect.width * fb_scale,
|
||||
.height = view_rect.height * fb_scale
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (!use_clipped_redraw)
|
||||
@ -616,26 +690,34 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
}
|
||||
else if (use_clipped_redraw)
|
||||
{
|
||||
int scissor_x;
|
||||
int scissor_y;
|
||||
cairo_rectangle_int_t scissor_rect;
|
||||
|
||||
calculate_scissor_region (&fb_clip_region,
|
||||
subpixel_compensation,
|
||||
fb_width, fb_height,
|
||||
&scissor_rect);
|
||||
|
||||
CLUTTER_NOTE (CLIPPING,
|
||||
"Stage clip pushed: x=%d, y=%d, width=%d, height=%d\n",
|
||||
clip_region.x,
|
||||
clip_region.y,
|
||||
clip_region.width,
|
||||
clip_region.height);
|
||||
scissor_rect.x,
|
||||
scissor_rect.y,
|
||||
scissor_rect.width,
|
||||
scissor_rect.height);
|
||||
|
||||
stage_cogl->using_clipped_redraw = TRUE;
|
||||
|
||||
scissor_x = (clip_region.x - view_rect.x) * window_scale;
|
||||
scissor_y = (clip_region.y - view_rect.y) * window_scale;
|
||||
cogl_framebuffer_push_scissor_clip (fb,
|
||||
scissor_x,
|
||||
scissor_y,
|
||||
clip_region.width * window_scale,
|
||||
clip_region.height * window_scale);
|
||||
paint_stage (stage_cogl, view, &clip_region);
|
||||
scissor_rect.x,
|
||||
scissor_rect.y,
|
||||
scissor_rect.width,
|
||||
scissor_rect.height);
|
||||
paint_stage (stage_cogl, view,
|
||||
&(cairo_rectangle_int_t) {
|
||||
.x = view_rect.x + floorf ((fb_clip_region.x - 0) / fb_scale),
|
||||
.y = view_rect.y + floorf ((fb_clip_region.y - 0) / fb_scale),
|
||||
.width = ceilf ((fb_clip_region.width + 0) / fb_scale),
|
||||
.height = ceilf ((fb_clip_region.height + 0) / fb_scale)
|
||||
});
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
|
||||
stage_cogl->using_clipped_redraw = FALSE;
|
||||
@ -650,17 +732,25 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
may_use_clipped_redraw &&
|
||||
!clip_region_empty)
|
||||
{
|
||||
int scissor_x;
|
||||
int scissor_y;
|
||||
cairo_rectangle_int_t scissor_rect;
|
||||
|
||||
calculate_scissor_region (&fb_clip_region,
|
||||
subpixel_compensation,
|
||||
fb_width, fb_height,
|
||||
&scissor_rect);
|
||||
|
||||
scissor_x = (clip_region.x - view_rect.x) * window_scale;;
|
||||
scissor_y = (clip_region.y - view_rect.y) * window_scale;
|
||||
cogl_framebuffer_push_scissor_clip (fb,
|
||||
scissor_x,
|
||||
scissor_y,
|
||||
clip_region.width * window_scale,
|
||||
clip_region.height * window_scale);
|
||||
paint_stage (stage_cogl, view, &clip_region);
|
||||
scissor_rect.x,
|
||||
scissor_rect.y,
|
||||
scissor_rect.width,
|
||||
scissor_rect.height);
|
||||
paint_stage (stage_cogl, view,
|
||||
&(cairo_rectangle_int_t) {
|
||||
.x = view_rect.x + floorf (fb_clip_region.x / fb_scale),
|
||||
.y = view_rect.y + floorf (fb_clip_region.y / fb_scale),
|
||||
.width = ceilf (fb_clip_region.width / fb_scale),
|
||||
.height = ceilf (fb_clip_region.height / fb_scale)
|
||||
});
|
||||
cogl_framebuffer_pop_clip (fb);
|
||||
}
|
||||
else
|
||||
@ -723,12 +813,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
}
|
||||
else if (use_clipped_redraw)
|
||||
{
|
||||
swap_region = (cairo_rectangle_int_t) {
|
||||
.x = (clip_region.x - view_rect.x) * window_scale,
|
||||
.y = (clip_region.y - view_rect.y) * window_scale,
|
||||
.width = clip_region.width * window_scale,
|
||||
.height = clip_region.height * window_scale,
|
||||
};
|
||||
swap_region = fb_clip_region;
|
||||
g_assert (swap_region.width > 0);
|
||||
do_swap_buffer = TRUE;
|
||||
}
|
||||
@ -737,8 +822,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
|
||||
swap_region = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = view_rect.width * window_scale,
|
||||
.height = view_rect.height * window_scale,
|
||||
.width = view_rect.width * fb_scale,
|
||||
.height = view_rect.height * fb_scale,
|
||||
};
|
||||
do_swap_buffer = TRUE;
|
||||
}
|
||||
@ -810,9 +895,25 @@ clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
|
||||
gboolean has_buffer_age =
|
||||
cogl_is_onscreen (framebuffer) &&
|
||||
cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_BUFFER_AGE);
|
||||
cairo_rectangle_int_t *rect;
|
||||
float fb_scale;
|
||||
gboolean scale_is_fractional;
|
||||
|
||||
if (!has_buffer_age)
|
||||
fb_scale = clutter_stage_view_get_scale (view);
|
||||
if (fb_scale != floorf (fb_scale))
|
||||
scale_is_fractional = TRUE;
|
||||
else
|
||||
scale_is_fractional = FALSE;
|
||||
|
||||
/*
|
||||
* Buffer damage is tracked in the framebuffer coordinate space
|
||||
* using the damage history. When fractional scaling is used, a
|
||||
* coordinate on the stage might not correspond to the exact position of any
|
||||
* physical pixel, which causes issues when painting using the pick mode.
|
||||
*
|
||||
* For now, always use the (0, 0) pixel for picking when using fractional
|
||||
* framebuffer scaling.
|
||||
*/
|
||||
if (!has_buffer_age || scale_is_fractional)
|
||||
{
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
@ -823,12 +924,13 @@ clutter_stage_cogl_get_dirty_pixel (ClutterStageWindow *stage_window,
|
||||
ClutterStageViewCoglPrivate *view_priv =
|
||||
clutter_stage_view_cogl_get_instance_private (view_cogl);
|
||||
cairo_rectangle_int_t view_layout;
|
||||
cairo_rectangle_int_t *fb_damage;
|
||||
|
||||
clutter_stage_view_get_layout (view, &view_layout);
|
||||
|
||||
rect = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
|
||||
*x = rect->x - view_layout.x;
|
||||
*y = rect->y - view_layout.y;
|
||||
fb_damage = &view_priv->damage_history[DAMAGE_HISTORY (view_priv->damage_index - 1)];
|
||||
*x = fb_damage->x / fb_scale;
|
||||
*y = fb_damage->y / fb_scale;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-main.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-settings-private.h"
|
||||
|
||||
#ifdef COGL_HAS_EGL_SUPPORT
|
||||
#include "clutter-egl.h"
|
||||
@ -60,6 +61,8 @@ clutter_backend_egl_native_dispose (GObject *gobject)
|
||||
{
|
||||
ClutterBackendEglNative *backend_egl_native = CLUTTER_BACKEND_EGL_NATIVE (gobject);
|
||||
|
||||
g_clear_object (&backend_egl_native->xsettings);
|
||||
|
||||
if (backend_egl_native->event_timer != NULL)
|
||||
{
|
||||
g_timer_destroy (backend_egl_native->event_timer);
|
||||
@ -77,9 +80,181 @@ clutter_backend_egl_native_class_init (ClutterBackendEglNativeClass *klass)
|
||||
gobject_class->dispose = clutter_backend_egl_native_dispose;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
cairo_antialias_t cairo_antialias;
|
||||
gint clutter_font_antialias;
|
||||
|
||||
cairo_hint_style_t cairo_hint_style;
|
||||
const char *clutter_font_hint_style;
|
||||
|
||||
cairo_subpixel_order_t cairo_subpixel_order;
|
||||
const char *clutter_font_subpixel_order;
|
||||
} FontSettings;
|
||||
|
||||
static void
|
||||
get_font_gsettings (GSettings *xsettings,
|
||||
FontSettings *output)
|
||||
{
|
||||
/* org.gnome.settings-daemon.GsdFontAntialiasingMode */
|
||||
static const struct
|
||||
{
|
||||
cairo_antialias_t cairo_antialias;
|
||||
gint clutter_font_antialias;
|
||||
}
|
||||
antialiasings[] =
|
||||
{
|
||||
/* none=0 */ {CAIRO_ANTIALIAS_NONE, 0},
|
||||
/* grayscale=1 */ {CAIRO_ANTIALIAS_GRAY, 1},
|
||||
/* rgba=2 */ {CAIRO_ANTIALIAS_SUBPIXEL, 1},
|
||||
};
|
||||
|
||||
/* org.gnome.settings-daemon.GsdFontHinting */
|
||||
static const struct
|
||||
{
|
||||
cairo_hint_style_t cairo_hint_style;
|
||||
const char *clutter_font_hint_style;
|
||||
}
|
||||
hintings[] =
|
||||
{
|
||||
/* none=0 */ {CAIRO_HINT_STYLE_NONE, "hintnone"},
|
||||
/* slight=1 */ {CAIRO_HINT_STYLE_SLIGHT, "hintslight"},
|
||||
/* medium=2 */ {CAIRO_HINT_STYLE_MEDIUM, "hintmedium"},
|
||||
/* full=3 */ {CAIRO_HINT_STYLE_FULL, "hintfull"},
|
||||
};
|
||||
|
||||
/* org.gnome.settings-daemon.GsdFontRgbaOrder */
|
||||
static const struct
|
||||
{
|
||||
cairo_subpixel_order_t cairo_subpixel_order;
|
||||
const char *clutter_font_subpixel_order;
|
||||
}
|
||||
rgba_orders[] =
|
||||
{
|
||||
/* rgba=0 */ {CAIRO_SUBPIXEL_ORDER_RGB, "rgb"}, /* XXX what is 'rgba'? */
|
||||
/* rgb=1 */ {CAIRO_SUBPIXEL_ORDER_RGB, "rgb"},
|
||||
/* bgr=2 */ {CAIRO_SUBPIXEL_ORDER_BGR, "bgr"},
|
||||
/* vrgb=3 */ {CAIRO_SUBPIXEL_ORDER_VRGB, "vrgb"},
|
||||
/* vbgr=4 */ {CAIRO_SUBPIXEL_ORDER_VBGR, "vbgr"},
|
||||
};
|
||||
guint i;
|
||||
|
||||
i = g_settings_get_enum (xsettings, "hinting");
|
||||
if (i < G_N_ELEMENTS (hintings))
|
||||
{
|
||||
output->cairo_hint_style = hintings[i].cairo_hint_style;
|
||||
output->clutter_font_hint_style = hintings[i].clutter_font_hint_style;
|
||||
}
|
||||
else
|
||||
{
|
||||
output->cairo_hint_style = CAIRO_HINT_STYLE_DEFAULT;
|
||||
output->clutter_font_hint_style = NULL;
|
||||
}
|
||||
|
||||
i = g_settings_get_enum (xsettings, "antialiasing");
|
||||
if (i < G_N_ELEMENTS (antialiasings))
|
||||
{
|
||||
output->cairo_antialias = antialiasings[i].cairo_antialias;
|
||||
output->clutter_font_antialias = antialiasings[i].clutter_font_antialias;
|
||||
}
|
||||
else
|
||||
{
|
||||
output->cairo_antialias = CAIRO_ANTIALIAS_DEFAULT;
|
||||
output->clutter_font_antialias = -1;
|
||||
}
|
||||
|
||||
i = g_settings_get_enum (xsettings, "rgba-order");
|
||||
if (i < G_N_ELEMENTS (rgba_orders))
|
||||
{
|
||||
output->cairo_subpixel_order = rgba_orders[i].cairo_subpixel_order;
|
||||
output->clutter_font_subpixel_order = rgba_orders[i].clutter_font_subpixel_order;
|
||||
}
|
||||
else
|
||||
{
|
||||
output->cairo_subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
|
||||
output->clutter_font_subpixel_order = NULL;
|
||||
}
|
||||
|
||||
if (output->cairo_antialias == CAIRO_ANTIALIAS_GRAY)
|
||||
output->clutter_font_subpixel_order = "none";
|
||||
}
|
||||
|
||||
static void
|
||||
init_font_options (ClutterBackendEglNative *backend_egl_native)
|
||||
{
|
||||
GSettings *xsettings = backend_egl_native->xsettings;
|
||||
cairo_font_options_t *options = cairo_font_options_create ();
|
||||
FontSettings fs;
|
||||
|
||||
get_font_gsettings (xsettings, &fs);
|
||||
|
||||
cairo_font_options_set_hint_style (options, fs.cairo_hint_style);
|
||||
cairo_font_options_set_antialias (options, fs.cairo_antialias);
|
||||
cairo_font_options_set_subpixel_order (options, fs.cairo_subpixel_order);
|
||||
|
||||
clutter_backend_set_font_options (CLUTTER_BACKEND (backend_egl_native),
|
||||
options);
|
||||
|
||||
cairo_font_options_destroy (options);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_xsettings_change_event (GSettings *xsettings,
|
||||
gpointer keys,
|
||||
gint n_keys,
|
||||
gpointer user_data)
|
||||
{
|
||||
/*
|
||||
* A simpler alternative to this function that does not update the screen
|
||||
* immediately (like macOS :P):
|
||||
*
|
||||
* init_font_options (CLUTTER_BACKEND_EGL_NATIVE (user_data));
|
||||
*
|
||||
* which has the added benefit of eliminating the need for all the
|
||||
* FontSettings.clutter_ fields. However the below approach is better for
|
||||
* testing settings and more consistent with the existing x11 backend...
|
||||
*/
|
||||
ClutterSettings *csettings = clutter_settings_get_default ();
|
||||
FontSettings fs;
|
||||
gint hinting;
|
||||
|
||||
get_font_gsettings (xsettings, &fs);
|
||||
hinting = fs.cairo_hint_style == CAIRO_HINT_STYLE_NONE ? 0 : 1;
|
||||
g_object_set (csettings,
|
||||
"font-hinting", hinting,
|
||||
"font-hint-style", fs.clutter_font_hint_style,
|
||||
"font-antialias", fs.clutter_font_antialias,
|
||||
"font-subpixel-order", fs.clutter_font_subpixel_order,
|
||||
NULL);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_backend_egl_native_init (ClutterBackendEglNative *backend_egl_native)
|
||||
{
|
||||
static const gchar xsettings_path[] = "org.gnome.settings-daemon.plugins.xsettings";
|
||||
GSettingsSchemaSource *source = g_settings_schema_source_get_default ();
|
||||
GSettingsSchema *schema = g_settings_schema_source_lookup (source,
|
||||
xsettings_path,
|
||||
FALSE);
|
||||
|
||||
if (!schema)
|
||||
{
|
||||
g_warning ("Failed to find schema: %s", xsettings_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
backend_egl_native->xsettings = g_settings_new_full (schema, NULL, NULL);
|
||||
if (backend_egl_native->xsettings)
|
||||
{
|
||||
init_font_options (backend_egl_native);
|
||||
g_signal_connect (backend_egl_native->xsettings, "change-event",
|
||||
G_CALLBACK (on_xsettings_change_event),
|
||||
backend_egl_native);
|
||||
}
|
||||
}
|
||||
|
||||
backend_egl_native->event_timer = g_timer_new ();
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,9 @@ struct _ClutterBackendEglNative
|
||||
|
||||
/* event timer */
|
||||
GTimer *event_timer;
|
||||
|
||||
/* "xsettings" is still the defacto place for Xft settings, even in Wayland */
|
||||
GSettings *xsettings;
|
||||
};
|
||||
|
||||
struct _ClutterBackendEglNativeClass
|
||||
|
@ -59,9 +59,6 @@
|
||||
|
||||
#include "clutter-device-manager-evdev.h"
|
||||
|
||||
#define DISCRETE_SCROLL_STEP 10.0
|
||||
|
||||
|
||||
/*
|
||||
* Clutter makes the assumption that two core devices have ID's 2 and 3 (core
|
||||
* pointer and core keyboard).
|
||||
@ -102,6 +99,9 @@ struct _ClutterDeviceManagerEvdevPrivate
|
||||
gpointer constrain_data;
|
||||
GDestroyNotify constrain_data_notify;
|
||||
|
||||
ClutterRelativeMotionFilter relative_motion_filter;
|
||||
gpointer relative_motion_filter_user_data;
|
||||
|
||||
ClutterStageManager *stage_manager;
|
||||
guint stage_added_handler;
|
||||
guint stage_removed_handler;
|
||||
@ -124,6 +124,7 @@ G_DEFINE_TYPE_WITH_CODE (ClutterDeviceManagerEvdev,
|
||||
static ClutterOpenDeviceCallback device_open_callback;
|
||||
static ClutterCloseDeviceCallback device_close_callback;
|
||||
static gpointer device_callback_data;
|
||||
static gchar * evdev_seat_id;
|
||||
|
||||
#ifdef CLUTTER_ENABLE_DEBUG
|
||||
static const char *device_type_str[] = {
|
||||
@ -263,6 +264,22 @@ _clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev *mana
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_device_manager_evdev_filter_relative_motion (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
ClutterInputDevice *device,
|
||||
float x,
|
||||
float y,
|
||||
float *dx,
|
||||
float *dy)
|
||||
{
|
||||
ClutterDeviceManagerEvdevPrivate *priv = manager_evdev->priv;
|
||||
|
||||
if (!priv->relative_motion_filter)
|
||||
return;
|
||||
|
||||
priv->relative_motion_filter (device, x, y, dx, dy,
|
||||
priv->relative_motion_filter_user_data);
|
||||
}
|
||||
|
||||
static ClutterEvent *
|
||||
new_absolute_motion_event (ClutterInputDevice *input_device,
|
||||
@ -311,6 +328,9 @@ new_absolute_motion_event (ClutterInputDevice *input_device,
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
event->motion.x = x;
|
||||
event->motion.y = y;
|
||||
clutter_input_device_evdev_translate_coordinates (input_device, stage,
|
||||
&event->motion.x,
|
||||
&event->motion.y);
|
||||
event->motion.axes = axes;
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
|
||||
@ -354,175 +374,29 @@ notify_relative_tool_motion (ClutterInputDevice *input_device,
|
||||
gfloat dy,
|
||||
gdouble *axes)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterEvent *event;
|
||||
ClutterSeatEvdev *seat;
|
||||
gfloat x, y;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
x = input_device->current_x + dx;
|
||||
y = input_device->current_y + dy;
|
||||
|
||||
_clutter_device_manager_evdev_filter_relative_motion (seat->manager_evdev,
|
||||
input_device,
|
||||
seat->pointer_x,
|
||||
seat->pointer_y,
|
||||
&dx,
|
||||
&dy);
|
||||
|
||||
event = new_absolute_motion_event (input_device, time_us, x, y, axes);
|
||||
_clutter_evdev_event_set_relative_motion (event, dx, dy, 0, 0);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static ClutterScrollDirection
|
||||
discrete_to_direction (gdouble discrete_x,
|
||||
gdouble discrete_y)
|
||||
{
|
||||
if (discrete_x > 0)
|
||||
return CLUTTER_SCROLL_RIGHT;
|
||||
else if (discrete_x < 0)
|
||||
return CLUTTER_SCROLL_LEFT;
|
||||
else if (discrete_y > 0)
|
||||
return CLUTTER_SCROLL_DOWN;
|
||||
else if (discrete_y < 0)
|
||||
return CLUTTER_SCROLL_UP;
|
||||
else
|
||||
return CLUTTER_SCROLL_SMOOTH;
|
||||
}
|
||||
|
||||
static void
|
||||
notify_discrete_scroll (ClutterInputDevice *input_device,
|
||||
guint64 time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source,
|
||||
gboolean emulated)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
|
||||
if (direction == CLUTTER_SCROLL_SMOOTH)
|
||||
return;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
event->scroll.device = seat->core_pointer;
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
event->scroll.direction = direction;
|
||||
|
||||
event->scroll.x = seat->pointer_x;
|
||||
event->scroll.y = seat->pointer_y;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
event->scroll.scroll_source = scroll_source;
|
||||
|
||||
_clutter_event_set_pointer_emulated (event, emulated);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_scroll (ClutterInputDevice *input_device,
|
||||
guint64 time_us,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
ClutterScrollSource source,
|
||||
ClutterScrollFinishFlags flags,
|
||||
gboolean emulated)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
gdouble scroll_factor;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
event->scroll.device = seat->core_pointer;
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
/* libinput pointer axis events are in pointer motion coordinate space.
|
||||
* To convert to Xi2 discrete step coordinate space, multiply the factor
|
||||
* 1/10. */
|
||||
event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
|
||||
scroll_factor = 1.0 / DISCRETE_SCROLL_STEP;
|
||||
clutter_event_set_scroll_delta (event,
|
||||
scroll_factor * dx,
|
||||
scroll_factor * dy);
|
||||
|
||||
event->scroll.x = seat->pointer_x;
|
||||
event->scroll.y = seat->pointer_y;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
event->scroll.scroll_source = source;
|
||||
event->scroll.finish_flags = flags;
|
||||
|
||||
_clutter_event_set_pointer_emulated (event, emulated);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_touch_event (ClutterInputDevice *input_device,
|
||||
ClutterEventType evtype,
|
||||
guint64 time_us,
|
||||
gint32 slot,
|
||||
gdouble x,
|
||||
gdouble y)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (evtype);
|
||||
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->touch.time = us2ms (time_us);
|
||||
event->touch.stage = CLUTTER_STAGE (stage);
|
||||
event->touch.device = seat->core_pointer;
|
||||
event->touch.x = x;
|
||||
event->touch.y = y;
|
||||
/* "NULL" sequences are special cased in clutter */
|
||||
event->touch.sequence = GINT_TO_POINTER (slot + 1);
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
if (evtype == CLUTTER_TOUCH_BEGIN ||
|
||||
evtype == CLUTTER_TOUCH_UPDATE)
|
||||
event->touch.modifier_state |= CLUTTER_BUTTON1_MASK;
|
||||
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_pinch_gesture_event (ClutterInputDevice *input_device,
|
||||
ClutterTouchpadGesturePhase phase,
|
||||
@ -530,7 +404,8 @@ notify_pinch_gesture_event (ClutterInputDevice *input_device,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
gdouble angle_delta,
|
||||
gdouble scale)
|
||||
gdouble scale,
|
||||
guint n_fingers)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
@ -561,6 +436,7 @@ notify_pinch_gesture_event (ClutterInputDevice *input_device,
|
||||
event->touchpad_pinch.dy = dy;
|
||||
event->touchpad_pinch.angle_delta = angle_delta;
|
||||
event->touchpad_pinch.scale = scale;
|
||||
event->touchpad_pinch.n_fingers = n_fingers;
|
||||
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
@ -658,6 +534,7 @@ notify_pad_button (ClutterInputDevice *input_device,
|
||||
guint64 time_us,
|
||||
guint32 button,
|
||||
guint32 mode_group,
|
||||
guint32 mode,
|
||||
guint32 pressed)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
@ -683,6 +560,7 @@ notify_pad_button (ClutterInputDevice *input_device,
|
||||
event->pad_button.stage = stage;
|
||||
event->pad_button.button = button;
|
||||
event->pad_button.group = mode_group;
|
||||
event->pad_button.mode = mode;
|
||||
clutter_event_set_device (event, input_device);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
clutter_event_set_time (event, us2ms (time_us));
|
||||
@ -698,6 +576,7 @@ notify_pad_strip (ClutterInputDevice *input_device,
|
||||
guint32 strip_number,
|
||||
guint32 strip_source,
|
||||
guint32 mode_group,
|
||||
guint32 mode,
|
||||
gdouble value)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
@ -727,6 +606,7 @@ notify_pad_strip (ClutterInputDevice *input_device,
|
||||
event->pad_strip.strip_number = strip_number;
|
||||
event->pad_strip.value = value;
|
||||
event->pad_strip.group = mode_group;
|
||||
event->pad_strip.mode = mode;
|
||||
clutter_event_set_device (event, input_device);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
clutter_event_set_time (event, us2ms (time_us));
|
||||
@ -742,6 +622,7 @@ notify_pad_ring (ClutterInputDevice *input_device,
|
||||
guint32 ring_number,
|
||||
guint32 ring_source,
|
||||
guint32 mode_group,
|
||||
guint32 mode,
|
||||
gdouble angle)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
@ -771,6 +652,7 @@ notify_pad_ring (ClutterInputDevice *input_device,
|
||||
event->pad_ring.ring_number = ring_number;
|
||||
event->pad_ring.angle = angle;
|
||||
event->pad_ring.group = mode_group;
|
||||
event->pad_ring.mode = mode;
|
||||
clutter_event_set_device (event, input_device);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
clutter_event_set_time (event, us2ms (time_us));
|
||||
@ -911,10 +793,12 @@ evdev_add_device (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
if (priv->main_seat->libinput_seat == NULL)
|
||||
seat = priv->main_seat;
|
||||
else
|
||||
seat = clutter_seat_evdev_new (manager_evdev);
|
||||
{
|
||||
seat = clutter_seat_evdev_new (manager_evdev);
|
||||
priv->seats = g_slist_append (priv->seats, seat);
|
||||
}
|
||||
|
||||
clutter_seat_evdev_set_libinput_seat (seat, libinput_seat);
|
||||
priv->seats = g_slist_append (priv->seats, seat);
|
||||
}
|
||||
|
||||
device = _clutter_input_device_evdev_new (manager, seat, libinput_device);
|
||||
@ -1037,7 +921,6 @@ clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager,
|
||||
ClutterDeviceManagerEvdev *manager_evdev;
|
||||
ClutterDeviceManagerEvdevPrivate *priv;
|
||||
GSList *l;
|
||||
GSList *device_it;
|
||||
|
||||
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (manager);
|
||||
priv = manager_evdev->priv;
|
||||
@ -1045,14 +928,10 @@ clutter_device_manager_evdev_get_device (ClutterDeviceManager *manager,
|
||||
for (l = priv->seats; l; l = l->next)
|
||||
{
|
||||
ClutterSeatEvdev *seat = l->data;
|
||||
ClutterInputDevice *device = clutter_seat_evdev_get_device (seat, id);
|
||||
|
||||
for (device_it = seat->devices; device_it; device_it = device_it->next)
|
||||
{
|
||||
ClutterInputDevice *device = device_it->data;
|
||||
|
||||
if (clutter_input_device_get_device_id (device) == id)
|
||||
return device;
|
||||
}
|
||||
if (device)
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -1106,40 +985,6 @@ process_base_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
return handled;
|
||||
}
|
||||
|
||||
static void
|
||||
check_notify_discrete_scroll (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
ClutterInputDevice *device,
|
||||
guint64 time_us,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev =
|
||||
CLUTTER_INPUT_DEVICE_EVDEV (device);
|
||||
ClutterSeatEvdev *seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
int i, n_xscrolls, n_yscrolls;
|
||||
|
||||
n_xscrolls = floor (fabs (seat->accum_scroll_dx) / DISCRETE_SCROLL_STEP);
|
||||
n_yscrolls = floor (fabs (seat->accum_scroll_dy) / DISCRETE_SCROLL_STEP);
|
||||
|
||||
for (i = 0; i < n_xscrolls; i++)
|
||||
{
|
||||
notify_discrete_scroll (device, time_us,
|
||||
seat->accum_scroll_dx > 0 ?
|
||||
CLUTTER_SCROLL_RIGHT : CLUTTER_SCROLL_LEFT,
|
||||
scroll_source, TRUE);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_yscrolls; i++)
|
||||
{
|
||||
notify_discrete_scroll (device, time_us,
|
||||
seat->accum_scroll_dy > 0 ?
|
||||
CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_UP,
|
||||
scroll_source, TRUE);
|
||||
}
|
||||
|
||||
seat->accum_scroll_dx = fmodf (seat->accum_scroll_dx, DISCRETE_SCROLL_STEP);
|
||||
seat->accum_scroll_dy = fmodf (seat->accum_scroll_dy, DISCRETE_SCROLL_STEP);
|
||||
}
|
||||
|
||||
static ClutterScrollSource
|
||||
translate_scroll_source (enum libinput_pointer_axis_source source)
|
||||
{
|
||||
@ -1208,11 +1053,17 @@ input_device_update_tool (ClutterInputDevice *input_device,
|
||||
}
|
||||
}
|
||||
|
||||
evdev_device->last_tool = tool;
|
||||
if (evdev_device->last_tool != tool)
|
||||
{
|
||||
evdev_device->last_tool = tool;
|
||||
g_signal_emit_by_name (clutter_device_manager_get_default (),
|
||||
"tool-changed", input_device, tool);
|
||||
}
|
||||
}
|
||||
|
||||
static gdouble *
|
||||
translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event)
|
||||
translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event,
|
||||
ClutterInputDeviceTool *tool)
|
||||
{
|
||||
GArray *axes = g_array_new (FALSE, FALSE, sizeof (gdouble));
|
||||
struct libinput_tablet_tool *libinput_tool;
|
||||
@ -1234,6 +1085,7 @@ translate_tablet_axes (struct libinput_event_tablet_tool *tablet_event)
|
||||
if (libinput_tablet_tool_has_pressure (libinput_tool))
|
||||
{
|
||||
value = libinput_event_tablet_tool_get_pressure (tablet_event);
|
||||
value = clutter_input_device_tool_evdev_translate_pressure (tool, value);
|
||||
g_array_append_val (axes, value);
|
||||
}
|
||||
|
||||
@ -1280,6 +1132,68 @@ seat_from_device (ClutterInputDevice *device)
|
||||
return _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_continuous_axis (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollSource scroll_source,
|
||||
struct libinput_event_pointer *axis_event)
|
||||
{
|
||||
gdouble dx = 0.0, dy = 0.0;
|
||||
ClutterScrollFinishFlags finish_flags = CLUTTER_SCROLL_FINISHED_NONE;
|
||||
|
||||
if (libinput_event_pointer_has_axis (axis_event,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
|
||||
{
|
||||
dx = libinput_event_pointer_get_axis_value (
|
||||
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
|
||||
|
||||
if (fabs (dx) < DBL_EPSILON)
|
||||
finish_flags |= CLUTTER_SCROLL_FINISHED_HORIZONTAL;
|
||||
}
|
||||
if (libinput_event_pointer_has_axis (axis_event,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
|
||||
{
|
||||
dy = libinput_event_pointer_get_axis_value (
|
||||
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
|
||||
|
||||
if (fabs (dy) < DBL_EPSILON)
|
||||
finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL;
|
||||
}
|
||||
|
||||
clutter_seat_evdev_notify_scroll_continuous (seat, device, time_us,
|
||||
dx, dy,
|
||||
scroll_source, finish_flags);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_discrete_axis (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollSource scroll_source,
|
||||
struct libinput_event_pointer *axis_event)
|
||||
{
|
||||
gdouble discrete_dx = 0.0, discrete_dy = 0.0;
|
||||
|
||||
if (libinput_event_pointer_has_axis (axis_event,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL))
|
||||
{
|
||||
discrete_dx = libinput_event_pointer_get_axis_value_discrete (
|
||||
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
|
||||
}
|
||||
if (libinput_event_pointer_has_axis (axis_event,
|
||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
|
||||
{
|
||||
discrete_dy = libinput_event_pointer_get_axis_value_discrete (
|
||||
axis_event, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
|
||||
}
|
||||
|
||||
clutter_seat_evdev_notify_discrete_scroll (seat, device,
|
||||
time_us,
|
||||
discrete_dx, discrete_dy,
|
||||
scroll_source);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
struct libinput_event *event)
|
||||
@ -1287,6 +1201,7 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
gboolean handled = TRUE;
|
||||
struct libinput_device *libinput_device = libinput_event_get_device(event);
|
||||
ClutterInputDevice *device;
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
|
||||
switch (libinput_event_get_type (event))
|
||||
{
|
||||
@ -1406,17 +1321,12 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
|
||||
case LIBINPUT_EVENT_POINTER_AXIS:
|
||||
{
|
||||
gdouble dx = 0.0, dy = 0.0;
|
||||
gdouble discrete_x = 0.0, discrete_y = 0.0;
|
||||
guint64 time_us;
|
||||
gboolean wheel = FALSE;
|
||||
enum libinput_pointer_axis axis;
|
||||
enum libinput_pointer_axis_source source;
|
||||
struct libinput_event_pointer *axis_event =
|
||||
libinput_event_get_pointer_event (event);
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterScrollSource scroll_source;
|
||||
ClutterScrollFinishFlags finish_flags = 0;
|
||||
|
||||
device = libinput_device_get_user_data (libinput_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
|
||||
@ -1430,68 +1340,25 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
backwards-compat with existing clients, we just send multiples of
|
||||
the click count. */
|
||||
|
||||
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL)
|
||||
wheel = TRUE;
|
||||
|
||||
axis = LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL;
|
||||
if (libinput_event_pointer_has_axis (axis_event, axis))
|
||||
switch (scroll_source)
|
||||
{
|
||||
discrete_y = libinput_event_pointer_get_axis_value_discrete (axis_event, axis);
|
||||
dy = libinput_event_pointer_get_axis_value (axis_event, axis);
|
||||
|
||||
if (wheel)
|
||||
seat->accum_scroll_dy = 0;
|
||||
else if (fabs (dy) < DBL_EPSILON)
|
||||
{
|
||||
finish_flags |= CLUTTER_SCROLL_FINISHED_VERTICAL;
|
||||
seat->accum_scroll_dy = 0;
|
||||
}
|
||||
else
|
||||
seat->accum_scroll_dy += dy;
|
||||
case CLUTTER_SCROLL_SOURCE_WHEEL:
|
||||
notify_discrete_axis (seat, device, time_us, scroll_source,
|
||||
axis_event);
|
||||
break;
|
||||
case CLUTTER_SCROLL_SOURCE_FINGER:
|
||||
case CLUTTER_SCROLL_SOURCE_CONTINUOUS:
|
||||
case CLUTTER_SCROLL_SOURCE_UNKNOWN:
|
||||
notify_continuous_axis (seat, device, time_us, scroll_source,
|
||||
axis_event);
|
||||
break;
|
||||
}
|
||||
|
||||
axis = LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL;
|
||||
if (libinput_event_pointer_has_axis (axis_event, axis))
|
||||
{
|
||||
discrete_x = libinput_event_pointer_get_axis_value_discrete (axis_event, axis);
|
||||
dx = libinput_event_pointer_get_axis_value (axis_event, axis);
|
||||
|
||||
if (wheel)
|
||||
seat->accum_scroll_dx = 0;
|
||||
else if (fabs (dx) < DBL_EPSILON)
|
||||
{
|
||||
finish_flags |= CLUTTER_SCROLL_FINISHED_HORIZONTAL;
|
||||
seat->accum_scroll_dx = 0;
|
||||
}
|
||||
else
|
||||
seat->accum_scroll_dx += dx;
|
||||
}
|
||||
|
||||
if (wheel)
|
||||
{
|
||||
notify_scroll (device, time_us,
|
||||
discrete_x * DISCRETE_SCROLL_STEP,
|
||||
discrete_y * DISCRETE_SCROLL_STEP,
|
||||
scroll_source, finish_flags, TRUE);
|
||||
notify_discrete_scroll (device, time_us,
|
||||
discrete_to_direction (discrete_x, discrete_y),
|
||||
scroll_source, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
notify_scroll (device, time_us, dx, dy,
|
||||
scroll_source, finish_flags, FALSE);
|
||||
check_notify_discrete_scroll (manager_evdev, device,
|
||||
time_us, scroll_source);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case LIBINPUT_EVENT_TOUCH_DOWN:
|
||||
{
|
||||
gint32 slot;
|
||||
int device_slot;
|
||||
guint64 time_us;
|
||||
double x, y;
|
||||
gfloat stage_width, stage_height;
|
||||
@ -1502,7 +1369,8 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
libinput_event_get_touch_event (event);
|
||||
|
||||
device = libinput_device_get_user_data (libinput_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
stage = _clutter_input_device_get_stage (device);
|
||||
if (stage == NULL)
|
||||
@ -1511,25 +1379,31 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
||||
stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
||||
|
||||
slot = libinput_event_touch_get_slot (touch_event);
|
||||
device_slot = libinput_event_touch_get_slot (touch_event);
|
||||
time_us = libinput_event_touch_get_time_usec (touch_event);
|
||||
x = libinput_event_touch_get_x_transformed (touch_event,
|
||||
stage_width);
|
||||
y = libinput_event_touch_get_y_transformed (touch_event,
|
||||
stage_height);
|
||||
|
||||
touch_state = clutter_seat_evdev_add_touch (seat, slot);
|
||||
touch_state =
|
||||
clutter_input_device_evdev_acquire_touch_state (device_evdev,
|
||||
device_slot);
|
||||
touch_state->coords.x = x;
|
||||
touch_state->coords.y = y;
|
||||
|
||||
notify_touch_event (device, CLUTTER_TOUCH_BEGIN, time_us, slot,
|
||||
touch_state->coords.x, touch_state->coords.y);
|
||||
clutter_seat_evdev_notify_touch_event (seat, device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
break;
|
||||
}
|
||||
|
||||
case LIBINPUT_EVENT_TOUCH_UP:
|
||||
{
|
||||
gint32 slot;
|
||||
int device_slot;
|
||||
guint64 time_us;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterTouchState *touch_state;
|
||||
@ -1537,22 +1411,30 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
libinput_event_get_touch_event (event);
|
||||
|
||||
device = libinput_device_get_user_data (libinput_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
slot = libinput_event_touch_get_slot (touch_event);
|
||||
device_slot = libinput_event_touch_get_slot (touch_event);
|
||||
time_us = libinput_event_touch_get_time_usec (touch_event);
|
||||
touch_state = clutter_seat_evdev_get_touch (seat, slot);
|
||||
|
||||
notify_touch_event (device, CLUTTER_TOUCH_END, time_us, slot,
|
||||
touch_state->coords.x, touch_state->coords.y);
|
||||
clutter_seat_evdev_remove_touch (seat, slot);
|
||||
touch_state =
|
||||
clutter_input_device_evdev_lookup_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
break;
|
||||
|
||||
clutter_seat_evdev_notify_touch_event (seat, device,
|
||||
CLUTTER_TOUCH_END, time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
clutter_input_device_evdev_release_touch_state (device_evdev,
|
||||
touch_state);
|
||||
break;
|
||||
}
|
||||
|
||||
case LIBINPUT_EVENT_TOUCH_MOTION:
|
||||
{
|
||||
gint32 slot;
|
||||
int device_slot;
|
||||
guint64 time_us;
|
||||
double x, y;
|
||||
gfloat stage_width, stage_height;
|
||||
@ -1563,7 +1445,8 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
libinput_event_get_touch_event (event);
|
||||
|
||||
device = libinput_device_get_user_data (libinput_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
stage = _clutter_input_device_get_stage (device);
|
||||
if (stage == NULL)
|
||||
@ -1572,42 +1455,41 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
stage_width = clutter_actor_get_width (CLUTTER_ACTOR (stage));
|
||||
stage_height = clutter_actor_get_height (CLUTTER_ACTOR (stage));
|
||||
|
||||
slot = libinput_event_touch_get_slot (touch_event);
|
||||
device_slot = libinput_event_touch_get_slot (touch_event);
|
||||
time_us = libinput_event_touch_get_time_usec (touch_event);
|
||||
x = libinput_event_touch_get_x_transformed (touch_event,
|
||||
stage_width);
|
||||
y = libinput_event_touch_get_y_transformed (touch_event,
|
||||
stage_height);
|
||||
|
||||
touch_state = clutter_seat_evdev_get_touch (seat, slot);
|
||||
touch_state =
|
||||
clutter_input_device_evdev_lookup_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
break;
|
||||
|
||||
touch_state->coords.x = x;
|
||||
touch_state->coords.y = y;
|
||||
|
||||
notify_touch_event (device, CLUTTER_TOUCH_UPDATE, time_us, slot,
|
||||
touch_state->coords.x, touch_state->coords.y);
|
||||
clutter_seat_evdev_notify_touch_event (seat, device,
|
||||
CLUTTER_TOUCH_UPDATE,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TOUCH_CANCEL:
|
||||
{
|
||||
ClutterTouchState *touch_state;
|
||||
GHashTableIter iter;
|
||||
guint64 time_us;
|
||||
struct libinput_event_touch *touch_event =
|
||||
libinput_event_get_touch_event (event);
|
||||
ClutterSeatEvdev *seat;
|
||||
|
||||
device = libinput_device_get_user_data (libinput_device);
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (device);
|
||||
time_us = libinput_event_touch_get_time_usec (touch_event);
|
||||
seat = _clutter_input_device_evdev_get_seat (CLUTTER_INPUT_DEVICE_EVDEV (device));
|
||||
g_hash_table_iter_init (&iter, seat->touches);
|
||||
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &touch_state))
|
||||
{
|
||||
notify_touch_event (device, CLUTTER_TOUCH_CANCEL,
|
||||
time_us, touch_state->id,
|
||||
touch_state->coords.x, touch_state->coords.y);
|
||||
g_hash_table_iter_remove (&iter);
|
||||
}
|
||||
clutter_input_device_evdev_release_touch_slots (device_evdev, time_us);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1617,6 +1499,7 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
struct libinput_event_gesture *gesture_event =
|
||||
libinput_event_get_gesture_event (event);
|
||||
ClutterTouchpadGesturePhase phase;
|
||||
guint n_fingers;
|
||||
guint64 time_us;
|
||||
|
||||
if (libinput_event_get_type (event) == LIBINPUT_EVENT_GESTURE_PINCH_BEGIN)
|
||||
@ -1625,9 +1508,10 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
phase = libinput_event_gesture_get_cancelled (gesture_event) ?
|
||||
CLUTTER_TOUCHPAD_GESTURE_PHASE_CANCEL : CLUTTER_TOUCHPAD_GESTURE_PHASE_END;
|
||||
|
||||
n_fingers = libinput_event_gesture_get_finger_count (gesture_event);
|
||||
device = libinput_device_get_user_data (libinput_device);
|
||||
time_us = libinput_event_gesture_get_time_usec (gesture_event);
|
||||
notify_pinch_gesture_event (device, phase, time_us, 0, 0, 0, 0);
|
||||
notify_pinch_gesture_event (device, phase, time_us, 0, 0, 0, 0, n_fingers);
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_PINCH_UPDATE:
|
||||
@ -1635,8 +1519,10 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
struct libinput_event_gesture *gesture_event =
|
||||
libinput_event_get_gesture_event (event);
|
||||
gdouble angle_delta, scale, dx, dy;
|
||||
guint n_fingers;
|
||||
guint64 time_us;
|
||||
|
||||
n_fingers = libinput_event_gesture_get_finger_count (gesture_event);
|
||||
device = libinput_device_get_user_data (libinput_device);
|
||||
time_us = libinput_event_gesture_get_time_usec (gesture_event);
|
||||
angle_delta = libinput_event_gesture_get_angle_delta (gesture_event);
|
||||
@ -1646,7 +1532,7 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
|
||||
notify_pinch_gesture_event (device,
|
||||
CLUTTER_TOUCHPAD_GESTURE_PHASE_UPDATE,
|
||||
time_us, dx, dy, angle_delta, scale);
|
||||
time_us, dx, dy, angle_delta, scale, n_fingers);
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN:
|
||||
@ -1707,7 +1593,8 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
if (!stage)
|
||||
break;
|
||||
|
||||
axes = translate_tablet_axes (tablet_event);
|
||||
axes = translate_tablet_axes (tablet_event,
|
||||
evdev_device->last_tool);
|
||||
if (!axes)
|
||||
break;
|
||||
|
||||
@ -1747,8 +1634,11 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
|
||||
libinput_tool = libinput_event_tablet_tool_get_tool (tablet_event);
|
||||
|
||||
input_device_update_tool (device, libinput_tool);
|
||||
if (state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN)
|
||||
input_device_update_tool (device, libinput_tool);
|
||||
notify_proximity (device, time, state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN);
|
||||
if (state == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT)
|
||||
input_device_update_tool (device, NULL);
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON:
|
||||
@ -1790,7 +1680,7 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
case LIBINPUT_EVENT_TABLET_PAD_BUTTON:
|
||||
{
|
||||
guint64 time;
|
||||
guint32 button_state, button, group;
|
||||
guint32 button_state, button, group, mode;
|
||||
struct libinput_tablet_pad_mode_group *mode_group;
|
||||
struct libinput_event_tablet_pad *pad_event =
|
||||
libinput_event_get_tablet_pad_event (event);
|
||||
@ -1800,17 +1690,18 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
|
||||
mode_group = libinput_event_tablet_pad_get_mode_group (pad_event);
|
||||
group = libinput_tablet_pad_mode_group_get_index (mode_group);
|
||||
mode = libinput_event_tablet_pad_get_mode (pad_event);
|
||||
|
||||
button = libinput_event_tablet_pad_get_button_number (pad_event);
|
||||
button_state = libinput_event_tablet_pad_get_button_state (pad_event) ==
|
||||
LIBINPUT_BUTTON_STATE_PRESSED;
|
||||
notify_pad_button (device, time, button, group, button_state);
|
||||
notify_pad_button (device, time, button, group, mode, button_state);
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_PAD_STRIP:
|
||||
{
|
||||
guint64 time;
|
||||
guint32 number, source, group;
|
||||
guint32 number, source, group, mode;
|
||||
struct libinput_tablet_pad_mode_group *mode_group;
|
||||
struct libinput_event_tablet_pad *pad_event =
|
||||
libinput_event_get_tablet_pad_event (event);
|
||||
@ -1824,14 +1715,15 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
|
||||
mode_group = libinput_event_tablet_pad_get_mode_group (pad_event);
|
||||
group = libinput_tablet_pad_mode_group_get_index (mode_group);
|
||||
mode = libinput_event_tablet_pad_get_mode (pad_event);
|
||||
|
||||
notify_pad_strip (device, time, number, source, group, value);
|
||||
notify_pad_strip (device, time, number, source, group, mode, value);
|
||||
break;
|
||||
}
|
||||
case LIBINPUT_EVENT_TABLET_PAD_RING:
|
||||
{
|
||||
guint64 time;
|
||||
guint32 number, source, group;
|
||||
guint32 number, source, group, mode;
|
||||
struct libinput_tablet_pad_mode_group *mode_group;
|
||||
struct libinput_event_tablet_pad *pad_event =
|
||||
libinput_event_get_tablet_pad_event (event);
|
||||
@ -1845,8 +1737,9 @@ process_device_event (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
|
||||
mode_group = libinput_event_tablet_pad_get_mode_group (pad_event);
|
||||
group = libinput_tablet_pad_mode_group_get_index (mode_group);
|
||||
mode = libinput_event_tablet_pad_get_mode (pad_event);
|
||||
|
||||
notify_pad_ring (device, time, number, source, group, angle);
|
||||
notify_pad_ring (device, time, number, source, group, mode, angle);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1970,6 +1863,14 @@ clutter_device_manager_evdev_create_virtual_device (ClutterDeviceManager *manag
|
||||
NULL);
|
||||
}
|
||||
|
||||
static ClutterVirtualDeviceType
|
||||
clutter_device_manager_evdev_get_supported_virtual_device_types (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD |
|
||||
CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER |
|
||||
CLUTTER_VIRTUAL_DEVICE_TYPE_TOUCHSCREEN);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_evdev_compress_motion (ClutterDeviceManager *device_manger,
|
||||
ClutterEvent *event,
|
||||
@ -1995,6 +1896,18 @@ clutter_device_manager_evdev_compress_motion (ClutterDeviceManager *device_mange
|
||||
dy_unaccel + dst_dy_unaccel);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_evdev_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *settings)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
|
||||
device = clutter_device_manager_evdev_get_core_device (device_manager, CLUTTER_KEYBOARD_DEVICE);
|
||||
if (device)
|
||||
clutter_input_device_evdev_apply_kbd_a11y_settings (CLUTTER_INPUT_DEVICE_EVDEV (device),
|
||||
settings);
|
||||
}
|
||||
|
||||
/*
|
||||
* GObject implementation
|
||||
*/
|
||||
@ -2028,7 +1941,8 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
|
||||
return;
|
||||
}
|
||||
|
||||
if (libinput_udev_assign_seat (priv->libinput, "seat0") == -1)
|
||||
if (libinput_udev_assign_seat (priv->libinput,
|
||||
evdev_seat_id ? evdev_seat_id : "seat0") == -1)
|
||||
{
|
||||
g_critical ("Failed to assign a seat to the libinput object.");
|
||||
libinput_unref (priv->libinput);
|
||||
@ -2050,6 +1964,7 @@ clutter_device_manager_evdev_constructed (GObject *gobject)
|
||||
xkb_context_unref (ctx);
|
||||
|
||||
priv->main_seat = clutter_seat_evdev_new (manager_evdev);
|
||||
priv->seats = g_slist_append (priv->seats, priv->main_seat);
|
||||
|
||||
dispatch_libinput (manager_evdev);
|
||||
|
||||
@ -2135,7 +2050,9 @@ clutter_device_manager_evdev_class_init (ClutterDeviceManagerEvdevClass *klass)
|
||||
manager_class->get_core_device = clutter_device_manager_evdev_get_core_device;
|
||||
manager_class->get_device = clutter_device_manager_evdev_get_device;
|
||||
manager_class->create_virtual_device = clutter_device_manager_evdev_create_virtual_device;
|
||||
manager_class->get_supported_virtual_device_types = clutter_device_manager_evdev_get_supported_virtual_device_types;
|
||||
manager_class->compress_motion = clutter_device_manager_evdev_compress_motion;
|
||||
manager_class->apply_kbd_a11y_settings = clutter_device_manager_evdev_apply_kbd_a11y_settings;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2256,7 +2173,7 @@ _clutter_device_manager_evdev_acquire_device_id (ClutterDeviceManagerEvdev *mana
|
||||
|
||||
first = g_list_first (priv->free_device_ids);
|
||||
next_id = GPOINTER_TO_INT (first->data);
|
||||
priv->free_device_ids = g_list_remove_link (priv->free_device_ids, first);
|
||||
priv->free_device_ids = g_list_delete_link (priv->free_device_ids, first);
|
||||
|
||||
return next_id;
|
||||
}
|
||||
@ -2375,7 +2292,7 @@ clutter_evdev_update_xkb_state (ClutterDeviceManagerEvdev *manager_evdev)
|
||||
0, /* depressed */
|
||||
latched_mods,
|
||||
locked_mods,
|
||||
0, 0, 0);
|
||||
0, 0, seat->layout_idx);
|
||||
|
||||
seat->caps_lock_led = xkb_keymap_led_get_index (priv->keymap, XKB_LED_NAME_CAPS);
|
||||
seat->num_lock_led = xkb_keymap_led_get_index (priv->keymap, XKB_LED_NAME_NUM);
|
||||
@ -2523,6 +2440,7 @@ clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev,
|
||||
xkb_mod_mask_t latched_mods;
|
||||
xkb_mod_mask_t locked_mods;
|
||||
struct xkb_state *state;
|
||||
GSList *l;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev));
|
||||
|
||||
@ -2534,6 +2452,24 @@ clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev,
|
||||
locked_mods = xkb_state_serialize_mods (state, XKB_STATE_MODS_LOCKED);
|
||||
|
||||
xkb_state_update_mask (state, depressed_mods, latched_mods, locked_mods, 0, 0, idx);
|
||||
for (l = manager_evdev->priv->seats; l; l = l->next)
|
||||
{
|
||||
ClutterSeatEvdev *seat = l->data;
|
||||
|
||||
seat->layout_idx = idx;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_evdev_get_keyboard_layout_index: (skip)
|
||||
*/
|
||||
xkb_layout_index_t
|
||||
clutter_evdev_get_keyboard_layout_index (ClutterDeviceManager *evdev)
|
||||
{
|
||||
ClutterDeviceManagerEvdev *manager_evdev;
|
||||
|
||||
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev);
|
||||
return manager_evdev->priv->main_seat->layout_idx;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2626,6 +2562,23 @@ clutter_evdev_set_pointer_constrain_callback (ClutterDeviceManager *e
|
||||
priv->constrain_data_notify = user_data_notify;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_evdev_set_relative_motion_filter (ClutterDeviceManager *evdev,
|
||||
ClutterRelativeMotionFilter filter,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterDeviceManagerEvdev *manager_evdev;
|
||||
ClutterDeviceManagerEvdevPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER_EVDEV (evdev));
|
||||
|
||||
manager_evdev = CLUTTER_DEVICE_MANAGER_EVDEV (evdev);
|
||||
priv = manager_evdev->priv;
|
||||
|
||||
priv->relative_motion_filter = filter;
|
||||
priv->relative_motion_filter_user_data = user_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_evdev_set_keyboard_repeat:
|
||||
* @evdev: the #ClutterDeviceManager created by the evdev backend
|
||||
@ -2777,3 +2730,18 @@ clutter_evdev_warp_pointer (ClutterInputDevice *pointer_device,
|
||||
{
|
||||
notify_absolute_motion (pointer_device, ms2us(time_), x, y, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_evdev_set_seat_id:
|
||||
* @seat_id: The seat ID
|
||||
*
|
||||
* Sets the seat to assign to the libinput context.
|
||||
*
|
||||
* For reliable effects, this function must be called before clutter_init().
|
||||
*/
|
||||
void
|
||||
clutter_evdev_set_seat_id (const gchar *seat_id)
|
||||
{
|
||||
g_free (evdev_seat_id);
|
||||
evdev_seat_id = g_strdup (seat_id);
|
||||
}
|
||||
|
@ -76,6 +76,13 @@ void _clutter_device_manager_evdev_constrain_pointer (ClutterDeviceManagerEvdev
|
||||
float *new_x,
|
||||
float *new_y);
|
||||
|
||||
void _clutter_device_manager_evdev_filter_relative_motion (ClutterDeviceManagerEvdev *manager_evdev,
|
||||
ClutterInputDevice *device,
|
||||
float x,
|
||||
float y,
|
||||
float *dx,
|
||||
float *dy);
|
||||
|
||||
void _clutter_device_manager_evdev_dispatch (ClutterDeviceManagerEvdev *manager_evdev);
|
||||
|
||||
static inline guint64
|
||||
|
@ -57,6 +57,9 @@ void clutter_evdev_set_device_callbacks (ClutterOpenDeviceCallback open_callba
|
||||
ClutterCloseDeviceCallback close_callback,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_evdev_set_seat_id (const gchar *seat_id);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_1_10
|
||||
void clutter_evdev_release_devices (void);
|
||||
CLUTTER_AVAILABLE_IN_1_10
|
||||
@ -94,6 +97,18 @@ void clutter_evdev_set_pointer_constrain_callback (ClutterDeviceManager
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_data_notify);
|
||||
|
||||
typedef void (*ClutterRelativeMotionFilter) (ClutterInputDevice *device,
|
||||
float x,
|
||||
float y,
|
||||
float *dx,
|
||||
float *dy,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
void clutter_evdev_set_relative_motion_filter (ClutterDeviceManager *evdev,
|
||||
ClutterRelativeMotionFilter filter,
|
||||
gpointer user_data);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_1_16
|
||||
void clutter_evdev_set_keyboard_map (ClutterDeviceManager *evdev,
|
||||
struct xkb_keymap *keymap);
|
||||
@ -105,6 +120,9 @@ CLUTTER_AVAILABLE_IN_1_20
|
||||
void clutter_evdev_set_keyboard_layout_index (ClutterDeviceManager *evdev,
|
||||
xkb_layout_index_t idx);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_MUTTER
|
||||
xkb_layout_index_t clutter_evdev_get_keyboard_layout_index (ClutterDeviceManager *evdev);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_1_26
|
||||
void clutter_evdev_set_keyboard_numlock (ClutterDeviceManager *evdev,
|
||||
gboolean numlock_state);
|
||||
@ -150,6 +168,14 @@ gboolean clutter_evdev_event_get_relative_motion (const ClutterEvent *event,
|
||||
double *dx_unaccel,
|
||||
double *dy_unaccel);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_evdev_input_device_tool_set_pressure_curve (ClutterInputDeviceTool *tool,
|
||||
gdouble curve[4]);
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_evdev_input_device_tool_set_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button,
|
||||
guint evcode);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_EVDEV_H__ */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -66,6 +66,35 @@ struct _ClutterInputDeviceEvdev
|
||||
struct libinput_device *libinput_device;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterInputDeviceTool *last_tool;
|
||||
|
||||
cairo_matrix_t device_matrix;
|
||||
gdouble device_aspect_ratio; /* w:h */
|
||||
gdouble output_ratio; /* w:h */
|
||||
|
||||
GHashTable *touches;
|
||||
|
||||
/* Keyboard a11y */
|
||||
ClutterKeyboardA11yFlags a11y_flags;
|
||||
GList *slow_keys_list;
|
||||
guint debounce_timer;
|
||||
guint16 debounce_key;
|
||||
xkb_mod_mask_t stickykeys_depressed_mask;
|
||||
xkb_mod_mask_t stickykeys_latched_mask;
|
||||
xkb_mod_mask_t stickykeys_locked_mask;
|
||||
guint toggle_slowkeys_timer;
|
||||
guint16 shift_count;
|
||||
guint32 last_shift_time;
|
||||
gint mousekeys_btn;
|
||||
gboolean mousekeys_btn_states[3];
|
||||
guint32 mousekeys_first_motion_time; /* ms */
|
||||
guint32 mousekeys_last_motion_time; /* ms */
|
||||
guint mousekeys_init_delay;
|
||||
guint mousekeys_accel_time;
|
||||
guint mousekeys_max_speed;
|
||||
gdouble mousekeys_curve_factor;
|
||||
guint move_mousekeys_timer;
|
||||
guint16 last_mousekeys_key;
|
||||
ClutterVirtualInputDevice *mousekeys_virtual_device;
|
||||
};
|
||||
|
||||
GType _clutter_input_device_evdev_get_type (void) G_GNUC_CONST;
|
||||
@ -102,6 +131,27 @@ void _clutter_evdev_event_set_relative_motion (ClutterEvent *event,
|
||||
double dx_unaccel,
|
||||
double dy_unaccel);
|
||||
|
||||
void clutter_input_device_evdev_translate_coordinates (ClutterInputDevice *device,
|
||||
ClutterStage *stage,
|
||||
gfloat *x,
|
||||
gfloat *y);
|
||||
|
||||
void clutter_input_device_evdev_apply_kbd_a11y_settings (ClutterInputDeviceEvdev *device,
|
||||
ClutterKbdA11ySettings *settings);
|
||||
|
||||
ClutterTouchState * clutter_input_device_evdev_acquire_touch_state (ClutterInputDeviceEvdev *device,
|
||||
int device_slot);
|
||||
|
||||
ClutterTouchState * clutter_input_device_evdev_lookup_touch_state (ClutterInputDeviceEvdev *device,
|
||||
int device_slot);
|
||||
|
||||
void clutter_input_device_evdev_release_touch_state (ClutterInputDeviceEvdev *device,
|
||||
ClutterTouchState *touch_state);
|
||||
|
||||
void clutter_input_device_evdev_release_touch_slots (ClutterInputDeviceEvdev *device_evdev,
|
||||
uint64_t time_us);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_DEVICE_EVDEV_H__ */
|
||||
|
@ -26,6 +26,7 @@
|
||||
#endif
|
||||
|
||||
#include "clutter-input-device-tool-evdev.h"
|
||||
#include "clutter-evdev.h"
|
||||
|
||||
G_DEFINE_TYPE (ClutterInputDeviceToolEvdev, clutter_input_device_tool_evdev,
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL)
|
||||
@ -35,6 +36,7 @@ clutter_input_device_tool_evdev_finalize (GObject *object)
|
||||
{
|
||||
ClutterInputDeviceToolEvdev *tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (object);
|
||||
|
||||
g_hash_table_unref (tool->button_map);
|
||||
libinput_tablet_tool_unref (tool->tool);
|
||||
|
||||
G_OBJECT_CLASS (clutter_input_device_tool_evdev_parent_class)->finalize (object);
|
||||
@ -51,6 +53,7 @@ clutter_input_device_tool_evdev_class_init (ClutterInputDeviceToolEvdevClass *kl
|
||||
static void
|
||||
clutter_input_device_tool_evdev_init (ClutterInputDeviceToolEvdev *tool)
|
||||
{
|
||||
tool->button_map = g_hash_table_new (NULL, NULL);
|
||||
}
|
||||
|
||||
ClutterInputDeviceTool *
|
||||
@ -70,3 +73,96 @@ clutter_input_device_tool_evdev_new (struct libinput_tablet_tool *tool,
|
||||
|
||||
return CLUTTER_INPUT_DEVICE_TOOL (evdev_tool);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_evdev_input_device_tool_set_pressure_curve (ClutterInputDeviceTool *tool,
|
||||
gdouble curve[4])
|
||||
{
|
||||
ClutterInputDeviceToolEvdev *evdev_tool;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL_EVDEV (tool));
|
||||
g_return_if_fail (curve[0] >= 0 && curve[0] <= 1 &&
|
||||
curve[1] >= 0 && curve[1] <= 1 &&
|
||||
curve[2] >= 0 && curve[2] <= 1 &&
|
||||
curve[3] >= 0 && curve[3] <= 1);
|
||||
|
||||
evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool);
|
||||
evdev_tool->pressure_curve[0] = curve[0];
|
||||
evdev_tool->pressure_curve[1] = curve[1];
|
||||
evdev_tool->pressure_curve[2] = curve[2];
|
||||
evdev_tool->pressure_curve[3] = curve[3];
|
||||
}
|
||||
|
||||
void
|
||||
clutter_evdev_input_device_tool_set_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button,
|
||||
guint evcode)
|
||||
{
|
||||
ClutterInputDeviceToolEvdev *evdev_tool;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL_EVDEV (tool));
|
||||
|
||||
evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool);
|
||||
|
||||
if (evcode == 0)
|
||||
{
|
||||
g_hash_table_remove (evdev_tool->button_map, GUINT_TO_POINTER (button));
|
||||
}
|
||||
else
|
||||
{
|
||||
g_hash_table_insert (evdev_tool->button_map, GUINT_TO_POINTER (button),
|
||||
GUINT_TO_POINTER (evcode));
|
||||
}
|
||||
}
|
||||
|
||||
static gdouble
|
||||
calculate_bezier_position (gdouble pos,
|
||||
gdouble x1,
|
||||
gdouble y1,
|
||||
gdouble x2,
|
||||
gdouble y2)
|
||||
{
|
||||
gdouble int1_y, int2_y;
|
||||
|
||||
pos = CLAMP (pos, 0, 1);
|
||||
|
||||
/* Intersection between 0,0 and x1,y1 */
|
||||
int1_y = pos * y1;
|
||||
|
||||
/* Intersection between x2,y2 and 1,1 */
|
||||
int2_y = (pos * (1 - y2)) + y2;
|
||||
|
||||
/* Find the new position in the line traced by the previous points */
|
||||
return (pos * (int2_y - int1_y)) + int1_y;
|
||||
}
|
||||
|
||||
gdouble
|
||||
clutter_input_device_tool_evdev_translate_pressure (ClutterInputDeviceTool *tool,
|
||||
gdouble pressure)
|
||||
{
|
||||
ClutterInputDeviceToolEvdev *evdev_tool;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), pressure);
|
||||
|
||||
evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool);
|
||||
|
||||
return calculate_bezier_position (CLAMP (pressure, 0, 1),
|
||||
evdev_tool->pressure_curve[0],
|
||||
evdev_tool->pressure_curve[1],
|
||||
evdev_tool->pressure_curve[2],
|
||||
evdev_tool->pressure_curve[3]);
|
||||
}
|
||||
|
||||
guint
|
||||
clutter_input_device_tool_evdev_get_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button)
|
||||
{
|
||||
ClutterInputDeviceToolEvdev *evdev_tool;
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE_TOOL (tool), 0);
|
||||
|
||||
evdev_tool = CLUTTER_INPUT_DEVICE_TOOL_EVDEV (tool);
|
||||
|
||||
return GPOINTER_TO_UINT (g_hash_table_lookup (evdev_tool->button_map,
|
||||
GUINT_TO_POINTER (button)));
|
||||
}
|
||||
|
@ -59,6 +59,8 @@ struct _ClutterInputDeviceToolEvdev
|
||||
{
|
||||
ClutterInputDeviceTool parent_instance;
|
||||
struct libinput_tablet_tool *tool;
|
||||
GHashTable *button_map;
|
||||
gdouble pressure_curve[4];
|
||||
};
|
||||
|
||||
struct _ClutterInputDeviceToolEvdevClass
|
||||
@ -72,6 +74,11 @@ ClutterInputDeviceTool * clutter_input_device_tool_evdev_new (struct libinp
|
||||
guint64 serial,
|
||||
ClutterInputDeviceToolType type);
|
||||
|
||||
gdouble clutter_input_device_tool_evdev_translate_pressure (ClutterInputDeviceTool *tool,
|
||||
gdouble pressure);
|
||||
guint clutter_input_device_tool_evdev_get_button_code (ClutterInputDeviceTool *tool,
|
||||
guint button);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_DEVICE_EVDEV_TOOL_H__ */
|
||||
|
@ -29,9 +29,11 @@
|
||||
#include "clutter-seat-evdev.h"
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "clutter-event-private.h"
|
||||
#include "clutter-input-device-evdev.h"
|
||||
#include "clutter-input-device-tool-evdev.h"
|
||||
#include "clutter-main.h"
|
||||
|
||||
/* Try to keep the pointer inside the stage. Hopefully no one is using
|
||||
@ -41,6 +43,12 @@
|
||||
|
||||
#define AUTOREPEAT_VALUE 2
|
||||
|
||||
#define DISCRETE_SCROLL_STEP 10.0
|
||||
|
||||
#ifndef BTN_STYLUS3
|
||||
#define BTN_STYLUS3 0x149 /* Linux 4.15 */
|
||||
#endif
|
||||
|
||||
void
|
||||
clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
|
||||
struct libinput_seat *libinput_seat)
|
||||
@ -84,32 +92,57 @@ clutter_touch_state_free (ClutterTouchState *touch_state)
|
||||
g_slice_free (ClutterTouchState, touch_state);
|
||||
}
|
||||
|
||||
ClutterTouchState *
|
||||
clutter_seat_evdev_add_touch (ClutterSeatEvdev *seat,
|
||||
guint32 id)
|
||||
static void
|
||||
ensure_seat_slot_allocated (ClutterSeatEvdev *seat,
|
||||
int seat_slot)
|
||||
{
|
||||
ClutterTouchState *touch;
|
||||
if (seat_slot >= seat->n_alloc_touch_states)
|
||||
{
|
||||
const int size_increase = 5;
|
||||
int i;
|
||||
|
||||
touch = g_slice_new0 (ClutterTouchState);
|
||||
touch->id = id;
|
||||
seat->n_alloc_touch_states += size_increase;
|
||||
seat->touch_states = g_realloc_n (seat->touch_states,
|
||||
seat->n_alloc_touch_states,
|
||||
sizeof (ClutterTouchState *));
|
||||
for (i = 0; i < size_increase; i++)
|
||||
seat->touch_states[seat->n_alloc_touch_states - (i + 1)] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_insert (seat->touches, GUINT_TO_POINTER (id), touch);
|
||||
ClutterTouchState *
|
||||
clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat,
|
||||
int device_slot)
|
||||
{
|
||||
ClutterTouchState *touch_state;
|
||||
int seat_slot;
|
||||
|
||||
return touch;
|
||||
for (seat_slot = 0; seat_slot < seat->n_alloc_touch_states; seat_slot++)
|
||||
{
|
||||
if (!seat->touch_states[seat_slot])
|
||||
break;
|
||||
}
|
||||
|
||||
ensure_seat_slot_allocated (seat, seat_slot);
|
||||
|
||||
touch_state = g_slice_new0 (ClutterTouchState);
|
||||
*touch_state = (ClutterTouchState) {
|
||||
.seat = seat,
|
||||
.seat_slot = seat_slot,
|
||||
.device_slot = device_slot,
|
||||
};
|
||||
|
||||
seat->touch_states[seat_slot] = touch_state;
|
||||
|
||||
return touch_state;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_seat_evdev_remove_touch (ClutterSeatEvdev *seat,
|
||||
guint32 id)
|
||||
clutter_seat_evdev_release_touch_state (ClutterSeatEvdev *seat,
|
||||
ClutterTouchState *touch_state)
|
||||
{
|
||||
g_hash_table_remove (seat->touches, GUINT_TO_POINTER (id));
|
||||
}
|
||||
|
||||
ClutterTouchState *
|
||||
clutter_seat_evdev_get_touch (ClutterSeatEvdev *seat,
|
||||
guint32 id)
|
||||
{
|
||||
return g_hash_table_lookup (seat->touches, GUINT_TO_POINTER (id));
|
||||
g_clear_pointer (&seat->touch_states[touch_state->seat_slot],
|
||||
(GDestroyNotify) clutter_touch_state_free);
|
||||
}
|
||||
|
||||
ClutterSeatEvdev *
|
||||
@ -146,9 +179,6 @@ clutter_seat_evdev_new (ClutterDeviceManagerEvdev *manager_evdev)
|
||||
_clutter_device_manager_add_device (manager, device);
|
||||
seat->core_keyboard = device;
|
||||
|
||||
seat->touches = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) clutter_touch_state_free);
|
||||
|
||||
seat->repeat = TRUE;
|
||||
seat->repeat_delay = 250; /* ms */
|
||||
seat->repeat_interval = 33; /* ms */
|
||||
@ -404,6 +434,13 @@ clutter_seat_evdev_notify_relative_motion (ClutterSeatEvdev *seat,
|
||||
if (!_clutter_input_device_get_stage (input_device))
|
||||
return;
|
||||
|
||||
_clutter_device_manager_evdev_filter_relative_motion (seat->manager_evdev,
|
||||
input_device,
|
||||
seat->pointer_x,
|
||||
seat->pointer_y,
|
||||
&dx,
|
||||
&dy);
|
||||
|
||||
new_x = seat->pointer_x + dx;
|
||||
new_y = seat->pointer_y + dy;
|
||||
event = new_absolute_motion_event (seat, input_device,
|
||||
@ -437,6 +474,7 @@ clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev = (ClutterInputDeviceEvdev *) input_device;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
gint button_nr;
|
||||
@ -480,6 +518,10 @@ clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
|
||||
button_nr = CLUTTER_BUTTON_MIDDLE;
|
||||
break;
|
||||
|
||||
case 0x149: /* BTN_STYLUS3 */
|
||||
button_nr = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* For compatibility reasons, all additional buttons go after the old 4-7 scroll ones */
|
||||
if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
|
||||
@ -532,13 +574,21 @@ clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
|
||||
if (device_evdev->last_tool)
|
||||
{
|
||||
/* Apply the button event code as per the tool mapping */
|
||||
guint mapped_button;
|
||||
|
||||
mapped_button = clutter_input_device_tool_evdev_get_button_code (device_evdev->last_tool,
|
||||
button_nr);
|
||||
if (mapped_button != 0)
|
||||
button = mapped_button;
|
||||
}
|
||||
|
||||
_clutter_evdev_event_set_event_code (event, button);
|
||||
|
||||
if (clutter_input_device_get_device_type (input_device) == CLUTTER_TABLET_DEVICE)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev =
|
||||
CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
|
||||
clutter_event_set_device_tool (event, device_evdev->last_tool);
|
||||
clutter_event_set_device (event, input_device);
|
||||
}
|
||||
@ -552,6 +602,238 @@ clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_scroll (ClutterInputDevice *input_device,
|
||||
guint64 time_us,
|
||||
gdouble dx,
|
||||
gdouble dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags flags,
|
||||
gboolean emulated)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
gdouble scroll_factor;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
event->scroll.device = seat->core_pointer;
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
/* libinput pointer axis events are in pointer motion coordinate space.
|
||||
* To convert to Xi2 discrete step coordinate space, multiply the factor
|
||||
* 1/10. */
|
||||
event->scroll.direction = CLUTTER_SCROLL_SMOOTH;
|
||||
scroll_factor = 1.0 / DISCRETE_SCROLL_STEP;
|
||||
clutter_event_set_scroll_delta (event,
|
||||
scroll_factor * dx,
|
||||
scroll_factor * dy);
|
||||
|
||||
event->scroll.x = seat->pointer_x;
|
||||
event->scroll.y = seat->pointer_y;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
event->scroll.scroll_source = scroll_source;
|
||||
event->scroll.finish_flags = flags;
|
||||
|
||||
_clutter_event_set_pointer_emulated (event, emulated);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
notify_discrete_scroll (ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source,
|
||||
gboolean emulated)
|
||||
{
|
||||
ClutterInputDeviceEvdev *device_evdev;
|
||||
ClutterSeatEvdev *seat;
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
|
||||
if (direction == CLUTTER_SCROLL_SMOOTH)
|
||||
return;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
device_evdev = CLUTTER_INPUT_DEVICE_EVDEV (input_device);
|
||||
seat = _clutter_input_device_evdev_get_seat (device_evdev);
|
||||
|
||||
event = clutter_event_new (CLUTTER_SCROLL);
|
||||
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->scroll.time = us2ms (time_us);
|
||||
event->scroll.stage = CLUTTER_STAGE (stage);
|
||||
event->scroll.device = seat->core_pointer;
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
event->scroll.direction = direction;
|
||||
|
||||
event->scroll.x = seat->pointer_x;
|
||||
event->scroll.y = seat->pointer_y;
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
event->scroll.scroll_source = scroll_source;
|
||||
|
||||
_clutter_event_set_pointer_emulated (event, emulated);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
static void
|
||||
check_notify_discrete_scroll (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
int i, n_xscrolls, n_yscrolls;
|
||||
|
||||
n_xscrolls = floor (fabs (seat->accum_scroll_dx) / DISCRETE_SCROLL_STEP);
|
||||
n_yscrolls = floor (fabs (seat->accum_scroll_dy) / DISCRETE_SCROLL_STEP);
|
||||
|
||||
for (i = 0; i < n_xscrolls; i++)
|
||||
{
|
||||
notify_discrete_scroll (device, time_us,
|
||||
seat->accum_scroll_dx > 0 ?
|
||||
CLUTTER_SCROLL_RIGHT : CLUTTER_SCROLL_LEFT,
|
||||
scroll_source, TRUE);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_yscrolls; i++)
|
||||
{
|
||||
notify_discrete_scroll (device, time_us,
|
||||
seat->accum_scroll_dy > 0 ?
|
||||
CLUTTER_SCROLL_DOWN : CLUTTER_SCROLL_UP,
|
||||
scroll_source, TRUE);
|
||||
}
|
||||
|
||||
seat->accum_scroll_dx = fmodf (seat->accum_scroll_dx, DISCRETE_SCROLL_STEP);
|
||||
seat->accum_scroll_dy = fmodf (seat->accum_scroll_dy, DISCRETE_SCROLL_STEP);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_seat_evdev_notify_scroll_continuous (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
{
|
||||
if (finish_flags & CLUTTER_SCROLL_FINISHED_HORIZONTAL)
|
||||
seat->accum_scroll_dx = 0;
|
||||
else
|
||||
seat->accum_scroll_dx += dx;
|
||||
|
||||
if (finish_flags & CLUTTER_SCROLL_FINISHED_VERTICAL)
|
||||
seat->accum_scroll_dy = 0;
|
||||
else
|
||||
seat->accum_scroll_dy += dy;
|
||||
|
||||
notify_scroll (input_device, time_us, dx, dy, scroll_source,
|
||||
finish_flags, FALSE);
|
||||
check_notify_discrete_scroll (seat, input_device, time_us, scroll_source);
|
||||
}
|
||||
|
||||
static ClutterScrollDirection
|
||||
discrete_to_direction (double discrete_dx,
|
||||
double discrete_dy)
|
||||
{
|
||||
if (discrete_dx > 0)
|
||||
return CLUTTER_SCROLL_RIGHT;
|
||||
else if (discrete_dx < 0)
|
||||
return CLUTTER_SCROLL_LEFT;
|
||||
else if (discrete_dy > 0)
|
||||
return CLUTTER_SCROLL_DOWN;
|
||||
else if (discrete_dy < 0)
|
||||
return CLUTTER_SCROLL_UP;
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
void
|
||||
clutter_seat_evdev_notify_discrete_scroll (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double discrete_dx,
|
||||
double discrete_dy,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
notify_scroll (input_device, time_us,
|
||||
discrete_dx * DISCRETE_SCROLL_STEP,
|
||||
discrete_dy * DISCRETE_SCROLL_STEP,
|
||||
scroll_source, CLUTTER_SCROLL_FINISHED_NONE,
|
||||
TRUE);
|
||||
notify_discrete_scroll (input_device, time_us,
|
||||
discrete_to_direction (discrete_dx, discrete_dy),
|
||||
scroll_source, FALSE);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
clutter_seat_evdev_notify_touch_event (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
ClutterEventType evtype,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
ClutterStage *stage;
|
||||
ClutterEvent *event = NULL;
|
||||
|
||||
/* We can drop the event on the floor if no stage has been
|
||||
* associated with the device yet. */
|
||||
stage = _clutter_input_device_get_stage (input_device);
|
||||
if (stage == NULL)
|
||||
return;
|
||||
|
||||
event = clutter_event_new (evtype);
|
||||
|
||||
_clutter_evdev_event_set_time_usec (event, time_us);
|
||||
event->touch.time = us2ms (time_us);
|
||||
event->touch.stage = CLUTTER_STAGE (stage);
|
||||
event->touch.device = seat->core_pointer;
|
||||
event->touch.x = x;
|
||||
event->touch.y = y;
|
||||
clutter_input_device_evdev_translate_coordinates (input_device, stage,
|
||||
&event->touch.x,
|
||||
&event->touch.y);
|
||||
|
||||
/* "NULL" sequences are special cased in clutter */
|
||||
event->touch.sequence = GINT_TO_POINTER (MAX (1, slot + 1));
|
||||
_clutter_xkb_translate_state (event, seat->xkb, seat->button_state);
|
||||
|
||||
if (evtype == CLUTTER_TOUCH_BEGIN ||
|
||||
evtype == CLUTTER_TOUCH_UPDATE)
|
||||
event->touch.modifier_state |= CLUTTER_BUTTON1_MASK;
|
||||
|
||||
clutter_event_set_device (event, seat->core_pointer);
|
||||
clutter_event_set_source_device (event, input_device);
|
||||
|
||||
queue_event (event);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_seat_evdev_free (ClutterSeatEvdev *seat)
|
||||
{
|
||||
@ -564,7 +846,7 @@ clutter_seat_evdev_free (ClutterSeatEvdev *seat)
|
||||
g_object_unref (device);
|
||||
}
|
||||
g_slist_free (seat->devices);
|
||||
g_hash_table_unref (seat->touches);
|
||||
g_free (seat->touch_states);
|
||||
|
||||
xkb_state_unref (seat->xkb);
|
||||
|
||||
@ -576,6 +858,24 @@ clutter_seat_evdev_free (ClutterSeatEvdev *seat)
|
||||
g_free (seat);
|
||||
}
|
||||
|
||||
ClutterInputDevice *
|
||||
clutter_seat_evdev_get_device (ClutterSeatEvdev *seat,
|
||||
gint id)
|
||||
{
|
||||
ClutterInputDevice *device;
|
||||
GSList *l;
|
||||
|
||||
for (l = seat->devices; l; l = l->next)
|
||||
{
|
||||
device = l->data;
|
||||
|
||||
if (clutter_input_device_get_device_id (device) == id)
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_seat_evdev_set_stage (ClutterSeatEvdev *seat,
|
||||
ClutterStage *stage)
|
||||
|
@ -38,7 +38,10 @@ typedef struct _ClutterTouchState ClutterTouchState;
|
||||
|
||||
struct _ClutterTouchState
|
||||
{
|
||||
guint32 id;
|
||||
ClutterSeatEvdev *seat;
|
||||
|
||||
int device_slot;
|
||||
int seat_slot;
|
||||
ClutterPoint coords;
|
||||
};
|
||||
|
||||
@ -52,12 +55,14 @@ struct _ClutterSeatEvdev
|
||||
ClutterInputDevice *core_pointer;
|
||||
ClutterInputDevice *core_keyboard;
|
||||
|
||||
GHashTable *touches;
|
||||
ClutterTouchState **touch_states;
|
||||
int n_alloc_touch_states;
|
||||
|
||||
struct xkb_state *xkb;
|
||||
xkb_led_index_t caps_lock_led;
|
||||
xkb_led_index_t num_lock_led;
|
||||
xkb_led_index_t scroll_lock_led;
|
||||
xkb_layout_index_t layout_idx;
|
||||
uint32_t button_state;
|
||||
int button_count[KEY_CNT];
|
||||
|
||||
@ -106,16 +111,42 @@ void clutter_seat_evdev_notify_button (ClutterSeatEvdev *seat,
|
||||
uint32_t button,
|
||||
uint32_t state);
|
||||
|
||||
void clutter_seat_evdev_notify_scroll_continuous (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource source,
|
||||
ClutterScrollFinishFlags flags);
|
||||
|
||||
void clutter_seat_evdev_notify_discrete_scroll (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
uint64_t time_us,
|
||||
double discrete_dx,
|
||||
double discrete_dy,
|
||||
ClutterScrollSource source);
|
||||
|
||||
void clutter_seat_evdev_notify_touch_event (ClutterSeatEvdev *seat,
|
||||
ClutterInputDevice *input_device,
|
||||
ClutterEventType evtype,
|
||||
uint64_t time_us,
|
||||
int slot,
|
||||
double x,
|
||||
double y);
|
||||
|
||||
void clutter_seat_evdev_set_libinput_seat (ClutterSeatEvdev *seat,
|
||||
struct libinput_seat *libinput_seat);
|
||||
|
||||
void clutter_seat_evdev_sync_leds (ClutterSeatEvdev *seat);
|
||||
|
||||
ClutterTouchState * clutter_seat_evdev_add_touch (ClutterSeatEvdev *seat,
|
||||
guint32 id);
|
||||
ClutterInputDevice * clutter_seat_evdev_get_device (ClutterSeatEvdev *seat,
|
||||
gint id);
|
||||
|
||||
void clutter_seat_evdev_remove_touch (ClutterSeatEvdev *seat,
|
||||
guint32 id);
|
||||
ClutterTouchState * clutter_seat_evdev_acquire_touch_state (ClutterSeatEvdev *seat,
|
||||
int device_slot);
|
||||
|
||||
void clutter_seat_evdev_release_touch_state (ClutterSeatEvdev *seat,
|
||||
ClutterTouchState *touch_state);
|
||||
|
||||
ClutterTouchState * clutter_seat_evdev_get_touch (ClutterSeatEvdev *seat,
|
||||
guint32 id);
|
||||
|
@ -156,6 +156,9 @@ clutter_virtual_input_device_evdev_notify_relative_motion (ClutterVirtualInputDe
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
clutter_seat_evdev_notify_relative_motion (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
@ -172,6 +175,9 @@ clutter_virtual_input_device_evdev_notify_absolute_motion (ClutterVirtualInputDe
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
clutter_seat_evdev_notify_absolute_motion (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
@ -189,6 +195,9 @@ clutter_virtual_input_device_evdev_notify_button (ClutterVirtualInputDevice *vir
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
int button_count;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
if (get_button_type (button) != EVDEV_BUTTON_TYPE_BUTTON)
|
||||
{
|
||||
g_warning ("Unknown/invalid virtual device button 0x%x pressed",
|
||||
@ -222,6 +231,9 @@ clutter_virtual_input_device_evdev_notify_key (ClutterVirtualInputDevice *virtua
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
int key_count;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
if (get_button_type (key) != EVDEV_BUTTON_TYPE_KEY)
|
||||
{
|
||||
g_warning ("Unknown/invalid virtual device key 0x%x pressed\n", key);
|
||||
@ -343,6 +355,9 @@ clutter_virtual_input_device_evdev_notify_keyval (ClutterVirtualInputDevice *vir
|
||||
int key_count;
|
||||
guint keycode = 0, level = 0, evcode = 0;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
if (!pick_keycode_for_keyval_in_current_group (virtual_device,
|
||||
keyval, &keycode, &level))
|
||||
{
|
||||
@ -382,6 +397,175 @@ clutter_virtual_input_device_evdev_notify_keyval (ClutterVirtualInputDevice *vir
|
||||
apply_level_modifiers (virtual_device, time_us, level, key_state);
|
||||
}
|
||||
|
||||
static void
|
||||
direction_to_discrete (ClutterScrollDirection direction,
|
||||
double *discrete_dx,
|
||||
double *discrete_dy)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case CLUTTER_SCROLL_UP:
|
||||
*discrete_dx = 0.0;
|
||||
*discrete_dy = -1.0;
|
||||
break;
|
||||
case CLUTTER_SCROLL_DOWN:
|
||||
*discrete_dx = 0.0;
|
||||
*discrete_dy = 1.0;
|
||||
break;
|
||||
case CLUTTER_SCROLL_LEFT:
|
||||
*discrete_dx = -1.0;
|
||||
*discrete_dy = 0.0;
|
||||
break;
|
||||
case CLUTTER_SCROLL_RIGHT:
|
||||
*discrete_dx = 1.0;
|
||||
*discrete_dy = 0.0;
|
||||
break;
|
||||
case CLUTTER_SCROLL_SMOOTH:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_evdev_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
double discrete_dx = 0.0, discrete_dy = 0.0;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
direction_to_discrete (direction, &discrete_dx, &discrete_dy);
|
||||
|
||||
clutter_seat_evdev_notify_discrete_scroll (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
discrete_dx, discrete_dy,
|
||||
scroll_source);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_evdev_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
{
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
clutter_seat_evdev_notify_scroll_continuous (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
time_us,
|
||||
dx, dy,
|
||||
scroll_source,
|
||||
CLUTTER_SCROLL_FINISHED_NONE);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_evdev_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
ClutterInputDeviceEvdev *device_evdev =
|
||||
CLUTTER_INPUT_DEVICE_EVDEV (virtual_evdev->device);
|
||||
ClutterTouchState *touch_state;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
touch_state = clutter_input_device_evdev_acquire_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
return;
|
||||
|
||||
touch_state->coords.x = x;
|
||||
touch_state->coords.y = y;
|
||||
|
||||
clutter_seat_evdev_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_evdev_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
ClutterInputDeviceEvdev *device_evdev =
|
||||
CLUTTER_INPUT_DEVICE_EVDEV (virtual_evdev->device);
|
||||
ClutterTouchState *touch_state;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
touch_state = clutter_input_device_evdev_lookup_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
return;
|
||||
|
||||
touch_state->coords.x = x;
|
||||
touch_state->coords.y = y;
|
||||
|
||||
clutter_seat_evdev_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_evdev_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot)
|
||||
{
|
||||
ClutterVirtualInputDeviceEvdev *virtual_evdev =
|
||||
CLUTTER_VIRTUAL_INPUT_DEVICE_EVDEV (virtual_device);
|
||||
ClutterInputDeviceEvdev *device_evdev =
|
||||
CLUTTER_INPUT_DEVICE_EVDEV (virtual_evdev->device);
|
||||
ClutterTouchState *touch_state;
|
||||
|
||||
if (time_us == CLUTTER_CURRENT_TIME)
|
||||
time_us = g_get_monotonic_time ();
|
||||
|
||||
touch_state = clutter_input_device_evdev_lookup_touch_state (device_evdev,
|
||||
device_slot);
|
||||
if (!touch_state)
|
||||
return;
|
||||
|
||||
clutter_seat_evdev_notify_touch_event (virtual_evdev->seat,
|
||||
virtual_evdev->device,
|
||||
CLUTTER_TOUCH_BEGIN,
|
||||
time_us,
|
||||
touch_state->seat_slot,
|
||||
touch_state->coords.x,
|
||||
touch_state->coords.y);
|
||||
|
||||
clutter_input_device_evdev_release_touch_state (device_evdev, touch_state);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_evdev_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -485,6 +669,11 @@ clutter_virtual_input_device_evdev_class_init (ClutterVirtualInputDeviceEvdevCla
|
||||
virtual_input_device_class->notify_button = clutter_virtual_input_device_evdev_notify_button;
|
||||
virtual_input_device_class->notify_key = clutter_virtual_input_device_evdev_notify_key;
|
||||
virtual_input_device_class->notify_keyval = clutter_virtual_input_device_evdev_notify_keyval;
|
||||
virtual_input_device_class->notify_discrete_scroll = clutter_virtual_input_device_evdev_notify_discrete_scroll;
|
||||
virtual_input_device_class->notify_scroll_continuous = clutter_virtual_input_device_evdev_notify_scroll_continuous;
|
||||
virtual_input_device_class->notify_touch_down = clutter_virtual_input_device_evdev_notify_touch_down;
|
||||
virtual_input_device_class->notify_touch_motion = clutter_virtual_input_device_evdev_notify_touch_motion;
|
||||
virtual_input_device_class->notify_touch_up = clutter_virtual_input_device_evdev_notify_touch_up;
|
||||
|
||||
obj_props[PROP_SEAT] = g_param_spec_pointer ("seat",
|
||||
P_("ClutterSeatEvdev"),
|
||||
|
@ -3,8 +3,8 @@ exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@/mutter
|
||||
includedir=@includedir@/mutter
|
||||
|
||||
apiversion=@CLUTTER_API_VERSION@
|
||||
requires=@CLUTTER_REQUIRES@ mutter-cogl-1.0
|
||||
apiversion=@LIBMUTTER_API_VERSION@
|
||||
requires=@CLUTTER_REQUIRES@ mutter-cogl-@LIBMUTTER_API_VERSION@
|
||||
requires_private=@CLUTTER_REQUIRES_PRIVATE@
|
||||
backends=@CLUTTER_BACKENDS@
|
||||
|
||||
@ -17,7 +17,7 @@ cogl_driver=deprecated
|
||||
|
||||
Name: Mutter Clutter
|
||||
Description: Mutter's Clutter Private Library
|
||||
Version: @VERSION@
|
||||
Version: @MUTTER_VERSION@
|
||||
Libs: -L${libdir} -lmutter-clutter-${apiversion}
|
||||
Cflags: -I${includedir}/clutter-${apiversion}
|
||||
Requires: ${requires}
|
||||
|
@ -109,7 +109,6 @@ static const gchar *atom_names[] = {
|
||||
#define N_ATOM_NAMES G_N_ELEMENTS (atom_names)
|
||||
|
||||
/* various flags corresponding to pre init setup calls */
|
||||
static gboolean _want_reset_on_video_memory_purge = FALSE;
|
||||
static gboolean _no_xevent_retrieval = FALSE;
|
||||
static gboolean clutter_enable_xinput = TRUE;
|
||||
static gboolean clutter_enable_argb = FALSE;
|
||||
@ -682,8 +681,7 @@ clutter_backend_x11_get_renderer (ClutterBackend *backend,
|
||||
|
||||
/* set the display object we're using */
|
||||
cogl_xlib_renderer_set_foreign_display (renderer, xdisplay);
|
||||
cogl_xlib_renderer_request_reset_on_video_memory_purge (renderer,
|
||||
_want_reset_on_video_memory_purge);
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
@ -1028,30 +1026,6 @@ clutter_x11_has_event_retrieval (void)
|
||||
return !_no_xevent_retrieval;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_request_reset_on_video_memory_purge:
|
||||
*
|
||||
* If the GL driver supports the NV_robustness_video_memory_purge
|
||||
* extension, this call lets applications request that it gets
|
||||
* initialized, thus allowing cogl_get_graphics_reset_status() to
|
||||
* report memory purged errors if they happen. Checking for the
|
||||
* graphics reset status is the application's responsibility.
|
||||
*
|
||||
* This function can only be called before calling clutter_init().
|
||||
*/
|
||||
void
|
||||
clutter_x11_request_reset_on_video_memory_purge (void)
|
||||
{
|
||||
if (_clutter_context_is_initialized ())
|
||||
{
|
||||
g_warning ("%s() can only be used before calling clutter_init()",
|
||||
G_STRFUNC);
|
||||
return;
|
||||
}
|
||||
|
||||
_want_reset_on_video_memory_purge = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_x11_get_default_screen:
|
||||
*
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "clutter-event-translator.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-xkb-a11y-x11.h"
|
||||
|
||||
enum
|
||||
{
|
||||
@ -136,7 +137,6 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
ClutterTranslateReturn res;
|
||||
ClutterStage *stage;
|
||||
XEvent *xevent;
|
||||
int window_scale;
|
||||
|
||||
manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (translator);
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||
@ -152,8 +152,6 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage));
|
||||
|
||||
window_scale = stage_x11->scale_factor;
|
||||
|
||||
event->any.stage = stage;
|
||||
|
||||
res = CLUTTER_TRANSLATE_CONTINUE;
|
||||
@ -226,8 +224,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
event->scroll.direction = CLUTTER_SCROLL_RIGHT;
|
||||
|
||||
event->scroll.time = xevent->xbutton.time;
|
||||
event->scroll.x = xevent->xbutton.x / window_scale;
|
||||
event->scroll.y = xevent->xbutton.y / window_scale;
|
||||
event->scroll.x = xevent->xbutton.x;
|
||||
event->scroll.y = xevent->xbutton.y;
|
||||
event->scroll.modifier_state = xevent->xbutton.state;
|
||||
event->scroll.axes = NULL;
|
||||
break;
|
||||
@ -235,8 +233,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
default:
|
||||
event->button.type = event->type = CLUTTER_BUTTON_PRESS;
|
||||
event->button.time = xevent->xbutton.time;
|
||||
event->button.x = xevent->xbutton.x / window_scale;
|
||||
event->button.y = xevent->xbutton.y / window_scale;
|
||||
event->button.x = xevent->xbutton.x;
|
||||
event->button.y = xevent->xbutton.y;
|
||||
event->button.modifier_state = xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
event->button.axes = NULL;
|
||||
@ -269,8 +267,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
|
||||
event->button.time = xevent->xbutton.time;
|
||||
event->button.x = xevent->xbutton.x / window_scale;
|
||||
event->button.y = xevent->xbutton.y / window_scale;
|
||||
event->button.x = xevent->xbutton.x;
|
||||
event->button.y = xevent->xbutton.y;
|
||||
event->button.modifier_state = xevent->xbutton.state;
|
||||
event->button.button = xevent->xbutton.button;
|
||||
event->button.axes = NULL;
|
||||
@ -287,8 +285,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
event->motion.type = event->type = CLUTTER_MOTION;
|
||||
event->motion.time = xevent->xmotion.time;
|
||||
event->motion.x = xevent->xmotion.x / window_scale;
|
||||
event->motion.y = xevent->xmotion.y / window_scale;
|
||||
event->motion.x = xevent->xmotion.x;
|
||||
event->motion.y = xevent->xmotion.y;
|
||||
event->motion.modifier_state = xevent->xmotion.state;
|
||||
event->motion.axes = NULL;
|
||||
clutter_event_set_device (event, manager_x11->core_pointer);
|
||||
@ -301,8 +299,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
event->crossing.type = CLUTTER_ENTER;
|
||||
event->crossing.time = xevent->xcrossing.time;
|
||||
event->crossing.x = xevent->xcrossing.x / window_scale;
|
||||
event->crossing.y = xevent->xcrossing.y / window_scale;
|
||||
event->crossing.x = xevent->xcrossing.x;
|
||||
event->crossing.y = xevent->xcrossing.y;
|
||||
event->crossing.source = CLUTTER_ACTOR (stage);
|
||||
event->crossing.related = NULL;
|
||||
clutter_event_set_device (event, manager_x11->core_pointer);
|
||||
@ -327,8 +325,8 @@ clutter_device_manager_x11_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
event->crossing.type = CLUTTER_LEAVE;
|
||||
event->crossing.time = xevent->xcrossing.time;
|
||||
event->crossing.x = xevent->xcrossing.x / window_scale;
|
||||
event->crossing.y = xevent->xcrossing.y / window_scale;
|
||||
event->crossing.x = xevent->xcrossing.x;
|
||||
event->crossing.y = xevent->xcrossing.y;
|
||||
event->crossing.source = CLUTTER_ACTOR (stage);
|
||||
event->crossing.related = NULL;
|
||||
clutter_event_set_device (event, manager_x11->core_pointer);
|
||||
@ -355,9 +353,11 @@ static void
|
||||
clutter_device_manager_x11_constructed (GObject *gobject)
|
||||
{
|
||||
ClutterDeviceManagerX11 *manager_x11;
|
||||
ClutterDeviceManager *manager;
|
||||
ClutterBackendX11 *backend_x11;
|
||||
|
||||
manager_x11 = CLUTTER_DEVICE_MANAGER_X11 (gobject);
|
||||
manager = CLUTTER_DEVICE_MANAGER (gobject);
|
||||
|
||||
g_object_get (gobject, "backend", &backend_x11, NULL);
|
||||
g_assert (backend_x11 != NULL);
|
||||
@ -392,6 +392,8 @@ clutter_device_manager_x11_constructed (GObject *gobject)
|
||||
_clutter_input_device_set_associated_device (manager_x11->core_keyboard,
|
||||
manager_x11->core_pointer);
|
||||
|
||||
clutter_device_manager_x11_a11y_init (manager);
|
||||
|
||||
if (G_OBJECT_CLASS (clutter_device_manager_x11_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (clutter_device_manager_x11_parent_class)->constructed (gobject);
|
||||
}
|
||||
@ -488,6 +490,13 @@ clutter_device_manager_x11_create_virtual_device (ClutterDeviceManager *device_
|
||||
return g_object_new (CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_X11, NULL);
|
||||
}
|
||||
|
||||
static ClutterVirtualDeviceType
|
||||
clutter_device_manager_x11_get_supported_virtual_device_types (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD |
|
||||
CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_x11_set_property (GObject *gobject,
|
||||
guint prop_id,
|
||||
@ -535,6 +544,8 @@ clutter_device_manager_x11_class_init (ClutterDeviceManagerX11Class *klass)
|
||||
manager_class->get_core_device = clutter_device_manager_x11_get_core_device;
|
||||
manager_class->get_device = clutter_device_manager_x11_get_device;
|
||||
manager_class->create_virtual_device = clutter_device_manager_x11_create_virtual_device;
|
||||
manager_class->get_supported_virtual_device_types = clutter_device_manager_x11_get_supported_virtual_device_types;
|
||||
manager_class->apply_kbd_a11y_settings = clutter_device_manager_x11_apply_kbd_a11y_settings;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
#include "clutter-backend-x11.h"
|
||||
#include "clutter-input-device-xi2.h"
|
||||
#include "clutter-input-device-tool-xi2.h"
|
||||
#include "clutter-virtual-input-device-x11.h"
|
||||
#include "clutter-stage-x11.h"
|
||||
|
||||
#include "clutter-backend.h"
|
||||
@ -38,6 +40,7 @@
|
||||
#include "clutter-event-translator.h"
|
||||
#include "clutter-stage-private.h"
|
||||
#include "clutter-private.h"
|
||||
#include "clutter-xkb-a11y-x11.h"
|
||||
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
@ -64,6 +67,14 @@ static const char *clutter_input_axis_atom_names[] = {
|
||||
|
||||
#define N_AXIS_ATOMS G_N_ELEMENTS (clutter_input_axis_atom_names)
|
||||
|
||||
enum {
|
||||
PAD_AXIS_FIRST = 3, /* First axes are always x/y/pressure, ignored in pads */
|
||||
PAD_AXIS_STRIP1 = PAD_AXIS_FIRST,
|
||||
PAD_AXIS_STRIP2,
|
||||
PAD_AXIS_RING1,
|
||||
PAD_AXIS_RING2,
|
||||
};
|
||||
|
||||
static Atom clutter_input_axis_atoms[N_AXIS_ATOMS] = { 0, };
|
||||
|
||||
static void clutter_event_translator_iface_init (ClutterEventTranslatorIface *iface);
|
||||
@ -357,6 +368,36 @@ get_device_node_path (ClutterBackendX11 *backend_x11,
|
||||
return node_path;
|
||||
}
|
||||
|
||||
static void
|
||||
get_pad_features (XIDeviceInfo *info,
|
||||
guint *n_rings,
|
||||
guint *n_strips)
|
||||
{
|
||||
gint i, rings = 0, strips = 0;
|
||||
|
||||
for (i = PAD_AXIS_FIRST; i < info->num_classes; i++)
|
||||
{
|
||||
XIValuatorClassInfo *valuator = (XIValuatorClassInfo*) info->classes[i];
|
||||
int axis = valuator->number;
|
||||
|
||||
if (valuator->type != XIValuatorClass)
|
||||
continue;
|
||||
if (valuator->max <= 1)
|
||||
continue;
|
||||
|
||||
/* Ring/strip axes are fixed in pad devices as handled by the
|
||||
* wacom driver. Match those to detect pad features.
|
||||
*/
|
||||
if (axis == PAD_AXIS_STRIP1 || axis == PAD_AXIS_STRIP2)
|
||||
strips++;
|
||||
else if (axis == PAD_AXIS_RING1 || axis == PAD_AXIS_RING2)
|
||||
rings++;
|
||||
}
|
||||
|
||||
*n_rings = rings;
|
||||
*n_strips = strips;
|
||||
}
|
||||
|
||||
static ClutterInputDevice *
|
||||
create_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
ClutterBackendX11 *backend_x11,
|
||||
@ -366,7 +407,7 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
ClutterInputDevice *retval;
|
||||
ClutterInputMode mode;
|
||||
gboolean is_enabled;
|
||||
guint num_touches = 0;
|
||||
guint num_touches = 0, num_rings = 0, num_strips = 0;
|
||||
gchar *vendor_id = NULL, *product_id = NULL, *node_path = NULL;
|
||||
|
||||
if (info->use == XIMasterKeyboard || info->use == XISlaveKeyboard)
|
||||
@ -394,6 +435,8 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
source = CLUTTER_ERASER_DEVICE;
|
||||
else if (strstr (name, "cursor") != NULL)
|
||||
source = CLUTTER_CURSOR_DEVICE;
|
||||
else if (strstr (name, " pad") != NULL)
|
||||
source = CLUTTER_PAD_DEVICE;
|
||||
else if (strstr (name, "wacom") != NULL || strstr (name, "pen") != NULL)
|
||||
source = CLUTTER_PEN_DEVICE;
|
||||
else if (strstr (name, "touchpad") != NULL)
|
||||
@ -432,6 +475,12 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
node_path = get_device_node_path (backend_x11, info);
|
||||
}
|
||||
|
||||
if (source == CLUTTER_PAD_DEVICE)
|
||||
{
|
||||
is_enabled = TRUE;
|
||||
get_pad_features (info, &num_rings, &num_strips);
|
||||
}
|
||||
|
||||
retval = g_object_new (CLUTTER_TYPE_INPUT_DEVICE_XI2,
|
||||
"name", info->name,
|
||||
"id", info->deviceid,
|
||||
@ -444,13 +493,23 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
"vendor-id", vendor_id,
|
||||
"product-id", product_id,
|
||||
"device-node", node_path,
|
||||
"n-rings", num_rings,
|
||||
"n-strips", num_strips,
|
||||
"n-mode-groups", MAX (num_rings, num_strips),
|
||||
NULL);
|
||||
|
||||
translate_device_classes (backend_x11->xdpy, retval,
|
||||
info->classes,
|
||||
info->num_classes);
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
if (source == CLUTTER_PAD_DEVICE)
|
||||
clutter_input_device_xi2_ensure_wacom_info (retval, manager_xi2->wacom_db);
|
||||
#endif
|
||||
|
||||
g_free (vendor_id);
|
||||
g_free (product_id);
|
||||
g_free (node_path);
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Created device '%s' (id: %d, has-cursor: %s)",
|
||||
info->name,
|
||||
@ -460,6 +519,46 @@ create_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
pad_passive_button_grab (ClutterInputDevice *device)
|
||||
{
|
||||
XIGrabModifiers xi_grab_mods = { XIAnyModifier, };
|
||||
XIEventMask xi_event_mask;
|
||||
gint device_id, rc;
|
||||
|
||||
device_id = clutter_input_device_get_device_id (device);
|
||||
|
||||
xi_event_mask.deviceid = device_id;
|
||||
xi_event_mask.mask_len = XIMaskLen (XI_LASTEVENT);
|
||||
xi_event_mask.mask = g_new0 (unsigned char, xi_event_mask.mask_len);
|
||||
|
||||
XISetMask (xi_event_mask.mask, XI_Motion);
|
||||
XISetMask (xi_event_mask.mask, XI_ButtonPress);
|
||||
XISetMask (xi_event_mask.mask, XI_ButtonRelease);
|
||||
|
||||
clutter_x11_trap_x_errors ();
|
||||
rc = XIGrabButton (clutter_x11_get_default_display (),
|
||||
device_id, XIAnyButton,
|
||||
clutter_x11_get_root_window (), None,
|
||||
XIGrabModeSync, XIGrabModeSync,
|
||||
True, &xi_event_mask, 1, &xi_grab_mods);
|
||||
if (rc != 0)
|
||||
{
|
||||
g_warning ("Could not passively grab pad device: %s",
|
||||
clutter_input_device_get_device_name (device));
|
||||
}
|
||||
else
|
||||
{
|
||||
XIAllowEvents (clutter_x11_get_default_display (),
|
||||
device_id, XIAsyncDevice,
|
||||
CLUTTER_CURRENT_TIME);
|
||||
}
|
||||
|
||||
clutter_x11_untrap_x_errors ();
|
||||
|
||||
g_free (xi_event_mask.mask);
|
||||
}
|
||||
|
||||
static ClutterInputDevice *
|
||||
add_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
ClutterBackendX11 *backend_x11,
|
||||
@ -494,6 +593,9 @@ add_device (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
g_warning ("Unhandled device: %s",
|
||||
clutter_input_device_get_device_name (device));
|
||||
|
||||
if (clutter_input_device_get_device_type (device) == CLUTTER_PAD_DEVICE)
|
||||
pad_passive_button_grab (device);
|
||||
|
||||
/* relationships between devices and signal emissions are not
|
||||
* necessary while we're constructing the device manager instance
|
||||
*/
|
||||
@ -800,6 +902,54 @@ translate_axes (ClutterInputDevice *device,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
translate_pad_axis (ClutterInputDevice *device,
|
||||
XIValuatorState *valuators,
|
||||
ClutterEventType *evtype,
|
||||
guint *number,
|
||||
gdouble *value)
|
||||
{
|
||||
double *values;
|
||||
gint i;
|
||||
|
||||
values = valuators->values;
|
||||
|
||||
for (i = PAD_AXIS_FIRST; i < valuators->mask_len * 8; i++)
|
||||
{
|
||||
gdouble val;
|
||||
guint axis_number = 0;
|
||||
|
||||
if (!XIMaskIsSet (valuators->mask, i))
|
||||
continue;
|
||||
|
||||
val = *values++;
|
||||
if (val <= 0)
|
||||
continue;
|
||||
|
||||
_clutter_input_device_translate_axis (device, i, val, value);
|
||||
|
||||
if (i == PAD_AXIS_RING1 || i == PAD_AXIS_RING2)
|
||||
{
|
||||
*evtype = CLUTTER_PAD_RING;
|
||||
(*value) *= 360.0;
|
||||
}
|
||||
else if (i == PAD_AXIS_STRIP1 || i == PAD_AXIS_STRIP2)
|
||||
{
|
||||
*evtype = CLUTTER_PAD_STRIP;
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
if (i == PAD_AXIS_STRIP2 || i == PAD_AXIS_RING2)
|
||||
axis_number++;
|
||||
|
||||
*number = axis_number;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
translate_coords (ClutterStageX11 *stage_x11,
|
||||
gdouble event_x,
|
||||
@ -814,8 +964,8 @@ translate_coords (ClutterStageX11 *stage_x11,
|
||||
|
||||
clutter_actor_get_size (stage, &stage_width, &stage_height);
|
||||
|
||||
*x_out = CLAMP (event_x / stage_x11->scale_factor, 0, stage_width);
|
||||
*y_out = CLAMP (event_y / stage_x11->scale_factor, 0, stage_height);
|
||||
*x_out = CLAMP (event_x, 0, stage_width);
|
||||
*y_out = CLAMP (event_y, 0, stage_height);
|
||||
}
|
||||
|
||||
static gdouble
|
||||
@ -906,6 +1056,132 @@ clutter_device_manager_xi2_select_stage_events (ClutterDeviceManager *manager,
|
||||
g_free (mask);
|
||||
}
|
||||
|
||||
static guint
|
||||
device_get_tool_serial (ClutterBackendX11 *backend_x11,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
gulong nitems, bytes_after;
|
||||
guint32 *data = NULL;
|
||||
guint serial_id = 0;
|
||||
int rc, format;
|
||||
Atom type;
|
||||
Atom prop;
|
||||
|
||||
prop = XInternAtom (backend_x11->xdpy, "Wacom Serial IDs", True);
|
||||
if (prop == None)
|
||||
return 0;
|
||||
|
||||
clutter_x11_trap_x_errors ();
|
||||
rc = XIGetProperty (backend_x11->xdpy,
|
||||
clutter_input_device_get_device_id (device),
|
||||
prop, 0, 4, FALSE, XA_INTEGER, &type, &format, &nitems, &bytes_after,
|
||||
(guchar **) &data);
|
||||
clutter_x11_untrap_x_errors ();
|
||||
|
||||
if (rc == Success && type == XA_INTEGER && format == 32 && nitems >= 4)
|
||||
serial_id = data[3];
|
||||
|
||||
XFree (data);
|
||||
|
||||
return serial_id;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_property_event (ClutterDeviceManagerXI2 *manager_xi2,
|
||||
XIEvent *event)
|
||||
{
|
||||
XIPropertyEvent *xev = (XIPropertyEvent *) event;
|
||||
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||
Atom serial_ids_prop = XInternAtom (backend_x11->xdpy, "Wacom Serial IDs", True);
|
||||
ClutterInputDevice *device;
|
||||
|
||||
device = g_hash_table_lookup (manager_xi2->devices_by_id,
|
||||
GINT_TO_POINTER (xev->deviceid));
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
if (xev->property == serial_ids_prop)
|
||||
{
|
||||
ClutterInputDeviceTool *tool = NULL;
|
||||
ClutterInputDeviceToolType type;
|
||||
guint serial_id;
|
||||
|
||||
serial_id = device_get_tool_serial (backend_x11, device);
|
||||
|
||||
if (serial_id != 0)
|
||||
{
|
||||
tool = g_hash_table_lookup (manager_xi2->tools_by_serial,
|
||||
GUINT_TO_POINTER (serial_id));
|
||||
if (!tool)
|
||||
{
|
||||
type = clutter_input_device_get_device_type (device) == CLUTTER_ERASER_DEVICE ?
|
||||
CLUTTER_INPUT_DEVICE_TOOL_ERASER : CLUTTER_INPUT_DEVICE_TOOL_PEN;
|
||||
tool = clutter_input_device_tool_xi2_new (serial_id, type);
|
||||
g_hash_table_insert (manager_xi2->tools_by_serial,
|
||||
GUINT_TO_POINTER (serial_id),
|
||||
tool);
|
||||
}
|
||||
}
|
||||
|
||||
clutter_input_device_xi2_update_tool (device, tool);
|
||||
g_signal_emit_by_name (manager_xi2, "tool-changed", device, tool);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
translate_pad_event (ClutterEvent *event,
|
||||
XIDeviceEvent *xev,
|
||||
ClutterInputDevice *device)
|
||||
{
|
||||
gdouble value;
|
||||
guint number, mode = 0;
|
||||
|
||||
if (!translate_pad_axis (device, &xev->valuators,
|
||||
&event->any.type,
|
||||
&number, &value))
|
||||
return FALSE;
|
||||
|
||||
/* When touching a ring/strip a first XI_Motion event
|
||||
* is generated. Use it to reset the pad state, so
|
||||
* later events actually have a directionality.
|
||||
*/
|
||||
if (xev->evtype == XI_Motion)
|
||||
value = -1;
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
mode = clutter_input_device_xi2_get_pad_group_mode (device, number);
|
||||
#endif
|
||||
|
||||
if (event->any.type == CLUTTER_PAD_RING)
|
||||
{
|
||||
event->pad_ring.ring_number = number;
|
||||
event->pad_ring.angle = value;
|
||||
event->pad_ring.mode = mode;
|
||||
}
|
||||
else
|
||||
{
|
||||
event->pad_strip.strip_number = number;
|
||||
event->pad_strip.value = value;
|
||||
event->pad_strip.mode = mode;
|
||||
}
|
||||
|
||||
event->any.time = xev->time;
|
||||
clutter_event_set_device (event, device);
|
||||
clutter_event_set_source_device (event, device);
|
||||
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"%s: win:0x%x, device:%d '%s', time:%d "
|
||||
"(value:%f)",
|
||||
event->any.type == CLUTTER_PAD_RING
|
||||
? "pad ring "
|
||||
: "pad strip",
|
||||
(unsigned int) xev->event,
|
||||
device->id,
|
||||
device->device_name,
|
||||
event->any.time, value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static ClutterTranslateReturn
|
||||
clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
gpointer native,
|
||||
@ -937,7 +1213,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
return CLUTTER_TRANSLATE_REMOVE;
|
||||
|
||||
if (!(xi_event->evtype == XI_HierarchyChanged ||
|
||||
xi_event->evtype == XI_DeviceChanged))
|
||||
xi_event->evtype == XI_DeviceChanged ||
|
||||
xi_event->evtype == XI_PropertyEvent))
|
||||
{
|
||||
stage = get_event_stage (translator, xi_event);
|
||||
if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage))
|
||||
@ -1078,6 +1355,66 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
stage != NULL)
|
||||
_clutter_input_device_set_stage (device, stage);
|
||||
|
||||
if (clutter_input_device_get_device_type (source_device) == CLUTTER_PAD_DEVICE)
|
||||
{
|
||||
/* We got these events because of the passive button grab */
|
||||
XIAllowEvents (clutter_x11_get_default_display (),
|
||||
xev->sourceid,
|
||||
XIAsyncDevice,
|
||||
xev->time);
|
||||
|
||||
event->any.stage = stage;
|
||||
|
||||
if (xev->detail >= 4 && xev->detail <= 7)
|
||||
{
|
||||
retval = CLUTTER_TRANSLATE_REMOVE;
|
||||
|
||||
if (xi_event->evtype == XI_ButtonPress &&
|
||||
translate_pad_event (event, xev, source_device))
|
||||
retval = CLUTTER_TRANSLATE_QUEUE;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
event->any.type =
|
||||
(xi_event->evtype == XI_ButtonPress) ? CLUTTER_PAD_BUTTON_PRESS
|
||||
: CLUTTER_PAD_BUTTON_RELEASE;
|
||||
event->any.time = xev->time;
|
||||
|
||||
/* The 4-7 button range is taken as non-existent on pad devices,
|
||||
* let the buttons above that take over this range.
|
||||
*/
|
||||
if (xev->detail > 7)
|
||||
xev->detail -= 4;
|
||||
|
||||
/* Pad buttons are 0-indexed */
|
||||
event->pad_button.button = xev->detail - 1;
|
||||
#ifdef HAVE_LIBWACOM
|
||||
clutter_input_device_xi2_update_pad_state (device,
|
||||
event->pad_button.button,
|
||||
(xi_event->evtype == XI_ButtonPress),
|
||||
&event->pad_button.group,
|
||||
&event->pad_button.mode);
|
||||
#endif
|
||||
clutter_event_set_device (event, device);
|
||||
clutter_event_set_source_device (event, source_device);
|
||||
|
||||
CLUTTER_NOTE (EVENT,
|
||||
"%s: win:0x%x, device:%d '%s', time:%d "
|
||||
"(button:%d)",
|
||||
event->any.type == CLUTTER_BUTTON_PRESS
|
||||
? "pad button press "
|
||||
: "pad button release",
|
||||
(unsigned int) stage_x11->xwin,
|
||||
device->id,
|
||||
device->device_name,
|
||||
event->any.time,
|
||||
event->pad_button.button);
|
||||
|
||||
retval = CLUTTER_TRANSLATE_QUEUE;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (xev->detail)
|
||||
{
|
||||
case 4:
|
||||
@ -1157,6 +1494,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
clutter_event_set_source_device (event, source_device);
|
||||
clutter_event_set_device (event, device);
|
||||
clutter_event_set_device_tool (event,
|
||||
clutter_input_device_xi2_get_current_tool (source_device));
|
||||
|
||||
event->button.axes = translate_axes (event->button.device,
|
||||
event->button.x,
|
||||
@ -1214,6 +1553,15 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
device = g_hash_table_lookup (manager_xi2->devices_by_id,
|
||||
GINT_TO_POINTER (xev->deviceid));
|
||||
|
||||
if (clutter_input_device_get_device_type (source_device) == CLUTTER_PAD_DEVICE)
|
||||
{
|
||||
event->any.stage = stage;
|
||||
|
||||
if (translate_pad_event (event, xev, source_device))
|
||||
retval = CLUTTER_TRANSLATE_QUEUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the stage for core events coming out of nowhere (see bug #684509) */
|
||||
if (clutter_input_device_get_device_mode (device) == CLUTTER_INPUT_MODE_MASTER &&
|
||||
clutter_input_device_get_pointer_stage (device) == NULL &&
|
||||
@ -1265,6 +1613,8 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
|
||||
clutter_event_set_source_device (event, source_device);
|
||||
clutter_event_set_device (event, device);
|
||||
clutter_event_set_device_tool (event,
|
||||
clutter_input_device_xi2_get_current_tool (source_device));
|
||||
|
||||
event->motion.axes = translate_axes (event->motion.device,
|
||||
event->motion.x,
|
||||
@ -1466,6 +1816,10 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator,
|
||||
case XI_FocusOut:
|
||||
retval = CLUTTER_TRANSLATE_CONTINUE;
|
||||
break;
|
||||
case XI_PropertyEvent:
|
||||
handle_property_event (manager_xi2, xi_event);
|
||||
retval = CLUTTER_TRANSLATE_CONTINUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -1643,6 +1997,7 @@ clutter_device_manager_xi2_constructed (GObject *gobject)
|
||||
|
||||
XISetMask (mask, XI_HierarchyChanged);
|
||||
XISetMask (mask, XI_DeviceChanged);
|
||||
XISetMask (mask, XI_PropertyEvent);
|
||||
|
||||
event_mask.deviceid = XIAllDevices;
|
||||
event_mask.mask_len = sizeof (mask);
|
||||
@ -1654,6 +2009,8 @@ clutter_device_manager_xi2_constructed (GObject *gobject)
|
||||
|
||||
XSync (backend_x11->xdpy, False);
|
||||
|
||||
clutter_device_manager_x11_a11y_init (manager);
|
||||
|
||||
if (G_OBJECT_CLASS (clutter_device_manager_xi2_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (clutter_device_manager_xi2_parent_class)->constructed (gobject);
|
||||
}
|
||||
@ -1678,6 +2035,23 @@ clutter_device_manager_xi2_set_property (GObject *gobject,
|
||||
}
|
||||
}
|
||||
|
||||
static ClutterVirtualInputDevice *
|
||||
clutter_device_manager_xi2_create_virtual_device (ClutterDeviceManager *manager,
|
||||
ClutterInputDeviceType device_type)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_VIRTUAL_INPUT_DEVICE_X11,
|
||||
"device-manager", manager,
|
||||
"device-type", device_type,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static ClutterVirtualDeviceType
|
||||
clutter_device_manager_xi2_get_supported_virtual_device_types (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
return (CLUTTER_VIRTUAL_DEVICE_TYPE_KEYBOARD |
|
||||
CLUTTER_VIRTUAL_DEVICE_TYPE_POINTER);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_device_manager_xi2_class_init (ClutterDeviceManagerXI2Class *klass)
|
||||
{
|
||||
@ -1705,6 +2079,9 @@ clutter_device_manager_xi2_class_init (ClutterDeviceManagerXI2Class *klass)
|
||||
manager_class->get_core_device = clutter_device_manager_xi2_get_core_device;
|
||||
manager_class->get_device = clutter_device_manager_xi2_get_device;
|
||||
manager_class->select_stage_events = clutter_device_manager_xi2_select_stage_events;
|
||||
manager_class->create_virtual_device = clutter_device_manager_xi2_create_virtual_device;
|
||||
manager_class->get_supported_virtual_device_types = clutter_device_manager_xi2_get_supported_virtual_device_types;
|
||||
manager_class->apply_kbd_a11y_settings = clutter_device_manager_x11_apply_kbd_a11y_settings;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1713,4 +2090,10 @@ clutter_device_manager_xi2_init (ClutterDeviceManagerXI2 *self)
|
||||
self->devices_by_id = g_hash_table_new_full (NULL, NULL,
|
||||
NULL,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
self->tools_by_serial = g_hash_table_new_full (NULL, NULL, NULL,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
self->wacom_db = libwacom_database_new ();
|
||||
#endif
|
||||
}
|
||||
|
@ -26,6 +26,10 @@
|
||||
|
||||
#include <clutter/clutter-device-manager.h>
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
#include <libwacom/libwacom.h>
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_DEVICE_MANAGER_XI2 (_clutter_device_manager_xi2_get_type ())
|
||||
@ -43,6 +47,7 @@ struct _ClutterDeviceManagerXI2
|
||||
ClutterDeviceManager parent_instance;
|
||||
|
||||
GHashTable *devices_by_id;
|
||||
GHashTable *tools_by_serial;
|
||||
|
||||
GSList *all_devices;
|
||||
|
||||
@ -50,6 +55,10 @@ struct _ClutterDeviceManagerXI2
|
||||
GList *slave_devices;
|
||||
|
||||
int opcode;
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
WacomDeviceDatabase *wacom_db;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _ClutterDeviceManagerXI2Class
|
||||
|
51
clutter/clutter/x11/clutter-input-device-tool-xi2.c
Normal file
51
clutter/clutter/x11/clutter-input-device-tool-xi2.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright © 2016 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "clutter-build-config.h"
|
||||
#endif
|
||||
|
||||
#include "clutter-input-device-tool-xi2.h"
|
||||
|
||||
G_DEFINE_TYPE (ClutterInputDeviceToolXI2, clutter_input_device_tool_xi2,
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL)
|
||||
|
||||
static void
|
||||
clutter_input_device_tool_xi2_class_init (ClutterInputDeviceToolXI2Class *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_device_tool_xi2_init (ClutterInputDeviceToolXI2 *tool)
|
||||
{
|
||||
}
|
||||
|
||||
ClutterInputDeviceTool *
|
||||
clutter_input_device_tool_xi2_new (guint serial,
|
||||
ClutterInputDeviceToolType type)
|
||||
{
|
||||
return g_object_new (CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2,
|
||||
"type", type,
|
||||
"serial", serial,
|
||||
NULL);
|
||||
}
|
74
clutter/clutter/x11/clutter-input-device-tool-xi2.h
Normal file
74
clutter/clutter/x11/clutter-input-device-tool-xi2.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Clutter.
|
||||
*
|
||||
* An OpenGL based 'interactive canvas' library.
|
||||
*
|
||||
* Copyright © 2016 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Carlos Garnacho <carlosg@gnome.org>
|
||||
*/
|
||||
|
||||
#ifndef __CLUTTER_INPUT_DEVICE_XI2_TOOL_H__
|
||||
#define __CLUTTER_INPUT_DEVICE_XI2_TOOL_H__
|
||||
|
||||
#include <clutter/clutter-input-device-tool.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2 (clutter_input_device_tool_xi2_get_type ())
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_TOOL_XI2(o) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((o), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2, ClutterInputDeviceToolXI2))
|
||||
|
||||
#define CLUTTER_IS_INPUT_DEVICE_TOOL_XI2(o) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((o), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2))
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_TOOL_XI2_CLASS(c) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((c), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2, ClutterInputDeviceToolXI2Class))
|
||||
|
||||
#define CLUTTER_IS_INPUT_DEVICE_TOOL_XI2_CLASS(c) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((c), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2))
|
||||
|
||||
#define CLUTTER_INPUT_DEVICE_TOOL_XI2_GET_CLASS(o) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((o), \
|
||||
CLUTTER_TYPE_INPUT_DEVICE_TOOL_XI2, ClutterInputDeviceToolXI2Class))
|
||||
|
||||
typedef struct _ClutterInputDeviceToolXI2 ClutterInputDeviceToolXI2;
|
||||
typedef struct _ClutterInputDeviceToolXI2Class ClutterInputDeviceToolXI2Class;
|
||||
|
||||
struct _ClutterInputDeviceToolXI2
|
||||
{
|
||||
ClutterInputDeviceTool parent_instance;
|
||||
struct libinput_tablet_tool *tool;
|
||||
};
|
||||
|
||||
struct _ClutterInputDeviceToolXI2Class
|
||||
{
|
||||
ClutterInputDeviceToolClass parent_class;
|
||||
};
|
||||
|
||||
GType clutter_input_device_tool_xi2_get_type (void) G_GNUC_CONST;
|
||||
|
||||
ClutterInputDeviceTool * clutter_input_device_tool_xi2_new (guint serial,
|
||||
ClutterInputDeviceToolType type);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_INPUT_DEVICE_XI2_TOOL_H__ */
|
@ -44,6 +44,12 @@ struct _ClutterInputDeviceXI2
|
||||
ClutterInputDevice device;
|
||||
|
||||
gint device_id;
|
||||
ClutterInputDeviceTool *current_tool;
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
WacomDevice *wacom_device;
|
||||
GArray *group_modes;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define N_BUTTONS 5
|
||||
@ -63,6 +69,15 @@ clutter_input_device_xi2_constructed (GObject *gobject)
|
||||
|
||||
if (G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->constructed)
|
||||
G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->constructed (gobject);
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
if (clutter_input_device_get_device_type (CLUTTER_INPUT_DEVICE (gobject)) == CLUTTER_PAD_DEVICE)
|
||||
{
|
||||
device_xi2->group_modes = g_array_new (FALSE, TRUE, sizeof (guint));
|
||||
g_array_set_size (device_xi2->group_modes,
|
||||
clutter_input_device_get_n_mode_groups (CLUTTER_INPUT_DEVICE (gobject)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -79,6 +94,92 @@ clutter_input_device_xi2_keycode_to_evdev (ClutterInputDevice *device,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
clutter_input_device_xi2_is_grouped (ClutterInputDevice *device,
|
||||
ClutterInputDevice *other_device)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_device_xi2_finalize (GObject *object)
|
||||
{
|
||||
#ifdef HAVE_LIBWACOM
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (object);
|
||||
|
||||
if (device_xi2->wacom_device)
|
||||
libwacom_destroy (device_xi2->wacom_device);
|
||||
|
||||
if (device_xi2->group_modes)
|
||||
g_array_unref (device_xi2->group_modes);
|
||||
#endif
|
||||
|
||||
G_OBJECT_CLASS (clutter_input_device_xi2_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static gint
|
||||
clutter_input_device_xi2_get_group_n_modes (ClutterInputDevice *device,
|
||||
gint group)
|
||||
{
|
||||
#ifdef HAVE_LIBWACOM
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
|
||||
if (device_xi2->wacom_device)
|
||||
{
|
||||
if (group == 0)
|
||||
{
|
||||
if (libwacom_has_ring (device_xi2->wacom_device))
|
||||
return libwacom_get_ring_num_modes (device_xi2->wacom_device);
|
||||
else if (libwacom_get_num_strips (device_xi2->wacom_device) >= 1)
|
||||
return libwacom_get_strips_num_modes (device_xi2->wacom_device);
|
||||
}
|
||||
else if (group == 1)
|
||||
{
|
||||
if (libwacom_has_ring2 (device_xi2->wacom_device))
|
||||
return libwacom_get_ring2_num_modes (device_xi2->wacom_device);
|
||||
else if (libwacom_get_num_strips (device_xi2->wacom_device) >= 2)
|
||||
return libwacom_get_strips_num_modes (device_xi2->wacom_device);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
static int
|
||||
clutter_input_device_xi2_get_button_group (ClutterInputDevice *device,
|
||||
guint button)
|
||||
{
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
|
||||
if (device_xi2->wacom_device)
|
||||
{
|
||||
if (button >= libwacom_get_num_buttons (device_xi2->wacom_device))
|
||||
return -1;
|
||||
|
||||
return libwacom_get_button_led_group (device_xi2->wacom_device,
|
||||
'A' + button);
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
clutter_input_device_xi2_is_mode_switch_button (ClutterInputDevice *device,
|
||||
guint group,
|
||||
guint button)
|
||||
{
|
||||
int button_group = -1;
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
button_group = clutter_input_device_xi2_get_button_group (device, button);
|
||||
#endif
|
||||
|
||||
return button_group == (int) group;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
|
||||
{
|
||||
@ -86,8 +187,12 @@ clutter_input_device_xi2_class_init (ClutterInputDeviceXI2Class *klass)
|
||||
ClutterInputDeviceClass *device_class = CLUTTER_INPUT_DEVICE_CLASS (klass);
|
||||
|
||||
gobject_class->constructed = clutter_input_device_xi2_constructed;
|
||||
gobject_class->finalize = clutter_input_device_xi2_finalize;
|
||||
|
||||
device_class->keycode_to_evdev = clutter_input_device_xi2_keycode_to_evdev;
|
||||
device_class->is_grouped = clutter_input_device_xi2_is_grouped;
|
||||
device_class->get_group_n_modes = clutter_input_device_xi2_get_group_n_modes;
|
||||
device_class->is_mode_switch_button = clutter_input_device_xi2_is_mode_switch_button;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -172,3 +277,81 @@ _clutter_input_device_xi2_translate_state (ClutterEvent *event,
|
||||
|
||||
_clutter_event_set_state_full (event, button, base, latched, locked, effective);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_device_xi2_update_tool (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool)
|
||||
{
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
g_set_object (&device_xi2->current_tool, tool);
|
||||
}
|
||||
|
||||
ClutterInputDeviceTool *
|
||||
clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device)
|
||||
{
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
return device_xi2->current_tool;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
void
|
||||
clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device,
|
||||
WacomDeviceDatabase *wacom_db)
|
||||
{
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
const gchar *node_path;
|
||||
|
||||
node_path = clutter_input_device_get_device_node (device);
|
||||
device_xi2->wacom_device = libwacom_new_from_path (wacom_db, node_path,
|
||||
WFALLBACK_NONE, NULL);
|
||||
}
|
||||
|
||||
guint
|
||||
clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device,
|
||||
guint group)
|
||||
{
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
|
||||
if (group >= device_xi2->group_modes->len)
|
||||
return 0;
|
||||
|
||||
return g_array_index (device_xi2->group_modes, guint, group);
|
||||
}
|
||||
|
||||
void
|
||||
clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device,
|
||||
guint button,
|
||||
guint state,
|
||||
guint *group,
|
||||
guint *mode)
|
||||
{
|
||||
ClutterInputDeviceXI2 *device_xi2 = CLUTTER_INPUT_DEVICE_XI2 (device);
|
||||
guint button_group, *group_mode;
|
||||
gboolean is_mode_switch = FALSE;
|
||||
|
||||
button_group = clutter_input_device_xi2_get_button_group (device, button);
|
||||
is_mode_switch = button_group >= 0;
|
||||
|
||||
/* Assign all non-mode-switch buttons to group 0 so far */
|
||||
button_group = MAX (0, button_group);
|
||||
|
||||
if (button_group >= device_xi2->group_modes->len)
|
||||
return;
|
||||
|
||||
group_mode = &g_array_index (device_xi2->group_modes, guint, button_group);
|
||||
|
||||
if (is_mode_switch && state)
|
||||
{
|
||||
guint next, n_modes;
|
||||
|
||||
n_modes = clutter_input_device_get_group_n_modes (device, button_group);
|
||||
next = (*group_mode + 1) % n_modes;
|
||||
*group_mode = next;
|
||||
}
|
||||
|
||||
if (group)
|
||||
*group = button_group;
|
||||
if (mode)
|
||||
*mode = *group_mode;
|
||||
}
|
||||
#endif
|
||||
|
@ -27,6 +27,10 @@
|
||||
#include <clutter/clutter-input-device.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
#include <libwacom/libwacom.h>
|
||||
#endif
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLUTTER_TYPE_INPUT_DEVICE_XI2 (_clutter_input_device_xi2_get_type ())
|
||||
@ -41,6 +45,24 @@ void _clutter_input_device_xi2_translate_state (ClutterEvent *event,
|
||||
XIModifierState *modifiers_state,
|
||||
XIButtonState *buttons_state,
|
||||
XIGroupState *group_state);
|
||||
void clutter_input_device_xi2_update_tool (ClutterInputDevice *device,
|
||||
ClutterInputDeviceTool *tool);
|
||||
ClutterInputDeviceTool * clutter_input_device_xi2_get_current_tool (ClutterInputDevice *device);
|
||||
|
||||
#ifdef HAVE_LIBWACOM
|
||||
void clutter_input_device_xi2_ensure_wacom_info (ClutterInputDevice *device,
|
||||
WacomDeviceDatabase *wacom_db);
|
||||
|
||||
guint clutter_input_device_xi2_get_pad_group_mode (ClutterInputDevice *device,
|
||||
guint group);
|
||||
|
||||
void clutter_input_device_xi2_update_pad_state (ClutterInputDevice *device,
|
||||
guint button,
|
||||
guint state,
|
||||
guint *group,
|
||||
guint *mode);
|
||||
|
||||
#endif
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -6,18 +6,14 @@ static const struct {
|
||||
const char *xsetting_name;
|
||||
const char *settings_property;
|
||||
} _clutter_settings_map[] = {
|
||||
{ "Net/DoubleClickTime", "double-click-time" },
|
||||
{ "Net/DoubleClickDistance", "double-click-distance" },
|
||||
{ "Net/DndDragThreshold", "dnd-drag-threshold" },
|
||||
{ "Gtk/FontName", "font-name" },
|
||||
{ "Xft/Antialias", "font-antialias" },
|
||||
{ "Xft/DPI", "font-dpi" },
|
||||
{ "Xft/Hinting", "font-hinting" },
|
||||
{ "Xft/HintStyle", "font-hint-style" },
|
||||
{ "Xft/RGBA", "font-subpixel-order" },
|
||||
{ "Fontconfig/Timestamp", "fontconfig-timestamp" },
|
||||
{ "Gdk/WindowScalingFactor", "window-scaling-factor" },
|
||||
{ "Gdk/UnscaledDPI", "unscaled-font-dpi" },
|
||||
};
|
||||
|
||||
static const gint _n_clutter_settings_map = G_N_ELEMENTS (_clutter_settings_map);
|
||||
|
@ -162,10 +162,10 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
|
||||
&min_height);
|
||||
|
||||
if (new_width <= 0)
|
||||
new_width = min_width * stage_x11->scale_factor;
|
||||
new_width = min_width;
|
||||
|
||||
if (new_height <= 0)
|
||||
new_height = min_height * stage_x11->scale_factor;
|
||||
new_height = min_height;
|
||||
|
||||
size_hints->flags = 0;
|
||||
|
||||
@ -175,8 +175,8 @@ clutter_stage_x11_fix_window_size (ClutterStageX11 *stage_x11,
|
||||
{
|
||||
if (resize)
|
||||
{
|
||||
size_hints->min_width = min_width * stage_x11->scale_factor;
|
||||
size_hints->min_height = min_height * stage_x11->scale_factor;
|
||||
size_hints->min_width = min_width;
|
||||
size_hints->min_height = min_height;
|
||||
size_hints->flags = PMinSize;
|
||||
}
|
||||
else
|
||||
@ -236,8 +236,8 @@ clutter_stage_x11_get_geometry (ClutterStageWindow *stage_window,
|
||||
return;
|
||||
}
|
||||
|
||||
geometry->width = stage_x11->xwin_width / stage_x11->scale_factor;
|
||||
geometry->height = stage_x11->xwin_height / stage_x11->scale_factor;
|
||||
geometry->width = stage_x11->xwin_width;
|
||||
geometry->height = stage_x11->xwin_height;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -255,8 +255,8 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
|
||||
* so we need to manually set the size and queue a relayout on the
|
||||
* stage here (as is normally done in response to ConfigureNotify).
|
||||
*/
|
||||
stage_x11->xwin_width = width * stage_x11->scale_factor;
|
||||
stage_x11->xwin_height = height * stage_x11->scale_factor;
|
||||
stage_x11->xwin_width = width;
|
||||
stage_x11->xwin_height = height;
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (stage_cogl->wrapper));
|
||||
return;
|
||||
}
|
||||
@ -277,9 +277,6 @@ clutter_stage_x11_resize (ClutterStageWindow *stage_window,
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "New size received: (%d, %d)", width, height);
|
||||
|
||||
width *= stage_x11->scale_factor;
|
||||
height *= stage_x11->scale_factor;
|
||||
|
||||
if (stage_x11->xwin != None)
|
||||
{
|
||||
clutter_stage_x11_fix_window_size (stage_x11, width, height);
|
||||
@ -400,20 +397,6 @@ set_cursor_visible (ClutterStageX11 *stage_x11)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_window_scaling_factor_notify (GObject *settings,
|
||||
GParamSpec *pspec,
|
||||
ClutterStageX11 *stage_x11)
|
||||
{
|
||||
g_object_get (settings,
|
||||
"window-scaling-factor", &stage_x11->scale_factor,
|
||||
NULL);
|
||||
|
||||
clutter_stage_x11_resize (CLUTTER_STAGE_WINDOW (stage_x11),
|
||||
stage_x11->xwin_width,
|
||||
stage_x11->xwin_height);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
|
||||
{
|
||||
@ -643,12 +626,8 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Wrapper size: %.2f x %.2f", width, height);
|
||||
|
||||
width = width * (float) stage_x11->scale_factor;
|
||||
height = height * (float) stage_x11->scale_factor;
|
||||
|
||||
CLUTTER_NOTE (BACKEND, "Creating a new Cogl onscreen surface: %.2f x %.2f (factor: %d)",
|
||||
width, height,
|
||||
stage_x11->scale_factor);
|
||||
CLUTTER_NOTE (BACKEND, "Creating a new Cogl onscreen surface: %.2f x %.2f",
|
||||
width, height);
|
||||
|
||||
stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
|
||||
|
||||
@ -909,28 +888,6 @@ clutter_stage_x11_can_clip_redraws (ClutterStageWindow *stage_window)
|
||||
return stage_x11->clipped_redraws_cool_off == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_x11_set_scale_factor (ClutterStageWindow *stage_window,
|
||||
int factor)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
if (stage_x11->scale_factor == factor)
|
||||
return;
|
||||
|
||||
stage_x11->scale_factor = factor;
|
||||
|
||||
clutter_stage_x11_resize (stage_window, stage_x11->xwin_width, stage_x11->xwin_height);
|
||||
}
|
||||
|
||||
static int
|
||||
clutter_stage_x11_get_scale_factor (ClutterStageWindow *stage_window)
|
||||
{
|
||||
ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
|
||||
|
||||
return stage_x11->scale_factor;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_legacy_view (ClutterStageWindow *stage_window)
|
||||
{
|
||||
@ -1002,8 +959,6 @@ clutter_stage_x11_class_init (ClutterStageX11Class *klass)
|
||||
static void
|
||||
clutter_stage_x11_init (ClutterStageX11 *stage)
|
||||
{
|
||||
ClutterSettings *settings;
|
||||
|
||||
stage->xwin = None;
|
||||
stage->xwin_width = 640;
|
||||
stage->xwin_height = 480;
|
||||
@ -1016,12 +971,6 @@ clutter_stage_x11_init (ClutterStageX11 *stage)
|
||||
stage->accept_focus = TRUE;
|
||||
|
||||
stage->title = NULL;
|
||||
|
||||
settings = clutter_settings_get_default ();
|
||||
g_signal_connect (settings, "notify::window-scaling-factor",
|
||||
G_CALLBACK (on_window_scaling_factor_notify),
|
||||
stage);
|
||||
on_window_scaling_factor_notify (G_OBJECT (settings), NULL, stage);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1041,8 +990,6 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
|
||||
iface->realize = clutter_stage_x11_realize;
|
||||
iface->unrealize = clutter_stage_x11_unrealize;
|
||||
iface->can_clip_redraws = clutter_stage_x11_can_clip_redraws;
|
||||
iface->set_scale_factor = clutter_stage_x11_set_scale_factor;
|
||||
iface->get_scale_factor = clutter_stage_x11_get_scale_factor;
|
||||
iface->get_views = clutter_stage_x11_get_views;
|
||||
iface->get_frame_counter = clutter_stage_x11_get_frame_counter;
|
||||
}
|
||||
@ -1167,8 +1114,8 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
|
||||
stage_x11->xwin_height = xevent->xconfigure.height;
|
||||
}
|
||||
|
||||
stage_width = xevent->xconfigure.width / stage_x11->scale_factor;
|
||||
stage_height = xevent->xconfigure.height / stage_x11->scale_factor;
|
||||
stage_width = xevent->xconfigure.width;
|
||||
stage_height = xevent->xconfigure.height;
|
||||
clutter_actor_set_size (CLUTTER_ACTOR (stage), stage_width, stage_height);
|
||||
|
||||
if (size_changed)
|
||||
@ -1335,10 +1282,10 @@ clutter_stage_x11_translate_event (ClutterEventTranslator *translator,
|
||||
expose->width,
|
||||
expose->height);
|
||||
|
||||
clip.x = expose->x / stage_x11->scale_factor;
|
||||
clip.y = expose->y / stage_x11->scale_factor;
|
||||
clip.width = expose->width / stage_x11->scale_factor;
|
||||
clip.height = expose->height / stage_x11->scale_factor;
|
||||
clip.x = expose->x;
|
||||
clip.y = expose->y;
|
||||
clip.width = expose->width;
|
||||
clip.height = expose->height;
|
||||
clutter_actor_queue_redraw_with_clip (CLUTTER_ACTOR (stage), &clip);
|
||||
}
|
||||
break;
|
||||
@ -1504,8 +1451,8 @@ set_foreign_window_callback (ClutterActor *actor,
|
||||
fwd->stage_x11->xwin = fwd->xwindow;
|
||||
fwd->stage_x11->is_foreign_xwin = TRUE;
|
||||
|
||||
fwd->stage_x11->xwin_width = fwd->geom.width * fwd->stage_x11->scale_factor;
|
||||
fwd->stage_x11->xwin_height = fwd->geom.height * fwd->stage_x11->scale_factor;
|
||||
fwd->stage_x11->xwin_width = fwd->geom.width;
|
||||
fwd->stage_x11->xwin_height = fwd->geom.height;
|
||||
|
||||
clutter_actor_set_size (actor, fwd->geom.width, fwd->geom.height);
|
||||
|
||||
@ -1599,8 +1546,8 @@ clutter_x11_set_stage_foreign (ClutterStage *stage,
|
||||
|
||||
fwd.geom.x = x;
|
||||
fwd.geom.y = y;
|
||||
fwd.geom.width = width / stage_x11->scale_factor;
|
||||
fwd.geom.height = height / stage_x11->scale_factor;
|
||||
fwd.geom.width = width;
|
||||
fwd.geom.height = height;
|
||||
|
||||
actor = CLUTTER_ACTOR (stage);
|
||||
|
||||
|
@ -69,8 +69,6 @@ struct _ClutterStageX11
|
||||
|
||||
ClutterStageX11State wm_state;
|
||||
|
||||
int scale_factor;
|
||||
|
||||
guint is_foreign_xwin : 1;
|
||||
guint fullscreening : 1;
|
||||
guint is_cursor_visible : 1;
|
||||
|
@ -27,6 +27,9 @@
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "clutter-x11.h"
|
||||
#include "X11/extensions/XTest.h"
|
||||
|
||||
#include "clutter-virtual-input-device.h"
|
||||
#include "x11/clutter-virtual-input-device-x11.h"
|
||||
|
||||
@ -45,6 +48,10 @@ clutter_virtual_input_device_x11_notify_relative_motion (ClutterVirtualInputDevi
|
||||
double dx,
|
||||
double dy)
|
||||
{
|
||||
XTestFakeRelativeMotionEvent (clutter_x11_get_default_display (),
|
||||
(int) dx,
|
||||
(int) dy,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -53,6 +60,11 @@ clutter_virtual_input_device_x11_notify_absolute_motion (ClutterVirtualInputDevi
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
XTestFakeMotionEvent (clutter_x11_get_default_display (),
|
||||
clutter_x11_get_default_screen (),
|
||||
(int) x,
|
||||
(int) y,
|
||||
0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -60,6 +72,50 @@ clutter_virtual_input_device_x11_notify_button (ClutterVirtualInputDevice *virtu
|
||||
uint64_t time_us,
|
||||
uint32_t button,
|
||||
ClutterButtonState button_state)
|
||||
{
|
||||
XTestFakeButtonEvent (clutter_x11_get_default_display (),
|
||||
button, button_state == CLUTTER_BUTTON_STATE_PRESSED, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_discrete_scroll (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
ClutterScrollDirection direction,
|
||||
ClutterScrollSource scroll_source)
|
||||
{
|
||||
Display *xdisplay = clutter_x11_get_default_display ();
|
||||
int button;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case CLUTTER_SCROLL_UP:
|
||||
button = 4;
|
||||
break;
|
||||
case CLUTTER_SCROLL_DOWN:
|
||||
button = 5;
|
||||
break;
|
||||
case CLUTTER_SCROLL_LEFT:
|
||||
button = 6;
|
||||
break;
|
||||
case CLUTTER_SCROLL_RIGHT:
|
||||
button = 7;
|
||||
break;
|
||||
default:
|
||||
g_warn_if_reached ();
|
||||
return;
|
||||
}
|
||||
|
||||
XTestFakeButtonEvent (xdisplay, button, True, 0);
|
||||
XTestFakeButtonEvent (xdisplay, button, False, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_scroll_continuous (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
double dx,
|
||||
double dy,
|
||||
ClutterScrollSource scroll_source,
|
||||
ClutterScrollFinishFlags finish_flags)
|
||||
{
|
||||
}
|
||||
|
||||
@ -69,6 +125,49 @@ clutter_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_
|
||||
uint32_t key,
|
||||
ClutterKeyState key_state)
|
||||
{
|
||||
XTestFakeKeyEvent (clutter_x11_get_default_display (),
|
||||
key, key_state == CLUTTER_KEY_STATE_PRESSED, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
uint32_t keyval,
|
||||
ClutterKeyState key_state)
|
||||
{
|
||||
KeyCode keycode;
|
||||
|
||||
keycode = XKeysymToKeycode (clutter_x11_get_default_display (), keyval);
|
||||
XTestFakeKeyEvent (clutter_x11_get_default_display (),
|
||||
keycode, key_state == CLUTTER_KEY_STATE_PRESSED, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
g_warning ("Virtual touch motion not implemented under X11");
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
g_warning ("Virtual touch motion not implemented under X11");
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_virtual_input_device_x11_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
|
||||
uint64_t time_us,
|
||||
int device_slot)
|
||||
{
|
||||
g_warning ("Virtual touch motion not implemented under X11");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -85,5 +184,11 @@ clutter_virtual_input_device_x11_class_init (ClutterVirtualInputDeviceX11Class *
|
||||
virtual_input_device_class->notify_relative_motion = clutter_virtual_input_device_x11_notify_relative_motion;
|
||||
virtual_input_device_class->notify_absolute_motion = clutter_virtual_input_device_x11_notify_absolute_motion;
|
||||
virtual_input_device_class->notify_button = clutter_virtual_input_device_x11_notify_button;
|
||||
virtual_input_device_class->notify_discrete_scroll = clutter_virtual_input_device_x11_notify_discrete_scroll;
|
||||
virtual_input_device_class->notify_scroll_continuous = clutter_virtual_input_device_x11_notify_scroll_continuous;
|
||||
virtual_input_device_class->notify_key = clutter_virtual_input_device_x11_notify_key;
|
||||
virtual_input_device_class->notify_keyval = clutter_virtual_input_device_x11_notify_keyval;
|
||||
virtual_input_device_class->notify_touch_down = clutter_virtual_input_device_x11_notify_touch_down;
|
||||
virtual_input_device_class->notify_touch_motion = clutter_virtual_input_device_x11_notify_touch_motion;
|
||||
virtual_input_device_class->notify_touch_up = clutter_virtual_input_device_x11_notify_touch_up;
|
||||
}
|
||||
|
@ -161,9 +161,6 @@ gint clutter_x11_event_get_key_group (const ClutterEvent *event);
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
guint clutter_x11_event_sequence_get_touch_detail (const ClutterEventSequence *sequence);
|
||||
|
||||
CLUTTER_AVAILABLE_IN_ALL
|
||||
void clutter_x11_request_reset_on_video_memory_purge (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __CLUTTER_X11_H__ */
|
||||
|
328
clutter/clutter/x11/clutter-xkb-a11y-x11.c
Normal file
328
clutter/clutter/x11/clutter-xkb-a11y-x11.c
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
*
|
||||
* Copyright © 2001 Ximian, Inc.
|
||||
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||
* Copyright (C) 2017 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-xkb-a11y-x11.h"
|
||||
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/XKBstr.h>
|
||||
|
||||
#define DEFAULT_XKB_SET_CONTROLS_MASK XkbSlowKeysMask | \
|
||||
XkbBounceKeysMask | \
|
||||
XkbStickyKeysMask | \
|
||||
XkbMouseKeysMask | \
|
||||
XkbMouseKeysAccelMask | \
|
||||
XkbAccessXKeysMask | \
|
||||
XkbAccessXTimeoutMask | \
|
||||
XkbAccessXFeedbackMask | \
|
||||
XkbControlsEnabledMask
|
||||
|
||||
static int _xkb_event_base;
|
||||
|
||||
static XkbDescRec *
|
||||
get_xkb_desc_rec (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
XkbDescRec *desc;
|
||||
Status status = Success;
|
||||
|
||||
clutter_x11_trap_x_errors ();
|
||||
desc = XkbGetMap (backend_x11->xdpy, XkbAllMapComponentsMask, XkbUseCoreKbd);
|
||||
if (desc != NULL)
|
||||
{
|
||||
desc->ctrls = NULL;
|
||||
status = XkbGetControls (backend_x11->xdpy, XkbAllControlsMask, desc);
|
||||
}
|
||||
clutter_x11_untrap_x_errors ();
|
||||
|
||||
g_return_val_if_fail (desc != NULL, NULL);
|
||||
g_return_val_if_fail (desc->ctrls != NULL, NULL);
|
||||
g_return_val_if_fail (status == Success, NULL);
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
static void
|
||||
set_xkb_desc_rec (ClutterBackendX11 *backend_x11,
|
||||
XkbDescRec *desc)
|
||||
{
|
||||
clutter_x11_trap_x_errors ();
|
||||
XkbSetControls (backend_x11->xdpy, DEFAULT_XKB_SET_CONTROLS_MASK, desc);
|
||||
XSync (backend_x11->xdpy, FALSE);
|
||||
clutter_x11_untrap_x_errors ();
|
||||
}
|
||||
|
||||
static void
|
||||
check_settings_changed (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11;
|
||||
ClutterKbdA11ySettings kbd_a11y_settings;
|
||||
ClutterKeyboardA11yFlags what_changed = 0;
|
||||
XkbDescRec *desc;
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||
desc = get_xkb_desc_rec (backend_x11);
|
||||
if (!desc)
|
||||
return;
|
||||
|
||||
clutter_device_manager_get_kbd_a11y_settings (device_manager, &kbd_a11y_settings);
|
||||
|
||||
if (desc->ctrls->enabled_ctrls & XkbSlowKeysMask &&
|
||||
!(kbd_a11y_settings.controls & CLUTTER_A11Y_SLOW_KEYS_ENABLED))
|
||||
{
|
||||
what_changed |= CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
||||
kbd_a11y_settings.controls |= CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
||||
}
|
||||
else if (!(desc->ctrls->enabled_ctrls & XkbSlowKeysMask) &&
|
||||
kbd_a11y_settings.controls & CLUTTER_A11Y_SLOW_KEYS_ENABLED)
|
||||
{
|
||||
what_changed |= CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
||||
kbd_a11y_settings.controls &= ~CLUTTER_A11Y_SLOW_KEYS_ENABLED;
|
||||
}
|
||||
|
||||
if (desc->ctrls->enabled_ctrls & XkbStickyKeysMask &&
|
||||
!(kbd_a11y_settings.controls & CLUTTER_A11Y_STICKY_KEYS_ENABLED))
|
||||
{
|
||||
what_changed |= CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
||||
kbd_a11y_settings.controls |= CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
||||
}
|
||||
else if (!(desc->ctrls->enabled_ctrls & XkbStickyKeysMask) &&
|
||||
kbd_a11y_settings.controls & CLUTTER_A11Y_STICKY_KEYS_ENABLED)
|
||||
{
|
||||
what_changed |= CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
||||
kbd_a11y_settings.controls &= ~CLUTTER_A11Y_STICKY_KEYS_ENABLED;
|
||||
}
|
||||
|
||||
if (what_changed)
|
||||
g_signal_emit_by_name (device_manager,
|
||||
"kbd-a11y-flags-changed",
|
||||
kbd_a11y_settings.controls,
|
||||
what_changed);
|
||||
|
||||
XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE);
|
||||
}
|
||||
|
||||
static ClutterX11FilterReturn
|
||||
xkb_a11y_event_filter (XEvent *xevent,
|
||||
ClutterEvent *clutter_event,
|
||||
gpointer data)
|
||||
{
|
||||
ClutterDeviceManager *device_manager = CLUTTER_DEVICE_MANAGER (data);
|
||||
XkbEvent *xkbev = (XkbEvent *) xevent;
|
||||
|
||||
/* 'event_type' is set to zero on notifying us of updates in
|
||||
* response to client requests (including our own) and non-zero
|
||||
* to notify us of key/mouse events causing changes (like
|
||||
* pressing shift 5 times to enable sticky keys).
|
||||
*
|
||||
* We only want to update out settings when it's in response to an
|
||||
* explicit user input event, so require a non-zero event_type.
|
||||
*/
|
||||
if (xevent->xany.type == (_xkb_event_base + XkbEventCode) &&
|
||||
xkbev->any.xkb_type == XkbControlsNotify && xkbev->ctrls.event_type != 0)
|
||||
check_settings_changed (device_manager);
|
||||
|
||||
return CLUTTER_X11_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_xkb_available (ClutterBackendX11 *backend_x11)
|
||||
{
|
||||
gint opcode, error_base, event_base, major, minor;
|
||||
|
||||
if (_xkb_event_base)
|
||||
return TRUE;
|
||||
|
||||
if (!XkbQueryExtension (backend_x11->xdpy,
|
||||
&opcode,
|
||||
&event_base,
|
||||
&error_base,
|
||||
&major,
|
||||
&minor))
|
||||
return FALSE;
|
||||
|
||||
if (!XkbUseExtension (backend_x11->xdpy, &major, &minor))
|
||||
return FALSE;
|
||||
|
||||
_xkb_event_base = event_base;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
set_value_mask (gboolean flag,
|
||||
unsigned long value,
|
||||
unsigned long mask)
|
||||
{
|
||||
if (flag)
|
||||
return value | mask;
|
||||
|
||||
return value & ~mask;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_xkb_ctrl (XkbDescRec *desc,
|
||||
ClutterKeyboardA11yFlags settings,
|
||||
ClutterKeyboardA11yFlags flag,
|
||||
unsigned long mask)
|
||||
{
|
||||
gboolean result = (settings & flag) == flag;
|
||||
desc->ctrls->enabled_ctrls = set_value_mask (result, desc->ctrls->enabled_ctrls, mask);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *kbd_a11y_settings)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11;
|
||||
XkbDescRec *desc;
|
||||
gboolean enable_accessX;
|
||||
|
||||
backend_x11 = CLUTTER_BACKEND_X11 (clutter_get_default_backend ());
|
||||
desc = get_xkb_desc_rec (backend_x11);
|
||||
if (!desc)
|
||||
return;
|
||||
|
||||
/* general */
|
||||
enable_accessX = kbd_a11y_settings->controls & CLUTTER_A11Y_KEYBOARD_ENABLED;
|
||||
|
||||
desc->ctrls->enabled_ctrls = set_value_mask (enable_accessX,
|
||||
desc->ctrls->enabled_ctrls,
|
||||
XkbAccessXKeysMask);
|
||||
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls, CLUTTER_A11Y_TIMEOUT_ENABLED,
|
||||
XkbAccessXTimeoutMask))
|
||||
{
|
||||
desc->ctrls->ax_timeout = kbd_a11y_settings->timeout_delay;
|
||||
/* disable only the master flag via the server we will disable
|
||||
* the rest on the rebound without affecting settings state
|
||||
* don't change the option flags at all.
|
||||
*/
|
||||
desc->ctrls->axt_ctrls_mask = XkbAccessXKeysMask | XkbAccessXFeedbackMask;
|
||||
desc->ctrls->axt_ctrls_values = 0;
|
||||
desc->ctrls->axt_opts_mask = 0;
|
||||
}
|
||||
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_FEATURE_STATE_CHANGE_BEEP,
|
||||
desc->ctrls->ax_options,
|
||||
XkbAccessXFeedbackMask | XkbAX_FeatureFBMask | XkbAX_SlowWarnFBMask);
|
||||
|
||||
/* bounce keys */
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_BOUNCE_KEYS_ENABLED, XkbBounceKeysMask))
|
||||
{
|
||||
desc->ctrls->debounce_delay = kbd_a11y_settings->debounce_delay;
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_BOUNCE_KEYS_BEEP_REJECT,
|
||||
desc->ctrls->ax_options,
|
||||
XkbAccessXFeedbackMask | XkbAX_BKRejectFBMask);
|
||||
}
|
||||
|
||||
/* mouse keys */
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_MOUSE_KEYS_ENABLED, XkbMouseKeysMask | XkbMouseKeysAccelMask))
|
||||
{
|
||||
gint mk_max_speed;
|
||||
gint mk_accel_time;
|
||||
|
||||
desc->ctrls->mk_interval = 100; /* msec between mousekey events */
|
||||
desc->ctrls->mk_curve = 50;
|
||||
|
||||
/* We store pixels / sec, XKB wants pixels / event */
|
||||
mk_max_speed = kbd_a11y_settings->mousekeys_max_speed;
|
||||
desc->ctrls->mk_max_speed = mk_max_speed / (1000 / desc->ctrls->mk_interval);
|
||||
if (desc->ctrls->mk_max_speed <= 0)
|
||||
desc->ctrls->mk_max_speed = 1;
|
||||
|
||||
mk_accel_time = kbd_a11y_settings->mousekeys_accel_time;
|
||||
desc->ctrls->mk_time_to_max = mk_accel_time / desc->ctrls->mk_interval;
|
||||
|
||||
if (desc->ctrls->mk_time_to_max <= 0)
|
||||
desc->ctrls->mk_time_to_max = 1;
|
||||
|
||||
desc->ctrls->mk_delay = kbd_a11y_settings->mousekeys_init_delay;
|
||||
}
|
||||
|
||||
/* slow keys */
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_SLOW_KEYS_ENABLED, XkbSlowKeysMask))
|
||||
{
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_PRESS,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKPressFBMask);
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_ACCEPT,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKAcceptFBMask);
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_SLOW_KEYS_BEEP_REJECT,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_SKRejectFBMask);
|
||||
desc->ctrls->slow_keys_delay = kbd_a11y_settings->slowkeys_delay;
|
||||
/* anything larger than 500 seems to loose all keyboard input */
|
||||
if (desc->ctrls->slow_keys_delay > 500)
|
||||
desc->ctrls->slow_keys_delay = 500;
|
||||
}
|
||||
|
||||
/* sticky keys */
|
||||
if (set_xkb_ctrl (desc, kbd_a11y_settings->controls,
|
||||
CLUTTER_A11Y_STICKY_KEYS_ENABLED, XkbStickyKeysMask))
|
||||
{
|
||||
desc->ctrls->ax_options |= XkbAX_LatchToLockMask;
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_STICKY_KEYS_TWO_KEY_OFF,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_TwoKeysMask);
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_STICKY_KEYS_BEEP,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_StickyKeysFBMask);
|
||||
}
|
||||
|
||||
/* toggle keys */
|
||||
desc->ctrls->ax_options =
|
||||
set_value_mask (kbd_a11y_settings->controls & CLUTTER_A11Y_TOGGLE_KEYS_ENABLED,
|
||||
desc->ctrls->ax_options, XkbAccessXFeedbackMask | XkbAX_IndicatorFBMask);
|
||||
|
||||
set_xkb_desc_rec (backend_x11, desc);
|
||||
XkbFreeKeyboard (desc, XkbAllComponentsMask, TRUE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
clutter_device_manager_x11_a11y_init (ClutterDeviceManager *device_manager)
|
||||
{
|
||||
ClutterBackendX11 *backend_x11;
|
||||
guint event_mask;
|
||||
|
||||
backend_x11 =
|
||||
CLUTTER_BACKEND_X11 (_clutter_device_manager_get_backend (device_manager));
|
||||
|
||||
if (!is_xkb_available (backend_x11))
|
||||
return FALSE;
|
||||
|
||||
event_mask = XkbControlsNotifyMask | XkbAccessXNotifyMask;
|
||||
|
||||
XkbSelectEvents (backend_x11->xdpy, XkbUseCoreKbd, event_mask, event_mask);
|
||||
|
||||
clutter_x11_add_filter (xkb_a11y_event_filter, device_manager);
|
||||
|
||||
return TRUE;
|
||||
}
|
39
clutter/clutter/x11/clutter-xkb-a11y-x11.h
Normal file
39
clutter/clutter/x11/clutter-xkb-a11y-x11.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
*
|
||||
* Copyright © 2001 Ximian, Inc.
|
||||
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
||||
* Copyright (C) 2017 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CLUTTER_XKB_A11Y_X11_H
|
||||
#define CLUTTER_XKB_A11Y_X11_H
|
||||
|
||||
#include "clutter-device-manager-private.h"
|
||||
#include "clutter-backend-x11.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
void
|
||||
clutter_device_manager_x11_apply_kbd_a11y_settings (ClutterDeviceManager *device_manager,
|
||||
ClutterKbdA11ySettings *kbd_a11y_settings);
|
||||
|
||||
gboolean
|
||||
clutter_device_manager_x11_a11y_init (ClutterDeviceManager *device_manager);
|
||||
|
||||
#endif /* CLUTTER_XKB_A11Y_X11_H */
|
@ -42,9 +42,6 @@ m4_define([clutter_release_status],
|
||||
|
||||
m4_define([clutter_version], [clutter_major_version.clutter_minor_version.clutter_micro_version])
|
||||
|
||||
# change this only when breaking the API
|
||||
m4_define([clutter_api_version], [1.0])
|
||||
|
||||
AC_PREREQ([2.63])
|
||||
|
||||
AC_INIT([clutter],
|
||||
@ -61,12 +58,18 @@ AC_CONFIG_MACRO_DIR([build/autotools])
|
||||
AM_INIT_AUTOMAKE([1.11 foreign -Wno-portability no-define no-dist-gzip dist-xz tar-ustar])
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
dnl = Check that we are configured by mutter ==============================
|
||||
|
||||
AC_ARG_VAR([MUTTER_VERSION])
|
||||
AC_ARG_VAR([LIBMUTTER_API_VERSION])
|
||||
|
||||
AS_IF([test "x$MUTTER_VERSION" = "x"],
|
||||
[AC_MSG_ERROR([Clutter can only be configured by mutter])],)
|
||||
|
||||
AC_SUBST([CLUTTER_MAJOR_VERSION], [clutter_major_version])
|
||||
AC_SUBST([CLUTTER_MINOR_VERSION], [clutter_minor_version])
|
||||
AC_SUBST([CLUTTER_MICRO_VERSION], [clutter_micro_version])
|
||||
AC_SUBST([CLUTTER_VERSION], [clutter_version])
|
||||
AC_SUBST([CLUTTER_API_VERSION], [clutter_api_version])
|
||||
AC_SUBST([CLUTTER_API_VERSION_AM], [$CLUTTER_MAJOR_VERSION\_0])
|
||||
AC_SUBST([CLUTTER_RELEASE_STATUS], [clutter_release_status])
|
||||
|
||||
m4_define([lt_current], [m4_eval(100 * clutter_minor_version + clutter_micro_version - clutter_interface_age)])
|
||||
@ -107,7 +110,7 @@ LT_LIB_M
|
||||
AC_HEADER_STDC
|
||||
|
||||
# required versions for dependencies
|
||||
m4_define([glib_req_version], [2.44.0])
|
||||
m4_define([glib_req_version], [2.53.2])
|
||||
m4_define([cogl_req_version], [1.21.2])
|
||||
m4_define([json_glib_req_version], [0.12.0])
|
||||
m4_define([atk_req_version], [2.5.3])
|
||||
@ -118,6 +121,7 @@ m4_define([xcomposite_req_version], [0.4])
|
||||
m4_define([gdk_req_version], [3.3.18])
|
||||
m4_define([libinput_req_version], [1.4.0])
|
||||
m4_define([libudev_req_version], [136])
|
||||
m4_define([libwacom_req_version], [0.13])
|
||||
|
||||
AC_SUBST([GLIB_REQ_VERSION], [glib_req_version])
|
||||
AC_SUBST([COGL_REQ_VERSION], [cogl_req_version])
|
||||
@ -130,6 +134,7 @@ AC_SUBST([XCOMPOSITE_REQ_VERSION], [xcomposite_req_version])
|
||||
AC_SUBST([GDK_REQ_VERSION], [gdk_req_version])
|
||||
AC_SUBST([LIBINPUT_REQ_VERSION], [libinput_req_version])
|
||||
AC_SUBST([LIBUDEV_REQ_VERSION], [libudev_req_version])
|
||||
AC_SUBST([LIBWACOM_REQ_VERSION], [libwacom_req_version])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AM_PATH_GLIB_2_0([glib_req_version],
|
||||
@ -146,7 +151,7 @@ AC_ARG_ENABLE([Bsymbolic],
|
||||
saved_LDFLAGS="${LDFLAGS}"
|
||||
AC_MSG_CHECKING([for -Bsymbolic-functions linker flag])
|
||||
LDFLAGS=-Wl,-Bsymbolic-functions
|
||||
AC_TRY_LINK([], [int main (void) { return 0; }],
|
||||
AC_TRY_LINK([], [return 0],
|
||||
[
|
||||
AC_MSG_RESULT([yes])
|
||||
enable_Bsymbolic=yes
|
||||
@ -167,7 +172,7 @@ dnl on other compilers, check if we can do -fvisibility=hidden
|
||||
SAVED_CFLAGS="${CFLAGS}"
|
||||
CFLAGS="-fvisibility=hidden"
|
||||
AC_MSG_CHECKING([for -fvisibility=hidden compiler flag])
|
||||
AC_TRY_COMPILE([], [int main (void) { return 0; }],
|
||||
AC_TRY_COMPILE([], [return 0],
|
||||
AC_MSG_RESULT(yes)
|
||||
enable_fvisibility_hidden=yes,
|
||||
AC_MSG_RESULT(no)
|
||||
@ -382,6 +387,22 @@ AS_IF([test "x$SUPPORT_X11" = "x1"],
|
||||
[AC_MSG_ERROR([not found])]
|
||||
)
|
||||
|
||||
# XTEST (required)
|
||||
AC_MSG_CHECKING([for XTest extension])
|
||||
PKG_CHECK_EXISTS([xtst], [have_xtest=yes], [have_xtest=no])
|
||||
AS_IF([test "x$have_xtest" = "xyes"],
|
||||
[
|
||||
AC_DEFINE(HAVE_XTEST, [1], [Define to 1 if we have the XTest X extension])
|
||||
|
||||
X11_LIBS="$X11_LIBS -lXtst"
|
||||
X11_PC_FILES="$X11_PC_FILES xtst"
|
||||
X11_EXTS="$X11_EXTS xtst"
|
||||
|
||||
AC_MSG_RESULT([found])
|
||||
],
|
||||
[AC_MSG_ERROR([Not found])]
|
||||
)
|
||||
|
||||
# X Generic Extensions (optional)
|
||||
clutter_save_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $X11_CFLAGS"
|
||||
@ -489,6 +510,32 @@ X11_EXTS=${X11_EXTS#* }
|
||||
|
||||
AC_CACHE_SAVE
|
||||
|
||||
dnl === Libwacom support for X11 ===============================================
|
||||
AC_ARG_WITH(libwacom,
|
||||
AC_HELP_STRING([--without-libwacom],
|
||||
[disable the use of libwacom for advanced tablet management]),,
|
||||
with_libwacom=auto)
|
||||
|
||||
have_libwacom=no
|
||||
AC_MSG_CHECKING([libwacom])
|
||||
if test x$with_libwacom = xno ; then
|
||||
AC_MSG_RESULT([disabled])
|
||||
else
|
||||
if $PKG_CONFIG --exists libwacom '>=' $LIBWACOM_REQ_VERSION; then
|
||||
have_libwacom=yes
|
||||
AC_MSG_RESULT(yes)
|
||||
PKG_CHECK_MODULES([LIBWACOM], [libwacom])
|
||||
AC_SUBST(LIBWACOM_CFLAGS)
|
||||
AC_SUBST(LIBWACOM_LIBS)
|
||||
AC_DEFINE([HAVE_LIBWACOM], 1, [Building with libwacom for advanced tablet management])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
if test x$with_libwacom = xyes ; then
|
||||
AC_MSG_ERROR([libwacom forced but not found])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl === Enable GDK-Pixbuf in tests ============================================
|
||||
|
||||
m4_define([pixbuf_default], [yes])
|
||||
@ -660,8 +707,8 @@ AS_IF([test "x$CLUTTER_BASE_PC_FILES_PRIVATE" = "x" && test "x$BACKEND_PC_FILES_
|
||||
AC_SUBST(CLUTTER_REQUIRES)
|
||||
AC_SUBST(CLUTTER_REQUIRES_PRIVATE)
|
||||
|
||||
CLUTTER_CFLAGS="$FLAVOUR_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_DEPS_PRIVATE_CFLAGS $GLIB_CFLAGS"
|
||||
CLUTTER_LIBS="$FLAVOUR_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_DEPS_PRIVATE_LIBS $GLIB_LIBS"
|
||||
CLUTTER_CFLAGS="$FLAVOUR_CFLAGS $CLUTTER_DEPS_CFLAGS $CLUTTER_DEPS_PRIVATE_CFLAGS $GLIB_CFLAGS $LIBWACOM_CFLAGS"
|
||||
CLUTTER_LIBS="$FLAVOUR_LIBS $CLUTTER_DEPS_LIBS $CLUTTER_DEPS_PRIVATE_LIBS $GLIB_LIBS $LIBWACOM_LIBS"
|
||||
AC_SUBST(CLUTTER_CFLAGS)
|
||||
AC_SUBST(CLUTTER_LIBS)
|
||||
|
||||
@ -765,7 +812,7 @@ AC_CONFIG_FILES([
|
||||
clutter/Makefile
|
||||
clutter/clutter-config.h
|
||||
clutter/clutter-version.h
|
||||
clutter/mutter-clutter-$CLUTTER_API_VERSION.pc:clutter/mutter-clutter.pc.in
|
||||
clutter/mutter-clutter-$LIBMUTTER_API_VERSION.pc:clutter/mutter-clutter.pc.in
|
||||
|
||||
tests/Makefile
|
||||
tests/accessibility/Makefile
|
||||
|
@ -21,7 +21,7 @@ all_examples += \
|
||||
image-content
|
||||
endif
|
||||
|
||||
LDADD = $(top_builddir)/clutter/libmutter-clutter-@CLUTTER_API_VERSION@.la $(CLUTTER_LIBS) $(GDK_PIXBUF_LIBS) $(LIBM)
|
||||
LDADD = $(top_builddir)/clutter/libmutter-clutter-@LIBMUTTER_API_VERSION@.la $(CLUTTER_LIBS) $(GDK_PIXBUF_LIBS) $(LIBM)
|
||||
AM_CFLAGS = $(CLUTTER_CFLAGS) $(GDK_PIXBUF_CFLAGS) $(MAINTAINER_CFLAGS)
|
||||
AM_CPPFLAGS = \
|
||||
-DG_DISABLE_SINGLE_INCLUDES \
|
||||
|
@ -1,5 +1,5 @@
|
||||
common_ldadd = \
|
||||
$(top_builddir)/clutter/libmutter-clutter-@CLUTTER_API_VERSION@.la
|
||||
$(top_builddir)/clutter/libmutter-clutter-@LIBMUTTER_API_VERSION@.la
|
||||
|
||||
common_sources = \
|
||||
cally-examples-util.c \
|
||||
@ -11,6 +11,7 @@ AM_CPPFLAGS = \
|
||||
-DGLIB_DISABLE_DEPRECATION_WARNINGS \
|
||||
-I$(top_srcdir)/../cogl \
|
||||
-I$(top_builddir)/../cogl \
|
||||
-I$(top_builddir)/../cogl/cogl \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir)/clutter \
|
||||
|
@ -3,12 +3,13 @@ installed_testdir = $(libexecdir)/installed-tests/mutter-clutter
|
||||
include $(top_srcdir)/build/autotools/glib-tap.mk
|
||||
|
||||
AM_CFLAGS = -g $(CLUTTER_CFLAGS) $(MAINTAINER_CFLAGS)
|
||||
LDADD = $(top_builddir)/../cogl/cogl/libmutter-cogl.la $(top_builddir)/clutter/libmutter-clutter-1.0.la $(CLUTTER_LIBS) $(LIBM)
|
||||
LDADD = $(top_builddir)/../cogl/cogl/libmutter-cogl-@LIBMUTTER_API_VERSION@.la $(top_builddir)/clutter/libmutter-clutter-@LIBMUTTER_API_VERSION@.la $(CLUTTER_LIBS) $(LIBM)
|
||||
AM_LDFLAGS = -export-dynamic
|
||||
AM_CPPFLAGS = \
|
||||
-DG_LOG_DOMAIN=\"Clutter-Conform\" \
|
||||
-I$(top_srcdir)/../cogl \
|
||||
-I$(top_builddir)/../cogl \
|
||||
-I$(top_builddir)/../cogl/cogl \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir) \
|
||||
-DCOGL_DISABLE_DEPRECATION_WARNINGS \
|
||||
@ -78,7 +79,7 @@ script_tests = \
|
||||
test-script-timeline-markers.json \
|
||||
test-state-1.json
|
||||
|
||||
TESTS_ENVIRONMENT += G_ENABLE_DIAGNOSTIC=0 CLUTTER_ENABLE_DIAGNOSTIC=0
|
||||
TESTS_ENVIRONMENT += G_ENABLE_DIAGNOSTIC=0 CLUTTER_ENABLE_DIAGNOSTIC=0 CLUTTER_SCALE=1
|
||||
|
||||
# simple rules for generating a Git ignore file for the conformance test suite
|
||||
$(srcdir)/.gitignore: Makefile
|
||||
|
@ -350,7 +350,8 @@ actor_replace_child (void)
|
||||
g_assert_cmpstr (clutter_actor_get_name (iter), ==, "qux");
|
||||
|
||||
clutter_actor_add_child (actor, g_object_new (CLUTTER_TYPE_ACTOR,
|
||||
"name", "foo"));
|
||||
"name", "foo",
|
||||
NULL));
|
||||
|
||||
clutter_actor_replace_child (actor, iter,
|
||||
g_object_new (CLUTTER_TYPE_ACTOR,
|
||||
|
@ -110,8 +110,8 @@ clean-wrappers:
|
||||
.PHONY: wrappers clean-wrappers
|
||||
|
||||
common_ldadd = \
|
||||
$(top_builddir)/clutter/libmutter-clutter-@CLUTTER_API_VERSION@.la \
|
||||
$(top_builddir)/../cogl/cogl/libmutter-cogl.la
|
||||
$(top_builddir)/clutter/libmutter-clutter-@LIBMUTTER_API_VERSION@.la \
|
||||
$(top_builddir)/../cogl/cogl/libmutter-cogl-@LIBMUTTER_API_VERSION@.la
|
||||
|
||||
check_PROGRAMS = test-interactive
|
||||
check_SCRIPTS = wrappers
|
||||
@ -127,6 +127,7 @@ test_interactive_CPPFLAGS = \
|
||||
-DCLUTTER_DISABLE_DEPRECATION_WARNINGS \
|
||||
-I$(top_srcdir)/../cogl \
|
||||
-I$(top_builddir)/../cogl \
|
||||
-I$(top_builddir)/../cogl/cogl \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir)/clutter \
|
||||
|
@ -1,6 +1,6 @@
|
||||
common_ldadd = \
|
||||
$(top_builddir)/clutter/libmutter-clutter-@CLUTTER_API_VERSION@.la \
|
||||
$(top_builddir)/../cogl/cogl/libmutter-cogl.la
|
||||
$(top_builddir)/clutter/libmutter-clutter-@LIBMUTTER_API_VERSION@.la \
|
||||
$(top_builddir)/../cogl/cogl/libmutter-cogl-@LIBMUTTER_API_VERSION@.la
|
||||
|
||||
|
||||
check_PROGRAMS = \
|
||||
@ -20,6 +20,7 @@ AM_CPPFLAGS = \
|
||||
-DTESTS_DATA_DIR=\""$(top_srcdir)/tests/data/"\" \
|
||||
-I$(top_srcdir)/../cogl \
|
||||
-I$(top_builddir)/../cogl \
|
||||
-I$(top_builddir)/../cogl/cogl \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir)/clutter \
|
||||
|
@ -7,7 +7,7 @@ check_PROGRAMS = \
|
||||
test-state-mini \
|
||||
test-state-pick
|
||||
|
||||
common_ldadd = $(top_builddir)/clutter/libmutter-clutter-@CLUTTER_API_VERSION@.la
|
||||
common_ldadd = $(top_builddir)/clutter/libmutter-clutter-@LIBMUTTER_API_VERSION@.la
|
||||
|
||||
LDADD = $(common_ldadd) $(CLUTTER_LIBS) $(LIBM)
|
||||
|
||||
@ -21,6 +21,7 @@ AM_CPPFLAGS = \
|
||||
-DTESTS_DATA_DIR=\""$(top_srcdir)/tests/data/"\" \
|
||||
-I$(top_srcdir)/../cogl \
|
||||
-I$(top_builddir)/../cogl \
|
||||
-I$(top_builddir)/../cogl/cogl \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir)/clutter \
|
||||
|
@ -2,8 +2,10 @@
|
||||
|
||||
NULL =
|
||||
|
||||
DISTCLEANFILES =
|
||||
|
||||
mutterlibdir = $(libdir)/mutter
|
||||
mutterlib_LTLIBRARIES = libmutter-cogl-gles2.la
|
||||
mutterlib_LTLIBRARIES = libmutter-cogl-gles2-@LIBMUTTER_API_VERSION@.la
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir) \
|
||||
@ -11,8 +13,8 @@ AM_CPPFLAGS = \
|
||||
|
||||
AM_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS)
|
||||
|
||||
libmutter_cogl_gles2_la_SOURCES = cogl-gles2-api.c
|
||||
libmutter_cogl_gles2_la_LDFLAGS = \
|
||||
libmutter_cogl_gles2_@LIBMUTTER_API_VERSION@_la_SOURCES = cogl-gles2-api.c
|
||||
libmutter_cogl_gles2_@LIBMUTTER_API_VERSION@_la_LDFLAGS = \
|
||||
-no-undefined \
|
||||
-rpath $(mutterlibdir) \
|
||||
-avoid-version \
|
||||
@ -25,7 +27,9 @@ coglgles2include_HEADERS = \
|
||||
GLES2/gl2ext.h \
|
||||
GLES2/gl2platform.h
|
||||
|
||||
pc_files = mutter-cogl-gles2-1.0.pc
|
||||
pc_files = mutter-cogl-gles2-$(LIBMUTTER_API_VERSION).pc
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = $(pc_files)
|
||||
|
||||
DISTCLEANFILES += $(pc_files)
|
||||
|
@ -2,12 +2,12 @@ prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@/mutter
|
||||
includedir=@includedir@/mutter
|
||||
apiversion=1.0
|
||||
requires=@COGL_PKG_REQUIRES@ mutter-cogl-1.0
|
||||
apiversion=@LIBMUTTER_API_VERSION@
|
||||
requires=@COGL_PKG_REQUIRES@ mutter-cogl-@LIBMUTTER_API_VERSION@
|
||||
|
||||
Name: Cogl
|
||||
Description: An object oriented GL/GLES Abstraction/Utility Layer
|
||||
Version: @COGL_1_VERSION@
|
||||
Libs: -L${libdir} -lmutter-cogl-gles2
|
||||
Version: @MUTTER_VERSION@
|
||||
Libs: -L${libdir} -lmutter-cogl-gles2-@LIBMUTTER_API_VERSION@
|
||||
Cflags: -I${includedir}/cogl
|
||||
Requires: ${requires}
|
@ -23,13 +23,13 @@ source_h_priv = \
|
||||
$(NULL)
|
||||
|
||||
mutterlibdir = $(libdir)/mutter
|
||||
mutterlib_LTLIBRARIES = libmutter-cogl-pango.la
|
||||
mutterlib_LTLIBRARIES = libmutter-cogl-pango-@LIBMUTTER_API_VERSION@.la
|
||||
|
||||
libmutter_cogl_pango_la_SOURCES = $(source_c) $(source_h) $(source_h_priv)
|
||||
libmutter_cogl_pango_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_PANGO_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS)
|
||||
libmutter_cogl_pango_la_LIBADD = $(top_builddir)/cogl/libmutter-cogl.la
|
||||
libmutter_cogl_pango_la_LIBADD += $(COGL_DEP_LIBS) $(COGL_PANGO_DEP_LIBS) $(COGL_EXTRA_LDFLAGS)
|
||||
libmutter_cogl_pango_la_LDFLAGS = \
|
||||
libmutter_cogl_pango_@LIBMUTTER_API_VERSION@_la_SOURCES = $(source_c) $(source_h) $(source_h_priv)
|
||||
libmutter_cogl_pango_@LIBMUTTER_API_VERSION@_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_PANGO_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS)
|
||||
libmutter_cogl_pango_@LIBMUTTER_API_VERSION@_la_LIBADD = $(top_builddir)/cogl/libmutter-cogl-$(LIBMUTTER_API_VERSION).la
|
||||
libmutter_cogl_pango_@LIBMUTTER_API_VERSION@_la_LIBADD += $(COGL_DEP_LIBS) $(COGL_PANGO_DEP_LIBS) $(COGL_EXTRA_LDFLAGS)
|
||||
libmutter_cogl_pango_@LIBMUTTER_API_VERSION@_la_LDFLAGS = \
|
||||
-export-dynamic \
|
||||
-rpath $(mutterlibdir) \
|
||||
-export-symbols-regex "^cogl_pango_.*" \
|
||||
@ -49,7 +49,7 @@ cogl_base_includedir = $(includedir)/mutter
|
||||
cogl_pangoheadersdir = $(cogl_base_includedir)/cogl/cogl-pango
|
||||
cogl_pangoheaders_HEADERS = $(source_h)
|
||||
|
||||
pc_files = mutter-cogl-pango-1.0.pc
|
||||
pc_files = mutter-cogl-pango-$(LIBMUTTER_API_VERSION).pc
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = $(pc_files)
|
||||
@ -65,23 +65,23 @@ INTROSPECTION_GIRS =
|
||||
if HAVE_INTROSPECTION
|
||||
INTROSPECTION_COMPILER_ARGS=--includedir=$(top_builddir)/cogl
|
||||
|
||||
CoglPango-1.0.gir: libmutter-cogl-pango.la Makefile
|
||||
CoglPango-@LIBMUTTER_API_VERSION@.gir: libmutter-cogl-pango-$(LIBMUTTER_API_VERSION).la Makefile
|
||||
|
||||
CoglPango_1_0_gir_NAMESPACE = CoglPango
|
||||
CoglPango_1_0_gir_VERSION = 1.0
|
||||
CoglPango_1_0_gir_LIBS = $(top_builddir)/cogl/libmutter-cogl.la libmutter-cogl-pango.la
|
||||
CoglPango_1_0_gir_FILES = $(source_h) $(source_c)
|
||||
CoglPango_1_0_gir_CFLAGS = $(AM_CPPFLAGS) $(COGL_DEP_CFLAGS) $(COGL_PANGO_DEP_CFLAGS)
|
||||
CoglPango_1_0_gir_INCLUDES = Pango-1.0 PangoCairo-1.0
|
||||
CoglPango_1_0_gir_EXPORT_PACKAGES = mutter-cogl-pango-1.0
|
||||
CoglPango_1_0_gir_SCANNERFLAGS = \
|
||||
CoglPango_@LIBMUTTER_API_VERSION@_gir_NAMESPACE = CoglPango
|
||||
CoglPango_@LIBMUTTER_API_VERSION@_gir_VERSION = @LIBMUTTER_API_VERSION@
|
||||
CoglPango_@LIBMUTTER_API_VERSION@_gir_LIBS = $(top_builddir)/cogl/libmutter-cogl-$(LIBMUTTER_API_VERSION).la libmutter-cogl-pango-$(LIBMUTTER_API_VERSION).la
|
||||
CoglPango_@LIBMUTTER_API_VERSION@_gir_FILES = $(source_h) $(source_c)
|
||||
CoglPango_@LIBMUTTER_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(COGL_DEP_CFLAGS) $(COGL_PANGO_DEP_CFLAGS)
|
||||
CoglPango_@LIBMUTTER_API_VERSION@_gir_INCLUDES = Pango-1.0 PangoCairo-1.0
|
||||
CoglPango_@LIBMUTTER_API_VERSION@_gir_EXPORT_PACKAGES = mutter-cogl-pango-@LIBMUTTER_API_VERSION@
|
||||
CoglPango_@LIBMUTTER_API_VERSION@_gir_SCANNERFLAGS = \
|
||||
--warn-all \
|
||||
--identifier-prefix=CoglPango \
|
||||
--symbol-prefix=cogl_pango \
|
||||
--c-include='cogl-pango/cogl-pango.h' \
|
||||
--include-uninstalled=$(top_builddir)/cogl/Cogl-1.0.gir
|
||||
--include-uninstalled=$(top_builddir)/cogl/Cogl-@LIBMUTTER_API_VERSION@.gir
|
||||
|
||||
INTROSPECTION_GIRS += CoglPango-1.0.gir
|
||||
INTROSPECTION_GIRS += CoglPango-@LIBMUTTER_API_VERSION@.gir
|
||||
|
||||
girdir = $(mutterlibdir)
|
||||
gir_DATA = $(INTROSPECTION_GIRS)
|
||||
|
@ -2,12 +2,12 @@ prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@/mutter
|
||||
includedir=@includedir@/mutter
|
||||
apiversion=1.0
|
||||
requires=@COGL_PKG_REQUIRES@ mutter-cogl-1.0
|
||||
apiversion=@LIBMUTTER_API_VERSION@
|
||||
requires=@COGL_PKG_REQUIRES@ mutter-cogl-@LIBMUTTER_API_VERSION@
|
||||
|
||||
Name: Cogl
|
||||
Description: An object oriented GL/GLES Abstraction/Utility Layer
|
||||
Version: @COGL_1_VERSION@
|
||||
Libs: -L${libdir} -lmutter-cogl-pango
|
||||
Version: @MUTTER_VERSION@
|
||||
Libs: -L${libdir} -lmutter-cogl-pango-@LIBMUTTER_API_VERSION@
|
||||
Cflags: -I${includedir}/cogl
|
||||
Requires: ${requires}
|
@ -65,14 +65,14 @@ glib_enum_headers = $(source_1_x_h)
|
||||
include $(top_srcdir)/build/autotools/Makefile.am.enums
|
||||
|
||||
mutterlibdir = $(libdir)/mutter
|
||||
mutterlib_LTLIBRARIES = libmutter-cogl-path.la
|
||||
mutterlib_LTLIBRARIES = libmutter-cogl-path-@LIBMUTTER_API_VERSION@.la
|
||||
|
||||
libmutter_cogl_path_la_SOURCES = $(source_c) $(source_h)
|
||||
nodist_libmutter_cogl_path_la_SOURCES = $(BUILT_SOURCES)
|
||||
libmutter_cogl_path_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS)
|
||||
libmutter_cogl_path_la_LIBADD = $(top_builddir)/cogl/libmutter-cogl.la
|
||||
libmutter_cogl_path_la_LIBADD += $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS)
|
||||
libmutter_cogl_path_la_LDFLAGS = \
|
||||
libmutter_cogl_path_@LIBMUTTER_API_VERSION@_la_SOURCES = $(source_c) $(source_h)
|
||||
nodist_libmutter_cogl_path_@LIBMUTTER_API_VERSION@_la_SOURCES = $(BUILT_SOURCES)
|
||||
libmutter_cogl_path_@LIBMUTTER_API_VERSION@_la_CFLAGS = $(COGL_DEP_CFLAGS) $(COGL_EXTRA_CFLAGS) $(MAINTAINER_CFLAGS)
|
||||
libmutter_cogl_path_@LIBMUTTER_API_VERSION@_la_LIBADD = $(top_builddir)/cogl/libmutter-cogl-$(LIBMUTTER_API_VERSION).la
|
||||
libmutter_cogl_path_@LIBMUTTER_API_VERSION@_la_LIBADD += $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS)
|
||||
libmutter_cogl_path_@LIBMUTTER_API_VERSION@_la_LDFLAGS = \
|
||||
-export-dynamic \
|
||||
-export-symbols-regex "^(cogl|cogl2)_(framebuffer|path|is|clip|[sg]et)_.*" \
|
||||
-no-undefined \
|
||||
@ -94,7 +94,7 @@ cogl_pathheadersdir = $(cogl_base_includedir)/cogl/cogl-path
|
||||
cogl_pathheaders_HEADERS = $(source_h)
|
||||
nodist_cogl_pathheaders_HEADERS = cogl-path-enum-types.h
|
||||
|
||||
pc_files = mutter-cogl-path-1.0.pc
|
||||
pc_files = mutter-cogl-path-$(LIBMUTTER_API_VERSION).pc
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = $(pc_files)
|
||||
|
@ -2,12 +2,12 @@ prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@/mutter
|
||||
includedir=@includedir@/mutter
|
||||
apiversion=1.0
|
||||
requires=@COGL_PKG_REQUIRES@ mutter-cogl-1.0
|
||||
apiversion=@LIBMUTTER_API_VERSION@
|
||||
requires=@COGL_PKG_REQUIRES@ mutter-cogl-@LIBMUTTER_API_VERSION@
|
||||
|
||||
Name: Cogl
|
||||
Description: A 2D path drawing library for Cogl
|
||||
Version: @COGL_1_VERSION@
|
||||
Libs: -L${libdir} -lmutter-cogl-path
|
||||
Version: @MUTTER_VERSION@
|
||||
Libs: -L${libdir} -lmutter-cogl-path-@LIBMUTTER_API_VERSION@
|
||||
Cflags: -I${includedir}/cogl
|
||||
Requires: ${requires}
|
@ -41,7 +41,7 @@ BUILT_SOURCES += cogl-defines.h cogl-egl-defines.h cogl-gl-header.h
|
||||
DISTCLEANFILES += cogl-defines.h cogl-egl-defines.h cogl-gl-header.h
|
||||
EXTRA_DIST += cogl-defines.h.in cogl-egl-defines.h.in cogl-gl-header.h.in
|
||||
|
||||
pc_files = mutter-cogl-1.0.pc
|
||||
pc_files = mutter-cogl-$(LIBMUTTER_API_VERSION).pc
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = $(pc_files)
|
||||
@ -439,23 +439,23 @@ cogl_sources_c += \
|
||||
endif
|
||||
|
||||
mutterlibdir = $(libdir)/mutter
|
||||
mutterlib_LTLIBRARIES = libmutter-cogl.la
|
||||
mutterlib_LTLIBRARIES = libmutter-cogl-@LIBMUTTER_API_VERSION@.la
|
||||
|
||||
libmutter_cogl_la_LIBADD = $(LIBM) $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS)
|
||||
libmutter_cogl_@LIBMUTTER_API_VERSION@_la_LIBADD = $(LIBM) $(COGL_DEP_LIBS) $(COGL_EXTRA_LDFLAGS)
|
||||
if UNIT_TESTS
|
||||
libmutter_cogl_la_LIBADD += $(top_builddir)/test-fixtures/libtest-fixtures.la
|
||||
libmutter_cogl_@LIBMUTTER_API_VERSION@_la_LIBADD += $(top_builddir)/test-fixtures/libtest-fixtures.la
|
||||
endif
|
||||
# XXX: The aim is to eventually get rid of all private API exports
|
||||
# for cogl-pango.
|
||||
libmutter_cogl_la_LDFLAGS = \
|
||||
libmutter_cogl_@LIBMUTTER_API_VERSION@_la_LDFLAGS = \
|
||||
-no-undefined \
|
||||
-avoid-version \
|
||||
-export-dynamic \
|
||||
-rpath $(mutterlibdir) \
|
||||
-export-symbols-regex "^(cogl|_cogl_debug_flags|_cogl_atlas_new|_cogl_atlas_add_reorganize_callback|_cogl_atlas_reserve_space|_cogl_callback|_cogl_util_get_eye_planes_for_screen_poly|_cogl_atlas_texture_remove_reorganize_callback|_cogl_atlas_texture_add_reorganize_callback|_cogl_texture_get_format|_cogl_texture_foreach_sub_texture_in_region|_cogl_profile_trace_message|_cogl_context_get_default|_cogl_framebuffer_get_stencil_bits|_cogl_clip_stack_push_rectangle|_cogl_framebuffer_get_modelview_stack|_cogl_object_default_unref|_cogl_pipeline_foreach_layer_internal|_cogl_clip_stack_push_primitive|_cogl_buffer_unmap_for_fill_or_fallback|_cogl_framebuffer_draw_primitive|_cogl_debug_instances|_cogl_framebuffer_get_projection_stack|_cogl_pipeline_layer_get_texture|_cogl_buffer_map_for_fill_or_fallback|_cogl_texture_can_hardware_repeat|_cogl_pipeline_prune_to_n_layers|_cogl_primitive_draw|test_|unit_test_|_cogl_winsys_glx_get_vtable|_cogl_winsys_egl_xlib_get_vtable|_cogl_winsys_egl_get_vtable|_cogl_closure_disconnect|_cogl_onscreen_notify_complete|_cogl_onscreen_notify_frame_sync|_cogl_winsys_egl_renderer_connect_common|_cogl_winsys_error_quark|_cogl_set_error|_cogl_poll_renderer_add_fd|_cogl_poll_renderer_add_idle|_cogl_framebuffer_winsys_update_size|_cogl_winsys_egl_make_current).*"
|
||||
-export-symbols-regex "^(cogl|_cogl_debug_flags|_cogl_atlas_new|_cogl_atlas_add_reorganize_callback|_cogl_atlas_reserve_space|_cogl_callback|_cogl_util_get_eye_planes_for_screen_poly|_cogl_atlas_texture_remove_reorganize_callback|_cogl_atlas_texture_add_reorganize_callback|_cogl_texture_get_format|_cogl_texture_foreach_sub_texture_in_region|_cogl_texture_set_region|_cogl_profile_trace_message|_cogl_context_get_default|_cogl_framebuffer_get_stencil_bits|_cogl_clip_stack_push_rectangle|_cogl_framebuffer_get_modelview_stack|_cogl_object_default_unref|_cogl_pipeline_foreach_layer_internal|_cogl_clip_stack_push_primitive|_cogl_buffer_unmap_for_fill_or_fallback|_cogl_framebuffer_draw_primitive|_cogl_debug_instances|_cogl_framebuffer_get_projection_stack|_cogl_pipeline_layer_get_texture|_cogl_buffer_map_for_fill_or_fallback|_cogl_texture_can_hardware_repeat|_cogl_pipeline_prune_to_n_layers|_cogl_primitive_draw|test_|unit_test_|_cogl_winsys_glx_get_vtable|_cogl_winsys_egl_xlib_get_vtable|_cogl_winsys_egl_get_vtable|_cogl_closure_disconnect|_cogl_onscreen_notify_complete|_cogl_onscreen_notify_frame_sync|_cogl_winsys_egl_renderer_connect_common|_cogl_winsys_error_quark|_cogl_set_error|_cogl_poll_renderer_add_fd|_cogl_poll_renderer_add_idle|_cogl_framebuffer_winsys_update_size|_cogl_winsys_egl_make_current|_cogl_winsys_egl_ensure_current|_cogl_pixel_format_get_bytes_per_pixel).*"
|
||||
|
||||
libmutter_cogl_la_SOURCES = $(cogl_sources_c)
|
||||
nodist_libmutter_cogl_la_SOURCES = $(BUILT_SOURCES)
|
||||
libmutter_cogl_@LIBMUTTER_API_VERSION@_la_SOURCES = $(cogl_sources_c)
|
||||
nodist_libmutter_cogl_@LIBMUTTER_API_VERSION@_la_SOURCES = $(BUILT_SOURCES)
|
||||
|
||||
# Cogl installed headers
|
||||
cogl_headers = \
|
||||
@ -483,22 +483,22 @@ EXTRA_DIST += \
|
||||
INTROSPECTION_GIRS =
|
||||
|
||||
if HAVE_INTROSPECTION
|
||||
Cogl-1.0.gir: libmutter-cogl.la Makefile
|
||||
Cogl-@LIBMUTTER_API_VERSION@.gir: libmutter-cogl-$(LIBMUTTER_API_VERSION).la Makefile
|
||||
|
||||
Cogl_1_0_gir_NAMESPACE = Cogl
|
||||
Cogl_1_0_gir_VERSION = 1.0
|
||||
Cogl_1_0_gir_LIBS = libmutter-cogl.la
|
||||
Cogl_@LIBMUTTER_API_VERSION@_gir_NAMESPACE = Cogl
|
||||
Cogl_@LIBMUTTER_API_VERSION@_gir_VERSION = $(LIBMUTTER_API_VERSION)
|
||||
Cogl_@LIBMUTTER_API_VERSION@_gir_LIBS = libmutter-cogl-$(LIBMUTTER_API_VERSION).la
|
||||
if UNIT_TESTS
|
||||
Cogl_1_0_gir_LIBS += $(top_builddir)/test-fixtures/libtest-fixtures.la
|
||||
Cogl_@LIBMUTTER_API_VERSION@_gir_LIBS += $(top_builddir)/test-fixtures/libtest-fixtures.la
|
||||
endif
|
||||
Cogl_1_0_gir_FILES = $(cogl_1_public_h)
|
||||
Cogl_@LIBMUTTER_API_VERSION@_gir_FILES = $(cogl_1_public_h)
|
||||
|
||||
Cogl_1_0_gir_CFLAGS = $(AM_CPPFLAGS) $(COGL_DEP_CFLAGS) -UCOGL_COMPILATION -D__COGL_H_INSIDE__ -D__COGL_XLIB_H_INSIDE__ -D__COGL_EGL_H_INSIDE__ -D__COGL_GLX_H_INSIDE__ -DCOGL_GIR_SCANNING
|
||||
Cogl_1_0_gir_INCLUDES = GL-1.0 GObject-2.0
|
||||
Cogl_1_0_gir_EXPORT_PACKAGES = mutter-cogl-1.0
|
||||
Cogl_1_0_gir_SCANNERFLAGS = --warn-all --c-include='cogl/cogl.h'
|
||||
Cogl_@LIBMUTTER_API_VERSION@_gir_CFLAGS = $(AM_CPPFLAGS) $(COGL_DEP_CFLAGS) -UCOGL_COMPILATION -D__COGL_H_INSIDE__ -D__COGL_XLIB_H_INSIDE__ -D__COGL_EGL_H_INSIDE__ -D__COGL_GLX_H_INSIDE__ -DCOGL_GIR_SCANNING
|
||||
Cogl_@LIBMUTTER_API_VERSION@_gir_INCLUDES = GL-1.0 GObject-2.0
|
||||
Cogl_@LIBMUTTER_API_VERSION@_gir_EXPORT_PACKAGES = mutter-cogl-@LIBMUTTER_API_VERSION@
|
||||
Cogl_@LIBMUTTER_API_VERSION@_gir_SCANNERFLAGS = --warn-all --c-include='cogl/cogl.h'
|
||||
|
||||
INTROSPECTION_GIRS += Cogl-1.0.gir
|
||||
INTROSPECTION_GIRS += Cogl-@LIBMUTTER_API_VERSION@.gir
|
||||
|
||||
girdir = $(mutterlibdir)
|
||||
gir_DATA = $(INTROSPECTION_GIRS)
|
||||
|
@ -81,6 +81,19 @@
|
||||
#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
|
||||
#endif
|
||||
|
||||
/* These aren't defined in the GLES2 headers */
|
||||
#ifndef GL_GUILTY_CONTEXT_RESET_ARB
|
||||
#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253
|
||||
#endif
|
||||
|
||||
#ifndef GL_INNOCENT_CONTEXT_RESET_ARB
|
||||
#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254
|
||||
#endif
|
||||
|
||||
#ifndef GL_UNKNOWN_CONTEXT_RESET_ARB
|
||||
#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255
|
||||
#endif
|
||||
|
||||
static void _cogl_context_free (CoglContext *context);
|
||||
|
||||
COGL_OBJECT_DEFINE (Context, context);
|
||||
|
@ -262,6 +262,7 @@ typedef enum _CoglFeatureID
|
||||
COGL_FEATURE_ID_PER_VERTEX_POINT_SIZE,
|
||||
COGL_FEATURE_ID_TEXTURE_RG,
|
||||
COGL_FEATURE_ID_BUFFER_AGE,
|
||||
COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL,
|
||||
|
||||
/*< private >*/
|
||||
_COGL_N_FEATURE_IDS /*< skip >*/
|
||||
|
@ -55,6 +55,13 @@ struct _CoglDriverVtable
|
||||
GLenum *out_glintformat,
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype);
|
||||
CoglPixelFormat
|
||||
(* pixel_format_to_gl_with_target) (CoglContext *context,
|
||||
CoglPixelFormat format,
|
||||
CoglPixelFormat target_format,
|
||||
GLenum *out_glintformat,
|
||||
GLenum *out_glformat,
|
||||
GLenum *out_gltype);
|
||||
|
||||
CoglBool
|
||||
(* update_features) (CoglContext *context,
|
||||
|
@ -152,6 +152,7 @@ typedef long GLsizeiptr;
|
||||
#define GL_POLYGON_OFFSET_FILL 0x8037
|
||||
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
|
||||
#define GL_SAMPLE_COVERAGE 0x80A0
|
||||
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
|
||||
|
||||
/* ErrorCode */
|
||||
#define GL_NO_ERROR 0
|
||||
|
@ -111,6 +111,14 @@ _cogl_glsl_shader_set_source_with_boilerplate (CoglContext *ctx,
|
||||
lengths[count++] = sizeof (texture_3d_extension) - 1;
|
||||
}
|
||||
|
||||
if (cogl_has_feature (ctx, COGL_FEATURE_ID_TEXTURE_EGL_IMAGE_EXTERNAL))
|
||||
{
|
||||
static const char texture_3d_extension[] =
|
||||
"#extension GL_OES_EGL_image_external : require\n";
|
||||
strings[count] = texture_3d_extension;
|
||||
lengths[count++] = sizeof (texture_3d_extension) - 1;
|
||||
}
|
||||
|
||||
if (shader_gl_type == GL_VERTEX_SHADER)
|
||||
{
|
||||
strings[count] = vertex_boilerplate;
|
||||
|
@ -51,6 +51,9 @@ typedef struct _CoglGLXDisplay
|
||||
|
||||
CoglBool found_fbconfig;
|
||||
CoglBool fbconfig_has_rgba_visual;
|
||||
CoglBool is_direct;
|
||||
CoglBool have_vblank_counter;
|
||||
CoglBool can_vblank_wait;
|
||||
GLXFBConfig fbconfig;
|
||||
|
||||
/* Single context for all wins */
|
||||
|
@ -43,8 +43,6 @@ typedef struct _CoglGLXRenderer
|
||||
int glx_error_base;
|
||||
int glx_event_base;
|
||||
|
||||
CoglBool is_direct;
|
||||
|
||||
/* Vblank stuff */
|
||||
int dri_fd;
|
||||
|
||||
|
@ -169,7 +169,8 @@ check_qualcomm_vendor (const CoglGpuInfoStrings *strings)
|
||||
static CoglBool
|
||||
check_nvidia_vendor (const CoglGpuInfoStrings *strings)
|
||||
{
|
||||
if (strcmp (strings->vendor_string, "NVIDIA") != 0)
|
||||
if (strcmp (strings->vendor_string, "NVIDIA") != 0 &&
|
||||
strcmp (strings->vendor_string, "NVIDIA Corporation") != 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
|
@ -1102,7 +1102,7 @@ upload_vertices (CoglJournal *journal,
|
||||
|
||||
attribute_buffer = create_attribute_buffer (journal, needed_vbo_len * 4);
|
||||
buffer = COGL_BUFFER (attribute_buffer);
|
||||
cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_STATIC);
|
||||
cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_DYNAMIC);
|
||||
|
||||
vout = _cogl_buffer_map_range_for_fill_or_fallback (buffer,
|
||||
0, /* offset */
|
||||
|
@ -42,7 +42,8 @@
|
||||
#include <cogl/winsys/cogl-winsys-egl-private.h>
|
||||
#include <cogl/winsys/cogl-winsys-private.h>
|
||||
|
||||
void cogl_renderer_set_custom_winsys (CoglRenderer *renderer,
|
||||
CoglWinsysVtableGetter winsys_vtable_getter);
|
||||
void cogl_renderer_set_custom_winsys (CoglRenderer *renderer,
|
||||
CoglCustomWinsysVtableGetter winsys_vtable_getter,
|
||||
void *user_data);
|
||||
|
||||
#endif /* __COGL_MUTTER_H___ */
|
||||
|
@ -109,7 +109,11 @@ _cogl_object_default_unref (void *object)
|
||||
void
|
||||
cogl_object_unref (void *obj)
|
||||
{
|
||||
void (* unref_func) (void *) = ((CoglObject *) obj)->klass->virt_unref;
|
||||
void (* unref_func) (void *);
|
||||
|
||||
_COGL_RETURN_IF_FAIL (obj != NULL);
|
||||
|
||||
unref_func = ((CoglObject *) obj)->klass->virt_unref;
|
||||
unref_func (obj);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user