Compare commits
914 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20f7118432 | ||
|
|
37e6c3f0cb | ||
|
|
0459dda5c2 | ||
|
|
a10c816c05 | ||
|
|
c0c7cfacc2 | ||
|
|
8cdb6647ed | ||
|
|
b68e3c85b9 | ||
|
|
ef25d5bbd5 | ||
|
|
278bf6e897 | ||
|
|
90a985b73a | ||
|
|
b016353809 | ||
|
|
bc222af2e2 | ||
|
|
44599c9460 | ||
|
|
902fc22670 | ||
|
|
d84e22fbf1 | ||
|
|
6cc720a350 | ||
|
|
c905978874 | ||
|
|
bfe595a8e8 | ||
|
|
94d56d1a9e | ||
|
|
bd3f0b5363 | ||
|
|
6fae3545c7 | ||
|
|
297963f6ab | ||
|
|
a0ceba407e | ||
|
|
35fa91fba2 | ||
|
|
a5d6cd169e | ||
|
|
06c2263657 | ||
|
|
472c6f6b8d | ||
|
|
afcaca85da | ||
|
|
2575349ec2 | ||
|
|
77054f688d | ||
|
|
c5cb24378f | ||
|
|
d66123dd14 | ||
|
|
4ef8f11f9e | ||
|
|
599be7ddc9 | ||
|
|
685497fc8c | ||
|
|
57542fc204 | ||
|
|
8d9323aec6 | ||
|
|
4984a25b19 | ||
|
|
3bdcb29e01 | ||
|
|
b9ab8e6348 | ||
|
|
4a851701e9 | ||
|
|
eafd8af937 | ||
|
|
28bb123be8 | ||
|
|
8e1ed2f8c3 | ||
|
|
4a0fcb3cff | ||
|
|
b5c2163238 | ||
|
|
d0ecdfb330 | ||
|
|
bdf7d98a36 | ||
|
|
e4b0980d15 | ||
|
|
d99c57aeae | ||
|
|
5f855ce547 | ||
|
|
68f3b6fbeb | ||
|
|
dc6d14943e | ||
|
|
05f7334db9 | ||
|
|
cd707e9335 | ||
|
|
505ed5e43b | ||
|
|
9dc8bf5f62 | ||
|
|
f8098662b6 | ||
|
|
de7a0e86c4 | ||
|
|
ca55438fda | ||
|
|
a4b60e7eef | ||
|
|
5d22e07738 | ||
|
|
bdade7e151 | ||
|
|
6958ded4c4 | ||
|
|
cc06104be6 | ||
|
|
059c34c345 | ||
|
|
9cbb726566 | ||
|
|
e8b4356a88 | ||
|
|
634138cd3b | ||
|
|
3f6b07de81 | ||
|
|
d218900b57 | ||
|
|
cab949a939 | ||
|
|
e350822f5e | ||
|
|
3d6fe93297 | ||
|
|
3a5baf2722 | ||
|
|
cdb472cb56 | ||
|
|
e634350e77 | ||
|
|
464a6c1441 | ||
|
|
d3750b2244 | ||
|
|
b8d2b76ee4 | ||
|
|
14fb7c3201 | ||
|
|
922bc62e0e | ||
|
|
00cae4ccd1 | ||
|
|
61df266df7 | ||
|
|
17751666f2 | ||
|
|
961b2c9b65 | ||
|
|
eaf6f06047 | ||
|
|
d0ac218c05 | ||
|
|
1a01bc15d8 | ||
|
|
cdbe2f13ca | ||
|
|
4f5264277e | ||
|
|
bed3adcc95 | ||
|
|
0c5d59bcf6 | ||
|
|
ff20acd8b8 | ||
|
|
d1cffcde68 | ||
|
|
546dd9b225 | ||
|
|
2a666620c8 | ||
|
|
db50985040 | ||
|
|
8c6d593c41 | ||
|
|
40086c8d1c | ||
|
|
38f73b9f5e | ||
|
|
49429b5f49 | ||
|
|
d9f90ef077 | ||
|
|
6a126fa18e | ||
|
|
14d703f5cc | ||
|
|
9850025f3a | ||
|
|
8daab0ba41 | ||
|
|
88f25ccc76 | ||
|
|
50e7351c73 | ||
|
|
51453a54e4 | ||
|
|
c02ba03f39 | ||
|
|
78dec3d698 | ||
|
|
1590c59131 | ||
|
|
b26f79998a | ||
|
|
489f3e6c9d | ||
|
|
5fef4726a7 | ||
|
|
51fdb8200a | ||
|
|
fb0d98ead1 | ||
|
|
4096caba64 | ||
|
|
38f77144fa | ||
|
|
b8041ce17f | ||
|
|
00575733c8 | ||
|
|
621c92780c | ||
|
|
37f03af4b7 | ||
|
|
bdc4558a43 | ||
|
|
46d483e8b2 | ||
|
|
5143b62a07 | ||
|
|
87ed774cb4 | ||
|
|
4e427d05b7 | ||
|
|
195d987331 | ||
|
|
9b58317fb1 | ||
|
|
1cb15dedac | ||
|
|
5521d6b623 | ||
|
|
f5cf6c1dcb | ||
|
|
89307727e7 | ||
|
|
c30c21b250 | ||
|
|
b6fb087d7e | ||
|
|
97c2b7c1fe | ||
|
|
81506640c8 | ||
|
|
8244f7cd58 | ||
|
|
63573d6e26 | ||
|
|
9368f7f670 | ||
|
|
b7a11035d5 | ||
|
|
2e1b5e2fa7 | ||
|
|
8e5cbafe63 | ||
|
|
eb006a6688 | ||
|
|
40b9049deb | ||
|
|
64ffca2d0a | ||
|
|
1f4b6d4e9a | ||
|
|
eb30ba7722 | ||
|
|
3e0f4d36bc | ||
|
|
1fb118edee | ||
|
|
ca39634880 | ||
|
|
f8418d68a6 | ||
|
|
c0000fb24e | ||
|
|
c169f7ae83 | ||
|
|
7ab5244bf5 | ||
|
|
7e36489034 | ||
|
|
d259b12ae7 | ||
|
|
8f8138d9bd | ||
|
|
a8668f5fbf | ||
|
|
e00e6bd1c2 | ||
|
|
0fc6c47556 | ||
|
|
d530dccb96 | ||
|
|
37bf0e81d2 | ||
|
|
f872f955b0 | ||
|
|
003cd0a203 | ||
|
|
e7173f8145 | ||
|
|
93af102bec | ||
|
|
67f23664c9 | ||
|
|
39f6071c68 | ||
|
|
edc8878632 | ||
|
|
93b62c4dfd | ||
|
|
c3e210c80f | ||
|
|
9a5cc8f650 | ||
|
|
5e7fbfefe9 | ||
|
|
29ad6fba22 | ||
|
|
c848c3ee0d | ||
|
|
547132131a | ||
|
|
40186fb54b | ||
|
|
5dc4e79c8d | ||
|
|
556992a117 | ||
|
|
a41ef8d513 | ||
|
|
6d96a89328 | ||
|
|
0fb1481038 | ||
|
|
4b77530c65 | ||
|
|
cdb493cf50 | ||
|
|
c9a574a764 | ||
|
|
bdb633a882 | ||
|
|
37aee7133d | ||
|
|
2cfd55f3ce | ||
|
|
2e8188e89d | ||
|
|
1e172caea3 | ||
|
|
6866cd0fb8 | ||
|
|
2719926870 | ||
|
|
406891abcc | ||
|
|
4be6e9009a | ||
|
|
6a31909557 | ||
|
|
f49f0d19f9 | ||
|
|
a2407f94e4 | ||
|
|
62a0be4a11 | ||
|
|
b9029f6c67 | ||
|
|
92496f42c9 | ||
|
|
841c907efc | ||
|
|
9bc288cd8e | ||
|
|
2ef0391b08 | ||
|
|
6db768d1a3 | ||
|
|
9b080950a9 | ||
|
|
3cd1fef4cb | ||
|
|
a491a801bf | ||
|
|
41ebb72276 | ||
|
|
e4c0e9073e | ||
|
|
efad733cc5 | ||
|
|
1fcd6e1811 | ||
|
|
75d697fa97 | ||
|
|
cde69670ba | ||
|
|
0be6c9cb97 | ||
|
|
8c9d2d3ca2 | ||
|
|
c84e73d8e6 | ||
|
|
3fb00f6c70 | ||
|
|
86305fdeb3 | ||
|
|
710e146d22 | ||
|
|
d5abc84bea | ||
|
|
6f8214c15c | ||
|
|
a56475e32f | ||
|
|
9dadd91887 | ||
|
|
df5a73bb35 | ||
|
|
a50bf59a2c | ||
|
|
241354ae52 | ||
|
|
c863116011 | ||
|
|
5cbd591a1e | ||
|
|
6bb78c9499 | ||
|
|
893f406a99 | ||
|
|
f722b898b0 | ||
|
|
18335b3eac | ||
|
|
4708b592e2 | ||
|
|
7598a2965c | ||
|
|
1b59761a19 | ||
|
|
7fd1053e0f | ||
|
|
e178e7f6a5 | ||
|
|
d0bf21ab16 | ||
|
|
c826965833 | ||
|
|
a76db39c19 | ||
|
|
323a538bdd | ||
|
|
2435feca3b | ||
|
|
29d059680c | ||
|
|
aaaf7f9d8b | ||
|
|
bc90ce569a | ||
|
|
27f9f1756b | ||
|
|
9135387cfa | ||
|
|
af3504e05c | ||
|
|
9c9eac9d46 | ||
|
|
f28383206a | ||
|
|
ba1c093d18 | ||
|
|
3ea3a85694 | ||
|
|
0e1a423889 | ||
|
|
3ce68ed53f | ||
|
|
90c10da398 | ||
|
|
630bf28c22 | ||
|
|
ff89c1d8e4 | ||
|
|
96703c23c8 | ||
|
|
2b78f5adad | ||
|
|
ab7df777eb | ||
|
|
adbc694ff8 | ||
|
|
7709cdb12b | ||
|
|
f6051f73f5 | ||
|
|
d5c2a21cdf | ||
|
|
8ffc841a3a | ||
|
|
6c478977bb | ||
|
|
07beb53b37 | ||
|
|
59df1a8647 | ||
|
|
fb98aa650d | ||
|
|
9981b5a9c6 | ||
|
|
603533e632 | ||
|
|
38bc90f724 | ||
|
|
721beb9202 | ||
|
|
2e99259589 | ||
|
|
83e6b75872 | ||
|
|
cf70946f50 | ||
|
|
f1c36aba83 | ||
|
|
2973cf15a4 | ||
|
|
55969bc3c5 | ||
|
|
a8504c971a | ||
|
|
1644de2083 | ||
|
|
dd1fb85f60 | ||
|
|
b945b19865 | ||
|
|
91bf9f2ec8 | ||
|
|
f151f4c165 | ||
|
|
95b9b2d373 | ||
|
|
8be698681c | ||
|
|
da3e1a3730 | ||
|
|
29f637c19a | ||
|
|
3d01565ba7 | ||
|
|
962291cc8e | ||
|
|
a662dace9c | ||
|
|
d34e0b325e | ||
|
|
4c242ec528 | ||
|
|
658be9405f | ||
|
|
15e8f6ad8a | ||
|
|
a5aca35f1c | ||
|
|
ae9df1ffac | ||
|
|
8bf2e098f5 | ||
|
|
7091d554b5 | ||
|
|
bada795320 | ||
|
|
7d385849fb | ||
|
|
78775b7f6b | ||
|
|
8d21a5b6b3 | ||
|
|
9da095ca50 | ||
|
|
0fafc07db0 | ||
|
|
65b95999c1 | ||
|
|
056012871f | ||
|
|
c7b377080c | ||
|
|
47acc9ff2f | ||
|
|
fe62700825 | ||
|
|
6bcab56988 | ||
|
|
fbc4d3e1be | ||
|
|
c89d1643f4 | ||
|
|
e2226a1509 | ||
|
|
656916e0fa | ||
|
|
4a55eb9e7f | ||
|
|
9c8cf04a80 | ||
|
|
e846bc9308 | ||
|
|
3c7a71772c | ||
|
|
857a53e80f | ||
|
|
84fcabe5cf | ||
|
|
9dc410c9fd | ||
|
|
8ebad06e7e | ||
|
|
5db1a07f81 | ||
|
|
48e5c8edb3 | ||
|
|
eefc21920e | ||
|
|
d7dd9c295b | ||
|
|
4faf71bd03 | ||
|
|
2751dbdb94 | ||
|
|
fe329cb4ab | ||
|
|
741e719ff8 | ||
|
|
866bb32046 | ||
|
|
7f01e758b3 | ||
|
|
03003d270e | ||
|
|
3d313016ba | ||
|
|
1292c752a8 | ||
|
|
4783947135 | ||
|
|
c9045788f5 | ||
|
|
4eed8463b3 | ||
|
|
303711ab8d | ||
|
|
98d7fc9f39 | ||
|
|
c0a96f2087 | ||
|
|
c509ecca52 | ||
|
|
e5d8eb7845 | ||
|
|
277f43aed6 | ||
|
|
f1494b64e5 | ||
|
|
6b9c71ec62 | ||
|
|
d12a4b0a1a | ||
|
|
a75d075dd1 | ||
|
|
8f8a37bf94 | ||
|
|
03f692fed8 | ||
|
|
614416d4b0 | ||
|
|
feb851716e | ||
|
|
2b095f720e | ||
|
|
d6e750727f | ||
|
|
961ff8633d | ||
|
|
8406d4a8f1 | ||
|
|
e25b64ae15 | ||
|
|
59205a4caf | ||
|
|
5001797179 | ||
|
|
b24dd69067 | ||
|
|
4f163338dd | ||
|
|
1e8f1f8cc6 | ||
|
|
5c3e2e6877 | ||
|
|
ff52ff7865 | ||
|
|
f6f55aaa9a | ||
|
|
6f1aecab99 | ||
|
|
f33205a490 | ||
|
|
2920638a3d | ||
|
|
1ae32b5742 | ||
|
|
4e9dabfb25 | ||
|
|
ca2c419c9b | ||
|
|
020c1311ca | ||
|
|
8193b2a44b | ||
|
|
324a000777 | ||
|
|
951b1c1e83 | ||
|
|
8e57fd93c6 | ||
|
|
d262f43b5b | ||
|
|
73224e7d95 | ||
|
|
19463c81a3 | ||
|
|
6f2bb31068 | ||
|
|
abf9c4117d | ||
|
|
39f50830d7 | ||
|
|
c2fd7005cb | ||
|
|
52f2ed33f5 | ||
|
|
a51239c6ae | ||
|
|
e6217e1428 | ||
|
|
f61dfb0828 | ||
|
|
00fe963e7c | ||
|
|
009ea1c8cd | ||
|
|
72069015b9 | ||
|
|
6c0c67dd7b | ||
|
|
3c090519a0 | ||
|
|
5da70929f6 | ||
|
|
5b66d6209f | ||
|
|
9f7f353485 | ||
|
|
05f01525c3 | ||
|
|
3aa016940c | ||
|
|
a792c94ccf | ||
|
|
249e59b310 | ||
|
|
3b43b76222 | ||
|
|
398f5cfbdc | ||
|
|
bc47be64b0 | ||
|
|
59c6fb9ce7 | ||
|
|
8b99d0a432 | ||
|
|
639b18c7e8 | ||
|
|
701942f6ef | ||
|
|
9d8e6a2b30 | ||
|
|
581deb6073 | ||
|
|
9849a69afd | ||
|
|
5f33d907aa | ||
|
|
0919eda640 | ||
|
|
5952a140e0 | ||
|
|
6d92996661 | ||
|
|
04e4b0c469 | ||
|
|
20f4a9a942 | ||
|
|
5552679c11 | ||
|
|
1369a36178 | ||
|
|
529337e00a | ||
|
|
fe882dad15 | ||
|
|
4fff84b4b9 | ||
|
|
3e964163c0 | ||
|
|
10a987b908 | ||
|
|
03e417e1be | ||
|
|
c95d3b19b3 | ||
|
|
1fa9b8f102 | ||
|
|
c27cf31a7c | ||
|
|
ad672fc9d6 | ||
|
|
a0f298ddb0 | ||
|
|
9b740849ed | ||
|
|
a3f9835b7b | ||
|
|
f4294b83fb | ||
|
|
4fa4a20b22 | ||
|
|
af2c9a49b1 | ||
|
|
bdeec61266 | ||
|
|
268e5cef3b | ||
|
|
b37f4333e2 | ||
|
|
f0c663d42d | ||
|
|
e36e44ab3a | ||
|
|
2dceec444f | ||
|
|
eaba3cff0b | ||
|
|
ec31a348cf | ||
|
|
d6a6e26500 | ||
|
|
cab1ba4e50 | ||
|
|
a2f589be00 | ||
|
|
7622cbaed5 | ||
|
|
53df123c0d | ||
|
|
c660840c19 | ||
|
|
c6d3ede57e | ||
|
|
6037167336 | ||
|
|
0804447881 | ||
|
|
83482873dc | ||
|
|
5e351e4d65 | ||
|
|
408cd9cf9b | ||
|
|
8b47e63136 | ||
|
|
379ec88776 | ||
|
|
a320e8bc25 | ||
|
|
1c4f5b471d | ||
|
|
d5846282a9 | ||
|
|
8b56f1ced6 | ||
|
|
0987a536b1 | ||
|
|
099510f4d1 | ||
|
|
35c6014025 | ||
|
|
895ac26d43 | ||
|
|
da999f730b | ||
|
|
47969e9f18 | ||
|
|
b6267d4a8c | ||
|
|
2df97e309b | ||
|
|
078b23e6aa | ||
|
|
d8eeed2296 | ||
|
|
e5afc5297a | ||
|
|
465ed48e73 | ||
|
|
f8b311b289 | ||
|
|
934336e642 | ||
|
|
6f5ff05c56 | ||
|
|
2376b7c255 | ||
|
|
ef86f8a20c | ||
|
|
b3f1acd400 | ||
|
|
5c4462281e | ||
|
|
91d94f262c | ||
|
|
2651acce91 | ||
|
|
25cfcdba76 | ||
|
|
6f5004fc13 | ||
|
|
df9c1aea64 | ||
|
|
a309069b6b | ||
|
|
beb90f2c55 | ||
|
|
0e0aba7a5e | ||
|
|
6e9b41314e | ||
|
|
dbeac923ed | ||
|
|
5953c2097d | ||
|
|
8969206450 | ||
|
|
41318d763b | ||
|
|
8251b906b6 | ||
|
|
790d630d17 | ||
|
|
c9644039b1 | ||
|
|
34de072a10 | ||
|
|
f6d7b3aa04 | ||
|
|
5c31c2b98e | ||
|
|
2cc779b667 | ||
|
|
7f4294f68c | ||
|
|
fd2515da5c | ||
|
|
db1f53fc29 | ||
|
|
96f5c66755 | ||
|
|
4baf7b5bba | ||
|
|
58bb5a7d1f | ||
|
|
c63dd76814 | ||
|
|
8d3e6b4796 | ||
|
|
b10312e249 | ||
|
|
6f3a9d6d29 | ||
|
|
c4e89d9d0c | ||
|
|
00a2126152 | ||
|
|
e7099cc771 | ||
|
|
b6724ed177 | ||
|
|
fcedc9f5c3 | ||
|
|
cb095be0cc | ||
|
|
ecf2c86787 | ||
|
|
971c28ce97 | ||
|
|
482129ff35 | ||
|
|
65c75859bc | ||
|
|
fcb26e5dc7 | ||
|
|
0dc6ac26c3 | ||
|
|
48303bac75 | ||
|
|
5ab8a665be | ||
|
|
733158a2de | ||
|
|
a2e47d2d0e | ||
|
|
bfb97a6e6f | ||
|
|
fc1a8351b0 | ||
|
|
be7a4a5868 | ||
|
|
493892a4df | ||
|
|
106dc2b03b | ||
|
|
d5490475f1 | ||
|
|
999a6a288c | ||
|
|
7d9d096fbf | ||
|
|
c129dd9331 | ||
|
|
5c75ac0a96 | ||
|
|
bafedf8376 | ||
|
|
136f15e647 | ||
|
|
e9e4ac13ee | ||
|
|
e24c758341 | ||
|
|
4b65b4ac2b | ||
|
|
d8d7765a82 | ||
|
|
b98bc1c787 | ||
|
|
4b08ce2a09 | ||
|
|
ed62e72a98 | ||
|
|
a28710c1fc | ||
|
|
764a058cf6 | ||
|
|
a538663679 | ||
|
|
8920d64f7d | ||
|
|
a051cb9ee3 | ||
|
|
56864cdfb7 | ||
|
|
428c600788 | ||
|
|
748f1a90b9 | ||
|
|
d3cee832ce | ||
|
|
8129246a10 | ||
|
|
a2789650e5 | ||
|
|
af376cf27e | ||
|
|
6c8ccbd73a | ||
|
|
626ac0d5b8 | ||
|
|
2550bc910d | ||
|
|
0a153e2524 | ||
|
|
facd353228 | ||
|
|
5b7eac280c | ||
|
|
7ab63525c7 | ||
|
|
a1c49a0f7f | ||
|
|
4c4c6ab0e6 | ||
|
|
2e0d39b512 | ||
|
|
0899019518 | ||
|
|
db16996181 | ||
|
|
aa2b21456f | ||
|
|
7e8e1e9e89 | ||
|
|
01e9702958 | ||
|
|
6d970c1175 | ||
|
|
16c0871e22 | ||
|
|
fd7ddc2905 | ||
|
|
c181919a57 | ||
|
|
5955b44c74 | ||
|
|
8b5f02bb0b | ||
|
|
f2a1ff2584 | ||
|
|
11522ccc92 | ||
|
|
bb97c589c1 | ||
|
|
4a5a9b2888 | ||
|
|
b1bd581065 | ||
|
|
3bd1ca0ac3 | ||
|
|
bbeb08ba08 | ||
|
|
66dbdf4b40 | ||
|
|
f0a2c34eca | ||
|
|
9f35b9281b | ||
|
|
7624578c21 | ||
|
|
d4b477ad78 | ||
|
|
e6d5eea7eb | ||
|
|
bef9490fa8 | ||
|
|
d593ccba2f | ||
|
|
1902d8bb19 | ||
|
|
f10c65f1bf | ||
|
|
da507dfd19 | ||
|
|
13254ac4d5 | ||
|
|
fc9ffb3115 | ||
|
|
f64ffcac48 | ||
|
|
f2a6cb3dbb | ||
|
|
4767d2b8d6 | ||
|
|
1ceb8b1b0b | ||
|
|
719a9a5b64 | ||
|
|
5adf7c2a3a | ||
|
|
1c9d6bf9e6 | ||
|
|
f85dfe91a9 | ||
|
|
749fb84053 | ||
|
|
e33af8b2f8 | ||
|
|
61a9f7baae | ||
|
|
4d4b690a99 | ||
|
|
d4c2293d56 | ||
|
|
3b34cec64c | ||
|
|
a1e9b854e3 | ||
|
|
01ed1e1604 | ||
|
|
b7b1a1f1c6 | ||
|
|
c9446727d3 | ||
|
|
cff79bc9d4 | ||
|
|
72ccf87d19 | ||
|
|
2387c71b3c | ||
|
|
47a2120023 | ||
|
|
b777353766 | ||
|
|
5d4491667b | ||
|
|
9fbd14f815 | ||
|
|
f38b27e923 | ||
|
|
cb8116e2af | ||
|
|
2066dd0077 | ||
|
|
37afd7aaa7 | ||
|
|
8df9ccc72c | ||
|
|
862075bd65 | ||
|
|
27ffed5a1a | ||
|
|
bf2c50b58b | ||
|
|
34c35ff4ca | ||
|
|
174a45b4bd | ||
|
|
e44b331cc3 | ||
|
|
aed504efdc | ||
|
|
ca38568187 | ||
|
|
a653c17e8a | ||
|
|
6bbd33eca4 | ||
|
|
494235750e | ||
|
|
076c81c4ee | ||
|
|
abd4de7311 | ||
|
|
4629ef627f | ||
|
|
b1c2e90a05 | ||
|
|
c19cbaad24 | ||
|
|
1a3fdac4e4 | ||
|
|
d343981faa | ||
|
|
51c0c51884 | ||
|
|
cb2d162bec | ||
|
|
6507fd1ac2 | ||
|
|
442f2adf23 | ||
|
|
702613915b | ||
|
|
8ebc9553c3 | ||
|
|
ae8076e411 | ||
|
|
f3974671f6 | ||
|
|
dcb2d95f9a | ||
|
|
c8bb7aae40 | ||
|
|
4711e10df2 | ||
|
|
28f1b8a7a0 | ||
|
|
104e213934 | ||
|
|
fe3a432845 | ||
|
|
423f8e59cc | ||
|
|
1c468b2931 | ||
|
|
85faad5ec7 | ||
|
|
869152750c | ||
|
|
7fd4ec50c9 | ||
|
|
8de4dd334b | ||
|
|
c5cc208397 | ||
|
|
718e6fa93d | ||
|
|
0833697c49 | ||
|
|
112ae0edab | ||
|
|
502c31b408 | ||
|
|
062563a562 | ||
|
|
c385532b10 | ||
|
|
81f4b4cece | ||
|
|
23482e3cf4 | ||
|
|
b49b34c4c1 | ||
|
|
b40ca5800d | ||
|
|
3b25081353 | ||
|
|
5726466db3 | ||
|
|
27acd4c7d4 | ||
|
|
f98d780f3e | ||
|
|
8177cfac2a | ||
|
|
fb4123a6f2 | ||
|
|
191913b7eb | ||
|
|
3a3f745d31 | ||
|
|
eebe12a972 | ||
|
|
274dd2f3fe | ||
|
|
fb5dbc811b | ||
|
|
c31c32f921 | ||
|
|
22b756753a | ||
|
|
cb7eb48768 | ||
|
|
22ed014123 | ||
|
|
419b078104 | ||
|
|
b51584525a | ||
|
|
728dbbfff0 | ||
|
|
7485269c37 | ||
|
|
cffaa54a78 | ||
|
|
1f597fd2b3 | ||
|
|
48d792bc19 | ||
|
|
5da123c632 | ||
|
|
27887ada45 | ||
|
|
4c9a6ed56c | ||
|
|
1bf2864638 | ||
|
|
c8bd61b345 | ||
|
|
7ee04b37ac | ||
|
|
5957befaad | ||
|
|
17a16ccd21 | ||
|
|
1de940d7b4 | ||
|
|
9a2ff9e419 | ||
|
|
84caf787aa | ||
|
|
e9d0d40809 | ||
|
|
0e2a5c63c6 | ||
|
|
9916802a69 | ||
|
|
bfac482940 | ||
|
|
8778cf63c4 | ||
|
|
d5d1e6c11e | ||
|
|
8e6780e761 | ||
|
|
ddb961f9af | ||
|
|
670de085a3 | ||
|
|
4c49573465 | ||
|
|
13d478ffca | ||
|
|
1cc95a605c | ||
|
|
e19f180c71 | ||
|
|
d3ad15dc51 | ||
|
|
3aaa69b36c | ||
|
|
41906cf7db | ||
|
|
f3696da0ff | ||
|
|
fab723b9bc | ||
|
|
d3a3a89098 | ||
|
|
68313e99a7 | ||
|
|
9b73d25151 | ||
|
|
440db8f4bd | ||
|
|
6690c4f916 | ||
|
|
6d3ad7d903 | ||
|
|
0d60b88f1d | ||
|
|
aa82d8fddd | ||
|
|
10f5461cd8 | ||
|
|
c7a0626c69 | ||
|
|
6a9a7dee55 | ||
|
|
8952afd6cc | ||
|
|
526c526bf3 | ||
|
|
12e269e791 | ||
|
|
c2f6450af3 | ||
|
|
c8dfe955d7 | ||
|
|
71091e73a4 | ||
|
|
25d1b2328f | ||
|
|
4085fe2e8e | ||
|
|
74445674f2 | ||
|
|
c343bdd120 | ||
|
|
5ff4a6f4d8 | ||
|
|
5172597d96 | ||
|
|
a09fb7b20d | ||
|
|
af9e633d56 | ||
|
|
df62478418 | ||
|
|
c623cd5d01 | ||
|
|
3126f31cbf | ||
|
|
c33c88b2c6 | ||
|
|
36d5afef9f | ||
|
|
c8ed52f600 | ||
|
|
8d7e083e64 | ||
|
|
2144f43142 | ||
|
|
66d2930b7e | ||
|
|
4dcaec0997 | ||
|
|
33da5ca869 | ||
|
|
4c1a69a98c | ||
|
|
d613962f5b | ||
|
|
8f7cef1232 | ||
|
|
7a91ba3699 | ||
|
|
14018a5e54 | ||
|
|
81a03fcea8 | ||
|
|
48962a58ae | ||
|
|
8c9c777ad3 | ||
|
|
dc6e276e39 | ||
|
|
8182fcecd2 | ||
|
|
4d082dbf80 | ||
|
|
5b5c49d317 | ||
|
|
51b5510669 | ||
|
|
7a4b438dc6 | ||
|
|
1a29de5ac9 | ||
|
|
ed8edf3e4c | ||
|
|
9fcde9d81d | ||
|
|
81ffa7e948 | ||
|
|
93d2d30867 | ||
|
|
42e05c5ad2 | ||
|
|
d37e815f13 | ||
|
|
a1f454937c | ||
|
|
b041dcc8ce | ||
|
|
22c65c5d03 | ||
|
|
60b64dadfe | ||
|
|
edb25314c5 | ||
|
|
19bce0c23c | ||
|
|
8ceb941051 | ||
|
|
8b28cbb30c | ||
|
|
de130787f6 | ||
|
|
6e94dae9cd | ||
|
|
d2431783f1 | ||
|
|
5787b472c0 | ||
|
|
6bdfc0387b | ||
|
|
7ba98344b6 | ||
|
|
c887df6ab4 | ||
|
|
a8ad4461a1 | ||
|
|
32a0e28686 | ||
|
|
df13f0ce5a | ||
|
|
972f0c0e2b | ||
|
|
c7a3a4d421 | ||
|
|
fbccfb9d0d | ||
|
|
9fdd8e4ae4 | ||
|
|
6b6dea5190 | ||
|
|
5af551c96d | ||
|
|
6761fdca1a | ||
|
|
725da39ecb | ||
|
|
9005fc359d | ||
|
|
33e4a44008 | ||
|
|
3bddb9d95b | ||
|
|
fa01e0b76f | ||
|
|
f8f188ecff | ||
|
|
07935d9bd3 | ||
|
|
a827f4190c | ||
|
|
18c108ed03 | ||
|
|
2d70059f47 | ||
|
|
63ff3cfb9f | ||
|
|
ca70f22d46 | ||
|
|
c247a6c0cc | ||
|
|
7421a0b9e3 | ||
|
|
30b5e8bf8f | ||
|
|
96475ce3ee | ||
|
|
24669fb6af | ||
|
|
851885568f | ||
|
|
8efbc479e1 | ||
|
|
2167bfd5b5 | ||
|
|
490d4455af | ||
|
|
c94e06ccd2 | ||
|
|
ea37799fb0 | ||
|
|
d00fbd73fc | ||
|
|
361b23e3f1 | ||
|
|
8feccdf63f | ||
|
|
ed905fcf6d | ||
|
|
50a6abaac1 | ||
|
|
718f7e77a1 | ||
|
|
c4aeb1adba | ||
|
|
d9c69f0a54 | ||
|
|
5afdbbe6f1 | ||
|
|
4273cb35bf | ||
|
|
89be7a031d | ||
|
|
06c5127856 | ||
|
|
fd298256d7 | ||
|
|
e0246044b7 | ||
|
|
2f677990b2 | ||
|
|
da2e4c8503 | ||
|
|
a1eb236616 | ||
|
|
11186735c2 | ||
|
|
a038f62a5b | ||
|
|
f45acc055e | ||
|
|
43a25c49c4 | ||
|
|
e47e2b2560 | ||
|
|
7652065134 | ||
|
|
d0da418e49 | ||
|
|
77e72cfd9a | ||
|
|
7b2ecb0498 | ||
|
|
318c5bca67 | ||
|
|
d52da934ca | ||
|
|
21951e3668 | ||
|
|
64bef38813 | ||
|
|
fe67e3dde7 | ||
|
|
fc5e74e457 | ||
|
|
fdbd8df7b2 | ||
|
|
246972b59f | ||
|
|
6057296499 | ||
|
|
b4b2207b93 | ||
|
|
b881364c50 | ||
|
|
76059882c4 | ||
|
|
be71f5f1f4 | ||
|
|
021dfcad39 | ||
|
|
4e7498b854 | ||
|
|
494035c94b | ||
|
|
9c4230ad9c | ||
|
|
056c2c12bb | ||
|
|
a97c440872 | ||
|
|
653d823175 | ||
|
|
c2a2dbc88c | ||
|
|
77492d31cf | ||
|
|
aaa609109e | ||
|
|
2367fad90b | ||
|
|
aaa521bd24 | ||
|
|
d22686da10 | ||
|
|
48b93ab28f | ||
|
|
703a1b83a8 | ||
|
|
c9441bd3e2 | ||
|
|
9de6d619ee | ||
|
|
9aae31ef2f | ||
|
|
dca04c549b | ||
|
|
69e76d6eeb | ||
|
|
b4a93c67c9 | ||
|
|
f098e6c973 | ||
|
|
f8ebba3954 | ||
|
|
37ee693de2 | ||
|
|
f77ad2b41d | ||
|
|
e99eb2e72b | ||
|
|
86b89072f3 | ||
|
|
022bee0560 | ||
|
|
204ea44946 | ||
|
|
3f2489b306 | ||
|
|
291a2d6295 | ||
|
|
b244d13e8a | ||
|
|
b33324d07c | ||
|
|
ae2a641db5 | ||
|
|
1cac757365 | ||
|
|
992de77040 | ||
|
|
f6b5e54890 | ||
|
|
d20c65ef80 | ||
|
|
4a8562a85f |
104
.circleci/config.yml
Normal file
104
.circleci/config.yml
Normal file
@@ -0,0 +1,104 @@
|
||||
version: 2
|
||||
|
||||
jobs:
|
||||
|
||||
lin-sys:
|
||||
docker:
|
||||
- image: kovidgoyal/kitty-test:latest
|
||||
steps:
|
||||
- checkout
|
||||
- run: if grep -Inr '\s$' kitty kitty_tests kittens docs *.py *.asciidoc *.rst .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
|
||||
- run: python3 -m flake8 --count .
|
||||
- run: python3 setup.py build --debug --verbose
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
- run: make FAIL_WARN=-W man
|
||||
- run: make FAIL_WARN=-W html
|
||||
|
||||
lin-package:
|
||||
docker:
|
||||
- image: kovidgoyal/kitty-test:latest
|
||||
steps:
|
||||
- checkout
|
||||
- run: python3 setup.py linux-package --update-check-interval=0
|
||||
|
||||
lin-35:
|
||||
docker:
|
||||
- image: kovidgoyal/kitty-test:latest
|
||||
environment:
|
||||
CC: gcc
|
||||
CFLAGS: -funsigned-char
|
||||
LD_LIBRARY_PATH: /opt/py3.5/lib
|
||||
ASAN_OPTIONS: leak_check_at_exit=0
|
||||
steps:
|
||||
- checkout
|
||||
- run: /opt/py3.5/bin/python3 setup.py build --debug --verbose --sanitize
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
|
||||
lin-37:
|
||||
docker:
|
||||
- image: kovidgoyal/kitty-test:latest
|
||||
environment:
|
||||
CC: clang
|
||||
LD_LIBRARY_PATH: /opt/py3.7/lib
|
||||
ASAN_OPTIONS: leak_check_at_exit=0
|
||||
steps:
|
||||
- checkout
|
||||
- run: /opt/py3.7/bin/python3 setup.py build --debug --verbose --sanitize
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
|
||||
lin-bundle:
|
||||
docker:
|
||||
- image: kovidgoyal/kitty-test:latest
|
||||
environment:
|
||||
ASAN_OPTIONS: leak_check_at_exit=0
|
||||
steps:
|
||||
- checkout
|
||||
- run: echo "export LD_LIBRARY_PATH=$SW/lib" >> $BASH_ENV
|
||||
- run: echo "export PKG_CONFIG_PATH=$SW/lib/pkgconfig" >> $BASH_ENV
|
||||
- run: echo "export PYTHONHOME=$SW" >> $BASH_ENV
|
||||
- run: $SW/bin/python3 setup.py build --debug --verbose
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
|
||||
mac-bundle:
|
||||
macos:
|
||||
xcode: "10.1.0"
|
||||
environment:
|
||||
LC_ALL: en_US.UTF-8
|
||||
LANG: en_US.UTF-8
|
||||
SW: /Users/Shared/buildbot/sw/sw
|
||||
steps:
|
||||
- checkout
|
||||
- run: mkdir -p $SW
|
||||
- run: curl https://download.calibre-ebook.com/travis/kitty/osx.tar.xz | tar xJ -C $SW
|
||||
- run: echo "export PATH=$SW/bin:$PATH" >> $BASH_ENV
|
||||
- run: python3 setup.py build --debug --verbose
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
|
||||
mac-brew:
|
||||
macos:
|
||||
xcode: "10.2.0"
|
||||
environment:
|
||||
LC_ALL: en_US.UTF-8
|
||||
LANG: en_US.UTF-8
|
||||
steps:
|
||||
- checkout
|
||||
- run: brew bundle
|
||||
- run: python3 setup.py build --debug --verbose
|
||||
- run: ./kitty/launcher/kitty +launch test.py
|
||||
- run: echo "export PATH=/usr/local/opt/sphinx-doc/bin:$PATH" >> $BASH_ENV
|
||||
- run: python3 setup.py linux-package --verbose
|
||||
- run: python3 setup.py kitty.app --verbose
|
||||
- run: kitty.app/Contents/MacOS/kitty +runpy "from kitty.constants import *; print(kitty_exe())"
|
||||
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
all_jobs:
|
||||
jobs:
|
||||
- mac-bundle
|
||||
- lin-sys
|
||||
- lin-35
|
||||
- lin-37
|
||||
- lin-package
|
||||
- lin-bundle
|
||||
- mac-brew
|
||||
55
.circleci/images/Dockerfile
Normal file
55
.circleci/images/Dockerfile
Normal file
@@ -0,0 +1,55 @@
|
||||
# When changing this file, go to
|
||||
# https://cloud.docker.com/repository/docker/kovidgoyal/kitty-test/builds and
|
||||
# click the "Trigger" button under Automated builds to rebuild
|
||||
FROM ubuntu:latest
|
||||
|
||||
# make Apt non-interactive
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/90circleci \
|
||||
&& echo 'DPkg::Options "--force-confnew";' >> /etc/apt/apt.conf.d/90circleci \
|
||||
&& echo 'Acquire::Languages "none";' >> /etc/apt/apt.conf.d/90circleci
|
||||
|
||||
# System setup
|
||||
RUN apt-get update && mkdir -p /usr/share/man/man1 && apt-get install -y python3-flake8 python3-pip python3-pil clang git apt locales sudo openssh-client ca-certificates tar gzip parallel net-tools netcat unzip zip bzip2 gnupg curl wget build-essential apt-utils
|
||||
|
||||
# Setup circleci user
|
||||
RUN groupadd --gid 3434 circleci \
|
||||
&& useradd --uid 3434 --gid circleci --shell /bin/bash --create-home circleci \
|
||||
&& echo 'circleci ALL=NOPASSWD: ALL' >> /etc/sudoers.d/50-circleci \
|
||||
&& echo 'Defaults env_keep += "DEBIAN_FRONTEND"' >> /etc/sudoers.d/env_keep \
|
||||
&& echo 'Defaults env_keep += "SW"' >> /etc/sudoers.d/env_keep \
|
||||
&& echo 'Defaults env_keep += "LANG"' >> /etc/sudoers.d/env_keep
|
||||
|
||||
# Set timezone to UTC by default
|
||||
RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime
|
||||
|
||||
# Use unicode
|
||||
RUN locale-gen en_US.UTF-8 || true
|
||||
ENV LANG=en_US.UTF-8
|
||||
|
||||
# Deps needed for building python
|
||||
RUN apt-get install -y libreadline-dev zlib1g-dev libssl-dev libbz2-dev libsqlite3-dev libffi-dev
|
||||
|
||||
# kitty deps
|
||||
RUN apt-get install -y libgl1-mesa-dev libxi-dev libxrandr-dev libxinerama-dev libxcursor-dev libxcb-xkb-dev libdbus-1-dev libxkbcommon-dev libharfbuzz-dev libpng-dev libfontconfig-dev libpython3-dev libxkbcommon-x11-dev python3-pygments libcanberra-dev
|
||||
|
||||
# Needed to build kitty docs
|
||||
RUN pip3 install sphinx
|
||||
|
||||
# Install multiple pythons
|
||||
ADD install-python.py /tmp/install-python.py
|
||||
RUN python3 /tmp/install-python.py py3.5 https://www.python.org/ftp/python/3.5.6/Python-3.5.6.tar.xz
|
||||
RUN python3 /tmp/install-python.py py3.7 https://www.python.org/ftp/python/3.7.2/Python-3.7.2.tar.xz
|
||||
|
||||
# Install kitty bundle
|
||||
ENV SW=/home/circleci/sw
|
||||
RUN python3 /tmp/install-python.py bundle https://download.calibre-ebook.com/travis/kitty/linux-64.tar.xz
|
||||
RUN echo SW=$SW >> /etc/environment
|
||||
|
||||
# Clean unused files
|
||||
RUN apt-get clean -y
|
||||
|
||||
USER circleci
|
||||
|
||||
LABEL com.circleci.preserve-entrypoint=true
|
||||
ENTRYPOINT sleep 2h
|
||||
60
.circleci/images/install-python.py
Normal file
60
.circleci/images/install-python.py
Normal file
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import io
|
||||
import os
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
from urllib.request import urlopen
|
||||
|
||||
PY, URL = sys.argv[1], sys.argv[2]
|
||||
if PY == 'bundle':
|
||||
SW = os.environ['SW']
|
||||
os.mkdir(SW)
|
||||
os.chdir(SW)
|
||||
else:
|
||||
os.chdir('/usr/src')
|
||||
|
||||
|
||||
def run(cmd):
|
||||
cmd = shlex.split(cmd)
|
||||
p = subprocess.Popen(cmd)
|
||||
if p.wait() != 0:
|
||||
raise SystemExit(p.returncode)
|
||||
|
||||
|
||||
with urlopen(URL) as f:
|
||||
data = f.read()
|
||||
|
||||
with tarfile.open(fileobj=io.BytesIO(data), mode='r:xz') as tf:
|
||||
tf.extractall()
|
||||
|
||||
|
||||
def replace_in_file(path, src, dest):
|
||||
with open(path, 'r+') as f:
|
||||
n = f.read().replace(src, dest)
|
||||
f.seek(0), f.truncate()
|
||||
f.write(n)
|
||||
|
||||
|
||||
if PY == 'bundle':
|
||||
replaced = 0
|
||||
for dirpath, dirnames, filenames in os.walk(SW):
|
||||
for f in filenames:
|
||||
if f.endswith('.pc') or (f.endswith('.py') and f.startswith('_sysconfig')):
|
||||
replace_in_file(os.path.join(dirpath, f), '/sw/sw', SW)
|
||||
replaced += 1
|
||||
if replaced < 2:
|
||||
raise SystemExit('Failed to replace path to SW in bundle')
|
||||
else:
|
||||
src = os.path.abspath(tuple(os.listdir('.'))[0])
|
||||
os.chdir(src)
|
||||
run(f'./configure --prefix=/opt/{PY} --enable-shared --with-system-expat --without-ensurepip')
|
||||
run(f'make -j {os.cpu_count()}')
|
||||
run('make install')
|
||||
os.chdir('/')
|
||||
shutil.rmtree(src)
|
||||
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
patreon: kovidgoyal
|
||||
liberapay: kovidgoyal
|
||||
custom: https://sw.kovidgoyal.net/kitty/support.html
|
||||
28
.gitignore
vendored
28
.gitignore
vendored
@@ -1,19 +1,17 @@
|
||||
*.so
|
||||
*.pyc
|
||||
*.pyo
|
||||
tags
|
||||
build
|
||||
linux-package
|
||||
kitty.app
|
||||
logo/*.iconset
|
||||
compile_commands.json
|
||||
glad/out
|
||||
asan-launcher
|
||||
asan-launcher.dSYM
|
||||
kitty-profile
|
||||
dev
|
||||
__pycache__
|
||||
glfw/wayland-*-client-protocol.[ch]
|
||||
docs/_build
|
||||
docs/generated
|
||||
/tags
|
||||
/build/
|
||||
/linux-package/
|
||||
/kitty.app/
|
||||
/compile_commands.json
|
||||
/link_commands.json
|
||||
/glad/out/
|
||||
/kitty/launcher/
|
||||
/*.dSYM/
|
||||
__pycache__/
|
||||
/glfw/wayland-*-client-protocol.[ch]
|
||||
/docs/_build/
|
||||
/docs/generated/
|
||||
.DS_Store
|
||||
|
||||
171
.travis.yml
171
.travis.yml
@@ -1,171 +0,0 @@
|
||||
git:
|
||||
depth: false
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
- os: linux
|
||||
dist: trusty
|
||||
group: beta
|
||||
language: python
|
||||
sudo: false
|
||||
env: USE_BUNDLE=1 SW=$HOME/sw PKG_CONFIG_PATH=$SW/lib/pkgconfig LD_LIBRARY_PATH=$SW/lib PYTHON=$SW/bin/python3
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libxi-dev
|
||||
- libxrandr-dev
|
||||
- libxinerama-dev
|
||||
- libxcursor-dev
|
||||
- libxcb-xkb-dev
|
||||
- libdbus-1-dev
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
group: beta
|
||||
sudo: false
|
||||
env:
|
||||
- CC=gcc CFLAGS=-funsigned-char SANITIZE_ARG=--sanitize
|
||||
language: python
|
||||
python: "3.5"
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libfontconfig1-dev
|
||||
- libharfbuzz-dev
|
||||
- libxi-dev
|
||||
- libxrandr-dev
|
||||
- libxinerama-dev
|
||||
- libxcursor-dev
|
||||
- libxcb-xkb-dev
|
||||
- libpng-dev
|
||||
- libdbus-1-dev
|
||||
- python3-pil
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
group: beta
|
||||
sudo: false
|
||||
env:
|
||||
- CC=clang SANITIZE_ARG=--sanitize
|
||||
language: python
|
||||
python: "3.5"
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libfontconfig1-dev
|
||||
- libharfbuzz-dev
|
||||
- libxi-dev
|
||||
- libxrandr-dev
|
||||
- libxinerama-dev
|
||||
- libxcursor-dev
|
||||
- libxcb-xkb-dev
|
||||
- libpng-dev
|
||||
- libdbus-1-dev
|
||||
- python3-pil
|
||||
|
||||
- os: linux
|
||||
dist: trusty
|
||||
group: beta
|
||||
sudo: false
|
||||
env:
|
||||
- RUN_FLAKE=1 BUILD_PKG=linux-package
|
||||
language: python
|
||||
python: "3.6"
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- libfontconfig1-dev
|
||||
- libharfbuzz-dev
|
||||
- libxi-dev
|
||||
- libxrandr-dev
|
||||
- libxinerama-dev
|
||||
- libxcursor-dev
|
||||
- libxcb-xkb-dev
|
||||
- libpng-dev
|
||||
- libdbus-1-dev
|
||||
- python3-pil
|
||||
- clang
|
||||
- os: osx
|
||||
language: generic
|
||||
env: SWBASE=/Users/Shared/buildbot/sw SW=$SWBASE/sw PATH=$SW/bin:$PATH
|
||||
|
||||
# Disabled because harfbuzz is currently broken in brew
|
||||
# - os: osx
|
||||
# language: generic
|
||||
# env: USE_BREW=1 BUILD_PKG=osx-bundle
|
||||
|
||||
env:
|
||||
global:
|
||||
- PYTHON=python3
|
||||
- PKG_CONFIG_PATH=$HOME/harfbuzz/lib/pkgconfig:$PKG_CONFIG_PATH
|
||||
- LD_LIBRARY_PATH=$HOME/harfbuzz/lib:$LD_LIBRARY_PATH
|
||||
- ASAN_OPTIONS=leak_check_at_exit=0
|
||||
|
||||
install: |
|
||||
set -e
|
||||
if [[ "$RUN_FLAKE" == "1" ]]; then pip install flake8; fi
|
||||
if [[ "$TRAVIS_OS_NAME" == 'osx' ]]; then
|
||||
if [[ "$USE_BREW" == "1" ]]; then
|
||||
brew update;
|
||||
# brew upgrade python;
|
||||
brew install harfbuzz --without-graphite2 --without-icu4c --without-freetype;
|
||||
brew install imagemagick
|
||||
brew install optipng
|
||||
brew install librsvg
|
||||
logo/make.py
|
||||
else
|
||||
mkdir -p $SW;
|
||||
curl https://download.calibre-ebook.com/travis/kitty/osx.tar.xz | tar xJ -C $SW;
|
||||
fi
|
||||
else
|
||||
if [[ "$USE_BUNDLE" == "1" ]]; then
|
||||
mkdir -p $SW;
|
||||
curl https://download.calibre-ebook.com/travis/kitty/linux-64.tar.xz | tar xJ -C $SW;
|
||||
find $SW -type f -name '*.pc' -exec sed -i "s,/sw/sw,$SW,g" {} \;;
|
||||
find $SW -type f -name '_sysconfig*.py' -exec sed -i "s,/sw/sw,$SW,g" {} \;;
|
||||
else
|
||||
pushd /tmp
|
||||
wget --no-check-certificate http://xkbcommon.org/download/libxkbcommon-0.6.1.tar.xz
|
||||
tar xf libxkbcommon-0.6.1.tar.xz
|
||||
cd libxkbcommon-0.6.1
|
||||
./configure --prefix=$HOME/harfbuzz --disable-dependency-tracking --disable-static
|
||||
make -j2
|
||||
make install
|
||||
wget https://github.com/behdad/harfbuzz/releases/download/1.6.3/harfbuzz-1.6.3.tar.bz2
|
||||
tar xf harfbuzz-1.6.3.tar.bz2
|
||||
cd harfbuzz-1.6.3
|
||||
./configure --prefix=$HOME/harfbuzz --disable-dependency-tracking --disable-static --with-glib=no --with-gobject=no --with-cairo=no --with-fontconfig=no --with-icu=no --with-directwrite=no --with-freetype=yes
|
||||
make -j2
|
||||
make install
|
||||
cd ..
|
||||
popd
|
||||
fi
|
||||
if [[ "$BUILD_PKG" == "linux-package" ]]; then
|
||||
pip install sphinx
|
||||
fi
|
||||
fi
|
||||
pkg-config --cflags harfbuzz
|
||||
if [[ "$TRAVIS_OS_NAME" != 'osx' ]]; then
|
||||
PLIB=$(ldd `which python` | grep libpython | cut -d ' ' -f 3)
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`dirname $PLIB`
|
||||
fi
|
||||
set +e
|
||||
|
||||
before_script:
|
||||
- echo LD_LIBRARY_PATH=$LD_LIBRARY_PATH PKG_CONFIG_PATH=$PKG_CONFIG_PATH
|
||||
- $PYTHON setup.py build --debug --verbose $SANITIZE_ARG;
|
||||
|
||||
script: |
|
||||
set -e
|
||||
|
||||
if grep -Inr '\s$' kitty kitty_tests kittens docs *.py *.asciidoc *.rst .gitattributes .gitignore; then echo Trailing whitespace found, aborting.; exit 1; fi
|
||||
|
||||
if [[ -z "$SANITIZE_ARG" ]]; then $PYTHON test.py; else ./asan-launcher test.py; fi
|
||||
|
||||
if [[ "$RUN_FLAKE" == "1" ]]; then flake8 --count .; fi
|
||||
|
||||
if [[ "$BUILD_PKG" == "linux-package" ]]; then make FAIL_WARN=-W man && make FAIL_WARN=-W html; fi
|
||||
|
||||
if [[ ! -z "$BUILD_PKG" ]]; then $PYTHON setup.py $BUILD_PKG; fi
|
||||
|
||||
set +e
|
||||
5
Brewfile
Normal file
5
Brewfile
Normal file
@@ -0,0 +1,5 @@
|
||||
brew 'pkg-config'
|
||||
brew 'imagemagick'
|
||||
brew 'harfbuzz'
|
||||
brew 'python'
|
||||
brew 'sphinx-doc'
|
||||
8
LICENSE
8
LICENSE
@@ -1,7 +1,7 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
<https://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
14
Makefile
14
Makefile
@@ -1,8 +1,8 @@
|
||||
ifdef V
|
||||
VVAL=--verbose
|
||||
VVAL=--verbose
|
||||
endif
|
||||
ifdef VERBOSE
|
||||
VVAL=--verbose
|
||||
VVAL=--verbose
|
||||
endif
|
||||
|
||||
all:
|
||||
@@ -18,6 +18,9 @@ clean:
|
||||
debug:
|
||||
python3 setup.py build $(VVAL) --debug
|
||||
|
||||
debug-event-loop:
|
||||
python3 setup.py build $(VVAL) --debug --extra-logging=event-loop
|
||||
|
||||
# Build with the ASAN and UBSAN sanitizers
|
||||
asan:
|
||||
python3 setup.py build $(VVAL) --debug --sanitize
|
||||
@@ -25,12 +28,7 @@ asan:
|
||||
profile:
|
||||
python3 setup.py build $(VVAL) --profile
|
||||
|
||||
logo/kitty.iconset/icon_256x256.png: logo/kitty.svg logo/make.py
|
||||
logo/make.py
|
||||
|
||||
rendered_logo: logo/kitty.iconset/icon_256x256.png
|
||||
|
||||
app: rendered_logo
|
||||
app:
|
||||
python3 setup.py kitty.app $(VVAL)
|
||||
|
||||
man:
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
See https://sw.kovidgoyal.net/kitty
|
||||
|
||||
image::https://travis-ci.org/kovidgoyal/kitty.svg?branch=master[Build status, link=https://travis-ci.org/kovidgoyal/kitty]
|
||||
image:https://circleci.com/gh/kovidgoyal/kitty.svg?style=svg["Build status", link="https://circleci.com/gh/kovidgoyal/kitty"]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
@@ -88,7 +88,7 @@ def setup_openssl_environment():
|
||||
# Workaround for Linux distros that have still failed to get their heads
|
||||
# out of their asses and implement a common location for SSL certificates.
|
||||
# It's not that hard people, there exists a wonderful tool called the symlink
|
||||
# See http://www.mobileread.com/forums/showthread.php?t=256095
|
||||
# See https://www.mobileread.com/forums/showthread.php?t=256095
|
||||
if 'SSL_CERT_FILE' not in os.environ and 'SSL_CERT_DIR' not in os.environ:
|
||||
if os.access('/etc/pki/tls/certs/ca-bundle.crt', os.R_OK):
|
||||
os.environ['SSL_CERT_FILE'] = '/etc/pki/tls/certs/ca-bundle.crt'
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* linux-launcher.c
|
||||
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#define MAX_ARGC 1024
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
wchar_t *argvw[MAX_ARGC + 1] = {0};
|
||||
argvw[0] = L"kitty";
|
||||
for (int i = 1; i < argc; i++) argvw[i] = Py_DecodeLocale(argv[i], NULL);
|
||||
int ret = Py_Main(argc, argvw);
|
||||
for (int i = 1; i < argc; i++) PyMem_RawFree(argvw[i]);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,24 +1,48 @@
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
base = os.path.dirname(os.path.abspath(__file__))
|
||||
os.chdir(base)
|
||||
sys.path.insert(0, base)
|
||||
|
||||
from kitty.terminfo import generate_terminfo # noqa
|
||||
def compile_terminfo(base):
|
||||
with tempfile.TemporaryDirectory() as tdir:
|
||||
proc = subprocess.run(['tic', '-x', '-o' + tdir, 'terminfo/kitty.terminfo'], check=True, stderr=subprocess.PIPE)
|
||||
regex = '^"terminfo/kitty.terminfo", line [0-9]+, col [0-9]+, terminal \'xterm-kitty\': older tic versions may treat the description field as an alias$'
|
||||
for error in proc.stderr.decode('utf-8').splitlines():
|
||||
if not re.match(regex, error):
|
||||
print(error, file=sys.stderr)
|
||||
tfiles = glob.glob(os.path.join(tdir, '*', 'xterm-kitty'))
|
||||
if not tfiles:
|
||||
raise SystemExit('tic failed to output the compiled kitty terminfo file')
|
||||
|
||||
with open('terminfo/kitty.terminfo', 'w') as f:
|
||||
f.write(generate_terminfo())
|
||||
tfile = tfiles[0]
|
||||
directory, xterm_kitty = os.path.split(tfile)
|
||||
_, directory = os.path.split(directory)
|
||||
odir = os.path.join(base, directory)
|
||||
os.makedirs(odir, exist_ok=True)
|
||||
ofile = os.path.join(odir, xterm_kitty)
|
||||
shutil.move(tfile, ofile)
|
||||
|
||||
os.environ['TERMINFO'] = os.path.join(base, 'terminfo')
|
||||
subprocess.check_call(['tic', '-x', 'terminfo/kitty.terminfo'])
|
||||
# On OS X tic puts the compiled database into a different directory
|
||||
try:
|
||||
os.mkdir('terminfo/78')
|
||||
except FileExistsError:
|
||||
pass
|
||||
shutil.copy2('terminfo/x/xterm-kitty', 'terminfo/78')
|
||||
|
||||
def generate_terminfo():
|
||||
base = os.path.dirname(os.path.abspath(__file__))
|
||||
os.chdir(base)
|
||||
sys.path.insert(0, base)
|
||||
|
||||
from kitty.terminfo import generate_terminfo
|
||||
|
||||
with open('terminfo/kitty.terminfo', 'w') as f:
|
||||
f.write(generate_terminfo())
|
||||
|
||||
compile_terminfo(os.path.join(base, 'terminfo'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
generate_terminfo()
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
cloc --exclude-list-file <(echo -e 'kitty/wcwidth-std.h\nkitty/glfw.c\nkitty/keys.h\nkitty/charsets.c\nkitty/unicode-data.c\nkitty/key_encoding.py\nkitty/rgb.py\nkitty/gl.h\nkitty/gl-wrapper.h\nkitty/gl-wrapper.c\nkitty/khrplatform.h\nkitty/glfw-wrapper.h\nkitty/glfw-wrapper.c\nkitty/emoji.h\nkittens/unicode_input/names.h') kitty kittens
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS = -T $(FAIL_WARN)
|
||||
SPHINXBUILD = python3 .. +launch :sphinx-build
|
||||
SPHINXOPTS = -j auto -T $(FAIL_WARN)
|
||||
SPHINXBUILD = sphinx-build
|
||||
SPHINXPROJ = kitty
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
9
docs/_templates/layout.html
vendored
9
docs/_templates/layout.html
vendored
@@ -1,13 +1,6 @@
|
||||
{% extends "!layout.html" %}
|
||||
|
||||
{%- block extrahead %}
|
||||
<!-- Google Analytics -->
|
||||
<script>
|
||||
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
|
||||
ga('create', 'UA-20736318-2', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
<script async="async" src='https://www.google-analytics.com/analytics.js'></script>
|
||||
<!-- End Google Analytics -->
|
||||
<!-- kitty analytics placeholder -->
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Building kitty from source
|
||||
==============================
|
||||
|
||||
.. image:: https://travis-ci.org/kovidgoyal/kitty.svg?branch=master
|
||||
.. image:: https://circleci.com/gh/kovidgoyal/kitty.svg?style=svg
|
||||
:alt: Build status
|
||||
:target: https://travis-ci.org/kovidgoyal/kitty
|
||||
:target: https://circleci.com/gh/kovidgoyal/kitty
|
||||
|
||||
|
||||
|kitty| is designed to run from source, for easy hackability. Make sure
|
||||
@@ -20,6 +20,7 @@ Run-time dependencies:
|
||||
* libpng
|
||||
* freetype (not needed on macOS)
|
||||
* fontconfig (not needed on macOS)
|
||||
* libcanberra (not needed on macOS)
|
||||
* ImageMagick (optional, needed to use the ``kitty icat`` tool to display images in the terminal)
|
||||
* pygments (optional, need for syntax highlighting in ``kitty +kitten diff``)
|
||||
|
||||
@@ -28,7 +29,7 @@ Build-time dependencies:
|
||||
* gcc or clang
|
||||
* pkg-config
|
||||
* For building on Linux in addition to the above dependencies you might also need to install the ``-dev`` packages for:
|
||||
``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev``, ``libxkbcommon-x11-dev``, ``libfontconfig-dev`` and ``libpython-dev``.
|
||||
``libdbus-1-dev``, ``libxcursor-dev``, ``libxrandr-dev``, ``libxi-dev``, ``libxinerama-dev``, ``libgl1-mesa-dev``, ``libxkbcommon-x11-dev``, ``libfontconfig-dev``, ``libcanberra-dev`` and ``libpython-dev``.
|
||||
if they are not already installed by your distro.
|
||||
|
||||
Install and run from source
|
||||
@@ -44,25 +45,17 @@ Now build the native code parts of |kitty| with the following command::
|
||||
|
||||
You can run |kitty|, as::
|
||||
|
||||
python3 .
|
||||
./kitty/launcher/kitty
|
||||
|
||||
If that works, you can create a script to launch |kitty|:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
#!/usr/bin/env python3
|
||||
import runpy
|
||||
runpy.run_path('/path/to/kitty/dir', run_name='__main__')
|
||||
|
||||
And place it in :file:`~/bin` or :file:`/usr/bin` so that you can run |kitty| using
|
||||
If that works, you can create a symlink to the launcher in :file:`~/bin` or
|
||||
some other directory on your PATH so that you can run |kitty| using
|
||||
just ``kitty``.
|
||||
|
||||
|
||||
Building kitty.app on macOS from source
|
||||
-------------------------------------------
|
||||
|
||||
Install `imagemagick`, `optipng` and `librsvg` using `brew` or similar (needed
|
||||
for the logo generation step). And run::
|
||||
Run::
|
||||
|
||||
make app
|
||||
|
||||
@@ -107,7 +100,13 @@ without needing to install all of |kitty|.
|
||||
development package of :file:`ncurses`. Also, if you are building from
|
||||
a git checkout instead of the released source code tarball, you will
|
||||
need :file:`sphinx-build` from the `Sphinx documentation generator
|
||||
<http://www.sphinx-doc.org/>`_.
|
||||
<https://www.sphinx-doc.org/>`_.
|
||||
|
||||
This applies to creating packages for |kitty| for macOS package managers such as
|
||||
brew or MacPorts as well.
|
||||
|
||||
|
||||
.. note::
|
||||
|kitty| has its own update check mechanism, if you would like to turn
|
||||
it off for your package, use
|
||||
``python3 setup.py linux-package --update-check-interval=0``
|
||||
|
||||
@@ -2,6 +2,393 @@ Changelog
|
||||
==============
|
||||
|
||||
|kitty| is a feature full, cross-platform, *fast*, GPU based terminal emulator.
|
||||
To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
|
||||
0.14.4 [2019-08-31]
|
||||
---------------------
|
||||
|
||||
- hints kitten: Add a :option:`kitty +kitten hints --alphabet` option to
|
||||
control what alphabets are used for hints (:iss:`1879`)
|
||||
|
||||
- hints kitten: Allow specifying :option:`kitty +kitten hints --program`
|
||||
multiple times to run multiple programs (:iss:`1879`)
|
||||
|
||||
- Add a :opt:`kitten_alias` option that can be used to alias kitten invocation
|
||||
for brevity and to change kitten option defaults globally (:iss:`1879`)
|
||||
|
||||
- macOS: Add an option :opt:`macos_show_window_title_in` to control
|
||||
showing the window title in the menubar/titlebar (:pull:`1837`)
|
||||
|
||||
- macOS: Allow drag and drop of text from other applications into kitty
|
||||
(:pull:`1921`)
|
||||
|
||||
- When running kittens, use the colorscheme of the current window
|
||||
rather than the configured colorscheme (:iss:`1906`)
|
||||
|
||||
- Don't fail to start if running the shell to read the EDITOR env var fails
|
||||
(:iss:`1869`)
|
||||
|
||||
- Disable the ``liga`` and ``dlig`` OpenType features for broken fonts
|
||||
such as Nimbus Mono.
|
||||
|
||||
- Fix a regression that broke setting background_opacity via remote control
|
||||
(:iss:`1895`)
|
||||
|
||||
- Fix piping PNG images into the icat kitten not working (:iss:`1920`)
|
||||
|
||||
- When the OS returns a fallback font that does not actually contain glyphs
|
||||
for the text, do not exhaust the list of fallback fonts (:iss:`1918`)
|
||||
|
||||
- Fix formatting attributes not reset across line boundaries when passing
|
||||
buffer as ANSI (:iss:`1924`)
|
||||
|
||||
|
||||
0.14.3 [2019-07-29]
|
||||
---------------------
|
||||
|
||||
- Remote control: Add a command `kitty @ scroll-window` to scroll windows
|
||||
|
||||
- Allow passing a ``!neighbor`` argument to the new_window mapping to open a
|
||||
new window next to the active window (:iss:`1746`)
|
||||
|
||||
- Document the kitty remote control protocol (:iss:`1646`)
|
||||
|
||||
- Add a new option :opt:`pointer_shape_when_grabbed` that allows you to control
|
||||
the mouse pointer shape when the terminal programs grabs the pointer
|
||||
(:iss:`1808`)
|
||||
|
||||
- Add an option :opt:`terminal_select_modifiers` to control which modifiers
|
||||
are used to override mouse selection even when a terminal application has
|
||||
grabbed the mouse (:iss:`1774`)
|
||||
|
||||
- When piping data to a child in the pipe command do it in a thread so as not
|
||||
to block the UI (:iss:`1708`)
|
||||
|
||||
- unicode_input kitten: Fix a regression that broke using indices to select
|
||||
recently used symbols.
|
||||
|
||||
- Fix a regression that caused closing an overlay window to focus
|
||||
the previously focused window rather than the underlying window (:iss:`1720`)
|
||||
|
||||
- macOS: Reduce energy consumption when idle by shutting down Apple's display
|
||||
link thread after 30 second of inactivity (:iss:`1763`)
|
||||
|
||||
- Linux: Fix incorrect scaling for fallback fonts when the font has an
|
||||
underscore that renders out of bounds (:iss:`1713`)
|
||||
|
||||
- macOS: Fix finding fallback font for private use unicode symbols not working
|
||||
reliably (:iss:`1650`)
|
||||
|
||||
- Fix an out of bounds read causing a crash when selecting text with the mouse
|
||||
in the alternate screen mode (:iss:`1578`)
|
||||
|
||||
- Linux: Use the system "bell" sound for the terminal bell. Adds libcanberra
|
||||
as a new dependency to play the system sound.
|
||||
|
||||
- macOS: Fix a rare deadlock causing kitty to hang (:iss:`1779`)
|
||||
|
||||
- Linux: Fix a regression in 0.14.0 that caused the event loop to tick
|
||||
continuously, wasting CPU even when idle (:iss:`1782`)
|
||||
|
||||
- ssh kitten: Make argument parsing more like ssh (:iss:`1787`)
|
||||
|
||||
- When using :opt:`strip_trailing_spaces` do not remove empty lines
|
||||
(:iss:`1802`)
|
||||
|
||||
- Fix a crash when displaying very large number of images (:iss:`1825`)
|
||||
|
||||
|
||||
0.14.2 [2019-06-09]
|
||||
---------------------
|
||||
|
||||
- Add an option :opt:`placement_strategy` to control how the cell area is
|
||||
aligned inside the window when the window size is not an exact multiple
|
||||
of the cell size (:pull:`1670`)
|
||||
|
||||
- hints kitten: Add a :option:`kitty +kitten hints --multiple-joiner` option to
|
||||
control how multiple selections are serialized when copying to clipboard
|
||||
or inserting into the terminal. You can have them on separate lines,
|
||||
separated by arbitrary characters, or even serialized as JSON (:iss:`1665`)
|
||||
|
||||
- macOS: Fix a regression in the previous release that broke using
|
||||
:kbd:`ctrl+shift+tab` (:iss:`1671`)
|
||||
|
||||
- panel kitten: Fix the contents of the panel kitten not being positioned
|
||||
correctly on the vertical axis
|
||||
|
||||
- icat kitten: Fix a regression that broke passing directories to icat
|
||||
(:iss:`1683`)
|
||||
|
||||
- clipboard kitten: Add a :option:`kitty +kitten clipboard --wait-for-completion`
|
||||
option to have the kitten wait till copying to clipboard is complete
|
||||
(:iss:`1693`)
|
||||
|
||||
- Allow using the :doc:`pipe <pipe>` command to send screen and scrollback
|
||||
contents directly to the clipboard (:iss:`1693`)
|
||||
|
||||
- Linux: Disable the Wayland backend on GNOME by default as GNOME has no
|
||||
support for server side decorations. Can be controlled by
|
||||
:opt:`linux_display_server`.
|
||||
|
||||
- Add an option to control the default :opt:`update_check_interval` when
|
||||
building kitty packages
|
||||
|
||||
- Wayland: Fix resizing the window on a compositor that does not provide
|
||||
server side window decorations, such a GNOME or Weston not working
|
||||
correctly (:iss:`1659`)
|
||||
|
||||
- Wayland: Fix crash when enabling disabling monitors on sway (:iss:`1696`)
|
||||
|
||||
|
||||
0.14.1 [2019-05-29]
|
||||
---------------------
|
||||
|
||||
- Add an option :opt:`command_on_bell` to run an arbitrary command when
|
||||
a bell occurs (:iss:`1660`)
|
||||
|
||||
- Add a shortcut to toggle maximized window state :sc:`toggle_maximized`
|
||||
|
||||
- Add support for the underscore key found in some keyboard layouts
|
||||
(:iss:`1639`)
|
||||
|
||||
- Fix a missing newline when using the pipe command between the
|
||||
scrollback and screen contents (:iss:`1642`)
|
||||
|
||||
- Fix colors not being preserved when using the pipe command with
|
||||
the pager history buffer (:pull:`1657`)
|
||||
|
||||
- macOS: Fix a regression that could cause rendering of a kitty window
|
||||
to occasionally freeze in certain situations, such as moving it between
|
||||
monitors or transitioning from/to fullscreen (:iss:`1641`)
|
||||
|
||||
- macOS: Fix a regression that caused :kbd:`cmd+v` to double up in the dvorak
|
||||
keyboard layout (:iss:`1652`)
|
||||
|
||||
- When resizing and only a single window is present in the current layout,
|
||||
use that window's background color to fill in the blank areas.
|
||||
|
||||
- Linux: Automatically increase cell height if the font being used is broken
|
||||
and draws the underscore outside the bounding box (:iss:`690`)
|
||||
|
||||
- Wayland: Fix maximizing the window on a compositor that does not provide
|
||||
server side window decorations, such a GNOME or Weston not working
|
||||
(:iss:`1662`)
|
||||
|
||||
|
||||
0.14.0 [2019-05-24]
|
||||
---------------------
|
||||
|
||||
- macOS: The default behavior of the Option key has changed. It now generates
|
||||
unicode characters rather than acting as the :kbd:`Alt` modifier. See
|
||||
:opt:`macos_option_as_alt`.
|
||||
|
||||
- Support for an arbitrary number of internal clipboard buffers to copy/paste
|
||||
from, see (:ref:`cpbuf`)
|
||||
|
||||
- Allow using the new private internal clipboard buffers with the
|
||||
:opt:`copy_on_select` option (:iss:`1390`)
|
||||
|
||||
- macOS: Allow opening new kitty tabs/top-level windows from Finder
|
||||
(:pull:`1350`)
|
||||
|
||||
- Add an option :opt:`disable_ligatures` to disable
|
||||
multi-character ligatures under the cursor to make editing easier
|
||||
or disable them completely (:iss:`461`)
|
||||
|
||||
- Allow creating new OS windows in session files (:iss:`1514`)
|
||||
|
||||
- Allow setting OS window size in session files
|
||||
|
||||
- Add an option :opt:`tab_switch_strategy` to control which
|
||||
tab becomes active when the current tab is closed (:pull:`1524`)
|
||||
|
||||
- Allow specifying a value of ``none`` for the :opt:`selection_foreground`
|
||||
which will cause kitty to not change text color in selections (:iss:`1358`)
|
||||
|
||||
- Make live resizing of OS windows smoother and add an option
|
||||
:opt:`resize_draw_strategy` to control what is drawn while a
|
||||
resize is in progress.
|
||||
|
||||
- macOS: Improve handling of IME extended input. Compose characters
|
||||
are now highlighted and the IME panel moves along with the text
|
||||
(:pull:`1586`). Also fixes handling of delete key in Chinese IME
|
||||
(:iss:`1461`)
|
||||
|
||||
- When a window is closed, switch focus to the previously active window (if
|
||||
any) instead of picking the previous window in the layout (:iss:`1450`)
|
||||
|
||||
- icat kitten: Add support for displaying images at http(s) URLs (:iss:`1340`)
|
||||
|
||||
- A new option :opt:`strip_trailing_spaces` to optionally remove trailing
|
||||
spaces from lines when copying to clipboard.
|
||||
|
||||
- A new option :opt:`tab_bar_min_tabs` to control how many tabs must be
|
||||
present before the tab-bar is shown (:iss:`1382`)
|
||||
|
||||
- Automatically check for new releases and notify when an update is available,
|
||||
via the system notification facilities. Can be controlled by
|
||||
:opt:`update_check_interval` (:iss:`1342`)
|
||||
|
||||
- macOS: Fix :kbd:`cmd+period` key not working (:iss:`1318`)
|
||||
|
||||
- macOS: Add an option `macos_show_window_title_in_menubar` to not
|
||||
show the current window title in the menu-bar (:iss:`1066`)
|
||||
|
||||
- macOS: Workaround for cocoa bug that could cause the mouse cursor to become
|
||||
hidden in other applications in rare circumstances (:iss:`1218`)
|
||||
|
||||
- macOS: Allow assigning only the left or right :kbd:`Option` key to work as the
|
||||
:kbd:`Alt` key. See :opt:`macos_option_as_alt` for details (:iss:`1022`)
|
||||
|
||||
- Fix using remote control to set cursor text color causing errors when
|
||||
creating new windows (:iss:`1326`)
|
||||
|
||||
- Fix window title for minimized windows not being updated (:iss:`1332`)
|
||||
|
||||
- macOS: Fix using multi-key sequences to input text ignoring the
|
||||
first few key presses if the sequence is aborted (:iss:`1311`)
|
||||
|
||||
- macOS: Add a number of common macOS keyboard shortcuts
|
||||
|
||||
- macOS: Reduce energy consumption by not rendering occluded windows
|
||||
|
||||
- Fix scrollback pager history not being cleared when clearing the
|
||||
main scrollback buffer (:iss:`1387`)
|
||||
|
||||
- macOS: When closing a top-level window only switch focus to the previous kitty
|
||||
window if it is on the same workspace (:iss:`1379`)
|
||||
|
||||
- macOS: Fix :opt:`sync_to_monitor` not working on Mojave.
|
||||
|
||||
- macOS: Use the system cursor blink interval by default
|
||||
:opt:`cursor_blink_interval`.
|
||||
|
||||
- Wayland: Use the kitty Wayland backend by default. Can be switched back
|
||||
to using XWayland by setting the environment variable:
|
||||
``KITTY_DISABLE_WAYLAND=1``
|
||||
|
||||
- Add a ``no-append`` setting to :opt:`clipboard_control` to disable
|
||||
the kitty copy concatenation protocol extension for OSC 52.
|
||||
|
||||
- Update to using the Unicode 12 standard
|
||||
|
||||
- Unicode input kitten: Allow using the arrow keys in code mode to go to next
|
||||
and previous unicode symbol.
|
||||
|
||||
- macOS: Fix specifying initial window size in cells not working correctly on
|
||||
Retina screens (:iss:`1444`)
|
||||
|
||||
- Fix a regression in version 0.13.0 that caused background colors of space
|
||||
characters after private use unicode characters to not be respected
|
||||
(:iss:`1455`)
|
||||
|
||||
- Only update the selected text to clipboard when the selection is finished,
|
||||
not continuously as it is updated. (:iss:`1460`)
|
||||
|
||||
- Allow setting :opt:`active_border_color` to ``none`` to not draw a border
|
||||
around the active window (:iss:`805`)
|
||||
|
||||
- Use negative values for :opt:`mouse_hide_wait` to hide the mouse cursor
|
||||
immediately when pressing a key (:iss:`1534`)
|
||||
|
||||
- When encountering errors in :file:`kitty.conf` report them to the user
|
||||
instead of failing to start.
|
||||
|
||||
- Allow the user to control the resize debounce time via
|
||||
:opt:`resize_debounce_time`.
|
||||
|
||||
- Remote control: Make the :ref:`at_set-font-size` command more capable.
|
||||
It can now increment font size and reset it. It also only acts on the
|
||||
active top-level window, by default (:iss:`1581`)
|
||||
|
||||
- When launching child processes set the :code:`PWD` environment variable
|
||||
(:iss:`1595`)
|
||||
|
||||
- X11: use the window manager's native full-screen implementation when
|
||||
making windows full-screen (:iss:`1605`)
|
||||
|
||||
- Mouse selection: When extending by word, fix extending selection to non-word
|
||||
characters not working well (:iss:`1616`)
|
||||
|
||||
0.13.3 [2019-01-19]
|
||||
------------------------------
|
||||
|
||||
- icat kitten: Add a ``--stdin`` option to control if image data is read from
|
||||
STDIN (:iss:`1308`)
|
||||
|
||||
- hints kitten: Start hints numbering at one instead of zero by default. Added
|
||||
an option ``--hints-offset`` to control it. (:iss:`1289`)
|
||||
|
||||
- Fix a regression in the previous release that broke using ``background`` for
|
||||
:opt:`cursor_text_color` (:iss:`1288`)
|
||||
|
||||
- macOS: Fix dragging kitty window tabs in traditional full screen mode causing
|
||||
crashes (:iss:`1296`)
|
||||
|
||||
- macOS: Ensure that when running from a bundle, the bundle kitty exe is
|
||||
preferred over any kitty in PATH (:iss:`1280`)
|
||||
|
||||
- macOS: Fix a regression that broke mapping of :kbd:`ctrl+tab` (:iss:`1304`)
|
||||
|
||||
- Add a list of user-created kittens to the docs
|
||||
|
||||
- Fix a regression that broke changing mouse wheel scroll direction with
|
||||
negative :opt:`wheel_scroll_multiplier` values in full-screen applications
|
||||
like vim (:iss:`1299`)
|
||||
|
||||
- Fix :opt:`background_opacity` not working with pure white backgrounds
|
||||
(:iss:`1285`)
|
||||
|
||||
- macOS: Fix "New OS Window" dock action not working when kitty is not focused
|
||||
(:iss:`1312`)
|
||||
|
||||
- macOS: Add aliases for close window and new tab actions that conform to common
|
||||
Apple shortcuts for these actions (:iss:`1313`)
|
||||
|
||||
- macOS: Fix some kittens causing 100% CPU usage
|
||||
|
||||
|
||||
0.13.2 [2019-01-04]
|
||||
------------------------------
|
||||
|
||||
- Add a new option :opt:`tab_title_template` to control how tab titles
|
||||
are formatted. In particular the template can be used to display
|
||||
the tab number next to the title (:iss:`1223`)
|
||||
|
||||
- Report the current foreground processes as well as the original child process,
|
||||
when using `kitty @ ls`
|
||||
|
||||
- Use the current working directory of the foreground process for the
|
||||
`*_with_cwd` actions that open a new window with the current working
|
||||
directory.
|
||||
|
||||
- Add a new ``copy_or_interrupt`` action that can be mapped to kbd:`ctrl+c`. It
|
||||
will copy if there is a selection and interrupt otherwise (:iss:`1286`)
|
||||
|
||||
- Fix setting :opt:`background_opacity` causing window margins/padding to be slightly
|
||||
different shade from background (:iss:`1221`)
|
||||
|
||||
- Handle keyboards with a "+" key (:iss:`1224`)
|
||||
|
||||
- Fix Private use Unicode area characters followed by spaces at the end of text
|
||||
not being rendered correctly (:iss:`1210`)
|
||||
|
||||
- macOS: Add an entry to the dock menu to open a new OS window (:iss:`1242`)
|
||||
|
||||
- macOS: Fix scrolling very slowly with wheel mice not working (:iss:`1238`)
|
||||
|
||||
- Fix changing :opt:`cursor_text_color` via remote control not working
|
||||
(:iss:`1229`)
|
||||
|
||||
- Add an action to resize windows that can be mapped to shortcuts in :file:`kitty.conf`
|
||||
(:pull:`1245`)
|
||||
|
||||
- Fix using the ``new_tab !neighbor`` action changing the order of the
|
||||
non-neighboring tabs (:iss:`1256`)
|
||||
|
||||
- macOS: Fix momentum scrolling continuing when changing the active window/tab
|
||||
(:iss:`1267`)
|
||||
|
||||
|
||||
0.13.1 [2018-12-06]
|
||||
------------------------------
|
||||
|
||||
66
docs/conf.py
66
docs/conf.py
@@ -1,15 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file does only contain a selection of the most common options. For a
|
||||
# full list see the documentation:
|
||||
# http://www.sphinx-doc.org/en/master/config
|
||||
# https://www.sphinx-doc.org/en/master/config
|
||||
|
||||
import importlib
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from functools import partial
|
||||
|
||||
from docutils import nodes
|
||||
@@ -19,15 +22,19 @@ from pygments.token import (
|
||||
Comment, Keyword, Literal, Name, Number, String, Whitespace
|
||||
)
|
||||
from sphinx import addnodes
|
||||
from sphinx.environment.adapters.toctree import TocTree
|
||||
from sphinx.util.logging import getLogger
|
||||
|
||||
from kitty.constants import str_version
|
||||
kitty_src = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
if kitty_src not in sys.path:
|
||||
sys.path.insert(0, kitty_src)
|
||||
str_version = importlib.import_module('kitty.constants').str_version
|
||||
|
||||
# config {{{
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'kitty'
|
||||
copyright = '2018, Kovid Goyal'
|
||||
copyright = time.strftime('%Y, Kovid Goyal')
|
||||
author = 'Kovid Goyal'
|
||||
building_man_pages = 'man' in sys.argv
|
||||
|
||||
@@ -175,7 +182,7 @@ texinfo_documents = [
|
||||
# }}}
|
||||
|
||||
|
||||
# GitHub linking inlne roles {{{
|
||||
# GitHub linking inline roles {{{
|
||||
|
||||
def num_role(which, name, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
' Link to a github issue '
|
||||
@@ -214,7 +221,8 @@ def commit_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
|
||||
# Sidebar ToC {{{
|
||||
def create_toc(app, pagename):
|
||||
toctree = app.env.get_toc_for(pagename, app.builder)
|
||||
tt = TocTree(app.env)
|
||||
toctree = tt.get_toc_for(pagename, app.builder)
|
||||
if toctree is not None:
|
||||
subtree = toctree[toctree.first_child_matching_class(nodes.list_item)]
|
||||
bl = subtree.first_child_matching_class(nodes.bullet_list)
|
||||
@@ -268,6 +276,48 @@ def write_cli_docs(all_kitten_names):
|
||||
# }}}
|
||||
|
||||
|
||||
def write_remote_control_protocol_docs(): # {{{
|
||||
from kitty.cmds import cmap
|
||||
field_pat = re.compile(r'\s*([a-zA-Z0-9_+]+)\s*:\s*(.+)')
|
||||
|
||||
def format_cmd(p, name, cmd):
|
||||
p(name)
|
||||
p('-' * 80)
|
||||
lines = cmd.__doc__.strip().splitlines()
|
||||
fields = []
|
||||
for line in lines:
|
||||
m = field_pat.match(line)
|
||||
if m is None:
|
||||
p(line)
|
||||
else:
|
||||
fields.append((m.group(1), m.group(2)))
|
||||
if fields:
|
||||
p('\nFields are:\n')
|
||||
for (name, desc) in fields:
|
||||
if '+' in name:
|
||||
title = name.replace('+', ' (required)')
|
||||
else:
|
||||
title = name
|
||||
defval = cmd.get_default(name.replace('-', '_'), cmd)
|
||||
if defval is not cmd:
|
||||
title = f'{title} (default: {defval})'
|
||||
else:
|
||||
title = f'{title} (optional)'
|
||||
p(f':code:`{title}`')
|
||||
p(' ', desc), p()
|
||||
p(), p()
|
||||
|
||||
with open(f'generated/rc.rst', 'w') as f:
|
||||
p = partial(print, file=f)
|
||||
for name in sorted(cmap):
|
||||
cmd = cmap[name]
|
||||
if not cmd.__doc__:
|
||||
continue
|
||||
name = name.replace('_', '-')
|
||||
format_cmd(p, name, cmd)
|
||||
# }}}
|
||||
|
||||
|
||||
# config file docs {{{
|
||||
|
||||
class ConfLexer(RegexLexer):
|
||||
@@ -475,9 +525,12 @@ def process_shortcut_link(env, refnode, has_explicit_title, title, target):
|
||||
conf_name, slug = 'kitty', conf_name
|
||||
full_name = conf_name + '.' + slug
|
||||
try:
|
||||
target, title = shortcut_slugs[full_name]
|
||||
target, stitle = shortcut_slugs[full_name]
|
||||
except KeyError:
|
||||
logger.warning('Unknown shortcut: {}'.format(target), location=refnode)
|
||||
else:
|
||||
if not has_explicit_title:
|
||||
title = stitle
|
||||
return title, target
|
||||
|
||||
|
||||
@@ -529,6 +582,7 @@ def setup(app):
|
||||
from kittens.runner import all_kitten_names
|
||||
all_kitten_names = all_kitten_names()
|
||||
write_cli_docs(all_kitten_names)
|
||||
write_remote_control_protocol_docs()
|
||||
write_conf_docs(app, all_kitten_names)
|
||||
app.add_lexer('session', SessionLexer())
|
||||
app.add_role('link', link_role)
|
||||
|
||||
@@ -20,6 +20,10 @@ You can also display the current configuration by running ``kitty
|
||||
:option:`kitty --config` option or use the ``KITTY_CONFIG_DIRECTORY``
|
||||
environment variable. See the :option:`kitty --config` option for full details.
|
||||
|
||||
Comments can be added to the config file as lines starting with the ``#``
|
||||
character. This works only if the ``#`` character is the first character
|
||||
in the line.
|
||||
|
||||
You can include secondary config files via the :code:`include` directive. If
|
||||
you use a relative path for include, it is resolved with respect to the
|
||||
location of the current config file. Note that environment variables are
|
||||
|
||||
96
docs/faq.rst
96
docs/faq.rst
@@ -6,7 +6,7 @@ Frequently Asked Questions
|
||||
.. contents::
|
||||
|
||||
Some special symbols are rendered small/truncated in kitty?
|
||||
-----------------------------------------------------------------
|
||||
-----------------------------------------------------------
|
||||
|
||||
The number of cells a unicode character takes up are controlled by the unicode
|
||||
standard. All characters are rendered in a single cell unless the unicode
|
||||
@@ -48,25 +48,83 @@ terminfo files to the server::
|
||||
kitty +kitten ssh myserver
|
||||
|
||||
If for some reason that does not work (typically because the server is using a
|
||||
a non POSIX compliant shell), you can use the following one-liner instead (it
|
||||
non POSIX compliant shell), you can use the following one-liner instead (it
|
||||
is slower as it needs to ssh into the server twice, but will work with most
|
||||
servers)::
|
||||
|
||||
infocmp xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin
|
||||
|
||||
If you are behind a proxy (like Balabit) that prevents this, you must redirect the
|
||||
1st command to a file, copy that to the server and run ``tic`` manually. If you
|
||||
connect to a server, embedded or Android system that doesn't have ``tic``, copy over
|
||||
your local file terminfo to the other system as :file:`~/.terminfo/x/xterm-kitty`.
|
||||
|
||||
Really, the correct solution for this is to convince the OpenSSH maintainers to
|
||||
have ssh do this automatically when connecting to a server, so that all
|
||||
terminals work transparently.
|
||||
have ssh do this automatically, if possible, when connecting to a server, so that
|
||||
all terminals work transparently.
|
||||
|
||||
|
||||
Keys such as arrow keys, backspace, delete, home/end, etc. do not work when using su or sudo?
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
Make sure the TERM environment variable, is ``xterm-kitty``. And either the
|
||||
TERMINFO environment variable points to a directory containing :file:`x/xterm-kitty`
|
||||
or that file is under :file:`~/.terminfo/x/`.
|
||||
|
||||
Note that ``sudo`` might remove TERMINFO. Then setting it at the shell prompt can
|
||||
be too late, because command line editing may not be reinitialized. In that case
|
||||
you can either ask ``sudo`` to set it or if that is not supported, insert an ``env``
|
||||
command before starting the shell, or, if not possible, after sudo start another
|
||||
Shell providing the right terminfo path::
|
||||
|
||||
sudo … TERMINFO=$HOME/.terminfo bash -i
|
||||
sudo … env TERMINFO=$HOME/.terminfo bash -i
|
||||
TERMINFO=/home/ORIGINALUSER/.terminfo exec bash -i
|
||||
|
||||
You can configure sudo to preserve TERMINFO by running ``sudo
|
||||
visudo`` and adding the following line::
|
||||
|
||||
Defaults env_keep += "TERM TERMINFO"
|
||||
|
||||
If you have double width characters in your prompt, you may also need to
|
||||
explicitly set a UTF-8 locale, like::
|
||||
|
||||
export LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
|
||||
|
||||
|
||||
How do I change the colors in a running kitty instance?
|
||||
------------------------------------------------------------
|
||||
|
||||
You can either use the
|
||||
`OSC terminal escape codes <http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands>`_
|
||||
`OSC terminal escape codes <https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Operating-System-Commands>`_
|
||||
to set colors or you can enable :doc:`remote control <remote-control>`
|
||||
for |kitty| and use :ref:`at_set-colors`.
|
||||
|
||||
A list of pre-made color themes for kitty is available at:
|
||||
`kitty-themes <https://github.com/dexpota/kitty-themes>`_
|
||||
|
||||
Examples of using OSC escape codes to set colors::
|
||||
|
||||
Change the default foreground color:
|
||||
printf '\x1b]10;#ff0000\x1b\\'
|
||||
Change the default background color:
|
||||
printf '\x1b]11;blue\x1b\\'
|
||||
Change the cursor color:
|
||||
printf '\x1b]12;blue\x1b\\'
|
||||
Change the selection background color:
|
||||
printf '\x1b]17;blue\x1b\\'
|
||||
Change the selection foreground color:
|
||||
printf '\x1b]19;blue\x1b\\'
|
||||
Change the nth color (0 - 255):
|
||||
printf '\x1b]4;n;green\x1b\\'
|
||||
|
||||
You can use various syntaxes/names for color specifications in the above
|
||||
examples. See `XParseColor <https://linux.die.net/man/3/xparsecolor>`_
|
||||
for full details.
|
||||
|
||||
If a ``?`` is given rather than a color specification, kitty will respond
|
||||
with the current value for the specified color.
|
||||
|
||||
|
||||
How do I specify command line options for kitty on macOS?
|
||||
---------------------------------------------------------------
|
||||
@@ -104,3 +162,31 @@ Bringing up applications on a single key press is the job of the window
|
||||
manager/desktop environment. For ways to do it with kitty (or indeed any
|
||||
terminal) in different environments,
|
||||
see `here <https://github.com/kovidgoyal/kitty/issues/45>`_.
|
||||
|
||||
|
||||
How do I map key presses in kitty to different keys in the terminal program?
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
This is accomplished by using ``map`` with :sc:`send_text <send_text>` in :file:`kitty.conf`.
|
||||
For example::
|
||||
|
||||
map alt+s send_text all \x13
|
||||
|
||||
This maps :kbd:`alt+s`` to :kbd:`ctrl+s`. To figure out what bytes to use for
|
||||
the :sc:`send_text <send_text>` you can use the ``showkey`` utility. Run::
|
||||
|
||||
showkey -a
|
||||
|
||||
Then press the key you want to emulate. On macOS, this utility is currently not
|
||||
available. The manual way to figure it out is:
|
||||
|
||||
1. Look up your key's decimal value in the table at the bottom of `this
|
||||
page <http://ascii-table.com/ansi-escape-sequences.php>`_ or any
|
||||
ANSI escape sequence table. There are different modifiers for :kbd:`ctrl`,
|
||||
:kbd:`alt`, etc. For e.g., for :kbd:`ctrl+s`, find the ``S`` row and look at
|
||||
the third column value, ``19``.
|
||||
|
||||
2. Convert the decimal value to hex with ``kitty +runpy "print(hex(19))"``.
|
||||
This shows the hex value, ``13`` in this case.
|
||||
|
||||
3. Use ``\x(hexval)`` in your ``send_text`` command in kitty. So in this example, ``\x13``
|
||||
|
||||
@@ -107,7 +107,8 @@ features of the graphics protocol:
|
||||
sys.stdout.flush()
|
||||
cmd.clear()
|
||||
|
||||
write_chunked({'a': 'T', 'f': 100}, open(sys.argv[-1], 'rb').read())
|
||||
with open(sys.argv[-1], 'rb') as f:
|
||||
write_chunked({'a': 'T', 'f': 100}, f.read())
|
||||
|
||||
|
||||
Save this script as :file:`png.py`, then you can use it to display any PNG
|
||||
@@ -201,7 +202,11 @@ Value of `t` Meaning
|
||||
================== ============
|
||||
``d`` Direct (the data is transmitted within the escape code itself)
|
||||
``f`` A simple file
|
||||
``t`` A temporary file, the terminal emulator will delete the file after reading the pixel data
|
||||
``t`` A temporary file, the terminal emulator will delete the file after reading the pixel data. For security reasons
|
||||
the terminal emulator should only delete the file if it
|
||||
is in a known temporary directory, such as :file:`/tmp`,
|
||||
:file:`/dev/shm`, :file:`TMPDIR env var if present` and any platform
|
||||
specific temporary directories.
|
||||
``s`` A `POSIX shared memory object <http://man7.org/linux/man-pages/man7/shm_overview.7.html>`_.
|
||||
The terminal emulator will delete it after reading the pixel data
|
||||
================== ============
|
||||
@@ -251,7 +256,10 @@ sequence of escape codes to the terminal emulator::
|
||||
Note that only the first escape code needs to have the full set of control
|
||||
codes such as width, height, format etc. Subsequent chunks must have
|
||||
only the ``m`` key. The client **must** finish sending all chunks for a single image
|
||||
before sending any other graphics related escape codes.
|
||||
before sending any other graphics related escape codes. Note that the cursor
|
||||
position used to display the image **must** be the position when the final chunk is
|
||||
received. Finally, terminals must not display anything, until the entire sequence is
|
||||
received and validated.
|
||||
|
||||
|
||||
Detecting available transmission mediums
|
||||
|
||||
110
docs/index.rst
110
docs/index.rst
@@ -36,6 +36,8 @@ kitty - the fast, featureful, GPU based terminal emulator
|
||||
separate window using arbitrary programs of your choice. This is useful for
|
||||
browsing the history comfortably in a pager or editor.
|
||||
|
||||
* Has :ref:`multiple copy/paste buffers <cpbuf>`, like vim.
|
||||
|
||||
|
||||
.. figure:: screenshots/screenshot.png
|
||||
:alt: Screenshot, showing three programs in the 'Tall' layout
|
||||
@@ -54,15 +56,18 @@ Pre-built binaries of |kitty| are available for both macOS and Linux.
|
||||
See the :doc:`binary install instructions </binary>`. You can also
|
||||
:doc:`build from source </build>`.
|
||||
|
||||
If you are on Linux, you can also use your distribution's |kitty| package.
|
||||
You can also use your favorite package manager to install the |kitty| package.
|
||||
|kitty| packages are available for:
|
||||
`macOS with Homebrew (Cask) <https://formulae.brew.sh/cask/kitty>`_,
|
||||
`macOS and Linux with Nix <https://nixos.org/nixos/packages.html#kitty>`_,
|
||||
`Ubuntu <https://launchpad.net/ubuntu/+source/kitty>`_,
|
||||
`Debian <https://packages.debian.org/buster/kitty>`_,
|
||||
`openSUSE <https://build.opensuse.org/package/show/X11:terminals/kitty>`_,
|
||||
`Arch Linux <https://www.archlinux.org/packages/community/x86_64/kitty/>`_,
|
||||
`NixOS <https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/kitty/default.nix>`_,
|
||||
`Gentoo <https://packages.gentoo.org/packages/x11-terms/kitty>`_,
|
||||
`Fedora <https://copr.fedorainfracloud.org/coprs/gagbo/kitty-latest/>`_,
|
||||
`Void Linux <https://github.com/void-linux/void-packages/blob/master/srcpkgs/kitty/template>`_.
|
||||
`Void Linux <https://github.com/void-linux/void-packages/blob/master/srcpkgs/kitty/template>`_,
|
||||
and `Solus <https://dev.getsol.us/source/kitty/>`_.
|
||||
|
||||
See :doc:`Configuring kitty <conf>` for help on configuring |kitty| and
|
||||
:doc:`Invocation <invocation>` for the command line arguments |kitty| supports.
|
||||
@@ -90,7 +95,7 @@ formatting, etc. It even extends existing text formatting escape codes,
|
||||
to add support for features not available elsewhere, such as colored and
|
||||
styled (curly) underlines. One of the design goals of |kitty| is to be
|
||||
easily extensible so that new features can be added in the future with
|
||||
relatively less effort.
|
||||
relatively little effort.
|
||||
|
||||
Tabs and Windows
|
||||
-------------------
|
||||
@@ -108,12 +113,12 @@ Scrolling
|
||||
======================== =======================
|
||||
Action Shortcut
|
||||
======================== =======================
|
||||
Scroll line up :sc:`scroll_line_up`
|
||||
Scroll line down :sc:`scroll_line_down`
|
||||
Scroll page up :sc:`scroll_page_up`
|
||||
Scroll page down :sc:`scroll_page_down`
|
||||
Scroll to top :sc:`scroll_home`
|
||||
Scroll to bottom :sc:`scroll_end`
|
||||
Scroll line up :sc:`scroll_line_up` (also :kbd:`⌥+⌘+⇞` and :kbd:`⌘+↑` on macOS)
|
||||
Scroll line down :sc:`scroll_line_down` (also :kbd:`⌥+⌘+⇟` and :kbd:`⌘+↓` on macOS)
|
||||
Scroll page up :sc:`scroll_page_up` (also :kbd:`⌘+⇞` on macOS)
|
||||
Scroll page down :sc:`scroll_page_down` (also :kbd:`⌘+⇟` on macOS)
|
||||
Scroll to top :sc:`scroll_home` (also :kbd:`⌘+↖` on macOS)
|
||||
Scroll to bottom :sc:`scroll_end` (also :kbd:`⌘+↘` on macOS)
|
||||
======================== =======================
|
||||
|
||||
Tabs
|
||||
@@ -122,14 +127,14 @@ Tabs
|
||||
======================== =======================
|
||||
Action Shortcut
|
||||
======================== =======================
|
||||
New tab :sc:`new_tab`
|
||||
Close tab :sc:`close_tab`
|
||||
Next tab :sc:`next_tab` (also :kbd:`control+tab` on macOS)
|
||||
Previous tab :sc:`previous_tab` (also :kbd:`control+shift+tab` on macOS)
|
||||
New tab :sc:`new_tab` (also :kbd:`⌘+t` on macOS)
|
||||
Close tab :sc:`close_tab` (also :kbd:`⌘+w` on macOS)
|
||||
Next tab :sc:`next_tab` (also :kbd:`^+⇥` and :kbd:`⇧+⌘+]` on macOS)
|
||||
Previous tab :sc:`previous_tab` (also :kbd:`⇧+^+⇥` and :kbd:`⇧+⌘+[` on macOS)
|
||||
Next layout :sc:`next_layout`
|
||||
Move tab forward :sc:`move_tab_forward`
|
||||
Move tab backward :sc:`move_tab_backward`
|
||||
Set tab title :sc:`set_tab_title`
|
||||
Set tab title :sc:`set_tab_title` (also :kbd:`⇧+⌘+i` on macOS)
|
||||
======================== =======================
|
||||
|
||||
|
||||
@@ -139,15 +144,16 @@ Windows
|
||||
======================== =======================
|
||||
Action Shortcut
|
||||
======================== =======================
|
||||
New window :sc:`new_window`
|
||||
New window :sc:`new_window` (also :kbd:`⌘+↩` on macOS)
|
||||
New OS window :sc:`new_os_window` (also :kbd:`⌘+n` on macOS)
|
||||
Close window :sc:`close_window`
|
||||
Close window :sc:`close_window` (also :kbd:`⇧+⌘+d` on macOS)
|
||||
Next window :sc:`next_window`
|
||||
Previous window :sc:`previous_window`
|
||||
Move window forward :sc:`move_window_forward`
|
||||
Move window backward :sc:`move_window_backward`
|
||||
Move window to top :sc:`move_window_to_top`
|
||||
Focus specific window :sc:`first_window`, :sc:`second_window` ... :sc:`tenth_window`
|
||||
(also :kbd:`⌘+1`, :kbd:`⌘+2` ... :kbd:`⌘+9` on macOS)
|
||||
(clockwise from the top-left)
|
||||
======================== =======================
|
||||
|
||||
@@ -177,11 +183,11 @@ Action Shortcut
|
||||
Copy to clipboard :sc:`copy_to_clipboard` (also :kbd:`⌘+c` on macOS)
|
||||
Paste from clipboard :sc:`paste_from_clipboard` (also :kbd:`⌘+v` on macOS)
|
||||
Paste from selection :sc:`paste_from_selection`
|
||||
Increase font size :sc:`increase_font_size`
|
||||
Decrease font size :sc:`decrease_font_size`
|
||||
Restore font size :sc:`reset_font_size`
|
||||
Toggle fullscreen :sc:`toggle_fullscreen` (also :kbd:`^⌘+f` on macOS)
|
||||
on
|
||||
Increase font size :sc:`increase_font_size` (also :kbd:`⌘++` on macOS)
|
||||
Decrease font size :sc:`decrease_font_size` (also :kbd:`⌘+-` on macOS)
|
||||
Restore font size :sc:`reset_font_size` (also :kbd:`⌘+0` on macOS)
|
||||
Toggle fullscreen :sc:`toggle_fullscreen` (also :kbd:`^+⌘+f` on macOS)
|
||||
Toggle maximized :sc:`toggle_maximized`
|
||||
Input unicode character :sc:`input_unicode_character`
|
||||
Click URL using the keyboard :sc:`open_url`
|
||||
Reset the terminal :sc:`reset_terminal`
|
||||
@@ -216,13 +222,26 @@ You can switch between layouts using the :sc:`next_layout` key combination. You
|
||||
also create shortcuts to select particular layouts, and choose which layouts
|
||||
you want to enable/disable, see :ref:`conf-kitty-shortcuts.layout` for examples.
|
||||
|
||||
You can resize windows inside layouts. Press :sc:`start_resizing_window` to
|
||||
You can resize windows inside layouts. Press :sc:`start_resizing_window` (also :kbd:`⌘+r` on macOS) to
|
||||
enter resizing mode and follow the on-screen instructions. In a given window
|
||||
layout only some operations may be possible for a particular window. For
|
||||
example, in the Tall layout you can make the first window wider/narrower, but
|
||||
not taller/shorter. Note that what you are resizing is actually not a window,
|
||||
but a row/column in the layout, all windows in that row/column will be resized.
|
||||
|
||||
You can also define shortcuts in :file:`kitty.conf` to make the active window
|
||||
wider, narrower, taller, or shorter by mapping to the ``resize_window``
|
||||
action, for example::
|
||||
|
||||
map ctrl+left resize_window narrower
|
||||
map ctrl+right resize_window wider
|
||||
map ctrl+up resize_window taller
|
||||
map ctrl+down resize_window shorter 3
|
||||
|
||||
The ``resize_window`` action has a second, optional argument to control
|
||||
the resizing increment (a positive integer that defaults to 1).
|
||||
|
||||
|
||||
Some layouts take options to control their behavior. For example, the ``fat``
|
||||
and ``tall`` layouts accept the ``bias`` option to control how the available
|
||||
space is split up. To specify the option, in :opt:`kitty.conf <enabled_layouts>` use::
|
||||
@@ -327,6 +346,12 @@ For example:
|
||||
# Set the current layout
|
||||
layout stack
|
||||
launch zsh
|
||||
|
||||
# Create a new OS window
|
||||
new_os_window
|
||||
# set new window size to 80x25 cells
|
||||
os_window_size 80c 25c
|
||||
launch sh
|
||||
# Make the current window the active (focused) window
|
||||
focus
|
||||
launch emacs
|
||||
@@ -335,11 +360,16 @@ For example:
|
||||
Mouse features
|
||||
-------------------
|
||||
|
||||
* You can also hold down :kbd:`ctrl+shift` and click on a URL to open it in a browser.
|
||||
* You can double click to select a word and triple click to select a line.
|
||||
* You can right click to extend a previous selection
|
||||
* You can hold down :kbd:`ctrl+shift` and click on a URL to open it in a browser.
|
||||
* You can double click to select a word and then drag to select more words.
|
||||
* You can triple click to select a line and then drag to select more lines.
|
||||
* You can right click to extend a previous selection.
|
||||
* You can hold down :kbd:`ctrl+alt` and drag with the mouse to select in
|
||||
columns
|
||||
columns.
|
||||
* Selecting text automatically copies it to the primary clipboard (on
|
||||
platforms with a primary clipboard).
|
||||
* You can select text with kitty even when a terminal program has grabbed
|
||||
the mouse by holding down the :kbd:`shift` key.
|
||||
|
||||
|
||||
Font control
|
||||
@@ -381,6 +411,23 @@ If you wish to store very large amounts of scrollback to view using the piping o
|
||||
:sc:`show_scrollback` features, you can use the :opt:`scrollback_pager_history_size`
|
||||
option.
|
||||
|
||||
.. _cpbuf:
|
||||
|
||||
Multiple copy/paste buffers
|
||||
-----------------------------
|
||||
|
||||
In addition to being able to copy/paste from the system clipboard, in |kitty| you
|
||||
can also setup an arbitrary number of copy paste buffers. To do so, simply add
|
||||
something like the following to your :file:`kitty.conf`::
|
||||
|
||||
map f1 copy_to_buffer a
|
||||
map f2 paste_from_buffer a
|
||||
|
||||
This will allow you to press :kbd:`F1` to copy the current selection to an
|
||||
internal buffer named ``a`` and :kbd:`F2` to paste from that buffer. The buffer
|
||||
names are arbitrary strings, so you can define as many such buffers as you
|
||||
need.
|
||||
|
||||
Frequently Asked Questions
|
||||
---------------------------------
|
||||
|
||||
@@ -403,6 +450,14 @@ Add the following to your :file:`~/.bashrc`
|
||||
|
||||
source <(kitty + complete setup bash)
|
||||
|
||||
Older versions of bash (for example, v3.2) do not support
|
||||
process substitution with the source command, in which
|
||||
case you can try an alternative:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
source /dev/stdin <<<"$(kitty + complete setup bash)"
|
||||
|
||||
|
||||
zsh
|
||||
~~~~~~~~~
|
||||
@@ -441,3 +496,4 @@ See :doc:`changelog`.
|
||||
|
||||
*
|
||||
kittens/*
|
||||
generated/rc
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
@@ -20,6 +20,10 @@ import tempfile
|
||||
py3 = sys.version_info[0] > 2
|
||||
is64bit = platform.architecture()[0] == '64bit'
|
||||
is_macos = 'darwin' in sys.platform.lower()
|
||||
if is_macos:
|
||||
mac_ver = tuple(map(int, platform.mac_ver()[0].split('.')))
|
||||
if mac_ver[:2] < (10, 12):
|
||||
raise SystemExit('Your version of macOS is too old, at least 10.12 is required')
|
||||
|
||||
try:
|
||||
__file__
|
||||
@@ -72,7 +76,10 @@ class Reporter: # {{{
|
||||
def get_latest_release_data():
|
||||
print('Checking for latest release on GitHub...')
|
||||
req = urllib.Request('https://api.github.com/repos/kovidgoyal/kitty/releases/latest', headers={'Accept': 'application/vnd.github.v3+json'})
|
||||
res = urllib.urlopen(req).read().decode('utf-8')
|
||||
try:
|
||||
res = urllib.urlopen(req).read().decode('utf-8')
|
||||
except Exception as err:
|
||||
raise SystemExit('Failed to contact {} with error: {}'.format(req.get_full_url(), err))
|
||||
data = json.loads(res)
|
||||
html_url = data['html_url'].replace('/tag/', '/download/').rstrip('/')
|
||||
for asset in data.get('assets', ()):
|
||||
@@ -222,7 +229,8 @@ def script_launch():
|
||||
|
||||
def update_intaller_wrapper():
|
||||
# To run: python3 -c "import runpy; runpy.run_path('installer.py', run_name='update_wrapper')" installer.sh
|
||||
src = open(__file__, 'rb').read().decode('utf-8')
|
||||
with open(__file__, 'rb') as f:
|
||||
src = f.read().decode('utf-8')
|
||||
wrapper = sys.argv[-1]
|
||||
with open(wrapper, 'r+b') as f:
|
||||
raw = f.read().decode('utf-8')
|
||||
|
||||
@@ -43,6 +43,8 @@ Now in :file:`kitty.conf` add the lines::
|
||||
Start kitty and press :kbd:`ctrl+k` and you should see the kitten running.
|
||||
The best way to develop your own kittens is to modify one of the built in
|
||||
kittens. Look in the kittens sub-directory of the kitty source code for those.
|
||||
Or see below for a list of :ref:`third-party kittens <external_kittens>`,
|
||||
that other kitty users have created.
|
||||
|
||||
|
||||
Passing arguments to kittens
|
||||
@@ -68,7 +70,14 @@ function, telling kitty what kind of input your kitten would like. For example:
|
||||
|
||||
.. code-block:: py
|
||||
|
||||
def handle_result(...):
|
||||
# in main, STDIN is for the kitten process and will contain
|
||||
# the contents of the screen
|
||||
def main(args):
|
||||
return sys.stdin.read()
|
||||
|
||||
# in handle_result, STDIN is for the kitty process itself, rather
|
||||
# than the kitten process and should not be read from.
|
||||
def handle_result(args, stdin_data, target_window_id, boss):
|
||||
pass
|
||||
|
||||
handle_result.type_of_input = 'text'
|
||||
@@ -120,3 +129,18 @@ layout, by simply adding the line::
|
||||
|
||||
|
||||
to the ``handle_result()`` function, above.
|
||||
|
||||
.. _external_kittens:
|
||||
|
||||
Kittens created by kitty users
|
||||
---------------------------------------------
|
||||
|
||||
`vim-kitty-navigator <https://github.com/knubie/vim-kitty-navigator>`_
|
||||
Allows you to navigate seamlessly between vim and kitty splits using a consistent set of hotkeys.
|
||||
|
||||
`smart-scroll <https://github.com/yurikhan/kitty-smart-scroll>`_
|
||||
Makes the kitty scroll bindings work in full screen applications
|
||||
|
||||
`insert password <https://github.com/kovidgoyal/kitty/issues/1222>`_
|
||||
Insert a password from a CLI password manager, taking care to only do it at
|
||||
a password prompt.
|
||||
|
||||
@@ -15,6 +15,8 @@ In :guilabel:`Code` mode, you enter a unicode character by typing in the hex cod
|
||||
character and pressing enter, for example, type in ``2716`` and press enter to get
|
||||
✖. You can also choose a character from the list of recently used characters by
|
||||
typing a leading period and then the two character index and pressing Enter.
|
||||
The up and down arrow keys can be used to choose the previous and next unicode
|
||||
symbol respectively.
|
||||
|
||||
In :guilabel:`Name` mode you instead type words from the character name and use the arrow
|
||||
keys/tab to select the character from the displayed matches. You can also type
|
||||
|
||||
@@ -14,12 +14,12 @@ render loop to reduce CPU usage. See :ref:`conf-kitty-performance` for details.
|
||||
See also the :opt:`sync_to_monitor` option to further decrease latency at the cost
|
||||
of some `tearing <https://en.wikipedia.org/wiki/Screen_tearing>`_ while scrolling.
|
||||
|
||||
You can generate detailed per-function performance data using
|
||||
`gperftools <https://github.com/gperftools/gperftools>`_. Build |kitty| with
|
||||
`make profile` which will create an executable called `kitty-profile`. Run
|
||||
that and perform the task you want to analyse, for example, scrolling a large
|
||||
file with `less`. After you quit, function call statistics will be printed to
|
||||
`stdout` and you can use tools like *kcachegrind* for more detailed analysis.
|
||||
You can generate detailed per-function performance data using `gperftools
|
||||
<https://github.com/gperftools/gperftools>`_. Build |kitty| with `make
|
||||
profile`. Run kitty and perform the task you want to analyse, for example,
|
||||
scrolling a large file with `less`. After you quit, function call statistics
|
||||
will be printed to `stdout` and you can use tools like *kcachegrind* for more
|
||||
detailed analysis.
|
||||
|
||||
Here are some CPU usage numbers for the task of scrolling a file continuously
|
||||
in less. The CPU usage is for the terminal process and X together and is
|
||||
|
||||
@@ -43,6 +43,10 @@ You can choose where to run the pipe program:
|
||||
``tab``
|
||||
A new window in a new tab
|
||||
|
||||
``clipboard, primary``
|
||||
Copy the text directly to the clipboard. In this case the specified program
|
||||
is not run, so use some dummy program name for it.
|
||||
|
||||
``none``
|
||||
Run it in the background
|
||||
|
||||
|
||||
@@ -51,6 +51,9 @@ To reset the underline color (also previously reserved and unused)::
|
||||
|
||||
<ESC>[59m
|
||||
|
||||
The underline color must remain the same under reverse video, if it has a
|
||||
color, if not, it should follow the foreground color.
|
||||
|
||||
To detect support for this feature in a terminal emulator, query the terminfo database
|
||||
for the ``Su`` boolean capability.
|
||||
|
||||
@@ -133,6 +136,10 @@ Alt -- ``0x2``, Control -- ``0x4`` and Super -- ``0x8``. ``<key>`` is a number
|
||||
(encoded in base85) corresponding to the key pressed. The key name to number
|
||||
mapping is defined in :doc:`this table <key-encoding>`.
|
||||
|
||||
Client programs must ignore events for keys they do not know. The mapping in
|
||||
the above table is stable and will never change, however, new codes might be
|
||||
added to it in the future, for new keys.
|
||||
|
||||
For example::
|
||||
|
||||
<ESC>_KpGp<ESC>\ is <Ctrl>+<Alt>+x (press)
|
||||
@@ -141,6 +148,10 @@ For example::
|
||||
This encoding means each key event is represented by 8 or 9 printable ascii
|
||||
only bytes, for maximum robustness.
|
||||
|
||||
To see the full mode in action, run::
|
||||
|
||||
kitty +kitten key_demo
|
||||
|
||||
Support for this mode is indicated by the ``fullkbd`` boolean capability
|
||||
in the terminfo database, in case querying for it via DECQRM is inconvenient.
|
||||
|
||||
@@ -160,7 +171,7 @@ The motivation for this extension is the various problems with the existing
|
||||
solution for erasing to background color, namely the *background color erase
|
||||
(bce)* capability. See
|
||||
`this discussion <https://github.com/kovidgoyal/kitty/issues/160#issuecomment-346470545>`_
|
||||
and `this FAQ <http://invisible-island.net/ncurses/ncurses.faq.html#bce_mismatches>`_
|
||||
and `this FAQ <https://invisible-island.net/ncurses/ncurses.faq.html#bce_mismatches>`_
|
||||
for a summary of problems with *bce*.
|
||||
|
||||
For example, to set the background color to blue in a
|
||||
@@ -208,3 +219,7 @@ first, for example::
|
||||
<ESC>]52;c;!<ESC>\
|
||||
|
||||
Here ``!`` is not valid base64 encoded text, so it clears the clipboard.
|
||||
|
||||
In case you're using software that can't be easily adapted to this
|
||||
protocol extension, it can be disabled by specifying ``no-append`` to the
|
||||
:opt:`clipboard_control` setting.
|
||||
|
||||
29
docs/rc_protocol.rst
Normal file
29
docs/rc_protocol.rst
Normal file
@@ -0,0 +1,29 @@
|
||||
Documentation for the kitty remote control protocol
|
||||
======================================================
|
||||
|
||||
The kitty remote control protocol is a simple protocol that involves sending
|
||||
data to kitty in the form of JSON. Any individual command of kitty has the
|
||||
form::
|
||||
|
||||
<ESC>P@kitty-cmd<JSON object><ESC>\
|
||||
|
||||
Where ``<ESC>`` is the byte ``0x1b``. The JSON object has the form::
|
||||
|
||||
{
|
||||
'cmd': "command name",
|
||||
'version': "kitty version",
|
||||
'no_response': Optional Boolean,
|
||||
'payload': <Optional JSON object>,
|
||||
}
|
||||
|
||||
The ``version`` above is a string of the form :code:`0.14.2`. If you are developing a
|
||||
standalone client, use the kitty version that you are developing against. Using
|
||||
a version greater than the version of the kitty instance you are talking to,
|
||||
will cause a failure.
|
||||
|
||||
Set ``no_response`` to True if you don't want a response from kitty.
|
||||
|
||||
The optional payload is a JSON object that is specific to the actual command being sent.
|
||||
The fields in the object for every command are documented below.
|
||||
|
||||
.. include:: generated/rc.rst
|
||||
@@ -134,5 +134,10 @@ still write to the pipes of any other program on the same computer and
|
||||
therefore can control |kitty|. It can, however, be useful to block programs
|
||||
running on other computers (for example, over ssh) or as other users.
|
||||
|
||||
Documentation for the remote control protocol
|
||||
-----------------------------------------------
|
||||
|
||||
If you wish to develop your own client to talk to |kitty|, you
|
||||
can use the :doc:`rc_protocol`.
|
||||
|
||||
.. include:: generated/cli-kitty-at.rst
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
@@ -93,7 +93,7 @@ def generate(function_name, callback_name, report_name, keymap, command_class, i
|
||||
report_cmd = cmd_for_report(report_name, keymap, type_map, payload_allowed)
|
||||
if payload_allowed:
|
||||
payload_after_value = "case ';': state = PAYLOAD; break;"
|
||||
payload = payload = ', PAYLOAD'
|
||||
payload = ', PAYLOAD'
|
||||
parr = 'static uint8_t payload[4096];'
|
||||
payload_case = f'''
|
||||
case PAYLOAD: {{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from collections import defaultdict
|
||||
from contextlib import contextmanager
|
||||
@@ -28,10 +29,12 @@ def get_data(fname, folder='UCD'):
|
||||
bn = os.path.basename(url)
|
||||
local = os.path.join('/tmp', bn)
|
||||
if os.path.exists(local):
|
||||
data = open(local, 'rb').read()
|
||||
with open(local, 'rb') as f:
|
||||
data = f.read()
|
||||
else:
|
||||
data = urlopen(url).read()
|
||||
open(local, 'wb').write(data)
|
||||
with open(local, 'wb') as f:
|
||||
f.write(data)
|
||||
for line in data.decode('utf-8').splitlines():
|
||||
line = line.strip()
|
||||
if line and not line.startswith('#'):
|
||||
@@ -165,21 +168,20 @@ def write_case(spec, p):
|
||||
|
||||
@contextmanager
|
||||
def create_header(path, include_data_types=True):
|
||||
f = open(path, 'w')
|
||||
p = partial(print, file=f)
|
||||
p('// unicode data, built from the unicode standard on:', date.today())
|
||||
p('// see gen-wcwidth.py')
|
||||
if path.endswith('.h'):
|
||||
p('#pragma once')
|
||||
if include_data_types:
|
||||
p('#include "data-types.h"\n')
|
||||
p('START_ALLOW_CASE_RANGE')
|
||||
p()
|
||||
yield p
|
||||
p()
|
||||
if include_data_types:
|
||||
p('END_ALLOW_CASE_RANGE')
|
||||
f.close()
|
||||
with open(path, 'w') as f:
|
||||
p = partial(print, file=f)
|
||||
p('// unicode data, built from the unicode standard on:', date.today())
|
||||
p('// see gen-wcwidth.py')
|
||||
if path.endswith('.h'):
|
||||
p('#pragma once')
|
||||
if include_data_types:
|
||||
p('#include "data-types.h"\n')
|
||||
p('START_ALLOW_CASE_RANGE')
|
||||
p()
|
||||
yield p
|
||||
p()
|
||||
if include_data_types:
|
||||
p('END_ALLOW_CASE_RANGE')
|
||||
|
||||
|
||||
def gen_emoji():
|
||||
@@ -281,7 +283,10 @@ def gen_ucd():
|
||||
p('combining_type mark_for_codepoint(char_type c) {')
|
||||
rmap = codepoint_to_mark_map(p, mark_map)
|
||||
p('}\n')
|
||||
if rmap[0xfe0e] != 1281:
|
||||
with open('kitty/unicode-data.h') as f:
|
||||
unicode_data = f.read()
|
||||
expected = int(re.search(r'^#define VS15 (\d+)', unicode_data, re.M).group(1))
|
||||
if rmap[0xfe0e] != expected:
|
||||
raise ValueError('The mark for 0xfe0e has changed, you have to update VS15 to {} and VS16 to {} in unicode-data.h'.format(
|
||||
rmap[0xfe0e], rmap[0xfe0f]
|
||||
))
|
||||
|
||||
@@ -8,9 +8,11 @@ import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
|
||||
cmdline = (
|
||||
'glad --profile core --out-path {dest} --api gl=3.3 --generator {generator} --spec gl'
|
||||
' --extensions GL_ARB_texture_storage,GL_ARB_copy_image,GL_ARB_multisample,GL_ARB_robustness,GL_KHR_debug'
|
||||
'glad --out-path {dest} --api gl:core=3.3 '
|
||||
' --extensions GL_ARB_texture_storage,GL_ARB_copy_image,GL_ARB_multisample,GL_ARB_robustness,GL_KHR_debug '
|
||||
'c --header-only --debug'
|
||||
)
|
||||
|
||||
|
||||
@@ -23,7 +25,7 @@ def regenerate():
|
||||
clean('out')
|
||||
|
||||
subprocess.check_call(
|
||||
shlex.split(cmdline.format(dest='out', generator='c-debug'))
|
||||
shlex.split(cmdline.format(dest='out'))
|
||||
)
|
||||
|
||||
|
||||
@@ -32,33 +34,12 @@ def strip_trailing_whitespace(c):
|
||||
|
||||
|
||||
def export():
|
||||
c = open('out/src/glad.c', 'rb').read().decode('utf-8')
|
||||
functions = []
|
||||
with open('out/include/glad/gl.h', 'r', encoding='utf-8') as source:
|
||||
data = source.read()
|
||||
data = strip_trailing_whitespace(data)
|
||||
|
||||
def sub(m):
|
||||
functions.append(m.group(2))
|
||||
return m.group()
|
||||
|
||||
c = re.sub(r'^([A-Z0-9]+) glad_debug_([a-zA-Z0-9]+) = glad_debug_impl_\2;$', sub, c, flags=re.M)
|
||||
switch = ['glad_debug_{0} = glad_{0}'.format(f) for f in functions]
|
||||
c = c.replace('<glad/glad.h>', '"gl-wrapper.h"', 1)
|
||||
c = '#pragma GCC diagnostic ignored "-Wpedantic"\n' + c
|
||||
c += '''
|
||||
int
|
||||
init_glad(GLADloadproc load, int debug) {
|
||||
int ret = gladLoadGLLoader(load);
|
||||
if (ret && !debug) {
|
||||
SUB;
|
||||
}
|
||||
return ret;
|
||||
}'''.replace('SUB', ';\n '.join(switch), 1)
|
||||
open('../kitty/gl-wrapper.c', 'w').write(strip_trailing_whitespace(c))
|
||||
raw = open('out/include/glad/glad.h').read()
|
||||
raw = raw.replace('<KHR/khrplatform.h>', '"khrplatform.h"')
|
||||
raw += '\nint init_glad(GLADloadproc, int);\n'
|
||||
open('../kitty/gl-wrapper.h', 'w').write(strip_trailing_whitespace(raw))
|
||||
raw = open('out/include/KHR/khrplatform.h', 'rb').read().decode('utf-8')
|
||||
open('../kitty/khrplatform.h', 'w').write(strip_trailing_whitespace(raw))
|
||||
with open('../kitty/gl-wrapper.h', 'w', encoding='utf-8') as dest:
|
||||
dest.write(data)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
124
glfw/backend_utils.c
vendored
124
glfw/backend_utils.c
vendored
@@ -11,6 +11,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <float.h>
|
||||
#include <time.h>
|
||||
@@ -21,16 +23,16 @@
|
||||
#endif
|
||||
|
||||
static inline double
|
||||
monotonic() {
|
||||
monotonic(void) {
|
||||
struct timespec ts = {0};
|
||||
#ifdef CLOCK_HIGHRES
|
||||
clock_gettime(CLOCK_HIGHRES, &ts);
|
||||
clock_gettime(CLOCK_HIGHRES, &ts);
|
||||
#elif CLOCK_MONOTONIC_RAW
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
|
||||
#else
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
#endif
|
||||
return (((double)ts.tv_nsec) / 1e9) + (double)ts.tv_sec;
|
||||
return (((double)ts.tv_nsec) / 1e9) + (double)ts.tv_sec;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -55,6 +57,7 @@ addWatch(EventLoopData *eld, const char* name, int fd, int events, int enabled,
|
||||
w->fd = fd; w->events = events; w->enabled = enabled;
|
||||
w->callback = cb;
|
||||
w->callback_data = cb_data;
|
||||
w->free = NULL;
|
||||
w->id = ++watch_counter;
|
||||
update_fds(eld);
|
||||
return w->id;
|
||||
@@ -64,6 +67,10 @@ addWatch(EventLoopData *eld, const char* name, int fd, int events, int enabled,
|
||||
for (nfds_t i = 0; i < eld->which##_count; i++) { \
|
||||
if (eld->which[i].id == item_id) { \
|
||||
eld->which##_count--; \
|
||||
if (eld->which[i].callback_data && eld->which[i].free) { \
|
||||
eld->which[i].free(eld->which[i].id, eld->which[i].callback_data); \
|
||||
eld->which[i].callback_data = NULL; eld->which[i].free = NULL; \
|
||||
} \
|
||||
if (i < eld->which##_count) { \
|
||||
memmove(eld->which + i, eld->which + i + 1, sizeof(eld->which[0]) * (eld->which##_count - i)); \
|
||||
} \
|
||||
@@ -102,7 +109,7 @@ update_timers(EventLoopData *eld) {
|
||||
}
|
||||
|
||||
id_type
|
||||
addTimer(EventLoopData *eld, const char *name, double interval, int enabled, timer_callback_func cb, void *cb_data) {
|
||||
addTimer(EventLoopData *eld, const char *name, double interval, int enabled, bool repeats, timer_callback_func cb, void *cb_data, GLFWuserdatafreefun free) {
|
||||
if (eld->timers_count >= sizeof(eld->timers)/sizeof(eld->timers[0])) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Too many timers added");
|
||||
return 0;
|
||||
@@ -111,11 +118,13 @@ addTimer(EventLoopData *eld, const char *name, double interval, int enabled, tim
|
||||
t->interval = interval;
|
||||
t->name = name;
|
||||
t->trigger_at = enabled ? monotonic() + interval : DBL_MAX;
|
||||
t->repeats = repeats;
|
||||
t->callback = cb;
|
||||
t->callback_data = cb_data;
|
||||
t->free = free;
|
||||
t->id = ++timer_counter;
|
||||
update_timers(eld);
|
||||
return t->id;
|
||||
return timer_counter;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -123,6 +132,14 @@ removeTimer(EventLoopData *eld, id_type timer_id) {
|
||||
removeX(timers, timer_id, update_timers);
|
||||
}
|
||||
|
||||
void
|
||||
removeAllTimers(EventLoopData *eld) {
|
||||
for (nfds_t i = 0; i < eld->timers_count; i++) {
|
||||
if (eld->timers[i].free && eld->timers[i].callback_data) eld->timers[i].free(eld->timers[i].id, eld->timers[i].callback_data);
|
||||
}
|
||||
eld->timers_count = 0;
|
||||
}
|
||||
|
||||
void
|
||||
toggleTimer(EventLoopData *eld, id_type timer_id, int enabled) {
|
||||
for (nfds_t i = 0; i < eld->timers_count; i++) {
|
||||
@@ -182,7 +199,7 @@ dispatchEvents(EventLoopData *eld) {
|
||||
unsigned
|
||||
dispatchTimers(EventLoopData *eld) {
|
||||
if (!eld->timers_count || eld->timers[0].trigger_at == DBL_MAX) return 0;
|
||||
static struct { timer_callback_func func; id_type id; void* data; } dispatches[sizeof(eld->timers)/sizeof(eld->timers[0])];
|
||||
static struct { timer_callback_func func; id_type id; void* data; bool repeats; } dispatches[sizeof(eld->timers)/sizeof(eld->timers[0])];
|
||||
unsigned num_dispatches = 0;
|
||||
double now = monotonic();
|
||||
for (nfds_t i = 0; i < eld->timers_count && eld->timers[i].trigger_at <= now; i++) {
|
||||
@@ -190,35 +207,105 @@ dispatchTimers(EventLoopData *eld) {
|
||||
dispatches[num_dispatches].func = eld->timers[i].callback;
|
||||
dispatches[num_dispatches].id = eld->timers[i].id;
|
||||
dispatches[num_dispatches].data = eld->timers[i].callback_data;
|
||||
dispatches[num_dispatches].repeats = eld->timers[i].repeats;
|
||||
num_dispatches++;
|
||||
}
|
||||
// we dispatch separately so that the callbacks can modify timers
|
||||
for (unsigned i = 0; i < num_dispatches; i++) {
|
||||
dispatches[i].func(dispatches[i].id, dispatches[i].data);
|
||||
if (!dispatches[i].repeats) {
|
||||
removeTimer(eld, dispatches[i].id);
|
||||
}
|
||||
}
|
||||
if (num_dispatches) update_timers(eld);
|
||||
return num_dispatches;
|
||||
}
|
||||
|
||||
static void
|
||||
drain_wakeup_fd(int fd, int events, void* data) {
|
||||
drain_wakeup_fd(int fd, EventLoopData* eld) {
|
||||
static char drain_buf[64];
|
||||
while(read(fd, drain_buf, sizeof(drain_buf)) < 0 && errno == EINTR);
|
||||
eld->wakeup_data_read = false;
|
||||
while(true) {
|
||||
ssize_t ret = read(fd, drain_buf, sizeof(drain_buf));
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) continue;
|
||||
break;
|
||||
}
|
||||
if (ret > 0) { eld->wakeup_data_read = true; continue; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mark_wakep_fd_ready(int fd UNUSED, int events UNUSED, void *data) {
|
||||
((EventLoopData*)(data))->wakeup_fd_ready = true;
|
||||
}
|
||||
|
||||
bool
|
||||
initPollData(EventLoopData *eld, int display_fd) {
|
||||
if (!addWatch(eld, "display", display_fd, POLLIN, 1, NULL, NULL)) return false;
|
||||
#ifdef HAS_EVENT_FD
|
||||
eld->wakeupFd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
|
||||
if (eld->wakeupFd == -1) return false;
|
||||
const int wakeup_fd = eld->wakeupFd;
|
||||
#else
|
||||
if (pipe2(eld->wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0) return false;
|
||||
const int wakeup_fd = eld->wakeupFds[0];
|
||||
#endif
|
||||
if (!addWatch(eld, "wakeup", wakeup_fd, POLLIN, 1, mark_wakep_fd_ready, eld)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
initPollData(EventLoopData *eld, int wakeup_fd, int display_fd) {
|
||||
addWatch(eld, "display", display_fd, POLLIN, 1, NULL, NULL);
|
||||
addWatch(eld, "wakeup", wakeup_fd, POLLIN, 1, drain_wakeup_fd, NULL);
|
||||
check_for_wakeup_events(EventLoopData *eld) {
|
||||
#ifdef HAS_EVENT_FD
|
||||
int fd = eld->wakeupFd;
|
||||
#else
|
||||
int fd = eld->wakeupFds[0];
|
||||
#endif
|
||||
drain_wakeup_fd(fd, eld);
|
||||
}
|
||||
|
||||
void
|
||||
wakeupEventLoop(EventLoopData *eld) {
|
||||
#ifdef HAS_EVENT_FD
|
||||
static const uint64_t value = 1;
|
||||
while (write(eld->wakeupFd, &value, sizeof value) < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
#else
|
||||
while (write(eld->wakeupFds[1], "w", 1) < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAS_EVENT_FD
|
||||
static inline void
|
||||
closeFds(int *fds, size_t count) {
|
||||
while(count--) {
|
||||
if (*fds > 0) {
|
||||
close(*fds);
|
||||
*fds = -1;
|
||||
}
|
||||
fds++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
finalizePollData(EventLoopData *eld) {
|
||||
#ifdef HAS_EVENT_FD
|
||||
close(eld->wakeupFd); eld->wakeupFd = -1;
|
||||
#else
|
||||
closeFds(eld->wakeupFds, arraysz(eld->wakeupFds));
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
pollForEvents(EventLoopData *eld, double timeout) {
|
||||
int read_ok = 0;
|
||||
timeout = prepareForPoll(eld, timeout);
|
||||
EVDBG("pollForEvents final timeout: %.3f", timeout);
|
||||
int result;
|
||||
double end_time = monotonic() + timeout;
|
||||
eld->wakeup_fd_ready = false;
|
||||
|
||||
while(1) {
|
||||
if (timeout >= 0) {
|
||||
@@ -251,17 +338,6 @@ pollForEvents(EventLoopData *eld, double timeout) {
|
||||
return read_ok;
|
||||
}
|
||||
|
||||
void
|
||||
closeFds(int *fds, size_t count) {
|
||||
while(count--) {
|
||||
if (*fds > 0) {
|
||||
close(*fds);
|
||||
*fds = -1;
|
||||
}
|
||||
fds++;
|
||||
}
|
||||
}
|
||||
|
||||
// Splits and translates a text/uri-list into separate file paths
|
||||
// NOTE: This function destroys the provided string
|
||||
//
|
||||
|
||||
31
glfw/backend_utils.h
vendored
31
glfw/backend_utils.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Wayland - www.glfw.org
|
||||
// GLFW 3.4 Wayland - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -27,15 +27,28 @@
|
||||
#pragma once
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __has_include
|
||||
#if __has_include(<sys/eventfd.h>)
|
||||
#define HAS_EVENT_FD
|
||||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
#else
|
||||
#define HAS_EVENT_FD
|
||||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
typedef unsigned long long id_type;
|
||||
typedef void(*watch_callback_func)(int, int, void*);
|
||||
typedef void(*timer_callback_func)(id_type, void*);
|
||||
typedef void (* GLFWuserdatafreefun)(id_type, void*);
|
||||
|
||||
typedef struct {
|
||||
int fd, events, enabled, ready;
|
||||
watch_callback_func callback;
|
||||
void *callback_data;
|
||||
GLFWuserdatafreefun free;
|
||||
id_type id;
|
||||
const char *name;
|
||||
} Watch;
|
||||
@@ -45,30 +58,40 @@ typedef struct {
|
||||
double interval, trigger_at;
|
||||
timer_callback_func callback;
|
||||
void *callback_data;
|
||||
GLFWuserdatafreefun free;
|
||||
const char *name;
|
||||
bool repeats;
|
||||
} Timer;
|
||||
|
||||
|
||||
typedef struct {
|
||||
struct pollfd fds[32];
|
||||
#ifdef HAS_EVENT_FD
|
||||
int wakeupFd;
|
||||
#else
|
||||
int wakeupFds[2];
|
||||
#endif
|
||||
bool wakeup_data_read, wakeup_fd_ready;
|
||||
nfds_t watches_count, timers_count;
|
||||
Watch watches[32];
|
||||
Timer timers[128];
|
||||
} EventLoopData;
|
||||
|
||||
|
||||
void check_for_wakeup_events(EventLoopData *eld);
|
||||
id_type addWatch(EventLoopData *eld, const char *name, int fd, int events, int enabled, watch_callback_func cb, void *cb_data);
|
||||
void removeWatch(EventLoopData *eld, id_type watch_id);
|
||||
void toggleWatch(EventLoopData *eld, id_type watch_id, int enabled);
|
||||
id_type addTimer(EventLoopData *eld, const char *name, double interval, int enabled, timer_callback_func cb, void *cb_data);
|
||||
id_type addTimer(EventLoopData *eld, const char *name, double interval, int enabled, bool repeats, timer_callback_func cb, void *cb_data, GLFWuserdatafreefun free);
|
||||
void removeTimer(EventLoopData *eld, id_type timer_id);
|
||||
void removeAllTimers(EventLoopData *eld);
|
||||
void toggleTimer(EventLoopData *eld, id_type timer_id, int enabled);
|
||||
void changeTimerInterval(EventLoopData *eld, id_type timer_id, double interval);
|
||||
double prepareForPoll(EventLoopData *eld, double timeout);
|
||||
int pollWithTimeout(struct pollfd *fds, nfds_t nfds, double timeout);
|
||||
int pollForEvents(EventLoopData *eld, double timeout);
|
||||
unsigned dispatchTimers(EventLoopData *eld);
|
||||
void closeFds(int *fds, size_t count);
|
||||
void initPollData(EventLoopData *eld, int wakeup_fd, int display_fd);
|
||||
void finalizePollData(EventLoopData *eld);
|
||||
bool initPollData(EventLoopData *eld, int display_fd);
|
||||
char** parseUriList(char* text, int* count);
|
||||
void wakeupEventLoop(EventLoopData *eld);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -23,10 +23,12 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
#include <sys/param.h> // For MAXPATHLEN
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
// Change to our application bundle's resources directory, if present
|
||||
//
|
||||
@@ -198,7 +200,7 @@ static void createKeyTables(void)
|
||||
|
||||
// Retrieve Unicode data for the current keyboard layout
|
||||
//
|
||||
static GLFWbool updateUnicodeDataNS(void)
|
||||
static bool updateUnicodeDataNS(void)
|
||||
{
|
||||
if (_glfw.ns.inputSource)
|
||||
{
|
||||
@@ -215,7 +217,7 @@ static GLFWbool updateUnicodeDataNS(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to retrieve keyboard layout input source");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.ns.unicodeData =
|
||||
@@ -225,15 +227,15 @@ static GLFWbool updateUnicodeDataNS(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to retrieve keyboard layout Unicode data");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Load HIToolbox.framework and the TIS symbols we need from it
|
||||
//
|
||||
static GLFWbool initializeTIS(void)
|
||||
static bool initializeTIS(void)
|
||||
{
|
||||
// This works only because Cocoa has already loaded it properly
|
||||
_glfw.ns.tis.bundle =
|
||||
@@ -242,19 +244,19 @@ static GLFWbool initializeTIS(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to load HIToolbox.framework");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
CFStringRef* kPropertyUnicodeKeyLayoutData =
|
||||
CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,
|
||||
CFSTR("kTISPropertyUnicodeKeyLayoutData"));
|
||||
_glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
|
||||
*(void **)&_glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
|
||||
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
|
||||
CFSTR("TISCopyCurrentKeyboardLayoutInputSource"));
|
||||
_glfw.ns.tis.GetInputSourceProperty =
|
||||
*(void **)&_glfw.ns.tis.GetInputSourceProperty =
|
||||
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
|
||||
CFSTR("TISGetInputSourceProperty"));
|
||||
_glfw.ns.tis.GetKbdType =
|
||||
*(void **)&_glfw.ns.tis.GetKbdType =
|
||||
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
|
||||
CFSTR("LMGetKbdType"));
|
||||
|
||||
@@ -265,7 +267,7 @@ static GLFWbool initializeTIS(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to load TIS API symbols");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
|
||||
@@ -274,16 +276,40 @@ static GLFWbool initializeTIS(void)
|
||||
return updateUnicodeDataNS();
|
||||
}
|
||||
|
||||
@interface GLFWLayoutListener : NSObject
|
||||
@interface GLFWHelper : NSObject
|
||||
@end
|
||||
|
||||
@implementation GLFWLayoutListener
|
||||
@implementation GLFWHelper
|
||||
|
||||
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
|
||||
{
|
||||
(void)object;
|
||||
updateUnicodeDataNS();
|
||||
}
|
||||
|
||||
- (void)doNothing:(id)object
|
||||
{
|
||||
(void)object;
|
||||
}
|
||||
|
||||
@end // GLFWHelper
|
||||
|
||||
@interface GLFWApplication : NSApplication
|
||||
- (void)tick_callback;
|
||||
- (void)render_frame_received:(id)displayIDAsID;
|
||||
@end
|
||||
|
||||
@implementation GLFWApplication
|
||||
- (void)tick_callback
|
||||
{
|
||||
_glfwDispatchTickCallback();
|
||||
}
|
||||
|
||||
- (void)render_frame_received:(id)displayIDAsID
|
||||
{
|
||||
CGDirectDisplayID displayID = [(NSNumber*)displayIDAsID unsignedIntValue];
|
||||
_glfwDispatchRenderFrame(displayID);
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@@ -291,16 +317,76 @@ static GLFWbool initializeTIS(void)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static inline bool
|
||||
is_ctrl_tab(NSEvent *event, NSEventModifierFlags modifierFlags) {
|
||||
if (
|
||||
(modifierFlags == NSEventModifierFlagControl &&
|
||||
[event.charactersIgnoringModifiers isEqualToString:@"\t"]) ||
|
||||
(modifierFlags == (NSEventModifierFlagControl | NSEventModifierFlagShift) &&
|
||||
[event.charactersIgnoringModifiers isEqualToString:@"\x19"])
|
||||
) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_cmd_period(NSEvent *event, NSEventModifierFlags modifierFlags) {
|
||||
if (modifierFlags != NSEventModifierFlagCommand) return false;
|
||||
if ([event.charactersIgnoringModifiers isEqualToString:@"."]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformInit(void)
|
||||
{
|
||||
_glfw.ns.autoreleasePool = [[NSAutoreleasePool alloc] init];
|
||||
@autoreleasepool {
|
||||
|
||||
_glfw.ns.helper = [[GLFWHelper alloc] init];
|
||||
|
||||
[NSThread detachNewThreadSelector:@selector(doNothing:)
|
||||
toTarget:_glfw.ns.helper
|
||||
withObject:nil];
|
||||
|
||||
[GLFWApplication sharedApplication];
|
||||
|
||||
NSEvent* (^keydown_block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
|
||||
{
|
||||
NSEventModifierFlags modifierFlags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
|
||||
if (is_ctrl_tab(event, modifierFlags) || is_cmd_period(event, modifierFlags)) {
|
||||
// Cocoa swallows Ctrl+Tab to cycle between views
|
||||
[[NSApp keyWindow].contentView keyDown:event];
|
||||
}
|
||||
|
||||
return event;
|
||||
};
|
||||
|
||||
NSEvent* (^keyup_block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
|
||||
{
|
||||
NSEventModifierFlags modifierFlags = [event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask;
|
||||
if (modifierFlags & NSEventModifierFlagCommand) {
|
||||
// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
|
||||
// This works around an AppKit bug, where key up events while holding
|
||||
// down the command key don't get sent to the key window.
|
||||
[[NSApp keyWindow] sendEvent:event];
|
||||
}
|
||||
if (is_ctrl_tab(event, modifierFlags) || is_cmd_period(event, modifierFlags)) {
|
||||
// Cocoa swallows Ctrl+Tab to cycle between views
|
||||
[[NSApp keyWindow].contentView keyUp:event];
|
||||
}
|
||||
|
||||
return event;
|
||||
};
|
||||
|
||||
_glfw.ns.keyUpMonitor =
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp
|
||||
handler:keyup_block];
|
||||
_glfw.ns.keyDownMonitor =
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyDown
|
||||
handler:keydown_block];
|
||||
|
||||
if (_glfw.hints.init.ns.chdir)
|
||||
changeToResourcesDirectory();
|
||||
|
||||
_glfw.ns.listener = [[GLFWLayoutListener alloc] init];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:_glfw.ns.listener
|
||||
addObserver:_glfw.ns.helper
|
||||
selector:@selector(selectedKeyboardInputSourceChanged:)
|
||||
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
||||
object:nil];
|
||||
@@ -309,22 +395,28 @@ int _glfwPlatformInit(void)
|
||||
|
||||
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
|
||||
if (!_glfw.ns.eventSource)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
|
||||
|
||||
if (!initializeTIS())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
_glfwInitTimerNS();
|
||||
_glfwInitJoysticksNS();
|
||||
|
||||
_glfwPollMonitorsNS();
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
{
|
||||
@autoreleasepool {
|
||||
|
||||
_glfwClearDisplayLinks();
|
||||
|
||||
if (_glfw.ns.inputSource)
|
||||
{
|
||||
CFRelease(_glfw.ns.inputSource);
|
||||
@@ -345,32 +437,165 @@ void _glfwPlatformTerminate(void)
|
||||
_glfw.ns.delegate = nil;
|
||||
}
|
||||
|
||||
if (_glfw.ns.listener)
|
||||
if (_glfw.ns.helper)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
removeObserver:_glfw.ns.listener
|
||||
removeObserver:_glfw.ns.helper
|
||||
name:NSTextInputContextKeyboardSelectionDidChangeNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
removeObserver:_glfw.ns.listener];
|
||||
[_glfw.ns.listener release];
|
||||
_glfw.ns.listener = nil;
|
||||
removeObserver:_glfw.ns.helper];
|
||||
[_glfw.ns.helper release];
|
||||
_glfw.ns.helper = nil;
|
||||
}
|
||||
|
||||
if (_glfw.ns.keyUpMonitor)
|
||||
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
|
||||
if (_glfw.ns.keyDownMonitor)
|
||||
[NSEvent removeMonitor:_glfw.ns.keyDownMonitor];
|
||||
|
||||
free(_glfw.ns.clipboardString);
|
||||
|
||||
_glfwTerminateNSGL();
|
||||
_glfwTerminateJoysticksNS();
|
||||
|
||||
[_glfw.ns.autoreleasePool release];
|
||||
_glfw.ns.autoreleasePool = nil;
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
{
|
||||
return _GLFW_VERSION_NUMBER " Cocoa NSGL"
|
||||
return _GLFW_VERSION_NUMBER " Cocoa NSGL EGL OSMesa"
|
||||
#if defined(_GLFW_BUILD_DLL)
|
||||
" dynamic"
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
static GLFWtickcallback tick_callback = NULL;
|
||||
static void* tick_callback_data = NULL;
|
||||
static bool tick_callback_requested = false;
|
||||
static pthread_t main_thread;
|
||||
static NSLock *tick_lock = NULL;
|
||||
|
||||
|
||||
void _glfwDispatchTickCallback() {
|
||||
if (tick_lock && tick_callback) {
|
||||
[tick_lock lock];
|
||||
while(tick_callback_requested) {
|
||||
tick_callback_requested = false;
|
||||
tick_callback(tick_callback_data);
|
||||
}
|
||||
[tick_lock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
request_tick_callback() {
|
||||
if (!tick_callback_requested) {
|
||||
tick_callback_requested = true;
|
||||
[NSApp performSelectorOnMainThread:@selector(tick_callback) withObject:nil waitUntilDone:NO];
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformPostEmptyEvent(void)
|
||||
{
|
||||
if (pthread_equal(pthread_self(), main_thread)) {
|
||||
request_tick_callback();
|
||||
} else if (tick_lock) {
|
||||
[tick_lock lock];
|
||||
request_tick_callback();
|
||||
[tick_lock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _glfwPlatformStopMainLoop(void) {
|
||||
[NSApp stop:nil];
|
||||
_glfwCocoaPostEmptyEvent();
|
||||
}
|
||||
|
||||
void _glfwPlatformRunMainLoop(GLFWtickcallback callback, void* data) {
|
||||
main_thread = pthread_self();
|
||||
tick_callback = callback;
|
||||
tick_callback_data = data;
|
||||
tick_lock = [NSLock new];
|
||||
[NSApp run];
|
||||
[tick_lock release];
|
||||
tick_lock = NULL;
|
||||
tick_callback = NULL;
|
||||
tick_callback_data = NULL;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
NSTimer *os_timer;
|
||||
unsigned long long id;
|
||||
bool repeats;
|
||||
double interval;
|
||||
GLFWuserdatafun callback;
|
||||
void *callback_data;
|
||||
GLFWuserdatafun free_callback_data;
|
||||
} Timer;
|
||||
|
||||
static Timer timers[128] = {{0}};
|
||||
static size_t num_timers = 0;
|
||||
|
||||
static inline void
|
||||
remove_timer_at(size_t idx) {
|
||||
if (idx < num_timers) {
|
||||
Timer *t = timers + idx;
|
||||
if (t->os_timer) { [t->os_timer invalidate]; t->os_timer = NULL; }
|
||||
if (t->callback_data && t->free_callback_data) { t->free_callback_data(t->id, t->callback_data); t->callback_data = NULL; }
|
||||
remove_i_from_array(timers, idx, num_timers);
|
||||
}
|
||||
}
|
||||
|
||||
static void schedule_timer(Timer *t) {
|
||||
t->os_timer = [NSTimer scheduledTimerWithTimeInterval:t->interval repeats:(t->repeats ? YES: NO) block:^(NSTimer *os_timer) {
|
||||
for (size_t i = 0; i < num_timers; i++) {
|
||||
if (timers[i].os_timer == os_timer) {
|
||||
timers[i].callback(timers[i].id, timers[i].callback_data);
|
||||
if (!timers[i].repeats) remove_timer_at(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuserdatafun callback, void *callback_data, GLFWuserdatafun free_callback) {
|
||||
static unsigned long long timer_counter = 0;
|
||||
if (num_timers >= sizeof(timers)/sizeof(timers[0]) - 1) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Too many timers added");
|
||||
return 0;
|
||||
}
|
||||
Timer *t = timers + num_timers++;
|
||||
t->id = ++timer_counter;
|
||||
t->repeats = repeats;
|
||||
t->interval = interval;
|
||||
t->callback = callback;
|
||||
t->callback_data = callback_data;
|
||||
t->free_callback_data = free_callback;
|
||||
schedule_timer(t);
|
||||
return timer_counter;
|
||||
}
|
||||
|
||||
void _glfwPlatformRemoveTimer(unsigned long long timer_id) {
|
||||
for (size_t i = 0; i < num_timers; i++) {
|
||||
if (timers[i].id == timer_id) {
|
||||
remove_timer_at(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, bool enabled) {
|
||||
for (size_t i = 0; i < num_timers; i++) {
|
||||
if (timers[i].id == timer_id) {
|
||||
Timer *t = timers + i;
|
||||
if (t->os_timer) { [t->os_timer invalidate]; t->os_timer = NULL; }
|
||||
t->interval = interval;
|
||||
if (enabled) schedule_timer(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
glfw/cocoa_joystick.h
vendored
4
glfw/cocoa_joystick.h
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Cocoa - www.glfw.org
|
||||
// GLFW 3.4 Cocoa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Cocoa - www.glfw.org
|
||||
// GLFW 3.4 Cocoa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -75,7 +77,7 @@ static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
|
||||
//
|
||||
static CFComparisonResult compareElements(const void* fp,
|
||||
const void* sp,
|
||||
void* user)
|
||||
void* user UNUSED)
|
||||
{
|
||||
const _GLFWjoyelementNS* fe = fp;
|
||||
const _GLFWjoyelementNS* se = sp;
|
||||
@@ -117,9 +119,9 @@ static void closeJoystick(_GLFWjoystick* js)
|
||||
|
||||
// Callback for user-initiated joystick addition
|
||||
//
|
||||
static void matchCallback(void* context,
|
||||
IOReturn result,
|
||||
void* sender,
|
||||
static void matchCallback(void* context UNUSED,
|
||||
IOReturn result UNUSED,
|
||||
void* sender UNUSED,
|
||||
IOHIDDeviceRef device)
|
||||
{
|
||||
int jid;
|
||||
@@ -220,9 +222,18 @@ static void matchCallback(void* context,
|
||||
case kHIDUsage_GD_Hatswitch:
|
||||
target = hats;
|
||||
break;
|
||||
case kHIDUsage_GD_DPadUp:
|
||||
case kHIDUsage_GD_DPadRight:
|
||||
case kHIDUsage_GD_DPadDown:
|
||||
case kHIDUsage_GD_DPadLeft:
|
||||
case kHIDUsage_GD_SystemMainMenu:
|
||||
case kHIDUsage_GD_Select:
|
||||
case kHIDUsage_GD_Start:
|
||||
target = buttons;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (page == kHIDPage_Button)
|
||||
else if (page == kHIDPage_Button || page == kHIDPage_Consumer)
|
||||
target = buttons;
|
||||
|
||||
if (target)
|
||||
@@ -261,9 +272,9 @@ static void matchCallback(void* context,
|
||||
|
||||
// Callback for user-initiated joystick removal
|
||||
//
|
||||
static void removeCallback(void* context,
|
||||
IOReturn result,
|
||||
void* sender,
|
||||
static void removeCallback(void* context UNUSED,
|
||||
IOReturn result UNUSED,
|
||||
void* sender UNUSED,
|
||||
IOHIDDeviceRef device)
|
||||
{
|
||||
int jid;
|
||||
@@ -307,7 +318,7 @@ void _glfwInitJoysticksNS(void)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(usages) / sizeof(long); i++)
|
||||
for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++)
|
||||
{
|
||||
const long page = kHIDPage_GenericDesktop;
|
||||
|
||||
@@ -397,12 +408,12 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
if (raw > axis->maximum)
|
||||
axis->maximum = raw;
|
||||
|
||||
const long delta = axis->maximum - axis->minimum;
|
||||
if (delta == 0)
|
||||
const long size = axis->maximum - axis->minimum;
|
||||
if (size == 0)
|
||||
_glfwInputJoystickAxis(js, (int) i, 0.f);
|
||||
else
|
||||
{
|
||||
const float value = (2.f * (raw - axis->minimum) / delta) - 1.f;
|
||||
const float value = (2.f * (raw - axis->minimum) / size) - 1.f;
|
||||
_glfwInputJoystickAxis(js, (int) i, value);
|
||||
}
|
||||
}
|
||||
@@ -417,7 +428,8 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
|
||||
CFArrayGetValueAtIndex(js->ns.buttons, i);
|
||||
const char value = getElementValue(js, button) - button->minimum;
|
||||
_glfwInputJoystickButton(js, (int) i, value);
|
||||
const int state = (value > 0) ? GLFW_PRESS : GLFW_RELEASE;
|
||||
_glfwInputJoystickButton(js, (int) i, state);
|
||||
}
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||
@@ -454,9 +466,8 @@ void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
(strncmp(guid + 20, "000000000000", 12) == 0))
|
||||
{
|
||||
char original[33];
|
||||
strcpy(original, guid);
|
||||
strncpy(original, guid, sizeof(original) - 1);
|
||||
sprintf(guid, "03000000%.4s0000%.4s000000000000",
|
||||
original, original + 16);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,11 +24,14 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <IOKit/graphics/IOGraphicsLib.h>
|
||||
#include <CoreVideo/CVBase.h>
|
||||
@@ -115,16 +118,16 @@ static char* getDisplayName(CGDirectDisplayID displayID)
|
||||
|
||||
// Check whether the display mode should be included in enumeration
|
||||
//
|
||||
static GLFWbool modeIsGood(CGDisplayModeRef mode)
|
||||
static bool modeIsGood(CGDisplayModeRef mode)
|
||||
{
|
||||
uint32_t flags = CGDisplayModeGetIOFlags(mode);
|
||||
|
||||
if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (flags & kDisplayModeInterlacedFlag)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (flags & kDisplayModeStretchedFlag)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
|
||||
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
|
||||
@@ -132,12 +135,12 @@ static GLFWbool modeIsGood(CGDisplayModeRef mode)
|
||||
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
|
||||
{
|
||||
CFRelease(format);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
CFRelease(format);
|
||||
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Convert Core Graphics display mode to GLFW video mode
|
||||
@@ -148,7 +151,7 @@ static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
|
||||
GLFWvidmode result;
|
||||
result.width = (int) CGDisplayModeGetWidth(mode);
|
||||
result.height = (int) CGDisplayModeGetHeight(mode);
|
||||
result.refreshRate = (int) CGDisplayModeGetRefreshRate(mode);
|
||||
result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode));
|
||||
|
||||
if (result.refreshRate == 0)
|
||||
{
|
||||
@@ -212,27 +215,87 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
|
||||
}
|
||||
}
|
||||
|
||||
// Finds and caches the NSScreen corresponding to the specified monitor
|
||||
//
|
||||
static bool refreshMonitorScreen(_GLFWmonitor* monitor)
|
||||
{
|
||||
if (monitor->ns.screen)
|
||||
return true;
|
||||
|
||||
for (NSScreen* screen in [NSScreen screens])
|
||||
{
|
||||
NSNumber* displayID = [screen deviceDescription][@"NSScreenNumber"];
|
||||
|
||||
// HACK: Compare unit numbers instead of display IDs to work around
|
||||
// display replacement on machines with automatic graphics
|
||||
// switching
|
||||
if (monitor->ns.unitNumber == CGDisplayUnitNumber([displayID unsignedIntValue]))
|
||||
{
|
||||
monitor->ns.screen = screen;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to find a screen for monitor");
|
||||
return false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwClearDisplayLinks() {
|
||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
||||
if (_glfw.ns.displayLinks.entries[i].displayLink) {
|
||||
CVDisplayLinkStop(_glfw.ns.displayLinks.entries[i].displayLink);
|
||||
CVDisplayLinkRelease(_glfw.ns.displayLinks.entries[i].displayLink);
|
||||
_glfw.ns.displayLinks.entries[i].displayLink = nil;
|
||||
_glfw.ns.displayLinks.entries[i].lastRenderFrameRequestedAt = 0;
|
||||
}
|
||||
}
|
||||
_glfw.ns.displayLinks.count = 0;
|
||||
}
|
||||
|
||||
static CVReturn displayLinkCallback(
|
||||
CVDisplayLinkRef displayLink UNUSED,
|
||||
const CVTimeStamp* now UNUSED, const CVTimeStamp* outputTime UNUSED,
|
||||
CVOptionFlags flagsIn UNUSED, CVOptionFlags* flagsOut UNUSED, void* userInfo)
|
||||
{
|
||||
CGDirectDisplayID displayID = (CGDirectDisplayID)userInfo;
|
||||
NSNumber *arg = [NSNumber numberWithUnsignedInt:displayID];
|
||||
[NSApp performSelectorOnMainThread:@selector(render_frame_received:) withObject:arg waitUntilDone:NO];
|
||||
[arg release];
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
static inline void createDisplayLink(CGDirectDisplayID displayID) {
|
||||
if (_glfw.ns.displayLinks.count >= sizeof(_glfw.ns.displayLinks.entries)/sizeof(_glfw.ns.displayLinks.entries[0]) - 1) return;
|
||||
for (size_t i = 0; i < _glfw.ns.displayLinks.count; i++) {
|
||||
if (_glfw.ns.displayLinks.entries[i].displayID == displayID) return;
|
||||
}
|
||||
_GLFWDisplayLinkNS *entry = &_glfw.ns.displayLinks.entries[_glfw.ns.displayLinks.count++];
|
||||
memset(entry, 0, sizeof(_GLFWDisplayLinkNS));
|
||||
entry->displayID = displayID;
|
||||
CVDisplayLinkCreateWithCGDisplay(displayID, &entry->displayLink);
|
||||
CVDisplayLinkSetOutputCallback(entry->displayLink, &displayLinkCallback, (void*)(uintptr_t)displayID);
|
||||
}
|
||||
|
||||
// Poll for changes in the set of connected monitors
|
||||
//
|
||||
void _glfwPollMonitorsNS(void)
|
||||
{
|
||||
uint32_t i, j, displayCount, disconnectedCount;
|
||||
CGDirectDisplayID* displays;
|
||||
_GLFWmonitor** disconnected = NULL;
|
||||
uint32_t displayCount;
|
||||
|
||||
CGGetOnlineDisplayList(0, NULL, &displayCount);
|
||||
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||
CGDirectDisplayID* displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
|
||||
_glfwClearDisplayLinks();
|
||||
|
||||
for (i = 0; i < _glfw.monitorCount; i++)
|
||||
for (int i = 0; i < _glfw.monitorCount; i++)
|
||||
_glfw.monitors[i]->ns.screen = nil;
|
||||
|
||||
disconnectedCount = _glfw.monitorCount;
|
||||
_GLFWmonitor** disconnected = NULL;
|
||||
uint32_t disconnectedCount = _glfw.monitorCount;
|
||||
if (disconnectedCount)
|
||||
{
|
||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||
@@ -241,19 +304,18 @@ void _glfwPollMonitorsNS(void)
|
||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||
}
|
||||
|
||||
for (i = 0; i < displayCount; i++)
|
||||
for (uint32_t i = 0; i < displayCount; i++)
|
||||
{
|
||||
_GLFWmonitor* monitor;
|
||||
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
||||
|
||||
if (CGDisplayIsAsleep(displays[i]))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < disconnectedCount; j++)
|
||||
// HACK: Compare unit numbers instead of display IDs to work around
|
||||
// display replacement on machines with automatic graphics
|
||||
// switching
|
||||
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
|
||||
|
||||
for (uint32_t j = 0; j < disconnectedCount; j++)
|
||||
{
|
||||
// HACK: Compare unit numbers instead of display IDs to work around
|
||||
// display replacement on machines with automatic graphics
|
||||
// switching
|
||||
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
|
||||
{
|
||||
disconnected[j] = NULL;
|
||||
@@ -266,16 +328,17 @@ void _glfwPollMonitorsNS(void)
|
||||
if (!name)
|
||||
name = _glfw_strdup("Unknown");
|
||||
|
||||
monitor = _glfwAllocMonitor(name, size.width, size.height);
|
||||
_GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height);
|
||||
monitor->ns.displayID = displays[i];
|
||||
monitor->ns.unitNumber = unitNumber;
|
||||
createDisplayLink(monitor->ns.displayID);
|
||||
|
||||
free(name);
|
||||
|
||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||
}
|
||||
|
||||
for (i = 0; i < disconnectedCount; i++)
|
||||
for (uint32_t i = 0; i < disconnectedCount; i++)
|
||||
{
|
||||
if (disconnected[i])
|
||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||
@@ -283,30 +346,27 @@ void _glfwPollMonitorsNS(void)
|
||||
|
||||
free(disconnected);
|
||||
free(displays);
|
||||
_glfwRestartDisplayLinks();
|
||||
}
|
||||
|
||||
// Change the current video mode
|
||||
//
|
||||
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||
{
|
||||
CFArrayRef modes;
|
||||
CFIndex count, i;
|
||||
CVDisplayLinkRef link;
|
||||
CGDisplayModeRef native = NULL;
|
||||
GLFWvidmode current;
|
||||
const GLFWvidmode* best;
|
||||
|
||||
best = _glfwChooseVideoMode(monitor, desired);
|
||||
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
|
||||
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||
if (_glfwCompareVideoModes(¤t, best) == 0)
|
||||
return;
|
||||
|
||||
CVDisplayLinkRef link;
|
||||
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
|
||||
|
||||
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||
count = CFArrayGetCount(modes);
|
||||
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||
const CFIndex count = CFArrayGetCount(modes);
|
||||
CGDisplayModeRef native = NULL;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
for (CFIndex i = 0; i < count; i++)
|
||||
{
|
||||
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||
if (!modeIsGood(dm))
|
||||
@@ -355,7 +415,7 @@ void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -372,35 +432,8 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
float* xscale, float* yscale)
|
||||
{
|
||||
if (!monitor->ns.screen)
|
||||
{
|
||||
NSUInteger i;
|
||||
NSArray* screens = [NSScreen screens];
|
||||
|
||||
for (i = 0; i < [screens count]; i++)
|
||||
{
|
||||
NSScreen* screen = [screens objectAtIndex:i];
|
||||
NSNumber* displayID =
|
||||
[[screen deviceDescription] objectForKey:@"NSScreenNumber"];
|
||||
|
||||
// HACK: Compare unit numbers instead of display IDs to work around
|
||||
// display replacement on machines with automatic graphics
|
||||
// switching
|
||||
if (monitor->ns.unitNumber ==
|
||||
CGDisplayUnitNumber([displayID unsignedIntValue]))
|
||||
{
|
||||
monitor->ns.screen = screen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == [screens count])
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to find a screen for monitor");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!refreshMonitorScreen(monitor))
|
||||
return;
|
||||
|
||||
const NSRect points = [monitor->ns.screen frame];
|
||||
const NSRect pixels = [monitor->ns.screen convertRectToBacking:points];
|
||||
@@ -411,22 +444,38 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
*yscale = (float) (pixels.size.height / points.size.height);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||
int* xpos, int* ypos,
|
||||
int* width, int* height)
|
||||
{
|
||||
if (!refreshMonitorScreen(monitor))
|
||||
return;
|
||||
|
||||
const NSRect frameRect = [monitor->ns.screen visibleFrame];
|
||||
|
||||
if (xpos)
|
||||
*xpos = frameRect.origin.x;
|
||||
if (ypos)
|
||||
*ypos = _glfwTransformYNS(frameRect.origin.y + frameRect.size.height - 1);
|
||||
if (width)
|
||||
*width = frameRect.size.width;
|
||||
if (height)
|
||||
*height = frameRect.size.height;
|
||||
|
||||
}
|
||||
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
{
|
||||
CFArrayRef modes;
|
||||
CFIndex found, i, j;
|
||||
GLFWvidmode* result;
|
||||
CVDisplayLinkRef link;
|
||||
|
||||
*count = 0;
|
||||
|
||||
CVDisplayLinkRef link;
|
||||
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
|
||||
|
||||
modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||
found = CFArrayGetCount(modes);
|
||||
result = calloc(found, sizeof(GLFWvidmode));
|
||||
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
|
||||
const CFIndex found = CFArrayGetCount(modes);
|
||||
GLFWvidmode* result = calloc(found, sizeof(GLFWvidmode));
|
||||
|
||||
for (i = 0; i < found; i++)
|
||||
for (CFIndex i = 0; i < found; i++)
|
||||
{
|
||||
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
|
||||
if (!modeIsGood(dm))
|
||||
@@ -434,7 +483,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
|
||||
const GLFWvidmode mode = vidmodeFromCGDisplayMode(dm, link);
|
||||
|
||||
for (j = 0; j < *count; j++)
|
||||
for (CFIndex j = 0; j < *count; j++)
|
||||
{
|
||||
if (_glfwCompareVideoModes(result + j, &mode) == 0)
|
||||
break;
|
||||
@@ -455,21 +504,20 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
|
||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode *mode)
|
||||
{
|
||||
CGDisplayModeRef displayMode;
|
||||
CVDisplayLinkRef link;
|
||||
|
||||
CVDisplayLinkCreateWithCGDisplay(monitor->ns.displayID, &link);
|
||||
|
||||
displayMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
|
||||
*mode = vidmodeFromCGDisplayMode(displayMode, link);
|
||||
CGDisplayModeRelease(displayMode);
|
||||
CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
|
||||
*mode = vidmodeFromCGDisplayMode(native, link);
|
||||
CGDisplayModeRelease(native);
|
||||
|
||||
CVDisplayLinkRelease(link);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
{
|
||||
uint32_t i, size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
|
||||
uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
|
||||
CGGammaValue* values = calloc(size * 3, sizeof(CGGammaValue));
|
||||
|
||||
CGGetDisplayTransferByTable(monitor->ns.displayID,
|
||||
@@ -481,7 +529,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
|
||||
_glfwAllocGammaArrays(ramp, size);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
for (uint32_t i = 0; i < size; i++)
|
||||
{
|
||||
ramp->red[i] = (unsigned short) (values[i] * 65535);
|
||||
ramp->green[i] = (unsigned short) (values[i + size] * 65535);
|
||||
@@ -489,14 +537,14 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
}
|
||||
|
||||
free(values);
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
{
|
||||
int i;
|
||||
CGGammaValue* values = calloc(ramp->size * 3, sizeof(CGGammaValue));
|
||||
|
||||
for (i = 0; i < ramp->size; i++)
|
||||
for (unsigned int i = 0; i < ramp->size; i++)
|
||||
{
|
||||
values[i] = ramp->red[i] / 65535.f;
|
||||
values[i + ramp->size] = ramp->green[i] / 65535.f;
|
||||
@@ -523,4 +571,3 @@ GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
|
||||
return monitor->ns.displayID;
|
||||
}
|
||||
|
||||
|
||||
69
glfw/cocoa_platform.h
vendored
69
glfw/cocoa_platform.h
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -30,14 +30,43 @@
|
||||
#include <Carbon/Carbon.h>
|
||||
#if defined(__OBJC__)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <CoreVideo/CoreVideo.h>
|
||||
#else
|
||||
typedef void* id;
|
||||
typedef void* CVDisplayLinkRef;
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
|
||||
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
|
||||
#define NSEventMaskAny NSAnyEventMask
|
||||
#define NSEventMaskKeyUp NSKeyUpMask
|
||||
#define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask
|
||||
#define NSEventModifierFlagCommand NSCommandKeyMask
|
||||
#define NSEventModifierFlagControl NSControlKeyMask
|
||||
#define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask
|
||||
#define NSEventModifierFlagOption NSAlternateKeyMask
|
||||
#define NSEventModifierFlagShift NSShiftKeyMask
|
||||
#define NSEventTypeApplicationDefined NSApplicationDefined
|
||||
#define NSWindowStyleMaskBorderless NSBorderlessWindowMask
|
||||
#define NSWindowStyleMaskClosable NSClosableWindowMask
|
||||
#define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
|
||||
#define NSWindowStyleMaskResizable NSResizableWindowMask
|
||||
#define NSWindowStyleMaskTitled NSTitledWindowMask
|
||||
#endif
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 101400)
|
||||
#define NSPasteboardTypeFileURL NSFilenamesPboardType
|
||||
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
|
||||
#define NSPasteboardTypeString NSStringPboardType
|
||||
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
|
||||
#endif
|
||||
|
||||
|
||||
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
|
||||
typedef int (* GLFWcocoatextinputfilterfun)(int,int,int);
|
||||
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int, unsigned long);
|
||||
typedef int (* GLFWapplicationshouldhandlereopenfun)(int);
|
||||
typedef int (* GLFWcocoatogglefullscreenfun)(GLFWwindow*);
|
||||
typedef void (* GLFWcocoarenderframefun)(GLFWwindow*);
|
||||
|
||||
typedef struct VkMacOSSurfaceCreateInfoMVK
|
||||
{
|
||||
@@ -87,7 +116,8 @@ typedef struct _GLFWwindowNS
|
||||
id view;
|
||||
id layer;
|
||||
|
||||
GLFWbool maximized;
|
||||
bool maximized;
|
||||
bool retina;
|
||||
|
||||
// Cached window properties to filter out duplicate events
|
||||
int width, height;
|
||||
@@ -105,20 +135,31 @@ typedef struct _GLFWwindowNS
|
||||
GLFWcocoatogglefullscreenfun toggleFullscreenCallback;
|
||||
// Dead key state
|
||||
UInt32 deadKeyState;
|
||||
// Whether a render frame has been requested for this window
|
||||
bool renderFrameRequested;
|
||||
GLFWcocoarenderframefun renderFrameCallback;
|
||||
} _GLFWwindowNS;
|
||||
|
||||
typedef struct _GLFWDisplayLinkNS
|
||||
{
|
||||
CVDisplayLinkRef displayLink;
|
||||
CGDirectDisplayID displayID;
|
||||
double lastRenderFrameRequestedAt;
|
||||
} _GLFWDisplayLinkNS;
|
||||
|
||||
// Cocoa-specific global data
|
||||
//
|
||||
typedef struct _GLFWlibraryNS
|
||||
{
|
||||
CGEventSourceRef eventSource;
|
||||
id delegate;
|
||||
id autoreleasePool;
|
||||
GLFWbool cursorHidden;
|
||||
bool cursorHidden;
|
||||
TISInputSourceRef inputSource;
|
||||
IOHIDManagerRef hidManager;
|
||||
id unicodeData;
|
||||
id listener;
|
||||
id helper;
|
||||
id keyUpMonitor;
|
||||
id keyDownMonitor;
|
||||
|
||||
char keyName[64];
|
||||
char text[256];
|
||||
@@ -139,6 +180,11 @@ typedef struct _GLFWlibraryNS
|
||||
CFStringRef kPropertyUnicodeKeyLayoutData;
|
||||
} tis;
|
||||
|
||||
struct {
|
||||
_GLFWDisplayLinkNS entries[256];
|
||||
size_t count;
|
||||
} displayLinks;
|
||||
|
||||
} _GLFWlibraryNS;
|
||||
|
||||
// Cocoa-specific per-monitor data
|
||||
@@ -174,3 +220,12 @@ void _glfwInitTimerNS(void);
|
||||
void _glfwPollMonitorsNS(void);
|
||||
void _glfwSetVideoModeNS(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||
void _glfwRestoreVideoModeNS(_GLFWmonitor* monitor);
|
||||
|
||||
float _glfwTransformYNS(float y);
|
||||
|
||||
void _glfwClearDisplayLinks(void);
|
||||
void _glfwRestartDisplayLinks(void);
|
||||
void _glfwDispatchTickCallback(void);
|
||||
void _glfwDispatchRenderFrame(CGDirectDisplayID);
|
||||
void _glfwShutdownCVDisplayLink(unsigned long long, void*);
|
||||
void _glfwCocoaPostEmptyEvent(void);
|
||||
|
||||
4
glfw/cocoa_time.c
vendored
4
glfw/cocoa_time.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
@@ -23,6 +23,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
73
glfw/context.c
vendored
73
glfw/context.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -44,7 +46,7 @@
|
||||
// exists and whether all relevant options have supported and non-conflicting
|
||||
// values
|
||||
//
|
||||
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
bool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
{
|
||||
if (ctxconfig->share)
|
||||
{
|
||||
@@ -52,7 +54,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
ctxconfig->share->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +65,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid context creation API 0x%08X",
|
||||
ctxconfig->source);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API &&
|
||||
@@ -73,7 +75,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid client API 0x%08X",
|
||||
ctxconfig->client);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
@@ -92,7 +94,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Invalid OpenGL version %i.%i",
|
||||
ctxconfig->major, ctxconfig->minor);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->profile)
|
||||
@@ -103,7 +105,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid OpenGL profile 0x%08X",
|
||||
ctxconfig->profile);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->major <= 2 ||
|
||||
@@ -114,7 +116,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Context profiles are only defined for OpenGL version 3.2 and above");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +125,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
// Forward-compatible contexts are only defined for OpenGL version 3.0 and above
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Forward-compatibility is only defined for OpenGL version 3.0 and above");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
@@ -140,7 +142,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"Invalid OpenGL ES version %i.%i",
|
||||
ctxconfig->major, ctxconfig->minor);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +154,7 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid context robustness mode 0x%08X",
|
||||
ctxconfig->robustness);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,11 +166,11 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
|
||||
_glfwInputError(GLFW_INVALID_ENUM,
|
||||
"Invalid context release behavior 0x%08X",
|
||||
ctxconfig->release);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Chooses the framebuffer config that best matches the desired one
|
||||
@@ -341,7 +343,7 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
||||
|
||||
// Retrieves the attributes of the current context
|
||||
//
|
||||
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
bool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig)
|
||||
{
|
||||
int i;
|
||||
@@ -358,7 +360,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
window->context.source = ctxconfig->source;
|
||||
window->context.client = GLFW_OPENGL_API;
|
||||
|
||||
previous = _glfwPlatformGetTls(&_glfw.contextSlot);;
|
||||
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
glfwMakeContextCurrent((GLFWwindow*) window);
|
||||
|
||||
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
|
||||
@@ -369,7 +371,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
version = (const char*) window->context.GetString(GL_VERSION);
|
||||
@@ -387,7 +389,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; prefixes[i]; i++)
|
||||
@@ -419,7 +421,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (window->context.major < ctxconfig->major ||
|
||||
@@ -449,7 +451,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (window->context.major >= 3)
|
||||
@@ -465,7 +467,7 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Entry point retrieval is broken");
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,21 +480,21 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
window->context.GetIntegerv(GL_CONTEXT_FLAGS, &flags);
|
||||
|
||||
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
|
||||
window->context.forward = GLFW_TRUE;
|
||||
window->context.forward = true;
|
||||
|
||||
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
|
||||
window->context.debug = GLFW_TRUE;
|
||||
window->context.debug = true;
|
||||
else if (glfwExtensionSupported("GL_ARB_debug_output") &&
|
||||
ctxconfig->debug)
|
||||
{
|
||||
// HACK: This is a workaround for older drivers (pre KHR_debug)
|
||||
// not setting the debug bit in the context flags for
|
||||
// debug contexts
|
||||
window->context.debug = GLFW_TRUE;
|
||||
window->context.debug = true;
|
||||
}
|
||||
|
||||
if (flags & GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR)
|
||||
window->context.noerror = GLFW_TRUE;
|
||||
window->context.noerror = true;
|
||||
}
|
||||
|
||||
// Read back OpenGL context profile (OpenGL 3.2 and above)
|
||||
@@ -572,12 +574,12 @@ GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent((GLFWwindow*) previous);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Searches an extension string for the specified extension
|
||||
//
|
||||
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions)
|
||||
bool _glfwStringInExtensionString(const char* string, const char* extensions)
|
||||
{
|
||||
const char* start = extensions;
|
||||
|
||||
@@ -588,7 +590,7 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
|
||||
|
||||
where = strstr(start, string);
|
||||
if (!where)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
terminator = where + strlen(string);
|
||||
if (where == start || *(where - 1) == ' ')
|
||||
@@ -600,7 +602,7 @@ GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions
|
||||
start = terminator;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -677,20 +679,20 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
_GLFWwindow* window;
|
||||
assert(extension != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
if (!window)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
|
||||
"Cannot query extension without a current OpenGL or OpenGL ES context");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*extension == '\0')
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Extension name cannot be an empty string");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (window->context.major >= 3)
|
||||
@@ -710,11 +712,11 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Extension string retrieval is broken");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp(en, extension) == 0)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -727,11 +729,11 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Extension string retrieval is broken");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if extension is in the platform-specific string
|
||||
@@ -755,4 +757,3 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
|
||||
|
||||
return window->context.getProcAddress(procname);
|
||||
}
|
||||
|
||||
|
||||
136
glfw/dbus_glfw.c
vendored
136
glfw/dbus_glfw.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 XKB - www.glfw.org
|
||||
// GLFW 3.4 XKB - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
//
|
||||
@@ -43,16 +43,17 @@ report_error(DBusError *err, const char *fmt, ...) {
|
||||
}
|
||||
|
||||
static _GLFWDBUSData *dbus_data = NULL;
|
||||
static DBusConnection *session_bus = NULL;
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld) {
|
||||
dbus->eld = eld;
|
||||
dbus_data = dbus;
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
on_dbus_watch_ready(int fd, int events, void *data) {
|
||||
on_dbus_watch_ready(int fd UNUSED, int events, void *data) {
|
||||
DBusWatch *watch = (DBusWatch*)data;
|
||||
unsigned int flags = 0;
|
||||
if (events & POLLERR) flags |= DBUS_WATCH_ERROR;
|
||||
@@ -83,19 +84,19 @@ add_dbus_watch(DBusWatch *watch, void *data) {
|
||||
}
|
||||
|
||||
static void
|
||||
remove_dbus_watch(DBusWatch *watch, void *data) {
|
||||
remove_dbus_watch(DBusWatch *watch, void *data UNUSED) {
|
||||
id_type *idp = dbus_watch_get_data(watch);
|
||||
if (idp) removeWatch(dbus_data->eld, *idp);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_dbus_watch(DBusWatch *watch, void *data) {
|
||||
toggle_dbus_watch(DBusWatch *watch, void *data UNUSED) {
|
||||
id_type *idp = dbus_watch_get_data(watch);
|
||||
if (idp) toggleWatch(dbus_data->eld, *idp, dbus_watch_get_enabled(watch));
|
||||
}
|
||||
|
||||
static void
|
||||
on_dbus_timer_ready(id_type timer_id, void *data) {
|
||||
on_dbus_timer_ready(id_type timer_id UNUSED, void *data) {
|
||||
if (data) {
|
||||
DBusTimeout *t = (DBusTimeout*)data;
|
||||
dbus_timeout_handle(t);
|
||||
@@ -108,7 +109,7 @@ add_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||
int enabled = dbus_timeout_get_enabled(timeout) ? 1 : 0;
|
||||
double interval = ((double)dbus_timeout_get_interval(timeout)) / 1000.0;
|
||||
if (interval < 0) return FALSE;
|
||||
id_type timer_id = addTimer(dbus_data->eld, data, interval, enabled, on_dbus_timer_ready, timeout);
|
||||
id_type timer_id = addTimer(dbus_data->eld, data, interval, enabled, true, on_dbus_timer_ready, timeout, NULL);
|
||||
if (!timer_id) return FALSE;
|
||||
id_type *idp = malloc(sizeof(id_type));
|
||||
if (!idp) {
|
||||
@@ -122,20 +123,20 @@ add_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||
}
|
||||
|
||||
static void
|
||||
remove_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||
remove_dbus_timeout(DBusTimeout *timeout, void *data UNUSED) {
|
||||
id_type *idp = dbus_timeout_get_data(timeout);
|
||||
if (idp) removeTimer(dbus_data->eld, *idp);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_dbus_timeout(DBusTimeout *timeout, void *data) {
|
||||
toggle_dbus_timeout(DBusTimeout *timeout, void *data UNUSED) {
|
||||
id_type *idp = dbus_timeout_get_data(timeout);
|
||||
if (idp) toggleTimer(dbus_data->eld, *idp, dbus_timeout_get_enabled(timeout));
|
||||
}
|
||||
|
||||
|
||||
DBusConnection*
|
||||
glfw_dbus_connect_to(const char *path, const char* err_msg, const char *name, GLFWbool register_on_bus) {
|
||||
glfw_dbus_connect_to(const char *path, const char* err_msg, const char *name, bool register_on_bus) {
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
DBusConnection *ans = dbus_connection_open_private(path, &err);
|
||||
@@ -172,11 +173,20 @@ glfw_dbus_dispatch(DBusConnection *conn) {
|
||||
}
|
||||
|
||||
void
|
||||
glfw_dbus_terminate(_GLFWDBUSData *dbus) {
|
||||
glfw_dbus_session_bus_dispatch() {
|
||||
if (session_bus) glfw_dbus_dispatch(session_bus);
|
||||
}
|
||||
|
||||
void
|
||||
glfw_dbus_terminate(_GLFWDBUSData *dbus UNUSED) {
|
||||
if (dbus_data) {
|
||||
dbus_data->eld = NULL;
|
||||
dbus_data = NULL;
|
||||
}
|
||||
if (session_bus) {
|
||||
dbus_connection_unref(session_bus);
|
||||
session_bus = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -185,14 +195,14 @@ glfw_dbus_close_connection(DBusConnection *conn) {
|
||||
dbus_connection_unref(conn);
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...) {
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
va_list ap;
|
||||
va_start(ap, failmsg);
|
||||
int firstarg = va_arg(ap, int);
|
||||
GLFWbool ret = dbus_message_get_args_valist(msg, &err, firstarg, ap) ? GLFW_TRUE : GLFW_FALSE;
|
||||
bool ret = dbus_message_get_args_valist(msg, &err, firstarg, ap) ? true : false;
|
||||
va_end(ap);
|
||||
if (!ret) report_error(&err, failmsg);
|
||||
return ret;
|
||||
@@ -223,34 +233,43 @@ method_reply_received(DBusPendingCall *pending, void *user_data) {
|
||||
}
|
||||
}
|
||||
|
||||
static GLFWbool
|
||||
bool
|
||||
call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_pending_callback callback, void *user_data) {
|
||||
bool retval = false;
|
||||
#define REPORT(errs) _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: node=%s path=%s interface=%s method=%s, with error: %s", dbus_message_get_destination(msg), dbus_message_get_path(msg), dbus_message_get_interface(msg), dbus_message_get_member(msg), errs)
|
||||
if (callback) {
|
||||
DBusPendingCall *pending = NULL;
|
||||
if (dbus_connection_send_with_reply(conn, msg, &pending, timeout)) {
|
||||
MethodResponse *res = malloc(sizeof(MethodResponse));
|
||||
if (!res) return false;
|
||||
res->callback = callback;
|
||||
res->user_data = user_data;
|
||||
dbus_pending_call_set_notify(pending, method_reply_received, res, free);
|
||||
retval = true;
|
||||
} else {
|
||||
REPORT("out of memory");
|
||||
}
|
||||
} else {
|
||||
if (dbus_connection_send(conn, msg, NULL)) {
|
||||
retval = true;
|
||||
} else {
|
||||
REPORT("out of memory");
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
#undef REPORT
|
||||
}
|
||||
|
||||
static bool
|
||||
call_method(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout, dbus_pending_callback callback, void *user_data, va_list ap) {
|
||||
if (!conn) return GLFW_FALSE;
|
||||
if (!conn) return false;
|
||||
DBusMessage *msg = dbus_message_new_method_call(node, path, interface, method);
|
||||
if (!msg) return GLFW_FALSE;
|
||||
GLFWbool retval = GLFW_FALSE;
|
||||
MethodResponse *res = malloc(sizeof(MethodResponse));
|
||||
if (!res) { dbus_message_unref(msg); return GLFW_FALSE; }
|
||||
res->callback = callback;
|
||||
res->user_data = user_data;
|
||||
if (!msg) return false;
|
||||
bool retval = false;
|
||||
|
||||
int firstarg = va_arg(ap, int);
|
||||
if ((firstarg == DBUS_TYPE_INVALID) || dbus_message_append_args_valist(msg, firstarg, ap)) {
|
||||
if (callback) {
|
||||
DBusPendingCall *pending = NULL;
|
||||
if (dbus_connection_send_with_reply(conn, msg, &pending, timeout)) {
|
||||
dbus_pending_call_set_notify(pending, method_reply_received, res, free);
|
||||
retval = GLFW_TRUE;
|
||||
} else {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s out of memory", method, node, interface);
|
||||
}
|
||||
} else {
|
||||
if (dbus_connection_send(conn, msg, NULL)) {
|
||||
retval = GLFW_TRUE;
|
||||
} else {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s out of memory", method, node, interface);
|
||||
}
|
||||
}
|
||||
retval = call_method_with_msg(conn, msg, timeout, callback, user_data);
|
||||
} else {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to call DBUS method: %s on node: %s and interface: %s could not add arguments", method, node, interface);
|
||||
}
|
||||
@@ -259,9 +278,9 @@ call_method(DBusConnection *conn, const char *node, const char *path, const char
|
||||
return retval;
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout, dbus_pending_callback callback, void* user_data, ...) {
|
||||
GLFWbool retval;
|
||||
bool retval;
|
||||
va_list ap;
|
||||
va_start(ap, user_data);
|
||||
retval = call_method(conn, node, path, interface, method, timeout, callback, user_data, ap);
|
||||
@@ -269,9 +288,9 @@ glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const c
|
||||
return retval;
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...) {
|
||||
GLFWbool retval;
|
||||
bool retval;
|
||||
va_list ap;
|
||||
va_start(ap, method);
|
||||
retval = call_method(conn, node, path, interface, method, DBUS_TIMEOUT_USE_DEFAULT, NULL, NULL, ap);
|
||||
@@ -293,3 +312,38 @@ glfw_dbus_match_signal(DBusMessage *msg, const char *interface, ...) {
|
||||
va_end(ap);
|
||||
return ans;
|
||||
}
|
||||
|
||||
static void
|
||||
glfw_dbus_connect_to_session_bus(void) {
|
||||
DBusError error;
|
||||
dbus_error_init(&error);
|
||||
if (session_bus) {
|
||||
dbus_connection_unref(session_bus);
|
||||
}
|
||||
session_bus = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
||||
if (dbus_error_is_set(&error)) {
|
||||
report_error(&error, "Failed to connect to DBUS session bus");
|
||||
session_bus = NULL;
|
||||
return;
|
||||
}
|
||||
static const char *name = "session-bus";
|
||||
if (!dbus_connection_set_watch_functions(session_bus, add_dbus_watch, remove_dbus_watch, toggle_dbus_watch, (void*)name, NULL)) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to set DBUS watches on connection to: %s", name);
|
||||
dbus_connection_close(session_bus);
|
||||
dbus_connection_unref(session_bus);
|
||||
return;
|
||||
}
|
||||
if (!dbus_connection_set_timeout_functions(session_bus, add_dbus_timeout, remove_dbus_timeout, toggle_dbus_timeout, (void*)name, NULL)) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to set DBUS timeout functions on connection to: %s", name);
|
||||
dbus_connection_close(session_bus);
|
||||
dbus_connection_unref(session_bus);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DBusConnection *
|
||||
glfw_dbus_session_bus() {
|
||||
if (!session_bus) glfw_dbus_connect_to_session_bus();
|
||||
return session_bus;
|
||||
}
|
||||
|
||||
16
glfw/dbus_glfw.h
vendored
16
glfw/dbus_glfw.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 XKB - www.glfw.org
|
||||
// GLFW 3.4 XKB - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
//
|
||||
@@ -37,14 +37,18 @@ typedef struct {
|
||||
} _GLFWDBUSData;
|
||||
|
||||
|
||||
GLFWbool glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld);
|
||||
bool glfw_dbus_init(_GLFWDBUSData *dbus, EventLoopData *eld);
|
||||
void glfw_dbus_terminate(_GLFWDBUSData *dbus);
|
||||
DBusConnection* glfw_dbus_connect_to(const char *path, const char* err_msg, const char* name, GLFWbool register_on_bus);
|
||||
DBusConnection* glfw_dbus_connect_to(const char *path, const char* err_msg, const char* name, bool register_on_bus);
|
||||
void glfw_dbus_close_connection(DBusConnection *conn);
|
||||
GLFWbool
|
||||
bool
|
||||
call_method_with_msg(DBusConnection *conn, DBusMessage *msg, int timeout, dbus_pending_callback callback, void *user_data);
|
||||
bool
|
||||
glfw_dbus_call_method_no_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, ...);
|
||||
GLFWbool
|
||||
bool
|
||||
glfw_dbus_call_method_with_reply(DBusConnection *conn, const char *node, const char *path, const char *interface, const char *method, int timeout_ms, dbus_pending_callback callback, void *user_data, ...);
|
||||
void glfw_dbus_dispatch(DBusConnection *);
|
||||
GLFWbool glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...);
|
||||
void glfw_dbus_session_bus_dispatch(void);
|
||||
bool glfw_dbus_get_args(DBusMessage *msg, const char *failmsg, ...);
|
||||
int glfw_dbus_match_signal(DBusMessage *msg, const char *interface, ...);
|
||||
DBusConnection* glfw_dbus_session_bus(void);
|
||||
|
||||
122
glfw/egl_context.c
vendored
122
glfw/egl_context.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 EGL - www.glfw.org
|
||||
// GLFW 3.4 EGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -85,7 +87,7 @@ static int getEGLConfigAttrib(EGLConfig config, int attrib)
|
||||
|
||||
// Return the EGLConfig most closely matching the specified hints
|
||||
//
|
||||
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
static bool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* desired,
|
||||
EGLConfig* result)
|
||||
{
|
||||
@@ -98,7 +100,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
if (!nativeCount)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
nativeConfigs = calloc(nativeCount, sizeof(EGLConfig));
|
||||
@@ -170,7 +172,7 @@ static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
|
||||
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
|
||||
|
||||
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
|
||||
u->doublebuffer = GLFW_TRUE;
|
||||
u->doublebuffer = true;
|
||||
|
||||
u->handle = (uintptr_t) n;
|
||||
usableCount++;
|
||||
@@ -241,10 +243,10 @@ static int extensionSupportedEGL(const char* extension)
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddressEGL(const char* procname)
|
||||
@@ -253,8 +255,8 @@ static GLFWglproc getProcAddressEGL(const char* procname)
|
||||
|
||||
if (window->context.egl.client)
|
||||
{
|
||||
GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->context.egl.client,
|
||||
procname);
|
||||
GLFWglproc proc = NULL;
|
||||
glfw_dlsym(proc, window->context.egl.client, procname);
|
||||
if (proc)
|
||||
return proc;
|
||||
}
|
||||
@@ -297,7 +299,7 @@ static void destroyContextEGL(_GLFWwindow* window)
|
||||
|
||||
// Initialize EGL
|
||||
//
|
||||
GLFWbool _glfwInitEGL(void)
|
||||
bool _glfwInitEGL(void)
|
||||
{
|
||||
int i;
|
||||
const char* sonames[] =
|
||||
@@ -318,7 +320,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
};
|
||||
|
||||
if (_glfw.egl.handle)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
for (i = 0; sonames[i]; i++)
|
||||
{
|
||||
@@ -330,43 +332,27 @@ GLFWbool _glfwInitEGL(void)
|
||||
if (!_glfw.egl.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
|
||||
|
||||
_glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigAttrib");
|
||||
_glfw.egl.GetConfigs = (PFN_eglGetConfigs)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetConfigs");
|
||||
_glfw.egl.GetDisplay = (PFN_eglGetDisplay)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetDisplay");
|
||||
_glfw.egl.GetError = (PFN_eglGetError)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetError");
|
||||
_glfw.egl.Initialize = (PFN_eglInitialize)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglInitialize");
|
||||
_glfw.egl.Terminate = (PFN_eglTerminate)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglTerminate");
|
||||
_glfw.egl.BindAPI = (PFN_eglBindAPI)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglBindAPI");
|
||||
_glfw.egl.CreateContext = (PFN_eglCreateContext)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglCreateContext");
|
||||
_glfw.egl.DestroySurface = (PFN_eglDestroySurface)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglDestroySurface");
|
||||
_glfw.egl.DestroyContext = (PFN_eglDestroyContext)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglDestroyContext");
|
||||
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglCreateWindowSurface");
|
||||
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglMakeCurrent");
|
||||
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglSwapBuffers");
|
||||
_glfw.egl.SwapInterval = (PFN_eglSwapInterval)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglSwapInterval");
|
||||
_glfw.egl.QueryString = (PFN_eglQueryString)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglQueryString");
|
||||
_glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
|
||||
_glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress");
|
||||
glfw_dlsym(_glfw.egl.GetConfigAttrib, _glfw.egl.handle, "eglGetConfigAttrib");
|
||||
glfw_dlsym(_glfw.egl.GetConfigs, _glfw.egl.handle, "eglGetConfigs");
|
||||
glfw_dlsym(_glfw.egl.GetDisplay, _glfw.egl.handle, "eglGetDisplay");
|
||||
glfw_dlsym(_glfw.egl.GetError, _glfw.egl.handle, "eglGetError");
|
||||
glfw_dlsym(_glfw.egl.Initialize, _glfw.egl.handle, "eglInitialize");
|
||||
glfw_dlsym(_glfw.egl.Terminate, _glfw.egl.handle, "eglTerminate");
|
||||
glfw_dlsym(_glfw.egl.BindAPI, _glfw.egl.handle, "eglBindAPI");
|
||||
glfw_dlsym(_glfw.egl.CreateContext, _glfw.egl.handle, "eglCreateContext");
|
||||
glfw_dlsym(_glfw.egl.DestroySurface, _glfw.egl.handle, "eglDestroySurface");
|
||||
glfw_dlsym(_glfw.egl.DestroyContext, _glfw.egl.handle, "eglDestroyContext");
|
||||
glfw_dlsym(_glfw.egl.CreateWindowSurface, _glfw.egl.handle, "eglCreateWindowSurface");
|
||||
glfw_dlsym(_glfw.egl.MakeCurrent, _glfw.egl.handle, "eglMakeCurrent");
|
||||
glfw_dlsym(_glfw.egl.SwapBuffers, _glfw.egl.handle, "eglSwapBuffers");
|
||||
glfw_dlsym(_glfw.egl.SwapInterval, _glfw.egl.handle, "eglSwapInterval");
|
||||
glfw_dlsym(_glfw.egl.QueryString, _glfw.egl.handle, "eglQueryString");
|
||||
glfw_dlsym(_glfw.egl.GetProcAddress, _glfw.egl.handle, "eglGetProcAddress");
|
||||
|
||||
if (!_glfw.egl.GetConfigAttrib ||
|
||||
!_glfw.egl.GetConfigs ||
|
||||
@@ -389,7 +375,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
"EGL: Failed to load required entry points");
|
||||
|
||||
_glfwTerminateEGL();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY);
|
||||
@@ -400,7 +386,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
getEGLErrorString(eglGetError()));
|
||||
|
||||
_glfwTerminateEGL();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
|
||||
@@ -410,7 +396,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
getEGLErrorString(eglGetError()));
|
||||
|
||||
_glfwTerminateEGL();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.egl.KHR_create_context =
|
||||
@@ -424,7 +410,7 @@ GLFWbool _glfwInitEGL(void)
|
||||
_glfw.egl.KHR_context_flush_control =
|
||||
extensionSupportedEGL("EGL_KHR_context_flush_control");
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Terminate EGL
|
||||
@@ -446,14 +432,14 @@ void _glfwTerminateEGL(void)
|
||||
|
||||
#define setAttrib(a, v) \
|
||||
{ \
|
||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
attribs[index++] = a; \
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
//
|
||||
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
bool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
@@ -465,7 +451,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
if (!_glfw.egl.display)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->share)
|
||||
@@ -475,7 +461,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"EGL: Failed to find a suitable EGLConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
@@ -485,7 +471,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to bind OpenGL ES: %s",
|
||||
getEGLErrorString(eglGetError()));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -495,7 +481,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to bind OpenGL: %s",
|
||||
getEGLErrorString(eglGetError()));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,7 +522,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
if (ctxconfig->noerror)
|
||||
{
|
||||
if (_glfw.egl.KHR_create_context_no_error)
|
||||
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
|
||||
setAttrib(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, true);
|
||||
}
|
||||
|
||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||
@@ -581,7 +567,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"EGL: Failed to create context: %s",
|
||||
getEGLErrorString(eglGetError()));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up attributes for surface creation
|
||||
@@ -607,11 +593,20 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to create window surface: %s",
|
||||
getEGLErrorString(eglGetError()));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
window->context.egl.config = config;
|
||||
|
||||
EGLint a = EGL_MIN_SWAP_INTERVAL;
|
||||
if (!eglGetConfigAttrib(_glfw.egl.display, config, a, &a)) {
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE, "EGL: could not check for non-blocking buffer swap with error: %s", getEGLErrorString(eglGetError()));
|
||||
} else {
|
||||
if (a > 0) {
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE, "EGL: non-blocking swap buffers not available, minimum swap interval is: %d", a);
|
||||
}
|
||||
}
|
||||
|
||||
// Load the appropriate client library
|
||||
if (!_glfw.egl.KHR_get_all_proc_addresses)
|
||||
{
|
||||
@@ -686,7 +681,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"EGL: Failed to load client library");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -697,7 +692,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
window->context.getProcAddress = getProcAddressEGL;
|
||||
window->context.destroy = destroyContextEGL;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef setAttrib
|
||||
@@ -705,7 +700,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
// Returns the Visual and depth of the chosen EGLConfig
|
||||
//
|
||||
#if defined(_GLFW_X11)
|
||||
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
bool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig UNUSED,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
Visual** visual, int* depth)
|
||||
@@ -720,7 +715,7 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"EGL: Failed to find a suitable EGLConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
eglGetConfigAttrib(_glfw.egl.display, native,
|
||||
@@ -734,14 +729,14 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"EGL: Failed to retrieve Visual for EGLConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
*visual = result->visual;
|
||||
*depth = result->depth;
|
||||
|
||||
XFree(result);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
#endif // _GLFW_X11
|
||||
|
||||
@@ -783,4 +778,3 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
|
||||
|
||||
return window->context.egl.surface;
|
||||
}
|
||||
|
||||
|
||||
40
glfw/egl_context.h
vendored
40
glfw/egl_context.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 EGL - www.glfw.org
|
||||
// GLFW 3.4 EGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -47,26 +47,26 @@ typedef struct wl_egl_window* EGLNativeWindowType;
|
||||
#error "No supported EGL platform selected"
|
||||
#endif
|
||||
|
||||
#define EGL_SUCCESS 0x3000
|
||||
#define EGL_NOT_INITIALIZED 0x3001
|
||||
#define EGL_SUCCESS 0x3000
|
||||
#define EGL_NOT_INITIALIZED 0x3001
|
||||
#define EGL_BAD_ACCESS 0x3002
|
||||
#define EGL_BAD_ALLOC 0x3003
|
||||
#define EGL_BAD_ATTRIBUTE 0x3004
|
||||
#define EGL_BAD_CONFIG 0x3005
|
||||
#define EGL_BAD_CONTEXT 0x3006
|
||||
#define EGL_BAD_CURRENT_SURFACE 0x3007
|
||||
#define EGL_BAD_DISPLAY 0x3008
|
||||
#define EGL_BAD_CONTEXT 0x3006
|
||||
#define EGL_BAD_CURRENT_SURFACE 0x3007
|
||||
#define EGL_BAD_DISPLAY 0x3008
|
||||
#define EGL_BAD_MATCH 0x3009
|
||||
#define EGL_BAD_NATIVE_PIXMAP 0x300a
|
||||
#define EGL_BAD_NATIVE_WINDOW 0x300b
|
||||
#define EGL_BAD_PARAMETER 0x300c
|
||||
#define EGL_BAD_SURFACE 0x300d
|
||||
#define EGL_BAD_SURFACE 0x300d
|
||||
#define EGL_CONTEXT_LOST 0x300e
|
||||
#define EGL_COLOR_BUFFER_TYPE 0x303f
|
||||
#define EGL_RGB_BUFFER 0x308e
|
||||
#define EGL_SURFACE_TYPE 0x3033
|
||||
#define EGL_WINDOW_BIT 0x0004
|
||||
#define EGL_RENDERABLE_TYPE 0x3040
|
||||
#define EGL_RENDERABLE_TYPE 0x3040
|
||||
#define EGL_OPENGL_ES_BIT 0x0001
|
||||
#define EGL_OPENGL_ES2_BIT 0x0004
|
||||
#define EGL_OPENGL_BIT 0x0008
|
||||
@@ -76,7 +76,7 @@ typedef struct wl_egl_window* EGLNativeWindowType;
|
||||
#define EGL_RED_SIZE 0x3024
|
||||
#define EGL_DEPTH_SIZE 0x3025
|
||||
#define EGL_STENCIL_SIZE 0x3026
|
||||
#define EGL_SAMPLES 0x3031
|
||||
#define EGL_SAMPLES 0x3031
|
||||
#define EGL_OPENGL_ES_API 0x30a0
|
||||
#define EGL_OPENGL_API 0x30a2
|
||||
#define EGL_NONE 0x3038
|
||||
@@ -87,6 +87,8 @@ typedef struct wl_egl_window* EGLNativeWindowType;
|
||||
#define EGL_NO_DISPLAY ((EGLDisplay) 0)
|
||||
#define EGL_NO_CONTEXT ((EGLContext) 0)
|
||||
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0)
|
||||
#define EGL_MIN_SWAP_INTERVAL 0x303B
|
||||
#define EGL_MAX_SWAP_INTERVAL 0x303C
|
||||
|
||||
#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
|
||||
#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
|
||||
@@ -171,13 +173,13 @@ typedef struct _GLFWlibraryEGL
|
||||
{
|
||||
EGLDisplay display;
|
||||
EGLint major, minor;
|
||||
GLFWbool prefix;
|
||||
bool prefix;
|
||||
|
||||
GLFWbool KHR_create_context;
|
||||
GLFWbool KHR_create_context_no_error;
|
||||
GLFWbool KHR_gl_colorspace;
|
||||
GLFWbool KHR_get_all_proc_addresses;
|
||||
GLFWbool KHR_context_flush_control;
|
||||
bool KHR_create_context;
|
||||
bool KHR_create_context_no_error;
|
||||
bool KHR_gl_colorspace;
|
||||
bool KHR_get_all_proc_addresses;
|
||||
bool KHR_context_flush_control;
|
||||
|
||||
void* handle;
|
||||
|
||||
@@ -201,13 +203,13 @@ typedef struct _GLFWlibraryEGL
|
||||
} _GLFWlibraryEGL;
|
||||
|
||||
|
||||
GLFWbool _glfwInitEGL(void);
|
||||
bool _glfwInitEGL(void);
|
||||
void _glfwTerminateEGL(void);
|
||||
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
bool _glfwCreateContextEGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
#if defined(_GLFW_X11)
|
||||
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
bool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
Visual** visual, int* depth);
|
||||
|
||||
86
glfw/glfw.py
86
glfw/glfw.py
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
@@ -8,7 +8,6 @@ import re
|
||||
import sys
|
||||
|
||||
_plat = sys.platform.lower()
|
||||
is_macos = 'darwin' in _plat
|
||||
is_freebsd = 'freebsd' in _plat
|
||||
is_netbsd = 'netbsd' in _plat
|
||||
is_dragonflybsd = 'dragonfly' in _plat
|
||||
@@ -23,26 +22,12 @@ def wayland_protocol_file_name(base, ext='c'):
|
||||
|
||||
def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
|
||||
ans = env.copy()
|
||||
ans.cflags = [
|
||||
x for x in ans.cflags
|
||||
if x not in '-Wpedantic -Wextra -pedantic-errors'.split()
|
||||
]
|
||||
if not is_macos:
|
||||
ans.cflags.append('-pthread')
|
||||
ans.ldpaths.append('-pthread')
|
||||
ans.cflags.append('-fpic')
|
||||
ans.cppflags.append('-D_GLFW_' + module.upper())
|
||||
ans.cppflags.append('-D_GLFW_BUILD_DLL')
|
||||
|
||||
if is_macos:
|
||||
ans.cppflags.append('-DGL_SILENCE_DEPRECATION')
|
||||
ans.ldpaths.extend(
|
||||
"-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo".
|
||||
split()
|
||||
)
|
||||
else:
|
||||
ans.ldpaths.extend('-lrt -lm -ldl'.split())
|
||||
sinfo = json.load(open(os.path.join(base, 'source-info.json')))
|
||||
with open(os.path.join(base, 'source-info.json')) as f:
|
||||
sinfo = json.load(f)
|
||||
module_sources = list(sinfo[module]['sources'])
|
||||
if module in ('x11', 'wayland'):
|
||||
remove = 'linux_joystick.c' if is_bsd else 'null_joystick.c'
|
||||
@@ -52,6 +37,9 @@ def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
|
||||
ans.all_headers = [x for x in os.listdir(base) if x.endswith('.h')]
|
||||
|
||||
if module in ('x11', 'wayland'):
|
||||
ans.cflags.append('-pthread')
|
||||
ans.ldpaths.append('-pthread')
|
||||
ans.ldpaths.extend('-lrt -lm -ldl'.split())
|
||||
at_least_version('xkbcommon', 0, 5)
|
||||
|
||||
if module == 'x11':
|
||||
@@ -60,6 +48,7 @@ def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
|
||||
ans.ldpaths.extend(pkg_config(dep, '--libs'))
|
||||
|
||||
elif module == 'cocoa':
|
||||
ans.cppflags.append('-DGL_SILENCE_DEPRECATION')
|
||||
for f in 'Cocoa IOKit CoreFoundation CoreVideo'.split():
|
||||
ans.ldpaths.extend(('-framework', f))
|
||||
|
||||
@@ -88,7 +77,8 @@ def init_env(env, pkg_config, at_least_version, test_compile, module='x11'):
|
||||
return ans
|
||||
|
||||
|
||||
def build_wayland_protocols(env, run_tool, emphasis, newer, dest_dir):
|
||||
def build_wayland_protocols(env, Command, parallel_run, emphasis, newer, dest_dir):
|
||||
items = []
|
||||
for protocol in env.wayland_protocols:
|
||||
src = os.path.join(env.wayland_packagedir, protocol)
|
||||
if not os.path.exists(src):
|
||||
@@ -98,42 +88,12 @@ def build_wayland_protocols(env, run_tool, emphasis, newer, dest_dir):
|
||||
dest = os.path.join(dest_dir, dest)
|
||||
if newer(dest, src):
|
||||
q = 'client-header' if ext == 'h' else env.wayland_scanner_code
|
||||
run_tool([env.wayland_scanner, q, src, dest],
|
||||
desc='Generating {} ...'.format(emphasis(os.path.basename(dest))))
|
||||
|
||||
|
||||
def collect_source_information():
|
||||
raw = open('src/CMakeLists.txt').read()
|
||||
mraw = open('CMakeLists.txt').read()
|
||||
|
||||
def extract_sources(group, start_pos=0):
|
||||
for which in 'HEADERS SOURCES'.split():
|
||||
yield which.lower(), list(filter(
|
||||
lambda x: x[0] not in '"$',
|
||||
re.search(
|
||||
r'{0}_{1}\s+([^)]+?)[)]'.format(group, which),
|
||||
raw[start_pos:]
|
||||
).group(1).strip().split()
|
||||
))
|
||||
|
||||
wayland_protocols = re.search(r'WaylandProtocols\s+(\S+)\s+', mraw).group(1)
|
||||
wayland_protocols = list(map(int, wayland_protocols.split('.')))
|
||||
ans = {
|
||||
'common': dict(extract_sources('common')),
|
||||
'wayland_protocols': wayland_protocols,
|
||||
}
|
||||
for group in 'cocoa win32 x11 wayland osmesa'.split():
|
||||
m = re.search('_GLFW_' + group.upper(), raw)
|
||||
ans[group] = dict(extract_sources('glfw', m.start()))
|
||||
if group in ('x11', 'wayland'):
|
||||
for joystick in ('linux', 'null'):
|
||||
ans[group]['headers'].append('{}_joystick.h'.format(joystick))
|
||||
ans[group]['sources'].append('{}_joystick.c'.format(joystick))
|
||||
if group == 'wayland':
|
||||
ans[group]['protocols'] = p = []
|
||||
for m in re.finditer(r'WAYLAND_PROTOCOLS_PKGDATADIR\}/(.+?)"?$', raw, flags=re.M):
|
||||
p.append(m.group(1))
|
||||
return ans
|
||||
items.append(Command(
|
||||
'Generating {} ...'.format(emphasis(os.path.basename(dest))),
|
||||
[env.wayland_scanner, q, src, dest],
|
||||
lambda: True, None, None, None))
|
||||
if items:
|
||||
parallel_run(items)
|
||||
|
||||
|
||||
class Arg:
|
||||
@@ -168,6 +128,8 @@ class Function:
|
||||
if a == 'void':
|
||||
continue
|
||||
self.args.append(Arg(a))
|
||||
if not self.args:
|
||||
self.args = [Arg('void v')]
|
||||
|
||||
def declaration(self):
|
||||
return 'typedef {restype} (*{name}_func)({args});\n{name}_func {name}_impl;\n#define {name} {name}_impl'.format(
|
||||
@@ -188,7 +150,8 @@ class Function:
|
||||
|
||||
|
||||
def generate_wrappers(glfw_header):
|
||||
src = open(glfw_header).read()
|
||||
with open(glfw_header) as f:
|
||||
src = f.read()
|
||||
functions = []
|
||||
first = None
|
||||
for m in re.finditer(r'^GLFWAPI\s+(.+[)]);\s*$', src, flags=re.MULTILINE):
|
||||
@@ -206,12 +169,16 @@ def generate_wrappers(glfw_header):
|
||||
GLFWcocoatogglefullscreenfun glfwSetCocoaToggleFullscreenIntercept(GLFWwindow *window, GLFWcocoatogglefullscreenfun callback)
|
||||
GLFWapplicationshouldhandlereopenfun glfwSetApplicationShouldHandleReopen(GLFWapplicationshouldhandlereopenfun callback)
|
||||
void glfwGetCocoaKeyEquivalent(int glfw_key, int glfw_mods, void* cocoa_key, void* cocoa_mods)
|
||||
void glfwCocoaRequestRenderFrame(GLFWwindow *w, GLFWcocoarenderframefun callback)
|
||||
void* glfwGetX11Display(void)
|
||||
int32_t glfwGetX11Window(GLFWwindow* window)
|
||||
void glfwSetPrimarySelectionString(GLFWwindow* window, const char* string)
|
||||
const char* glfwGetPrimarySelectionString(GLFWwindow* window, void)
|
||||
int glfwGetXKBScancode(const char* key_name, int case_sensitive)
|
||||
void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long id, GLFWwaylandframecallbackfunc callback)
|
||||
unsigned long long glfwDBusUserNotify(const char *app_name, const char* icon, const char *summary, const char *body, \
|
||||
const char *action_text, int32_t timeout, GLFWDBusnotificationcreatedfun callback, void *data)
|
||||
void glfwDBusSetUserNotificationHandler(GLFWDBusnotificationactivatedfun handler)
|
||||
'''.splitlines():
|
||||
if line:
|
||||
functions.append(Function(line.strip(), check_fail=False))
|
||||
@@ -227,10 +194,13 @@ def generate_wrappers(glfw_header):
|
||||
|
||||
{}
|
||||
|
||||
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int);
|
||||
typedef int (* GLFWcocoatextinputfilterfun)(int,int,unsigned int,unsigned long);
|
||||
typedef int (* GLFWapplicationshouldhandlereopenfun)(int);
|
||||
typedef int (* GLFWcocoatogglefullscreenfun)(GLFWwindow*);
|
||||
typedef void (* GLFWcocoarenderframefun)(GLFWwindow*);
|
||||
typedef void (*GLFWwaylandframecallbackfunc)(unsigned long long id);
|
||||
typedef void (*GLFWDBusnotificationcreatedfun)(unsigned long long, uint32_t, void*);
|
||||
typedef void (*GLFWDBusnotificationactivatedfun)(uint32_t, const char*);
|
||||
{}
|
||||
|
||||
const char* load_glfw(const char* path);
|
||||
@@ -260,7 +230,7 @@ load_glfw(const char* path) {
|
||||
}
|
||||
|
||||
void
|
||||
unload_glfw() {
|
||||
unload_glfw(void) {
|
||||
if (handle) { dlclose(handle); handle = NULL; }
|
||||
}
|
||||
'''.replace('LOAD', '\n\n '.join(f.load() for f in functions))
|
||||
|
||||
542
glfw/glfw3.h
vendored
542
glfw/glfw3.h
vendored
File diff suppressed because it is too large
Load Diff
151
glfw/glx_context.c
vendored
151
glfw/glx_context.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 GLX - www.glfw.org
|
||||
// GLFW 3.4 GLX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -47,7 +49,7 @@ static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
|
||||
|
||||
// Return the GLXFBConfig most closely matching the specified hints
|
||||
//
|
||||
static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
static bool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
GLXFBConfig* result)
|
||||
{
|
||||
GLXFBConfig* nativeConfigs;
|
||||
@@ -55,20 +57,20 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
const _GLFWfbconfig* closest;
|
||||
int i, nativeCount, usableCount;
|
||||
const char* vendor;
|
||||
GLFWbool trustWindowBit = GLFW_TRUE;
|
||||
bool trustWindowBit = true;
|
||||
|
||||
// HACK: This is a (hopefully temporary) workaround for Chromium
|
||||
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
|
||||
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
|
||||
if (vendor && strcmp(vendor, "Chromium") == 0)
|
||||
trustWindowBit = GLFW_FALSE;
|
||||
trustWindowBit = false;
|
||||
|
||||
nativeConfigs =
|
||||
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
|
||||
if (!nativeConfigs || !nativeCount)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
@@ -116,9 +118,9 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
|
||||
|
||||
if (getGLXFBConfigAttrib(n, GLX_STEREO))
|
||||
u->stereo = GLFW_TRUE;
|
||||
u->stereo = true;
|
||||
if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER))
|
||||
u->doublebuffer = GLFW_TRUE;
|
||||
u->doublebuffer = true;
|
||||
|
||||
if (_glfw.glx.ARB_multisample)
|
||||
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
|
||||
@@ -142,7 +144,7 @@ static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
|
||||
|
||||
// Create the OpenGL context using legacy API
|
||||
//
|
||||
static GLXContext createLegacyContextGLX(_GLFWwindow* window,
|
||||
static GLXContext createLegacyContextGLX(_GLFWwindow* window UNUSED,
|
||||
GLXFBConfig fbconfig,
|
||||
GLXContext share)
|
||||
{
|
||||
@@ -210,10 +212,10 @@ static int extensionSupportedGLX(const char* extension)
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddressGLX(const char* procname)
|
||||
@@ -222,12 +224,13 @@ static GLFWglproc getProcAddressGLX(const char* procname)
|
||||
return _glfw.glx.GetProcAddress((const GLubyte*) procname);
|
||||
else if (_glfw.glx.GetProcAddressARB)
|
||||
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
|
||||
else
|
||||
return _glfw_dlsym(_glfw.glx.handle, procname);
|
||||
else {
|
||||
GLFWglproc ans = NULL;
|
||||
glfw_dlsym(ans, _glfw.glx.handle, procname);
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
static void destroyContextGLX(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.glx.window)
|
||||
@@ -250,7 +253,7 @@ static void destroyContextGLX(_GLFWwindow* window)
|
||||
|
||||
// Initialize GLX
|
||||
//
|
||||
GLFWbool _glfwInitGLX(void)
|
||||
bool _glfwInitGLX(void)
|
||||
{
|
||||
int i;
|
||||
const char* sonames[] =
|
||||
@@ -267,7 +270,7 @@ GLFWbool _glfwInitGLX(void)
|
||||
};
|
||||
|
||||
if (_glfw.glx.handle)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
for (i = 0; sonames[i]; i++)
|
||||
{
|
||||
@@ -279,39 +282,24 @@ GLFWbool _glfwInitGLX(void)
|
||||
if (!_glfw.glx.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.glx.GetFBConfigs =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigs");
|
||||
_glfw.glx.GetFBConfigAttrib =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib");
|
||||
_glfw.glx.GetClientString =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetClientString");
|
||||
_glfw.glx.QueryExtension =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtension");
|
||||
_glfw.glx.QueryVersion =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXQueryVersion");
|
||||
_glfw.glx.DestroyContext =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXDestroyContext");
|
||||
_glfw.glx.MakeCurrent =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXMakeCurrent");
|
||||
_glfw.glx.SwapBuffers =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXSwapBuffers");
|
||||
_glfw.glx.QueryExtensionsString =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXQueryExtensionsString");
|
||||
_glfw.glx.CreateNewContext =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXCreateNewContext");
|
||||
_glfw.glx.CreateWindow =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXCreateWindow");
|
||||
_glfw.glx.DestroyWindow =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXDestroyWindow");
|
||||
_glfw.glx.GetProcAddress =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddress");
|
||||
_glfw.glx.GetProcAddressARB =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
|
||||
_glfw.glx.GetVisualFromFBConfig =
|
||||
_glfw_dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
|
||||
glfw_dlsym(_glfw.glx.GetFBConfigs, _glfw.glx.handle, "glXGetFBConfigs");
|
||||
glfw_dlsym(_glfw.glx.GetFBConfigAttrib, _glfw.glx.handle, "glXGetFBConfigAttrib");
|
||||
glfw_dlsym(_glfw.glx.GetClientString, _glfw.glx.handle, "glXGetClientString");
|
||||
glfw_dlsym(_glfw.glx.QueryExtension, _glfw.glx.handle, "glXQueryExtension");
|
||||
glfw_dlsym(_glfw.glx.QueryVersion, _glfw.glx.handle, "glXQueryVersion");
|
||||
glfw_dlsym(_glfw.glx.DestroyContext, _glfw.glx.handle, "glXDestroyContext");
|
||||
glfw_dlsym(_glfw.glx.MakeCurrent, _glfw.glx.handle, "glXMakeCurrent");
|
||||
glfw_dlsym(_glfw.glx.SwapBuffers, _glfw.glx.handle, "glXSwapBuffers");
|
||||
glfw_dlsym(_glfw.glx.QueryExtensionsString, _glfw.glx.handle, "glXQueryExtensionsString");
|
||||
glfw_dlsym(_glfw.glx.CreateNewContext, _glfw.glx.handle, "glXCreateNewContext");
|
||||
glfw_dlsym(_glfw.glx.CreateWindow, _glfw.glx.handle, "glXCreateWindow");
|
||||
glfw_dlsym(_glfw.glx.DestroyWindow, _glfw.glx.handle, "glXDestroyWindow");
|
||||
glfw_dlsym(_glfw.glx.GetProcAddress, _glfw.glx.handle, "glXGetProcAddress");
|
||||
glfw_dlsym(_glfw.glx.GetProcAddressARB, _glfw.glx.handle, "glXGetProcAddressARB");
|
||||
glfw_dlsym(_glfw.glx.GetVisualFromFBConfig, _glfw.glx.handle, "glXGetVisualFromFBConfig");
|
||||
|
||||
if (!_glfw.glx.GetFBConfigs ||
|
||||
!_glfw.glx.GetFBConfigAttrib ||
|
||||
@@ -331,7 +319,7 @@ GLFWbool _glfwInitGLX(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to load required entry points");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!glXQueryExtension(_glfw.x11.display,
|
||||
@@ -339,21 +327,21 @@ GLFWbool _glfwInitGLX(void)
|
||||
&_glfw.glx.eventBase))
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor))
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"GLX: Failed to query GLX version");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_glfw.glx.major == 1 && _glfw.glx.minor < 3)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"GLX: GLX version 1.3 is required");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extensionSupportedGLX("GLX_EXT_swap_control"))
|
||||
@@ -362,7 +350,7 @@ GLFWbool _glfwInitGLX(void)
|
||||
getProcAddressGLX("glXSwapIntervalEXT");
|
||||
|
||||
if (_glfw.glx.SwapIntervalEXT)
|
||||
_glfw.glx.EXT_swap_control = GLFW_TRUE;
|
||||
_glfw.glx.EXT_swap_control = true;
|
||||
}
|
||||
|
||||
if (extensionSupportedGLX("GLX_SGI_swap_control"))
|
||||
@@ -371,7 +359,7 @@ GLFWbool _glfwInitGLX(void)
|
||||
getProcAddressGLX("glXSwapIntervalSGI");
|
||||
|
||||
if (_glfw.glx.SwapIntervalSGI)
|
||||
_glfw.glx.SGI_swap_control = GLFW_TRUE;
|
||||
_glfw.glx.SGI_swap_control = true;
|
||||
}
|
||||
|
||||
if (extensionSupportedGLX("GLX_MESA_swap_control"))
|
||||
@@ -380,17 +368,17 @@ GLFWbool _glfwInitGLX(void)
|
||||
getProcAddressGLX("glXSwapIntervalMESA");
|
||||
|
||||
if (_glfw.glx.SwapIntervalMESA)
|
||||
_glfw.glx.MESA_swap_control = GLFW_TRUE;
|
||||
_glfw.glx.MESA_swap_control = true;
|
||||
}
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_multisample"))
|
||||
_glfw.glx.ARB_multisample = GLFW_TRUE;
|
||||
_glfw.glx.ARB_multisample = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
|
||||
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
|
||||
_glfw.glx.ARB_framebuffer_sRGB = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
|
||||
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
|
||||
_glfw.glx.EXT_framebuffer_sRGB = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_create_context"))
|
||||
{
|
||||
@@ -398,25 +386,25 @@ GLFWbool _glfwInitGLX(void)
|
||||
getProcAddressGLX("glXCreateContextAttribsARB");
|
||||
|
||||
if (_glfw.glx.CreateContextAttribsARB)
|
||||
_glfw.glx.ARB_create_context = GLFW_TRUE;
|
||||
_glfw.glx.ARB_create_context = true;
|
||||
}
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
|
||||
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
|
||||
_glfw.glx.ARB_create_context_robustness = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
|
||||
_glfw.glx.ARB_create_context_profile = GLFW_TRUE;
|
||||
_glfw.glx.ARB_create_context_profile = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
|
||||
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
|
||||
_glfw.glx.EXT_create_context_es2_profile = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
|
||||
_glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
|
||||
_glfw.glx.ARB_create_context_no_error = true;
|
||||
|
||||
if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
|
||||
_glfw.glx.ARB_context_flush_control = GLFW_TRUE;
|
||||
_glfw.glx.ARB_context_flush_control = true;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Terminate GLX
|
||||
@@ -435,14 +423,14 @@ void _glfwTerminateGLX(void)
|
||||
|
||||
#define setAttrib(a, v) \
|
||||
{ \
|
||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
attribs[index++] = a; \
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
//
|
||||
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
bool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
@@ -457,7 +445,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"GLX: Failed to find a suitable GLXFBConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_ES_API)
|
||||
@@ -468,7 +456,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,7 +466,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +477,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,7 +542,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
if (ctxconfig->noerror)
|
||||
{
|
||||
if (_glfw.glx.ARB_create_context_no_error)
|
||||
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
||||
setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, true);
|
||||
}
|
||||
|
||||
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||
@@ -590,7 +578,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
|
||||
ctxconfig->client == GLFW_OPENGL_API &&
|
||||
ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
|
||||
ctxconfig->forward == GLFW_FALSE)
|
||||
ctxconfig->forward == false)
|
||||
{
|
||||
window->context.glx.handle =
|
||||
createLegacyContextGLX(window, native, share);
|
||||
@@ -608,7 +596,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
if (!window->context.glx.handle)
|
||||
{
|
||||
_glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
window->context.glx.window =
|
||||
@@ -616,7 +604,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
if (!window->context.glx.window)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentGLX;
|
||||
@@ -626,15 +614,15 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
window->context.getProcAddress = getProcAddressGLX;
|
||||
window->context.destroy = destroyContextGLX;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef setAttrib
|
||||
|
||||
// Returns the Visual and depth of the chosen GLXFBConfig
|
||||
//
|
||||
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
bool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig UNUSED,
|
||||
const _GLFWctxconfig* ctxconfig UNUSED,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
Visual** visual, int* depth)
|
||||
{
|
||||
@@ -645,7 +633,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"GLX: Failed to find a suitable GLXFBConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
result = glXGetVisualFromFBConfig(_glfw.x11.display, native);
|
||||
@@ -653,14 +641,14 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"GLX: Failed to retrieve Visual for GLXFBConfig");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
*visual = result->visual;
|
||||
*depth = result->depth;
|
||||
|
||||
XFree(result);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -695,4 +683,3 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
|
||||
|
||||
return window->context.glx.window;
|
||||
}
|
||||
|
||||
|
||||
45
glfw/glx_context.h
vendored
45
glfw/glx_context.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 GLX - www.glfw.org
|
||||
// GLFW 3.4 GLX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -29,11 +29,11 @@
|
||||
#define GLX_RGBA_BIT 0x00000001
|
||||
#define GLX_WINDOW_BIT 0x00000001
|
||||
#define GLX_DRAWABLE_TYPE 0x8010
|
||||
#define GLX_RENDER_TYPE 0x8011
|
||||
#define GLX_RENDER_TYPE 0x8011
|
||||
#define GLX_RGBA_TYPE 0x8014
|
||||
#define GLX_DOUBLEBUFFER 5
|
||||
#define GLX_STEREO 6
|
||||
#define GLX_AUX_BUFFERS 7
|
||||
#define GLX_AUX_BUFFERS 7
|
||||
#define GLX_RED_SIZE 8
|
||||
#define GLX_GREEN_SIZE 9
|
||||
#define GLX_BLUE_SIZE 10
|
||||
@@ -42,7 +42,7 @@
|
||||
#define GLX_STENCIL_SIZE 13
|
||||
#define GLX_ACCUM_RED_SIZE 14
|
||||
#define GLX_ACCUM_GREEN_SIZE 15
|
||||
#define GLX_ACCUM_BLUE_SIZE 16
|
||||
#define GLX_ACCUM_BLUE_SIZE 16
|
||||
#define GLX_ACCUM_ALPHA_SIZE 17
|
||||
#define GLX_SAMPLES 0x186a1
|
||||
#define GLX_VISUAL_ID 0x800b
|
||||
@@ -107,8 +107,8 @@ typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLX
|
||||
#define glXCreateWindow _glfw.glx.CreateWindow
|
||||
#define glXDestroyWindow _glfw.glx.DestroyWindow
|
||||
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx;
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx;
|
||||
|
||||
|
||||
// GLX-specific per-context data
|
||||
@@ -153,29 +153,28 @@ typedef struct _GLFWlibraryGLX
|
||||
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
|
||||
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
|
||||
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
||||
GLFWbool SGI_swap_control;
|
||||
GLFWbool EXT_swap_control;
|
||||
GLFWbool MESA_swap_control;
|
||||
GLFWbool ARB_multisample;
|
||||
GLFWbool ARB_framebuffer_sRGB;
|
||||
GLFWbool EXT_framebuffer_sRGB;
|
||||
GLFWbool ARB_create_context;
|
||||
GLFWbool ARB_create_context_profile;
|
||||
GLFWbool ARB_create_context_robustness;
|
||||
GLFWbool EXT_create_context_es2_profile;
|
||||
GLFWbool ARB_create_context_no_error;
|
||||
GLFWbool ARB_context_flush_control;
|
||||
bool SGI_swap_control;
|
||||
bool EXT_swap_control;
|
||||
bool MESA_swap_control;
|
||||
bool ARB_multisample;
|
||||
bool ARB_framebuffer_sRGB;
|
||||
bool EXT_framebuffer_sRGB;
|
||||
bool ARB_create_context;
|
||||
bool ARB_create_context_profile;
|
||||
bool ARB_create_context_robustness;
|
||||
bool EXT_create_context_es2_profile;
|
||||
bool ARB_create_context_no_error;
|
||||
bool ARB_context_flush_control;
|
||||
|
||||
} _GLFWlibraryGLX;
|
||||
|
||||
GLFWbool _glfwInitGLX(void);
|
||||
bool _glfwInitGLX(void);
|
||||
void _glfwTerminateGLX(void);
|
||||
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
bool _glfwCreateContextGLX(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContextGLX(_GLFWwindow* window);
|
||||
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
bool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig,
|
||||
Visual** visual, int* depth);
|
||||
|
||||
|
||||
80
glfw/ibus_glfw.c
vendored
80
glfw/ibus_glfw.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 XKB - www.glfw.org
|
||||
// GLFW 3.4 XKB - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
//
|
||||
@@ -50,14 +50,14 @@ enum Capabilities {
|
||||
};
|
||||
|
||||
|
||||
static inline GLFWbool
|
||||
static inline bool
|
||||
test_env_var(const char *name, const char *val) {
|
||||
const char *q = getenv(name);
|
||||
return (q && strcmp(q, val) == 0) ? GLFW_TRUE : GLFW_FALSE;
|
||||
return (q && strcmp(q, val) == 0) ? true : false;
|
||||
}
|
||||
|
||||
static inline GLFWbool
|
||||
MIN(size_t a, size_t b) {
|
||||
static inline size_t
|
||||
GLFW_MIN(size_t a, size_t b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ send_text(const char *text, int state) {
|
||||
// Connection handling {{{
|
||||
|
||||
static DBusHandlerResult
|
||||
message_handler(DBusConnection *conn, DBusMessage *msg, void *user_data) {
|
||||
message_handler(DBusConnection *conn UNUSED, DBusMessage *msg, void *user_data) {
|
||||
// To monitor signals from IBUS, use
|
||||
// dbus-monitor --address `ibus address` "type='signal',interface='org.freedesktop.IBus.InputContext'"
|
||||
_GLFWIBUSData *ibus = (_GLFWIBUSData*)user_data;
|
||||
@@ -151,7 +151,7 @@ get_ibus_address_file_name(void) {
|
||||
addr = getenv("IBUS_ADDRESS");
|
||||
int offset = 0;
|
||||
if (addr && addr[0]) {
|
||||
memcpy(ans, addr, MIN(strlen(addr), sizeof(ans)));
|
||||
memcpy(ans, addr, GLFW_MIN(strlen(addr), sizeof(ans)));
|
||||
return ans;
|
||||
}
|
||||
|
||||
@@ -193,39 +193,39 @@ get_ibus_address_file_name(void) {
|
||||
}
|
||||
|
||||
|
||||
static inline GLFWbool
|
||||
static inline bool
|
||||
read_ibus_address(_GLFWIBUSData *ibus) {
|
||||
static char buf[1024];
|
||||
struct stat s;
|
||||
FILE *addr_file = fopen(ibus->address_file_name, "r");
|
||||
if (!addr_file) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to open IBUS address file: %s with error: %s", ibus->address_file_name, strerror(errno));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
int stat_result = fstat(fileno(addr_file), &s);
|
||||
GLFWbool found = GLFW_FALSE;
|
||||
bool found = false;
|
||||
while (fgets(buf, sizeof(buf), addr_file)) {
|
||||
if (strncmp(buf, "IBUS_ADDRESS=", sizeof("IBUS_ADDRESS=")-1) == 0) {
|
||||
size_t sz = strlen(buf);
|
||||
if (buf[sz-1] == '\n') buf[sz-1] = 0;
|
||||
if (buf[sz-2] == '\r') buf[sz-2] = 0;
|
||||
found = GLFW_TRUE;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(addr_file); addr_file = NULL;
|
||||
if (stat_result != 0) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to stat IBUS address file: %s with error: %s", ibus->address_file_name, strerror(errno));
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
ibus->address_file_mtime = s.st_mtime;
|
||||
if (found) {
|
||||
free((void*)ibus->address);
|
||||
ibus->address = _glfw_strdup(buf + sizeof("IBUS_ADDRESS=") - 1);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Could not find IBUS_ADDRESS in %s", ibus->address_file_name);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -245,35 +245,35 @@ input_context_created(DBusMessage *msg, const char* errmsg, void *data) {
|
||||
dbus_connection_try_register_object_path(ibus->conn, ibus->input_ctx_path, &ibus_vtable, ibus, NULL);
|
||||
enum Capabilities caps = IBUS_CAP_FOCUS | IBUS_CAP_PREEDIT_TEXT;
|
||||
if (!glfw_dbus_call_method_no_reply(ibus->conn, IBUS_SERVICE, ibus->input_ctx_path, IBUS_INPUT_INTERFACE, "SetCapabilities", DBUS_TYPE_UINT32, &caps, DBUS_TYPE_INVALID)) return;
|
||||
ibus->ok = GLFW_TRUE;
|
||||
glfw_ibus_set_focused(ibus, GLFW_FALSE);
|
||||
ibus->ok = true;
|
||||
glfw_ibus_set_focused(ibus, false);
|
||||
glfw_ibus_set_cursor_geometry(ibus, 0, 0, 0, 0);
|
||||
debug("Connected to IBUS daemon for IME input management\n");
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
setup_connection(_GLFWIBUSData *ibus) {
|
||||
const char *client_name = "GLFW_Application";
|
||||
const char *address_file_name = get_ibus_address_file_name();
|
||||
ibus->ok = GLFW_FALSE;
|
||||
if (!address_file_name) return GLFW_FALSE;
|
||||
ibus->ok = false;
|
||||
if (!address_file_name) return false;
|
||||
free((void*)ibus->address_file_name);
|
||||
ibus->address_file_name = _glfw_strdup(address_file_name);
|
||||
if (!read_ibus_address(ibus)) return GLFW_FALSE;
|
||||
if (!read_ibus_address(ibus)) return false;
|
||||
if (ibus->conn) {
|
||||
glfw_dbus_close_connection(ibus->conn);
|
||||
ibus->conn = NULL;
|
||||
}
|
||||
debug("Connecting to IBUS daemon @ %s for IME input management\n", ibus->address);
|
||||
ibus->conn = glfw_dbus_connect_to(ibus->address, "Failed to connect to the IBUS daemon, with error", "ibus", GLFW_FALSE);
|
||||
if (!ibus->conn) return GLFW_FALSE;
|
||||
ibus->conn = glfw_dbus_connect_to(ibus->address, "Failed to connect to the IBUS daemon, with error", "ibus", false);
|
||||
if (!ibus->conn) return false;
|
||||
free((void*)ibus->input_ctx_path); ibus->input_ctx_path = NULL;
|
||||
if (!glfw_dbus_call_method_with_reply(
|
||||
ibus->conn, IBUS_SERVICE, IBUS_PATH, IBUS_INTERFACE, "CreateInputContext", DBUS_TIMEOUT_USE_DEFAULT, input_context_created, ibus,
|
||||
DBUS_TYPE_STRING, &client_name, DBUS_TYPE_INVALID)) {
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ void
|
||||
glfw_connect_to_ibus(_GLFWIBUSData *ibus) {
|
||||
if (ibus->inited) return;
|
||||
if (!test_env_var("GLFW_IM_MODULE", "ibus")) return;
|
||||
ibus->inited = GLFW_TRUE;
|
||||
ibus->inited = true;
|
||||
setup_connection(ibus);
|
||||
}
|
||||
|
||||
@@ -297,21 +297,21 @@ glfw_ibus_terminate(_GLFWIBUSData *ibus) {
|
||||
F(address_file_name);
|
||||
#undef F
|
||||
|
||||
ibus->ok = GLFW_FALSE;
|
||||
ibus->ok = false;
|
||||
}
|
||||
|
||||
static GLFWbool
|
||||
static bool
|
||||
check_connection(_GLFWIBUSData *ibus) {
|
||||
if (!ibus->inited) return GLFW_FALSE;
|
||||
if (!ibus->inited) return false;
|
||||
if (ibus->conn && dbus_connection_get_is_connected(ibus->conn)) {
|
||||
return ibus->ok;
|
||||
}
|
||||
struct stat s;
|
||||
if (stat(ibus->address_file_name, &s) != 0 || s.st_mtime != ibus->address_file_mtime) {
|
||||
if (!read_ibus_address(ibus)) return GLFW_FALSE;
|
||||
if (!read_ibus_address(ibus)) return false;
|
||||
setup_connection(ibus);
|
||||
}
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ simple_message(_GLFWIBUSData *ibus, const char *method) {
|
||||
}
|
||||
|
||||
void
|
||||
glfw_ibus_set_focused(_GLFWIBUSData *ibus, GLFWbool focused) {
|
||||
glfw_ibus_set_focused(_GLFWIBUSData *ibus, bool focused) {
|
||||
simple_message(ibus, focused ? "FocusIn" : "FocusOut");
|
||||
}
|
||||
|
||||
@@ -394,24 +394,24 @@ void
|
||||
key_event_processed(DBusMessage *msg, const char* errmsg, void *data) {
|
||||
uint32_t handled = 0;
|
||||
KeyEvent *ev = (KeyEvent*)data;
|
||||
GLFWbool is_release = ev->action == GLFW_RELEASE;
|
||||
GLFWbool failed = GLFW_FALSE;
|
||||
bool is_release = ev->action == GLFW_RELEASE;
|
||||
bool failed = false;
|
||||
if (errmsg) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "IBUS: Failed to process key with error: %s", errmsg);
|
||||
failed = GLFW_TRUE;
|
||||
failed = true;
|
||||
} else {
|
||||
glfw_dbus_get_args(msg, "Failed to get IBUS handled key from reply", DBUS_TYPE_BOOLEAN, &handled, DBUS_TYPE_INVALID);
|
||||
debug("IBUS processed scancode: 0x%x release: %d handled: %u\n", ev->keycode, is_release, handled);
|
||||
}
|
||||
glfw_xkb_key_from_ime(ev, handled ? GLFW_TRUE : GLFW_FALSE, failed);
|
||||
glfw_xkb_key_from_ime(ev, handled ? true : false, failed);
|
||||
free(ev);
|
||||
}
|
||||
|
||||
GLFWbool
|
||||
bool
|
||||
ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus) {
|
||||
if (!check_connection(ibus)) return GLFW_FALSE;
|
||||
if (!check_connection(ibus)) return false;
|
||||
KeyEvent *ev = malloc(sizeof(KeyEvent));
|
||||
if (!ev) return GLFW_FALSE;
|
||||
if (!ev) return false;
|
||||
memcpy(ev, ev_, sizeof(KeyEvent));
|
||||
uint32_t state = ibus_key_state(ev->glfw_modifiers, ev->action);
|
||||
if (!glfw_dbus_call_method_with_reply(
|
||||
@@ -420,7 +420,7 @@ ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus) {
|
||||
DBUS_TYPE_UINT32, &ev->ibus_sym, DBUS_TYPE_UINT32, &ev->ibus_keycode, DBUS_TYPE_UINT32,
|
||||
&state, DBUS_TYPE_INVALID)) {
|
||||
free(ev);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
8
glfw/ibus_glfw.h
vendored
8
glfw/ibus_glfw.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 XKB - www.glfw.org
|
||||
// GLFW 3.4 XKB - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2018 Kovid Goyal <kovid@kovidgoyal.net>
|
||||
//
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
typedef struct {
|
||||
GLFWbool ok, inited;
|
||||
bool ok, inited;
|
||||
time_t address_file_mtime;
|
||||
DBusConnection *conn;
|
||||
const char *input_ctx_path, *address_file_name, *address;
|
||||
@@ -49,7 +49,7 @@ typedef struct {
|
||||
|
||||
void glfw_connect_to_ibus(_GLFWIBUSData *ibus);
|
||||
void glfw_ibus_terminate(_GLFWIBUSData *ibus);
|
||||
void glfw_ibus_set_focused(_GLFWIBUSData *ibus, GLFWbool focused);
|
||||
void glfw_ibus_set_focused(_GLFWIBUSData *ibus, bool focused);
|
||||
void glfw_ibus_dispatch(_GLFWIBUSData *ibus);
|
||||
GLFWbool ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus);
|
||||
bool ibus_process_key(const KeyEvent *ev_, _GLFWIBUSData *ibus);
|
||||
void glfw_ibus_set_cursor_geometry(_GLFWIBUSData *ibus, int x, int y, int w, int h);
|
||||
|
||||
73
glfw/init.c
vendored
73
glfw/init.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
#include "mappings.h"
|
||||
@@ -41,7 +43,7 @@
|
||||
|
||||
// Global state shared between compilation units of GLFW
|
||||
//
|
||||
_GLFWlibrary _glfw = { GLFW_FALSE };
|
||||
_GLFWlibrary _glfw = { false };
|
||||
|
||||
// These are outside of _glfw so they can be used before initialization and
|
||||
// after termination
|
||||
@@ -50,12 +52,12 @@ static _GLFWerror _glfwMainThreadError;
|
||||
static GLFWerrorfun _glfwErrorCallback;
|
||||
static _GLFWinitconfig _glfwInitHints =
|
||||
{
|
||||
GLFW_TRUE, // hat buttons
|
||||
GLFW_FALSE, // debug keyboard
|
||||
GLFW_TRUE, // enable joystick
|
||||
true, // hat buttons
|
||||
false, // debug keyboard
|
||||
true, // enable joystick
|
||||
{
|
||||
GLFW_TRUE, // macOS menu bar
|
||||
GLFW_TRUE // macOS bundle chdir
|
||||
true, // macOS menu bar
|
||||
true // macOS bundle chdir
|
||||
}
|
||||
};
|
||||
|
||||
@@ -92,7 +94,7 @@ static void terminate(void)
|
||||
_glfwTerminateVulkan();
|
||||
_glfwPlatformTerminate();
|
||||
|
||||
_glfw.initialized = GLFW_FALSE;
|
||||
_glfw.initialized = false;
|
||||
|
||||
while (_glfw.errorListHead)
|
||||
{
|
||||
@@ -193,6 +195,20 @@ void _glfwInputError(int code, const char* format, ...)
|
||||
_glfwErrorCallback(code, description);
|
||||
}
|
||||
|
||||
void
|
||||
_glfwDebug(const char *format, ...) {
|
||||
if (format)
|
||||
{
|
||||
va_list vl;
|
||||
|
||||
fprintf(stderr, "[%.4f] ", glfwGetTime());
|
||||
va_start(vl, format);
|
||||
vfprintf(stderr, format, vl);
|
||||
va_end(vl);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW public API //////
|
||||
@@ -201,7 +217,7 @@ void _glfwInputError(int code, const char* format, ...)
|
||||
GLFWAPI int glfwInit(void)
|
||||
{
|
||||
if (_glfw.initialized)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
memset(&_glfw, 0, sizeof(_glfw));
|
||||
_glfw.hints.init = _glfwInitHints;
|
||||
@@ -209,7 +225,7 @@ GLFWAPI int glfwInit(void)
|
||||
if (!_glfwPlatformInit())
|
||||
{
|
||||
terminate();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_glfwPlatformCreateMutex(&_glfw.errorLock) ||
|
||||
@@ -217,12 +233,12 @@ GLFWAPI int glfwInit(void)
|
||||
!_glfwPlatformCreateTls(&_glfw.contextSlot))
|
||||
{
|
||||
terminate();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
|
||||
|
||||
_glfw.initialized = GLFW_TRUE;
|
||||
_glfw.initialized = true;
|
||||
_glfw.timer.offset = _glfwPlatformGetTimerValue();
|
||||
|
||||
glfwDefaultWindowHints();
|
||||
@@ -235,12 +251,12 @@ GLFWAPI int glfwInit(void)
|
||||
if (!glfwUpdateGamepadMappings(_glfwDefaultMappings[i]))
|
||||
{
|
||||
terminate();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwTerminate(void)
|
||||
@@ -320,3 +336,30 @@ GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
|
||||
_GLFW_SWAP_POINTERS(_glfwErrorCallback, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
|
||||
GLFWAPI void glfwRunMainLoop(GLFWtickcallback callback, void *data)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT();
|
||||
_glfwPlatformRunMainLoop(callback, data);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwStopMainLoop(void) {
|
||||
_GLFW_REQUIRE_INIT();
|
||||
_glfwPlatformStopMainLoop();
|
||||
}
|
||||
|
||||
GLFWAPI unsigned long long glfwAddTimer(
|
||||
double interval, bool repeats, GLFWuserdatafun callback,
|
||||
void *callback_data, GLFWuserdatafun free_callback)
|
||||
{
|
||||
return _glfwPlatformAddTimer(interval, repeats, callback, callback_data, free_callback);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwUpdateTimer(unsigned long long timer_id, double interval, bool enabled) {
|
||||
_glfwPlatformUpdateTimer(timer_id, interval, enabled);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwRemoveTimer(unsigned long long timer_id) {
|
||||
_glfwPlatformRemoveTimer(timer_id);
|
||||
}
|
||||
|
||||
122
glfw/input.c
vendored
122
glfw/input.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -58,17 +60,17 @@ static _GLFWmapping* findMapping(const char* guid)
|
||||
|
||||
// Checks whether a gamepad mapping element is present in the hardware
|
||||
//
|
||||
static GLFWbool isValidElementForJoystick(const _GLFWmapelement* e,
|
||||
static bool isValidElementForJoystick(const _GLFWmapelement* e,
|
||||
const _GLFWjoystick* js)
|
||||
{
|
||||
if (e->type == _GLFW_JOYSTICK_HATBIT && (e->index >> 4) >= js->hatCount)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
else if (e->type == _GLFW_JOYSTICK_BUTTON && e->index >= js->buttonCount)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
else if (e->type == _GLFW_JOYSTICK_AXIS && e->index >= js->axisCount)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Finds a mapping based on joystick GUID and verifies element indices
|
||||
@@ -110,7 +112,7 @@ static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
|
||||
|
||||
// Parses an SDL_GameControllerDB line and adds it to the mapping list
|
||||
//
|
||||
static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
static bool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
{
|
||||
const char* c = string;
|
||||
size_t i, length;
|
||||
@@ -148,7 +150,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
if (length != 32 || c[length] != ',')
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(mapping->guid, c, length);
|
||||
@@ -158,7 +160,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
if (length >= sizeof(mapping->name) || c[length] != ',')
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(mapping->name, c, length);
|
||||
@@ -168,7 +170,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
{
|
||||
// TODO: Implement output modifiers
|
||||
if (*c == '+' || *c == '-')
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
for (i = 0; i < sizeof(fields) / sizeof(fields[0]); i++)
|
||||
{
|
||||
@@ -229,7 +231,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
{
|
||||
length = strlen(_GLFW_PLATFORM_MAPPING_NAME);
|
||||
if (strncmp(c, _GLFW_PLATFORM_MAPPING_NAME, length) != 0)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -246,7 +248,7 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
}
|
||||
|
||||
_glfwPlatformUpdateGamepadGUID(mapping->guid);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -254,19 +256,19 @@ static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
////// GLFW event API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Notifies shared code of a key event
|
||||
// Notifies shared code of a physical key event
|
||||
//
|
||||
void _glfwInputKeyboard(_GLFWwindow* window, int key, int scancode, int action, int mods, const char* text, int state)
|
||||
{
|
||||
if (key >= 0 && key <= GLFW_KEY_LAST)
|
||||
{
|
||||
GLFWbool repeated = GLFW_FALSE;
|
||||
bool repeated = false;
|
||||
|
||||
if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE)
|
||||
return;
|
||||
|
||||
if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS)
|
||||
repeated = GLFW_TRUE;
|
||||
repeated = true;
|
||||
|
||||
if (action == GLFW_RELEASE && window->stickyKeys)
|
||||
window->keys[key] = _GLFW_STICK;
|
||||
@@ -312,7 +314,7 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
|
||||
}
|
||||
|
||||
// Notifies shared code of a cursor motion event
|
||||
// The position is specified in client-area relative screen coordinates
|
||||
// The position is specified in content area relative screen coordinates
|
||||
//
|
||||
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
|
||||
{
|
||||
@@ -328,7 +330,7 @@ void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
|
||||
|
||||
// Notifies shared code of a cursor enter/leave event
|
||||
//
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, bool entered)
|
||||
{
|
||||
if (window->callbacks.cursorEnter)
|
||||
window->callbacks.cursorEnter((GLFWwindow*) window, entered);
|
||||
@@ -406,16 +408,16 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
return NULL;
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
js->present = GLFW_TRUE;
|
||||
js->present = true;
|
||||
js->name = _glfw_strdup(name);
|
||||
js->axes = calloc(axisCount, sizeof(float));
|
||||
js->buttons = calloc(buttonCount + hatCount * 4, 1);
|
||||
js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1);
|
||||
js->hats = calloc(hatCount, 1);
|
||||
js->axisCount = axisCount;
|
||||
js->buttonCount = buttonCount;
|
||||
js->hatCount = hatCount;
|
||||
|
||||
strcpy(js->guid, guid);
|
||||
strncpy(js->guid, guid, sizeof(js->guid) - 1);
|
||||
js->mapping = findValidMapping(js);
|
||||
|
||||
return js;
|
||||
@@ -487,6 +489,8 @@ const char* _glfwGetKeyName(int key)
|
||||
case GLFW_KEY_SLASH: return "SLASH";
|
||||
case GLFW_KEY_WORLD_1: return "WORLD 1";
|
||||
case GLFW_KEY_WORLD_2: return "WORLD 2";
|
||||
case GLFW_KEY_PLUS: return "PLUS";
|
||||
case GLFW_KEY_UNDERSCORE: return "UNDERSCORE";
|
||||
|
||||
// Function keys
|
||||
case GLFW_KEY_ESCAPE: return "ESCAPE";
|
||||
@@ -545,7 +549,7 @@ const char* _glfwGetKeyName(int key)
|
||||
case GLFW_KEY_KP_8: return "KEYPAD 8";
|
||||
case GLFW_KEY_KP_9: return "KEYPAD 9";
|
||||
case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE";
|
||||
case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTPLY";
|
||||
case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTIPLY";
|
||||
case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT";
|
||||
case GLFW_KEY_KP_ADD: return "KEYPAD ADD";
|
||||
case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL";
|
||||
@@ -564,6 +568,17 @@ const char* _glfwGetKeyName(int key)
|
||||
}
|
||||
}
|
||||
|
||||
// Center the cursor in the content area of the specified window
|
||||
//
|
||||
void _glfwCenterCursorInContentArea(_GLFWwindow* window)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW public API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -622,7 +637,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
}
|
||||
else if (mode == GLFW_STICKY_KEYS)
|
||||
{
|
||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
value = value ? true : false;
|
||||
if (window->stickyKeys == value)
|
||||
return;
|
||||
|
||||
@@ -642,7 +657,7 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
}
|
||||
else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
|
||||
{
|
||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
value = value ? true : false;
|
||||
if (window->stickyMouseButtons == value)
|
||||
return;
|
||||
|
||||
@@ -661,7 +676,9 @@ GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
|
||||
window->stickyMouseButtons = value;
|
||||
}
|
||||
else if (mode == GLFW_LOCK_KEY_MODS)
|
||||
window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
{
|
||||
window->lockKeyMods = value ? true : false;
|
||||
}
|
||||
else
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
|
||||
}
|
||||
@@ -821,20 +838,15 @@ GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot,
|
||||
return (GLFWcursor*) cursor;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
|
||||
GLFWAPI GLFWcursor* glfwCreateStandardCursor(GLFWCursorShape shape)
|
||||
{
|
||||
_GLFWcursor* cursor;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (shape != GLFW_ARROW_CURSOR &&
|
||||
shape != GLFW_IBEAM_CURSOR &&
|
||||
shape != GLFW_CROSSHAIR_CURSOR &&
|
||||
shape != GLFW_HAND_CURSOR &&
|
||||
shape != GLFW_HRESIZE_CURSOR &&
|
||||
shape != GLFW_VRESIZE_CURSOR)
|
||||
if (shape >= GLFW_INVALID_CURSOR)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor: %d", shape);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -914,7 +926,7 @@ GLFWAPI void glfwUpdateIMEState(GLFWwindow* handle, int which, int a, int b, int
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
|
||||
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) || defined(_GLFW_COCOA)
|
||||
_glfwPlatformUpdateIMEState(window, which, a, b, c, d);
|
||||
#else
|
||||
(void)window; (void)which; (void)a; (void)b; (void)c; (void)d;
|
||||
@@ -982,17 +994,17 @@ GLFWAPI int glfwJoystickPresent(int jid)
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
|
||||
}
|
||||
@@ -1184,7 +1196,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
|
||||
|
||||
assert(string != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
while (*c)
|
||||
{
|
||||
@@ -1234,7 +1246,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string)
|
||||
js->mapping = findValidMapping(js);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwJoystickIsGamepad(int jid)
|
||||
@@ -1244,20 +1256,20 @@ GLFWAPI int glfwJoystickIsGamepad(int jid)
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
return js->mapping != NULL;
|
||||
}
|
||||
@@ -1301,23 +1313,23 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
||||
|
||||
memset(state, 0, sizeof(GLFWgamepadstate));
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->present)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (!js->mapping)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
|
||||
{
|
||||
@@ -1353,15 +1365,17 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
||||
const unsigned int bit = e->index & 0xf;
|
||||
if (js->hats[hat] & bit)
|
||||
state->axes[i] = 1.f;
|
||||
else
|
||||
state->axes[i] = -1.f;
|
||||
}
|
||||
else if (e->type == _GLFW_JOYSTICK_BUTTON)
|
||||
state->axes[i] = (float) js->buttons[e->index];
|
||||
state->axes[i] = js->buttons[e->index] * 2.f - 1.f;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
||||
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle UNUSED, const char* string)
|
||||
{
|
||||
assert(string != NULL);
|
||||
|
||||
@@ -1369,14 +1383,14 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
||||
_glfwPlatformSetClipboardString(string);
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
|
||||
GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle UNUSED)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return _glfwPlatformGetClipboardString();
|
||||
}
|
||||
|
||||
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
|
||||
GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle, const char* string)
|
||||
GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle UNUSED, const char* string)
|
||||
{
|
||||
assert(string != NULL);
|
||||
|
||||
@@ -1384,7 +1398,7 @@ GLFWAPI void glfwSetPrimarySelectionString(GLFWwindow* handle, const char* strin
|
||||
_glfwPlatformSetPrimarySelectionString(string);
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetPrimarySelectionString(GLFWwindow* handle)
|
||||
GLFWAPI const char* glfwGetPrimarySelectionString(GLFWwindow* handle UNUSED)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return _glfwPlatformGetPrimarySelectionString();
|
||||
|
||||
191
glfw/internal.h
vendored
191
glfw/internal.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -60,7 +60,6 @@
|
||||
|
||||
#define _GLFW_MESSAGE_SIZE 1024
|
||||
|
||||
typedef int GLFWbool;
|
||||
typedef unsigned long long GLFWid;
|
||||
|
||||
typedef struct _GLFWerror _GLFWerror;
|
||||
@@ -87,8 +86,8 @@ typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*);
|
||||
typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);
|
||||
|
||||
#define GL_VERSION 0x1f02
|
||||
#define GL_NONE 0
|
||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||
#define GL_NONE 0
|
||||
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
#define GL_EXTENSIONS 0x1f03
|
||||
#define GL_NUM_EXTENSIONS 0x821d
|
||||
@@ -105,7 +104,7 @@ typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*);
|
||||
#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82fc
|
||||
#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
|
||||
|
||||
typedef int GLint;
|
||||
typedef int GLint;
|
||||
typedef unsigned int GLuint;
|
||||
typedef unsigned int GLenum;
|
||||
typedef unsigned int GLbitfield;
|
||||
@@ -196,6 +195,13 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
||||
#error "No supported window creation API selected"
|
||||
#endif
|
||||
|
||||
#define remove_i_from_array(array, i, count) { \
|
||||
(count)--; \
|
||||
if ((i) < (count)) { \
|
||||
memmove((array) + (i), (array) + (i) + 1, sizeof((array)[0]) * ((count) - (i))); \
|
||||
}}
|
||||
|
||||
|
||||
// Constructs a version number string from the public header macros
|
||||
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
|
||||
#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)
|
||||
@@ -219,12 +225,32 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void);
|
||||
|
||||
// Swaps the provided pointers
|
||||
#define _GLFW_SWAP_POINTERS(x, y) \
|
||||
{ \
|
||||
void* t; \
|
||||
do{ \
|
||||
__typeof__(x) t; \
|
||||
t = x; \
|
||||
x = y; \
|
||||
y = t; \
|
||||
}
|
||||
}while(0)
|
||||
|
||||
|
||||
// Suppress some pedantic warnings
|
||||
#ifdef __clang__
|
||||
#define START_ALLOW_CASE_RANGE _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wpedantic\"")
|
||||
#define END_ALLOW_CASE_RANGE _Pragma("clang diagnostic pop")
|
||||
#define ALLOW_UNUSED_RESULT _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wunused-result\"")
|
||||
#define END_ALLOW_UNUSED_RESULT _Pragma("clang diagnostic pop")
|
||||
#else
|
||||
#define START_ALLOW_CASE_RANGE _Pragma("GCC diagnostic ignored \"-Wpedantic\"")
|
||||
#define END_ALLOW_CASE_RANGE _Pragma("GCC diagnostic pop")
|
||||
#define ALLOW_UNUSED_RESULT _Pragma("GCC diagnostic ignored \"-Wunused-result\"")
|
||||
#define END_ALLOW_UNUSED_RESULT _Pragma("GCC diagnostic pop")
|
||||
#endif
|
||||
|
||||
// dlsym that works with -Wpedantic
|
||||
#define glfw_dlsym(dest, handle, name) do {*(void **)&(dest) = _glfw_dlsym(handle, name);}while (0)
|
||||
|
||||
// Mark function arguments as unused
|
||||
#define UNUSED __attribute__ ((unused))
|
||||
|
||||
// Per-thread error structure
|
||||
//
|
||||
@@ -241,12 +267,12 @@ struct _GLFWerror
|
||||
//
|
||||
struct _GLFWinitconfig
|
||||
{
|
||||
GLFWbool hatButtons;
|
||||
GLFWbool debugKeyboard;
|
||||
GLFWbool enableJoysticks;
|
||||
bool hatButtons;
|
||||
bool debugKeyboard;
|
||||
bool enableJoysticks;
|
||||
struct {
|
||||
GLFWbool menubar;
|
||||
GLFWbool chdir;
|
||||
bool menubar;
|
||||
bool chdir;
|
||||
} ns;
|
||||
};
|
||||
|
||||
@@ -261,18 +287,18 @@ struct _GLFWwndconfig
|
||||
int width;
|
||||
int height;
|
||||
const char* title;
|
||||
GLFWbool resizable;
|
||||
GLFWbool visible;
|
||||
GLFWbool decorated;
|
||||
GLFWbool focused;
|
||||
GLFWbool autoIconify;
|
||||
GLFWbool floating;
|
||||
GLFWbool maximized;
|
||||
GLFWbool centerCursor;
|
||||
GLFWbool focusOnShow;
|
||||
GLFWbool scaleToMonitor;
|
||||
bool resizable;
|
||||
bool visible;
|
||||
bool decorated;
|
||||
bool focused;
|
||||
bool autoIconify;
|
||||
bool floating;
|
||||
bool maximized;
|
||||
bool centerCursor;
|
||||
bool focusOnShow;
|
||||
bool scaleToMonitor;
|
||||
struct {
|
||||
GLFWbool retina;
|
||||
bool retina;
|
||||
char frameName[256];
|
||||
} ns;
|
||||
struct {
|
||||
@@ -296,15 +322,15 @@ struct _GLFWctxconfig
|
||||
int source;
|
||||
int major;
|
||||
int minor;
|
||||
GLFWbool forward;
|
||||
GLFWbool debug;
|
||||
GLFWbool noerror;
|
||||
bool forward;
|
||||
bool debug;
|
||||
bool noerror;
|
||||
int profile;
|
||||
int robustness;
|
||||
int release;
|
||||
_GLFWwindow* share;
|
||||
struct {
|
||||
GLFWbool offline;
|
||||
bool offline;
|
||||
} nsgl;
|
||||
};
|
||||
|
||||
@@ -329,11 +355,11 @@ struct _GLFWfbconfig
|
||||
int accumBlueBits;
|
||||
int accumAlphaBits;
|
||||
int auxBuffers;
|
||||
GLFWbool stereo;
|
||||
bool stereo;
|
||||
int samples;
|
||||
GLFWbool sRGB;
|
||||
GLFWbool doublebuffer;
|
||||
GLFWbool transparent;
|
||||
bool sRGB;
|
||||
bool doublebuffer;
|
||||
bool transparent;
|
||||
uintptr_t handle;
|
||||
};
|
||||
|
||||
@@ -344,7 +370,7 @@ struct _GLFWcontext
|
||||
int client;
|
||||
int source;
|
||||
int major, minor, revision;
|
||||
GLFWbool forward, debug, noerror;
|
||||
bool forward, debug, noerror;
|
||||
int profile;
|
||||
int robustness;
|
||||
int release;
|
||||
@@ -361,7 +387,7 @@ struct _GLFWcontext
|
||||
_GLFWdestroycontextfun destroy;
|
||||
|
||||
// This is defined in the context API's context.h
|
||||
_GLFW_PLATFORM_CONTEXT_STATE;
|
||||
_GLFW_PLATFORM_CONTEXT_STATE
|
||||
// This is defined in egl_context.h
|
||||
_GLFW_EGL_CONTEXT_STATE;
|
||||
// This is defined in osmesa_context.h
|
||||
@@ -375,12 +401,12 @@ struct _GLFWwindow
|
||||
struct _GLFWwindow* next;
|
||||
|
||||
// Window settings and state
|
||||
GLFWbool resizable;
|
||||
GLFWbool decorated;
|
||||
GLFWbool autoIconify;
|
||||
GLFWbool floating;
|
||||
GLFWbool focusOnShow;
|
||||
GLFWbool shouldClose;
|
||||
bool resizable;
|
||||
bool decorated;
|
||||
bool autoIconify;
|
||||
bool floating;
|
||||
bool focusOnShow;
|
||||
bool shouldClose;
|
||||
void* userPointer;
|
||||
GLFWid id;
|
||||
GLFWvidmode videoMode;
|
||||
@@ -391,9 +417,9 @@ struct _GLFWwindow
|
||||
int maxwidth, maxheight;
|
||||
int numer, denom;
|
||||
|
||||
GLFWbool stickyKeys;
|
||||
GLFWbool stickyMouseButtons;
|
||||
GLFWbool lockKeyMods;
|
||||
bool stickyKeys;
|
||||
bool stickyMouseButtons;
|
||||
bool lockKeyMods;
|
||||
int cursorMode;
|
||||
char mouseButtons[GLFW_MOUSE_BUTTON_LAST + 1];
|
||||
char keys[GLFW_KEY_LAST + 1];
|
||||
@@ -408,6 +434,7 @@ struct _GLFWwindow
|
||||
GLFWwindowclosefun close;
|
||||
GLFWwindowrefreshfun refresh;
|
||||
GLFWwindowfocusfun focus;
|
||||
GLFWwindowocclusionfun occlusion;
|
||||
GLFWwindowiconifyfun iconify;
|
||||
GLFWwindowmaximizefun maximize;
|
||||
GLFWframebuffersizefun fbsize;
|
||||
@@ -418,6 +445,7 @@ struct _GLFWwindow
|
||||
GLFWscrollfun scroll;
|
||||
GLFWkeyboardfun keyboard;
|
||||
GLFWdropfun drop;
|
||||
GLFWliveresizefun liveResize;
|
||||
} callbacks;
|
||||
|
||||
// This is defined in the window API's platform.h
|
||||
@@ -482,7 +510,7 @@ struct _GLFWmapping
|
||||
//
|
||||
struct _GLFWjoystick
|
||||
{
|
||||
GLFWbool present;
|
||||
bool present;
|
||||
float* axes;
|
||||
int axisCount;
|
||||
unsigned char* buttons;
|
||||
@@ -518,7 +546,7 @@ struct _GLFWmutex
|
||||
//
|
||||
struct _GLFWlibrary
|
||||
{
|
||||
GLFWbool initialized;
|
||||
bool initialized;
|
||||
|
||||
struct {
|
||||
_GLFWinitconfig init;
|
||||
@@ -551,23 +579,23 @@ struct _GLFWlibrary
|
||||
} timer;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
char* extensions[2];
|
||||
#if !defined(_GLFW_VULKAN_STATIC)
|
||||
PFN_vkEnumerateInstanceExtensionProperties EnumerateInstanceExtensionProperties;
|
||||
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
|
||||
#endif
|
||||
GLFWbool KHR_surface;
|
||||
bool KHR_surface;
|
||||
#if defined(_GLFW_WIN32)
|
||||
GLFWbool KHR_win32_surface;
|
||||
bool KHR_win32_surface;
|
||||
#elif defined(_GLFW_COCOA)
|
||||
GLFWbool MVK_macos_surface;
|
||||
bool MVK_macos_surface;
|
||||
#elif defined(_GLFW_X11)
|
||||
GLFWbool KHR_xlib_surface;
|
||||
GLFWbool KHR_xcb_surface;
|
||||
bool KHR_xlib_surface;
|
||||
bool KHR_xcb_surface;
|
||||
#elif defined(_GLFW_WAYLAND)
|
||||
GLFWbool KHR_wayland_surface;
|
||||
bool KHR_wayland_surface;
|
||||
#endif
|
||||
} vk;
|
||||
|
||||
@@ -579,9 +607,9 @@ struct _GLFWlibrary
|
||||
// This is defined in the window API's platform.h
|
||||
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
|
||||
// This is defined in the context API's context.h
|
||||
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE;
|
||||
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE
|
||||
// This is defined in the platform's joystick.h
|
||||
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
|
||||
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE
|
||||
// This is defined in egl_context.h
|
||||
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
|
||||
// This is defined in osmesa_context.h
|
||||
@@ -606,7 +634,7 @@ void _glfwPlatformSetCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||
void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode);
|
||||
int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||
const GLFWimage* image, int xhot, int yhot, int count);
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape);
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, GLFWCursorShape shape);
|
||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor);
|
||||
void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor);
|
||||
|
||||
@@ -617,9 +645,10 @@ void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor);
|
||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos);
|
||||
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
float* xscale, float* yscale);
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int *width, int *height);
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count);
|
||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode);
|
||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
|
||||
|
||||
void _glfwPlatformSetClipboardString(const char* string);
|
||||
@@ -652,6 +681,7 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window,
|
||||
int maxwidth, int maxheight);
|
||||
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom);
|
||||
void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height);
|
||||
void _glfwInputLiveResize(_GLFWwindow* window, bool started);
|
||||
void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window,
|
||||
int* left, int* top,
|
||||
int* right, int* bottom);
|
||||
@@ -669,16 +699,18 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window);
|
||||
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor,
|
||||
int xpos, int ypos, int width, int height,
|
||||
int refreshRate);
|
||||
bool _glfwPlatformToggleFullscreen(_GLFWwindow *w, unsigned int flags);
|
||||
int _glfwPlatformWindowFocused(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowOccluded(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowIconified(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowVisible(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window);
|
||||
int _glfwPlatformWindowHovered(_GLFWwindow* window);
|
||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window);
|
||||
float _glfwPlatformGetWindowOpacity(_GLFWwindow* window);
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled);
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, bool enabled);
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled);
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled);
|
||||
void _glfwPlatformSetWindowOpacity(_GLFWwindow* window, float opacity);
|
||||
void _glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int d);
|
||||
|
||||
@@ -696,12 +728,12 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||
const VkAllocationCallbacks* allocator,
|
||||
VkSurfaceKHR* surface);
|
||||
|
||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls);
|
||||
bool _glfwPlatformCreateTls(_GLFWtls* tls);
|
||||
void _glfwPlatformDestroyTls(_GLFWtls* tls);
|
||||
void* _glfwPlatformGetTls(_GLFWtls* tls);
|
||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value);
|
||||
|
||||
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex);
|
||||
bool _glfwPlatformCreateMutex(_GLFWmutex* mutex);
|
||||
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex);
|
||||
void _glfwPlatformLockMutex(_GLFWmutex* mutex);
|
||||
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
|
||||
@@ -711,14 +743,15 @@ void _glfwPlatformUnlockMutex(_GLFWmutex* mutex);
|
||||
////// GLFW event API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused);
|
||||
void _glfwInputWindowFocus(_GLFWwindow* window, bool focused);
|
||||
void _glfwInputWindowOcclusion(_GLFWwindow* window, bool occluded);
|
||||
void _glfwInputWindowPos(_GLFWwindow* window, int xpos, int ypos);
|
||||
void _glfwInputWindowSize(_GLFWwindow* window, int width, int height);
|
||||
void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height);
|
||||
void _glfwInputWindowContentScale(_GLFWwindow* window,
|
||||
float xscale, float yscale);
|
||||
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified);
|
||||
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized);
|
||||
void _glfwInputWindowIconify(_GLFWwindow* window, bool iconified);
|
||||
void _glfwInputWindowMaximize(_GLFWwindow* window, bool maximized);
|
||||
void _glfwInputWindowDamage(_GLFWwindow* window);
|
||||
void _glfwInputWindowCloseRequest(_GLFWwindow* window);
|
||||
void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor);
|
||||
@@ -727,7 +760,7 @@ void _glfwInputKeyboard(_GLFWwindow* window, int key, int scancode, int action,
|
||||
void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset, int flags);
|
||||
void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods);
|
||||
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered);
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, bool entered);
|
||||
void _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
|
||||
void _glfwInputJoystick(_GLFWjoystick* js, int event);
|
||||
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value);
|
||||
@@ -737,25 +770,33 @@ void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value);
|
||||
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
|
||||
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
void _glfwInputError(int code, const char* format, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
void _glfwDebug(const char* format, ...)
|
||||
__attribute__((format(printf, 1, 2)));
|
||||
#else
|
||||
void _glfwInputError(int code, const char* format, ...);
|
||||
void _glfwDebug(const char* format, ...);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_EVENT_LOOP
|
||||
#define EVDBG(...) _glfwDebug(__VA_ARGS__)
|
||||
#else
|
||||
#define EVDBG(...)
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions);
|
||||
bool _glfwStringInExtensionString(const char* string, const char* extensions);
|
||||
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
|
||||
const _GLFWfbconfig* alternatives,
|
||||
unsigned int count);
|
||||
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
bool _glfwRefreshContextAttribs(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig);
|
||||
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
|
||||
bool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig);
|
||||
|
||||
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
|
||||
const GLFWvidmode* desired);
|
||||
@@ -773,11 +814,17 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
int hatCount);
|
||||
void _glfwFreeJoystick(_GLFWjoystick* js);
|
||||
const char* _glfwGetKeyName(int key);
|
||||
void _glfwCenterCursorInContentArea(_GLFWwindow* window);
|
||||
|
||||
GLFWbool _glfwInitVulkan(int mode);
|
||||
bool _glfwInitVulkan(int mode);
|
||||
void _glfwTerminateVulkan(void);
|
||||
const char* _glfwGetVulkanResultString(VkResult result);
|
||||
_GLFWwindow* _glfwFocusedWindow();
|
||||
_GLFWwindow* _glfwFocusedWindow(void);
|
||||
_GLFWwindow* _glfwWindowForId(GLFWid id);
|
||||
void _glfwPlatformRunMainLoop(GLFWtickcallback, void*);
|
||||
void _glfwPlatformStopMainLoop(void);
|
||||
unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuserdatafun callback, void *callback_data, GLFWuserdatafun free_callback);
|
||||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, bool enabled);
|
||||
void _glfwPlatformRemoveTimer(unsigned long long timer_id);
|
||||
|
||||
char* _glfw_strdup(const char* source);
|
||||
|
||||
95
glfw/linux_joystick.c
vendored
95
glfw/linux_joystick.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Linux - www.glfw.org
|
||||
// GLFW 3.4 Linux - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -104,9 +106,7 @@ static void handleAbsEvent(_GLFWjoystick* js, int code, int value)
|
||||
//
|
||||
static void pollAbsState(_GLFWjoystick* js)
|
||||
{
|
||||
int code;
|
||||
|
||||
for (code = 0; code < ABS_CNT; code++)
|
||||
for (int code = 0; code < ABS_CNT; code++)
|
||||
{
|
||||
if (js->linjs.absMap[code] < 0)
|
||||
continue;
|
||||
@@ -124,53 +124,52 @@ static void pollAbsState(_GLFWjoystick* js)
|
||||
|
||||
// Attempt to open the specified joystick device
|
||||
//
|
||||
static GLFWbool openJoystickDevice(const char* path)
|
||||
static bool openJoystickDevice(const char* path)
|
||||
{
|
||||
int jid, code;
|
||||
char name[256] = "";
|
||||
char guid[33] = "";
|
||||
char evBits[(EV_CNT + 7) / 8] = {0};
|
||||
char keyBits[(KEY_CNT + 7) / 8] = {0};
|
||||
char absBits[(ABS_CNT + 7) / 8] = {0};
|
||||
int axisCount = 0, buttonCount = 0, hatCount = 0;
|
||||
struct input_id id;
|
||||
_GLFWjoystickLinux linjs = {0};
|
||||
_GLFWjoystick* js = NULL;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (!_glfw.joysticks[jid].present)
|
||||
continue;
|
||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_GLFWjoystickLinux linjs = {0};
|
||||
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||
if (linjs.fd == -1)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
|
||||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
|
||||
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
|
||||
ioctl(linjs.fd, EVIOCGID, &id) < 0)
|
||||
char evBits[(EV_CNT + 7) / 8] = {0};
|
||||
char keyBits[(KEY_CNT + 7) / 8] = {0};
|
||||
char absBits[(ABS_CNT + 7) / 8] = {0};
|
||||
struct input_id id;
|
||||
|
||||
if (ioctl(linjs.fd, (int32_t)EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
|
||||
ioctl(linjs.fd, (int32_t)EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
|
||||
ioctl(linjs.fd, (int32_t)EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
|
||||
ioctl(linjs.fd, (int32_t)EVIOCGID, &id) < 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Linux: Failed to query input device: %s",
|
||||
strerror(errno));
|
||||
close(linjs.fd);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure this device supports the events expected of a joystick
|
||||
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
|
||||
{
|
||||
close(linjs.fd);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
|
||||
char name[256] = "";
|
||||
|
||||
if (ioctl(linjs.fd, (int32_t)EVIOCGNAME(sizeof(name)), name) < 0)
|
||||
strncpy(name, "Unknown", sizeof(name));
|
||||
|
||||
char guid[33] = "";
|
||||
|
||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||
if (id.vendor && id.product && id.version)
|
||||
{
|
||||
@@ -189,7 +188,9 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
name[8], name[9], name[10]);
|
||||
}
|
||||
|
||||
for (code = BTN_MISC; code < KEY_CNT; code++)
|
||||
int axisCount = 0, buttonCount = 0, hatCount = 0;
|
||||
|
||||
for (int code = BTN_MISC; code < KEY_CNT; code++)
|
||||
{
|
||||
if (!isBitSet(code, keyBits))
|
||||
continue;
|
||||
@@ -198,7 +199,7 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
buttonCount++;
|
||||
}
|
||||
|
||||
for (code = 0; code < ABS_CNT; code++)
|
||||
for (int code = 0; code < ABS_CNT; code++)
|
||||
{
|
||||
linjs.absMap[code] = -1;
|
||||
if (!isBitSet(code, absBits))
|
||||
@@ -221,11 +222,11 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
}
|
||||
}
|
||||
|
||||
js = _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
|
||||
_GLFWjoystick* js = _glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
|
||||
if (!js)
|
||||
{
|
||||
close(linjs.fd);
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
strncpy(linjs.path, path, sizeof(linjs.path) - 1);
|
||||
@@ -234,7 +235,7 @@ static GLFWbool openJoystickDevice(const char* path)
|
||||
pollAbsState(js);
|
||||
|
||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef isBitSet
|
||||
@@ -264,10 +265,8 @@ static int compareJoysticks(const void* fp, const void* sp)
|
||||
|
||||
// Initialize joystick interface
|
||||
//
|
||||
GLFWbool _glfwInitJoysticksLinux(void)
|
||||
bool _glfwInitJoysticksLinux(void)
|
||||
{
|
||||
DIR* dir;
|
||||
int count = 0;
|
||||
const char* dirname = "/dev/input";
|
||||
|
||||
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||
@@ -286,10 +285,12 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
||||
if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
dir = opendir(dirname);
|
||||
int count = 0;
|
||||
|
||||
DIR* dir = opendir(dirname);
|
||||
if (dir)
|
||||
{
|
||||
struct dirent* entry;
|
||||
@@ -314,8 +315,8 @@ GLFWbool _glfwInitJoysticksLinux(void)
|
||||
|
||||
// Continue with no joysticks if enumeration fails
|
||||
|
||||
qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
|
||||
return GLFW_TRUE;
|
||||
qsort(_glfw.joysticks, count, sizeof(_glfw.joysticks[0]), compareJoysticks);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Close all opened joystick handles
|
||||
@@ -344,12 +345,12 @@ void _glfwTerminateJoysticksLinux(void)
|
||||
|
||||
void _glfwDetectJoystickConnectionLinux(void)
|
||||
{
|
||||
ssize_t offset = 0;
|
||||
char buffer[16384];
|
||||
|
||||
if (_glfw.linjs.inotify <= 0)
|
||||
return;
|
||||
|
||||
ssize_t offset = 0;
|
||||
char buffer[16384];
|
||||
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
|
||||
|
||||
while (size > offset)
|
||||
@@ -369,9 +370,7 @@ void _glfwDetectJoystickConnectionLinux(void)
|
||||
openJoystickDevice(path);
|
||||
else if (e->mask & IN_DELETE)
|
||||
{
|
||||
int jid;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||
{
|
||||
@@ -388,7 +387,7 @@ void _glfwDetectJoystickConnectionLinux(void)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode UNUSED)
|
||||
{
|
||||
// Read all queued events (non-blocking)
|
||||
for (;;)
|
||||
@@ -408,10 +407,10 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
if (e.type == EV_SYN)
|
||||
{
|
||||
if (e.code == SYN_DROPPED)
|
||||
_glfw.linjs.dropped = GLFW_TRUE;
|
||||
_glfw.linjs.dropped = true;
|
||||
else if (e.code == SYN_REPORT)
|
||||
{
|
||||
_glfw.linjs.dropped = GLFW_FALSE;
|
||||
_glfw.linjs.dropped = false;
|
||||
pollAbsState(js);
|
||||
}
|
||||
}
|
||||
@@ -428,6 +427,6 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
return js->present;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
9
glfw/linux_joystick.h
vendored
9
glfw/linux_joystick.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Linux - www.glfw.org
|
||||
// GLFW 3.4 Linux - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <regex.h>
|
||||
|
||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs;
|
||||
|
||||
#define _GLFW_PLATFORM_MAPPING_NAME "Linux"
|
||||
|
||||
@@ -52,11 +52,10 @@ typedef struct _GLFWlibraryLinux
|
||||
int inotify;
|
||||
int watch;
|
||||
regex_t regex;
|
||||
GLFWbool dropped;
|
||||
bool dropped;
|
||||
} _GLFWlibraryLinux;
|
||||
|
||||
|
||||
GLFWbool _glfwInitJoysticksLinux(void);
|
||||
bool _glfwInitJoysticksLinux(void);
|
||||
void _glfwTerminateJoysticksLinux(void);
|
||||
void _glfwDetectJoystickConnectionLinux(void);
|
||||
|
||||
|
||||
105
glfw/linux_notify.c
vendored
Normal file
105
glfw/linux_notify.c
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* linux_notify.c
|
||||
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "linux_notify.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NOTIFICATIONS_SERVICE "org.freedesktop.Notifications"
|
||||
#define NOTIFICATIONS_PATH "/org/freedesktop/Notifications"
|
||||
#define NOTIFICATIONS_IFACE "org.freedesktop.Notifications"
|
||||
|
||||
static notification_id_type notification_id = 0;
|
||||
|
||||
typedef struct {
|
||||
notification_id_type next_id;
|
||||
GLFWDBusnotificationcreatedfun callback;
|
||||
void *data;
|
||||
} NotificationCreatedData;
|
||||
|
||||
static GLFWDBusnotificationactivatedfun activated_handler = NULL;
|
||||
|
||||
void
|
||||
glfw_dbus_set_user_notification_activated_handler(GLFWDBusnotificationactivatedfun handler) {
|
||||
activated_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
notification_created(DBusMessage *msg, const char* errmsg, void *data) {
|
||||
if (errmsg) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Notify: Failed to create notification error: %s", errmsg);
|
||||
if (data) free(data);
|
||||
return;
|
||||
}
|
||||
uint32_t notification_id;
|
||||
if (!glfw_dbus_get_args(msg, "Failed to get Notification uid", DBUS_TYPE_UINT32, ¬ification_id, DBUS_TYPE_INVALID)) return;
|
||||
NotificationCreatedData *ncd = (NotificationCreatedData*)data;
|
||||
if (ncd->callback) ncd->callback(ncd->next_id, notification_id, ncd->data);
|
||||
if (data) free(data);
|
||||
}
|
||||
|
||||
static DBusHandlerResult
|
||||
message_handler(DBusConnection *conn UNUSED, DBusMessage *msg, void *user_data UNUSED) {
|
||||
/* printf("session_bus message_handler invoked interface: %s member: %s\n", dbus_message_get_interface(msg), dbus_message_get_member(msg)); */
|
||||
if (dbus_message_is_signal(msg, NOTIFICATIONS_IFACE, "ActionInvoked")) {
|
||||
uint32_t notification_id;
|
||||
const char *action;
|
||||
if (glfw_dbus_get_args(msg, "Failed to get args from ActionInvoked notification signal",
|
||||
DBUS_TYPE_UINT32, ¬ification_id, DBUS_TYPE_STRING, &action, DBUS_TYPE_INVALID)) {
|
||||
if (activated_handler) {
|
||||
activated_handler(notification_id, action);
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
notification_id_type
|
||||
glfw_dbus_send_user_notification(const char *app_name, const char* icon, const char *summary, const char *body, const char* action_name, int32_t timeout, GLFWDBusnotificationcreatedfun callback, void *user_data) {
|
||||
DBusConnection *session_bus = glfw_dbus_session_bus();
|
||||
static DBusConnection *added_signal_match = NULL;
|
||||
if (!session_bus) return 0;
|
||||
if (added_signal_match != session_bus) {
|
||||
dbus_bus_add_match(session_bus, "type='signal',interface='" NOTIFICATIONS_IFACE "',member='ActionInvoked'", NULL);
|
||||
dbus_connection_add_filter(session_bus, message_handler, NULL, NULL);
|
||||
added_signal_match = session_bus;
|
||||
}
|
||||
NotificationCreatedData *data = malloc(sizeof(NotificationCreatedData));
|
||||
if (!data) return 0;
|
||||
data->next_id = ++notification_id;
|
||||
data->callback = callback; data->data = user_data;
|
||||
if (!data->next_id) data->next_id = ++notification_id;
|
||||
uint32_t replaces_id = 0;
|
||||
|
||||
DBusMessage *msg = dbus_message_new_method_call(NOTIFICATIONS_SERVICE, NOTIFICATIONS_PATH, NOTIFICATIONS_IFACE, "Notify");
|
||||
if (!msg) { free(data); return 0; }
|
||||
DBusMessageIter args, array;
|
||||
dbus_message_iter_init_append(msg, &args);
|
||||
#define OOMMSG { free(data); data = NULL; dbus_message_unref(msg); _glfwInputError(GLFW_PLATFORM_ERROR, "%s", "Out of memory allocating DBUS message for notification\n"); return 0; }
|
||||
#define APPEND(type, val) { if (!dbus_message_iter_append_basic(&args, type, val)) OOMMSG }
|
||||
APPEND(DBUS_TYPE_STRING, &app_name)
|
||||
APPEND(DBUS_TYPE_UINT32, &replaces_id)
|
||||
APPEND(DBUS_TYPE_STRING, &icon)
|
||||
APPEND(DBUS_TYPE_STRING, &summary)
|
||||
APPEND(DBUS_TYPE_STRING, &body)
|
||||
if (!dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "s", &array)) OOMMSG;
|
||||
if (action_name) {
|
||||
static const char* default_action = "default";
|
||||
dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &default_action);
|
||||
dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &action_name);
|
||||
}
|
||||
if (!dbus_message_iter_close_container(&args, &array)) OOMMSG;
|
||||
if (!dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, "{sv}", &array)) OOMMSG;
|
||||
if (!dbus_message_iter_close_container(&args, &array)) OOMMSG;
|
||||
APPEND(DBUS_TYPE_INT32, &timeout)
|
||||
#undef OOMMSG
|
||||
#undef APPEND
|
||||
if (!call_method_with_msg(session_bus, msg, 5000, notification_created, data)) return 0;
|
||||
return data->next_id;
|
||||
}
|
||||
19
glfw/linux_notify.h
vendored
Normal file
19
glfw/linux_notify.h
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "dbus_glfw.h"
|
||||
#include "internal.h"
|
||||
|
||||
typedef unsigned long long notification_id_type;
|
||||
typedef void (*GLFWDBusnotificationcreatedfun)(notification_id_type, uint32_t, void*);
|
||||
typedef void (*GLFWDBusnotificationactivatedfun)(uint32_t, const char*);
|
||||
notification_id_type
|
||||
glfw_dbus_send_user_notification(const char *app_name, const char* icon, const char *summary, const char *body, const char *action_name, int32_t timeout, GLFWDBusnotificationcreatedfun, void*);
|
||||
void
|
||||
glfw_dbus_set_user_notification_activated_handler(GLFWDBusnotificationactivatedfun handler);
|
||||
50
glfw/main_loop.h
vendored
Normal file
50
glfw/main_loop.h
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* Distributed under terms of the GPL3 license.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#ifndef GLFW_LOOP_BACKEND
|
||||
#define GLFW_LOOP_BACKEND x11
|
||||
#endif
|
||||
|
||||
static bool keep_going = false;
|
||||
|
||||
|
||||
void _glfwPlatformStopMainLoop(void) {
|
||||
if (keep_going) {
|
||||
keep_going = false;
|
||||
_glfwPlatformPostEmptyEvent();
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformRunMainLoop(GLFWtickcallback tick_callback, void* data) {
|
||||
keep_going = 1;
|
||||
EventLoopData *eld = &_glfw.GLFW_LOOP_BACKEND.eventLoopData;
|
||||
while(keep_going) {
|
||||
_glfwPlatformWaitEvents();
|
||||
EVDBG("--------- loop tick, wakeups_happened: %d ----------", eld->wakeup_data_read);
|
||||
if (eld->wakeup_data_read) {
|
||||
eld->wakeup_data_read = false;
|
||||
tick_callback(data);
|
||||
}
|
||||
}
|
||||
EVDBG("main loop exiting");
|
||||
}
|
||||
|
||||
unsigned long long _glfwPlatformAddTimer(double interval, bool repeats, GLFWuserdatafreefun callback, void *callback_data, GLFWuserdatafreefun free_callback) {
|
||||
return addTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, "user timer", interval, 1, repeats, callback, callback_data, free_callback);
|
||||
}
|
||||
|
||||
void _glfwPlatformRemoveTimer(unsigned long long timer_id) {
|
||||
removeTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id);
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateTimer(unsigned long long timer_id, double interval, bool enabled) {
|
||||
changeTimerInterval(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id, interval);
|
||||
toggleTimer(&_glfw.GLFW_LOOP_BACKEND.eventLoopData, timer_id, enabled);
|
||||
}
|
||||
4
glfw/mappings.h
vendored
4
glfw/mappings.h
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
4
glfw/memfd.h
vendored
4
glfw/memfd.h
vendored
@@ -29,8 +29,8 @@ static inline int memfd_create(const char *name, unsigned int flags) {
|
||||
#endif
|
||||
|
||||
#ifndef MFD_CLOEXEC
|
||||
#define MFD_CLOEXEC 0x0001U
|
||||
#define MFD_ALLOW_SEALING 0x0002U
|
||||
#define MFD_CLOEXEC 0x0001U
|
||||
#define MFD_ALLOW_SEALING 0x0002U
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
78
glfw/monitor.c
vendored
78
glfw/monitor.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -60,25 +62,25 @@ static int compareVideoModes(const void* fp, const void* sp)
|
||||
|
||||
// Retrieves the available modes for the specified monitor
|
||||
//
|
||||
static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
|
||||
static bool refreshVideoModes(_GLFWmonitor* monitor)
|
||||
{
|
||||
int modeCount;
|
||||
GLFWvidmode* modes;
|
||||
|
||||
if (monitor->modes)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
modes = _glfwPlatformGetVideoModes(monitor, &modeCount);
|
||||
if (!modes)
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes);
|
||||
qsort(modes, modeCount, sizeof(modes[0]), compareVideoModes);
|
||||
|
||||
free(monitor->modes);
|
||||
monitor->modes = modes;
|
||||
monitor->modeCount = modeCount;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +102,7 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
|
||||
{
|
||||
memmove(_glfw.monitors + 1,
|
||||
_glfw.monitors,
|
||||
(_glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
|
||||
((size_t) _glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
|
||||
_glfw.monitors[0] = monitor;
|
||||
}
|
||||
else
|
||||
@@ -127,10 +129,7 @@ void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
|
||||
{
|
||||
if (_glfw.monitors[i] == monitor)
|
||||
{
|
||||
_glfw.monitorCount--;
|
||||
memmove(_glfw.monitors + i,
|
||||
_glfw.monitors + i + 1,
|
||||
(_glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
|
||||
remove_i_from_array(_glfw.monitors, i, _glfw.monitorCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -330,6 +329,27 @@ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
|
||||
_glfwPlatformGetMonitorPos(monitor, xpos, ypos);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
|
||||
int* xpos, int* ypos,
|
||||
int* width, int* height)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
assert(monitor != NULL);
|
||||
|
||||
if (xpos)
|
||||
*xpos = 0;
|
||||
if (ypos)
|
||||
*ypos = 0;
|
||||
if (width)
|
||||
*width = 0;
|
||||
if (height)
|
||||
*height = 0;
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
_glfwPlatformGetMonitorWorkarea(monitor, xpos, ypos, width, height);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
@@ -427,12 +447,12 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
|
||||
|
||||
GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
||||
{
|
||||
int i;
|
||||
unsigned short values[256];
|
||||
unsigned int i;
|
||||
unsigned short* values;
|
||||
GLFWgammaramp ramp;
|
||||
const GLFWgammaramp* original;
|
||||
assert(handle != NULL);
|
||||
assert(gamma == gamma);
|
||||
assert(gamma >= 0.f);
|
||||
assert(gamma > 0.f);
|
||||
assert(gamma <= FLT_MAX);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
@@ -443,18 +463,22 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
original = glfwGetGammaRamp(handle);
|
||||
if (!original)
|
||||
return;
|
||||
|
||||
values = calloc(original->size, sizeof(unsigned short));
|
||||
|
||||
for (i = 0; i < original->size; i++)
|
||||
{
|
||||
float value;
|
||||
|
||||
// Calculate intensity
|
||||
value = i / 255.f;
|
||||
value = i / (float) (original->size - 1);
|
||||
// Apply gamma curve
|
||||
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
|
||||
|
||||
// Clamp to value range
|
||||
if (value > 65535.f)
|
||||
value = 65535.f;
|
||||
value = fminf(value, 65535.f);
|
||||
|
||||
values[i] = (unsigned short) value;
|
||||
}
|
||||
@@ -462,9 +486,10 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
|
||||
ramp.red = values;
|
||||
ramp.green = values;
|
||||
ramp.blue = values;
|
||||
ramp.size = 256;
|
||||
ramp.size = original->size;
|
||||
|
||||
glfwSetGammaRamp(handle, &ramp);
|
||||
free(values);
|
||||
}
|
||||
|
||||
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
|
||||
@@ -475,7 +500,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
_glfwFreeGammaArrays(&monitor->currentRamp);
|
||||
_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp);
|
||||
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->currentRamp))
|
||||
return NULL;
|
||||
|
||||
return &monitor->currentRamp;
|
||||
}
|
||||
@@ -501,8 +527,10 @@ GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (!monitor->originalRamp.size)
|
||||
_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp);
|
||||
{
|
||||
if (!_glfwPlatformGetGammaRamp(monitor, &monitor->originalRamp))
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwPlatformSetGammaRamp(monitor, ramp);
|
||||
}
|
||||
|
||||
|
||||
15
glfw/nsgl_context.h
vendored
15
glfw/nsgl_context.h
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,8 +24,8 @@
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl;
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl;
|
||||
|
||||
|
||||
// NSGL-specific per-context data
|
||||
@@ -33,7 +33,7 @@
|
||||
typedef struct _GLFWcontextNSGL
|
||||
{
|
||||
id pixelFormat;
|
||||
id object;
|
||||
id object;
|
||||
|
||||
} _GLFWcontextNSGL;
|
||||
|
||||
@@ -47,10 +47,9 @@ typedef struct _GLFWlibraryNSGL
|
||||
} _GLFWlibraryNSGL;
|
||||
|
||||
|
||||
GLFWbool _glfwInitNSGL(void);
|
||||
bool _glfwInitNSGL(void);
|
||||
void _glfwTerminateNSGL(void);
|
||||
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
bool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContextNSGL(_GLFWwindow* window);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 macOS - www.glfw.org
|
||||
// GLFW 3.4 macOS - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -23,15 +23,12 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
#if (MAC_OS_X_VERSION_MAX_ALLOWED < 101400)
|
||||
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
|
||||
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
|
||||
#endif
|
||||
|
||||
static void makeContextCurrentNSGL(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
@@ -48,19 +45,17 @@ static void swapBuffersNSGL(_GLFWwindow* window)
|
||||
[window->context.nsgl.object flushBuffer];
|
||||
}
|
||||
|
||||
static void swapIntervalNSGL(int interval)
|
||||
static void swapIntervalNSGL(int interval UNUSED)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
|
||||
GLint sync = interval;
|
||||
[window->context.nsgl.object setValues:&sync
|
||||
forParameter:NSOpenGLContextParameterSwapInterval];
|
||||
// As of Mojave this does not work so we use CVDisplayLink instead
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"NSGL: Swap intervals do not work on macOS");
|
||||
}
|
||||
|
||||
static int extensionSupportedNSGL(const char* extension)
|
||||
static int extensionSupportedNSGL(const char* extension UNUSED)
|
||||
{
|
||||
// There are no NSGL extensions
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddressNSGL(const char* procname)
|
||||
@@ -69,16 +64,15 @@ static GLFWglproc getProcAddressNSGL(const char* procname)
|
||||
procname,
|
||||
kCFStringEncodingASCII);
|
||||
|
||||
GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
|
||||
symbolName);
|
||||
GLFWglproc symbol;
|
||||
*(void **) &symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
|
||||
symbolName);
|
||||
|
||||
CFRelease(symbolName);
|
||||
|
||||
return symbol;
|
||||
}
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
static void destroyContextNSGL(_GLFWwindow* window)
|
||||
{
|
||||
[window->context.nsgl.pixelFormat release];
|
||||
@@ -95,10 +89,10 @@ static void destroyContextNSGL(_GLFWwindow* window)
|
||||
|
||||
// Initialize OpenGL support
|
||||
//
|
||||
GLFWbool _glfwInitNSGL(void)
|
||||
bool _glfwInitNSGL(void)
|
||||
{
|
||||
if (_glfw.nsgl.framework)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
_glfw.nsgl.framework =
|
||||
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
|
||||
@@ -106,10 +100,10 @@ GLFWbool _glfwInitNSGL(void)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"NSGL: Failed to locate OpenGL framework");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Terminate OpenGL support
|
||||
@@ -120,7 +114,7 @@ void _glfwTerminateNSGL(void)
|
||||
|
||||
// Create the OpenGL context
|
||||
//
|
||||
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
bool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
@@ -128,7 +122,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"NSGL: OpenGL ES is not available on macOS");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->major > 2)
|
||||
@@ -137,14 +131,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!ctxconfig->forward || ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"NSGL: The targeted version of macOS only supports forward-compatible core profile contexts for OpenGL 3.2 and above");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,9 +167,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
// Info.plist for unbundled applications
|
||||
// HACK: This assumes that NSOpenGLPixelFormat will remain
|
||||
// a straightforward wrapper of its CGL counterpart
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
|
||||
addAttrib(kCGLPFASupportsAutomaticGraphicsSwitching);
|
||||
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
|
||||
@@ -247,7 +232,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"NSGL: Stereo rendering is deprecated");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
#else
|
||||
addAttrib(NSOpenGLPFAStereo);
|
||||
#endif
|
||||
@@ -283,7 +268,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"NSGL: Failed to find a suitable pixel format");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
NSOpenGLContext* share = NULL;
|
||||
@@ -298,15 +283,23 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"NSGL: Failed to create OpenGL context");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fbconfig->transparent)
|
||||
{
|
||||
GLint opaque = 0;
|
||||
[window->context.nsgl.object setValues:&opaque forParameter:NSOpenGLContextParameterSurfaceOpacity];
|
||||
[window->context.nsgl.object setValues:&opaque
|
||||
forParameter:NSOpenGLContextParameterSurfaceOpacity];
|
||||
}
|
||||
|
||||
if (window->ns.retina)
|
||||
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
|
||||
|
||||
GLint interval = 0;
|
||||
[window->context.nsgl.object setValues:&interval
|
||||
forParameter:NSOpenGLContextParameterSwapInterval];
|
||||
|
||||
[window->context.nsgl.object setView:window->ns.view];
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentNSGL;
|
||||
@@ -316,7 +309,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
|
||||
window->context.getProcAddress = getProcAddressNSGL;
|
||||
window->context.destroy = destroyContextNSGL;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
8
glfw/null_init.c
vendored
8
glfw/null_init.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -35,7 +37,7 @@
|
||||
int _glfwPlatformInit(void)
|
||||
{
|
||||
_glfwInitTimerPOSIX();
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
|
||||
8
glfw/null_joystick.c
vendored
8
glfw/null_joystick.c
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -23,6 +23,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -33,7 +35,7 @@
|
||||
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
|
||||
7
glfw/null_joystick.h
vendored
7
glfw/null_joystick.h
vendored
@@ -1,7 +1,7 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -25,7 +25,6 @@
|
||||
//========================================================================
|
||||
|
||||
#define _GLFW_PLATFORM_JOYSTICK_STATE int nulljs
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs;
|
||||
|
||||
#define _GLFW_PLATFORM_MAPPING_NAME ""
|
||||
|
||||
|
||||
15
glfw/null_monitor.c
vendored
15
glfw/null_monitor.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -49,6 +51,12 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
*yscale = 1.f;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||
int* xpos, int* ypos,
|
||||
int* width, int* height)
|
||||
{
|
||||
}
|
||||
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||
{
|
||||
return NULL;
|
||||
@@ -58,8 +66,9 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
|
||||
4
glfw/null_platform.h
vendored
4
glfw/null_platform.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
50
glfw/null_window.c
vendored
50
glfw/null_window.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -34,7 +36,7 @@ static int createNativeWindow(_GLFWwindow* window,
|
||||
window->null.width = wndconfig->width;
|
||||
window->null.height = wndconfig->height;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +50,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
if (!createNativeWindow(window, wndconfig))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (ctxconfig->client != GLFW_NO_API)
|
||||
{
|
||||
@@ -56,18 +58,18 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window,
|
||||
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
|
||||
{
|
||||
if (!_glfwInitOSMesa())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Null: EGL not available");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
||||
@@ -167,28 +169,28 @@ void _glfwPlatformMaximizeWindow(_GLFWwindow* window)
|
||||
|
||||
int _glfwPlatformWindowMaximized(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowHovered(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformFramebufferTransparent(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowResizable(_GLFWwindow* window, bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled)
|
||||
void _glfwPlatformSetWindowFloating(_GLFWwindow* window, bool enabled)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -212,7 +214,7 @@ void _glfwPlatformRequestWindowAttention(_GLFWwindow* window)
|
||||
|
||||
int _glfwPlatformWindowBell(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformUnhideWindow(_GLFWwindow* window)
|
||||
@@ -229,17 +231,22 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window)
|
||||
|
||||
int _glfwPlatformWindowFocused(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowOccluded(_GLFWwindow* window)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowIconified(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowVisible(_GLFWwindow* window)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformPollEvents(void)
|
||||
@@ -274,12 +281,12 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
|
||||
const GLFWimage* image,
|
||||
int xhot, int yhot, int count)
|
||||
{
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
|
||||
{
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyCursor(_GLFWcursor* cursor)
|
||||
@@ -317,7 +324,7 @@ int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||
VkPhysicalDevice device,
|
||||
uint32_t queuefamily)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||
@@ -328,3 +335,4 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance,
|
||||
// This seems like the most appropriate error to return here
|
||||
return VK_ERROR_INITIALIZATION_FAILED;
|
||||
}
|
||||
|
||||
|
||||
76
glfw/osmesa_context.c
vendored
76
glfw/osmesa_context.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 OSMesa - www.glfw.org
|
||||
// GLFW 3.4 OSMesa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -47,7 +49,7 @@ static void makeContextCurrentOSMesa(_GLFWwindow* window)
|
||||
free(window->context.osmesa.buffer);
|
||||
|
||||
// Allocate the new buffer (width * height * 8-bit RGBA)
|
||||
window->context.osmesa.buffer = calloc(4, width * height);
|
||||
window->context.osmesa.buffer = calloc(4, (size_t) width * height);
|
||||
window->context.osmesa.width = width;
|
||||
window->context.osmesa.height = height;
|
||||
}
|
||||
@@ -87,20 +89,20 @@ static void destroyContextOSMesa(_GLFWwindow* window)
|
||||
}
|
||||
}
|
||||
|
||||
static void swapBuffersOSMesa(_GLFWwindow* window)
|
||||
static void swapBuffersOSMesa(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
// No double buffering on OSMesa
|
||||
}
|
||||
|
||||
static void swapIntervalOSMesa(int interval)
|
||||
static void swapIntervalOSMesa(int interval UNUSED)
|
||||
{
|
||||
// No swap interval on OSMesa
|
||||
}
|
||||
|
||||
static int extensionSupportedOSMesa(const char* extension)
|
||||
static int extensionSupportedOSMesa(const char* extension UNUSED)
|
||||
{
|
||||
// OSMesa does not have extensions
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +110,7 @@ static int extensionSupportedOSMesa(const char* extension)
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwInitOSMesa(void)
|
||||
bool _glfwInitOSMesa(void)
|
||||
{
|
||||
int i;
|
||||
const char* sonames[] =
|
||||
@@ -130,7 +132,7 @@ GLFWbool _glfwInitOSMesa(void)
|
||||
};
|
||||
|
||||
if (_glfw.osmesa.handle)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
for (i = 0; sonames[i]; i++)
|
||||
{
|
||||
@@ -142,23 +144,16 @@ GLFWbool _glfwInitOSMesa(void)
|
||||
if (!_glfw.osmesa.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextExt");
|
||||
_glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
|
||||
_glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaDestroyContext");
|
||||
_glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaMakeCurrent");
|
||||
_glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
|
||||
_glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
|
||||
_glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
|
||||
_glfw_dlsym(_glfw.osmesa.handle, "OSMesaGetProcAddress");
|
||||
glfw_dlsym(_glfw.osmesa.CreateContextExt, _glfw.osmesa.handle, "OSMesaCreateContextExt");
|
||||
glfw_dlsym(_glfw.osmesa.CreateContextAttribs, _glfw.osmesa.handle, "OSMesaCreateContextAttribs");
|
||||
glfw_dlsym(_glfw.osmesa.DestroyContext, _glfw.osmesa.handle, "OSMesaDestroyContext");
|
||||
glfw_dlsym(_glfw.osmesa.MakeCurrent, _glfw.osmesa.handle, "OSMesaMakeCurrent");
|
||||
glfw_dlsym(_glfw.osmesa.GetColorBuffer, _glfw.osmesa.handle, "OSMesaGetColorBuffer");
|
||||
glfw_dlsym(_glfw.osmesa.GetDepthBuffer, _glfw.osmesa.handle, "OSMesaGetDepthBuffer");
|
||||
glfw_dlsym(_glfw.osmesa.GetProcAddress, _glfw.osmesa.handle, "OSMesaGetProcAddress");
|
||||
|
||||
if (!_glfw.osmesa.CreateContextExt ||
|
||||
!_glfw.osmesa.DestroyContext ||
|
||||
@@ -171,10 +166,10 @@ GLFWbool _glfwInitOSMesa(void)
|
||||
"OSMesa: Failed to load required entry points");
|
||||
|
||||
_glfwTerminateOSMesa();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwTerminateOSMesa(void)
|
||||
@@ -188,12 +183,12 @@ void _glfwTerminateOSMesa(void)
|
||||
|
||||
#define setAttrib(a, v) \
|
||||
{ \
|
||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
attribs[index++] = a; \
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
bool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
@@ -207,7 +202,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"OSMesa: OpenGL ES is not available on OSMesa");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ctxconfig->share)
|
||||
@@ -240,8 +235,8 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
if (ctxconfig->forward)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"OSMesa: Foward-compatible contexts not supported");
|
||||
return GLFW_FALSE;
|
||||
"OSMesa: Forward-compatible contexts not supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
setAttrib(0, 0);
|
||||
@@ -255,7 +250,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"OSMesa: OpenGL profiles unavailable");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
window->context.osmesa.handle =
|
||||
@@ -270,7 +265,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"OSMesa: Failed to create context");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentOSMesa;
|
||||
@@ -280,7 +275,7 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
window->context.getProcAddress = getProcAddressOSMesa;
|
||||
window->context.destroy = destroyContextOSMesa;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef setAttrib
|
||||
@@ -298,7 +293,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
|
||||
&mesaWidth, &mesaHeight,
|
||||
@@ -306,7 +301,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"OSMesa: Failed to retrieve color buffer");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (width)
|
||||
@@ -318,7 +313,7 @@ GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
|
||||
if (buffer)
|
||||
*buffer = mesaBuffer;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
||||
@@ -331,7 +326,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
|
||||
&mesaWidth, &mesaHeight,
|
||||
@@ -339,7 +334,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"OSMesa: Failed to retrieve depth buffer");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (width)
|
||||
@@ -351,7 +346,7 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
|
||||
if (buffer)
|
||||
*buffer = mesaBuffer;
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
|
||||
@@ -367,4 +362,3 @@ GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
|
||||
|
||||
return window->context.osmesa.handle;
|
||||
}
|
||||
|
||||
|
||||
8
glfw/osmesa_context.h
vendored
8
glfw/osmesa_context.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 OSMesa - www.glfw.org
|
||||
// GLFW 3.4 OSMesa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016 Google Inc.
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -86,9 +86,9 @@ typedef struct _GLFWlibraryOSMesa
|
||||
} _GLFWlibraryOSMesa;
|
||||
|
||||
|
||||
GLFWbool _glfwInitOSMesa(void);
|
||||
bool _glfwInitOSMesa(void);
|
||||
void _glfwTerminateOSMesa(void);
|
||||
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
bool _glfwCreateContextOSMesa(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
||||
|
||||
32
glfw/posix_thread.c
vendored
32
glfw/posix_thread.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 POSIX - www.glfw.org
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -35,19 +37,19 @@
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
|
||||
bool _glfwPlatformCreateTls(_GLFWtls* tls)
|
||||
{
|
||||
assert(tls->posix.allocated == GLFW_FALSE);
|
||||
assert(tls->posix.allocated == false);
|
||||
|
||||
if (pthread_key_create(&tls->posix.key, NULL) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"POSIX: Failed to create context TLS");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
tls->posix.allocated = GLFW_TRUE;
|
||||
return GLFW_TRUE;
|
||||
tls->posix.allocated = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
||||
@@ -59,27 +61,27 @@ void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
||||
|
||||
void* _glfwPlatformGetTls(_GLFWtls* tls)
|
||||
{
|
||||
assert(tls->posix.allocated == GLFW_TRUE);
|
||||
assert(tls->posix.allocated == true);
|
||||
return pthread_getspecific(tls->posix.key);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
|
||||
{
|
||||
assert(tls->posix.allocated == GLFW_TRUE);
|
||||
assert(tls->posix.allocated == true);
|
||||
pthread_setspecific(tls->posix.key, value);
|
||||
}
|
||||
|
||||
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
||||
bool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->posix.allocated == GLFW_FALSE);
|
||||
assert(mutex->posix.allocated == false);
|
||||
|
||||
if (pthread_mutex_init(&mutex->posix.handle, NULL) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "POSIX: Failed to create mutex");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return mutex->posix.allocated = GLFW_TRUE;
|
||||
return mutex->posix.allocated = true;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
||||
@@ -91,13 +93,13 @@ void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
||||
|
||||
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->posix.allocated == GLFW_TRUE);
|
||||
assert(mutex->posix.allocated == true);
|
||||
pthread_mutex_lock(&mutex->posix.handle);
|
||||
}
|
||||
|
||||
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->posix.allocated == GLFW_TRUE);
|
||||
assert(mutex->posix.allocated == true);
|
||||
pthread_mutex_unlock(&mutex->posix.handle);
|
||||
}
|
||||
|
||||
|
||||
8
glfw/posix_thread.h
vendored
8
glfw/posix_thread.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 POSIX - www.glfw.org
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -35,7 +35,7 @@
|
||||
//
|
||||
typedef struct _GLFWtlsPOSIX
|
||||
{
|
||||
GLFWbool allocated;
|
||||
bool allocated;
|
||||
pthread_key_t key;
|
||||
|
||||
} _GLFWtlsPOSIX;
|
||||
@@ -44,7 +44,7 @@ typedef struct _GLFWtlsPOSIX
|
||||
//
|
||||
typedef struct _GLFWmutexPOSIX
|
||||
{
|
||||
GLFWbool allocated;
|
||||
bool allocated;
|
||||
pthread_mutex_t handle;
|
||||
|
||||
} _GLFWmutexPOSIX;
|
||||
|
||||
10
glfw/posix_time.c
vendored
10
glfw/posix_time.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 POSIX - www.glfw.org
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -44,13 +46,13 @@ void _glfwInitTimerPOSIX(void)
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||
{
|
||||
_glfw.timer.posix.monotonic = GLFW_TRUE;
|
||||
_glfw.timer.posix.monotonic = true;
|
||||
_glfw.timer.posix.frequency = 1000000000;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_glfw.timer.posix.monotonic = GLFW_FALSE;
|
||||
_glfw.timer.posix.monotonic = false;
|
||||
_glfw.timer.posix.frequency = 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
6
glfw/posix_time.h
vendored
6
glfw/posix_time.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 POSIX - www.glfw.org
|
||||
// GLFW 3.4 POSIX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -34,7 +34,7 @@
|
||||
//
|
||||
typedef struct _GLFWtimerPOSIX
|
||||
{
|
||||
GLFWbool monotonic;
|
||||
bool monotonic;
|
||||
uint64_t frequency;
|
||||
|
||||
} _GLFWtimerPOSIX;
|
||||
|
||||
@@ -64,7 +64,9 @@
|
||||
"egl_context.h",
|
||||
"osmesa_context.h",
|
||||
"linux_joystick.h",
|
||||
"null_joystick.h"
|
||||
"null_joystick.h",
|
||||
"linux_notify.h",
|
||||
"main_loop.h"
|
||||
],
|
||||
"protocols": [
|
||||
"stable/xdg-shell/xdg-shell.xml",
|
||||
@@ -88,7 +90,8 @@
|
||||
"osmesa_context.c",
|
||||
"backend_utils.c",
|
||||
"linux_joystick.c",
|
||||
"null_joystick.c"
|
||||
"null_joystick.c",
|
||||
"linux_notify.c"
|
||||
]
|
||||
},
|
||||
"wayland_protocols": [
|
||||
@@ -128,7 +131,9 @@
|
||||
"egl_context.h",
|
||||
"osmesa_context.h",
|
||||
"linux_joystick.h",
|
||||
"null_joystick.h"
|
||||
"null_joystick.h",
|
||||
"linux_notify.h",
|
||||
"main_loop.h"
|
||||
],
|
||||
"sources": [
|
||||
"x11_init.c",
|
||||
@@ -144,7 +149,8 @@
|
||||
"osmesa_context.c",
|
||||
"backend_utils.c",
|
||||
"linux_joystick.c",
|
||||
"null_joystick.c"
|
||||
"null_joystick.c",
|
||||
"linux_notify.c"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
48
glfw/vulkan.c
vendored
48
glfw/vulkan.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -39,14 +41,14 @@
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwInitVulkan(int mode)
|
||||
bool _glfwInitVulkan(int mode)
|
||||
{
|
||||
VkResult err;
|
||||
VkExtensionProperties* ep;
|
||||
uint32_t i, count;
|
||||
|
||||
if (_glfw.vk.available)
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
|
||||
#if !defined(_GLFW_VULKAN_STATIC)
|
||||
#if defined(_GLFW_VULKAN_LIBRARY)
|
||||
@@ -63,10 +65,10 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
if (mode == _GLFW_REQUIRE_LOADER)
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
|
||||
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
|
||||
*(void **) &_glfw.vk.GetInstanceProcAddr =
|
||||
_glfw_dlsym(_glfw.vk.handle, "vkGetInstanceProcAddr");
|
||||
if (!_glfw.vk.GetInstanceProcAddr)
|
||||
{
|
||||
@@ -74,7 +76,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
"Vulkan: Loader does not export vkGetInstanceProcAddr");
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.vk.EnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
|
||||
@@ -85,7 +87,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
#endif // _GLFW_VULKAN_STATIC
|
||||
|
||||
@@ -101,7 +103,7 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
}
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
ep = calloc(count, sizeof(VkExtensionProperties));
|
||||
@@ -115,37 +117,37 @@ GLFWbool _glfwInitVulkan(int mode)
|
||||
|
||||
free(ep);
|
||||
_glfwTerminateVulkan();
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
|
||||
_glfw.vk.KHR_surface = GLFW_TRUE;
|
||||
_glfw.vk.KHR_surface = true;
|
||||
#if defined(_GLFW_WIN32)
|
||||
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
|
||||
_glfw.vk.KHR_win32_surface = GLFW_TRUE;
|
||||
_glfw.vk.KHR_win32_surface = true;
|
||||
#elif defined(_GLFW_COCOA)
|
||||
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
|
||||
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
|
||||
_glfw.vk.MVK_macos_surface = true;
|
||||
#elif defined(_GLFW_X11)
|
||||
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
|
||||
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
|
||||
_glfw.vk.KHR_xlib_surface = true;
|
||||
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
|
||||
_glfw.vk.KHR_xcb_surface = GLFW_TRUE;
|
||||
_glfw.vk.KHR_xcb_surface = true;
|
||||
#elif defined(_GLFW_WAYLAND)
|
||||
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
|
||||
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
|
||||
_glfw.vk.KHR_wayland_surface = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
free(ep);
|
||||
|
||||
_glfw.vk.available = GLFW_TRUE;
|
||||
_glfw.vk.available = true;
|
||||
|
||||
_glfwPlatformGetRequiredInstanceExtensions(_glfw.vk.extensions);
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwTerminateVulkan(void)
|
||||
@@ -218,7 +220,7 @@ const char* _glfwGetVulkanResultString(VkResult result)
|
||||
|
||||
GLFWAPI int glfwVulkanSupported(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
return _glfwInitVulkan(_GLFW_FIND_LOADER);
|
||||
}
|
||||
|
||||
@@ -260,7 +262,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
|
||||
}
|
||||
#else
|
||||
if (!proc)
|
||||
proc = (GLFWvkproc) _glfw_dlsym(_glfw.vk.handle, procname);
|
||||
*(void **) &proc = _glfw_dlsym(_glfw.vk.handle, procname);
|
||||
#endif
|
||||
|
||||
return proc;
|
||||
@@ -273,16 +275,16 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
|
||||
assert(instance != VK_NULL_HANDLE);
|
||||
assert(device != VK_NULL_HANDLE);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
if (!_glfw.vk.extensions[0])
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"Vulkan: Window surface creation extensions not found");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
return _glfwPlatformGetPhysicalDevicePresentationSupport(instance,
|
||||
|
||||
744
glfw/wgl_context.c
vendored
744
glfw/wgl_context.c
vendored
@@ -1,744 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 WGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
// Returns the specified attribute of the specified pixel format
|
||||
//
|
||||
static int getPixelFormatAttrib(_GLFWwindow* window, int pixelFormat, int attrib)
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
assert(_glfw.wgl.ARB_pixel_format);
|
||||
|
||||
if (!_glfw.wgl.GetPixelFormatAttribivARB(window->context.wgl.dc,
|
||||
pixelFormat,
|
||||
0, 1, &attrib, &value))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve pixel format attribute");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// Return a list of available and usable framebuffer configs
|
||||
//
|
||||
static int choosePixelFormat(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
_GLFWfbconfig* usableConfigs;
|
||||
const _GLFWfbconfig* closest;
|
||||
int i, pixelFormat, nativeCount, usableCount;
|
||||
|
||||
if (_glfw.wgl.ARB_pixel_format)
|
||||
{
|
||||
nativeCount = getPixelFormatAttrib(window,
|
||||
1,
|
||||
WGL_NUMBER_PIXEL_FORMATS_ARB);
|
||||
}
|
||||
else
|
||||
{
|
||||
nativeCount = DescribePixelFormat(window->context.wgl.dc,
|
||||
1,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
NULL);
|
||||
}
|
||||
|
||||
usableConfigs = calloc(nativeCount, sizeof(_GLFWfbconfig));
|
||||
usableCount = 0;
|
||||
|
||||
for (i = 0; i < nativeCount; i++)
|
||||
{
|
||||
const int n = i + 1;
|
||||
_GLFWfbconfig* u = usableConfigs + usableCount;
|
||||
|
||||
if (_glfw.wgl.ARB_pixel_format)
|
||||
{
|
||||
// Get pixel format attributes through "modern" extension
|
||||
|
||||
if (!getPixelFormatAttrib(window, n, WGL_SUPPORT_OPENGL_ARB) ||
|
||||
!getPixelFormatAttrib(window, n, WGL_DRAW_TO_WINDOW_ARB))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getPixelFormatAttrib(window, n, WGL_PIXEL_TYPE_ARB) !=
|
||||
WGL_TYPE_RGBA_ARB)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getPixelFormatAttrib(window, n, WGL_ACCELERATION_ARB) ==
|
||||
WGL_NO_ACCELERATION_ARB)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
u->redBits = getPixelFormatAttrib(window, n, WGL_RED_BITS_ARB);
|
||||
u->greenBits = getPixelFormatAttrib(window, n, WGL_GREEN_BITS_ARB);
|
||||
u->blueBits = getPixelFormatAttrib(window, n, WGL_BLUE_BITS_ARB);
|
||||
u->alphaBits = getPixelFormatAttrib(window, n, WGL_ALPHA_BITS_ARB);
|
||||
|
||||
u->depthBits = getPixelFormatAttrib(window, n, WGL_DEPTH_BITS_ARB);
|
||||
u->stencilBits = getPixelFormatAttrib(window, n, WGL_STENCIL_BITS_ARB);
|
||||
|
||||
u->accumRedBits = getPixelFormatAttrib(window, n, WGL_ACCUM_RED_BITS_ARB);
|
||||
u->accumGreenBits = getPixelFormatAttrib(window, n, WGL_ACCUM_GREEN_BITS_ARB);
|
||||
u->accumBlueBits = getPixelFormatAttrib(window, n, WGL_ACCUM_BLUE_BITS_ARB);
|
||||
u->accumAlphaBits = getPixelFormatAttrib(window, n, WGL_ACCUM_ALPHA_BITS_ARB);
|
||||
|
||||
u->auxBuffers = getPixelFormatAttrib(window, n, WGL_AUX_BUFFERS_ARB);
|
||||
|
||||
if (getPixelFormatAttrib(window, n, WGL_STEREO_ARB))
|
||||
u->stereo = GLFW_TRUE;
|
||||
if (getPixelFormatAttrib(window, n, WGL_DOUBLE_BUFFER_ARB))
|
||||
u->doublebuffer = GLFW_TRUE;
|
||||
|
||||
if (_glfw.wgl.ARB_multisample)
|
||||
u->samples = getPixelFormatAttrib(window, n, WGL_SAMPLES_ARB);
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (_glfw.wgl.ARB_framebuffer_sRGB ||
|
||||
_glfw.wgl.EXT_framebuffer_sRGB)
|
||||
{
|
||||
if (getPixelFormatAttrib(window, n, WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
|
||||
u->sRGB = GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_glfw.wgl.EXT_colorspace)
|
||||
{
|
||||
if (getPixelFormatAttrib(window, n, WGL_COLORSPACE_EXT) ==
|
||||
WGL_COLORSPACE_SRGB_EXT)
|
||||
{
|
||||
u->sRGB = GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get pixel format attributes through legacy PFDs
|
||||
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
|
||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||
n,
|
||||
sizeof(PIXELFORMATDESCRIPTOR),
|
||||
&pfd))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
|
||||
!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
|
||||
(pfd.dwFlags & PFD_GENERIC_FORMAT))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pfd.iPixelType != PFD_TYPE_RGBA)
|
||||
continue;
|
||||
|
||||
u->redBits = pfd.cRedBits;
|
||||
u->greenBits = pfd.cGreenBits;
|
||||
u->blueBits = pfd.cBlueBits;
|
||||
u->alphaBits = pfd.cAlphaBits;
|
||||
|
||||
u->depthBits = pfd.cDepthBits;
|
||||
u->stencilBits = pfd.cStencilBits;
|
||||
|
||||
u->accumRedBits = pfd.cAccumRedBits;
|
||||
u->accumGreenBits = pfd.cAccumGreenBits;
|
||||
u->accumBlueBits = pfd.cAccumBlueBits;
|
||||
u->accumAlphaBits = pfd.cAccumAlphaBits;
|
||||
|
||||
u->auxBuffers = pfd.cAuxBuffers;
|
||||
|
||||
if (pfd.dwFlags & PFD_STEREO)
|
||||
u->stereo = GLFW_TRUE;
|
||||
if (pfd.dwFlags & PFD_DOUBLEBUFFER)
|
||||
u->doublebuffer = GLFW_TRUE;
|
||||
}
|
||||
|
||||
u->handle = n;
|
||||
usableCount++;
|
||||
}
|
||||
|
||||
if (!usableCount)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"WGL: The driver does not appear to support OpenGL");
|
||||
|
||||
free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
|
||||
if (!closest)
|
||||
{
|
||||
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
|
||||
"WGL: Failed to find a suitable pixel format");
|
||||
|
||||
free(usableConfigs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pixelFormat = (int) closest->handle;
|
||||
free(usableConfigs);
|
||||
|
||||
return pixelFormat;
|
||||
}
|
||||
|
||||
static void makeContextCurrentWGL(_GLFWwindow* window)
|
||||
{
|
||||
if (window)
|
||||
{
|
||||
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
|
||||
_glfwPlatformSetTls(&_glfw.contextSlot, window);
|
||||
else
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to make context current");
|
||||
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!wglMakeCurrent(NULL, NULL))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to clear current context");
|
||||
}
|
||||
|
||||
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void swapBuffersWGL(_GLFWwindow* window)
|
||||
{
|
||||
if (!window->monitor)
|
||||
{
|
||||
if (IsWindowsVistaOrGreater())
|
||||
{
|
||||
BOOL enabled;
|
||||
|
||||
// HACK: Use DwmFlush when desktop composition is enabled
|
||||
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
||||
{
|
||||
int count = abs(window->context.wgl.interval);
|
||||
while (count--)
|
||||
DwmFlush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwapBuffers(window->context.wgl.dc);
|
||||
}
|
||||
|
||||
static void swapIntervalWGL(int interval)
|
||||
{
|
||||
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
|
||||
|
||||
window->context.wgl.interval = interval;
|
||||
|
||||
if (!window->monitor)
|
||||
{
|
||||
if (IsWindowsVistaOrGreater())
|
||||
{
|
||||
BOOL enabled;
|
||||
|
||||
// HACK: Disable WGL swap interval when desktop composition is enabled to
|
||||
// avoid interfering with DWM vsync
|
||||
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
|
||||
interval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfw.wgl.EXT_swap_control)
|
||||
_glfw.wgl.SwapIntervalEXT(interval);
|
||||
}
|
||||
|
||||
static int extensionSupportedWGL(const char* extension)
|
||||
{
|
||||
const char* extensions;
|
||||
|
||||
if (_glfw.wgl.GetExtensionsStringEXT)
|
||||
{
|
||||
extensions = _glfw.wgl.GetExtensionsStringEXT();
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfw.wgl.GetExtensionsStringARB)
|
||||
{
|
||||
extensions = _glfw.wgl.GetExtensionsStringARB(wglGetCurrentDC());
|
||||
if (extensions)
|
||||
{
|
||||
if (_glfwStringInExtensionString(extension, extensions))
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
static GLFWglproc getProcAddressWGL(const char* procname)
|
||||
{
|
||||
const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);
|
||||
if (proc)
|
||||
return proc;
|
||||
|
||||
return (GLFWglproc) GetProcAddress(_glfw.wgl.instance, procname);
|
||||
}
|
||||
|
||||
// Destroy the OpenGL context
|
||||
//
|
||||
static void destroyContextWGL(_GLFWwindow* window)
|
||||
{
|
||||
if (window->context.wgl.handle)
|
||||
{
|
||||
wglDeleteContext(window->context.wgl.handle);
|
||||
window->context.wgl.handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Initialize WGL
|
||||
//
|
||||
GLFWbool _glfwInitWGL(void)
|
||||
{
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
HGLRC prc, rc;
|
||||
HDC pdc, dc;
|
||||
|
||||
if (_glfw.wgl.instance)
|
||||
return GLFW_TRUE;
|
||||
|
||||
_glfw.wgl.instance = LoadLibraryA("opengl32.dll");
|
||||
if (!_glfw.wgl.instance)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to load opengl32.dll");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.wgl.CreateContext = (PFN_wglCreateContext)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglCreateContext");
|
||||
_glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
|
||||
_glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
|
||||
_glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
|
||||
_glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglGetCurrentContext");
|
||||
_glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
|
||||
_glfw.wgl.ShareLists = (PFN_wglShareLists)
|
||||
GetProcAddress(_glfw.wgl.instance, "wglShareLists");
|
||||
|
||||
// NOTE: A dummy context has to be created for opengl32.dll to load the
|
||||
// OpenGL ICD, from which we can then query WGL extensions
|
||||
// NOTE: This code will accept the Microsoft GDI ICD; accelerated context
|
||||
// creation failure occurs during manual pixel format enumeration
|
||||
|
||||
dc = GetDC(_glfw.win32.helperWindowHandle);;
|
||||
|
||||
ZeroMemory(&pfd, sizeof(pfd));
|
||||
pfd.nSize = sizeof(pfd);
|
||||
pfd.nVersion = 1;
|
||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
|
||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
||||
pfd.cColorBits = 24;
|
||||
|
||||
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to set pixel format for dummy context");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
rc = wglCreateContext(dc);
|
||||
if (!rc)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to create dummy context");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
pdc = wglGetCurrentDC();
|
||||
prc = wglGetCurrentContext();
|
||||
|
||||
if (!wglMakeCurrent(dc, rc))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to make dummy context current");
|
||||
wglMakeCurrent(pdc, prc);
|
||||
wglDeleteContext(rc);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
// NOTE: Functions must be loaded first as they're needed to retrieve the
|
||||
// extension string that tells us whether the functions are supported
|
||||
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
|
||||
wglGetProcAddress("wglGetExtensionsStringEXT");
|
||||
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
|
||||
wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
|
||||
wglGetProcAddress("wglCreateContextAttribsARB");
|
||||
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
|
||||
wglGetProcAddress("wglSwapIntervalEXT");
|
||||
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
|
||||
wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
||||
|
||||
// NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
|
||||
// checked below as we are already using them
|
||||
_glfw.wgl.ARB_multisample =
|
||||
extensionSupportedWGL("WGL_ARB_multisample");
|
||||
_glfw.wgl.ARB_framebuffer_sRGB =
|
||||
extensionSupportedWGL("WGL_ARB_framebuffer_sRGB");
|
||||
_glfw.wgl.EXT_framebuffer_sRGB =
|
||||
extensionSupportedWGL("WGL_EXT_framebuffer_sRGB");
|
||||
_glfw.wgl.ARB_create_context =
|
||||
extensionSupportedWGL("WGL_ARB_create_context");
|
||||
_glfw.wgl.ARB_create_context_profile =
|
||||
extensionSupportedWGL("WGL_ARB_create_context_profile");
|
||||
_glfw.wgl.EXT_create_context_es2_profile =
|
||||
extensionSupportedWGL("WGL_EXT_create_context_es2_profile");
|
||||
_glfw.wgl.ARB_create_context_robustness =
|
||||
extensionSupportedWGL("WGL_ARB_create_context_robustness");
|
||||
_glfw.wgl.ARB_create_context_no_error =
|
||||
extensionSupportedWGL("WGL_ARB_create_context_no_error");
|
||||
_glfw.wgl.EXT_swap_control =
|
||||
extensionSupportedWGL("WGL_EXT_swap_control");
|
||||
_glfw.wgl.EXT_colorspace =
|
||||
extensionSupportedWGL("WGL_EXT_colorspace");
|
||||
_glfw.wgl.ARB_pixel_format =
|
||||
extensionSupportedWGL("WGL_ARB_pixel_format");
|
||||
_glfw.wgl.ARB_context_flush_control =
|
||||
extensionSupportedWGL("WGL_ARB_context_flush_control");
|
||||
|
||||
wglMakeCurrent(pdc, prc);
|
||||
wglDeleteContext(rc);
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Terminate WGL
|
||||
//
|
||||
void _glfwTerminateWGL(void)
|
||||
{
|
||||
if (_glfw.wgl.instance)
|
||||
FreeLibrary(_glfw.wgl.instance);
|
||||
}
|
||||
|
||||
#define setAttrib(a, v) \
|
||||
{ \
|
||||
assert((size_t) (index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
|
||||
attribs[index++] = a; \
|
||||
attribs[index++] = v; \
|
||||
}
|
||||
|
||||
// Create the OpenGL or OpenGL ES context
|
||||
//
|
||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig)
|
||||
{
|
||||
int attribs[40];
|
||||
int pixelFormat;
|
||||
PIXELFORMATDESCRIPTOR pfd;
|
||||
HGLRC share = NULL;
|
||||
|
||||
if (ctxconfig->share)
|
||||
share = ctxconfig->share->context.wgl.handle;
|
||||
|
||||
window->context.wgl.dc = GetDC(window->win32.handle);
|
||||
if (!window->context.wgl.dc)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve DC for window");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
pixelFormat = choosePixelFormat(window, ctxconfig, fbconfig);
|
||||
if (!pixelFormat)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!DescribePixelFormat(window->context.wgl.dc,
|
||||
pixelFormat, sizeof(pfd), &pfd))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to retrieve PFD for selected pixel format");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to set selected pixel format");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (ctxconfig->forward)
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->profile)
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context_profile)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_glfw.wgl.ARB_create_context ||
|
||||
!_glfw.wgl.ARB_create_context_profile ||
|
||||
!_glfw.wgl.EXT_create_context_es2_profile)
|
||||
{
|
||||
_glfwInputError(GLFW_API_UNAVAILABLE,
|
||||
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfw.wgl.ARB_create_context)
|
||||
{
|
||||
int index = 0, mask = 0, flags = 0;
|
||||
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
if (ctxconfig->forward)
|
||||
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
|
||||
|
||||
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
|
||||
mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
|
||||
mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
|
||||
}
|
||||
else
|
||||
mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
|
||||
|
||||
if (ctxconfig->debug)
|
||||
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
|
||||
|
||||
if (ctxconfig->robustness)
|
||||
{
|
||||
if (_glfw.wgl.ARB_create_context_robustness)
|
||||
{
|
||||
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
|
||||
{
|
||||
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
WGL_NO_RESET_NOTIFICATION_ARB);
|
||||
}
|
||||
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
|
||||
{
|
||||
setAttrib(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
|
||||
WGL_LOSE_CONTEXT_ON_RESET_ARB);
|
||||
}
|
||||
|
||||
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->release)
|
||||
{
|
||||
if (_glfw.wgl.ARB_context_flush_control)
|
||||
{
|
||||
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
|
||||
{
|
||||
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
|
||||
}
|
||||
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
|
||||
{
|
||||
setAttrib(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
|
||||
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ctxconfig->noerror)
|
||||
{
|
||||
if (_glfw.wgl.ARB_create_context_no_error)
|
||||
setAttrib(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
|
||||
}
|
||||
|
||||
// NOTE: Only request an explicitly versioned context when necessary, as
|
||||
// explicitly requesting version 1.0 does not always return the
|
||||
// highest version supported by the driver
|
||||
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
|
||||
{
|
||||
setAttrib(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
|
||||
setAttrib(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
|
||||
}
|
||||
|
||||
if (flags)
|
||||
setAttrib(WGL_CONTEXT_FLAGS_ARB, flags);
|
||||
|
||||
if (mask)
|
||||
setAttrib(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
|
||||
|
||||
setAttrib(0, 0);
|
||||
|
||||
window->context.wgl.handle =
|
||||
_glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc,
|
||||
share, attribs);
|
||||
if (!window->context.wgl.handle)
|
||||
{
|
||||
const DWORD error = GetLastError();
|
||||
|
||||
if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
|
||||
{
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Driver does not support OpenGL version %i.%i",
|
||||
ctxconfig->major,
|
||||
ctxconfig->minor);
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Driver does not support OpenGL ES version %i.%i",
|
||||
ctxconfig->major,
|
||||
ctxconfig->minor);
|
||||
}
|
||||
}
|
||||
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Driver does not support the requested OpenGL profile");
|
||||
}
|
||||
else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB))
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE,
|
||||
"WGL: The share context is not compatible with the requested context");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctxconfig->client == GLFW_OPENGL_API)
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Failed to create OpenGL context");
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Failed to create OpenGL ES context");
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
|
||||
if (!window->context.wgl.handle)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
|
||||
"WGL: Failed to create OpenGL context");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (share)
|
||||
{
|
||||
if (!wglShareLists(share, window->context.wgl.handle))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"WGL: Failed to enable sharing with specified OpenGL context");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window->context.makeCurrent = makeContextCurrentWGL;
|
||||
window->context.swapBuffers = swapBuffersWGL;
|
||||
window->context.swapInterval = swapIntervalWGL;
|
||||
window->context.extensionSupported = extensionSupportedWGL;
|
||||
window->context.getProcAddress = getProcAddressWGL;
|
||||
window->context.destroy = destroyContextWGL;
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
#undef setAttrib
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (window->context.client == GLFW_NO_API)
|
||||
{
|
||||
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return window->context.wgl.handle;
|
||||
}
|
||||
|
||||
159
glfw/wgl_context.h
vendored
159
glfw/wgl_context.h
vendored
@@ -1,159 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 WGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
|
||||
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
||||
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
|
||||
#define WGL_PIXEL_TYPE_ARB 0x2013
|
||||
#define WGL_TYPE_RGBA_ARB 0x202b
|
||||
#define WGL_ACCELERATION_ARB 0x2003
|
||||
#define WGL_NO_ACCELERATION_ARB 0x2025
|
||||
#define WGL_RED_BITS_ARB 0x2015
|
||||
#define WGL_RED_SHIFT_ARB 0x2016
|
||||
#define WGL_GREEN_BITS_ARB 0x2017
|
||||
#define WGL_GREEN_SHIFT_ARB 0x2018
|
||||
#define WGL_BLUE_BITS_ARB 0x2019
|
||||
#define WGL_BLUE_SHIFT_ARB 0x201a
|
||||
#define WGL_ALPHA_BITS_ARB 0x201b
|
||||
#define WGL_ALPHA_SHIFT_ARB 0x201c
|
||||
#define WGL_ACCUM_BITS_ARB 0x201d
|
||||
#define WGL_ACCUM_RED_BITS_ARB 0x201e
|
||||
#define WGL_ACCUM_GREEN_BITS_ARB 0x201f
|
||||
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
|
||||
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
|
||||
#define WGL_DEPTH_BITS_ARB 0x2022
|
||||
#define WGL_STENCIL_BITS_ARB 0x2023
|
||||
#define WGL_AUX_BUFFERS_ARB 0x2024
|
||||
#define WGL_STEREO_ARB 0x2012
|
||||
#define WGL_DOUBLE_BUFFER_ARB 0x2011
|
||||
#define WGL_SAMPLES_ARB 0x2042
|
||||
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
|
||||
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
|
||||
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
|
||||
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
|
||||
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
|
||||
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
|
||||
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define WGL_CONTEXT_FLAGS_ARB 0x2094
|
||||
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
|
||||
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
|
||||
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
|
||||
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
|
||||
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
|
||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
|
||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
|
||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
|
||||
#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
|
||||
#define WGL_COLORSPACE_EXT 0x309d
|
||||
#define WGL_COLORSPACE_SRGB_EXT 0x3089
|
||||
|
||||
#define ERROR_INVALID_VERSION_ARB 0x2095
|
||||
#define ERROR_INVALID_PROFILE_ARB 0x2096
|
||||
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
|
||||
|
||||
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
|
||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
|
||||
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
|
||||
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC);
|
||||
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*);
|
||||
|
||||
typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
|
||||
typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
|
||||
typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
|
||||
typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void);
|
||||
typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void);
|
||||
typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
|
||||
typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
|
||||
|
||||
// opengl32.dll function pointer typedefs
|
||||
#define wglCreateContext _glfw.wgl.CreateContext
|
||||
#define wglDeleteContext _glfw.wgl.DeleteContext
|
||||
#define wglGetProcAddress _glfw.wgl.GetProcAddress
|
||||
#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
|
||||
#define wglGetCurrentContext _glfw.wgl.GetCurrentContext
|
||||
#define wglMakeCurrent _glfw.wgl.MakeCurrent
|
||||
#define wglShareLists _glfw.wgl.ShareLists
|
||||
|
||||
#define _GLFW_RECREATION_NOT_NEEDED 0
|
||||
#define _GLFW_RECREATION_REQUIRED 1
|
||||
#define _GLFW_RECREATION_IMPOSSIBLE 2
|
||||
|
||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl
|
||||
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl
|
||||
|
||||
|
||||
// WGL-specific per-context data
|
||||
//
|
||||
typedef struct _GLFWcontextWGL
|
||||
{
|
||||
HDC dc;
|
||||
HGLRC handle;
|
||||
int interval;
|
||||
|
||||
} _GLFWcontextWGL;
|
||||
|
||||
// WGL-specific global data
|
||||
//
|
||||
typedef struct _GLFWlibraryWGL
|
||||
{
|
||||
HINSTANCE instance;
|
||||
PFN_wglCreateContext CreateContext;
|
||||
PFN_wglDeleteContext DeleteContext;
|
||||
PFN_wglGetProcAddress GetProcAddress;
|
||||
PFN_wglGetCurrentDC GetCurrentDC;
|
||||
PFN_wglGetCurrentContext GetCurrentContext;
|
||||
PFN_wglMakeCurrent MakeCurrent;
|
||||
PFN_wglShareLists ShareLists;
|
||||
|
||||
PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
|
||||
PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;
|
||||
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
|
||||
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
|
||||
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
|
||||
GLFWbool EXT_swap_control;
|
||||
GLFWbool EXT_colorspace;
|
||||
GLFWbool ARB_multisample;
|
||||
GLFWbool ARB_framebuffer_sRGB;
|
||||
GLFWbool EXT_framebuffer_sRGB;
|
||||
GLFWbool ARB_pixel_format;
|
||||
GLFWbool ARB_create_context;
|
||||
GLFWbool ARB_create_context_profile;
|
||||
GLFWbool EXT_create_context_es2_profile;
|
||||
GLFWbool ARB_create_context_robustness;
|
||||
GLFWbool ARB_create_context_no_error;
|
||||
GLFWbool ARB_context_flush_control;
|
||||
|
||||
} _GLFWlibraryWGL;
|
||||
|
||||
|
||||
GLFWbool _glfwInitWGL(void);
|
||||
void _glfwTerminateWGL(void);
|
||||
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
|
||||
const _GLFWctxconfig* ctxconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
||||
627
glfw/win32_init.c
vendored
627
glfw/win32_init.c
vendored
@@ -1,627 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
|
||||
static const GUID _glfw_GUID_DEVINTERFACE_HID =
|
||||
{0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
|
||||
|
||||
#define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID
|
||||
|
||||
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
|
||||
|
||||
// Executables (but not DLLs) exporting this symbol with this value will be
|
||||
// automatically directed to the high-performance GPU on Nvidia Optimus systems
|
||||
// with up-to-date drivers
|
||||
//
|
||||
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
|
||||
|
||||
// Executables (but not DLLs) exporting this symbol with this value will be
|
||||
// automatically directed to the high-performance GPU on AMD PowerXpress systems
|
||||
// with up-to-date drivers
|
||||
//
|
||||
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
|
||||
|
||||
#endif // _GLFW_USE_HYBRID_HPG
|
||||
|
||||
#if defined(_GLFW_BUILD_DLL)
|
||||
|
||||
// GLFW DLL entry point
|
||||
//
|
||||
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif // _GLFW_BUILD_DLL
|
||||
|
||||
// Load necessary libraries (DLLs)
|
||||
//
|
||||
static GLFWbool loadLibraries(void)
|
||||
{
|
||||
_glfw.win32.winmm.instance = LoadLibraryA("winmm.dll");
|
||||
if (!_glfw.win32.winmm.instance)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to load winmm.dll");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.win32.winmm.GetTime = (PFN_timeGetTime)
|
||||
GetProcAddress(_glfw.win32.winmm.instance, "timeGetTime");
|
||||
|
||||
_glfw.win32.user32.instance = LoadLibraryA("user32.dll");
|
||||
if (!_glfw.win32.user32.instance)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to load user32.dll");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
|
||||
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
|
||||
_glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
|
||||
_glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext");
|
||||
_glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "GetDpiForWindow");
|
||||
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
|
||||
|
||||
_glfw.win32.dinput8.instance = LoadLibraryA("dinput8.dll");
|
||||
if (_glfw.win32.dinput8.instance)
|
||||
{
|
||||
_glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
|
||||
GetProcAddress(_glfw.win32.dinput8.instance, "DirectInput8Create");
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
const char* names[] =
|
||||
{
|
||||
"xinput1_4.dll",
|
||||
"xinput1_3.dll",
|
||||
"xinput9_1_0.dll",
|
||||
"xinput1_2.dll",
|
||||
"xinput1_1.dll",
|
||||
NULL
|
||||
};
|
||||
|
||||
for (i = 0; names[i]; i++)
|
||||
{
|
||||
_glfw.win32.xinput.instance = LoadLibraryA(names[i]);
|
||||
if (_glfw.win32.xinput.instance)
|
||||
{
|
||||
_glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
|
||||
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetCapabilities");
|
||||
_glfw.win32.xinput.GetState = (PFN_XInputGetState)
|
||||
GetProcAddress(_glfw.win32.xinput.instance, "XInputGetState");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_glfw.win32.dwmapi.instance = LoadLibraryA("dwmapi.dll");
|
||||
if (_glfw.win32.dwmapi.instance)
|
||||
{
|
||||
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
|
||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
|
||||
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
|
||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmFlush");
|
||||
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
|
||||
GetProcAddress(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
|
||||
}
|
||||
|
||||
_glfw.win32.shcore.instance = LoadLibraryA("shcore.dll");
|
||||
if (_glfw.win32.shcore.instance)
|
||||
{
|
||||
_glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
|
||||
GetProcAddress(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
|
||||
_glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor)
|
||||
GetProcAddress(_glfw.win32.shcore.instance, "GetDpiForMonitor");
|
||||
}
|
||||
|
||||
_glfw.win32.ntdll.instance = LoadLibraryA("ntdll.dll");
|
||||
if (_glfw.win32.ntdll.instance)
|
||||
{
|
||||
_glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
|
||||
GetProcAddress(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Unload used libraries (DLLs)
|
||||
//
|
||||
static void freeLibraries(void)
|
||||
{
|
||||
if (_glfw.win32.xinput.instance)
|
||||
FreeLibrary(_glfw.win32.xinput.instance);
|
||||
|
||||
if (_glfw.win32.dinput8.instance)
|
||||
FreeLibrary(_glfw.win32.dinput8.instance);
|
||||
|
||||
if (_glfw.win32.winmm.instance)
|
||||
FreeLibrary(_glfw.win32.winmm.instance);
|
||||
|
||||
if (_glfw.win32.user32.instance)
|
||||
FreeLibrary(_glfw.win32.user32.instance);
|
||||
|
||||
if (_glfw.win32.dwmapi.instance)
|
||||
FreeLibrary(_glfw.win32.dwmapi.instance);
|
||||
|
||||
if (_glfw.win32.shcore.instance)
|
||||
FreeLibrary(_glfw.win32.shcore.instance);
|
||||
|
||||
if (_glfw.win32.ntdll.instance)
|
||||
FreeLibrary(_glfw.win32.ntdll.instance);
|
||||
}
|
||||
|
||||
// Create key code translation tables
|
||||
//
|
||||
static void createKeyTables(void)
|
||||
{
|
||||
int scancode;
|
||||
|
||||
memset(_glfw.win32.keycodes, -1, sizeof(_glfw.win32.keycodes));
|
||||
memset(_glfw.win32.scancodes, -1, sizeof(_glfw.win32.scancodes));
|
||||
|
||||
_glfw.win32.keycodes[0x00B] = GLFW_KEY_0;
|
||||
_glfw.win32.keycodes[0x002] = GLFW_KEY_1;
|
||||
_glfw.win32.keycodes[0x003] = GLFW_KEY_2;
|
||||
_glfw.win32.keycodes[0x004] = GLFW_KEY_3;
|
||||
_glfw.win32.keycodes[0x005] = GLFW_KEY_4;
|
||||
_glfw.win32.keycodes[0x006] = GLFW_KEY_5;
|
||||
_glfw.win32.keycodes[0x007] = GLFW_KEY_6;
|
||||
_glfw.win32.keycodes[0x008] = GLFW_KEY_7;
|
||||
_glfw.win32.keycodes[0x009] = GLFW_KEY_8;
|
||||
_glfw.win32.keycodes[0x00A] = GLFW_KEY_9;
|
||||
_glfw.win32.keycodes[0x01E] = GLFW_KEY_A;
|
||||
_glfw.win32.keycodes[0x030] = GLFW_KEY_B;
|
||||
_glfw.win32.keycodes[0x02E] = GLFW_KEY_C;
|
||||
_glfw.win32.keycodes[0x020] = GLFW_KEY_D;
|
||||
_glfw.win32.keycodes[0x012] = GLFW_KEY_E;
|
||||
_glfw.win32.keycodes[0x021] = GLFW_KEY_F;
|
||||
_glfw.win32.keycodes[0x022] = GLFW_KEY_G;
|
||||
_glfw.win32.keycodes[0x023] = GLFW_KEY_H;
|
||||
_glfw.win32.keycodes[0x017] = GLFW_KEY_I;
|
||||
_glfw.win32.keycodes[0x024] = GLFW_KEY_J;
|
||||
_glfw.win32.keycodes[0x025] = GLFW_KEY_K;
|
||||
_glfw.win32.keycodes[0x026] = GLFW_KEY_L;
|
||||
_glfw.win32.keycodes[0x032] = GLFW_KEY_M;
|
||||
_glfw.win32.keycodes[0x031] = GLFW_KEY_N;
|
||||
_glfw.win32.keycodes[0x018] = GLFW_KEY_O;
|
||||
_glfw.win32.keycodes[0x019] = GLFW_KEY_P;
|
||||
_glfw.win32.keycodes[0x010] = GLFW_KEY_Q;
|
||||
_glfw.win32.keycodes[0x013] = GLFW_KEY_R;
|
||||
_glfw.win32.keycodes[0x01F] = GLFW_KEY_S;
|
||||
_glfw.win32.keycodes[0x014] = GLFW_KEY_T;
|
||||
_glfw.win32.keycodes[0x016] = GLFW_KEY_U;
|
||||
_glfw.win32.keycodes[0x02F] = GLFW_KEY_V;
|
||||
_glfw.win32.keycodes[0x011] = GLFW_KEY_W;
|
||||
_glfw.win32.keycodes[0x02D] = GLFW_KEY_X;
|
||||
_glfw.win32.keycodes[0x015] = GLFW_KEY_Y;
|
||||
_glfw.win32.keycodes[0x02C] = GLFW_KEY_Z;
|
||||
|
||||
_glfw.win32.keycodes[0x028] = GLFW_KEY_APOSTROPHE;
|
||||
_glfw.win32.keycodes[0x02B] = GLFW_KEY_BACKSLASH;
|
||||
_glfw.win32.keycodes[0x033] = GLFW_KEY_COMMA;
|
||||
_glfw.win32.keycodes[0x00D] = GLFW_KEY_EQUAL;
|
||||
_glfw.win32.keycodes[0x029] = GLFW_KEY_GRAVE_ACCENT;
|
||||
_glfw.win32.keycodes[0x01A] = GLFW_KEY_LEFT_BRACKET;
|
||||
_glfw.win32.keycodes[0x00C] = GLFW_KEY_MINUS;
|
||||
_glfw.win32.keycodes[0x034] = GLFW_KEY_PERIOD;
|
||||
_glfw.win32.keycodes[0x01B] = GLFW_KEY_RIGHT_BRACKET;
|
||||
_glfw.win32.keycodes[0x027] = GLFW_KEY_SEMICOLON;
|
||||
_glfw.win32.keycodes[0x035] = GLFW_KEY_SLASH;
|
||||
_glfw.win32.keycodes[0x056] = GLFW_KEY_WORLD_2;
|
||||
|
||||
_glfw.win32.keycodes[0x00E] = GLFW_KEY_BACKSPACE;
|
||||
_glfw.win32.keycodes[0x153] = GLFW_KEY_DELETE;
|
||||
_glfw.win32.keycodes[0x14F] = GLFW_KEY_END;
|
||||
_glfw.win32.keycodes[0x01C] = GLFW_KEY_ENTER;
|
||||
_glfw.win32.keycodes[0x001] = GLFW_KEY_ESCAPE;
|
||||
_glfw.win32.keycodes[0x147] = GLFW_KEY_HOME;
|
||||
_glfw.win32.keycodes[0x152] = GLFW_KEY_INSERT;
|
||||
_glfw.win32.keycodes[0x15D] = GLFW_KEY_MENU;
|
||||
_glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
|
||||
_glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
|
||||
_glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
|
||||
_glfw.win32.keycodes[0x146] = GLFW_KEY_PAUSE;
|
||||
_glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
|
||||
_glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
|
||||
_glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
|
||||
_glfw.win32.keycodes[0x145] = GLFW_KEY_NUM_LOCK;
|
||||
_glfw.win32.keycodes[0x046] = GLFW_KEY_SCROLL_LOCK;
|
||||
_glfw.win32.keycodes[0x03B] = GLFW_KEY_F1;
|
||||
_glfw.win32.keycodes[0x03C] = GLFW_KEY_F2;
|
||||
_glfw.win32.keycodes[0x03D] = GLFW_KEY_F3;
|
||||
_glfw.win32.keycodes[0x03E] = GLFW_KEY_F4;
|
||||
_glfw.win32.keycodes[0x03F] = GLFW_KEY_F5;
|
||||
_glfw.win32.keycodes[0x040] = GLFW_KEY_F6;
|
||||
_glfw.win32.keycodes[0x041] = GLFW_KEY_F7;
|
||||
_glfw.win32.keycodes[0x042] = GLFW_KEY_F8;
|
||||
_glfw.win32.keycodes[0x043] = GLFW_KEY_F9;
|
||||
_glfw.win32.keycodes[0x044] = GLFW_KEY_F10;
|
||||
_glfw.win32.keycodes[0x057] = GLFW_KEY_F11;
|
||||
_glfw.win32.keycodes[0x058] = GLFW_KEY_F12;
|
||||
_glfw.win32.keycodes[0x064] = GLFW_KEY_F13;
|
||||
_glfw.win32.keycodes[0x065] = GLFW_KEY_F14;
|
||||
_glfw.win32.keycodes[0x066] = GLFW_KEY_F15;
|
||||
_glfw.win32.keycodes[0x067] = GLFW_KEY_F16;
|
||||
_glfw.win32.keycodes[0x068] = GLFW_KEY_F17;
|
||||
_glfw.win32.keycodes[0x069] = GLFW_KEY_F18;
|
||||
_glfw.win32.keycodes[0x06A] = GLFW_KEY_F19;
|
||||
_glfw.win32.keycodes[0x06B] = GLFW_KEY_F20;
|
||||
_glfw.win32.keycodes[0x06C] = GLFW_KEY_F21;
|
||||
_glfw.win32.keycodes[0x06D] = GLFW_KEY_F22;
|
||||
_glfw.win32.keycodes[0x06E] = GLFW_KEY_F23;
|
||||
_glfw.win32.keycodes[0x076] = GLFW_KEY_F24;
|
||||
_glfw.win32.keycodes[0x038] = GLFW_KEY_LEFT_ALT;
|
||||
_glfw.win32.keycodes[0x01D] = GLFW_KEY_LEFT_CONTROL;
|
||||
_glfw.win32.keycodes[0x02A] = GLFW_KEY_LEFT_SHIFT;
|
||||
_glfw.win32.keycodes[0x15B] = GLFW_KEY_LEFT_SUPER;
|
||||
_glfw.win32.keycodes[0x137] = GLFW_KEY_PRINT_SCREEN;
|
||||
_glfw.win32.keycodes[0x138] = GLFW_KEY_RIGHT_ALT;
|
||||
_glfw.win32.keycodes[0x11D] = GLFW_KEY_RIGHT_CONTROL;
|
||||
_glfw.win32.keycodes[0x036] = GLFW_KEY_RIGHT_SHIFT;
|
||||
_glfw.win32.keycodes[0x15C] = GLFW_KEY_RIGHT_SUPER;
|
||||
_glfw.win32.keycodes[0x150] = GLFW_KEY_DOWN;
|
||||
_glfw.win32.keycodes[0x14B] = GLFW_KEY_LEFT;
|
||||
_glfw.win32.keycodes[0x14D] = GLFW_KEY_RIGHT;
|
||||
_glfw.win32.keycodes[0x148] = GLFW_KEY_UP;
|
||||
|
||||
_glfw.win32.keycodes[0x052] = GLFW_KEY_KP_0;
|
||||
_glfw.win32.keycodes[0x04F] = GLFW_KEY_KP_1;
|
||||
_glfw.win32.keycodes[0x050] = GLFW_KEY_KP_2;
|
||||
_glfw.win32.keycodes[0x051] = GLFW_KEY_KP_3;
|
||||
_glfw.win32.keycodes[0x04B] = GLFW_KEY_KP_4;
|
||||
_glfw.win32.keycodes[0x04C] = GLFW_KEY_KP_5;
|
||||
_glfw.win32.keycodes[0x04D] = GLFW_KEY_KP_6;
|
||||
_glfw.win32.keycodes[0x047] = GLFW_KEY_KP_7;
|
||||
_glfw.win32.keycodes[0x048] = GLFW_KEY_KP_8;
|
||||
_glfw.win32.keycodes[0x049] = GLFW_KEY_KP_9;
|
||||
_glfw.win32.keycodes[0x04E] = GLFW_KEY_KP_ADD;
|
||||
_glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL;
|
||||
_glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE;
|
||||
_glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER;
|
||||
_glfw.win32.keycodes[0x059] = GLFW_KEY_KP_EQUAL;
|
||||
_glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY;
|
||||
_glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT;
|
||||
|
||||
for (scancode = 0; scancode < 512; scancode++)
|
||||
{
|
||||
if (_glfw.win32.keycodes[scancode] > 0)
|
||||
_glfw.win32.scancodes[_glfw.win32.keycodes[scancode]] = scancode;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a dummy window for behind-the-scenes work
|
||||
//
|
||||
static HWND createHelperWindow(void)
|
||||
{
|
||||
MSG msg;
|
||||
HWND window = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
|
||||
_GLFW_WNDCLASSNAME,
|
||||
L"GLFW message window",
|
||||
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
|
||||
0, 0, 1, 1,
|
||||
NULL, NULL,
|
||||
GetModuleHandleW(NULL),
|
||||
NULL);
|
||||
if (!window)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to create helper window");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// HACK: The command to the first ShowWindow call is ignored if the parent
|
||||
// process passed along a STARTUPINFO, so clear that with a no-op call
|
||||
ShowWindow(window, SW_HIDE);
|
||||
|
||||
// Register for HID device notifications
|
||||
{
|
||||
DEV_BROADCAST_DEVICEINTERFACE_W dbi;
|
||||
ZeroMemory(&dbi, sizeof(dbi));
|
||||
dbi.dbcc_size = sizeof(dbi);
|
||||
dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
dbi.dbcc_classguid = GUID_DEVINTERFACE_HID;
|
||||
|
||||
_glfw.win32.deviceNotificationHandle =
|
||||
RegisterDeviceNotificationW(window,
|
||||
(DEV_BROADCAST_HDR*) &dbi,
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
}
|
||||
|
||||
while (PeekMessageW(&msg, _glfw.win32.helperWindowHandle, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageW(&msg);
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Returns a wide string version of the specified UTF-8 string
|
||||
//
|
||||
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
|
||||
{
|
||||
WCHAR* target;
|
||||
int count;
|
||||
|
||||
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
|
||||
if (!count)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to convert string from UTF-8");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target = calloc(count, sizeof(WCHAR));
|
||||
|
||||
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to convert string from UTF-8");
|
||||
free(target);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
// Returns a UTF-8 string version of the specified wide string
|
||||
//
|
||||
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
|
||||
{
|
||||
char* target;
|
||||
int size;
|
||||
|
||||
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
|
||||
if (!size)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to convert string to UTF-8");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
target = calloc(size, 1);
|
||||
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to convert string to UTF-8");
|
||||
free(target);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
// Reports the specified error, appending information about the last Win32 error
|
||||
//
|
||||
void _glfwInputErrorWin32(int error, const char* description)
|
||||
{
|
||||
WCHAR buffer[_GLFW_MESSAGE_SIZE] = L"";
|
||||
char message[_GLFW_MESSAGE_SIZE] = "";
|
||||
|
||||
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||
FORMAT_MESSAGE_MAX_WIDTH_MASK,
|
||||
NULL,
|
||||
GetLastError() & 0xffff,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
NULL);
|
||||
WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL);
|
||||
|
||||
_glfwInputError(error, "%s: %s", description, message);
|
||||
}
|
||||
|
||||
// Updates key names according to the current keyboard layout
|
||||
//
|
||||
void _glfwUpdateKeyNamesWin32(void)
|
||||
{
|
||||
int key;
|
||||
BYTE state[256] = {0};
|
||||
|
||||
memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
|
||||
|
||||
for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++)
|
||||
{
|
||||
UINT vk;
|
||||
int scancode, length;
|
||||
WCHAR chars[16];
|
||||
|
||||
scancode = _glfw.win32.scancodes[key];
|
||||
if (scancode == -1)
|
||||
continue;
|
||||
|
||||
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
|
||||
{
|
||||
const UINT vks[] = {
|
||||
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
|
||||
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
|
||||
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
|
||||
VK_MULTIPLY, VK_SUBTRACT, VK_ADD
|
||||
};
|
||||
|
||||
vk = vks[key - GLFW_KEY_KP_0];
|
||||
}
|
||||
else
|
||||
vk = MapVirtualKey(scancode, MAPVK_VSC_TO_VK);
|
||||
|
||||
length = ToUnicode(vk, scancode, state,
|
||||
chars, sizeof(chars) / sizeof(WCHAR),
|
||||
0);
|
||||
|
||||
if (length == -1)
|
||||
{
|
||||
length = ToUnicode(vk, scancode, state,
|
||||
chars, sizeof(chars) / sizeof(WCHAR),
|
||||
0);
|
||||
}
|
||||
|
||||
if (length < 1)
|
||||
continue;
|
||||
|
||||
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
|
||||
_glfw.win32.keynames[key],
|
||||
sizeof(_glfw.win32.keynames[key]),
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
// Replacement for IsWindowsVersionOrGreater as MinGW lacks versionhelpers.h
|
||||
//
|
||||
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
|
||||
{
|
||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
|
||||
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
|
||||
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
||||
// latter lies unless the user knew to embedd a non-default manifest
|
||||
// announcing support for Windows 10 via supportedOS GUID
|
||||
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
||||
}
|
||||
|
||||
// Checks whether we are on at least the specified build of Windows 10
|
||||
//
|
||||
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build)
|
||||
{
|
||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), 10, 0, build };
|
||||
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER;
|
||||
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
|
||||
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
|
||||
// latter lies unless the user knew to embedd a non-default manifest
|
||||
// announcing support for Windows 10 via supportedOS GUID
|
||||
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformInit(void)
|
||||
{
|
||||
// To make SetForegroundWindow work as we want, we need to fiddle
|
||||
// with the FOREGROUNDLOCKTIMEOUT system setting (we do this as early
|
||||
// as possible in the hope of still being the foreground process)
|
||||
SystemParametersInfoW(SPI_GETFOREGROUNDLOCKTIMEOUT, 0,
|
||||
&_glfw.win32.foregroundLockTimeout, 0);
|
||||
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, UIntToPtr(0),
|
||||
SPIF_SENDCHANGE);
|
||||
|
||||
if (!loadLibraries())
|
||||
return GLFW_FALSE;
|
||||
|
||||
createKeyTables();
|
||||
_glfwUpdateKeyNamesWin32();
|
||||
|
||||
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32())
|
||||
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||
else if (IsWindows8Point1OrGreater())
|
||||
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
else if (IsWindowsVistaOrGreater())
|
||||
SetProcessDPIAware();
|
||||
|
||||
if (!_glfwRegisterWindowClassWin32())
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfw.win32.helperWindowHandle = createHelperWindow();
|
||||
if (!_glfw.win32.helperWindowHandle)
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfwInitTimerWin32();
|
||||
_glfwInitJoysticksWin32();
|
||||
|
||||
_glfwPollMonitorsWin32();
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
{
|
||||
if (_glfw.win32.deviceNotificationHandle)
|
||||
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
|
||||
|
||||
if (_glfw.win32.helperWindowHandle)
|
||||
DestroyWindow(_glfw.win32.helperWindowHandle);
|
||||
|
||||
_glfwUnregisterWindowClassWin32();
|
||||
|
||||
// Restore previous foreground lock timeout system setting
|
||||
SystemParametersInfoW(SPI_SETFOREGROUNDLOCKTIMEOUT, 0,
|
||||
UIntToPtr(_glfw.win32.foregroundLockTimeout),
|
||||
SPIF_SENDCHANGE);
|
||||
|
||||
free(_glfw.win32.clipboardString);
|
||||
free(_glfw.win32.rawInput);
|
||||
|
||||
_glfwTerminateWGL();
|
||||
_glfwTerminateEGL();
|
||||
|
||||
_glfwTerminateJoysticksWin32();
|
||||
|
||||
freeLibraries();
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
{
|
||||
return _GLFW_VERSION_NUMBER " Win32 WGL EGL"
|
||||
#if defined(__MINGW32__)
|
||||
" MinGW"
|
||||
#elif defined(_MSC_VER)
|
||||
" VisualC"
|
||||
#endif
|
||||
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
|
||||
" hybrid-GPU"
|
||||
#endif
|
||||
#if defined(_GLFW_BUILD_DLL)
|
||||
" DLL"
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
751
glfw/win32_joystick.c
vendored
751
glfw/win32_joystick.c
vendored
@@ -1,751 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define _GLFW_TYPE_AXIS 0
|
||||
#define _GLFW_TYPE_SLIDER 1
|
||||
#define _GLFW_TYPE_BUTTON 2
|
||||
#define _GLFW_TYPE_POV 3
|
||||
|
||||
// Data produced with DirectInput device object enumeration
|
||||
//
|
||||
typedef struct _GLFWobjenumWin32
|
||||
{
|
||||
IDirectInputDevice8W* device;
|
||||
_GLFWjoyobjectWin32* objects;
|
||||
int objectCount;
|
||||
int axisCount;
|
||||
int sliderCount;
|
||||
int buttonCount;
|
||||
int povCount;
|
||||
} _GLFWobjenumWin32;
|
||||
|
||||
// Define local copies of the necessary GUIDs
|
||||
//
|
||||
static const GUID _glfw_IID_IDirectInput8W =
|
||||
{0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
|
||||
static const GUID _glfw_GUID_XAxis =
|
||||
{0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||
static const GUID _glfw_GUID_YAxis =
|
||||
{0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||
static const GUID _glfw_GUID_ZAxis =
|
||||
{0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||
static const GUID _glfw_GUID_RxAxis =
|
||||
{0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||
static const GUID _glfw_GUID_RyAxis =
|
||||
{0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||
static const GUID _glfw_GUID_RzAxis =
|
||||
{0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||
static const GUID _glfw_GUID_Slider =
|
||||
{0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||
static const GUID _glfw_GUID_POV =
|
||||
{0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
|
||||
|
||||
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
|
||||
#define GUID_XAxis _glfw_GUID_XAxis
|
||||
#define GUID_YAxis _glfw_GUID_YAxis
|
||||
#define GUID_ZAxis _glfw_GUID_ZAxis
|
||||
#define GUID_RxAxis _glfw_GUID_RxAxis
|
||||
#define GUID_RyAxis _glfw_GUID_RyAxis
|
||||
#define GUID_RzAxis _glfw_GUID_RzAxis
|
||||
#define GUID_Slider _glfw_GUID_Slider
|
||||
#define GUID_POV _glfw_GUID_POV
|
||||
|
||||
// Object data array for our clone of c_dfDIJoystick
|
||||
// Generated with https://github.com/elmindreda/c_dfDIJoystick2
|
||||
//
|
||||
static DIOBJECTDATAFORMAT _glfwObjectDataFormats[] =
|
||||
{
|
||||
{ &GUID_XAxis,DIJOFS_X,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||
{ &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||
{ &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||
{ &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||
{ &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||
{ &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||
{ &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||
{ &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
|
||||
{ &GUID_POV,DIJOFS_POV(0),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ &GUID_POV,DIJOFS_POV(1),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ &GUID_POV,DIJOFS_POV(2),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ &GUID_POV,DIJOFS_POV(3),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
{ NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
|
||||
};
|
||||
|
||||
// Our clone of c_dfDIJoystick
|
||||
//
|
||||
static const DIDATAFORMAT _glfwDataFormat =
|
||||
{
|
||||
sizeof(DIDATAFORMAT),
|
||||
sizeof(DIOBJECTDATAFORMAT),
|
||||
DIDFT_ABSAXIS,
|
||||
sizeof(DIJOYSTATE),
|
||||
sizeof(_glfwObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT),
|
||||
_glfwObjectDataFormats
|
||||
};
|
||||
|
||||
// Returns a description fitting the specified XInput capabilities
|
||||
//
|
||||
static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic)
|
||||
{
|
||||
switch (xic->SubType)
|
||||
{
|
||||
case XINPUT_DEVSUBTYPE_WHEEL:
|
||||
return "XInput Wheel";
|
||||
case XINPUT_DEVSUBTYPE_ARCADE_STICK:
|
||||
return "XInput Arcade Stick";
|
||||
case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
|
||||
return "XInput Flight Stick";
|
||||
case XINPUT_DEVSUBTYPE_DANCE_PAD:
|
||||
return "XInput Dance Pad";
|
||||
case XINPUT_DEVSUBTYPE_GUITAR:
|
||||
return "XInput Guitar";
|
||||
case XINPUT_DEVSUBTYPE_DRUM_KIT:
|
||||
return "XInput Drum Kit";
|
||||
case XINPUT_DEVSUBTYPE_GAMEPAD:
|
||||
{
|
||||
if (xic->Flags & XINPUT_CAPS_WIRELESS)
|
||||
return "Wireless Xbox Controller";
|
||||
else
|
||||
return "Xbox Controller";
|
||||
}
|
||||
}
|
||||
|
||||
return "Unknown XInput Device";
|
||||
}
|
||||
|
||||
// Lexically compare device objects
|
||||
//
|
||||
static int compareJoystickObjects(const void* first, const void* second)
|
||||
{
|
||||
const _GLFWjoyobjectWin32* fo = first;
|
||||
const _GLFWjoyobjectWin32* so = second;
|
||||
|
||||
if (fo->type != so->type)
|
||||
return fo->type - so->type;
|
||||
|
||||
return fo->offset - so->offset;
|
||||
}
|
||||
|
||||
// Checks whether the specified device supports XInput
|
||||
// Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom
|
||||
//
|
||||
static GLFWbool supportsXInput(const GUID* guid)
|
||||
{
|
||||
UINT i, count = 0;
|
||||
RAWINPUTDEVICELIST* ridl;
|
||||
GLFWbool result = GLFW_FALSE;
|
||||
|
||||
if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)
|
||||
return GLFW_FALSE;
|
||||
|
||||
ridl = calloc(count, sizeof(RAWINPUTDEVICELIST));
|
||||
|
||||
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
|
||||
{
|
||||
free(ridl);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
RID_DEVICE_INFO rdi;
|
||||
char name[256];
|
||||
UINT size;
|
||||
|
||||
if (ridl[i].dwType != RIM_TYPEHID)
|
||||
continue;
|
||||
|
||||
ZeroMemory(&rdi, sizeof(rdi));
|
||||
rdi.cbSize = sizeof(rdi);
|
||||
size = sizeof(rdi);
|
||||
|
||||
if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
|
||||
RIDI_DEVICEINFO,
|
||||
&rdi, &size) == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
|
||||
continue;
|
||||
|
||||
memset(name, 0, sizeof(name));
|
||||
size = sizeof(name);
|
||||
|
||||
if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
|
||||
RIDI_DEVICENAME,
|
||||
name, &size) == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
name[sizeof(name) - 1] = '\0';
|
||||
if (strstr(name, "IG_"))
|
||||
{
|
||||
result = GLFW_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(ridl);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Frees all resources associated with the specified joystick
|
||||
//
|
||||
static void closeJoystick(_GLFWjoystick* js)
|
||||
{
|
||||
if (js->win32.device)
|
||||
{
|
||||
IDirectInputDevice8_Unacquire(js->win32.device);
|
||||
IDirectInputDevice8_Release(js->win32.device);
|
||||
}
|
||||
|
||||
_glfwFreeJoystick(js);
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
}
|
||||
|
||||
// DirectInput device object enumeration callback
|
||||
// Insights gleaned from SDL
|
||||
//
|
||||
static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,
|
||||
void* user)
|
||||
{
|
||||
_GLFWobjenumWin32* data = user;
|
||||
_GLFWjoyobjectWin32* object = data->objects + data->objectCount;
|
||||
|
||||
if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS)
|
||||
{
|
||||
DIPROPRANGE dipr;
|
||||
|
||||
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
|
||||
object->offset = DIJOFS_SLIDER(data->sliderCount);
|
||||
else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0)
|
||||
object->offset = DIJOFS_X;
|
||||
else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0)
|
||||
object->offset = DIJOFS_Y;
|
||||
else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0)
|
||||
object->offset = DIJOFS_Z;
|
||||
else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0)
|
||||
object->offset = DIJOFS_RX;
|
||||
else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0)
|
||||
object->offset = DIJOFS_RY;
|
||||
else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0)
|
||||
object->offset = DIJOFS_RZ;
|
||||
else
|
||||
return DIENUM_CONTINUE;
|
||||
|
||||
ZeroMemory(&dipr, sizeof(dipr));
|
||||
dipr.diph.dwSize = sizeof(dipr);
|
||||
dipr.diph.dwHeaderSize = sizeof(dipr.diph);
|
||||
dipr.diph.dwObj = doi->dwType;
|
||||
dipr.diph.dwHow = DIPH_BYID;
|
||||
dipr.lMin = -32768;
|
||||
dipr.lMax = 32767;
|
||||
|
||||
if (FAILED(IDirectInputDevice8_SetProperty(data->device,
|
||||
DIPROP_RANGE,
|
||||
&dipr.diph)))
|
||||
{
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
|
||||
{
|
||||
object->type = _GLFW_TYPE_SLIDER;
|
||||
data->sliderCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
object->type = _GLFW_TYPE_AXIS;
|
||||
data->axisCount++;
|
||||
}
|
||||
}
|
||||
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON)
|
||||
{
|
||||
object->offset = DIJOFS_BUTTON(data->buttonCount);
|
||||
object->type = _GLFW_TYPE_BUTTON;
|
||||
data->buttonCount++;
|
||||
}
|
||||
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV)
|
||||
{
|
||||
object->offset = DIJOFS_POV(data->povCount);
|
||||
object->type = _GLFW_TYPE_POV;
|
||||
data->povCount++;
|
||||
}
|
||||
|
||||
data->objectCount++;
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
// DirectInput device enumeration callback
|
||||
//
|
||||
static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
|
||||
{
|
||||
int jid = 0;
|
||||
DIDEVCAPS dc;
|
||||
DIPROPDWORD dipd;
|
||||
IDirectInputDevice8* device;
|
||||
_GLFWobjenumWin32 data;
|
||||
_GLFWjoystick* js;
|
||||
char guid[33];
|
||||
char name[256];
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->present)
|
||||
{
|
||||
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (supportsXInput(&di->guidProduct))
|
||||
return DIENUM_CONTINUE;
|
||||
|
||||
if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api,
|
||||
&di->guidInstance,
|
||||
&device,
|
||||
NULL)))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create device");
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat)))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to set device data format");
|
||||
|
||||
IDirectInputDevice8_Release(device);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
ZeroMemory(&dc, sizeof(dc));
|
||||
dc.dwSize = sizeof(dc);
|
||||
|
||||
if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc)))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to query device capabilities");
|
||||
|
||||
IDirectInputDevice8_Release(device);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
ZeroMemory(&dipd, sizeof(dipd));
|
||||
dipd.diph.dwSize = sizeof(dipd);
|
||||
dipd.diph.dwHeaderSize = sizeof(dipd.diph);
|
||||
dipd.diph.dwHow = DIPH_DEVICE;
|
||||
dipd.dwData = DIPROPAXISMODE_ABS;
|
||||
|
||||
if (FAILED(IDirectInputDevice8_SetProperty(device,
|
||||
DIPROP_AXISMODE,
|
||||
&dipd.diph)))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to set device axis mode");
|
||||
|
||||
IDirectInputDevice8_Release(device);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.device = device;
|
||||
data.objects = calloc(dc.dwAxes + dc.dwButtons + dc.dwPOVs,
|
||||
sizeof(_GLFWjoyobjectWin32));
|
||||
|
||||
if (FAILED(IDirectInputDevice8_EnumObjects(device,
|
||||
deviceObjectCallback,
|
||||
&data,
|
||||
DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to enumerate device objects");
|
||||
|
||||
IDirectInputDevice8_Release(device);
|
||||
free(data.objects);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
qsort(data.objects, data.objectCount,
|
||||
sizeof(_GLFWjoyobjectWin32),
|
||||
compareJoystickObjects);
|
||||
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0,
|
||||
di->tszInstanceName, -1,
|
||||
name, sizeof(name),
|
||||
NULL, NULL))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to convert joystick name to UTF-8");
|
||||
|
||||
IDirectInputDevice8_Release(device);
|
||||
free(data.objects);
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||
if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
|
||||
{
|
||||
sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
|
||||
(uint8_t) di->guidProduct.Data1,
|
||||
(uint8_t) (di->guidProduct.Data1 >> 8),
|
||||
(uint8_t) (di->guidProduct.Data1 >> 16),
|
||||
(uint8_t) (di->guidProduct.Data1 >> 24));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
||||
name[0], name[1], name[2], name[3],
|
||||
name[4], name[5], name[6], name[7],
|
||||
name[8], name[9], name[10]);
|
||||
}
|
||||
|
||||
js = _glfwAllocJoystick(name, guid,
|
||||
data.axisCount + data.sliderCount,
|
||||
data.buttonCount,
|
||||
data.povCount);
|
||||
if (!js)
|
||||
{
|
||||
IDirectInputDevice8_Release(device);
|
||||
free(data.objects);
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
js->win32.device = device;
|
||||
js->win32.guid = di->guidInstance;
|
||||
js->win32.objects = data.objects;
|
||||
js->win32.objectCount = data.objectCount;
|
||||
|
||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Initialize joystick interface
|
||||
//
|
||||
void _glfwInitJoysticksWin32(void)
|
||||
{
|
||||
if (_glfw.win32.dinput8.instance)
|
||||
{
|
||||
if (FAILED(DirectInput8Create(GetModuleHandle(NULL),
|
||||
DIRECTINPUT_VERSION,
|
||||
&IID_IDirectInput8W,
|
||||
(void**) &_glfw.win32.dinput8.api,
|
||||
NULL)))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to create interface");
|
||||
}
|
||||
}
|
||||
|
||||
_glfwDetectJoystickConnectionWin32();
|
||||
}
|
||||
|
||||
// Close all opened joystick handles
|
||||
//
|
||||
void _glfwTerminateJoysticksWin32(void)
|
||||
{
|
||||
int jid;
|
||||
|
||||
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
closeJoystick(_glfw.joysticks + jid);
|
||||
|
||||
if (_glfw.win32.dinput8.api)
|
||||
IDirectInput8_Release(_glfw.win32.dinput8.api);
|
||||
}
|
||||
|
||||
// Checks for new joysticks after DBT_DEVICEARRIVAL
|
||||
//
|
||||
void _glfwDetectJoystickConnectionWin32(void)
|
||||
{
|
||||
if (_glfw.win32.xinput.instance)
|
||||
{
|
||||
DWORD index;
|
||||
|
||||
for (index = 0; index < XUSER_MAX_COUNT; index++)
|
||||
{
|
||||
int jid;
|
||||
char guid[33];
|
||||
XINPUT_CAPABILITIES xic;
|
||||
_GLFWjoystick* js;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (_glfw.joysticks[jid].present &&
|
||||
_glfw.joysticks[jid].win32.device == NULL &&
|
||||
_glfw.joysticks[jid].win32.index == index)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (jid <= GLFW_JOYSTICK_LAST)
|
||||
continue;
|
||||
|
||||
if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)
|
||||
continue;
|
||||
|
||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||
sprintf(guid, "78696e707574%02x000000000000000000",
|
||||
xic.SubType & 0xff);
|
||||
|
||||
js = _glfwAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1);
|
||||
if (!js)
|
||||
continue;
|
||||
|
||||
js->win32.index = index;
|
||||
|
||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfw.win32.dinput8.api)
|
||||
{
|
||||
if (FAILED(IDirectInput8_EnumDevices(_glfw.win32.dinput8.api,
|
||||
DI8DEVCLASS_GAMECTRL,
|
||||
deviceCallback,
|
||||
NULL,
|
||||
DIEDFL_ALLDEVICES)))
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Failed to enumerate DirectInput8 devices");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE
|
||||
//
|
||||
void _glfwDetectJoystickDisconnectionWin32(void)
|
||||
{
|
||||
int jid;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->present)
|
||||
_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
{
|
||||
if (js->win32.device)
|
||||
{
|
||||
int i, ai = 0, bi = 0, pi = 0;
|
||||
HRESULT result;
|
||||
DIJOYSTATE state;
|
||||
|
||||
IDirectInputDevice8_Poll(js->win32.device);
|
||||
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
|
||||
sizeof(state),
|
||||
&state);
|
||||
if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
|
||||
{
|
||||
IDirectInputDevice8_Acquire(js->win32.device);
|
||||
IDirectInputDevice8_Poll(js->win32.device);
|
||||
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
|
||||
sizeof(state),
|
||||
&state);
|
||||
}
|
||||
|
||||
if (FAILED(result))
|
||||
{
|
||||
closeJoystick(js);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (mode == _GLFW_POLL_PRESENCE)
|
||||
return GLFW_TRUE;
|
||||
|
||||
for (i = 0; i < js->win32.objectCount; i++)
|
||||
{
|
||||
const void* data = (char*) &state + js->win32.objects[i].offset;
|
||||
|
||||
switch (js->win32.objects[i].type)
|
||||
{
|
||||
case _GLFW_TYPE_AXIS:
|
||||
case _GLFW_TYPE_SLIDER:
|
||||
{
|
||||
const float value = (*((LONG*) data) + 0.5f) / 32767.5f;
|
||||
_glfwInputJoystickAxis(js, ai, value);
|
||||
ai++;
|
||||
break;
|
||||
}
|
||||
|
||||
case _GLFW_TYPE_BUTTON:
|
||||
{
|
||||
const char value = (*((BYTE*) data) & 0x80) != 0;
|
||||
_glfwInputJoystickButton(js, bi, value);
|
||||
bi++;
|
||||
break;
|
||||
}
|
||||
|
||||
case _GLFW_TYPE_POV:
|
||||
{
|
||||
const int states[9] =
|
||||
{
|
||||
GLFW_HAT_UP,
|
||||
GLFW_HAT_RIGHT_UP,
|
||||
GLFW_HAT_RIGHT,
|
||||
GLFW_HAT_RIGHT_DOWN,
|
||||
GLFW_HAT_DOWN,
|
||||
GLFW_HAT_LEFT_DOWN,
|
||||
GLFW_HAT_LEFT,
|
||||
GLFW_HAT_LEFT_UP,
|
||||
GLFW_HAT_CENTERED
|
||||
};
|
||||
|
||||
// Screams of horror are appropriate at this point
|
||||
int state = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
|
||||
if (state < 0 || state > 8)
|
||||
state = 8;
|
||||
|
||||
_glfwInputJoystickHat(js, pi, states[state]);
|
||||
pi++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, dpad = 0;
|
||||
DWORD result;
|
||||
XINPUT_STATE xis;
|
||||
const WORD buttons[10] =
|
||||
{
|
||||
XINPUT_GAMEPAD_A,
|
||||
XINPUT_GAMEPAD_B,
|
||||
XINPUT_GAMEPAD_X,
|
||||
XINPUT_GAMEPAD_Y,
|
||||
XINPUT_GAMEPAD_LEFT_SHOULDER,
|
||||
XINPUT_GAMEPAD_RIGHT_SHOULDER,
|
||||
XINPUT_GAMEPAD_BACK,
|
||||
XINPUT_GAMEPAD_START,
|
||||
XINPUT_GAMEPAD_LEFT_THUMB,
|
||||
XINPUT_GAMEPAD_RIGHT_THUMB
|
||||
};
|
||||
|
||||
result = XInputGetState(js->win32.index, &xis);
|
||||
if (result != ERROR_SUCCESS)
|
||||
{
|
||||
if (result == ERROR_DEVICE_NOT_CONNECTED)
|
||||
closeJoystick(js);
|
||||
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
if (mode == _GLFW_POLL_PRESENCE)
|
||||
return GLFW_TRUE;
|
||||
|
||||
_glfwInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f);
|
||||
_glfwInputJoystickAxis(js, 1, -(xis.Gamepad.sThumbLY + 0.5f) / 32767.5f);
|
||||
_glfwInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f);
|
||||
_glfwInputJoystickAxis(js, 3, -(xis.Gamepad.sThumbRY + 0.5f) / 32767.5f);
|
||||
_glfwInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f);
|
||||
_glfwInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f);
|
||||
|
||||
for (i = 0; i < 10; i++)
|
||||
{
|
||||
const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
|
||||
_glfwInputJoystickButton(js, i, value);
|
||||
}
|
||||
|
||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
|
||||
dpad |= GLFW_HAT_UP;
|
||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
|
||||
dpad |= GLFW_HAT_RIGHT;
|
||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
|
||||
dpad |= GLFW_HAT_DOWN;
|
||||
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
|
||||
dpad |= GLFW_HAT_LEFT;
|
||||
|
||||
_glfwInputJoystickHat(js, 0, dpad);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
{
|
||||
if (strcmp(guid + 20, "504944564944") == 0)
|
||||
{
|
||||
char original[33];
|
||||
strcpy(original, guid);
|
||||
sprintf(guid, "03000000%.4s0000%.4s000000000000",
|
||||
original, original + 4);
|
||||
}
|
||||
}
|
||||
|
||||
56
glfw/win32_joystick.h
vendored
56
glfw/win32_joystick.h
vendored
@@ -1,56 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int dummy
|
||||
|
||||
#define _GLFW_PLATFORM_MAPPING_NAME "Windows"
|
||||
|
||||
// Joystick element (axis, button or slider)
|
||||
//
|
||||
typedef struct _GLFWjoyobjectWin32
|
||||
{
|
||||
int offset;
|
||||
int type;
|
||||
} _GLFWjoyobjectWin32;
|
||||
|
||||
// Win32-specific per-joystick data
|
||||
//
|
||||
typedef struct _GLFWjoystickWin32
|
||||
{
|
||||
_GLFWjoyobjectWin32* objects;
|
||||
int objectCount;
|
||||
IDirectInputDevice8W* device;
|
||||
DWORD index;
|
||||
GUID guid;
|
||||
} _GLFWjoystickWin32;
|
||||
|
||||
|
||||
void _glfwInitJoysticksWin32(void);
|
||||
void _glfwTerminateJoysticksWin32(void);
|
||||
void _glfwDetectJoystickConnectionWin32(void);
|
||||
void _glfwDetectJoystickDisconnectionWin32(void);
|
||||
|
||||
513
glfw/win32_monitor.c
vendored
513
glfw/win32_monitor.c
vendored
@@ -1,513 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <malloc.h>
|
||||
|
||||
|
||||
// Callback for EnumDisplayMonitors in createMonitor
|
||||
//
|
||||
static BOOL CALLBACK monitorCallback(HMONITOR handle,
|
||||
HDC dc,
|
||||
RECT* rect,
|
||||
LPARAM data)
|
||||
{
|
||||
MONITORINFOEXW mi;
|
||||
ZeroMemory(&mi, sizeof(mi));
|
||||
mi.cbSize = sizeof(mi);
|
||||
|
||||
if (GetMonitorInfoW(handle, (MONITORINFO*) &mi))
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) data;
|
||||
if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0)
|
||||
monitor->win32.handle = handle;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Create monitor from an adapter and (optionally) a display
|
||||
//
|
||||
static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
|
||||
DISPLAY_DEVICEW* display)
|
||||
{
|
||||
_GLFWmonitor* monitor;
|
||||
int widthMM, heightMM;
|
||||
char* name;
|
||||
HDC dc;
|
||||
DEVMODEW dm;
|
||||
RECT rect;
|
||||
|
||||
if (display)
|
||||
name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
|
||||
else
|
||||
name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
ZeroMemory(&dm, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm);
|
||||
|
||||
dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
|
||||
|
||||
if (IsWindows8Point1OrGreater())
|
||||
{
|
||||
widthMM = GetDeviceCaps(dc, HORZSIZE);
|
||||
heightMM = GetDeviceCaps(dc, VERTSIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
widthMM = (int) (dm.dmPelsWidth * 25.4f / GetDeviceCaps(dc, LOGPIXELSX));
|
||||
heightMM = (int) (dm.dmPelsHeight * 25.4f / GetDeviceCaps(dc, LOGPIXELSY));
|
||||
}
|
||||
|
||||
DeleteDC(dc);
|
||||
|
||||
monitor = _glfwAllocMonitor(name, widthMM, heightMM);
|
||||
free(name);
|
||||
|
||||
if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)
|
||||
monitor->win32.modesPruned = GLFW_TRUE;
|
||||
|
||||
wcscpy(monitor->win32.adapterName, adapter->DeviceName);
|
||||
WideCharToMultiByte(CP_UTF8, 0,
|
||||
adapter->DeviceName, -1,
|
||||
monitor->win32.publicAdapterName,
|
||||
sizeof(monitor->win32.publicAdapterName),
|
||||
NULL, NULL);
|
||||
|
||||
if (display)
|
||||
{
|
||||
wcscpy(monitor->win32.displayName, display->DeviceName);
|
||||
WideCharToMultiByte(CP_UTF8, 0,
|
||||
display->DeviceName, -1,
|
||||
monitor->win32.publicDisplayName,
|
||||
sizeof(monitor->win32.publicDisplayName),
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
rect.left = dm.dmPosition.x;
|
||||
rect.top = dm.dmPosition.y;
|
||||
rect.right = dm.dmPosition.x + dm.dmPelsWidth;
|
||||
rect.bottom = dm.dmPosition.y + dm.dmPelsHeight;
|
||||
|
||||
EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor);
|
||||
return monitor;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Poll for changes in the set of connected monitors
|
||||
//
|
||||
void _glfwPollMonitorsWin32(void)
|
||||
{
|
||||
int i, disconnectedCount;
|
||||
_GLFWmonitor** disconnected = NULL;
|
||||
DWORD adapterIndex, displayIndex;
|
||||
DISPLAY_DEVICEW adapter, display;
|
||||
_GLFWmonitor* monitor;
|
||||
|
||||
disconnectedCount = _glfw.monitorCount;
|
||||
if (disconnectedCount)
|
||||
{
|
||||
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
|
||||
memcpy(disconnected,
|
||||
_glfw.monitors,
|
||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||
}
|
||||
|
||||
for (adapterIndex = 0; ; adapterIndex++)
|
||||
{
|
||||
int type = _GLFW_INSERT_LAST;
|
||||
|
||||
ZeroMemory(&adapter, sizeof(adapter));
|
||||
adapter.cb = sizeof(adapter);
|
||||
|
||||
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
|
||||
break;
|
||||
|
||||
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||
continue;
|
||||
|
||||
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
||||
type = _GLFW_INSERT_FIRST;
|
||||
|
||||
for (displayIndex = 0; ; displayIndex++)
|
||||
{
|
||||
ZeroMemory(&display, sizeof(display));
|
||||
display.cb = sizeof(display);
|
||||
|
||||
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
|
||||
break;
|
||||
|
||||
if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||
continue;
|
||||
|
||||
for (i = 0; i < disconnectedCount; i++)
|
||||
{
|
||||
if (disconnected[i] &&
|
||||
wcscmp(disconnected[i]->win32.displayName,
|
||||
display.DeviceName) == 0)
|
||||
{
|
||||
disconnected[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < disconnectedCount)
|
||||
continue;
|
||||
|
||||
monitor = createMonitor(&adapter, &display);
|
||||
if (!monitor)
|
||||
{
|
||||
free(disconnected);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
||||
|
||||
type = _GLFW_INSERT_LAST;
|
||||
}
|
||||
|
||||
// HACK: If an active adapter does not have any display devices
|
||||
// (as sometimes happens), add it directly as a monitor
|
||||
if (displayIndex == 0)
|
||||
{
|
||||
for (i = 0; i < disconnectedCount; i++)
|
||||
{
|
||||
if (disconnected[i] &&
|
||||
wcscmp(disconnected[i]->win32.adapterName,
|
||||
adapter.DeviceName) == 0)
|
||||
{
|
||||
disconnected[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < disconnectedCount)
|
||||
continue;
|
||||
|
||||
monitor = createMonitor(&adapter, NULL);
|
||||
if (!monitor)
|
||||
{
|
||||
free(disconnected);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < disconnectedCount; i++)
|
||||
{
|
||||
if (disconnected[i])
|
||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||
}
|
||||
|
||||
free(disconnected);
|
||||
}
|
||||
|
||||
// Change the current video mode
|
||||
//
|
||||
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||
{
|
||||
GLFWvidmode current;
|
||||
const GLFWvidmode* best;
|
||||
DEVMODEW dm;
|
||||
LONG result;
|
||||
|
||||
best = _glfwChooseVideoMode(monitor, desired);
|
||||
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||
if (_glfwCompareVideoModes(¤t, best) == 0)
|
||||
return;
|
||||
|
||||
ZeroMemory(&dm, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
|
||||
DM_DISPLAYFREQUENCY;
|
||||
dm.dmPelsWidth = best->width;
|
||||
dm.dmPelsHeight = best->height;
|
||||
dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits;
|
||||
dm.dmDisplayFrequency = best->refreshRate;
|
||||
|
||||
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
|
||||
dm.dmBitsPerPel = 32;
|
||||
|
||||
result = ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
||||
&dm,
|
||||
NULL,
|
||||
CDS_FULLSCREEN,
|
||||
NULL);
|
||||
if (result == DISP_CHANGE_SUCCESSFUL)
|
||||
monitor->win32.modeChanged = GLFW_TRUE;
|
||||
else
|
||||
{
|
||||
const char* description = "Unknown error";
|
||||
|
||||
if (result == DISP_CHANGE_BADDUALVIEW)
|
||||
description = "The system uses DualView";
|
||||
else if (result == DISP_CHANGE_BADFLAGS)
|
||||
description = "Invalid flags";
|
||||
else if (result == DISP_CHANGE_BADMODE)
|
||||
description = "Graphics mode not supported";
|
||||
else if (result == DISP_CHANGE_BADPARAM)
|
||||
description = "Invalid parameter";
|
||||
else if (result == DISP_CHANGE_FAILED)
|
||||
description = "Graphics mode failed";
|
||||
else if (result == DISP_CHANGE_NOTUPDATED)
|
||||
description = "Failed to write to registry";
|
||||
else if (result == DISP_CHANGE_RESTART)
|
||||
description = "Computer restart required";
|
||||
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to set video mode: %s",
|
||||
description);
|
||||
}
|
||||
}
|
||||
|
||||
// Restore the previously saved (original) video mode
|
||||
//
|
||||
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
|
||||
{
|
||||
if (monitor->win32.modeChanged)
|
||||
{
|
||||
ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
||||
NULL, NULL, CDS_FULLSCREEN, NULL);
|
||||
monitor->win32.modeChanged = GLFW_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale)
|
||||
{
|
||||
UINT xdpi, ydpi;
|
||||
|
||||
if (IsWindows8Point1OrGreater())
|
||||
GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
||||
else
|
||||
{
|
||||
const HDC dc = GetDC(NULL);
|
||||
xdpi = GetDeviceCaps(dc, LOGPIXELSX);
|
||||
ydpi = GetDeviceCaps(dc, LOGPIXELSY);
|
||||
ReleaseDC(NULL, dc);
|
||||
}
|
||||
|
||||
if (xscale)
|
||||
*xscale = xdpi / (float) USER_DEFAULT_SCREEN_DPI;
|
||||
if (yscale)
|
||||
*yscale = ydpi / (float) USER_DEFAULT_SCREEN_DPI;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||
{
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||
{
|
||||
DEVMODEW dm;
|
||||
ZeroMemory(&dm, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
|
||||
EnumDisplaySettingsExW(monitor->win32.adapterName,
|
||||
ENUM_CURRENT_SETTINGS,
|
||||
&dm,
|
||||
EDS_ROTATEDMODE);
|
||||
|
||||
if (xpos)
|
||||
*xpos = dm.dmPosition.x;
|
||||
if (ypos)
|
||||
*ypos = dm.dmPosition.y;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
float* xscale, float* yscale)
|
||||
{
|
||||
_glfwGetMonitorContentScaleWin32(monitor->win32.handle, xscale, yscale);
|
||||
}
|
||||
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
{
|
||||
int modeIndex = 0, size = 0;
|
||||
GLFWvidmode* result = NULL;
|
||||
|
||||
*count = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int i;
|
||||
GLFWvidmode mode;
|
||||
DEVMODEW dm;
|
||||
|
||||
ZeroMemory(&dm, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
|
||||
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
|
||||
break;
|
||||
|
||||
modeIndex++;
|
||||
|
||||
// Skip modes with less than 15 BPP
|
||||
if (dm.dmBitsPerPel < 15)
|
||||
continue;
|
||||
|
||||
mode.width = dm.dmPelsWidth;
|
||||
mode.height = dm.dmPelsHeight;
|
||||
mode.refreshRate = dm.dmDisplayFrequency;
|
||||
_glfwSplitBPP(dm.dmBitsPerPel,
|
||||
&mode.redBits,
|
||||
&mode.greenBits,
|
||||
&mode.blueBits);
|
||||
|
||||
for (i = 0; i < *count; i++)
|
||||
{
|
||||
if (_glfwCompareVideoModes(result + i, &mode) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Skip duplicate modes
|
||||
if (i < *count)
|
||||
continue;
|
||||
|
||||
if (monitor->win32.modesPruned)
|
||||
{
|
||||
// Skip modes not supported by the connected displays
|
||||
if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
|
||||
&dm,
|
||||
NULL,
|
||||
CDS_TEST,
|
||||
NULL) != DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (*count == size)
|
||||
{
|
||||
size += 128;
|
||||
result = (GLFWvidmode*) realloc(result, size * sizeof(GLFWvidmode));
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
result[*count - 1] = mode;
|
||||
}
|
||||
|
||||
if (!*count)
|
||||
{
|
||||
// HACK: Report the current mode if no valid modes were found
|
||||
result = calloc(1, sizeof(GLFWvidmode));
|
||||
_glfwPlatformGetVideoMode(monitor, result);
|
||||
*count = 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
{
|
||||
DEVMODEW dm;
|
||||
ZeroMemory(&dm, sizeof(dm));
|
||||
dm.dmSize = sizeof(dm);
|
||||
|
||||
EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm);
|
||||
|
||||
mode->width = dm.dmPelsWidth;
|
||||
mode->height = dm.dmPelsHeight;
|
||||
mode->refreshRate = dm.dmDisplayFrequency;
|
||||
_glfwSplitBPP(dm.dmBitsPerPel,
|
||||
&mode->redBits,
|
||||
&mode->greenBits,
|
||||
&mode->blueBits);
|
||||
}
|
||||
|
||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
{
|
||||
HDC dc;
|
||||
WORD values[768];
|
||||
|
||||
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
||||
GetDeviceGammaRamp(dc, values);
|
||||
DeleteDC(dc);
|
||||
|
||||
_glfwAllocGammaArrays(ramp, 256);
|
||||
|
||||
memcpy(ramp->red, values + 0, 256 * sizeof(unsigned short));
|
||||
memcpy(ramp->green, values + 256, 256 * sizeof(unsigned short));
|
||||
memcpy(ramp->blue, values + 512, 256 * sizeof(unsigned short));
|
||||
}
|
||||
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
{
|
||||
HDC dc;
|
||||
WORD values[768];
|
||||
|
||||
if (ramp->size != 256)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Gamma ramp size must be 256");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(values + 0, ramp->red, 256 * sizeof(unsigned short));
|
||||
memcpy(values + 256, ramp->green, 256 * sizeof(unsigned short));
|
||||
memcpy(values + 512, ramp->blue, 256 * sizeof(unsigned short));
|
||||
|
||||
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
|
||||
SetDeviceGammaRamp(dc, values);
|
||||
DeleteDC(dc);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW native API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return monitor->win32.publicAdapterName;
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
|
||||
{
|
||||
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
return monitor->win32.publicDisplayName;
|
||||
}
|
||||
|
||||
449
glfw/win32_platform.h
vendored
449
glfw/win32_platform.h
vendored
@@ -1,449 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
// We don't need all the fancy stuff
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
#define VC_EXTRALEAN
|
||||
#endif
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||
// example to allow applications to correctly declare a GL_ARB_debug_output
|
||||
// callback) but windows.h assumes no one will define APIENTRY before it does
|
||||
#undef APIENTRY
|
||||
|
||||
// GLFW on Windows is Unicode only and does not work in MBCS mode
|
||||
#ifndef UNICODE
|
||||
#define UNICODE
|
||||
#endif
|
||||
|
||||
// GLFW requires Windows XP or later
|
||||
#if WINVER < 0x0501
|
||||
#undef WINVER
|
||||
#define WINVER 0x0501
|
||||
#endif
|
||||
#if _WIN32_WINNT < 0x0501
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#endif
|
||||
|
||||
// GLFW uses DirectInput8 interfaces
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
|
||||
#include <wctype.h>
|
||||
#include <windows.h>
|
||||
#include <dinput.h>
|
||||
#include <xinput.h>
|
||||
#include <dbt.h>
|
||||
|
||||
// HACK: Define macros that some windows.h variants don't
|
||||
#ifndef WM_MOUSEHWHEEL
|
||||
#define WM_MOUSEHWHEEL 0x020E
|
||||
#endif
|
||||
#ifndef WM_DWMCOMPOSITIONCHANGED
|
||||
#define WM_DWMCOMPOSITIONCHANGED 0x031E
|
||||
#endif
|
||||
#ifndef WM_COPYGLOBALDATA
|
||||
#define WM_COPYGLOBALDATA 0x0049
|
||||
#endif
|
||||
#ifndef WM_UNICHAR
|
||||
#define WM_UNICHAR 0x0109
|
||||
#endif
|
||||
#ifndef UNICODE_NOCHAR
|
||||
#define UNICODE_NOCHAR 0xFFFF
|
||||
#endif
|
||||
#ifndef WM_DPICHANGED
|
||||
#define WM_DPICHANGED 0x02E0
|
||||
#endif
|
||||
#ifndef GET_XBUTTON_WPARAM
|
||||
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
|
||||
#endif
|
||||
#ifndef EDS_ROTATEDMODE
|
||||
#define EDS_ROTATEDMODE 0x00000004
|
||||
#endif
|
||||
#ifndef DISPLAY_DEVICE_ACTIVE
|
||||
#define DISPLAY_DEVICE_ACTIVE 0x00000001
|
||||
#endif
|
||||
#ifndef _WIN32_WINNT_WINBLUE
|
||||
#define _WIN32_WINNT_WINBLUE 0x0602
|
||||
#endif
|
||||
#ifndef WM_GETDPISCALEDSIZE
|
||||
#define WM_GETDPISCALEDSIZE 0x02e4
|
||||
#endif
|
||||
#ifndef USER_DEFAULT_SCREEN_DPI
|
||||
#define USER_DEFAULT_SCREEN_DPI 96
|
||||
#endif
|
||||
|
||||
#if WINVER < 0x0601
|
||||
typedef struct
|
||||
{
|
||||
DWORD cbSize;
|
||||
DWORD ExtStatus;
|
||||
} CHANGEFILTERSTRUCT;
|
||||
#ifndef MSGFLT_ALLOW
|
||||
#define MSGFLT_ALLOW 1
|
||||
#endif
|
||||
#endif /*Windows 7*/
|
||||
|
||||
#if WINVER < 0x0600
|
||||
#define DWM_BB_ENABLE 0x00000001
|
||||
#define DWM_BB_BLURREGION 0x00000002
|
||||
typedef struct
|
||||
{
|
||||
DWORD dwFlags;
|
||||
BOOL fEnable;
|
||||
HRGN hRgnBlur;
|
||||
BOOL fTransitionOnMaximized;
|
||||
} DWM_BLURBEHIND;
|
||||
#else
|
||||
#include <dwmapi.h>
|
||||
#endif /*Windows Vista*/
|
||||
|
||||
#ifndef DPI_ENUMS_DECLARED
|
||||
typedef enum
|
||||
{
|
||||
PROCESS_DPI_UNAWARE = 0,
|
||||
PROCESS_SYSTEM_DPI_AWARE = 1,
|
||||
PROCESS_PER_MONITOR_DPI_AWARE = 2
|
||||
} PROCESS_DPI_AWARENESS;
|
||||
typedef enum
|
||||
{
|
||||
MDT_EFFECTIVE_DPI = 0,
|
||||
MDT_ANGULAR_DPI = 1,
|
||||
MDT_RAW_DPI = 2,
|
||||
MDT_DEFAULT = MDT_EFFECTIVE_DPI
|
||||
} MONITOR_DPI_TYPE;
|
||||
#endif /*DPI_ENUMS_DECLARED*/
|
||||
|
||||
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
||||
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
|
||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT) -4)
|
||||
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
|
||||
|
||||
// HACK: Define versionhelpers.h functions manually as MinGW lacks the header
|
||||
#define IsWindowsXPOrGreater() \
|
||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINXP), \
|
||||
LOBYTE(_WIN32_WINNT_WINXP), 0)
|
||||
#define IsWindowsVistaOrGreater() \
|
||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
|
||||
LOBYTE(_WIN32_WINNT_VISTA), 0)
|
||||
#define IsWindows7OrGreater() \
|
||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7), \
|
||||
LOBYTE(_WIN32_WINNT_WIN7), 0)
|
||||
#define IsWindows8OrGreater() \
|
||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8), \
|
||||
LOBYTE(_WIN32_WINNT_WIN8), 0)
|
||||
#define IsWindows8Point1OrGreater() \
|
||||
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
|
||||
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
|
||||
|
||||
#define _glfwIsWindows10AnniversaryUpdateOrGreaterWin32() \
|
||||
_glfwIsWindows10BuildOrGreaterWin32(14393)
|
||||
#define _glfwIsWindows10CreatorsUpdateOrGreaterWin32() \
|
||||
_glfwIsWindows10BuildOrGreaterWin32(15063)
|
||||
|
||||
// HACK: Define macros that some xinput.h variants don't
|
||||
#ifndef XINPUT_CAPS_WIRELESS
|
||||
#define XINPUT_CAPS_WIRELESS 0x0002
|
||||
#endif
|
||||
#ifndef XINPUT_DEVSUBTYPE_WHEEL
|
||||
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
|
||||
#endif
|
||||
#ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK
|
||||
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
|
||||
#endif
|
||||
#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK
|
||||
#define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04
|
||||
#endif
|
||||
#ifndef XINPUT_DEVSUBTYPE_DANCE_PAD
|
||||
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
|
||||
#endif
|
||||
#ifndef XINPUT_DEVSUBTYPE_GUITAR
|
||||
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
|
||||
#endif
|
||||
#ifndef XINPUT_DEVSUBTYPE_DRUM_KIT
|
||||
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
|
||||
#endif
|
||||
#ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD
|
||||
#define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13
|
||||
#endif
|
||||
#ifndef XUSER_MAX_COUNT
|
||||
#define XUSER_MAX_COUNT 4
|
||||
#endif
|
||||
|
||||
// HACK: Define macros that some dinput.h variants don't
|
||||
#ifndef DIDFT_OPTIONAL
|
||||
#define DIDFT_OPTIONAL 0x80000000
|
||||
#endif
|
||||
|
||||
// winmm.dll function pointer typedefs
|
||||
typedef DWORD (WINAPI * PFN_timeGetTime)(void);
|
||||
#define timeGetTime _glfw.win32.winmm.GetTime
|
||||
|
||||
// xinput.dll function pointer typedefs
|
||||
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
|
||||
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
|
||||
#define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities
|
||||
#define XInputGetState _glfw.win32.xinput.GetState
|
||||
|
||||
// dinput8.dll function pointer typedefs
|
||||
typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
|
||||
#define DirectInput8Create _glfw.win32.dinput8.Create
|
||||
|
||||
// user32.dll function pointer typedefs
|
||||
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
|
||||
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
|
||||
typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
|
||||
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
|
||||
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
|
||||
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
|
||||
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
|
||||
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
|
||||
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
|
||||
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
|
||||
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
|
||||
#define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
|
||||
|
||||
// dwmapi.dll function pointer typedefs
|
||||
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
|
||||
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
|
||||
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
|
||||
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
|
||||
#define DwmFlush _glfw.win32.dwmapi.Flush
|
||||
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
|
||||
|
||||
// shcore.dll function pointer typedefs
|
||||
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||
typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
|
||||
#define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
|
||||
#define GetDpiForMonitor _glfw.win32.shcore.GetDpiForMonitor_
|
||||
|
||||
// ntdll.dll function pointer typedefs
|
||||
typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
|
||||
#define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_
|
||||
|
||||
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
|
||||
|
||||
typedef struct VkWin32SurfaceCreateInfoKHR
|
||||
{
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkWin32SurfaceCreateFlagsKHR flags;
|
||||
HINSTANCE hinstance;
|
||||
HWND hwnd;
|
||||
} VkWin32SurfaceCreateInfoKHR;
|
||||
|
||||
typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
|
||||
|
||||
#include "win32_joystick.h"
|
||||
#include "wgl_context.h"
|
||||
#include "egl_context.h"
|
||||
#include "osmesa_context.h"
|
||||
|
||||
#if !defined(_GLFW_WNDCLASSNAME)
|
||||
#define _GLFW_WNDCLASSNAME L"GLFW30"
|
||||
#endif
|
||||
|
||||
#define _glfw_dlopen(name) LoadLibraryA(name)
|
||||
#define _glfw_dlclose(handle) FreeLibrary((HMODULE) handle)
|
||||
#define _glfw_dlsym(handle, name) GetProcAddress((HMODULE) handle, name)
|
||||
|
||||
#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->win32.handle)
|
||||
#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY
|
||||
|
||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 win32
|
||||
#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32
|
||||
#define _GLFW_PLATFORM_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32
|
||||
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 win32
|
||||
#define _GLFW_PLATFORM_CURSOR_STATE _GLFWcursorWin32 win32
|
||||
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32
|
||||
#define _GLFW_PLATFORM_MUTEX_STATE _GLFWmutexWin32 win32
|
||||
|
||||
|
||||
// Win32-specific per-window data
|
||||
//
|
||||
typedef struct _GLFWwindowWin32
|
||||
{
|
||||
HWND handle;
|
||||
HICON bigIcon;
|
||||
HICON smallIcon;
|
||||
|
||||
GLFWbool cursorTracked;
|
||||
GLFWbool frameAction;
|
||||
GLFWbool iconified;
|
||||
GLFWbool maximized;
|
||||
// Whether to enable framebuffer transparency on DWM
|
||||
GLFWbool transparent;
|
||||
GLFWbool scaleToMonitor;
|
||||
|
||||
// The last received cursor position, regardless of source
|
||||
int lastCursorPosX, lastCursorPosY;
|
||||
|
||||
} _GLFWwindowWin32;
|
||||
|
||||
// Win32-specific global data
|
||||
//
|
||||
typedef struct _GLFWlibraryWin32
|
||||
{
|
||||
HWND helperWindowHandle;
|
||||
HDEVNOTIFY deviceNotificationHandle;
|
||||
DWORD foregroundLockTimeout;
|
||||
int acquiredMonitorCount;
|
||||
char* clipboardString;
|
||||
short int keycodes[512];
|
||||
short int scancodes[GLFW_KEY_LAST + 1];
|
||||
char keynames[GLFW_KEY_LAST + 1][5];
|
||||
// Where to place the cursor when re-enabled
|
||||
double restoreCursorPosX, restoreCursorPosY;
|
||||
// The window whose disabled cursor mode is active
|
||||
_GLFWwindow* disabledCursorWindow;
|
||||
RAWINPUT* rawInput;
|
||||
int rawInputSize;
|
||||
UINT mouseTrailSize;
|
||||
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
PFN_timeGetTime GetTime;
|
||||
} winmm;
|
||||
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
PFN_DirectInput8Create Create;
|
||||
IDirectInput8W* api;
|
||||
} dinput8;
|
||||
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
PFN_XInputGetCapabilities GetCapabilities;
|
||||
PFN_XInputGetState GetState;
|
||||
} xinput;
|
||||
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
PFN_SetProcessDPIAware SetProcessDPIAware_;
|
||||
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
|
||||
PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_;
|
||||
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
|
||||
PFN_GetDpiForWindow GetDpiForWindow_;
|
||||
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
|
||||
} user32;
|
||||
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
|
||||
PFN_DwmFlush Flush;
|
||||
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
|
||||
} dwmapi;
|
||||
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
PFN_SetProcessDpiAwareness SetProcessDpiAwareness_;
|
||||
PFN_GetDpiForMonitor GetDpiForMonitor_;
|
||||
} shcore;
|
||||
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
|
||||
} ntdll;
|
||||
|
||||
} _GLFWlibraryWin32;
|
||||
|
||||
// Win32-specific per-monitor data
|
||||
//
|
||||
typedef struct _GLFWmonitorWin32
|
||||
{
|
||||
HMONITOR handle;
|
||||
// This size matches the static size of DISPLAY_DEVICE.DeviceName
|
||||
WCHAR adapterName[32];
|
||||
WCHAR displayName[32];
|
||||
char publicAdapterName[32];
|
||||
char publicDisplayName[32];
|
||||
GLFWbool modesPruned;
|
||||
GLFWbool modeChanged;
|
||||
|
||||
} _GLFWmonitorWin32;
|
||||
|
||||
// Win32-specific per-cursor data
|
||||
//
|
||||
typedef struct _GLFWcursorWin32
|
||||
{
|
||||
HCURSOR handle;
|
||||
|
||||
} _GLFWcursorWin32;
|
||||
|
||||
// Win32-specific global timer data
|
||||
//
|
||||
typedef struct _GLFWtimerWin32
|
||||
{
|
||||
GLFWbool hasPC;
|
||||
uint64_t frequency;
|
||||
|
||||
} _GLFWtimerWin32;
|
||||
|
||||
// Win32-specific thread local storage data
|
||||
//
|
||||
typedef struct _GLFWtlsWin32
|
||||
{
|
||||
GLFWbool allocated;
|
||||
DWORD index;
|
||||
|
||||
} _GLFWtlsWin32;
|
||||
|
||||
// Win32-specific mutex data
|
||||
//
|
||||
typedef struct _GLFWmutexWin32
|
||||
{
|
||||
GLFWbool allocated;
|
||||
CRITICAL_SECTION section;
|
||||
|
||||
} _GLFWmutexWin32;
|
||||
|
||||
|
||||
GLFWbool _glfwRegisterWindowClassWin32(void);
|
||||
void _glfwUnregisterWindowClassWin32(void);
|
||||
|
||||
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
|
||||
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
|
||||
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
|
||||
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
|
||||
void _glfwInputErrorWin32(int error, const char* description);
|
||||
void _glfwUpdateKeyNamesWin32(void);
|
||||
|
||||
void _glfwInitTimerWin32(void);
|
||||
|
||||
void _glfwPollMonitorsWin32(void);
|
||||
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
|
||||
void _glfwGetMonitorContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);
|
||||
97
glfw/win32_thread.c
vendored
97
glfw/win32_thread.c
vendored
@@ -1,97 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
|
||||
{
|
||||
assert(tls->win32.allocated == GLFW_FALSE);
|
||||
|
||||
tls->win32.index = TlsAlloc();
|
||||
if (tls->win32.index == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to allocate TLS index");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
tls->win32.allocated = GLFW_TRUE;
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyTls(_GLFWtls* tls)
|
||||
{
|
||||
if (tls->win32.allocated)
|
||||
TlsFree(tls->win32.index);
|
||||
memset(tls, 0, sizeof(_GLFWtls));
|
||||
}
|
||||
|
||||
void* _glfwPlatformGetTls(_GLFWtls* tls)
|
||||
{
|
||||
assert(tls->win32.allocated == GLFW_TRUE);
|
||||
return TlsGetValue(tls->win32.index);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
|
||||
{
|
||||
assert(tls->win32.allocated == GLFW_TRUE);
|
||||
TlsSetValue(tls->win32.index, value);
|
||||
}
|
||||
|
||||
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->win32.allocated == GLFW_FALSE);
|
||||
InitializeCriticalSection(&mutex->win32.section);
|
||||
return mutex->win32.allocated = GLFW_TRUE;
|
||||
}
|
||||
|
||||
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
if (mutex->win32.allocated)
|
||||
DeleteCriticalSection(&mutex->win32.section);
|
||||
memset(mutex, 0, sizeof(_GLFWmutex));
|
||||
}
|
||||
|
||||
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->win32.allocated == GLFW_TRUE);
|
||||
EnterCriticalSection(&mutex->win32.section);
|
||||
}
|
||||
|
||||
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
|
||||
{
|
||||
assert(mutex->win32.allocated == GLFW_TRUE);
|
||||
LeaveCriticalSection(&mutex->win32.section);
|
||||
}
|
||||
|
||||
74
glfw/win32_time.c
vendored
74
glfw/win32_time.c
vendored
@@ -1,74 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Initialise timer
|
||||
//
|
||||
void _glfwInitTimerWin32(void)
|
||||
{
|
||||
uint64_t frequency;
|
||||
|
||||
if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency))
|
||||
{
|
||||
_glfw.timer.win32.hasPC = GLFW_TRUE;
|
||||
_glfw.timer.win32.frequency = frequency;
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfw.timer.win32.hasPC = GLFW_FALSE;
|
||||
_glfw.timer.win32.frequency = 1000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint64_t _glfwPlatformGetTimerValue(void)
|
||||
{
|
||||
if (_glfw.timer.win32.hasPC)
|
||||
{
|
||||
uint64_t value;
|
||||
QueryPerformanceCounter((LARGE_INTEGER*) &value);
|
||||
return value;
|
||||
}
|
||||
else
|
||||
return (uint64_t) timeGetTime();
|
||||
}
|
||||
|
||||
uint64_t _glfwPlatformGetTimerFrequency(void)
|
||||
{
|
||||
return _glfw.timer.win32.frequency;
|
||||
}
|
||||
|
||||
2197
glfw/win32_window.c
vendored
2197
glfw/win32_window.c
vendored
File diff suppressed because it is too large
Load Diff
171
glfw/window.c
vendored
171
glfw/window.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
// GLFW 3.4 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
@@ -25,6 +25,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// Please use C89 style variable declarations in this file because VS 2010
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -40,7 +42,7 @@
|
||||
|
||||
// Notifies shared code that a window has lost or received input focus
|
||||
//
|
||||
void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused)
|
||||
void _glfwInputWindowFocus(_GLFWwindow* window, bool focused)
|
||||
{
|
||||
if (window->callbacks.focus)
|
||||
window->callbacks.focus((GLFWwindow*) window, focused);
|
||||
@@ -82,14 +84,22 @@ _GLFWwindow* _glfwFocusedWindow() {
|
||||
_GLFWwindow* _glfwWindowForId(GLFWid id) {
|
||||
_GLFWwindow *w = _glfw.windowListHead;
|
||||
while (w) {
|
||||
if (w->id == _glfw.focusedWindowId) return w;
|
||||
if (w->id == id) return w;
|
||||
w = w->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Notifies shared code that a window's occlusion state has changed
|
||||
//
|
||||
void _glfwInputWindowOcclusion(_GLFWwindow* window, bool occluded)
|
||||
{
|
||||
if (window->callbacks.occlusion)
|
||||
window->callbacks.occlusion((GLFWwindow*) window, occluded);
|
||||
}
|
||||
|
||||
// Notifies shared code that a window has moved
|
||||
// The position is specified in client-area relative screen coordinates
|
||||
// The position is specified in content area relative screen coordinates
|
||||
//
|
||||
void _glfwInputWindowPos(_GLFWwindow* window, int x, int y)
|
||||
{
|
||||
@@ -108,7 +118,7 @@ void _glfwInputWindowSize(_GLFWwindow* window, int width, int height)
|
||||
|
||||
// Notifies shared code that a window has been iconified or restored
|
||||
//
|
||||
void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
|
||||
void _glfwInputWindowIconify(_GLFWwindow* window, bool iconified)
|
||||
{
|
||||
if (window->callbacks.iconify)
|
||||
window->callbacks.iconify((GLFWwindow*) window, iconified);
|
||||
@@ -116,7 +126,7 @@ void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified)
|
||||
|
||||
// Notifies shared code that a window has been maximized or restored
|
||||
//
|
||||
void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized)
|
||||
void _glfwInputWindowMaximize(_GLFWwindow* window, bool maximized)
|
||||
{
|
||||
if (window->callbacks.maximize)
|
||||
window->callbacks.maximize((GLFWwindow*) window, maximized);
|
||||
@@ -131,6 +141,14 @@ void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height)
|
||||
window->callbacks.fbsize((GLFWwindow*) window, width, height);
|
||||
}
|
||||
|
||||
// Notifies shared code that a window live resize is in progress
|
||||
//
|
||||
void _glfwInputLiveResize(_GLFWwindow* window, bool started)
|
||||
{
|
||||
if (window && window->callbacks.liveResize)
|
||||
window->callbacks.liveResize((GLFWwindow*) window, started);
|
||||
}
|
||||
|
||||
// Notifies shared code that a window content scale has changed
|
||||
// The scale is specified as the ratio between the current and default DPI
|
||||
//
|
||||
@@ -152,7 +170,7 @@ void _glfwInputWindowDamage(_GLFWwindow* window)
|
||||
//
|
||||
void _glfwInputWindowCloseRequest(_GLFWwindow* window)
|
||||
{
|
||||
window->shouldClose = GLFW_TRUE;
|
||||
window->shouldClose = true;
|
||||
|
||||
if (window->callbacks.close)
|
||||
window->callbacks.close((GLFWwindow*) window);
|
||||
@@ -165,7 +183,6 @@ void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor)
|
||||
window->monitor = monitor;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW public API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -254,19 +271,17 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
|
||||
if (window->monitor)
|
||||
{
|
||||
if (wndconfig.centerCursor)
|
||||
{
|
||||
int width, height;
|
||||
_glfwPlatformGetWindowSize(window, &width, &height);
|
||||
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
|
||||
}
|
||||
_glfwCenterCursorInContentArea(window);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wndconfig.visible)
|
||||
{
|
||||
_glfwPlatformShowWindow(window);
|
||||
#ifndef _GLFW_WAYLAND
|
||||
if (wndconfig.focused)
|
||||
_glfwPlatformFocusWindow(window);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,13 +301,13 @@ void glfwDefaultWindowHints(void)
|
||||
|
||||
// The default is a focused, visible, resizable window with decorations
|
||||
memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window));
|
||||
_glfw.hints.window.resizable = GLFW_TRUE;
|
||||
_glfw.hints.window.visible = GLFW_TRUE;
|
||||
_glfw.hints.window.decorated = GLFW_TRUE;
|
||||
_glfw.hints.window.focused = GLFW_TRUE;
|
||||
_glfw.hints.window.autoIconify = GLFW_TRUE;
|
||||
_glfw.hints.window.centerCursor = GLFW_TRUE;
|
||||
_glfw.hints.window.focusOnShow = GLFW_TRUE;
|
||||
_glfw.hints.window.resizable = true;
|
||||
_glfw.hints.window.visible = true;
|
||||
_glfw.hints.window.decorated = true;
|
||||
_glfw.hints.window.focused = true;
|
||||
_glfw.hints.window.autoIconify = true;
|
||||
_glfw.hints.window.centerCursor = true;
|
||||
_glfw.hints.window.focusOnShow = true;
|
||||
|
||||
// The default is 24 bits of color, 24 bits of depth and 8 bits of stencil,
|
||||
// double buffered
|
||||
@@ -303,13 +318,13 @@ void glfwDefaultWindowHints(void)
|
||||
_glfw.hints.framebuffer.alphaBits = 8;
|
||||
_glfw.hints.framebuffer.depthBits = 24;
|
||||
_glfw.hints.framebuffer.stencilBits = 8;
|
||||
_glfw.hints.framebuffer.doublebuffer = GLFW_TRUE;
|
||||
_glfw.hints.framebuffer.doublebuffer = true;
|
||||
|
||||
// The default is to select the highest available refresh rate
|
||||
_glfw.hints.refreshRate = GLFW_DONT_CARE;
|
||||
|
||||
// The default is to use full Retina resolution framebuffers
|
||||
_glfw.hints.window.ns.retina = GLFW_TRUE;
|
||||
_glfw.hints.window.ns.retina = true;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwWindowHint(int hint, int value)
|
||||
@@ -352,55 +367,55 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
||||
_glfw.hints.framebuffer.auxBuffers = value;
|
||||
return;
|
||||
case GLFW_STEREO:
|
||||
_glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.stereo = value ? true : false;
|
||||
return;
|
||||
case GLFW_DOUBLEBUFFER:
|
||||
_glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.doublebuffer = value ? true : false;
|
||||
return;
|
||||
case GLFW_TRANSPARENT_FRAMEBUFFER:
|
||||
_glfw.hints.framebuffer.transparent = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.transparent = value ? true : false;
|
||||
return;
|
||||
case GLFW_SAMPLES:
|
||||
_glfw.hints.framebuffer.samples = value;
|
||||
return;
|
||||
case GLFW_SRGB_CAPABLE:
|
||||
_glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.framebuffer.sRGB = value ? true : false;
|
||||
return;
|
||||
case GLFW_RESIZABLE:
|
||||
_glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.resizable = value ? true : false;
|
||||
return;
|
||||
case GLFW_DECORATED:
|
||||
_glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.decorated = value ? true : false;
|
||||
return;
|
||||
case GLFW_FOCUSED:
|
||||
_glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.focused = value ? true : false;
|
||||
return;
|
||||
case GLFW_AUTO_ICONIFY:
|
||||
_glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.autoIconify = value ? true : false;
|
||||
return;
|
||||
case GLFW_FLOATING:
|
||||
_glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.floating = value ? true : false;
|
||||
return;
|
||||
case GLFW_MAXIMIZED:
|
||||
_glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.maximized = value ? true : false;
|
||||
return;
|
||||
case GLFW_VISIBLE:
|
||||
_glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.visible = value ? true : false;
|
||||
return;
|
||||
case GLFW_COCOA_RETINA_FRAMEBUFFER:
|
||||
_glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.ns.retina = value ? true : false;
|
||||
return;
|
||||
case GLFW_COCOA_GRAPHICS_SWITCHING:
|
||||
_glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.nsgl.offline = value ? true : false;
|
||||
return;
|
||||
case GLFW_SCALE_TO_MONITOR:
|
||||
_glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.scaleToMonitor = value ? true : false;
|
||||
return;
|
||||
case GLFW_CENTER_CURSOR:
|
||||
_glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.centerCursor = value ? true : false;
|
||||
return;
|
||||
case GLFW_FOCUS_ON_SHOW:
|
||||
_glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.window.focusOnShow = value ? true : false;
|
||||
return;
|
||||
case GLFW_CLIENT_API:
|
||||
_glfw.hints.context.client = value;
|
||||
@@ -418,13 +433,13 @@ GLFWAPI void glfwWindowHint(int hint, int value)
|
||||
_glfw.hints.context.robustness = value;
|
||||
return;
|
||||
case GLFW_OPENGL_FORWARD_COMPAT:
|
||||
_glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.forward = value ? true : false;
|
||||
return;
|
||||
case GLFW_OPENGL_DEBUG_CONTEXT:
|
||||
_glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.debug = value ? true : false;
|
||||
return;
|
||||
case GLFW_CONTEXT_NO_ERROR:
|
||||
_glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
_glfw.hints.context.noerror = value ? true : false;
|
||||
return;
|
||||
case GLFW_OPENGL_PROFILE:
|
||||
_glfw.hints.context.profile = value;
|
||||
@@ -801,8 +816,10 @@ GLFWAPI void glfwShowWindow(GLFWwindow* handle)
|
||||
|
||||
_glfwPlatformShowWindow(window);
|
||||
|
||||
#ifndef _GLFW_WAYLAND
|
||||
if (window->focusOnShow)
|
||||
_glfwPlatformFocusWindow(window);
|
||||
#endif
|
||||
}
|
||||
|
||||
GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle)
|
||||
@@ -820,7 +837,7 @@ GLFWAPI int glfwWindowBell(GLFWwindow* handle)
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(false);
|
||||
|
||||
return _glfwPlatformWindowBell(window);
|
||||
}
|
||||
@@ -871,6 +888,8 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib)
|
||||
return window->focusOnShow;
|
||||
case GLFW_TRANSPARENT_FRAMEBUFFER:
|
||||
return _glfwPlatformFramebufferTransparent(window);
|
||||
case GLFW_OCCLUDED:
|
||||
return _glfwPlatformWindowOccluded(window);
|
||||
case GLFW_RESIZABLE:
|
||||
return window->resizable;
|
||||
case GLFW_DECORATED:
|
||||
@@ -914,7 +933,7 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
value = value ? GLFW_TRUE : GLFW_FALSE;
|
||||
value = value ? true : false;
|
||||
|
||||
if (attrib == GLFW_AUTO_ICONIFY)
|
||||
window->autoIconify = value;
|
||||
@@ -999,6 +1018,12 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh,
|
||||
refreshRate);
|
||||
}
|
||||
|
||||
GLFWAPI bool glfwToggleFullscreen(GLFWwindow* wh, unsigned int flags) {
|
||||
_GLFWwindow* window = (_GLFWwindow*) wh;
|
||||
if (window) return _glfwPlatformToggleFullscreen(window, flags);
|
||||
return false;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
@@ -1072,6 +1097,17 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle,
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWwindowocclusionfun glfwSetWindowOcclusionCallback(GLFWwindow* handle,
|
||||
GLFWwindowocclusionfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.occlusion, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle,
|
||||
GLFWwindowiconifyfun cbfun)
|
||||
{
|
||||
@@ -1105,6 +1141,17 @@ GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWliveresizefun glfwSetLiveResizeCallback(GLFWwindow* handle,
|
||||
GLFWliveresizefun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
assert(window != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.liveResize, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* handle,
|
||||
GLFWwindowcontentscalefun cbfun)
|
||||
{
|
||||
@@ -1116,44 +1163,8 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwPollEvents(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT();
|
||||
_glfwPlatformPollEvents();
|
||||
}
|
||||
|
||||
GLFWAPI void glfwWaitEvents(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (!_glfw.windowListHead)
|
||||
return;
|
||||
|
||||
_glfwPlatformWaitEvents();
|
||||
}
|
||||
|
||||
GLFWAPI void glfwWaitEventsTimeout(double timeout)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT();
|
||||
assert(timeout == timeout);
|
||||
assert(timeout >= 0.0);
|
||||
assert(timeout <= DBL_MAX);
|
||||
|
||||
if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwPlatformWaitEventsTimeout(timeout);
|
||||
}
|
||||
|
||||
GLFWAPI void glfwPostEmptyEvent(void)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
if (!_glfw.windowListHead)
|
||||
return;
|
||||
|
||||
_glfwPlatformPostEmptyEvent();
|
||||
}
|
||||
|
||||
312
glfw/wl_init.c
vendored
312
glfw/wl_init.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Wayland - www.glfw.org
|
||||
// GLFW 3.4 Wayland - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -23,6 +23,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "internal.h"
|
||||
@@ -31,7 +33,6 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <linux/input.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -39,6 +40,16 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <wayland-client.h>
|
||||
// Needed for the BTN_* defines
|
||||
#ifdef __has_include
|
||||
#if __has_include(<linux/input.h>)
|
||||
#include <linux/input.h>
|
||||
#elif __has_include(<dev/evdev/input.h>)
|
||||
#include <dev/evdev/input.h>
|
||||
#endif
|
||||
#else
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
|
||||
|
||||
static inline int min(int n1, int n2)
|
||||
@@ -46,7 +57,8 @@ static inline int min(int n1, int n2)
|
||||
return n1 < n2 ? n1 : n2;
|
||||
}
|
||||
|
||||
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface, int* which)
|
||||
static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
||||
int* which)
|
||||
{
|
||||
int focus;
|
||||
_GLFWwindow* window = _glfw.windowListHead;
|
||||
@@ -79,12 +91,12 @@ static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
|
||||
return window;
|
||||
}
|
||||
|
||||
static void pointerHandleEnter(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
static void pointerHandleEnter(void* data UNUSED,
|
||||
struct wl_pointer* pointer UNUSED,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface,
|
||||
wl_fixed_t sx,
|
||||
wl_fixed_t sy)
|
||||
wl_fixed_t sx UNUSED,
|
||||
wl_fixed_t sy UNUSED)
|
||||
{
|
||||
// Happens in the case we just destroyed the surface.
|
||||
if (!surface)
|
||||
@@ -103,44 +115,38 @@ static void pointerHandleEnter(void* data,
|
||||
_glfw.wl.pointerSerial = serial;
|
||||
_glfw.wl.pointerFocus = window;
|
||||
|
||||
window->wl.hovered = GLFW_TRUE;
|
||||
window->wl.hovered = true;
|
||||
|
||||
_glfwPlatformSetCursor(window, window->wl.currentCursor);
|
||||
_glfwInputCursorEnter(window, GLFW_TRUE);
|
||||
_glfwInputCursorEnter(window, true);
|
||||
}
|
||||
|
||||
static void pointerHandleLeave(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
static void pointerHandleLeave(void* data UNUSED,
|
||||
struct wl_pointer* pointer UNUSED,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface)
|
||||
struct wl_surface* surface UNUSED)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
window->wl.hovered = GLFW_FALSE;
|
||||
window->wl.hovered = false;
|
||||
|
||||
_glfw.wl.pointerSerial = serial;
|
||||
_glfw.wl.pointerFocus = NULL;
|
||||
_glfwInputCursorEnter(window, GLFW_FALSE);
|
||||
_glfwInputCursorEnter(window, false);
|
||||
}
|
||||
|
||||
static void setCursor(const char* name)
|
||||
static void setCursor(GLFWCursorShape shape)
|
||||
{
|
||||
struct wl_buffer* buffer;
|
||||
struct wl_cursor* cursor;
|
||||
struct wl_cursor_image* image;
|
||||
struct wl_surface* surface = _glfw.wl.cursorSurface;
|
||||
|
||||
cursor = wl_cursor_theme_get_cursor(_glfw.wl.cursorTheme,
|
||||
name);
|
||||
if (!cursor)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Standard cursor not found");
|
||||
return;
|
||||
}
|
||||
cursor = _glfwLoadCursor(shape);
|
||||
if (!cursor) return;
|
||||
// TODO: handle animated cursors too.
|
||||
image = cursor->images[0];
|
||||
|
||||
@@ -160,77 +166,71 @@ static void setCursor(const char* name)
|
||||
wl_surface_commit(surface);
|
||||
}
|
||||
|
||||
static void pointerHandleMotion(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
uint32_t time,
|
||||
static void pointerHandleMotion(void* data UNUSED,
|
||||
struct wl_pointer* pointer UNUSED,
|
||||
uint32_t time UNUSED,
|
||||
wl_fixed_t sx,
|
||||
wl_fixed_t sy)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||
const char* cursorName = NULL;
|
||||
GLFWCursorShape cursorShape = GLFW_ARROW_CURSOR;
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
if (window->cursorMode == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
else
|
||||
{
|
||||
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
||||
}
|
||||
window->wl.cursorPosX = wl_fixed_to_double(sx);
|
||||
window->wl.cursorPosY = wl_fixed_to_double(sy);
|
||||
|
||||
switch (window->wl.decorations.focus)
|
||||
{
|
||||
case mainWindow:
|
||||
_glfwInputCursorPos(window,
|
||||
wl_fixed_to_double(sx),
|
||||
wl_fixed_to_double(sy));
|
||||
window->wl.cursorPosX, window->wl.cursorPosY);
|
||||
return;
|
||||
case topDecoration:
|
||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||
cursorName = "n-resize";
|
||||
cursorShape = GLFW_VRESIZE_CURSOR;
|
||||
else
|
||||
cursorName = "left_ptr";
|
||||
cursorShape = GLFW_ARROW_CURSOR;
|
||||
break;
|
||||
case leftDecoration:
|
||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||
cursorName = "nw-resize";
|
||||
cursorShape = GLFW_NW_RESIZE_CURSOR;
|
||||
else
|
||||
cursorName = "w-resize";
|
||||
cursorShape = GLFW_HRESIZE_CURSOR;
|
||||
break;
|
||||
case rightDecoration:
|
||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||
cursorName = "ne-resize";
|
||||
cursorShape = GLFW_NE_RESIZE_CURSOR;
|
||||
else
|
||||
cursorName = "e-resize";
|
||||
cursorShape = GLFW_HRESIZE_CURSOR;
|
||||
break;
|
||||
case bottomDecoration:
|
||||
if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH)
|
||||
cursorName = "sw-resize";
|
||||
cursorShape = GLFW_SW_RESIZE_CURSOR;
|
||||
else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH)
|
||||
cursorName = "se-resize";
|
||||
cursorShape = GLFW_SE_RESIZE_CURSOR;
|
||||
else
|
||||
cursorName = "s-resize";
|
||||
cursorShape = GLFW_VRESIZE_CURSOR;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
setCursor(cursorName);
|
||||
setCursor(cursorShape);
|
||||
}
|
||||
|
||||
static void pointerHandleButton(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
static void pointerHandleButton(void* data UNUSED,
|
||||
struct wl_pointer* pointer UNUSED,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
uint32_t time UNUSED,
|
||||
uint32_t button,
|
||||
uint32_t state)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.pointerFocus;
|
||||
int glfwButton;
|
||||
|
||||
// Both xdg-shell and wl_shell use the same values.
|
||||
uint32_t edges = WL_SHELL_SURFACE_RESIZE_NONE;
|
||||
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
|
||||
|
||||
if (!window)
|
||||
return;
|
||||
@@ -242,46 +242,40 @@ static void pointerHandleButton(void* data,
|
||||
break;
|
||||
case topDecoration:
|
||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||
edges = WL_SHELL_SURFACE_RESIZE_TOP;
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
|
||||
else
|
||||
{
|
||||
if (window->wl.xdg.toplevel)
|
||||
xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
|
||||
else
|
||||
wl_shell_surface_move(window->wl.shellSurface, _glfw.wl.seat, serial);
|
||||
}
|
||||
break;
|
||||
case leftDecoration:
|
||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||
edges = WL_SHELL_SURFACE_RESIZE_TOP_LEFT;
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
|
||||
else
|
||||
edges = WL_SHELL_SURFACE_RESIZE_LEFT;
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
|
||||
break;
|
||||
case rightDecoration:
|
||||
if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
|
||||
edges = WL_SHELL_SURFACE_RESIZE_TOP_RIGHT;
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
|
||||
else
|
||||
edges = WL_SHELL_SURFACE_RESIZE_RIGHT;
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
|
||||
break;
|
||||
case bottomDecoration:
|
||||
if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH)
|
||||
edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT;
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
|
||||
else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH)
|
||||
edges = WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT;
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
|
||||
else
|
||||
edges = WL_SHELL_SURFACE_RESIZE_BOTTOM;
|
||||
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
if (edges != WL_SHELL_SURFACE_RESIZE_NONE)
|
||||
if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)
|
||||
{
|
||||
if (window->wl.xdg.toplevel)
|
||||
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
|
||||
serial, edges);
|
||||
else
|
||||
wl_shell_surface_resize(window->wl.shellSurface, _glfw.wl.seat,
|
||||
serial, edges);
|
||||
xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
|
||||
serial, edges);
|
||||
}
|
||||
}
|
||||
else if (button == BTN_RIGHT)
|
||||
@@ -314,9 +308,9 @@ static void pointerHandleButton(void* data,
|
||||
_glfw.wl.xkb.states.modifiers);
|
||||
}
|
||||
|
||||
static void pointerHandleAxis(void* data,
|
||||
struct wl_pointer* pointer,
|
||||
uint32_t time,
|
||||
static void pointerHandleAxis(void* data UNUSED,
|
||||
struct wl_pointer* pointer UNUSED,
|
||||
uint32_t time UNUSED,
|
||||
uint32_t axis,
|
||||
wl_fixed_t value)
|
||||
{
|
||||
@@ -344,8 +338,8 @@ static const struct wl_pointer_listener pointerListener = {
|
||||
pointerHandleAxis,
|
||||
};
|
||||
|
||||
static void keyboardHandleKeymap(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
static void keyboardHandleKeymap(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard UNUSED,
|
||||
uint32_t format,
|
||||
int fd,
|
||||
uint32_t size)
|
||||
@@ -369,11 +363,11 @@ static void keyboardHandleKeymap(void* data,
|
||||
|
||||
}
|
||||
|
||||
static void keyboardHandleEnter(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
static void keyboardHandleEnter(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard UNUSED,
|
||||
uint32_t serial UNUSED,
|
||||
struct wl_surface* surface,
|
||||
struct wl_array* keys)
|
||||
struct wl_array* keys UNUSED)
|
||||
{
|
||||
// Happens in the case we just destroyed the surface.
|
||||
if (!surface)
|
||||
@@ -388,13 +382,13 @@ static void keyboardHandleEnter(void* data,
|
||||
}
|
||||
|
||||
_glfw.wl.keyboardFocus = window;
|
||||
_glfwInputWindowFocus(window, GLFW_TRUE);
|
||||
_glfwInputWindowFocus(window, true);
|
||||
}
|
||||
|
||||
static void keyboardHandleLeave(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
struct wl_surface* surface)
|
||||
static void keyboardHandleLeave(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard UNUSED,
|
||||
uint32_t serial UNUSED,
|
||||
struct wl_surface* surface UNUSED)
|
||||
{
|
||||
_GLFWwindow* window = _glfw.wl.keyboardFocus;
|
||||
|
||||
@@ -402,11 +396,11 @@ static void keyboardHandleLeave(void* data,
|
||||
return;
|
||||
|
||||
_glfw.wl.keyboardFocus = NULL;
|
||||
_glfwInputWindowFocus(window, GLFW_FALSE);
|
||||
_glfwInputWindowFocus(window, false);
|
||||
}
|
||||
|
||||
static void
|
||||
dispatchPendingKeyRepeats(id_type timer_id, void *data) {
|
||||
dispatchPendingKeyRepeats(id_type timer_id UNUSED, void *data UNUSED) {
|
||||
if (_glfw.wl.keyRepeatInfo.keyboardFocus != _glfw.wl.keyboardFocus || _glfw.wl.keyboardRepeatRate == 0) return;
|
||||
glfw_xkb_handle_key_event(_glfw.wl.keyRepeatInfo.keyboardFocus, &_glfw.wl.xkb, _glfw.wl.keyRepeatInfo.key, GLFW_REPEAT);
|
||||
changeTimerInterval(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, (1.0 / (double)_glfw.wl.keyboardRepeatRate));
|
||||
@@ -414,10 +408,10 @@ dispatchPendingKeyRepeats(id_type timer_id, void *data) {
|
||||
}
|
||||
|
||||
|
||||
static void keyboardHandleKey(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
uint32_t time,
|
||||
static void keyboardHandleKey(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard UNUSED,
|
||||
uint32_t serial UNUSED,
|
||||
uint32_t time UNUSED,
|
||||
uint32_t key,
|
||||
uint32_t state)
|
||||
{
|
||||
@@ -426,12 +420,12 @@ static void keyboardHandleKey(void* data,
|
||||
return;
|
||||
int action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;
|
||||
glfw_xkb_handle_key_event(window, &_glfw.wl.xkb, key, action);
|
||||
GLFWbool repeatable = GLFW_FALSE;
|
||||
bool repeatable = false;
|
||||
|
||||
if (action == GLFW_PRESS && _glfw.wl.keyboardRepeatRate > 0 && glfw_xkb_should_repeat(&_glfw.wl.xkb, key))
|
||||
{
|
||||
_glfw.wl.keyRepeatInfo.key = key;
|
||||
repeatable = GLFW_TRUE;
|
||||
repeatable = true;
|
||||
_glfw.wl.keyRepeatInfo.keyboardFocus = window;
|
||||
}
|
||||
if (repeatable) {
|
||||
@@ -440,9 +434,9 @@ static void keyboardHandleKey(void* data,
|
||||
toggleTimer(&_glfw.wl.eventLoopData, _glfw.wl.keyRepeatInfo.keyRepeatTimer, repeatable ? 1 : 0);
|
||||
}
|
||||
|
||||
static void keyboardHandleModifiers(void* data,
|
||||
struct wl_keyboard* keyboard,
|
||||
uint32_t serial,
|
||||
static void keyboardHandleModifiers(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard UNUSED,
|
||||
uint32_t serial UNUSED,
|
||||
uint32_t modsDepressed,
|
||||
uint32_t modsLatched,
|
||||
uint32_t modsLocked,
|
||||
@@ -451,7 +445,7 @@ static void keyboardHandleModifiers(void* data,
|
||||
glfw_xkb_update_modifiers(&_glfw.wl.xkb, modsDepressed, modsLatched, modsLocked, 0, 0, group);
|
||||
}
|
||||
|
||||
static void keyboardHandleRepeatInfo(void* data,
|
||||
static void keyboardHandleRepeatInfo(void* data UNUSED,
|
||||
struct wl_keyboard* keyboard,
|
||||
int32_t rate,
|
||||
int32_t delay)
|
||||
@@ -472,7 +466,7 @@ static const struct wl_keyboard_listener keyboardListener = {
|
||||
keyboardHandleRepeatInfo,
|
||||
};
|
||||
|
||||
static void seatHandleCapabilities(void* data,
|
||||
static void seatHandleCapabilities(void* data UNUSED,
|
||||
struct wl_seat* seat,
|
||||
enum wl_seat_capability caps)
|
||||
{
|
||||
@@ -499,9 +493,9 @@ static void seatHandleCapabilities(void* data,
|
||||
}
|
||||
}
|
||||
|
||||
static void seatHandleName(void* data,
|
||||
struct wl_seat* seat,
|
||||
const char* name)
|
||||
static void seatHandleName(void* data UNUSED,
|
||||
struct wl_seat* seat UNUSED,
|
||||
const char* name UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -510,7 +504,7 @@ static const struct wl_seat_listener seatListener = {
|
||||
seatHandleName,
|
||||
};
|
||||
|
||||
static void wmBaseHandlePing(void* data,
|
||||
static void wmBaseHandlePing(void* data UNUSED,
|
||||
struct xdg_wm_base* wmBase,
|
||||
uint32_t serial)
|
||||
{
|
||||
@@ -521,7 +515,7 @@ static const struct xdg_wm_base_listener wmBaseListener = {
|
||||
wmBaseHandlePing
|
||||
};
|
||||
|
||||
static void registryHandleGlobal(void* data,
|
||||
static void registryHandleGlobal(void* data UNUSED,
|
||||
struct wl_registry* registry,
|
||||
uint32_t name,
|
||||
const char* interface,
|
||||
@@ -544,11 +538,6 @@ static void registryHandleGlobal(void* data,
|
||||
_glfw.wl.shm =
|
||||
wl_registry_bind(registry, name, &wl_shm_interface, 1);
|
||||
}
|
||||
else if (strcmp(interface, "wl_shell") == 0)
|
||||
{
|
||||
_glfw.wl.shell =
|
||||
wl_registry_bind(registry, name, &wl_shell_interface, 1);
|
||||
}
|
||||
else if (strcmp(interface, "wl_output") == 0)
|
||||
{
|
||||
_glfwAddOutputWayland(name, version);
|
||||
@@ -632,18 +621,24 @@ static void registryHandleGlobal(void* data,
|
||||
|
||||
}
|
||||
|
||||
static void registryHandleGlobalRemove(void *data,
|
||||
struct wl_registry *registry,
|
||||
static void registryHandleGlobalRemove(void *data UNUSED,
|
||||
struct wl_registry *registry UNUSED,
|
||||
uint32_t name)
|
||||
{
|
||||
int i;
|
||||
_GLFWmonitor* monitor;
|
||||
|
||||
for (i = 0; i < _glfw.monitorCount; ++i)
|
||||
for (int i = 0; i < _glfw.monitorCount; ++i)
|
||||
{
|
||||
monitor = _glfw.monitors[i];
|
||||
if (monitor->wl.name == name)
|
||||
{
|
||||
for (_GLFWwindow *window = _glfw.windowListHead; window; window = window->next) {
|
||||
for (int m = window->wl.monitorsCount - 1; m >= 0; m--) {
|
||||
if (window->wl.monitors[m] == monitor) {
|
||||
remove_i_from_array(window->wl.monitors, m, window->wl.monitorsCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
_glfwInputMonitor(monitor, GLFW_DISCONNECTED, 0);
|
||||
return;
|
||||
}
|
||||
@@ -657,67 +652,89 @@ static const struct wl_registry_listener registryListener = {
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void registry_handle_global(void* data,
|
||||
struct wl_registry* registry UNUSED,
|
||||
uint32_t name UNUSED,
|
||||
const char* interface,
|
||||
uint32_t version UNUSED) {
|
||||
if (strcmp(interface, "zxdg_decoration_manager_v1") == 0) {
|
||||
bool *has_ssd = (bool*)data;
|
||||
if (has_ssd) *has_ssd = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void registry_handle_global_remove(void *data UNUSED,
|
||||
struct wl_registry *registry UNUSED,
|
||||
uint32_t name UNUSED) {}
|
||||
GLFWAPI const char*
|
||||
glfwWaylandCheckForServerSideDecorations(void) {
|
||||
struct wl_display *display = wl_display_connect(NULL);
|
||||
if (!display) return "ERR: Failed to connect to Wayland display";
|
||||
static const struct wl_registry_listener rl = {
|
||||
registry_handle_global, registry_handle_global_remove
|
||||
};
|
||||
struct wl_registry *registry = wl_display_get_registry(display);
|
||||
bool has_ssd = false;
|
||||
wl_registry_add_listener(registry, &rl, &has_ssd);
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
wl_registry_destroy(registry);
|
||||
wl_display_flush(display);
|
||||
wl_display_flush(display);
|
||||
return has_ssd ? "YES" : "NO";
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformInit(void)
|
||||
{
|
||||
if (pipe2(_glfw.wl.eventLoopData.wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: failed to create self pipe");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
|
||||
if (!_glfw.wl.cursor.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to open libwayland-cursor");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load)
|
||||
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_load");
|
||||
_glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy)
|
||||
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
|
||||
_glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor)
|
||||
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
|
||||
_glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer)
|
||||
_glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");
|
||||
glfw_dlsym(_glfw.wl.cursor.theme_load, _glfw.wl.cursor.handle, "wl_cursor_theme_load");
|
||||
glfw_dlsym(_glfw.wl.cursor.theme_destroy, _glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
|
||||
glfw_dlsym(_glfw.wl.cursor.theme_get_cursor, _glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
|
||||
glfw_dlsym(_glfw.wl.cursor.image_get_buffer, _glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");
|
||||
|
||||
_glfw.wl.egl.handle = _glfw_dlopen("libwayland-egl.so.1");
|
||||
if (!_glfw.wl.egl.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to open libwayland-egl");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
_glfw.wl.egl.window_create = (PFN_wl_egl_window_create)
|
||||
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_create");
|
||||
_glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy)
|
||||
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_destroy");
|
||||
_glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize)
|
||||
_glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_resize");
|
||||
glfw_dlsym(_glfw.wl.egl.window_create, _glfw.wl.egl.handle, "wl_egl_window_create");
|
||||
glfw_dlsym(_glfw.wl.egl.window_destroy, _glfw.wl.egl.handle, "wl_egl_window_destroy");
|
||||
glfw_dlsym(_glfw.wl.egl.window_resize, _glfw.wl.egl.handle, "wl_egl_window_resize");
|
||||
|
||||
_glfw.wl.display = wl_display_connect(NULL);
|
||||
if (!_glfw.wl.display)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to connect to display");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
if (!initPollData(&_glfw.wl.eventLoopData, wl_display_get_fd(_glfw.wl.display))) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to initialize event loop data");
|
||||
}
|
||||
initPollData(&_glfw.wl.eventLoopData, _glfw.wl.eventLoopData.wakeupFds[0], wl_display_get_fd(_glfw.wl.display));
|
||||
glfw_dbus_init(&_glfw.wl.dbus, &_glfw.wl.eventLoopData);
|
||||
_glfw.wl.keyRepeatInfo.keyRepeatTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-key-repeat", 0.5, 0, dispatchPendingKeyRepeats, NULL);
|
||||
_glfw.wl.cursorAnimationTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-cursor-animation", 0.5, 0, animateCursorImage, NULL);
|
||||
_glfw.wl.keyRepeatInfo.keyRepeatTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-key-repeat", 0.5, 0, true, dispatchPendingKeyRepeats, NULL, NULL);
|
||||
_glfw.wl.cursorAnimationTimer = addTimer(&_glfw.wl.eventLoopData, "wayland-cursor-animation", 0.5, 0, true, animateCursorImage, NULL, NULL);
|
||||
|
||||
_glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
|
||||
wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL);
|
||||
|
||||
if (!glfw_xkb_create_context(&_glfw.wl.xkb)) return GLFW_FALSE;
|
||||
if (!glfw_xkb_create_context(&_glfw.wl.xkb)) return false;
|
||||
|
||||
// Sync so we got all registry objects
|
||||
wl_display_roundtrip(_glfw.wl.display);
|
||||
@@ -728,13 +745,19 @@ int _glfwPlatformInit(void)
|
||||
#ifdef __linux__
|
||||
if (_glfw.hints.init.enableJoysticks) {
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
_glfwInitTimerPOSIX();
|
||||
if (!_glfw.wl.wmBase)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Failed to find xdg-shell in your compositor");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_glfw.wl.pointer && _glfw.wl.shm)
|
||||
if (_glfw.wl.shm)
|
||||
{
|
||||
const char *cursorTheme = getenv("XCURSOR_THEME"), *cursorSizeStr = getenv("XCURSOR_SIZE");
|
||||
char *cursorSizeEnd;
|
||||
@@ -751,13 +774,13 @@ int _glfwPlatformInit(void)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Unable to load default cursor theme");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
_glfw.wl.cursorSurface =
|
||||
wl_compositor_create_surface(_glfw.wl.compositor);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
@@ -791,8 +814,6 @@ void _glfwPlatformTerminate(void)
|
||||
wl_compositor_destroy(_glfw.wl.compositor);
|
||||
if (_glfw.wl.shm)
|
||||
wl_shm_destroy(_glfw.wl.shm);
|
||||
if (_glfw.wl.shell)
|
||||
wl_shell_destroy(_glfw.wl.shell);
|
||||
if (_glfw.wl.viewporter)
|
||||
wp_viewporter_destroy(_glfw.wl.viewporter);
|
||||
if (_glfw.wl.decorationManager)
|
||||
@@ -833,7 +854,7 @@ void _glfwPlatformTerminate(void)
|
||||
wl_display_flush(_glfw.wl.display);
|
||||
wl_display_disconnect(_glfw.wl.display);
|
||||
}
|
||||
closeFds(_glfw.wl.eventLoopData.wakeupFds, sizeof(_glfw.wl.eventLoopData.wakeupFds)/sizeof(_glfw.wl.eventLoopData.wakeupFds[0]));
|
||||
finalizePollData(&_glfw.wl.eventLoopData);
|
||||
free(_glfw.wl.clipboardString); _glfw.wl.clipboardString = NULL;
|
||||
free(_glfw.wl.primarySelectionString); _glfw.wl.primarySelectionString = NULL;
|
||||
free(_glfw.wl.pasteString); _glfw.wl.pasteString = NULL;
|
||||
@@ -842,7 +863,7 @@ void _glfwPlatformTerminate(void)
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
{
|
||||
return _GLFW_VERSION_NUMBER " Wayland EGL"
|
||||
return _GLFW_VERSION_NUMBER " Wayland EGL OSMesa"
|
||||
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
|
||||
" clock_gettime"
|
||||
#else
|
||||
@@ -854,3 +875,6 @@ const char* _glfwPlatformGetVersionString(void)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
#define GLFW_LOOP_BACKEND wl
|
||||
#include "main_loop.h"
|
||||
|
||||
74
glfw/wl_monitor.c
vendored
74
glfw/wl_monitor.c
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Wayland - www.glfw.org
|
||||
// GLFW 3.4 Wayland - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -23,6 +23,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -30,18 +32,19 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
static void outputHandleGeometry(void* data,
|
||||
struct wl_output* output,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
int32_t physicalWidth,
|
||||
int32_t physicalHeight,
|
||||
int32_t subpixel,
|
||||
const char* make,
|
||||
const char* model,
|
||||
int32_t transform)
|
||||
struct wl_output* output UNUSED,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
int32_t physicalWidth,
|
||||
int32_t physicalHeight,
|
||||
int32_t subpixel UNUSED,
|
||||
const char* make,
|
||||
const char* model,
|
||||
int32_t transform UNUSED)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
char name[1024];
|
||||
@@ -56,11 +59,11 @@ static void outputHandleGeometry(void* data,
|
||||
}
|
||||
|
||||
static void outputHandleMode(void* data,
|
||||
struct wl_output* output,
|
||||
uint32_t flags,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t refresh)
|
||||
struct wl_output* output UNUSED,
|
||||
uint32_t flags,
|
||||
int32_t width,
|
||||
int32_t height,
|
||||
int32_t refresh)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
GLFWvidmode mode;
|
||||
@@ -70,7 +73,7 @@ static void outputHandleMode(void* data,
|
||||
mode.redBits = 8;
|
||||
mode.greenBits = 8;
|
||||
mode.blueBits = 8;
|
||||
mode.refreshRate = refresh / 1000;
|
||||
mode.refreshRate = (int) round(refresh / 1000.0);
|
||||
|
||||
monitor->modeCount++;
|
||||
monitor->modes =
|
||||
@@ -81,20 +84,23 @@ static void outputHandleMode(void* data,
|
||||
monitor->wl.currentMode = monitor->modeCount - 1;
|
||||
}
|
||||
|
||||
static void outputHandleDone(void* data, struct wl_output* output)
|
||||
static void outputHandleDone(void* data, struct wl_output* output UNUSED)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
for (int i = 0; i < _glfw.monitorCount; i++) {
|
||||
if (_glfw.monitors[i] == monitor) return;
|
||||
}
|
||||
|
||||
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
|
||||
}
|
||||
|
||||
static void outputHandleScale(void* data,
|
||||
struct wl_output* output,
|
||||
int32_t factor)
|
||||
struct wl_output* output UNUSED,
|
||||
int32_t factor)
|
||||
{
|
||||
struct _GLFWmonitor *monitor = data;
|
||||
|
||||
monitor->wl.scale = factor;
|
||||
if (factor > 0 && factor < 24)
|
||||
monitor->wl.scale = factor;
|
||||
}
|
||||
|
||||
static const struct wl_output_listener outputListener = {
|
||||
@@ -169,6 +175,20 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
*yscale = (float) monitor->wl.scale;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
|
||||
int* xpos, int* ypos,
|
||||
int* width, int* height)
|
||||
{
|
||||
if (xpos)
|
||||
*xpos = monitor->wl.x;
|
||||
if (ypos)
|
||||
*ypos = monitor->wl.y;
|
||||
if (width)
|
||||
*width = monitor->modes[monitor->wl.currentMode].width;
|
||||
if (height)
|
||||
*height = monitor->modes[monitor->wl.currentMode].height;
|
||||
}
|
||||
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||
{
|
||||
*found = monitor->modeCount;
|
||||
@@ -180,18 +200,18 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
*mode = monitor->modes[monitor->wl.currentMode];
|
||||
}
|
||||
|
||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor UNUSED, GLFWgammaramp* ramp UNUSED)
|
||||
{
|
||||
// TODO
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Gamma ramp getting not supported yet");
|
||||
"Wayland: Gamma ramp access is not available");
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor UNUSED,
|
||||
const GLFWgammaramp* ramp UNUSED)
|
||||
{
|
||||
// TODO
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Wayland: Gamma ramp setting not supported yet");
|
||||
"Wayland: Gamma ramp access is not available");
|
||||
}
|
||||
|
||||
|
||||
|
||||
24
glfw/wl_platform.h
vendored
24
glfw/wl_platform.h
vendored
@@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Wayland - www.glfw.org
|
||||
// GLFW 3.4 Wayland - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
@@ -133,13 +133,12 @@ typedef struct _GLFWdecorationWayland
|
||||
typedef struct _GLFWwindowWayland
|
||||
{
|
||||
int width, height;
|
||||
GLFWbool visible;
|
||||
GLFWbool maximized;
|
||||
GLFWbool hovered;
|
||||
GLFWbool transparent;
|
||||
bool visible;
|
||||
bool maximized;
|
||||
bool hovered;
|
||||
bool transparent;
|
||||
struct wl_surface* surface;
|
||||
struct wl_egl_window* native;
|
||||
struct wl_shell_surface* shellSurface;
|
||||
struct wl_callback* callback;
|
||||
|
||||
struct {
|
||||
@@ -168,11 +167,10 @@ typedef struct _GLFWwindowWayland
|
||||
|
||||
struct zwp_idle_inhibitor_v1* idleInhibitor;
|
||||
|
||||
// This is a hack to prevent auto-iconification on creation.
|
||||
GLFWbool justCreated;
|
||||
bool fullscreened;
|
||||
|
||||
struct {
|
||||
GLFWbool serverSide;
|
||||
bool serverSide;
|
||||
struct wl_buffer* buffer;
|
||||
_GLFWdecorationWayland top, left, right, bottom;
|
||||
int focus;
|
||||
@@ -227,7 +225,6 @@ typedef struct _GLFWlibraryWayland
|
||||
struct wl_registry* registry;
|
||||
struct wl_compositor* compositor;
|
||||
struct wl_subcompositor* subcompositor;
|
||||
struct wl_shell* shell;
|
||||
struct wl_shm* shm;
|
||||
struct wl_seat* seat;
|
||||
struct wl_pointer* pointer;
|
||||
@@ -298,7 +295,7 @@ typedef struct _GLFWlibraryWayland
|
||||
typedef struct _GLFWmonitorWayland
|
||||
{
|
||||
struct wl_output* output;
|
||||
int name;
|
||||
uint32_t name;
|
||||
int currentMode;
|
||||
|
||||
int x;
|
||||
@@ -320,6 +317,7 @@ typedef struct _GLFWcursorWayland
|
||||
|
||||
|
||||
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
|
||||
void _glfwSetupWaylandDataDevice();
|
||||
void _glfwSetupWaylandPrimarySelectionDevice();
|
||||
void _glfwSetupWaylandDataDevice(void);
|
||||
void _glfwSetupWaylandPrimarySelectionDevice(void);
|
||||
void animateCursorImage(id_type timer_id, void *data);
|
||||
struct wl_cursor* _glfwLoadCursor(GLFWCursorShape);
|
||||
|
||||
871
glfw/wl_window.c
vendored
871
glfw/wl_window.c
vendored
File diff suppressed because it is too large
Load Diff
223
glfw/x11_init.c
vendored
223
glfw/x11_init.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 X11 - www.glfw.org
|
||||
// GLFW 3.4 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,6 +24,8 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include "internal.h"
|
||||
@@ -46,10 +48,9 @@ static Atom getSupportedAtom(Atom* supportedAtoms,
|
||||
unsigned long atomCount,
|
||||
const char* atomName)
|
||||
{
|
||||
unsigned long i;
|
||||
const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
|
||||
|
||||
for (i = 0; i < atomCount; i++)
|
||||
for (unsigned long i = 0; i < atomCount; i++)
|
||||
{
|
||||
if (supportedAtoms[i] == atom)
|
||||
return atom;
|
||||
@@ -62,18 +63,12 @@ static Atom getSupportedAtom(Atom* supportedAtoms,
|
||||
//
|
||||
static void detectEWMH(void)
|
||||
{
|
||||
// First we read the _NET_SUPPORTING_WM_CHECK property on the root window
|
||||
Window* windowFromRoot = NULL;
|
||||
Window* windowFromChild = NULL;
|
||||
|
||||
// First we need a couple of atoms
|
||||
const Atom supportingWmCheck =
|
||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
|
||||
const Atom wmSupported =
|
||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
|
||||
|
||||
// Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
|
||||
if (!_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
supportingWmCheck,
|
||||
_glfw.x11.NET_SUPPORTING_WM_CHECK,
|
||||
XA_WINDOW,
|
||||
(unsigned char**) &windowFromRoot))
|
||||
{
|
||||
@@ -82,10 +77,12 @@ static void detectEWMH(void)
|
||||
|
||||
_glfwGrabErrorHandlerX11();
|
||||
|
||||
// It should be the ID of a child window (of the root)
|
||||
// Then we look for the same property on the child window
|
||||
// If it exists, it should be the XID of a top-level window
|
||||
// Then we look for the same property on that window
|
||||
|
||||
Window* windowFromChild = NULL;
|
||||
if (!_glfwGetWindowPropertyX11(*windowFromRoot,
|
||||
supportingWmCheck,
|
||||
_glfw.x11.NET_SUPPORTING_WM_CHECK,
|
||||
XA_WINDOW,
|
||||
(unsigned char**) &windowFromChild))
|
||||
{
|
||||
@@ -95,7 +92,7 @@ static void detectEWMH(void)
|
||||
|
||||
_glfwReleaseErrorHandlerX11();
|
||||
|
||||
// It should be the ID of that same child window
|
||||
// If the property exists, it should contain the XID of the window
|
||||
if (*windowFromRoot != *windowFromChild)
|
||||
{
|
||||
XFree(windowFromRoot);
|
||||
@@ -107,18 +104,20 @@ static void detectEWMH(void)
|
||||
XFree(windowFromChild);
|
||||
|
||||
// We are now fairly sure that an EWMH-compliant window manager is running
|
||||
// We can now start querying the WM about what features it supports by
|
||||
// looking in the _NET_SUPPORTED property on the root window
|
||||
// It should contain a list of supported EWMH protocol and state atoms
|
||||
|
||||
Atom* supportedAtoms;
|
||||
unsigned long atomCount;
|
||||
|
||||
// Now we need to check the _NET_SUPPORTED property of the root window
|
||||
// It should be a list of supported WM protocol and state atoms
|
||||
atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
wmSupported,
|
||||
Atom* supportedAtoms = NULL;
|
||||
const unsigned long atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
_glfw.x11.NET_SUPPORTED,
|
||||
XA_ATOM,
|
||||
(unsigned char**) &supportedAtoms);
|
||||
if (!supportedAtoms)
|
||||
return;
|
||||
|
||||
// See which of the atoms we support that are supported by the WM
|
||||
|
||||
_glfw.x11.NET_WM_STATE =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
|
||||
_glfw.x11.NET_WM_STATE_ABOVE =
|
||||
@@ -137,6 +136,10 @@ static void detectEWMH(void)
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");
|
||||
_glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
|
||||
_glfw.x11.NET_WORKAREA =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WORKAREA");
|
||||
_glfw.x11.NET_CURRENT_DESKTOP =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_CURRENT_DESKTOP");
|
||||
_glfw.x11.NET_ACTIVE_WINDOW =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
|
||||
_glfw.x11.NET_FRAME_EXTENTS =
|
||||
@@ -144,25 +147,20 @@ static void detectEWMH(void)
|
||||
_glfw.x11.NET_REQUEST_FRAME_EXTENTS =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
|
||||
|
||||
if (supportedAtoms)
|
||||
XFree(supportedAtoms);
|
||||
XFree(supportedAtoms);
|
||||
}
|
||||
|
||||
// Look for and initialize supported X11 extensions
|
||||
//
|
||||
static GLFWbool initExtensions(void)
|
||||
static bool initExtensions(void)
|
||||
{
|
||||
_glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so.1");
|
||||
if (_glfw.x11.vidmode.handle)
|
||||
{
|
||||
_glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
|
||||
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension");
|
||||
_glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp)
|
||||
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp");
|
||||
_glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp)
|
||||
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp");
|
||||
_glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize)
|
||||
_glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize");
|
||||
glfw_dlsym(_glfw.x11.vidmode.QueryExtension, _glfw.x11.vidmode.handle, "XF86VidModeQueryExtension");
|
||||
glfw_dlsym(_glfw.x11.vidmode.GetGammaRamp, _glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp");
|
||||
glfw_dlsym(_glfw.x11.vidmode.SetGammaRamp, _glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp");
|
||||
glfw_dlsym(_glfw.x11.vidmode.GetGammaRampSize, _glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize");
|
||||
|
||||
_glfw.x11.vidmode.available =
|
||||
XF86VidModeQueryExtension(_glfw.x11.display,
|
||||
@@ -177,10 +175,8 @@ static GLFWbool initExtensions(void)
|
||||
#endif
|
||||
if (_glfw.x11.xi.handle)
|
||||
{
|
||||
_glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
|
||||
_glfw_dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
|
||||
_glfw.x11.xi.SelectEvents = (PFN_XISelectEvents)
|
||||
_glfw_dlsym(_glfw.x11.xi.handle, "XISelectEvents");
|
||||
glfw_dlsym(_glfw.x11.xi.QueryVersion, _glfw.x11.xi.handle, "XIQueryVersion");
|
||||
glfw_dlsym(_glfw.x11.xi.SelectEvents, _glfw.x11.xi.handle, "XISelectEvents");
|
||||
|
||||
if (XQueryExtension(_glfw.x11.display,
|
||||
"XInputExtension",
|
||||
@@ -195,7 +191,7 @@ static GLFWbool initExtensions(void)
|
||||
&_glfw.x11.xi.major,
|
||||
&_glfw.x11.xi.minor) == Success)
|
||||
{
|
||||
_glfw.x11.xi.available = GLFW_TRUE;
|
||||
_glfw.x11.xi.available = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,42 +203,24 @@ static GLFWbool initExtensions(void)
|
||||
#endif
|
||||
if (_glfw.x11.randr.handle)
|
||||
{
|
||||
_glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
|
||||
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
|
||||
_glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
|
||||
_glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
|
||||
_glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
|
||||
_glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
|
||||
_glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
|
||||
_glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
|
||||
_glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
|
||||
_glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
|
||||
_glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
|
||||
_glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
|
||||
_glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
|
||||
_glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
|
||||
_glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
|
||||
_glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
|
||||
_glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
|
||||
_glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
|
||||
_glfw_dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");
|
||||
glfw_dlsym(_glfw.x11.randr.AllocGamma, _glfw.x11.randr.handle, "XRRAllocGamma");
|
||||
glfw_dlsym(_glfw.x11.randr.FreeGamma, _glfw.x11.randr.handle, "XRRFreeGamma");
|
||||
glfw_dlsym(_glfw.x11.randr.FreeCrtcInfo, _glfw.x11.randr.handle, "XRRFreeCrtcInfo");
|
||||
glfw_dlsym(_glfw.x11.randr.FreeGamma, _glfw.x11.randr.handle, "XRRFreeGamma");
|
||||
glfw_dlsym(_glfw.x11.randr.FreeOutputInfo, _glfw.x11.randr.handle, "XRRFreeOutputInfo");
|
||||
glfw_dlsym(_glfw.x11.randr.FreeScreenResources, _glfw.x11.randr.handle, "XRRFreeScreenResources");
|
||||
glfw_dlsym(_glfw.x11.randr.GetCrtcGamma, _glfw.x11.randr.handle, "XRRGetCrtcGamma");
|
||||
glfw_dlsym(_glfw.x11.randr.GetCrtcGammaSize, _glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
|
||||
glfw_dlsym(_glfw.x11.randr.GetCrtcInfo, _glfw.x11.randr.handle, "XRRGetCrtcInfo");
|
||||
glfw_dlsym(_glfw.x11.randr.GetOutputInfo, _glfw.x11.randr.handle, "XRRGetOutputInfo");
|
||||
glfw_dlsym(_glfw.x11.randr.GetOutputPrimary, _glfw.x11.randr.handle, "XRRGetOutputPrimary");
|
||||
glfw_dlsym(_glfw.x11.randr.GetScreenResourcesCurrent, _glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
|
||||
glfw_dlsym(_glfw.x11.randr.QueryExtension, _glfw.x11.randr.handle, "XRRQueryExtension");
|
||||
glfw_dlsym(_glfw.x11.randr.QueryVersion, _glfw.x11.randr.handle, "XRRQueryVersion");
|
||||
glfw_dlsym(_glfw.x11.randr.SelectInput, _glfw.x11.randr.handle, "XRRSelectInput");
|
||||
glfw_dlsym(_glfw.x11.randr.SetCrtcConfig, _glfw.x11.randr.handle, "XRRSetCrtcConfig");
|
||||
glfw_dlsym(_glfw.x11.randr.SetCrtcGamma, _glfw.x11.randr.handle, "XRRSetCrtcGamma");
|
||||
glfw_dlsym(_glfw.x11.randr.UpdateConfiguration, _glfw.x11.randr.handle, "XRRUpdateConfiguration");
|
||||
|
||||
if (XRRQueryExtension(_glfw.x11.display,
|
||||
&_glfw.x11.randr.eventBase,
|
||||
@@ -254,7 +232,7 @@ static GLFWbool initExtensions(void)
|
||||
{
|
||||
// The GLFW RandR path requires at least version 1.3
|
||||
if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
|
||||
_glfw.x11.randr.available = GLFW_TRUE;
|
||||
_glfw.x11.randr.available = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -273,14 +251,14 @@ static GLFWbool initExtensions(void)
|
||||
{
|
||||
// This is likely an older Nvidia driver with broken gamma support
|
||||
// Flag it as useless and fall back to xf86vm gamma, if available
|
||||
_glfw.x11.randr.gammaBroken = GLFW_TRUE;
|
||||
_glfw.x11.randr.gammaBroken = true;
|
||||
}
|
||||
|
||||
if (!sr->ncrtc)
|
||||
{
|
||||
// A system without CRTCs is likely a system with broken RandR
|
||||
// Disable the RandR monitor path and fall back to core functions
|
||||
_glfw.x11.randr.monitorBroken = GLFW_TRUE;
|
||||
_glfw.x11.randr.monitorBroken = true;
|
||||
}
|
||||
|
||||
XRRFreeScreenResources(sr);
|
||||
@@ -299,12 +277,9 @@ static GLFWbool initExtensions(void)
|
||||
#endif
|
||||
if (_glfw.x11.xcursor.handle)
|
||||
{
|
||||
_glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate");
|
||||
_glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
|
||||
_glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
|
||||
_glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
||||
glfw_dlsym(_glfw.x11.xcursor.ImageCreate, _glfw.x11.xcursor.handle, "XcursorImageCreate");
|
||||
glfw_dlsym(_glfw.x11.xcursor.ImageDestroy, _glfw.x11.xcursor.handle, "XcursorImageDestroy");
|
||||
glfw_dlsym(_glfw.x11.xcursor.ImageLoadCursor, _glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__)
|
||||
@@ -314,19 +289,16 @@ static GLFWbool initExtensions(void)
|
||||
#endif
|
||||
if (_glfw.x11.xinerama.handle)
|
||||
{
|
||||
_glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
|
||||
_glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive");
|
||||
_glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension)
|
||||
_glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension");
|
||||
_glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens)
|
||||
_glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens");
|
||||
glfw_dlsym(_glfw.x11.xinerama.IsActive, _glfw.x11.xinerama.handle, "XineramaIsActive");
|
||||
glfw_dlsym(_glfw.x11.xinerama.QueryExtension, _glfw.x11.xinerama.handle, "XineramaQueryExtension");
|
||||
glfw_dlsym(_glfw.x11.xinerama.QueryScreens, _glfw.x11.xinerama.handle, "XineramaQueryScreens");
|
||||
|
||||
if (XineramaQueryExtension(_glfw.x11.display,
|
||||
&_glfw.x11.xinerama.major,
|
||||
&_glfw.x11.xinerama.minor))
|
||||
{
|
||||
if (XineramaIsActive(_glfw.x11.display))
|
||||
_glfw.x11.xinerama.available = GLFW_TRUE;
|
||||
_glfw.x11.xinerama.available = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,12 +309,9 @@ static GLFWbool initExtensions(void)
|
||||
#endif
|
||||
if (_glfw.x11.xrender.handle)
|
||||
{
|
||||
_glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension)
|
||||
_glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryExtension");
|
||||
_glfw.x11.xrender.QueryVersion = (PFN_XRenderQueryVersion)
|
||||
_glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryVersion");
|
||||
_glfw.x11.xrender.FindVisualFormat = (PFN_XRenderFindVisualFormat)
|
||||
_glfw_dlsym(_glfw.x11.xrender.handle, "XRenderFindVisualFormat");
|
||||
glfw_dlsym(_glfw.x11.xrender.QueryExtension, _glfw.x11.xrender.handle, "XRenderQueryExtension");
|
||||
glfw_dlsym(_glfw.x11.xrender.QueryVersion, _glfw.x11.xrender.handle, "XRenderQueryVersion");
|
||||
glfw_dlsym(_glfw.x11.xrender.FindVisualFormat, _glfw.x11.xrender.handle, "XRenderFindVisualFormat");
|
||||
|
||||
if (XRenderQueryExtension(_glfw.x11.display,
|
||||
&_glfw.x11.xrender.errorBase,
|
||||
@@ -352,7 +321,7 @@ static GLFWbool initExtensions(void)
|
||||
&_glfw.x11.xrender.major,
|
||||
&_glfw.x11.xrender.minor))
|
||||
{
|
||||
_glfw.x11.xrender.available = GLFW_TRUE;
|
||||
_glfw.x11.xrender.available = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,22 +338,19 @@ static GLFWbool initExtensions(void)
|
||||
if (!_glfw.x11.xkb.available)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to load Xkb extension");
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
Bool supported;
|
||||
if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
|
||||
{
|
||||
if (supported)
|
||||
_glfw.x11.xkb.detectable = GLFW_TRUE;
|
||||
_glfw.x11.xkb.detectable = true;
|
||||
}
|
||||
|
||||
if (!glfw_xkb_set_x11_events_mask()) return GLFW_FALSE;
|
||||
if (!glfw_xkb_create_context(&_glfw.x11.xkb)) return GLFW_FALSE;
|
||||
if (!glfw_xkb_update_x11_keyboard_id(&_glfw.x11.xkb)) return GLFW_FALSE;
|
||||
if (!glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL)) return GLFW_FALSE;
|
||||
|
||||
// Detect whether an EWMH-conformant window manager is running
|
||||
detectEWMH();
|
||||
if (!glfw_xkb_set_x11_events_mask()) return false;
|
||||
if (!glfw_xkb_create_context(&_glfw.x11.xkb)) return false;
|
||||
if (!glfw_xkb_update_x11_keyboard_id(&_glfw.x11.xkb)) return false;
|
||||
if (!glfw_xkb_compile_keymap(&_glfw.x11.xkb, NULL)) return false;
|
||||
|
||||
// String format atoms
|
||||
_glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
|
||||
@@ -429,6 +395,10 @@ static GLFWbool initExtensions(void)
|
||||
XInternAtom(_glfw.x11.display, "WM_STATE", False);
|
||||
_glfw.x11.WM_DELETE_WINDOW =
|
||||
XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);
|
||||
_glfw.x11.NET_SUPPORTED =
|
||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
|
||||
_glfw.x11.NET_SUPPORTING_WM_CHECK =
|
||||
XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
|
||||
_glfw.x11.NET_WM_ICON =
|
||||
XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);
|
||||
_glfw.x11.NET_WM_PING =
|
||||
@@ -453,12 +423,15 @@ static GLFWbool initExtensions(void)
|
||||
_glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
// Detect whether an EWMH-conformant window manager is running
|
||||
detectEWMH();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Retrieve system content scale via folklore heuristics
|
||||
//
|
||||
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, GLFWbool bypass_cache)
|
||||
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, bool bypass_cache)
|
||||
{
|
||||
// NOTE: Default to the display-wide DPI as we don't currently have a policy
|
||||
// for which monitor a window is considered to be on
|
||||
@@ -532,7 +505,7 @@ static Window createHelperWindow(void)
|
||||
|
||||
// X error handler
|
||||
//
|
||||
static int errorHandler(Display *display, XErrorEvent* event)
|
||||
static int errorHandler(Display *display UNUSED, XErrorEvent* event)
|
||||
{
|
||||
_glfw.x11.errorCode = event->error_code;
|
||||
return 0;
|
||||
@@ -607,6 +580,7 @@ Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
|
||||
return cursor;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -616,13 +590,6 @@ int _glfwPlatformInit(void)
|
||||
XInitThreads();
|
||||
XrmInitialize();
|
||||
|
||||
if (pipe2(_glfw.x11.eventLoopData.wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: failed to create self pipe");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_glfw.x11.display = XOpenDisplay(NULL);
|
||||
if (!_glfw.x11.display)
|
||||
{
|
||||
@@ -638,10 +605,13 @@ int _glfwPlatformInit(void)
|
||||
"X11: The DISPLAY environment variable is missing");
|
||||
}
|
||||
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
}
|
||||
|
||||
initPollData(&_glfw.x11.eventLoopData, _glfw.x11.eventLoopData.wakeupFds[0], ConnectionNumber(_glfw.x11.display));
|
||||
if (!initPollData(&_glfw.x11.eventLoopData, ConnectionNumber(_glfw.x11.display))) {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Failed to initialize event loop data");
|
||||
}
|
||||
glfw_dbus_init(&_glfw.x11.dbus, &_glfw.x11.eventLoopData);
|
||||
|
||||
_glfw.x11.screen = DefaultScreen(_glfw.x11.display);
|
||||
@@ -650,10 +620,10 @@ int _glfwPlatformInit(void)
|
||||
_glfw.x11.RESOURCE_MANAGER = XInternAtom(_glfw.x11.display, "RESOURCE_MANAGER", True);
|
||||
XSelectInput(_glfw.x11.display, _glfw.x11.root, PropertyChangeMask);
|
||||
|
||||
_glfwGetSystemContentScaleX11(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY, GLFW_FALSE);
|
||||
_glfwGetSystemContentScaleX11(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY, false);
|
||||
|
||||
if (!initExtensions())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
|
||||
_glfw.x11.helperWindowHandle = createHelperWindow();
|
||||
_glfw.x11.hiddenCursorHandle = createHiddenCursor();
|
||||
@@ -661,7 +631,7 @@ int _glfwPlatformInit(void)
|
||||
#if defined(__linux__)
|
||||
if (_glfw.hints.init.enableJoysticks) {
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
return false;
|
||||
if (_glfw.linjs.inotify > 0)
|
||||
addWatch(&_glfw.x11.eventLoopData, "joystick", _glfw.linjs.inotify, POLLIN, 1, NULL, NULL);
|
||||
}
|
||||
@@ -670,11 +640,12 @@ int _glfwPlatformInit(void)
|
||||
_glfwInitTimerPOSIX();
|
||||
|
||||
_glfwPollMonitorsX11();
|
||||
return GLFW_TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
{
|
||||
removeAllTimers(&_glfw.x11.eventLoopData);
|
||||
if (_glfw.x11.helperWindowHandle)
|
||||
{
|
||||
if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
|
||||
@@ -749,12 +720,12 @@ void _glfwPlatformTerminate(void)
|
||||
#if defined(__linux__)
|
||||
_glfwTerminateJoysticksLinux();
|
||||
#endif
|
||||
closeFds(_glfw.x11.eventLoopData.wakeupFds, sizeof(_glfw.x11.eventLoopData.wakeupFds)/sizeof(_glfw.x11.eventLoopData.wakeupFds[0]));
|
||||
finalizePollData(&_glfw.x11.eventLoopData);
|
||||
}
|
||||
|
||||
const char* _glfwPlatformGetVersionString(void)
|
||||
{
|
||||
return _GLFW_VERSION_NUMBER " X11 GLX EGL"
|
||||
return _GLFW_VERSION_NUMBER " X11 GLX EGL OSMesa"
|
||||
#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
|
||||
" clock_gettime"
|
||||
#else
|
||||
@@ -768,3 +739,5 @@ const char* _glfwPlatformGetVersionString(void)
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
#include "main_loop.h"
|
||||
|
||||
197
glfw/x11_monitor.c
vendored
197
glfw/x11_monitor.c
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 X11 - www.glfw.org
|
||||
// GLFW 3.4 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -24,17 +24,20 @@
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
// Check whether the display mode should be included in enumeration
|
||||
//
|
||||
static GLFWbool modeIsGood(const XRRModeInfo* mi)
|
||||
static bool modeIsGood(const XRRModeInfo* mi)
|
||||
{
|
||||
return (mi->modeFlags & RR_Interlace) == 0;
|
||||
}
|
||||
@@ -44,7 +47,7 @@ static GLFWbool modeIsGood(const XRRModeInfo* mi)
|
||||
static int calculateRefreshRate(const XRRModeInfo* mi)
|
||||
{
|
||||
if (mi->hTotal && mi->vTotal)
|
||||
return (int) ((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal));
|
||||
return (int) round((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@@ -53,9 +56,7 @@ static int calculateRefreshRate(const XRRModeInfo* mi)
|
||||
//
|
||||
static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sr->nmode; i++)
|
||||
for (int i = 0; i < sr->nmode; i++)
|
||||
{
|
||||
if (sr->modes[i].id == id)
|
||||
return sr->modes + i;
|
||||
@@ -101,7 +102,7 @@ void _glfwPollMonitorsX11(void)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
int i, j, disconnectedCount, screenCount = 0;
|
||||
int disconnectedCount, screenCount = 0;
|
||||
_GLFWmonitor** disconnected = NULL;
|
||||
XineramaScreenInfo* screens = NULL;
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
|
||||
@@ -121,14 +122,11 @@ void _glfwPollMonitorsX11(void)
|
||||
_glfw.monitorCount * sizeof(_GLFWmonitor*));
|
||||
}
|
||||
|
||||
for (i = 0; i < sr->noutput; i++)
|
||||
for (int i = 0; i < sr->noutput; i++)
|
||||
{
|
||||
int type, widthMM, heightMM;
|
||||
XRROutputInfo* oi;
|
||||
XRRCrtcInfo* ci;
|
||||
_GLFWmonitor* monitor;
|
||||
int j, type, widthMM, heightMM;
|
||||
|
||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
|
||||
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
|
||||
if (oi->connection != RR_Connected || oi->crtc == None)
|
||||
{
|
||||
XRRFreeOutputInfo(oi);
|
||||
@@ -151,7 +149,7 @@ void _glfwPollMonitorsX11(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
|
||||
if (!ci)
|
||||
{
|
||||
XRRFreeOutputInfo(oi);
|
||||
@@ -168,7 +166,7 @@ void _glfwPollMonitorsX11(void)
|
||||
heightMM = oi->mm_height;
|
||||
}
|
||||
|
||||
monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
||||
_GLFWmonitor* monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
|
||||
monitor->x11.output = sr->outputs[i];
|
||||
monitor->x11.crtc = oi->crtc;
|
||||
|
||||
@@ -176,8 +174,8 @@ void _glfwPollMonitorsX11(void)
|
||||
{
|
||||
if (screens[j].x_org == ci->x &&
|
||||
screens[j].y_org == ci->y &&
|
||||
screens[j].width == ci->width &&
|
||||
screens[j].height == ci->height)
|
||||
screens[j].width == (short int)ci->width &&
|
||||
screens[j].height == (short int)ci->height)
|
||||
{
|
||||
monitor->x11.index = j;
|
||||
break;
|
||||
@@ -200,7 +198,7 @@ void _glfwPollMonitorsX11(void)
|
||||
if (screens)
|
||||
XFree(screens);
|
||||
|
||||
for (i = 0; i < disconnectedCount; i++)
|
||||
for (int i = 0; i < disconnectedCount; i++)
|
||||
{
|
||||
if (disconnected[i])
|
||||
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
|
||||
@@ -225,24 +223,19 @@ void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
XRROutputInfo* oi;
|
||||
GLFWvidmode current;
|
||||
const GLFWvidmode* best;
|
||||
RRMode native = None;
|
||||
int i;
|
||||
|
||||
best = _glfwChooseVideoMode(monitor, desired);
|
||||
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
|
||||
_glfwPlatformGetVideoMode(monitor, ¤t);
|
||||
if (_glfwCompareVideoModes(¤t, best) == 0)
|
||||
return;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||
|
||||
for (i = 0; i < oi->nmode; i++)
|
||||
for (int i = 0; i < oi->nmode; i++)
|
||||
{
|
||||
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
|
||||
if (!modeIsGood(mi))
|
||||
@@ -283,14 +276,11 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
|
||||
if (monitor->x11.oldMode == None)
|
||||
return;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
|
||||
XRRSetCrtcConfig(_glfw.x11.display,
|
||||
sr, monitor->x11.crtc,
|
||||
@@ -313,7 +303,7 @@ void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
|
||||
void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -321,11 +311,9 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
if (ci)
|
||||
{
|
||||
if (xpos)
|
||||
@@ -339,7 +327,7 @@ void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor UNUSED,
|
||||
float* xscale, float* yscale)
|
||||
{
|
||||
if (xscale)
|
||||
@@ -348,6 +336,98 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
|
||||
*yscale = _glfw.x11.contentScaleY;
|
||||
}
|
||||
|
||||
void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height)
|
||||
{
|
||||
int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0;
|
||||
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
|
||||
areaX = ci->x;
|
||||
areaY = ci->y;
|
||||
|
||||
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
|
||||
|
||||
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
|
||||
{
|
||||
areaWidth = mi->height;
|
||||
areaHeight = mi->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
areaWidth = mi->width;
|
||||
areaHeight = mi->height;
|
||||
}
|
||||
|
||||
XRRFreeCrtcInfo(ci);
|
||||
XRRFreeScreenResources(sr);
|
||||
}
|
||||
else
|
||||
{
|
||||
areaWidth = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
|
||||
areaHeight = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
|
||||
}
|
||||
|
||||
if (_glfw.x11.NET_WORKAREA && _glfw.x11.NET_CURRENT_DESKTOP)
|
||||
{
|
||||
Atom* extents = NULL;
|
||||
Atom* desktop = NULL;
|
||||
const unsigned long extentCount =
|
||||
_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
_glfw.x11.NET_WORKAREA,
|
||||
XA_CARDINAL,
|
||||
(unsigned char**) &extents);
|
||||
|
||||
if (_glfwGetWindowPropertyX11(_glfw.x11.root,
|
||||
_glfw.x11.NET_CURRENT_DESKTOP,
|
||||
XA_CARDINAL,
|
||||
(unsigned char**) &desktop) > 0)
|
||||
{
|
||||
if (extentCount >= 4 && *desktop < extentCount / 4)
|
||||
{
|
||||
const int globalX = extents[*desktop * 4 + 0];
|
||||
const int globalY = extents[*desktop * 4 + 1];
|
||||
const int globalWidth = extents[*desktop * 4 + 2];
|
||||
const int globalHeight = extents[*desktop * 4 + 3];
|
||||
|
||||
if (areaX < globalX)
|
||||
{
|
||||
areaWidth -= globalX - areaX;
|
||||
areaX = globalX;
|
||||
}
|
||||
|
||||
if (areaY < globalY)
|
||||
{
|
||||
areaHeight -= globalY - areaY;
|
||||
areaY = globalY;
|
||||
}
|
||||
|
||||
if (areaX + areaWidth > globalX + globalWidth)
|
||||
areaWidth = globalX - areaX + globalWidth;
|
||||
if (areaY + areaHeight > globalY + globalHeight)
|
||||
areaHeight = globalY - areaY + globalHeight;
|
||||
}
|
||||
}
|
||||
|
||||
if (extents)
|
||||
XFree(extents);
|
||||
if (desktop)
|
||||
XFree(desktop);
|
||||
}
|
||||
|
||||
if (xpos)
|
||||
*xpos = areaX;
|
||||
if (ypos)
|
||||
*ypos = areaY;
|
||||
if (width)
|
||||
*width = areaWidth;
|
||||
if (height)
|
||||
*height = areaHeight;
|
||||
}
|
||||
|
||||
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
{
|
||||
GLFWvidmode* result;
|
||||
@@ -356,24 +436,20 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
|
||||
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
int i, j;
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
XRROutputInfo* oi;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
|
||||
|
||||
result = calloc(oi->nmode, sizeof(GLFWvidmode));
|
||||
|
||||
for (i = 0; i < oi->nmode; i++)
|
||||
for (int i = 0; i < oi->nmode; i++)
|
||||
{
|
||||
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
|
||||
if (!modeIsGood(mi))
|
||||
continue;
|
||||
|
||||
const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
|
||||
int j;
|
||||
|
||||
for (j = 0; j < *count; j++)
|
||||
{
|
||||
@@ -407,11 +483,9 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
|
||||
sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
|
||||
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
|
||||
|
||||
if (ci) {
|
||||
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
|
||||
@@ -433,7 +507,7 @@ void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
bool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
|
||||
{
|
||||
@@ -449,6 +523,7 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
|
||||
|
||||
XRRFreeGamma(gamma);
|
||||
return true;
|
||||
}
|
||||
else if (_glfw.x11.vidmode.available)
|
||||
{
|
||||
@@ -460,6 +535,13 @@ void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
|
||||
XF86VidModeGetGammaRamp(_glfw.x11.display,
|
||||
_glfw.x11.screen,
|
||||
ramp->size, ramp->red, ramp->green, ramp->blue);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Gamma ramp access not supported by server");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +549,7 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
{
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
|
||||
{
|
||||
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size)
|
||||
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != (int)ramp->size)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Gamma ramp size must match current ramp size");
|
||||
@@ -492,6 +574,11 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
(unsigned short*) ramp->green,
|
||||
(unsigned short*) ramp->blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: Gamma ramp access not supported by server");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
37
glfw/x11_platform.h
vendored
37
glfw/x11_platform.h
vendored
@@ -1,8 +1,8 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 X11 - www.glfw.org
|
||||
// GLFW 3.4 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
@@ -182,12 +182,11 @@ typedef struct _GLFWwindowX11
|
||||
Colormap colormap;
|
||||
Window handle;
|
||||
|
||||
GLFWbool overrideRedirect;
|
||||
GLFWbool iconified;
|
||||
GLFWbool maximized;
|
||||
bool iconified;
|
||||
bool maximized;
|
||||
|
||||
// Whether the visual supports framebuffer transparency
|
||||
GLFWbool transparent;
|
||||
bool transparent;
|
||||
|
||||
// Cached position and size used to filter out duplicate events
|
||||
int width, height;
|
||||
@@ -198,9 +197,6 @@ typedef struct _GLFWwindowX11
|
||||
// The last position the cursor was warped to by GLFW
|
||||
int warpCursorPosX, warpCursorPosY;
|
||||
|
||||
// The time of the last KeyPress event
|
||||
Time lastKeyTime;
|
||||
|
||||
} _GLFWwindowX11;
|
||||
|
||||
// X11-specific global data
|
||||
@@ -231,6 +227,8 @@ typedef struct _GLFWlibraryX11
|
||||
_GLFWwindow* disabledCursorWindow;
|
||||
|
||||
// Window manager atoms
|
||||
Atom NET_SUPPORTED;
|
||||
Atom NET_SUPPORTING_WM_CHECK;
|
||||
Atom WM_PROTOCOLS;
|
||||
Atom WM_STATE;
|
||||
Atom WM_DELETE_WINDOW;
|
||||
@@ -251,6 +249,8 @@ typedef struct _GLFWlibraryX11
|
||||
Atom NET_WM_FULLSCREEN_MONITORS;
|
||||
Atom NET_WM_WINDOW_OPACITY;
|
||||
Atom NET_WM_CM_Sx;
|
||||
Atom NET_WORKAREA;
|
||||
Atom NET_CURRENT_DESKTOP;
|
||||
Atom NET_ACTIVE_WINDOW;
|
||||
Atom NET_FRAME_EXTENTS;
|
||||
Atom NET_REQUEST_FRAME_EXTENTS;
|
||||
@@ -286,14 +286,14 @@ typedef struct _GLFWlibraryX11
|
||||
Atom RESOURCE_MANAGER;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
int eventBase;
|
||||
int errorBase;
|
||||
int major;
|
||||
int minor;
|
||||
GLFWbool gammaBroken;
|
||||
GLFWbool monitorBroken;
|
||||
bool gammaBroken;
|
||||
bool monitorBroken;
|
||||
PFN_XRRAllocGamma AllocGamma;
|
||||
PFN_XRRFreeCrtcInfo FreeCrtcInfo;
|
||||
PFN_XRRFreeGamma FreeGamma;
|
||||
@@ -338,7 +338,7 @@ typedef struct _GLFWlibraryX11
|
||||
} xcursor;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
int major;
|
||||
int minor;
|
||||
@@ -348,7 +348,7 @@ typedef struct _GLFWlibraryX11
|
||||
} xinerama;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
int eventBase;
|
||||
int errorBase;
|
||||
@@ -359,7 +359,7 @@ typedef struct _GLFWlibraryX11
|
||||
} vidmode;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
int majorOpcode;
|
||||
int eventBase;
|
||||
@@ -371,7 +371,7 @@ typedef struct _GLFWlibraryX11
|
||||
} xi;
|
||||
|
||||
struct {
|
||||
GLFWbool available;
|
||||
bool available;
|
||||
void* handle;
|
||||
int major;
|
||||
int minor;
|
||||
@@ -408,6 +408,7 @@ typedef struct _GLFWcursorX11
|
||||
|
||||
} _GLFWcursorX11;
|
||||
|
||||
|
||||
void _glfwPollMonitorsX11(void);
|
||||
void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor);
|
||||
@@ -418,11 +419,11 @@ unsigned long _glfwGetWindowPropertyX11(Window window,
|
||||
Atom property,
|
||||
Atom type,
|
||||
unsigned char** value);
|
||||
GLFWbool _glfwIsVisualTransparentX11(Visual* visual);
|
||||
bool _glfwIsVisualTransparentX11(Visual* visual);
|
||||
|
||||
void _glfwGrabErrorHandlerX11(void);
|
||||
void _glfwReleaseErrorHandlerX11(void);
|
||||
void _glfwInputErrorX11(int error, const char* message);
|
||||
|
||||
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, GLFWbool bypass_cache);
|
||||
void _glfwGetSystemContentScaleX11(float* xscale, float* yscale, bool bypass_cache);
|
||||
void _glfwPushSelectionToManagerX11(void);
|
||||
|
||||
500
glfw/x11_window.c
vendored
500
glfw/x11_window.c
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user