Compare commits
1141 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b40ace381c | ||
|
01c262abdd | ||
|
595bda604c | ||
|
9c0a0a8c16 | ||
|
e58796d69b | ||
|
1e3acce73e | ||
|
a958e37e20 | ||
|
514c62c7c1 | ||
|
b31862462a | ||
|
6a54c21998 | ||
|
d17d12d078 | ||
|
c46eece00f | ||
|
661885f71d | ||
|
c0ccb56908 | ||
|
4d80cf6d77 | ||
|
dd1dc7c630 | ||
|
ab56c2b52a | ||
|
2c19a20d85 | ||
|
c734be35d6 | ||
|
b5772cef91 | ||
|
28ad8c6ee1 | ||
|
edd4276633 | ||
|
dea4b0096c | ||
|
b9703af7ee | ||
|
493e01eb81 | ||
|
10cf8f2d1c | ||
|
f4d73054a9 | ||
|
fcc82c3499 | ||
|
7eb586d1ae | ||
|
65993312b7 | ||
|
89a4a1b8f7 | ||
|
66e5eebb1c | ||
|
d4c30d5fc9 | ||
|
984b71449e | ||
|
ea69f9a26a | ||
|
7efcaaf027 | ||
|
37d2c2d41b | ||
|
82c95faaa9 | ||
|
eab3cbb1d5 | ||
|
af22422260 | ||
|
bc3f0e63f6 | ||
|
27f0febb04 | ||
|
5351511272 | ||
|
abfa633a35 | ||
|
a00374d1a4 | ||
|
1ac216da1d | ||
|
e251512ba4 | ||
|
2c2585cc90 | ||
|
7238f8f99d | ||
|
07e4e23c7b | ||
|
8f21f43768 | ||
|
5029bd12cd | ||
|
72ede776ed | ||
|
b9d593bc11 | ||
|
16ef3dc3a8 | ||
|
854d060917 | ||
|
6aeb364c8d | ||
|
010b6a3dbf | ||
|
d50c2fd4e4 | ||
|
b3513ba8df | ||
|
2ebe6d1b6c | ||
|
3bfa59472e | ||
|
9f59c6aafc | ||
|
2aeec83bab | ||
|
c0a13e4471 | ||
|
abbc1076bc | ||
|
11be388f17 | ||
|
413c8c833d | ||
|
ba0b6fd6fe | ||
|
b418f657a9 | ||
|
8fd941632d | ||
|
3f568b42fb | ||
|
ba1d93930a | ||
|
c9a2039858 | ||
|
d83fc8a93f | ||
|
37348d362c | ||
|
dc696f5b7f | ||
|
7fe5b3ea34 | ||
|
5779edd23f | ||
|
ef14039c62 | ||
|
43d6db45ed | ||
|
c91ef80ca9 | ||
|
d82a172b55 | ||
|
0f6e731524 | ||
|
34b5582460 | ||
|
c3f7eec4f5 | ||
|
a90228241d | ||
|
d8b5435710 | ||
|
f1d3b21177 | ||
|
5e95fc0cb3 | ||
|
ecebe4588a | ||
|
597d30b6e2 | ||
|
c9e84dc16c | ||
|
4bfeb668e1 | ||
|
a4f57572e6 | ||
|
b6407a9bf9 | ||
|
2a8eea90de | ||
|
ce27b373c1 | ||
|
f1ba92b35e | ||
|
c2b8cbf19e | ||
|
19c111c74c | ||
|
10c4700e9a | ||
|
8caadb370f | ||
|
a1f148d307 | ||
|
ab383ed713 | ||
|
52dd88b576 | ||
|
cc4a4c95f2 | ||
|
fced0002bd | ||
|
0ebf4cff13 | ||
|
48255da29a | ||
|
ce355fc235 | ||
|
b1d8428579 | ||
|
2446c206e6 | ||
|
ddff9ebb32 | ||
|
17a56567d2 | ||
|
8ac2f6db34 | ||
|
1d927add29 | ||
|
c92334720c | ||
|
faed0d538c | ||
|
a6199e8510 | ||
|
57cf5c19b7 | ||
|
d2bab53364 | ||
|
8ee4a6cb6f | ||
|
620f3b6220 | ||
|
96168ff918 | ||
|
a5a7ccc660 | ||
|
a1b7c17906 | ||
|
095f0d0e4c | ||
|
6fa941e208 | ||
|
985b0de35e | ||
|
809df89c08 | ||
|
8048a63b49 | ||
|
f38e215de5 | ||
|
c98289732e | ||
|
5c4278ccb1 | ||
|
70f1b685ba | ||
|
c47a87e8e6 | ||
|
cbaaf221cd | ||
|
5f91eec695 | ||
|
00332aca17 | ||
|
4dcf59c8f4 | ||
|
2bed4f6b9b | ||
|
485e64ee76 | ||
|
112a534f4c | ||
|
96ff6fdba8 | ||
|
57ed8e9d52 | ||
|
b583a8d510 | ||
|
ab97002c22 | ||
|
e5e56a2ed9 | ||
|
e622f0512b | ||
|
3d5c8822a1 | ||
|
4d91771cac | ||
|
8ffd75e8d1 | ||
|
bd49d2f690 | ||
|
6257dae74d | ||
|
1cb2ce06cd | ||
|
7301b505c9 | ||
|
2be49f3d73 | ||
|
fe410a595d | ||
|
b0cfc1a12b | ||
|
c12c475e04 | ||
|
d32737a993 | ||
|
f0069456f9 | ||
|
de5711637f | ||
|
21e11de157 | ||
|
640411dd39 | ||
|
e0a1339b34 | ||
|
98d0003715 | ||
|
cad94531da | ||
|
d512b0dbc0 | ||
|
c53662e3c1 | ||
|
33670aed48 | ||
|
bc71ac22f5 | ||
|
65fa487c37 | ||
|
4e77772ea2 | ||
|
4599ac7bf6 | ||
|
c42a09709e | ||
|
48644258e0 | ||
|
1e78b42022 | ||
|
7ae69a663e | ||
|
430e980c9c | ||
|
a2064e51c1 | ||
|
b623766503 | ||
|
8c98ed4a58 | ||
|
bcd690f037 | ||
|
3b1cc551e4 | ||
|
d4e2e0a093 | ||
|
bea72150fb | ||
|
a8c075e84e | ||
|
97138d5bad | ||
|
7bea1f9d56 | ||
|
6da58825fe | ||
|
20b90c1098 | ||
|
67ace5c59d | ||
|
dbbb172f92 | ||
|
15b46f8ccf | ||
|
c7070b95af | ||
|
5eed76f32b | ||
|
5db94568ec | ||
|
fb9c175b11 | ||
|
f92076a2e7 | ||
|
d6a256cca2 | ||
|
cc7d5ef921 | ||
|
d31e3f6174 | ||
|
f781962a55 | ||
|
82d0e50348 | ||
|
4502b70618 | ||
|
c07d6e793e | ||
|
0a0a39380e | ||
|
fe0ee0f9df | ||
|
4b571b8499 | ||
|
e73f26c7c1 | ||
|
898e1ca135 | ||
|
95bfb349a8 | ||
|
2277a111dc | ||
|
8a2f427162 | ||
|
7fabef86f0 | ||
|
f5d8fe5f3d | ||
|
fb34d742bb | ||
|
e0e9177f5e | ||
|
200e4d84f4 | ||
|
651fcf85b7 | ||
|
45df24076f | ||
|
661a441745 | ||
|
4f03b02302 | ||
|
6ff99cc4b5 | ||
|
697dcbb24d | ||
|
0187daeb59 | ||
|
bf81557cdc | ||
|
b6d4e9df4f | ||
|
e3c83c544c | ||
|
5ccabaf706 | ||
|
0b4150ff48 | ||
|
a2c0d39c1e | ||
|
90e4aca26a | ||
|
5845ce7c16 | ||
|
5afbca4954 | ||
|
b79a7690fa | ||
|
3430b8898c | ||
|
2a0c2a612f | ||
|
b2c0c506e8 | ||
|
e821eddb62 | ||
|
b6b9283df1 | ||
|
9bc706f412 | ||
|
82bbf7ef03 | ||
|
ae249c6755 | ||
|
4ba026be38 | ||
|
8cea9b03ab | ||
|
b53c683edf | ||
|
04c67a5039 | ||
|
98d6545566 | ||
|
3b6c9bcba3 | ||
|
bf53a76ea1 | ||
|
bc9b35c38c | ||
|
7e305f9e24 | ||
|
49f60fc64f | ||
|
da0f3cefd7 | ||
|
22f17ad123 | ||
|
58b3989655 | ||
|
547388ddce | ||
|
2af2e032c3 | ||
|
eaffeaf53f | ||
|
e32671cd79 | ||
|
d3a751cff8 | ||
|
bacda80492 | ||
|
56eec32b7e | ||
|
3ea306249b | ||
|
c103d2308b | ||
|
42388ca009 | ||
|
895fe28961 | ||
|
2849dce105 | ||
|
09715f4cf4 | ||
|
c21521f80d | ||
|
3ca3bd197f | ||
|
f3fe06a0c7 | ||
|
bc70a86de6 | ||
|
dd37720188 | ||
|
e27c634970 | ||
|
bedaf990ac | ||
|
ae836fb543 | ||
|
27ad405cd8 | ||
|
74598d1cc3 | ||
|
689269dcde | ||
|
422cfb7a9c | ||
|
9ad0d6abb6 | ||
|
b9fd19e6b5 | ||
|
4c2a7e893b | ||
|
494376438c | ||
|
2307608cfb | ||
|
45fd497645 | ||
|
4f8301f38a | ||
|
b8f0094603 | ||
|
76242bbf63 | ||
|
47d4ab1339 | ||
|
ffd25af182 | ||
|
b39c12f351 | ||
|
8027a42497 | ||
|
75b41afa04 | ||
|
33539c1d8b | ||
|
54acca43cf | ||
|
d9783a9529 | ||
|
d23d147dc7 | ||
|
e5d455d0be | ||
|
ccead296e6 | ||
|
3fab31c644 | ||
|
97b2527018 | ||
|
2e1f7f1484 | ||
|
c08cebb01d | ||
|
c961563403 | ||
|
5293f13f39 | ||
|
1b6ca2245d | ||
|
584a894490 | ||
|
63e963daf6 | ||
|
de2c01ad1d | ||
|
65137e6edb | ||
|
afa70e464a | ||
|
8af430e197 | ||
|
17ba2e01e8 | ||
|
5742e1cafa | ||
|
ec8dd8ad33 | ||
|
b23d6f89d5 | ||
|
b80f07d2a7 | ||
|
a547a8b613 | ||
|
db04b4b54c | ||
|
db70ce8b8d | ||
|
62a51dead9 | ||
|
4d03d69125 | ||
|
05c78bb284 | ||
|
7bcaa2a0b9 | ||
|
c38308a2d9 | ||
|
bbd3571d09 | ||
|
e529a04d26 | ||
|
c65494886d | ||
|
1b8e30ad29 | ||
|
9fbe0ad18c | ||
|
aa8c651e38 | ||
|
04db78f6c6 | ||
|
c52a173db0 | ||
|
e520ce3a5d | ||
|
94b1481270 | ||
|
a679b4ed2b | ||
|
64b347d7ef | ||
|
cdf574cf6c | ||
|
50cff2eb75 | ||
|
76d12c50a8 | ||
|
7ceff70c1c | ||
|
736da24dd1 | ||
|
c51ec2e8e9 | ||
|
675dd77807 | ||
|
63235eaafd | ||
|
547c619c2f | ||
|
ee328784dc | ||
|
8f73f5ba73 | ||
|
f5f67e2e80 | ||
|
d722ffe357 | ||
|
1b286a0469 | ||
|
8556f83905 | ||
|
f8e7fd4c2c | ||
|
a50afc6500 | ||
|
3a5b8936d1 | ||
|
36ea4a3f86 | ||
|
0758fe03a6 | ||
|
0463e552dc | ||
|
da8fa059cd | ||
|
8c214280d3 | ||
|
f687174af1 | ||
|
b1fca0100e | ||
|
2a287963da | ||
|
eb1c3cd4b3 | ||
|
e0ffa11495 | ||
|
ad5916c5e4 | ||
|
93dfc1839e | ||
|
d098214531 | ||
|
d11617adbe | ||
|
bce303c3a8 | ||
|
cf5c2718af | ||
|
5837deae04 | ||
|
cf677da22c | ||
|
84a0befd30 | ||
|
284c17c0b2 | ||
|
89ceaf0c52 | ||
|
73acbe1f79 | ||
|
bc3ea01b3e | ||
|
98ad496072 | ||
|
fea7d80723 | ||
|
433c05eb36 | ||
|
e138c1a601 | ||
|
6decef6046 | ||
|
9305008ba8 | ||
|
5ffca14b2f | ||
|
572ee7686d | ||
|
36a1a33b84 | ||
|
bfdcdb0082 | ||
|
def567c2e0 | ||
|
16d45a8f4f | ||
|
98f45baff3 | ||
|
27d34e784d | ||
|
deb8a317ba | ||
|
d8446c263f | ||
|
aae4f33602 | ||
|
a978b58f11 | ||
|
c37ce6fa47 | ||
|
8fb5bd9096 | ||
|
a111a0fdfe | ||
|
25a1fab5b6 | ||
|
4b1482b5df | ||
|
67c297d273 | ||
|
84ae372a58 | ||
|
8eed7a395e | ||
|
45ca9fe098 | ||
|
9bbb2ec68f | ||
|
1d6997001e | ||
|
90c80ce855 | ||
|
463cd8a543 | ||
|
ae43cee4b3 | ||
|
1ac6206af6 | ||
|
d77b0b3b9d | ||
|
14b224f7ae | ||
|
6e192995cb | ||
|
416615bfb5 | ||
|
ce42e3e12d | ||
|
afb34f23a4 | ||
|
07797866e3 | ||
|
650dc032ce | ||
|
5a02a3b3d9 | ||
|
9bf78e4a80 | ||
|
cb9a697fa8 | ||
|
0f32661056 | ||
|
a2798fe9e9 | ||
|
7cf9101407 | ||
|
3c98420517 | ||
|
f4210a20ae | ||
|
dab1443e87 | ||
|
07ac4c3eca | ||
|
c0f9c55de6 | ||
|
73b7bd5ebc | ||
|
6853048a0c | ||
|
05d1733950 | ||
|
3d87d40d0a | ||
|
d5684e0633 | ||
|
ac65538a48 | ||
|
8535f8e08c | ||
|
2fa92be379 | ||
|
24d115824d | ||
|
c250529e8e | ||
|
544ead05e7 | ||
|
fdfe47668b | ||
|
b191d87e33 | ||
|
1c0c923ad1 | ||
|
e199dba32f | ||
|
0a44594f51 | ||
|
4b37e1a508 | ||
|
41ae2f4efa | ||
|
f57e0b959f | ||
|
42d32e7496 | ||
|
7fe7ce9434 | ||
|
8853b1c4ee | ||
|
ae94891ab7 | ||
|
4dcaa84fbe | ||
|
c5971b535d | ||
|
74cd7d1837 | ||
|
3895954b75 | ||
|
9c2c43693c | ||
|
8e291846d5 | ||
|
dadb393443 | ||
|
3d95954d87 | ||
|
1a9d15bef0 | ||
|
82ede29388 | ||
|
06580ec448 | ||
|
970d936106 | ||
|
dec05f91fa | ||
|
8064a463c9 | ||
|
c3f02f5107 | ||
|
f79f8bfa70 | ||
|
e96d77bac1 | ||
|
cf5e1961d3 | ||
|
65ff618479 | ||
|
ff24984cf3 | ||
|
563cfaf009 | ||
|
c0ed83a022 | ||
|
b3b12b1be5 | ||
|
0d0004f3cb | ||
|
2a58ba40c9 | ||
|
f08355a325 | ||
|
adb7476187 | ||
|
1c798cee47 | ||
|
cf9e07d341 | ||
|
d712f3527a | ||
|
b811fdb36b | ||
|
184287d81e | ||
|
6d756f8002 | ||
|
d71ec3fed0 | ||
|
5741653900 | ||
|
f2146aecfb | ||
|
6628d57b55 | ||
|
bc8c8c67b9 | ||
|
3b62bf1df2 | ||
|
65330761a1 | ||
|
a251aae49e | ||
|
65a69cdd8f | ||
|
7ca834e3b8 | ||
|
576feffe90 | ||
|
cd1c479069 | ||
|
740bcfde47 | ||
|
68555abe74 | ||
|
2c5940f0a0 | ||
|
40e3421bf1 | ||
|
ee1ea91eb1 | ||
|
f6e9552649 | ||
|
8a91932f04 | ||
|
4d7c9af3c6 | ||
|
5605ce44b1 | ||
|
53cc5c3e18 | ||
|
5e339d5054 | ||
|
8044bd1ecf | ||
|
ea12231247 | ||
|
d2362f23a0 | ||
|
b4f9d250e2 | ||
|
75c9979b54 | ||
|
2f3693b3dc | ||
|
411dd3a16b | ||
|
d05dd853bb | ||
|
2995d4942f | ||
|
dff380fb78 | ||
|
d83bf100fa | ||
|
cf5c1494cf | ||
|
db1f4c95a6 | ||
|
f24400f4f1 | ||
|
177707dcb9 | ||
|
9fe9ae3bc0 | ||
|
7bf95fc1d2 | ||
|
3ee8eb9c9e | ||
|
f9573e9908 | ||
|
a1cb7af524 | ||
|
2d8b52f744 | ||
|
0c32d391ea | ||
|
054c78d568 | ||
|
991770cc5d | ||
|
34ad55faa6 | ||
|
efd871b37d | ||
|
6bf0aed8dd | ||
|
5cb5542d91 | ||
|
fb25de0419 | ||
|
84c19e05ce | ||
|
c0b9bf9a37 | ||
|
8b9f9b40c8 | ||
|
b53060e734 | ||
|
1cdaf5c6c4 | ||
|
520798a782 | ||
|
42be576287 | ||
|
5c01729d6f | ||
|
3681ecdf23 | ||
|
eeaa803948 | ||
|
edb8fa7946 | ||
|
204a6e713b | ||
|
5273624089 | ||
|
545663494c | ||
|
56d99d8535 | ||
|
45983b6c5e | ||
|
3bd1820407 | ||
|
653a7a9bff | ||
|
c9940f6b0d | ||
|
75f534b69f | ||
|
621b3fc6dc | ||
|
c3d697de16 | ||
|
a6995f5e58 | ||
|
a317c3de5d | ||
|
1ae819668a | ||
|
4f9b3055ab | ||
|
fbb3b9cef9 | ||
|
89e178e7c9 | ||
|
39abe6fbfe | ||
|
eb3d159612 | ||
|
420a7a429f | ||
|
cdc65db487 | ||
|
a2a8a0ba89 | ||
|
fda1ed0042 | ||
|
c886415893 | ||
|
8be6bc137e | ||
|
e80e02220e | ||
|
726099f870 | ||
|
5364ee6aaf | ||
|
3a2a64dee0 | ||
|
ba0e75f8be | ||
|
11a8823a3a | ||
|
b9a12257fc | ||
|
54db636e76 | ||
|
86d0d0e9fd | ||
|
acdfd12cb6 | ||
|
78fa1c15b2 | ||
|
b414cfcd5e | ||
|
994418cd90 | ||
|
5aa5624551 | ||
|
a27440c237 | ||
|
f3dc94448c | ||
|
cb39b84de5 | ||
|
1e5b42893c | ||
|
829378bba8 | ||
|
9bab8e0da5 | ||
|
b1edd4ff05 | ||
|
259be09334 | ||
|
d3be110ffc | ||
|
9d7a817e87 | ||
|
c463a0e865 | ||
|
ec2f165af4 | ||
|
1ffe7890d8 | ||
|
73a8865561 | ||
|
a355b7bf98 | ||
|
264ee4a761 | ||
|
5f07c648e4 | ||
|
4b4989b6a7 | ||
|
ddba7a317a | ||
|
dd03a1ad10 | ||
|
e92ee19d97 | ||
|
7542dfc4f2 | ||
|
7520c69049 | ||
|
61c11891be | ||
|
ee4b57b4c9 | ||
|
04a9c76087 | ||
|
093baad9b0 | ||
|
9e53b72c80 | ||
|
46398fcda5 | ||
|
3156ed32ed | ||
|
367a045f00 | ||
|
2052664d69 | ||
|
5bcac32bf1 | ||
|
3458210c1c | ||
|
5ed9b96530 | ||
|
b75a5ce763 | ||
|
e119e0f257 | ||
|
f21f412c23 | ||
|
7a190bf709 | ||
|
c9adb3a2a6 | ||
|
8a71322fe4 | ||
|
02a3821f4d | ||
|
2c6419475c | ||
|
a5034e3572 | ||
|
57bd1be5b1 | ||
|
1fbcdffff1 | ||
|
3183f54088 | ||
|
0cbdeecf14 | ||
|
29ef7f896a | ||
|
db5ea2f214 | ||
|
59f2ae39dd | ||
|
5f030a95b7 | ||
|
8fdb0fab39 | ||
|
af8995e022 | ||
|
9b846b7b7e | ||
|
1ea175e0c9 | ||
|
305db83de0 | ||
|
dfc636f587 | ||
|
ad7cb5c726 | ||
|
06beb07c68 | ||
|
2856995089 | ||
|
b98c49ed95 | ||
|
af69606e0b | ||
|
a35082e6c5 | ||
|
48e46d183a | ||
|
cd58d14cef | ||
|
bef2e3b1e4 | ||
|
d8c8b22589 | ||
|
8a0a0249b2 | ||
|
47ace4acfd | ||
|
1a48527df9 | ||
|
851bed680c | ||
|
fd99653957 | ||
|
c5b6479985 | ||
|
d2a5fcdcd8 | ||
|
2a3cec4125 | ||
|
4c4bdc9782 | ||
|
891efed9ad | ||
|
a16e56f711 | ||
|
752b4bcaa5 | ||
|
c04bf92552 | ||
|
a4fb635a5d | ||
|
a6714225e6 | ||
|
767d861df4 | ||
|
36f3c4307c | ||
|
cce78b0698 | ||
|
df83fbf9bf | ||
|
ee8c4ddc2f | ||
|
5d6123a046 | ||
|
321f124c73 | ||
|
99ca31a546 | ||
|
6363d85e85 | ||
|
7780fd4ccb | ||
|
f2282db410 | ||
|
1e42426db5 | ||
|
bc6b052959 | ||
|
b5b047458e | ||
|
ae7c17e1f6 | ||
|
5d1cb432ca | ||
|
b1147f5faa | ||
|
cea7313257 | ||
|
96afae1ec5 | ||
|
3dab2c23da | ||
|
89c873e4aa | ||
|
e05d223462 | ||
|
790db4df03 | ||
|
8fc5610dad | ||
|
791db0998a | ||
|
4c8997f033 | ||
|
b0ab1c8529 | ||
|
a2ac6b694a | ||
|
fb34012482 | ||
|
94447752f2 | ||
|
e97a66593b | ||
|
a63ce2bacd | ||
|
93d97dcb08 | ||
|
31de86f77a | ||
|
b34daa1a70 | ||
|
3279e16bbf | ||
|
2b0c903afe | ||
|
70bc5ea092 | ||
|
a2693d0d22 | ||
|
d5e5bc0675 | ||
|
e37b096951 | ||
|
1b2e1b9a48 | ||
|
c3bb7dc294 | ||
|
9940f2f5ee | ||
|
3a0a932472 | ||
|
4ff968bc98 | ||
|
9b007f1eec | ||
|
17dda486a1 | ||
|
b7d0bd784a | ||
|
6c2bc83ec9 | ||
|
79d6219d9d | ||
|
cc43061ed4 | ||
|
9120dc9a66 | ||
|
d6e888cf38 | ||
|
59ca0e1c58 | ||
|
32da5a7ed6 | ||
|
44c977a7c2 | ||
|
fe14cb14a3 | ||
|
791f055e18 | ||
|
ece8fd2946 | ||
|
2d5a1c37d7 | ||
|
3fe20d1856 | ||
|
18c5538781 | ||
|
5cbf0cb5ac | ||
|
23a3c85bc1 | ||
|
288dbf4e1f | ||
|
5b510107aa | ||
|
042317a306 | ||
|
fa138f80f7 | ||
|
662011a757 | ||
|
db96239982 | ||
|
aca05c4f2e | ||
|
fafd7bfda2 | ||
|
4114774ef3 | ||
|
a5d8bfdb64 | ||
|
660ac303f0 | ||
|
e1697879ec | ||
|
cb2b32e6c5 | ||
|
9d33b4cbcb | ||
|
6cc842b3e6 | ||
|
c2b465880b | ||
|
c4d6714979 | ||
|
d80d096e32 | ||
|
61a58aaad9 | ||
|
62167d867e | ||
|
02513dbd4b | ||
|
7354eb6060 | ||
|
e44879740f | ||
|
a417ab0542 | ||
|
d0c8e28d27 | ||
|
36959e593a | ||
|
90561f7bad | ||
|
ae6a55dbac | ||
|
70622bf92b | ||
|
9875f0c0d8 | ||
|
888c2a0434 | ||
|
c3585adaa0 | ||
|
fc2d61e0c8 | ||
|
b4dd86fadd | ||
|
59f8d9fe07 | ||
|
0c942feaff | ||
|
5ff68740e5 | ||
|
048e3c9e99 | ||
|
7fe18cc1c0 | ||
|
5d0c4b4e3a | ||
|
cb75014221 | ||
|
686bb4e075 | ||
|
235d264a02 | ||
|
77a8b64379 | ||
|
d43821f11f | ||
|
d5445e9dc1 | ||
|
682ca95635 | ||
|
6f461aa54c | ||
|
7711978713 | ||
|
d01ce57c5f | ||
|
521e5e0e42 | ||
|
07dbd0e032 | ||
|
eeb5daa338 | ||
|
965dbdedb7 | ||
|
55215cf271 | ||
|
ab4daf4064 | ||
|
a275c1de92 | ||
|
2c25e60abc | ||
|
559ab8f809 | ||
|
be2b778bae | ||
|
690d9e88d3 | ||
|
8236cda6a6 | ||
|
d8669a2998 | ||
|
52f4920af8 | ||
|
a64573b596 | ||
|
dabd049ad2 | ||
|
58573c4110 | ||
|
6c4bdf7d5e | ||
|
38bf969a46 | ||
|
8d88fe7a83 | ||
|
d0197b7124 | ||
|
3e488773d7 | ||
|
a16695efd4 | ||
|
61bfb264de | ||
|
c1d2dcfc7f | ||
|
a4c6c36cf2 | ||
|
79bec8110c | ||
|
608d91a68b | ||
|
8fdc1ba216 | ||
|
6838643494 | ||
|
28da2045d9 | ||
|
7eb44bd54c | ||
|
95f7a79b61 | ||
|
d77de66c26 | ||
|
6686cbf946 | ||
|
978be50842 | ||
|
df425c23c4 | ||
|
9033066756 | ||
|
be8ae4677a | ||
|
34fe9b60eb | ||
|
43c52b1fad | ||
|
e6ff36f1b4 | ||
|
8f1bdaa95e | ||
|
017d18c045 | ||
|
7868622a79 | ||
|
2dc01f2749 | ||
|
6a6f7bb83e | ||
|
902c951648 | ||
|
829106d793 | ||
|
fd3f81e720 | ||
|
dd4abcb27a | ||
|
0db849fc5c | ||
|
9c30d4c2f8 | ||
|
b91b9a3c62 | ||
|
0a54106866 | ||
|
4bfeddbbed | ||
|
54c2cab5ff | ||
|
ffc6fa66a0 | ||
|
7cfd3bb3d8 | ||
|
94a6f6282f | ||
|
4183d8ddbf | ||
|
dc72ca269b | ||
|
1d190c6ea8 | ||
|
275eaf7683 | ||
|
cd1af4772c | ||
|
d2be050911 | ||
|
bf16cb5f2a | ||
|
46e23ebcab | ||
|
104304aad1 | ||
|
bd9147d18f | ||
|
4a0db63be7 | ||
|
f3c37e2694 | ||
|
d37c87a7ef | ||
|
dd968a98b0 | ||
|
4b09265483 | ||
|
3fa6e9852b | ||
|
68abf67a05 | ||
|
0ad7bac693 | ||
|
3d91ba6a22 | ||
|
8e27f231fd | ||
|
1746ac2f79 | ||
|
bb820cca87 | ||
|
a952ff8542 | ||
|
32f644a907 | ||
|
a55992b1a0 | ||
|
c0cb03801c | ||
|
6cf053c9df | ||
|
e059336dff | ||
|
8f4860cb55 | ||
|
d5f99f41ac | ||
|
2ec28aca62 | ||
|
8bd597a038 | ||
|
2484928a5a | ||
|
a94ddce0bd | ||
|
fcd991844a | ||
|
50028e8623 | ||
|
b689707d15 | ||
|
4030dbad8e | ||
|
df23c01c37 | ||
|
1309ea405e | ||
|
d23f7328f8 | ||
|
f8f18e27c5 | ||
|
ff39ce719e | ||
|
371c0dc873 | ||
|
8f0f848a9a | ||
|
773a8f7da1 | ||
|
a0f4d94cfe | ||
|
e1c6afa38e | ||
|
82b1aab9ba | ||
|
35d400a899 | ||
|
e6c098e750 | ||
|
a13742f097 | ||
|
baf62457a3 | ||
|
2651682be9 | ||
|
79bc7c040e | ||
|
4def30ab8e | ||
|
eb4a8e342d | ||
|
934a91fc29 | ||
|
7b1316fd1b | ||
|
4699dced14 | ||
|
8b8cfbe119 | ||
|
e79bc7f181 | ||
|
c894ba5b40 | ||
|
6cebade78e | ||
|
fde161bac3 | ||
|
d02059d967 | ||
|
d853228c19 | ||
|
3146e624c4 | ||
|
e528a1f452 | ||
|
bf4c5f2631 | ||
|
db982ec1dd | ||
|
307bfc1f4a | ||
|
dfd64e2147 | ||
|
cffce1f856 | ||
|
8487c298ba | ||
|
47bc56f5a4 | ||
|
1d6d80d14f | ||
|
fb1c4ec945 | ||
|
bd82084505 | ||
|
69ea406440 | ||
|
d27e5472dd | ||
|
3de1e966b4 | ||
|
d76732b342 | ||
|
1ce2215aac | ||
|
137b76d329 | ||
|
453ae8c700 | ||
|
f826e55eda | ||
|
96a92d4e32 | ||
|
7be27ef8b0 | ||
|
ab0e141fa9 | ||
|
15b8578b54 | ||
|
ec44055139 | ||
|
63c4d1f793 | ||
|
e80a8bbe3f | ||
|
67bf23feee | ||
|
f07412839a | ||
|
a8375d68b5 | ||
|
53027ad5af | ||
|
0d1cdb8d48 | ||
|
c9f1346fcc | ||
|
73b66c21be | ||
|
9140737a6e | ||
|
5a11b698ef | ||
|
0d584c1954 | ||
|
737139b00f | ||
|
b292febd86 | ||
|
3f0af85588 | ||
|
ab558213b7 | ||
|
a57d8491c0 | ||
|
c24b6d95dd | ||
|
8e4ea49532 | ||
|
0a2562d33d | ||
|
3c10abd1be | ||
|
a266d67fdf | ||
|
53c9bcc976 | ||
|
23906383b6 | ||
|
c39bb18469 | ||
|
b557de4888 | ||
|
c02dcd0f13 | ||
|
1c7b471231 | ||
|
13568dea2b | ||
|
ab62ea5e9d | ||
|
54fbae2593 | ||
|
a3d8761e20 | ||
|
f64c824a78 | ||
|
dc5ec83df9 | ||
|
0416d32114 | ||
|
9abe0960f7 | ||
|
582433b827 | ||
|
3e4ab9009c | ||
|
f505ecc1eb | ||
|
ba5f2e4e52 | ||
|
5c610aee28 | ||
|
30a92cb095 | ||
|
5862a6123f | ||
|
8b9b22c773 | ||
|
b2e39049cb | ||
|
3b24ecdedf | ||
|
3f5327542f | ||
|
ce23c824ea | ||
|
c36f92049d | ||
|
03ae4840e4 | ||
|
4ea93beebb | ||
|
dd2336f8c6 | ||
|
a49144be73 | ||
|
b87b7f9ee8 | ||
|
a7b48cd1cf | ||
|
50e37bf673 | ||
|
0b28fe05b6 | ||
|
5fb621ca53 | ||
|
60016c1f75 | ||
|
b816403172 | ||
|
e867c925d5 | ||
|
26b2efc449 | ||
|
8413531cae | ||
|
0c71c44e16 | ||
|
aa59f27650 | ||
|
47467ec2b3 | ||
|
543334f208 | ||
|
15b7f18ede | ||
|
0c605a3cc4 | ||
|
24bb730d02 | ||
|
0b5445b676 | ||
|
729aaaddd0 | ||
|
ed2fb6d739 | ||
|
fa3beb3694 | ||
|
b0f3b13cff | ||
|
c11d0e3d2e | ||
|
223ea04992 | ||
|
f0a0ec7b0f | ||
|
f01c3d6be6 | ||
|
cda6c60748 | ||
|
b0c9c92627 | ||
|
0c8ac11f09 | ||
|
6138cac56a | ||
|
d868c00e2c | ||
|
346f48401e | ||
|
a5e7e641e9 | ||
|
7a8711e2d7 | ||
|
32d5d7cc27 | ||
|
eb848747d2 | ||
|
ad13956b12 | ||
|
85518a8157 | ||
|
2dbec63327 | ||
|
253ea6eb6d | ||
|
d9988c340c | ||
|
23742dbb8e | ||
|
e1bbef99aa | ||
|
8fdf7b518c | ||
|
6a5895ce37 | ||
|
9d8676f89d | ||
|
3e5948f52e | ||
|
8e9fb8008f | ||
|
d32953c405 | ||
|
d1f4a47c99 | ||
|
ae45344a45 | ||
|
58727cb383 | ||
|
ce27e25dcc | ||
|
b367f57036 | ||
|
62ca216d4d | ||
|
b56bd78c08 | ||
|
f69bcda8c7 | ||
|
63c3ca4ddd | ||
|
aa43a005e3 | ||
|
e35507125c | ||
|
ed6e71a54f | ||
|
82b8c0a78e | ||
|
d998ce7b5b | ||
|
971f911290 | ||
|
2d123d519d | ||
|
19d49e3622 | ||
|
8f8b4c5868 | ||
|
1606cdfb8e | ||
|
47737c7d13 | ||
|
f87502872d | ||
|
2c841d0603 | ||
|
ee79247110 | ||
|
5808832495 | ||
|
61cb6ca4f9 | ||
|
00d97a9731 | ||
|
6207679fad | ||
|
7847b23808 | ||
|
b481351ad7 | ||
|
1722451715 | ||
|
507305b8fb | ||
|
57bf8b8a5c | ||
|
08eefbaffc | ||
|
badc612a8a | ||
|
f55a8fbfc5 | ||
|
34e56f35d2 | ||
|
5c9839a7f4 | ||
|
d4c81229ba | ||
|
c9afd804a4 | ||
|
a10de5c5aa | ||
|
3643cc37ec | ||
|
95d4de206d | ||
|
738e346f81 | ||
|
7e95576849 | ||
|
fd4f19e40a | ||
|
5442b62fca | ||
|
446cdd2a52 | ||
|
e3ffad77ca | ||
|
e0a482fbfc | ||
|
36ec662a13 | ||
|
27107039d6 | ||
|
efcd960748 | ||
|
dfdbc371b7 | ||
|
2ed54a8879 | ||
|
20ec03dbe0 | ||
|
2d3c40bb73 | ||
|
e7fdb45744 | ||
|
c9bab54f76 | ||
|
2ee5e76ed7 | ||
|
53e2ecff4d | ||
|
a79f5c00b1 | ||
|
87701051d3 | ||
|
ce666a02fa | ||
|
87bbfd96ca | ||
|
f52d038d3e | ||
|
fe28af93e8 | ||
|
3ea19ef0cd | ||
|
85b101dfb2 | ||
|
949a81443b | ||
|
96052ba6e3 | ||
|
2727bba2e3 | ||
|
cc0f0bad4e | ||
|
7e03f8d006 | ||
|
d126a31067 | ||
|
09d4e1db14 | ||
|
148000c46b | ||
|
7d8f0846d9 | ||
|
eda01f0853 | ||
|
763f8fab7f | ||
|
d0a8ed37e0 | ||
|
c714a555bd | ||
|
52a52daddd | ||
|
fa1a6cfe5e | ||
|
341a32581c | ||
|
604fa30083 | ||
|
43107d5c71 | ||
|
b95e14ed2e | ||
|
ce10d3a1a8 | ||
|
70a8af10f4 | ||
|
c6fcb16361 | ||
|
52707ac686 | ||
|
f8652e3a0f | ||
|
a4c7ee077c | ||
|
5b462e5c6e | ||
|
b042d986fc | ||
|
38a7d701b2 |
@ -4,15 +4,17 @@ FreeBSD_task:
|
||||
SSL: libressl
|
||||
matrix:
|
||||
freebsd_instance:
|
||||
image_family: freebsd-12-2
|
||||
image_family: freebsd-13-3
|
||||
prepare_script:
|
||||
- pkg install -y $SSL git autoconf automake libtool pkgconf opus jpeg-turbo fdk-aac pixman libX11 libXfixes libXrandr nasm fusefs-libs check
|
||||
- pkg install -y $SSL git autoconf automake libtool pkgconf opus jpeg-turbo fdk-aac pixman libX11 libXfixes libXrandr libxkbfile nasm fusefs-libs3 check imlib2 freetype2 cmocka ibus
|
||||
- git submodule update --init --recursive
|
||||
configure_script:
|
||||
- ./bootstrap
|
||||
- env CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure --localstatedir=/var --enable-strict-locations --with-pkgconfigdir=/usr/local/libdata/pkgconfig --enable-strict-locations --enable-ipv6 --enable-opus --enable-jpeg --enable-fdkaac --enable-painter --enable-pixman --enable-fuse
|
||||
- env CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure --localstatedir=/var --enable-strict-locations --with-pkgconfigdir=/usr/local/libdata/pkgconfig --enable-strict-locations --enable-ibus --enable-ipv6 --enable-opus --enable-jpeg --enable-fdkaac --enable-painter --enable-pixman --enable-fuse --with-imlib2 --with-freetype2
|
||||
build_script:
|
||||
- make -j $(sysctl -n hw.ncpu || echo 4)
|
||||
check_script:
|
||||
- make check
|
||||
install_script:
|
||||
- make install
|
||||
test_script:
|
||||
|
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
||||
open_collective: xrdp-project
|
112
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
112
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@ -0,0 +1,112 @@
|
||||
name: "🕷️ Bug report"
|
||||
description: Report errors or unexpected behavior
|
||||
labels:
|
||||
- "bug"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Before submitting a bug, read the [FAQ](https://github.com/neutrinolabs/xrdp/wiki/Tips-and-FAQ). **In particular, on systemd-based systems. make sure you are not logged in on the console as the same user you are trying to use for xrdp**
|
||||
|
||||
Please do not include links to images or videos on external websites. These are not guaranteed to always be available, and could be used to compromise web browsers.
|
||||
|
||||
Videos hosted on github have a size limit (currently 10MB). If your video is larger than this, please upload it to https://youtube.com
|
||||
- type: input
|
||||
attributes:
|
||||
label: xrdp version
|
||||
placeholder: 0.9.20
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Detailed xrdp version, build options
|
||||
description: Copy & paste the result of `xrdp --version`. DO NOT remove `~~~` but paste the result between two `~~~`.
|
||||
value: |
|
||||
~~~
|
||||
Paste the result between `~~~`. Please DO NOT remove `~~~`!
|
||||
~~~
|
||||
- type: input
|
||||
attributes:
|
||||
label: Operating system & version
|
||||
placeholder: "Ubuntu 22.04 / AlmaLinux 9 / FreeBSD 13.2 / etc"
|
||||
description: Tell us about your operating system. See PRETTY_NAME
|
||||
in /etc/os-release if you don't know.
|
||||
|
||||
Note we are currently unable to provide direct support for Red Hat
|
||||
Enterprise Linux. Either reproduce the issue on CentOS/Alma/Rocky
|
||||
OS, or contact Red Hat directly for support.
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Installation method
|
||||
description: How was xrdp installed from?
|
||||
options:
|
||||
- dnf / apt / zypper / pkg / etc
|
||||
- Homebrew / MacPorts
|
||||
- git clone & make install
|
||||
- Doesn't matter
|
||||
- other
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Which backend do you use?
|
||||
description: Tell us about xrdp backend and version you're using. Typically, it would be either Xvnc or xorgxrdp or rarely NeutrionRDP / FreeRDP.
|
||||
placeholder: Xvnc (tigervnc-1.12.0-13.el9_2)
|
||||
- type: input
|
||||
attributes:
|
||||
label: What desktop environment do you use?
|
||||
description: Tell us about your desktop (e.g. GNOME / KDE / Xfce / xterm). If you're certain the bug you about to report is not desktop specific, fill "any" here.
|
||||
placeholder: GNOME
|
||||
- type: input
|
||||
attributes:
|
||||
label: Environment xrdp running on
|
||||
description: Tell us whether xrdp is running on a VM, or if on a physical machine what graphics cards are installed.
|
||||
- type: input
|
||||
attributes:
|
||||
label: What's your client?
|
||||
description: If you issue occurs with specific clients, tell us the client app name, app version client os version and platform.
|
||||
placeholder: Microsoft's official client from Mac App Store, running on macOS Ventura.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Area(s) with issue?
|
||||
description: What things had an issue? Check all that apply.
|
||||
multiple: true
|
||||
options:
|
||||
- Audio redirection
|
||||
- Authentication
|
||||
- Crashes such as segfault
|
||||
- Clipboard
|
||||
- Compatiblity aginst clients
|
||||
- Compile error
|
||||
- File transfer / drive redirection
|
||||
- Graphic glitches
|
||||
- Keyboard / Mouse
|
||||
- Network
|
||||
- Performance
|
||||
- Session manager (sesman)
|
||||
- Smartcard
|
||||
- Other
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
placeholder: Having detailed steps helps us reproduce the bug.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: ✔️ Expected Behavior
|
||||
placeholder: What were you expecting?
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: ❌ Actual Behavior
|
||||
placeholder: What happened instead?
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Anything else?
|
||||
description: Links? References? Anything that will give us more context about the issue you are encountering! We recommend attaching `xrdp.log`, `xrdp-sesman.log`, `xrdp/xorg.conf` or screenshots to clarify context.
|
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
contact_links:
|
||||
- name: Questions
|
||||
about: If you are new to xrdp and want to ask community for help, raise it as Q&A in discussion.
|
||||
url: https://github.com/neutrinolabs/xrdp/discussions/new?category=q-a
|
||||
|
157
.github/workflows/build.yml
vendored
157
.github/workflows/build.yml
vendored
@ -21,104 +21,157 @@ jobs:
|
||||
feature_set: min
|
||||
arch: amd64
|
||||
os: ubuntu-latest
|
||||
unittests: false
|
||||
DISTCHECK: false
|
||||
|
||||
- CC: g++
|
||||
feature_set: min
|
||||
arch: amd64
|
||||
os: ubuntu-latest
|
||||
unittests: false
|
||||
DISTCHECK: false
|
||||
|
||||
- CC: clang
|
||||
feature_set: min
|
||||
arch: amd64
|
||||
os: ubuntu-latest
|
||||
unittests: false
|
||||
DISTCHECK: false
|
||||
|
||||
# Maximal 64-bit arch builds
|
||||
- CC: gcc
|
||||
feature_set: max
|
||||
arch: amd64
|
||||
os: ubuntu-latest
|
||||
unittests: true
|
||||
DISTCHECK: true
|
||||
|
||||
- CC: g++
|
||||
feature_set: max
|
||||
arch: amd64
|
||||
os: ubuntu-latest
|
||||
unittests: false
|
||||
DISTCHECK: false
|
||||
|
||||
- CC: clang
|
||||
feature_set: max
|
||||
arch: amd64
|
||||
os: ubuntu-latest
|
||||
unittests: true
|
||||
DISTCHECK: true
|
||||
|
||||
- CC: clang
|
||||
feature_set: max
|
||||
arch: amd64
|
||||
os: ubuntu-latest
|
||||
DISTCHECK: true
|
||||
unittests: true
|
||||
DISTCHECK: false
|
||||
name_extra: and AddressSanitized
|
||||
CFLAGS: "-fsanitize=address -ggdb"
|
||||
LDFLAGS: "-fsanitize=address"
|
||||
|
||||
# Maximal debug 64-bit arch builds
|
||||
# Check we can also do a static build without
|
||||
# installing .a files
|
||||
- CC: gcc
|
||||
feature_set: max
|
||||
arch: amd64
|
||||
os: ubuntu-latest
|
||||
unittests: true
|
||||
DISTCHECK: false
|
||||
name_extra: and DEBUG
|
||||
CONF_FLAGS_EXTRA: "--enable-xrdpdebug"
|
||||
CONF_FLAGS_EXTRA: "--enable-devel-all --disable-static"
|
||||
|
||||
# Maximal 32-bit arch builds
|
||||
- CC: gcc
|
||||
feature_set: max
|
||||
arch: i386
|
||||
os: ubuntu-16.04
|
||||
os: ubuntu-latest
|
||||
unittests: true
|
||||
DISTCHECK: false
|
||||
name_extra: for 32-bit arch (legacy OS)
|
||||
CFLAGS: "-m32"
|
||||
LDFLAGS: "-m32"
|
||||
|
||||
- CC: g++
|
||||
feature_set: max
|
||||
arch: i386
|
||||
os: ubuntu-16.04
|
||||
os: ubuntu-latest
|
||||
unittests: false
|
||||
DISTCHECK: false
|
||||
name_extra: for 32-bit arch (legacy OS)
|
||||
CFLAGS: "-m32"
|
||||
LDFLAGS: "-m32"
|
||||
|
||||
- CC: clang
|
||||
feature_set: max
|
||||
arch: i386
|
||||
os: ubuntu-16.04
|
||||
os: ubuntu-latest
|
||||
unittests: true
|
||||
DISTCHECK: false
|
||||
name_extra: for 32-bit arch (legacy OS)
|
||||
CFLAGS: "-m32"
|
||||
LDFLAGS: "-m32"
|
||||
|
||||
name: ${{ matrix.feature_set }} features with ${{ matrix.CC }} ${{ matrix.name_extra }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
CC: ${{ matrix.CC }}
|
||||
CFLAGS: ${{ matrix.CFLAGS }}
|
||||
LDFLAGS: ${{ matrix.LDFLAGS }}
|
||||
|
||||
# HACK (2020-11-16): github actions dosen't support YAML anchors/aliases to
|
||||
# HACK (2020-11-16): github actions doesn't support YAML anchors/aliases to
|
||||
# avoid repeating long config values. So instead the config values are defined
|
||||
# as environment variables using a naming convention with fields that come from
|
||||
# the job config. These environment variables are then referenced as regualr
|
||||
# the job config. These environment variables are then referenced as regular
|
||||
# environment variables via the naming convention in the "define env" step to
|
||||
# define the stardard environment variable used in the rest of the steps.
|
||||
# define the standard environment variable used in the rest of the steps.
|
||||
CONF_FLAGS_amd64_min: "--disable-ipv6 --disable-jpeg --disable-fuse --disable-mp3lame
|
||||
--disable-fdkaac --disable-opus --disable-rfxcodec --disable-painter
|
||||
--disable-pixman"
|
||||
CONF_FLAGS_amd64_max: "--enable-ipv6 --enable-jpeg --enable-fuse --enable-mp3lame
|
||||
--enable-fdkaac --enable-opus --enable-rfxcodec --enable-painter
|
||||
--enable-pixman"
|
||||
CONF_FLAGS_i386_max: "--enable-ipv6 --enable-jpeg --enable-fuse --enable-mp3lame
|
||||
--enable-fdkaac --enable-opus --enable-rfxcodec --enable-painter
|
||||
--disable-pixman --host=i686-linux"
|
||||
--disable-pixman --disable-utmp"
|
||||
CONF_FLAGS_amd64_max: "--enable-ibus --enable-ipv6 --enable-jpeg --enable-fuse
|
||||
--enable-mp3lame --enable-fdkaac --enable-opus --enable-rfxcodec
|
||||
--enable-painter --enable-pixman --enable-utmp
|
||||
--with-imlib2 --with-freetype2 --enable-tests --with-x264"
|
||||
CONF_FLAGS_i386_max: "--enable-ibus --enable-ipv6 --enable-jpeg
|
||||
--enable-mp3lame --enable-opus --enable-rfxcodec
|
||||
--enable-painter --disable-pixman --with-imlib2
|
||||
--with-freetype2 --host=i686-linux --enable-tests"
|
||||
|
||||
PKG_CONFIG_PATH_i386: "/usr/lib/i386-linux-gnu/pkgconfig"
|
||||
CFLAGS_i386: "-m32"
|
||||
LDFLAGS_i386: "-m32"
|
||||
steps:
|
||||
- name: Define feature and arch dependent environment variables
|
||||
- name: "Define feature and arch dependent environment variables"
|
||||
# Note: any "variable=value" written to the $GITHUB_ENV file will be
|
||||
# defined as an environment variable for all future steps in this job
|
||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
|
||||
run: |
|
||||
echo "CONF_FLAGS=$CONF_FLAGS_${{ matrix.arch }}_${{ matrix.feature_set }} ${{ matrix.CONF_FLAGS_EXTRA }}" >> $GITHUB_ENV
|
||||
echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH_${{ matrix.arch }}" >> $GITHUB_ENV
|
||||
echo "CFLAGS=$CFLAGS_${{ matrix.arch }}" >> $GITHUB_ENV
|
||||
echo "LDFLAGS=$LDFLAGS_${{ matrix.arch }}" >> $GITHUB_ENV
|
||||
- uses: actions/checkout@v2
|
||||
- run: sudo scripts/install_xrdp_build_dependencies_with_apt.sh ${{ matrix.feature_set }} ${{ matrix.arch }} --allow-downgrades --allow-remove-essential --allow-change-held-packages
|
||||
- run: ./bootstrap
|
||||
- run: ./configure $CONF_FLAGS
|
||||
- run: make
|
||||
- if: ${{ matrix.DISTCHECK }}
|
||||
run: make distcheck
|
||||
- uses: actions/checkout@v4
|
||||
- name: "Install Dependencies"
|
||||
# See https://github.com/actions/runner-images/issues/7192
|
||||
run: |
|
||||
echo RESET grub-efi/install_devices | sudo debconf-communicate grub-pc
|
||||
sudo scripts/install_xrdp_build_dependencies_with_apt.sh ${{ matrix.feature_set }} ${{ matrix.arch }} --allow-downgrades --allow-remove-essential --allow-change-held-packages
|
||||
- name: Bootstrap
|
||||
run: ./bootstrap
|
||||
- name: configure
|
||||
run: ./configure $CONF_FLAGS
|
||||
- name: make
|
||||
run: make -j $(nproc)
|
||||
- name: unittests
|
||||
if: ${{ matrix.unittests }}
|
||||
run: make check -j $(nproc) || (cat tests/*/test-suite.log && exit 1)
|
||||
- name: distcheck
|
||||
id: dist_check
|
||||
if: ${{ matrix.DISTCHECK }}
|
||||
run: make distcheck -j $(nproc)
|
||||
- name: "Artifact: test-suite.log distcheck"
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always() && steps.dist_check.outcome == 'failure'
|
||||
with:
|
||||
name: test-suite-distcheck-${{ matrix.cc }}-${{ matrix.feature_set }}
|
||||
path: ${{ github.workspace }}/xrdp-*/_build/sub/tests/xrdp/test-suite.log
|
||||
|
||||
cppcheck:
|
||||
name: cppcheck
|
||||
@ -127,22 +180,54 @@ jobs:
|
||||
CC: gcc
|
||||
# This is required to use a version of cppcheck other than that
|
||||
# supplied with the operating system
|
||||
CPPCHECK_VER: 2.4
|
||||
CPPCHECK_VER: "2.16.0"
|
||||
CPPCHECK_REPO: https://github.com/danmar/cppcheck.git
|
||||
steps:
|
||||
# This is currently the only way to get a version into
|
||||
# the cache tag name - see https://github.com/actions/cache/issues/543
|
||||
- run: |
|
||||
echo "OS_VERSION=`lsb_release -sr`" >> $GITHUB_ENV
|
||||
- uses: actions/checkout@v2
|
||||
# Set steps.os.outputs.image to the specific OS (e.g. 'ubuntu20')
|
||||
- name: Get operating system name and version.
|
||||
id: os
|
||||
run: echo "image=$ImageOS" >>$GITHUB_OUTPUT
|
||||
shell: bash
|
||||
- uses: actions/checkout@v4
|
||||
- name: Cache cppcheck
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: cache-cppcheck
|
||||
with:
|
||||
path: ~/cppcheck.local
|
||||
key: ${{ runner.os }}-${{ env.OS_VERSION }}-build-${{ env.cache-name }}-${{ env.CPPCHECK_VER }}
|
||||
- run: sudo scripts/install_cppcheck_dependencies_with_apt.sh
|
||||
key: ${{ steps.os.outputs.image }}-build-${{ env.cache-name }}-${{ env.CPPCHECK_VER }}
|
||||
- run: sudo scripts/install_cppcheck_dependencies_with_apt.sh $CPPCHECK_VER
|
||||
- run: ./bootstrap
|
||||
- run: ./configure
|
||||
- run: scripts/install_cppcheck.sh $CPPCHECK_REPO $CPPCHECK_VER
|
||||
- run: scripts/run_cppcheck.sh -v $CPPCHECK_VER
|
||||
|
||||
code_formatting_check:
|
||||
name: code formatting check
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CC: gcc
|
||||
# This is required to use a version of astyle other than that
|
||||
# supplied with the operating system
|
||||
ASTYLE_VER: 3.4.14
|
||||
ASTYLE_REPO: https://gitlab.com/saalen/astyle.git
|
||||
steps:
|
||||
# Set steps.os.outputs.image to the specific OS (e.g. 'ubuntu20')
|
||||
- name: Get operating system name and version.
|
||||
id: os
|
||||
run: echo "image=$ImageOS" >>$GITHUB_OUTPUT
|
||||
shell: bash
|
||||
- uses: actions/checkout@v4
|
||||
- name: Cache astyle
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: cache-astyle
|
||||
with:
|
||||
path: ~/astyle.local
|
||||
key: ${{ steps.os.outputs.image }}-build-${{ env.cache-name }}-${{ env.ASTYLE_VER }}
|
||||
- run: sudo scripts/install_astyle_dependencies_with_apt.sh
|
||||
- run: scripts/install_astyle.sh $ASTYLE_REPO $ASTYLE_VER
|
||||
- name: Format code with astyle
|
||||
run: scripts/run_astyle.sh -v $ASTYLE_VER
|
||||
- name: Check code formatting
|
||||
run: git diff --exit-code
|
||||
|
50
.github/workflows/coverity.yml
vendored
Normal file
50
.github/workflows/coverity.yml
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
name: Coverity
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
name: scan
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.repository_owner == 'neutrinolabs' }}
|
||||
env:
|
||||
CC: gcc
|
||||
CONF_FLAGS_amd64_max: "--enable-ipv6 --enable-jpeg --enable-fuse --enable-mp3lame
|
||||
--enable-fdkaac --enable-opus --enable-rfxcodec --enable-painter
|
||||
--enable-pixman --enable-utmp
|
||||
--with-imlib2 --with-freetype2 --enable-tests"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download Coverity build tool
|
||||
run: |
|
||||
wget -c -N https://scan.coverity.com/download/linux64 --post-data "token=${{ secrets.COVERITY_SCAN_TOKEN }}&project=neutrinolabs/xrdp" -O coverity_tool.tar.gz
|
||||
mkdir coverity_tool
|
||||
tar xzf coverity_tool.tar.gz --strip 1 -C coverity_tool
|
||||
|
||||
- name: "Install Dependencies"
|
||||
run: |
|
||||
echo RESET grub-efi/install_devices | sudo debconf-communicate grub-pc
|
||||
sudo scripts/install_xrdp_build_dependencies_with_apt.sh max amd64 --allow-downgrades --allow-remove-essential --allow-change-held-packages
|
||||
- name: Bootstrap
|
||||
run: ./bootstrap
|
||||
- name: configure
|
||||
run: ./configure $CONF_FLAGS_amd64_max
|
||||
- name: make
|
||||
run: |
|
||||
export PATH=`pwd`/coverity_tool/bin:$PATH
|
||||
cov-build --dir cov-int make -j $(nproc)
|
||||
|
||||
- name: Submit build result to Coverity Scan
|
||||
run: |
|
||||
tar czvf cov.tar.gz cov-int
|
||||
curl --form token=${{ secrets.COVERITY_SCAN_TOKEN }} \
|
||||
--form email=meta@vmeta.jp \
|
||||
--form file=@cov.tar.gz \
|
||||
--form version="Commit $GITHUB_SHA" \
|
||||
--form description="Build submitted via CI" \
|
||||
https://scan.coverity.com/builds?project=neutrinolabs/xrdp
|
||||
|
14
.gitignore
vendored
14
.gitignore
vendored
@ -14,9 +14,12 @@ config.sub
|
||||
configure
|
||||
depcomp
|
||||
.deps/
|
||||
fontutils/xrdp-dumpfv1
|
||||
fontutils/xrdp-mkfv1
|
||||
genkeymap/xrdp-genkeymap
|
||||
install-sh
|
||||
instfiles/pam.d/xrdp-sesman
|
||||
instfiles/*.service
|
||||
keygen/xrdp-keygen
|
||||
*.la
|
||||
.libs
|
||||
@ -32,7 +35,8 @@ NEWS
|
||||
*.o
|
||||
README
|
||||
sesman/chansrv/xrdp-chansrv
|
||||
sesman/sessvc/xrdp-sessvc
|
||||
sesman/sesexec/xrdp-sesexec
|
||||
sesman/tools/xrdp-authtest
|
||||
sesman/tools/xrdp-dis
|
||||
sesman/tools/xrdp-sesadmin
|
||||
sesman/tools/xrdp-sesrun
|
||||
@ -45,9 +49,17 @@ stamp-h1
|
||||
tap-driver.sh
|
||||
test-driver
|
||||
tests/common/test_common
|
||||
tests/libipm/test_libipm
|
||||
tests/libxrdp/test_libxrdp
|
||||
tests/memtest/memtest
|
||||
tests/xrdp/test_xrdp
|
||||
tools/devel/tcp_proxy/tcp_proxy
|
||||
tools/chkpriv/xrdp-chkpriv
|
||||
tools/chkpriv/xrdp-droppriv
|
||||
*.trs
|
||||
waitforx/waitforx
|
||||
xrdp/xrdp
|
||||
xrdp/xrdp.ini
|
||||
xrdp_configure_options.h
|
||||
xrdpapi/xrdp-xrdpapi-simple
|
||||
.vscode/*
|
||||
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -3,9 +3,11 @@
|
||||
url = https://github.com/neutrinolabs/librfxcodec.git
|
||||
branch = .
|
||||
ignore = untracked
|
||||
|
||||
[submodule "libpainter"]
|
||||
path = libpainter
|
||||
url = https://github.com/neutrinolabs/libpainter.git
|
||||
branch = .
|
||||
ignore = untracked
|
||||
[submodule "ulalaca"]
|
||||
path = ulalaca
|
||||
url = https://github.com/neutrinolabs/ulalaca-xrdp.git
|
||||
|
24
Makefile.am
24
Makefile.am
@ -11,16 +11,7 @@ EXTRA_DIST = \
|
||||
astyle_config.as \
|
||||
bootstrap \
|
||||
coding_style.md \
|
||||
description-pak \
|
||||
design.txt \
|
||||
faq-compile.txt \
|
||||
faq-general.txt \
|
||||
file-loc.txt \
|
||||
fontdump \
|
||||
install.txt \
|
||||
m4 \
|
||||
postinstall-pak \
|
||||
tcutils \
|
||||
vrplayer
|
||||
|
||||
if XRDP_NEUTRINORDP
|
||||
@ -47,24 +38,37 @@ else
|
||||
RFXCODECDIR =
|
||||
endif
|
||||
|
||||
if XRDP_ULALACA
|
||||
ULALACADIR = ulalaca
|
||||
else
|
||||
ULALACADIR =
|
||||
endif
|
||||
|
||||
# This should not be dictionary order but build order
|
||||
SUBDIRS = \
|
||||
third_party \
|
||||
third_party/tomlc99 \
|
||||
common \
|
||||
vnc \
|
||||
xup \
|
||||
mc \
|
||||
$(NEUTRINORDPDIR) \
|
||||
libipm \
|
||||
libxrdp \
|
||||
$(PAINTERDIR) \
|
||||
$(RFXCODECDIR) \
|
||||
xrdp \
|
||||
sesman \
|
||||
xrdp \
|
||||
fontutils \
|
||||
keygen \
|
||||
waitforx \
|
||||
docs \
|
||||
instfiles \
|
||||
genkeymap \
|
||||
xrdpapi \
|
||||
pkgconfig \
|
||||
$(XRDPVRDIR) \
|
||||
$(ULALACADIR) \
|
||||
tests \
|
||||
tools
|
||||
|
||||
|
193
NEWS.md
193
NEWS.md
@ -1,3 +1,194 @@
|
||||
# Release notes for xrdp v0.9.19 (2022/03/17)
|
||||
|
||||
## General announcements
|
||||
* Running xrdp and xrdp-sesman on separate hosts is still supported by this release, but is now deprecated. This is not secure. A future release will replace the TCP socket used between these processes with a Unix Domain Socket, and then cross-host running will not be possible.
|
||||
|
||||
## New features
|
||||
* Both inbound and outbound clipboards can now be restricted for text, files or images [Sponsored by @CyberTrust @clear-code and @kenhys] (#2087)
|
||||
|
||||
## Bug fixes
|
||||
* [CVE-2022-23613](https://www.cve.org/CVERecord?id=CVE-2022-23613): Privilege escalation on xrdp-sesman (This fix is also in the out-of-band v0.9.18.1 release)
|
||||
* The versions of imlib2 used on RHEL 7 and 8 are now detected correctly (#2118)
|
||||
* Some situations where zombie processes could exist have been resolved (#2146, #2151, #2168)
|
||||
* Some null-pointer exceptions which can happen in the logging module have been addressed (#2149)
|
||||
* Some minor logging errors have been corrected (#2152)
|
||||
* The signal handling in sesman has been reworked to prevent race conditions when a child exits. This has also made it possible to reliably reload the sesman configuration with SIGHUP (#1729, #2168)
|
||||
|
||||
## Internal changes
|
||||
* Versions 0.13 and later of checklib can undefine the pre-processor symbol `HAVE_STDINT_H`. The xrdp tests now build successfully against these versions (#2124)
|
||||
* OpenSSL packaging changes (#2130):-
|
||||
- The OpenSSL 3 EVP interface is now fully supported
|
||||
- When building against OpenSSL 3, an internal implementation of the RC4 cipher is used instead of the implementation from the OpenSSL legacy provider
|
||||
- The wrapping of the OpenSSL library has been improved which should make it simpler to provide an alternative cryptographic provider in the future, if required
|
||||
- The logging of TLS/non-TLS security negotiation has been improved
|
||||
* cppcheck version used for CI bumped to 2.7 (#2140)
|
||||
* The `s_check()` macro which is easily mis-used has been removed (#2144)
|
||||
* Status values for the DRDYNVC channel are now available in `libxrdp/xrdp_channel.h`
|
||||
|
||||
## Changes for packagers or developers
|
||||
* On OpenSSL 3 systems, there is now no need to build with the `-Wno-error=deprecated-declarations` flag
|
||||
|
||||
## Known issues
|
||||
|
||||
* On-the-fly resolution change requires the Microsoft Store version of Remote Desktop client but sometimes crashes on connect (#1869)
|
||||
* xrdp's login dialog is not relocated at the center of the new resolution after on-the-fly resolution change happens (#1867)
|
||||
|
||||
-----------------------
|
||||
|
||||
# Release notes for xrdp v0.9.18.1 (2022/02/08)
|
||||
|
||||
This is a security fix release that includes fixes for the following privilege escalation vulnerability.
|
||||
|
||||
* [CVE-2022-23613: Privilege escalation on xrdp-sesman](https://www.cve.org/CVERecord?id=CVE-2022-23613)
|
||||
|
||||
Users who uses xrdp v0.9.17 or v0.9.18 are recommended to update to this version.
|
||||
|
||||
## Special thanks
|
||||
|
||||
Thanks to [Gilad Kleinman](https://github.com/giladkl) reporting the vulnerability and reviewing fix.
|
||||
|
||||
-----------------------
|
||||
|
||||
# Release notes for xrdp v0.9.18 (2022/01/10)
|
||||
|
||||
## General announcements
|
||||
* Running xrdp and xrdp-sesman on separate hosts is still supported by this release, but is now deprecated. This is not secure. A future release will replace the TCP socket used between these processes with a Unix Domain Socket, and then cross-host running will not be possible.
|
||||
* Special thanks for @trishume for contributing code to the RFX codec
|
||||
|
||||
## New features
|
||||
* Backgrounds and logos on the login screen can now be zoomed and scaled (#1962)
|
||||
* Small change for Alpine Linux support (#2005)
|
||||
* loongarch support (#2057)
|
||||
* Improved Fail2ban support (#1976)
|
||||
|
||||
## Bug fixes
|
||||
* Logging is improved for security protocol level decisions (#1974, #1975)
|
||||
* An unnecessary log error message which is always generated when running neutrinordp has been removed (#2016)
|
||||
* An incorrect development log message has been fixed (#2074)
|
||||
* Some informational and error messages written to the console on stdout have been removed or replaced with log messages (#2078 #2080)
|
||||
* Failure to attach to the memory area shared with xorgxrdp is now logged (#2065)
|
||||
* A regression in the VNC module logging which might cause a connection to drop out has been identified and fixed (#1989)
|
||||
* Remote drive redirection now works if printer redirection is also requested by the client (#327)
|
||||
* Some file names could not be copied from the client to the server over the clipboard. This is now fixed (#1992, #1995)
|
||||
* A config value has been added which allows copy-pasting of files to work with Nautilus for GNOME 3 versions >= 3.29.92 (#1994, #1996)
|
||||
* Clipboard now works properly when files can't be read (#1997 #2001)
|
||||
* (xorgxrdp v0.2.18) The screen is fully refreshed after initialising shared memory which should fix black screen problems like #1964
|
||||
* An incorrect initialisation reported by @qarmin has been fixed (#1909)
|
||||
* Some minor memory leaks have been fixed (#2014 #2028)
|
||||
* A hard hang in chansrv when copying files from the remote system has been addressed (#2032)
|
||||
* Users can now capitalise username and password on the login screen if required (#2061)
|
||||
* Some failed size checks in the fastpath code with `--enable-devel-streamcheck` have been addressed (#2066,#2070)
|
||||
* Log level for clipboard restriction has been promoted from DEVEL DEBUG to INFO (#2088)
|
||||
* A buffer overflow in the RFX codec associated with large screens has been fixed (#2087)
|
||||
|
||||
## Internal changes
|
||||
* Some 64-bit packages are removed during the 32-bit CI build process in an attempt to make this more robust (#1985)
|
||||
* Minor improvements to error checking and logging for file copy-paste (#1996)
|
||||
* Now uses cppcheck 2.6 for CI builds (#2008)
|
||||
* Generated systemd unit files now ignored by git (#2006)
|
||||
* More internal tests (#2015)
|
||||
* Some unnecessary files have been removed from the distribution (#2030)
|
||||
* The `which` command in shell scripts has been replaced with `command -v` (#2067)
|
||||
* Additional unit tests added for `g_file_get_size()` (#1988)
|
||||
* A compiler warning with -O3 on gcc 11.1 has been addressed (#2105)
|
||||
* An unused declaration for xrdp_wm_drdynvc_up has been removed (#2098)
|
||||
* The SCP V0 code has been unified, which will make it easier to update and replace (#2011)
|
||||
* Monitor processing unit tests for existing xrdp_sec function have been added (#1932)
|
||||
* The librfxcodec has been updated as part of #2087, and also to add stack frames to assemble code to assist debugging
|
||||
|
||||
## Changes for packagers or developers
|
||||
* The `--with-imlib2` option has been added. If xrdp is built with imlib2, the login screen supports more image formats for the background and logo, and better quality zooming and scaling (#1962)
|
||||
|
||||
## Known issues
|
||||
|
||||
* On-the-fly resolution change requires the Microsoft Store version of Remote Desktop client but sometimes crashes on connect (#1869)
|
||||
* xrdp's login dialog is not relocated at the center of the new resolution after on-the-fly resolution change happens (#1867)
|
||||
|
||||
-----------------------
|
||||
|
||||
# Release notes for xrdp v0.9.17 (2021/08/31)
|
||||
|
||||
## General announcements
|
||||
* Running xrdp and xrdp-sesman on separate hosts is still supported by this release, but is now deprecated. This is not secure. A future release will replace the TCP socket used between these processes with a Unix Domain Socket, and then cross-host running will not be possible.
|
||||
|
||||
## New features
|
||||
* The IP address, port, and user name of NeutrinoRDP Proxy connection are logged in xrdp.log - these connections may not have a sesman log to use (#1873)
|
||||
* The performance settings for NeutrinoRDP can be now configured (#1903)
|
||||
* Support for Alpine Linux in startwm.sh (#1965)
|
||||
* clipboard: log file transfer for the purpose of audit (#1954)
|
||||
* Client's Keyboard layout now can be overridden by xrdp configuration for debugging purposes (#1952)
|
||||
|
||||
## Bug fixes
|
||||
* PAM_USER environment variable is not set when using pam_exec module (#1882)
|
||||
* Allow common channel settings to be overridden for modules as well as chansrv (#1899)
|
||||
* The text only-copy/paste interface for the VNC module (used only when chansrv is not active) has been improved (#1900)
|
||||
* The unsupported `tcutils` utility has been removed (#1943)
|
||||
* The quality of TLS logging has been improved (#1926)
|
||||
* Keyboard information is now passed correctly through NeuutrinoRDP, and can be overridden if required (#1934)
|
||||
* A message is now logged in the sesman log for unsuccessful login attempts detailing the user used (#1947)
|
||||
|
||||
|
||||
## Internal changes
|
||||
* astyle formatting is now checked during CI builds (#1879)
|
||||
* Generalise development build options, and add --enable-devel-streamcheck (#1887)
|
||||
* Now uses cppcheck 2.5 for CI builds (#1938)
|
||||
* The SCP protocol is now using a standard `struct trans` for messaging rather than its own thing (#1925)
|
||||
|
||||
## Changes for packagers or developers
|
||||
* The `--enable-xrdpdebug` developer option has been replaced with finer-grained `--enable-devel-*` options. Consequently, specifying `--enable-xrdpdebug` is now an error (#1913)
|
||||
|
||||
## Known issues
|
||||
|
||||
* On-the-fly resolution change requires the Microsoft Store version of Remote Desktop client but sometimes crashes on connect (#1869)
|
||||
* xrdp's login dialog is not relocated at the center of the new resolution after on-the-fly resolution change happens (#1867)
|
||||
|
||||
-----------------------
|
||||
|
||||
# Release notes for xrdp v0.9.16 (2021/04/30)
|
||||
|
||||
## New features
|
||||
* On-the-fly resolution change now supported for Xvnc and Xorg (#448, #1820) - thanks to @Nexarian for this significant first contribution. See the following YouTube video for a demo.
|
||||
* [Windows] https://youtu.be/cZ0ebieZHeA
|
||||
* [Mac] https://youtu.be/6kfAkyLUgFY
|
||||
* xrdp can now use key algorithms other than RSA for TLS (#1776)
|
||||
* Do not spit on the console 2nd stage (inspired by Debian) #1762
|
||||
* Unified and improved logging (#1742, #1767, #1802, #1806, #1807, #1826, #1843) - thanks to @aquesnel for this detailed work.
|
||||
* Other logging level fixes (#1864)
|
||||
* chansrv can now work on `DISPLAY=:0` so it can be used with x11vnc/Vino/etc sessions (#1849)
|
||||
|
||||
## Bug fixes
|
||||
* Fix some regressions in sesman auth modules (#1769)
|
||||
* Minor manpage fixes (#1787)
|
||||
* Fix TS_PLAY_SOUND_PDU_DATA to set the correct frequency and duration (#1793)
|
||||
* Fix password leakage to logs in NeutrinoRDP module (#1872) - thanks to @TOMATO-ONE for reporting.
|
||||
|
||||
## Internal changes
|
||||
* cppcheck version for CI bumped to 2.4 (#1771, #1836)
|
||||
* FreeBSD version for CI bumped to 12-2 (#1804)
|
||||
* Support for check unit test framework added (#1843, #1860)
|
||||
* FreeBSD FUSE module now compiles under CI but needs additional work (#1856)
|
||||
* Compilation support added for additional Debian platforms (#1818)
|
||||
* Refactoring:-
|
||||
* Confusing preprocessor macro USE_NOPAM replaced with USE_PAM (#1800)
|
||||
* Window manager states in xrdp executable now use symbolic constants instead of numbers (#1803)
|
||||
* Documentation improvements
|
||||
* KRDC added to client list (#1817)
|
||||
* Platform support tier added (#1822)
|
||||
* README file revised (#1863)
|
||||
* Don't install test+development executables by default (#1858)
|
||||
|
||||
## Changes for packagers
|
||||
These changes are likely to impact operating system package builders and those building xrdp from source.
|
||||
* (#1843, #1860) This release introduces an additional optional compile-time dependency on the `check` unit test framework. The dependency is recommended when packaging for compile-time tests.
|
||||
* (#1858) The executables `memtest` and `tcp_proxy` are no longer copied to the sbin directory on a package install.
|
||||
|
||||
## Known issues
|
||||
|
||||
* On-the-fly resolution change requires the Microsoft Store version of Remote Desktop client but sometimes crashes on connect (#1869)
|
||||
* xrdp's login dialog is not relocated at the center of the new resolution after on-the-fly resolution change happens (#1867)
|
||||
|
||||
-----------------------
|
||||
|
||||
# Release notes for xrdp v0.9.15 (2020/12/28)
|
||||
|
||||
## New features
|
||||
@ -68,7 +259,7 @@
|
||||
|
||||
This is a security fix release that includes fixes for the following local buffer overflow vulnerability.
|
||||
|
||||
* [CVE-2022-4044: Local users can perform a buffer overflow attack against the xrdp-sesman service and then impersonate it](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-4044)
|
||||
* [CVE-2020-4044: Local users can perform a buffer overflow attack against the xrdp-sesman service and then impersonate it](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-4044)
|
||||
|
||||
This update is recommended for all xrdp users.
|
||||
|
||||
|
24
README.md
24
README.md
@ -2,7 +2,7 @@
|
||||
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/neutrinolabs/xrdp-questions)
|
||||
![Apache-License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)
|
||||
|
||||
*Current Version:* 0.9.15
|
||||
[![Latest Version](https://img.shields.io/github/v/release/neutrinolabs/xrdp.svg?label=Latest%20Version)](https://github.com/neutrinolabs/xrdp/releases)
|
||||
|
||||
# xrdp - an open source RDP server
|
||||
|
||||
@ -65,23 +65,20 @@ xrdp listens on 3389/tcp. Make sure your firewall accepts connection to
|
||||
apt install xrdp
|
||||
```
|
||||
|
||||
### RedHat / CentOS / Fedora
|
||||
### Fedora, RHEL and derivatives
|
||||
|
||||
On RedHat and CentOS, make sure to enable EPEL packages first.
|
||||
If you're not running Fedora, make sure to enable EPEL packages first.
|
||||
|
||||
```bash
|
||||
yum install epel-release
|
||||
dnf install epel-release
|
||||
```
|
||||
|
||||
Install xrdp package.
|
||||
(All systems) Install xrdp with:-
|
||||
|
||||
```bash
|
||||
yum install xrdp
|
||||
dnf install xrdp
|
||||
```
|
||||
|
||||
`yum` is being replaced with `dnf`, so you may need to use `dnf` instead
|
||||
of `yum` in the above commands.
|
||||
|
||||
## Compiling
|
||||
|
||||
See also https://github.com/neutrinolabs/xrdp/wiki#building-from-sources
|
||||
@ -95,7 +92,7 @@ you would need **openssl-devel**, **pam-devel**, **libX11-devel**,
|
||||
be needed depending on your configuration.
|
||||
|
||||
To compile xrdp from a checked out git repository, you would additionally
|
||||
need **autoconf**, **automake**, **libtool** and **pkgconfig**.
|
||||
need **autoconf**, **automake**, **libtool** and **pkg-config**.
|
||||
|
||||
### Get the source and build it
|
||||
|
||||
@ -124,7 +121,7 @@ pulseaudio modules. The build instructions can be found at wiki.
|
||||
xrdp
|
||||
├── common ······ common code
|
||||
├── docs ········ documentation
|
||||
├── fontdump ···· font dump for Windows
|
||||
├── fontutils ··· font handling utilities
|
||||
├── genkeymap ··· keymap generator
|
||||
├── instfiles ··· installable data file
|
||||
├── keygen ······ xrdp RSA key pair generator
|
||||
@ -138,9 +135,8 @@ xrdp
|
||||
├── scripts ····· build scripts
|
||||
├┬─ sesman ······ session manager for xrdp
|
||||
|├── chansrv ···· channel server for xrdp
|
||||
|├── libscp ····· authorization library
|
||||
|├── libsesman ·· Code common to sesman and its related executables
|
||||
|└── tools ······ session management tools for sys admins
|
||||
├── tcutils ····· QT based utility program for thin clients
|
||||
├── tests ······· tests for the code
|
||||
├┬─ tools ······· tools
|
||||
|└┬─ devel ······ development tools
|
||||
@ -151,5 +147,5 @@ xrdp
|
||||
├── xrdp ········ main server code
|
||||
├── xrdpapi ····· virtual channel API
|
||||
├── xrdpvr ······ API for playing media over RDP
|
||||
└── xup ········· X11rdp and xorgxrdp client module
|
||||
└── xup ········· xorgxrdp client module
|
||||
```
|
||||
|
@ -1,16 +1,12 @@
|
||||
# Security Policy
|
||||
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please DO NOT report any security issues to public GitHub issue.
|
||||
|
||||
If you find a security vulnerability please kindly inform us about the problem immediately
|
||||
so that we can fix the security problem to protect a lot of users around the world as soon
|
||||
as possible.
|
||||
If you find a security vulnerability please kindly inform us via [Report Form](https://github.com/neutrinolabs/xrdp/security/advisories/new) so that we can fix the security problem to protect a lot of users around the world as soon as possible.
|
||||
|
||||
Our email address for security report is below. This is a private mailing list and not open
|
||||
for public viewing.
|
||||
If you have anything else you want to report privately to developers, send us an email to the following email address. This is a private mailing list not open for public viewing.
|
||||
|
||||
* [xrdp-core@googlegroups.com](mailto:xrdp-core@googlegroups.com)
|
||||
|
||||
|
@ -19,13 +19,13 @@
|
||||
--convert-tabs
|
||||
|
||||
# requires --convert-tabs to work properly
|
||||
--indent-preprocessor
|
||||
--indent-preproc-define
|
||||
|
||||
--indent-col1-comments
|
||||
|
||||
--min-conditional-indent=2
|
||||
|
||||
--max-instatement-indent=40
|
||||
--max-continuation-indent=40
|
||||
|
||||
# Insert space padding around operators.
|
||||
--pad-oper
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
|
||||
# Add brackets to unbracketed one line conditional statements (e.g. 'if', 'for', 'while'...).
|
||||
--add-brackets
|
||||
--add-braces
|
||||
|
||||
--align-pointer=name
|
||||
|
||||
@ -45,6 +45,14 @@
|
||||
# For each directory in the command line, process all subdirectories recursively.
|
||||
--recursive
|
||||
|
||||
# Exclude git submodule directories and generated files.
|
||||
--exclude=libpainter
|
||||
--exclude=librfxcodec
|
||||
--exclude=xrdp_configure_options.h
|
||||
|
||||
# ignore errors from generated files that do not exist
|
||||
--ignore-exclude-errors
|
||||
|
||||
# Preserve the original file's date and time modified.
|
||||
--preserve-date
|
||||
|
||||
@ -53,4 +61,3 @@
|
||||
--formatted
|
||||
|
||||
--lineend=linux
|
||||
|
||||
|
13
bootstrap
13
bootstrap
@ -1,27 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
which autoconf
|
||||
command -v autoconf
|
||||
if ! test $? -eq 0
|
||||
then
|
||||
echo "error, install autoconf"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
which automake
|
||||
command -v automake
|
||||
if ! test $? -eq 0
|
||||
then
|
||||
echo "error, install automake"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
which libtool || which libtoolize
|
||||
command -v libtool || command -v libtoolize
|
||||
if ! test $? -eq 0
|
||||
then
|
||||
echo "error, install libtool"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
which pkg-config
|
||||
command -v pkg-config
|
||||
if ! test $? -eq 0
|
||||
then
|
||||
echo "error, install pkg-config"
|
||||
@ -38,4 +38,9 @@ then
|
||||
git submodule update --init librfxcodec
|
||||
fi
|
||||
|
||||
if ! test -f ulalaca/Makefile.am
|
||||
then
|
||||
git submodule update --init ulalaca
|
||||
fi
|
||||
|
||||
autoreconf -fvi
|
||||
|
@ -10,6 +10,7 @@ include_HEADERS = \
|
||||
ms-erref.h \
|
||||
ms-fscc.h \
|
||||
ms-rdpbcgr.h \
|
||||
ms-rdpeclip.h \
|
||||
ms-rdpefs.h \
|
||||
ms-rdpegdi.h \
|
||||
ms-rdpele.h \
|
||||
@ -19,6 +20,7 @@ include_HEADERS = \
|
||||
xrdp_client_info.h \
|
||||
xrdp_constants.h \
|
||||
xrdp_rail.h \
|
||||
xrdp_scancode_defs.h \
|
||||
xrdp_sockets.h
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
@ -26,12 +28,7 @@ AM_CPPFLAGS = \
|
||||
-DXRDP_SBIN_PATH=\"${sbindir}\" \
|
||||
-DXRDP_SHARE_PATH=\"${datadir}/xrdp\" \
|
||||
-DXRDP_PID_PATH=\"${localstatedir}/run\" \
|
||||
-DXRDP_LOG_PATH=\"${localstatedir}/log\" \
|
||||
-DXRDP_SOCKET_PATH=\"${socketdir}\"
|
||||
|
||||
if XRDP_DEBUG
|
||||
AM_CPPFLAGS += -DXRDP_DEBUG
|
||||
endif
|
||||
-DXRDP_LOG_PATH=\"${localstatedir}/log\"
|
||||
|
||||
# -no-suppress is an automake-specific flag which is needed
|
||||
# to prevent us missing compiler errors in some circumstances
|
||||
@ -50,6 +47,8 @@ libcommon_la_SOURCES = \
|
||||
fifo.h \
|
||||
file.c \
|
||||
file.h \
|
||||
guid.c \
|
||||
guid.h \
|
||||
list.c \
|
||||
list.h \
|
||||
list16.c \
|
||||
@ -58,8 +57,11 @@ libcommon_la_SOURCES = \
|
||||
log.h \
|
||||
os_calls.c \
|
||||
os_calls.h \
|
||||
parse.c \
|
||||
parse.h \
|
||||
rail.h \
|
||||
scancode.c \
|
||||
scancode.h \
|
||||
ssl_calls.c \
|
||||
ssl_calls.h \
|
||||
string_calls.c \
|
||||
@ -68,6 +70,7 @@ libcommon_la_SOURCES = \
|
||||
thread_calls.h \
|
||||
trans.c \
|
||||
trans.h \
|
||||
unicode_defines.h \
|
||||
$(PIXMAN_SOURCES)
|
||||
|
||||
libcommon_la_LIBADD = \
|
||||
|
@ -20,6 +20,7 @@
|
||||
#define ARCH_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
@ -45,6 +46,17 @@ typedef unsigned long uintptr_t;
|
||||
|
||||
typedef int bool_t;
|
||||
|
||||
// Define Unicode character types
|
||||
#if defined(HAVE_UCHAR_H)
|
||||
#include <uchar.h>
|
||||
#elif defined(HAVE_STDINT_H)
|
||||
typedef uint_least16_t char16_t;
|
||||
typedef uint_least32_t char32_t;
|
||||
#else
|
||||
typedef uint16_t char16_t;
|
||||
typedef uint32_t char32_t;
|
||||
#endif
|
||||
|
||||
/* you can define L_ENDIAN or B_ENDIAN and NEED_ALIGN or NO_NEED_ALIGN
|
||||
in the makefile to override */
|
||||
|
||||
@ -81,7 +93,8 @@ typedef int bool_t;
|
||||
defined(__AIX__) || defined(__m68k__) || defined(__mips__) || \
|
||||
defined(__ia64__) || defined(__arm__) || defined(__sh__) || \
|
||||
(defined(__PPC__) && defined(__BIG_ENDIAN__)) || \
|
||||
(defined(__ppc__) && defined(__BIG_ENDIAN__))
|
||||
(defined(__ppc__) && defined(__BIG_ENDIAN__)) || \
|
||||
defined(__loongarch__) || defined(__e2k__)
|
||||
#define NEED_ALIGN
|
||||
#elif defined(__x86__) || defined(__x86_64__) || \
|
||||
defined(__AMD64__) || defined(_M_IX86) || defined (_M_AMD64) || \
|
||||
@ -132,12 +145,10 @@ typedef bool_t tbool;
|
||||
typedef intptr_t tbus;
|
||||
typedef intptr_t tintptr;
|
||||
|
||||
/* wide char, socket */
|
||||
/* socket */
|
||||
#if defined(_WIN32)
|
||||
typedef unsigned short twchar;
|
||||
typedef unsigned int tsock;
|
||||
#else
|
||||
typedef int twchar;
|
||||
typedef int tsock;
|
||||
#endif
|
||||
#endif /* DEFINED_Ts */
|
||||
|
254
common/base64.c
254
common/base64.c
@ -1,7 +1,5 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Koichiro Iwao 2017
|
||||
* Copyright (C) 2022 Matt Burt, all xrdp contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -15,7 +13,11 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Base64 encoder / decoder
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file common/base64.c
|
||||
* @brief Base64 encoder / decoder
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
@ -24,57 +26,229 @@
|
||||
|
||||
#include "string_calls.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include "base64.h"
|
||||
|
||||
size_t
|
||||
base64_decoded_bytes(const char *src)
|
||||
/*
|
||||
* Values for invalid and padding characters, used in the charmap
|
||||
* for converting base64 to binary
|
||||
*
|
||||
* These values are specially chosen to make it easy to detect padding or
|
||||
* invalid characters by or-ing together the values looked up in
|
||||
* a base64 quantum */
|
||||
#define E_INVALID 0x40
|
||||
#define E_PAD 0x80
|
||||
|
||||
/* Determine the character set on this platform */
|
||||
#if ('a' == 0x61 && 'z' == 0x7a ) && \
|
||||
('A' == 0x41 && 'Z' == 0x5a ) && \
|
||||
('0' == 0x30 && '9' == 0x39 )
|
||||
# define PLATFORM_IS_ASCII 1
|
||||
#else
|
||||
# error "Unrecognised character set on this platform"
|
||||
#endif /* character set check */
|
||||
|
||||
|
||||
/*
|
||||
* Define a table to map the base64 character values to bit values.
|
||||
*/
|
||||
#ifdef PLATFORM_IS_ASCII
|
||||
#define CHARMAP_BASE 0x28
|
||||
#define E_IV E_INVALID /* For table alignment */
|
||||
const unsigned char charmap[] =
|
||||
{
|
||||
size_t len;
|
||||
size_t padding;
|
||||
/* 0x28 */ E_IV, E_IV, E_IV, 0x3e, E_IV, E_IV, E_IV, 0x3f,
|
||||
/* 0x30 */ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
|
||||
/* 0x38 */ 0x3c, 0x3d, E_IV, E_IV, E_IV, E_PAD, E_IV, E_IV,
|
||||
/* 0x40 */ E_IV, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
|
||||
/* 0x48 */ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
|
||||
/* 0x50 */ 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
|
||||
/* 0x58 */ 0x17, 0x18, 0x19, E_IV, E_IV, E_IV, E_IV, E_IV,
|
||||
/* 0x60 */ E_IV, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
||||
/* 0x68 */ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
/* 0x70 */ 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
||||
/* 0x78 */ 0x31, 0x32, 0x33
|
||||
};
|
||||
#undef E_IV
|
||||
#endif /* PLATFORM_IS_ASCII */
|
||||
|
||||
len = g_strlen(src);
|
||||
padding = 0;
|
||||
|
||||
if (src[len - 1] == '=')
|
||||
/**
|
||||
* Lookup a value in the charmap
|
||||
*
|
||||
* @param x - byte to lookup. Only referenced once so can safely have
|
||||
* side effects.
|
||||
* @param dest - destination to assign result to.
|
||||
*/
|
||||
#define CM_LOOKUP(x,dest) \
|
||||
{ \
|
||||
unsigned int t = (unsigned int)(x) - CHARMAP_BASE;\
|
||||
dest = (t < sizeof(charmap)) ? charmap[t] : E_INVALID; \
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
base64_decode(const char *src, char *dst, size_t dst_len, size_t *actual_len)
|
||||
{
|
||||
*actual_len = 0;
|
||||
size_t src_len;
|
||||
size_t src_i = 0;
|
||||
size_t dst_i = 0;
|
||||
unsigned int a; /* Four characters of base64 quantum */
|
||||
unsigned int b;
|
||||
unsigned int c;
|
||||
unsigned int d;
|
||||
unsigned int v;
|
||||
|
||||
#define OUTPUT_CHAR(x) \
|
||||
{ \
|
||||
if (dst_i < dst_len) \
|
||||
{ \
|
||||
dst[dst_i] = (x);\
|
||||
} \
|
||||
++dst_i; \
|
||||
}
|
||||
|
||||
src_len = g_strlen(src);
|
||||
|
||||
while (src_i < src_len)
|
||||
{
|
||||
padding++;
|
||||
|
||||
if (src[len - 2] == '=')
|
||||
if ((src_len - src_i) >= 4)
|
||||
{
|
||||
padding++;
|
||||
/* Usual case - full quantum */
|
||||
CM_LOOKUP(src[src_i++], a);
|
||||
CM_LOOKUP(src[src_i++], b);
|
||||
CM_LOOKUP(src[src_i++], c);
|
||||
CM_LOOKUP(src[src_i++], d);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add padding on the end to make up the full quantum */
|
||||
CM_LOOKUP(src[src_i++], a);
|
||||
b = E_PAD;
|
||||
c = E_PAD;
|
||||
d = E_PAD;
|
||||
if ((src_len - src_i) > 0)
|
||||
{
|
||||
CM_LOOKUP(src[src_i++], b);
|
||||
}
|
||||
if ((src_len - src_i) > 0)
|
||||
{
|
||||
CM_LOOKUP(src[src_i++], c);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitwise-or the translated quantum values together, so that
|
||||
* any invalid or padding characters can be detected with a
|
||||
* single test */
|
||||
v = a | b | c | d;
|
||||
|
||||
if ((v & E_INVALID) != 0)
|
||||
{
|
||||
return -1; /* At least one invalid character */
|
||||
}
|
||||
|
||||
if ((v & E_PAD) == 0)
|
||||
{
|
||||
/* No padding - a full quantum */
|
||||
v = (a << 18) | (b << 12) | (c << 6) | d;
|
||||
OUTPUT_CHAR(v >> 16);
|
||||
OUTPUT_CHAR((v >> 8) & 0xff);
|
||||
OUTPUT_CHAR(v & 0xff);
|
||||
}
|
||||
else if (((a | b | c) & E_PAD) == 0)
|
||||
{
|
||||
/* No padding in the first 3 chars, so the padding must
|
||||
* be at the end */
|
||||
v = (a << 10) | (b << 4) | (c >> 2);
|
||||
OUTPUT_CHAR(v >> 8);
|
||||
OUTPUT_CHAR(v & 0xff);
|
||||
}
|
||||
else if (((a | b) & E_PAD) == 0 && c == d)
|
||||
{
|
||||
/* No padding in first two chars, so if the last two chars are
|
||||
* equal, they must both be padding */
|
||||
v = (a << 2) | (b >> 4);
|
||||
OUTPUT_CHAR(v);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Illegal padding */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return len * 3 / 4 - padding;
|
||||
*actual_len = dst_i;
|
||||
return 0;
|
||||
|
||||
#undef OUTPUT_CHAR
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
char *
|
||||
base64_decode(char *dst, const char *src, size_t len)
|
||||
size_t
|
||||
base64_encode(const char *src, size_t src_len, char *dst, size_t dst_len)
|
||||
{
|
||||
BIO *b64;
|
||||
BIO *bio;
|
||||
char *b64str;
|
||||
size_t estimated_decoded_bytes;
|
||||
size_t decoded_bytes;
|
||||
char *p = dst;
|
||||
size_t src_i = 0;
|
||||
size_t max_src_len;
|
||||
unsigned int v;
|
||||
static const char *b64chr =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/=";
|
||||
|
||||
b64str = g_strdup(src);
|
||||
estimated_decoded_bytes = base64_decoded_bytes(b64str);
|
||||
dst[estimated_decoded_bytes] = '\0';
|
||||
|
||||
b64 = BIO_new(BIO_f_base64());
|
||||
bio = BIO_new_mem_buf(b64str, len);
|
||||
bio = BIO_push(b64, bio);
|
||||
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
|
||||
decoded_bytes = BIO_read(bio, dst, len);
|
||||
BIO_free_all(bio);
|
||||
|
||||
/* if input is corrupt, return empty string */
|
||||
if (estimated_decoded_bytes != decoded_bytes)
|
||||
/* Each three octets of the source results in four bytes at the output,
|
||||
* plus we need a terminator. So we can work out the maximum number of
|
||||
* source octets we can process */
|
||||
if (dst_len == 0)
|
||||
{
|
||||
g_strncpy(dst, "", sizeof(""));
|
||||
max_src_len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
max_src_len = (dst_len - 1) / 4 * 3;
|
||||
}
|
||||
|
||||
return dst;
|
||||
if (src_len > max_src_len)
|
||||
{
|
||||
src_len = max_src_len;
|
||||
}
|
||||
|
||||
while (src_i < src_len)
|
||||
{
|
||||
switch (src_len - src_i)
|
||||
{
|
||||
case 1:
|
||||
v = (unsigned int)(unsigned char)src[src_i++] << 4;
|
||||
*p++ = b64chr[v >> 6];
|
||||
*p++ = b64chr[v & 0x3f];
|
||||
*p++ = b64chr[64];
|
||||
*p++ = b64chr[64];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
v = (unsigned int)(unsigned char)src[src_i++] << 10;
|
||||
v |= (unsigned int)(unsigned char)src[src_i++] << 2;
|
||||
*p++ = b64chr[v >> 12];
|
||||
*p++ = b64chr[(v >> 6) & 0x3f];
|
||||
*p++ = b64chr[v & 0x3f];
|
||||
*p++ = b64chr[64];
|
||||
break;
|
||||
|
||||
default:
|
||||
v = (unsigned int)(unsigned char)src[src_i++] << 16;
|
||||
v |= (unsigned int)(unsigned char)src[src_i++] << 8;
|
||||
v |= (unsigned int)(unsigned char)src[src_i++];
|
||||
*p++ = b64chr[v >> 18];
|
||||
*p++ = b64chr[(v >> 12) & 0x3f];
|
||||
*p++ = b64chr[(v >> 6) & 0x3f];
|
||||
*p++ = b64chr[v & 0x3f];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
return src_len;
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Koichiro Iwao 2017
|
||||
* Copyright (C) 2021 Koichiro Iwao, all xrdp contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -14,18 +12,71 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Base64 encoder / decoder
|
||||
*/
|
||||
|
||||
#if !defined(SSL_CALLS_H)
|
||||
#define SSL_CALLS_H
|
||||
/**
|
||||
* @file common/base64.h
|
||||
* @brief Base64 encoder / decoder
|
||||
*
|
||||
* Base-64 is described in RFC4648. The following notes apply to this
|
||||
* implementation:-
|
||||
* - The only supported characters are [A-Za-z0-9+/=]. At present,
|
||||
* embedded linefeeds and URL encodings are not supported.
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(BASE64_CALLS_H)
|
||||
#define BASE64_CALLS_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
size_t
|
||||
base64_decoded_bytes(const char *src);
|
||||
char *
|
||||
base64_decode(char *dst, const char *src, size_t len);
|
||||
/*
|
||||
* Decodes a base64 string
|
||||
*
|
||||
* @param src Pointer to null-terminated source
|
||||
* @param dst Pointer to output buffer
|
||||
* @param dst_len Length of above. No more than this is written to the
|
||||
* output buffer
|
||||
* @param actual_len Pointer to value to receive actual length of decoded data
|
||||
* @return 0 for success, 1 for an invalid input string
|
||||
*
|
||||
* The following notes apply to this implementation:-
|
||||
* - Embedded padding is supported, provided it only occurs at the end
|
||||
* of a quantum as described in RFC4648(4). This allows concatenated
|
||||
* encodings to be fed into the decoder.
|
||||
* - Padding of the last quantum is assumed if not provided.
|
||||
* - Excess padding of the last quantum is ignored.
|
||||
*
|
||||
* Only dst_len bytes at most are written to the output. The length
|
||||
* returned in actual_len however represents how much buffer is needed for
|
||||
* a correct result. This may be more than dst_len, and enables the caller
|
||||
* to detect a potential buffer overflow
|
||||
*/
|
||||
int
|
||||
base64_decode(const char *src, char *dst, size_t dst_len, size_t *actual_len);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Encodes a buffer as base64
|
||||
*
|
||||
* @param src Pointer to source
|
||||
* @param src_len Length of above.
|
||||
* @param dst Pointer to output buffer for null-terminated string
|
||||
* @param dst_len Length of above. No more than this is written to the
|
||||
* output buffer
|
||||
* @return Number of source characters processed
|
||||
*
|
||||
* The following notes apply to this implementation:-
|
||||
* - Padding of the last quantum is always written if the number of
|
||||
* source bytes is not divisible by 3.
|
||||
*
|
||||
* The number of source characters processed is always returned. If
|
||||
* the destination buffer is too small for all the output plus a
|
||||
* terminator, the returned value from this procedure will be less than
|
||||
* src_len. In this case no padding characters will have been written,
|
||||
* and the remaining characters can be converted with more calls to
|
||||
* this procedure.
|
||||
*/
|
||||
size_t
|
||||
base64_encode(const char *src, size_t src_len, char *dst, size_t dst_len);
|
||||
|
||||
#endif /* BASE64_CALLS_H */
|
||||
|
@ -91,8 +91,10 @@
|
||||
b = (c) & 0xff; \
|
||||
}
|
||||
/* font macros */
|
||||
#define FONT_DATASIZE(f) \
|
||||
((((f)->height * (((f)->width + 7) / 8)) + 3) & ~3);
|
||||
#define FONT_DATASIZE_FROM_GEOMETRY(width,height) \
|
||||
((((height) * (((width) + 7) / 8)) + 3) & ~3)
|
||||
#define FONT_DATASIZE(f) FONT_DATASIZE_FROM_GEOMETRY((f->width), (f->height))
|
||||
|
||||
/* use crc for bitmap cache lookups */
|
||||
#define USE_CRC
|
||||
|
||||
|
334
common/fifo.c
334
common/fifo.c
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Laxmikant Rashinkar 2004-2014
|
||||
* Copyright (C) Matt Burt 2023
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -14,174 +14,250 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* FIFO implementation to store pointer to data struct
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file common/fifo.c
|
||||
* @brief Fifo for storing generic pointers
|
||||
*
|
||||
* Defines an unbounded FIFO-queue for void * pointers
|
||||
*
|
||||
* The stored pointers are called 'items' below.
|
||||
*
|
||||
* Items are stored in groups called 'chunks'. Chunks are linked together
|
||||
* in a chain:-
|
||||
*
|
||||
* +-------------+ +--------+ +--------+ +--------+
|
||||
* | first_chunk |--->| next |--->| next |--->| NULL |<-+
|
||||
* | last_chunk |-+ +--------+ +--------+ +--------+ |
|
||||
* | . . . | | | item.0 | | item.0 | | item.0 | |
|
||||
* +-------------+ | | ... | | ... | | ... | |
|
||||
* | | item.n | | item.n | | item.n | |
|
||||
* | +--------+ +--------+ +--------+ |
|
||||
* | |
|
||||
* +------------------------------------------+
|
||||
*
|
||||
* This allows items to be added to the FIFO by allocating blocks
|
||||
* as each one fills up.
|
||||
*
|
||||
* The code to read from the FIFO de-allocates blocks as each one is
|
||||
* consumed.
|
||||
*
|
||||
* There is always at least one chunk in the FIFO.
|
||||
*/
|
||||
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fifo.h"
|
||||
#include "os_calls.h"
|
||||
|
||||
/**
|
||||
* Create new fifo data struct
|
||||
*
|
||||
* @return pointer to new FIFO or NULL if system out of memory
|
||||
*****************************************************************************/
|
||||
#define ITEMS_PER_CHUNK 31
|
||||
|
||||
FIFO *
|
||||
fifo_create(void)
|
||||
struct chunk
|
||||
{
|
||||
return (FIFO *) g_malloc(sizeof(FIFO), 1);
|
||||
struct chunk *next;
|
||||
void *items[ITEMS_PER_CHUNK];
|
||||
};
|
||||
|
||||
struct fifo
|
||||
{
|
||||
struct chunk *first_chunk;
|
||||
struct chunk *last_chunk;
|
||||
/** Next address to write in 'last_chunk' */
|
||||
unsigned short writer;
|
||||
/** Next address to read in 'first_chunk' */
|
||||
unsigned short reader;
|
||||
/** Item destructor function, or NULL */
|
||||
fifo_item_destructor item_destructor;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct fifo *
|
||||
fifo_create(fifo_item_destructor item_destructor)
|
||||
{
|
||||
struct fifo *result = NULL;
|
||||
struct chunk *cptr = (struct chunk *)malloc(sizeof(struct chunk));
|
||||
if (cptr != NULL)
|
||||
{
|
||||
/* 'next' pointer in last block is always NULL */
|
||||
cptr->next = NULL;
|
||||
result = (struct fifo *)malloc(sizeof(struct fifo));
|
||||
if (result == NULL)
|
||||
{
|
||||
free(cptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
result->first_chunk = cptr;
|
||||
result->last_chunk = cptr;
|
||||
result->writer = 0;
|
||||
result->reader = 0;
|
||||
result->item_destructor = item_destructor;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Delete specified FIFO
|
||||
*****************************************************************************/
|
||||
* Internal function to call the destructor function on all items in the fifo
|
||||
*
|
||||
* @param self fifo. Can't be NULL
|
||||
* @param closure Additional argument to destructor function
|
||||
*/
|
||||
static void
|
||||
call_item_destructor(struct fifo *self, void *closure)
|
||||
{
|
||||
if (self->item_destructor != NULL)
|
||||
{
|
||||
struct chunk *cptr = self->first_chunk;
|
||||
unsigned int i = self->reader;
|
||||
|
||||
// Process all the chunks up to the last one
|
||||
while (cptr != self->last_chunk)
|
||||
{
|
||||
(*self->item_destructor)(cptr->items[i++], closure);
|
||||
if (i == ITEMS_PER_CHUNK)
|
||||
{
|
||||
cptr = cptr->next;
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Process all the items in the last chunk
|
||||
while (i < self->writer)
|
||||
{
|
||||
(*self->item_destructor)(cptr->items[i++], closure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
fifo_delete(FIFO *self)
|
||||
fifo_delete(struct fifo *self, void *closure)
|
||||
{
|
||||
USER_DATA *udp;
|
||||
|
||||
if (!self)
|
||||
if (self != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
call_item_destructor(self, closure);
|
||||
|
||||
if (!self->head)
|
||||
{
|
||||
/* FIFO is empty */
|
||||
g_free(self);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->head == self->tail)
|
||||
{
|
||||
/* only one item in FIFO */
|
||||
if (self->auto_free)
|
||||
// Now free all the chunks
|
||||
struct chunk *cptr = self->first_chunk;
|
||||
while (cptr != NULL)
|
||||
{
|
||||
g_free(self->head->item);
|
||||
struct chunk *next = cptr->next;
|
||||
free(cptr);
|
||||
cptr = next;
|
||||
}
|
||||
|
||||
g_free(self->head);
|
||||
g_free(self);
|
||||
return;
|
||||
free(self);
|
||||
}
|
||||
|
||||
/* more then one item in FIFO */
|
||||
while (self->head)
|
||||
{
|
||||
udp = self->head;
|
||||
|
||||
if (self->auto_free)
|
||||
{
|
||||
g_free(udp->item);
|
||||
}
|
||||
|
||||
self->head = udp->next;
|
||||
g_free(udp);
|
||||
}
|
||||
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an item to the specified FIFO
|
||||
*
|
||||
* @param self FIFO to operate on
|
||||
* @param item item to add to specified FIFO
|
||||
*
|
||||
* @return 0 on success, -1 on error
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
fifo_clear(struct fifo *self, void *closure)
|
||||
{
|
||||
if (self != NULL)
|
||||
{
|
||||
call_item_destructor(self, closure);
|
||||
|
||||
// Now free all the chunks except the last one
|
||||
struct chunk *cptr = self->first_chunk;
|
||||
while (cptr->next != NULL)
|
||||
{
|
||||
struct chunk *next = cptr->next;
|
||||
free(cptr);
|
||||
cptr = next;
|
||||
}
|
||||
|
||||
// Re-initialise fifo fields
|
||||
self->first_chunk = cptr;
|
||||
self->last_chunk = cptr;
|
||||
self->reader = 0;
|
||||
self->writer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
fifo_add_item(FIFO *self, void *item)
|
||||
fifo_add_item(struct fifo *self, void *item)
|
||||
{
|
||||
USER_DATA *udp;
|
||||
|
||||
if (!self || !item)
|
||||
int rv = 0;
|
||||
if (self != NULL && item != NULL)
|
||||
{
|
||||
return -1;
|
||||
if (self->writer == ITEMS_PER_CHUNK)
|
||||
{
|
||||
// Add another chunk to the chain
|
||||
struct chunk *cptr;
|
||||
cptr = (struct chunk *)malloc(sizeof(struct chunk));
|
||||
if (cptr == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cptr->next = NULL;
|
||||
self->last_chunk->next = cptr;
|
||||
self->last_chunk = cptr;
|
||||
self->writer = 0;
|
||||
}
|
||||
|
||||
self->last_chunk->items[self->writer++] = item;
|
||||
rv = 1;
|
||||
}
|
||||
|
||||
if ((udp = (USER_DATA *) g_malloc(sizeof(USER_DATA), 0)) == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
udp->item = item;
|
||||
udp->next = 0;
|
||||
|
||||
/* if fifo is empty, add to head */
|
||||
if (!self->head)
|
||||
{
|
||||
self->head = udp;
|
||||
self->tail = udp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* add to tail */
|
||||
self->tail->next = udp;
|
||||
self->tail = udp;
|
||||
|
||||
return 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an item from top of FIFO
|
||||
*
|
||||
* @param self FIFO to operate on
|
||||
*
|
||||
* @return top item from FIFO or NULL if FIFO is empty
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
void *
|
||||
fifo_remove_item(FIFO *self)
|
||||
fifo_remove_item(struct fifo *self)
|
||||
{
|
||||
void *item;
|
||||
USER_DATA *udp;
|
||||
|
||||
if (!self || !self->head)
|
||||
void *item = NULL;
|
||||
if (self != NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// More than one chunk in the fifo?
|
||||
if (self->first_chunk != self->last_chunk)
|
||||
{
|
||||
/* We're not reading the last chunk. There
|
||||
* must be something in the fifo */
|
||||
item = self->first_chunk->items[self->reader++];
|
||||
|
||||
if (self->head == self->tail)
|
||||
{
|
||||
/* only one item in FIFO */
|
||||
item = self->head->item;
|
||||
g_free(self->head);
|
||||
self->head = 0;
|
||||
self->tail = 0;
|
||||
return item;
|
||||
/* At the end of this chunk? */
|
||||
if (self->reader == ITEMS_PER_CHUNK)
|
||||
{
|
||||
struct chunk *old_chunk = self->first_chunk;
|
||||
self->first_chunk = old_chunk->next;
|
||||
free(old_chunk);
|
||||
self->reader = 0;
|
||||
}
|
||||
}
|
||||
else if (self->reader < self->writer)
|
||||
{
|
||||
/* We're reading the last chunk */
|
||||
item = self->first_chunk->items[self->reader++];
|
||||
if (self->reader == self->writer)
|
||||
{
|
||||
// fifo is now empty. We can reset the pointers
|
||||
// to prevent unnecessary allocations in the future.
|
||||
self->reader = 0;
|
||||
self->writer = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* more then one item in FIFO */
|
||||
udp = self->head;
|
||||
item = self->head->item;
|
||||
self->head = self->head->next;
|
||||
g_free(udp);
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return FIFO status
|
||||
*
|
||||
* @param self FIFO to operate on
|
||||
*
|
||||
* @return true if FIFO is empty, false otherwise
|
||||
*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
fifo_is_empty(FIFO *self)
|
||||
fifo_is_empty(struct fifo *self)
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return (self->head == 0);
|
||||
return (self == NULL ||
|
||||
(self->first_chunk == self->last_chunk &&
|
||||
self->reader == self->writer));
|
||||
}
|
||||
|
@ -14,34 +14,85 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file common/fifo.h
|
||||
* @brief Fifo for storing generic pointers
|
||||
*
|
||||
* FIFO implementation to store pointer to data struct
|
||||
* Declares an unbounded FIFO-queue for void * pointers
|
||||
*/
|
||||
|
||||
#ifndef _FIFO_H
|
||||
#define _FIFO_H
|
||||
|
||||
#include "arch.h"
|
||||
struct fifo;
|
||||
|
||||
typedef struct user_data USER_DATA;
|
||||
/**
|
||||
* Function used by fifo_clear()/fifo_delete() to destroy items
|
||||
*
|
||||
* @param item Item being deleted
|
||||
* @param closure Additional argument to function
|
||||
*
|
||||
* Use this function to free any allocated storage (e.g. if the items
|
||||
* are dynamically allocated)
|
||||
*/
|
||||
typedef void (*fifo_item_destructor)(void *item, void *closure);
|
||||
|
||||
struct user_data
|
||||
{
|
||||
USER_DATA *next;
|
||||
void *item;
|
||||
};
|
||||
/**
|
||||
* Create new fifo
|
||||
*
|
||||
* @param item_destructor Destructor for fifo items, or NULL for none
|
||||
* @return fifo, or NULL if no memory
|
||||
*/
|
||||
struct fifo *
|
||||
fifo_create(fifo_item_destructor item_destructor);
|
||||
|
||||
typedef struct fifo
|
||||
{
|
||||
USER_DATA *head;
|
||||
USER_DATA *tail;
|
||||
int auto_free;
|
||||
} FIFO;
|
||||
/**
|
||||
* Delete an existing fifo
|
||||
*
|
||||
* Any existing entries on the fifo are passed in order to the
|
||||
* item destructor specified when the fifo was created.
|
||||
*
|
||||
* @param self fifo to delete (may be NULL)
|
||||
* @param closure Additional parameter for fifo item destructor
|
||||
*/
|
||||
void
|
||||
fifo_delete(struct fifo *self, void *closure);
|
||||
|
||||
FIFO *fifo_create(void);
|
||||
void fifo_delete(FIFO *self);
|
||||
int fifo_add_item(FIFO *self, void *item);
|
||||
void *fifo_remove_item(FIFO *self);
|
||||
int fifo_is_empty(FIFO *self);
|
||||
/**
|
||||
* Clear(empty) an existing fifo
|
||||
*
|
||||
* Any existing entries on the fifo are passed in order to the
|
||||
* item destructor specified when the fifo was created.
|
||||
*
|
||||
* @param self fifo to clear (may be NULL)
|
||||
* @param closure Additional parameter for fifo item destructor
|
||||
*/
|
||||
void
|
||||
fifo_clear(struct fifo *self, void *closure);
|
||||
|
||||
/** Add an item to a fifo
|
||||
* @param self fifo
|
||||
* @param item Item to add
|
||||
* @return 1 if successful, 0 for no memory, or tried to add NULL
|
||||
*/
|
||||
int
|
||||
fifo_add_item(struct fifo *self, void *item);
|
||||
|
||||
/** Remove an item from a fifo
|
||||
* @param self fifo
|
||||
* @return item if successful, NULL for no items in FIFO
|
||||
*/
|
||||
void *
|
||||
fifo_remove_item(struct fifo *self);
|
||||
|
||||
/** Is fifo empty?
|
||||
*
|
||||
* @param self fifo
|
||||
* @return 1 if fifo is empty, 0 if not
|
||||
*/
|
||||
int
|
||||
fifo_is_empty(struct fifo *self);
|
||||
|
||||
#endif
|
||||
|
@ -100,7 +100,7 @@ l_file_read_sections(int fd, int max_file_size, struct list *names)
|
||||
{
|
||||
if (line_lookup_for_section_name(text, FILE_MAX_LINE_BYTES) != 0)
|
||||
{
|
||||
list_add_item(names, (tbus)g_strdup(text));
|
||||
list_add_strdup(names, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -286,7 +286,7 @@ l_file_read_section(int fd, int max_file_size, const char *section,
|
||||
if (g_strlen(text) > 0)
|
||||
{
|
||||
file_split_name_value(text, name, value);
|
||||
list_add_item(names, (tbus)g_strdup(name));
|
||||
list_add_strdup(names, name);
|
||||
|
||||
if (value[0] == '$')
|
||||
{
|
||||
@ -294,16 +294,16 @@ l_file_read_section(int fd, int max_file_size, const char *section,
|
||||
|
||||
if (lvalue != 0)
|
||||
{
|
||||
list_add_item(values, (tbus)g_strdup(lvalue));
|
||||
list_add_strdup(values, lvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
list_add_item(values, (tbus)g_strdup(""));
|
||||
list_add_strdup(values, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
list_add_item(values, (tbus)g_strdup(value));
|
||||
list_add_strdup(values, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -349,7 +349,7 @@ file_by_name_read_sections(const char *file_name, struct list *names)
|
||||
return 1;
|
||||
}
|
||||
|
||||
fd = g_file_open_ex(file_name, 1, 0, 0, 0);
|
||||
fd = g_file_open_ro(file_name);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
@ -390,7 +390,7 @@ file_by_name_read_section(const char *file_name, const char *section,
|
||||
return 1;
|
||||
}
|
||||
|
||||
fd = g_file_open_ex(file_name, 1, 0, 0, 0);
|
||||
fd = g_file_open_ro(file_name);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
|
100
common/guid.c
Normal file
100
common/guid.c
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) 2021 Matt Burt, all xrdp contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file common/guid.c
|
||||
* @brief GUID manipulation definitions
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include "guid.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
enum
|
||||
{
|
||||
/* Field offsets in the UUID */
|
||||
E_CLOCK_SEQ_HI_AND_RESERVED = 8,
|
||||
E_TIME_HI_AND_VERSION_MSB = 7,
|
||||
/* UUID versions from RFC4122 section 4.1.3 */
|
||||
E_UUID_VERSION_RANDOM = 4
|
||||
};
|
||||
|
||||
struct guid
|
||||
guid_new(void)
|
||||
{
|
||||
struct guid guid = {0};
|
||||
g_random(guid.g, sizeof(guid.g));
|
||||
/* Show this UUID as conforming to RFC4122 (section 4.1.1) */
|
||||
guid.g[E_CLOCK_SEQ_HI_AND_RESERVED] &= ~0x40; /* Clear bit 6 */
|
||||
guid.g[E_CLOCK_SEQ_HI_AND_RESERVED] |= (char)0x80; /* Set bit 7 */
|
||||
|
||||
guid.g[E_TIME_HI_AND_VERSION_MSB] &= ~0xf0;
|
||||
guid.g[E_TIME_HI_AND_VERSION_MSB] |= (E_UUID_VERSION_RANDOM << 4);
|
||||
|
||||
return guid;
|
||||
}
|
||||
|
||||
void
|
||||
guid_clear(struct guid *guid)
|
||||
{
|
||||
g_memset(&guid->g, '\x00', GUID_SIZE);
|
||||
}
|
||||
|
||||
int
|
||||
guid_is_set(const struct guid *guid)
|
||||
{
|
||||
unsigned int i;
|
||||
int rv = 0;
|
||||
if (guid != NULL)
|
||||
{
|
||||
for (i = 0 ; i < GUID_SIZE; ++i)
|
||||
{
|
||||
if (guid->g[i] != '\x00')
|
||||
{
|
||||
rv = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
const char *guid_to_str(const struct guid *src, char *dest)
|
||||
{
|
||||
const unsigned char *guid = (const unsigned char *)src->g;
|
||||
|
||||
/*
|
||||
* Flipping integers into little-endian
|
||||
* See also: https://devblogs.microsoft.com/oldnewthing/20220928-00/?p=107221
|
||||
*/
|
||||
g_sprintf(dest, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
guid[3], guid[2], guid[1], guid[0],
|
||||
guid[5], guid[4],
|
||||
guid[7], guid[6],
|
||||
guid[8], guid[9],
|
||||
guid[10], guid[11], guid[12], guid[13], guid[14], guid[15]);
|
||||
|
||||
return dest;
|
||||
}
|
94
common/guid.h
Normal file
94
common/guid.h
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2004-2021
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file common/guid.h
|
||||
* @brief GUID manipulation declarations
|
||||
*/
|
||||
|
||||
#ifndef GUID_H
|
||||
#define GUID_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
#define GUID_SIZE 16 /* bytes */
|
||||
#define GUID_STR_SIZE (GUID_SIZE * 2 + 4 + 1) /* w/ 4 hyphens + null terminator */
|
||||
|
||||
|
||||
/**
|
||||
* Use a struct for the guid so we can easily copy by assignment.
|
||||
* We use an array of char so that
|
||||
* we can compare GUIDs with a straight memcmp()
|
||||
*
|
||||
* Some fields of the GUID are in little-endian-order as specified by
|
||||
* [MS-DTYP]. This is at odds with RFC4122 which specifies big-endian
|
||||
* order for all fields.
|
||||
*
|
||||
* Octets RFC4122 field
|
||||
* ------ -------------
|
||||
* 0-3 time_low (little-endian)
|
||||
* 4-5 time_mid (little-endian)
|
||||
* 6-7 time_hi_and_version (little-endian)
|
||||
* 8 clock_seq_hi_and_reserved
|
||||
* 9 clock_seq_low (in order)
|
||||
* 10-15 node
|
||||
*/
|
||||
struct guid
|
||||
{
|
||||
char g[GUID_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an initialised GUID
|
||||
*
|
||||
* The GUID is compatible with RFC4122 section 4.4.
|
||||
*
|
||||
* @return new GUID
|
||||
*/
|
||||
struct guid guid_new(void);
|
||||
|
||||
/**
|
||||
* Clears an initialised GUID, so guid_is_set() returns true
|
||||
*
|
||||
* @param guid GUID to clear
|
||||
*/
|
||||
void
|
||||
guid_clear(struct guid *guid);
|
||||
|
||||
/**
|
||||
* Checks if a GUID is initialised
|
||||
*
|
||||
* @param guid GUID to check (can be NULL)
|
||||
* @return non-zero if GUID is set
|
||||
*/
|
||||
int
|
||||
guid_is_set(const struct guid *guid);
|
||||
|
||||
/**
|
||||
* Converts a GUID to a string representation
|
||||
*
|
||||
* @param guid GUID to represent
|
||||
* @param dest destionation pointer to at least GUID_STR_SIZE
|
||||
* bytes to store the representation
|
||||
* @return dest is returned for convenience
|
||||
*/
|
||||
const char *guid_to_str(const struct guid *guid, char *dest);
|
||||
|
||||
#endif
|
||||
|
303
common/list.c
303
common/list.c
@ -22,26 +22,57 @@
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "arch.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
enum
|
||||
{
|
||||
DEFAULT_LIST_SIZE = 10,
|
||||
DEFAULT_GROW_BY_SIZE = 10
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
struct list *
|
||||
list_create(void)
|
||||
list_create_sized(unsigned int size)
|
||||
{
|
||||
struct list *self;
|
||||
|
||||
self = (struct list *)g_malloc(sizeof(struct list), 1);
|
||||
self->grow_by = 10;
|
||||
self->alloc_size = 10;
|
||||
self->items = (tbus *)g_malloc(sizeof(tbus) * 10, 1);
|
||||
if (size < DEFAULT_LIST_SIZE)
|
||||
{
|
||||
size = DEFAULT_LIST_SIZE;
|
||||
}
|
||||
self = (struct list *)calloc(sizeof(struct list), 1);
|
||||
if (self != NULL)
|
||||
{
|
||||
self->items = (tbus *)malloc(sizeof(tbus) * size);
|
||||
if (self->items == NULL)
|
||||
{
|
||||
free(self);
|
||||
self = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->grow_by = DEFAULT_GROW_BY_SIZE;
|
||||
self->alloc_size = size;
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************************************************************/
|
||||
struct list *
|
||||
list_create(void)
|
||||
{
|
||||
return list_create_sized(DEFAULT_LIST_SIZE);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void
|
||||
list_delete(struct list *self)
|
||||
{
|
||||
@ -56,37 +87,49 @@ list_delete(struct list *self)
|
||||
{
|
||||
for (i = 0; i < self->count; i++)
|
||||
{
|
||||
g_free((void *)self->items[i]);
|
||||
free((void *)self->items[i]);
|
||||
self->items[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
g_free(self->items);
|
||||
g_free(self);
|
||||
free(self->items);
|
||||
free(self);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int
|
||||
grow_list(struct list *self)
|
||||
{
|
||||
int rv = 1;
|
||||
unsigned int new_alloc_size = self->alloc_size + self->grow_by;
|
||||
tbus *p = (tbus *)realloc(self->items, sizeof(tbus) * new_alloc_size);
|
||||
if (p == NULL)
|
||||
{
|
||||
rv = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->alloc_size = new_alloc_size;
|
||||
self->items = p;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
int
|
||||
list_add_item(struct list *self, tbus item)
|
||||
{
|
||||
tbus *p;
|
||||
int i;
|
||||
|
||||
if (self->count >= self->alloc_size)
|
||||
if (self->count == self->alloc_size && !grow_list(self))
|
||||
{
|
||||
i = self->alloc_size;
|
||||
self->alloc_size += self->grow_by;
|
||||
p = (tbus *)g_malloc(sizeof(tbus) * self->alloc_size, 1);
|
||||
g_memcpy(p, self->items, sizeof(tbus) * i);
|
||||
g_free(self->items);
|
||||
self->items = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
self->items[self->count] = item;
|
||||
self->count++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************************************************************/
|
||||
tbus
|
||||
list_get_item(const struct list *self, int index)
|
||||
{
|
||||
@ -98,7 +141,7 @@ list_get_item(const struct list *self, int index)
|
||||
return self->items[index];
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************************************************************/
|
||||
void
|
||||
list_clear(struct list *self)
|
||||
{
|
||||
@ -108,19 +151,18 @@ list_clear(struct list *self)
|
||||
{
|
||||
for (i = 0; i < self->count; i++)
|
||||
{
|
||||
g_free((void *)self->items[i]);
|
||||
free((void *)self->items[i]);
|
||||
self->items[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
g_free(self->items);
|
||||
self->count = 0;
|
||||
self->grow_by = 10;
|
||||
self->alloc_size = 10;
|
||||
self->items = (tbus *)g_malloc(sizeof(tbus) * 10, 1);
|
||||
self->grow_by = DEFAULT_GROW_BY_SIZE;
|
||||
self->alloc_size = DEFAULT_LIST_SIZE;
|
||||
self->items = (tbus *)realloc(self->items, sizeof(tbus) * self->alloc_size);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************************************************************/
|
||||
int
|
||||
list_index_of(struct list *self, tbus item)
|
||||
{
|
||||
@ -137,7 +179,7 @@ list_index_of(struct list *self, tbus item)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************************************************************/
|
||||
void
|
||||
list_remove_item(struct list *self, int index)
|
||||
{
|
||||
@ -147,7 +189,7 @@ list_remove_item(struct list *self, int index)
|
||||
{
|
||||
if (self->auto_free)
|
||||
{
|
||||
g_free((void *)self->items[index]);
|
||||
free((void *)self->items[index]);
|
||||
self->items[index] = 0;
|
||||
}
|
||||
|
||||
@ -160,61 +202,129 @@ list_remove_item(struct list *self, int index)
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
int
|
||||
list_insert_item(struct list *self, int index, tbus item)
|
||||
{
|
||||
tbus *p;
|
||||
int i;
|
||||
|
||||
if (index == self->count)
|
||||
if (index > self->count)
|
||||
{
|
||||
list_add_item(self, item);
|
||||
return;
|
||||
index = self->count;
|
||||
}
|
||||
else if (index < 0)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
if (index >= 0 && index < self->count)
|
||||
if (self->count == self->alloc_size && !grow_list(self))
|
||||
{
|
||||
self->count++;
|
||||
|
||||
if (self->count > self->alloc_size)
|
||||
{
|
||||
i = self->alloc_size;
|
||||
self->alloc_size += self->grow_by;
|
||||
p = (tbus *)g_malloc(sizeof(tbus) * self->alloc_size, 1);
|
||||
g_memcpy(p, self->items, sizeof(tbus) * i);
|
||||
g_free(self->items);
|
||||
self->items = p;
|
||||
}
|
||||
|
||||
for (i = (self->count - 2); i >= index; i--)
|
||||
{
|
||||
self->items[i + 1] = self->items[i];
|
||||
}
|
||||
|
||||
self->items[index] = item;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Move all the items above this location up one
|
||||
for (i = self->count ; i > index ; --i)
|
||||
{
|
||||
self->items[i] = self->items[i - 1];
|
||||
}
|
||||
|
||||
self->count++;
|
||||
|
||||
self->items[index] = item;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
int
|
||||
list_add_strdup(struct list *self, const char *str)
|
||||
{
|
||||
int rv;
|
||||
char *dup;
|
||||
|
||||
if (str == NULL)
|
||||
{
|
||||
rv = list_add_item(self, (tintptr)str);
|
||||
}
|
||||
else if ((dup = g_strdup(str)) == NULL)
|
||||
{
|
||||
rv = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = list_add_item(self, (tintptr)dup);
|
||||
if (!rv)
|
||||
{
|
||||
g_free(dup);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int
|
||||
list_add_strdup_multi(struct list *self, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int entry_count = self->count;
|
||||
const char *s;
|
||||
int rv = 1;
|
||||
|
||||
va_start(ap, self);
|
||||
while ((s = va_arg(ap, const char *)) != NULL)
|
||||
{
|
||||
if (!list_add_strdup(self, s))
|
||||
{
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
if (rv == 0)
|
||||
{
|
||||
// Remove the additional items we added
|
||||
while (self->count > entry_count)
|
||||
{
|
||||
list_remove_item(self, self->count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
/******************************************************************************/
|
||||
/* append one list to another using strdup for each item in the list */
|
||||
/* begins copy at start_index, a zero based index on the source list */
|
||||
void
|
||||
int
|
||||
list_append_list_strdup(struct list *self, struct list *dest, int start_index)
|
||||
{
|
||||
int index;
|
||||
tbus item;
|
||||
char *dup;
|
||||
int rv = 1;
|
||||
int entry_dest_count = dest->count;
|
||||
|
||||
for (index = start_index; index < self->count; index++)
|
||||
{
|
||||
item = list_get_item(self, index);
|
||||
dup = g_strdup((char *)item);
|
||||
list_add_item(dest, (tbus)dup);
|
||||
const char *item = (const char *)list_get_item(self, index);
|
||||
if (!list_add_strdup(dest, item))
|
||||
{
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rv == 0)
|
||||
{
|
||||
// Remove the additional items we added
|
||||
while (dest->count > entry_dest_count)
|
||||
{
|
||||
list_remove_item(dest, dest->count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/******************************************************************************/
|
||||
void
|
||||
list_dump_items(struct list *self)
|
||||
{
|
||||
@ -230,3 +340,68 @@ list_dump_items(struct list *self)
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "%d: %p", index, (void *) list_get_item(self, index));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
split_string_append_fragment(const char **start, const char *end,
|
||||
struct list *list)
|
||||
{
|
||||
unsigned int len = end - *start;
|
||||
// Check for an unexpected terminator in the string
|
||||
const char *term = (const char *)memchr(*start, '\0', len);
|
||||
if (term != NULL)
|
||||
{
|
||||
end = term;
|
||||
len = end - *start;
|
||||
}
|
||||
char *copy = (char *)malloc(len + 1);
|
||||
if (copy == NULL)
|
||||
{
|
||||
list_delete(list);
|
||||
return 0;
|
||||
}
|
||||
g_memcpy(copy, *start, len);
|
||||
copy[len] = '\0';
|
||||
if (!list_add_item(list, (tintptr)copy))
|
||||
{
|
||||
g_free(copy);
|
||||
list_delete(list);
|
||||
return 0;
|
||||
}
|
||||
*start = end + 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
struct list *
|
||||
split_string_into_list(const char *str, char character)
|
||||
{
|
||||
struct list *result = list_create();
|
||||
if (result == NULL)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result->auto_free = 1;
|
||||
|
||||
if (str == NULL)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
const char *p;
|
||||
while ((p = g_strchr(str, character)) != NULL)
|
||||
{
|
||||
if (!split_string_append_fragment(&str, p, result))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (*str != '\0')
|
||||
{
|
||||
if (!split_string_append_fragment(&str, str + g_strlen(str), result))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
111
common/list.h
111
common/list.h
@ -35,9 +35,27 @@ struct list
|
||||
|
||||
struct list *
|
||||
list_create(void);
|
||||
/**
|
||||
* Creates a list with at least the specified number of items
|
||||
* reserved
|
||||
* @param size Number of items to reserve
|
||||
* @return list, or NULL if no memory
|
||||
*/
|
||||
struct list *
|
||||
list_create_sized(unsigned int size);
|
||||
void
|
||||
list_delete(struct list *self);
|
||||
void
|
||||
/**
|
||||
* Adds an item to a list
|
||||
* @param self The list
|
||||
* @param item The item to add
|
||||
* @result 0 if a memory allocation failure occurred. In this
|
||||
* case the item is not added
|
||||
*
|
||||
* Memory allocation failures will not occur if the list is
|
||||
* sized appropriately when created.
|
||||
*/
|
||||
int
|
||||
list_add_item(struct list *self, tintptr item);
|
||||
tintptr
|
||||
list_get_item(const struct list *self, int index);
|
||||
@ -47,11 +65,98 @@ int
|
||||
list_index_of(struct list *self, tintptr item);
|
||||
void
|
||||
list_remove_item(struct list *self, int index);
|
||||
void
|
||||
/**
|
||||
* Inserts an item into a list
|
||||
* @param self The list
|
||||
* @param index The location to insert the item before
|
||||
* @param item The item to add
|
||||
* @result 0 if a memory allocation failure occurred. In this
|
||||
* case the item is not added
|
||||
*
|
||||
* Memory allocation failures will not occur if the list is
|
||||
* sized appropriately when created.
|
||||
*/
|
||||
int
|
||||
list_insert_item(struct list *self, int index, tintptr item);
|
||||
void
|
||||
/**
|
||||
* Adds strings to a list from another list
|
||||
* @param self The source list
|
||||
* @param dest Destination list
|
||||
* @param start_index Index to start on the source list (zero based)
|
||||
*
|
||||
* @result 0 if a memory allocation failure occurred. In this
|
||||
* case the destination list is unaltered.
|
||||
*
|
||||
* Strings from the source list are copied with strdup()
|
||||
* The dest list should have auto_free set, or memory leaks will occur
|
||||
*/
|
||||
int
|
||||
list_append_list_strdup(struct list *self, struct list *dest, int start_index);
|
||||
void
|
||||
list_dump_items(struct list *self);
|
||||
|
||||
/**
|
||||
* Appends a string fragment to a list
|
||||
* @param[in,out] start Pointer to start of fragment (by reference)
|
||||
* @param end Pointer to one past end of fragment
|
||||
* @param list List to append to
|
||||
* @result 1 for success
|
||||
*
|
||||
* In the event of a memory failure, 0 is returned and the list is deleted.
|
||||
*/
|
||||
int
|
||||
split_string_append_fragment(const char **start, const char *end,
|
||||
struct list *list);
|
||||
|
||||
/**
|
||||
* Splits a string on a separation character and then returns a list of
|
||||
* the string split by the character, without the character contained within
|
||||
* the pieces.
|
||||
*
|
||||
* The list must be disposed of by the caller.
|
||||
*
|
||||
* @param str String to split.
|
||||
* @param character Character used as the delimiter between strings.
|
||||
* @param start_index Index to start on the source list (zero based)
|
||||
*
|
||||
* @result 0 if a memory allocation failure occurred.
|
||||
*
|
||||
* String fragments in the list are created with strdup()
|
||||
*/
|
||||
struct list *
|
||||
split_string_into_list(const char *str, char character);
|
||||
|
||||
/**
|
||||
* As list_add_item() but for a C string
|
||||
*
|
||||
* This is a convenience function for a common operation
|
||||
* @param self List to append to
|
||||
* @param str String to append
|
||||
*
|
||||
* The passed-in string is strdup'd onto the list, so if auto_free
|
||||
* isn't set, memory leaks will occur.
|
||||
*
|
||||
* A NULL pointer will be added as a NULL entry.
|
||||
*
|
||||
* @result 0 if any memory allocation failure occurred. In this case
|
||||
* the list is unchanged.
|
||||
*/
|
||||
|
||||
int
|
||||
list_add_strdup(struct list *self, const char *str);
|
||||
|
||||
/**
|
||||
* Add multiple strings to a list
|
||||
*
|
||||
* This is a convenience function for a common operation
|
||||
* @param self List to append to
|
||||
* @param ... Strings to append. Terminate the list with a NULL.
|
||||
*
|
||||
* @result 0 if any memory allocation failure occurred. In this case
|
||||
* the list is unchanged.
|
||||
*/
|
||||
|
||||
int
|
||||
list_add_strdup_multi(struct list *self, ...);
|
||||
|
||||
#endif
|
||||
|
291
common/log.c
291
common/log.c
@ -20,6 +20,7 @@
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
@ -27,6 +28,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "list.h"
|
||||
#include "file.h"
|
||||
#include "os_calls.h"
|
||||
@ -53,23 +55,28 @@ static struct log_config *g_staticLogConfig = NULL;
|
||||
* @return see open(2) return values
|
||||
*
|
||||
*/
|
||||
int
|
||||
static int
|
||||
internal_log_file_open(const char *fname)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (fname != NULL)
|
||||
{
|
||||
ret = open(fname, O_WRONLY | O_CREAT | O_APPEND | O_SYNC,
|
||||
S_IRUSR | S_IWUSR);
|
||||
if (g_strcmp(fname, "<stdout>") != 0)
|
||||
{
|
||||
ret = open(fname, O_WRONLY | O_CREAT | O_APPEND | O_SYNC,
|
||||
S_IRUSR | S_IWUSR);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = dup(1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FD_CLOEXEC
|
||||
if (ret != -1)
|
||||
{
|
||||
fcntl(ret, F_SETFD, FD_CLOEXEC);
|
||||
g_file_set_cloexec(ret, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -81,7 +88,7 @@ internal_log_file_open(const char *fname)
|
||||
* @return syslog equivalent logging level
|
||||
*
|
||||
*/
|
||||
int
|
||||
static int
|
||||
internal_log_xrdp2syslog(const enum logLevels lvl)
|
||||
{
|
||||
switch (lvl)
|
||||
@ -224,7 +231,7 @@ internal_log_end(struct log_config *l_cfg)
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string representing th log level to a value
|
||||
* Converts a string representing the log level to a value
|
||||
* @param buf
|
||||
* @return
|
||||
*/
|
||||
@ -268,7 +275,7 @@ internal_log_text2level(const char *buf)
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
struct log_config *
|
||||
static struct log_config *
|
||||
internal_config_read_logging(int file,
|
||||
const char *applicationName,
|
||||
const char *section_prefix)
|
||||
@ -320,7 +327,7 @@ internal_config_read_logging(int file,
|
||||
|
||||
if (lc->log_file != NULL)
|
||||
{
|
||||
if (lc->log_file[0] != '/')
|
||||
if (lc->log_file[0] != '/' && g_strcmp(lc->log_file, "<stdout>") != 0)
|
||||
{
|
||||
temp_buf = (char *)g_malloc(512, 0);
|
||||
g_snprintf(temp_buf, 511, "%s/%s", XRDP_LOG_PATH, lc->log_file);
|
||||
@ -470,6 +477,7 @@ internalInitAndAllocStruct(void)
|
||||
{
|
||||
ret->fd = -1;
|
||||
ret->enable_syslog = 0;
|
||||
#ifdef LOG_PER_LOGGER_LEVEL
|
||||
ret->per_logger_level = list_create();
|
||||
if (ret->per_logger_level != NULL)
|
||||
{
|
||||
@ -481,6 +489,7 @@ internalInitAndAllocStruct(void)
|
||||
g_free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -490,34 +499,71 @@ internalInitAndAllocStruct(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
internal_log_config_copy(struct log_config *dest, const struct log_config *src)
|
||||
{
|
||||
int i;
|
||||
/**
|
||||
* Copies logging levels only from one log_config structure to another
|
||||
**/
|
||||
|
||||
dest->enable_syslog = src->enable_syslog;
|
||||
dest->fd = src->fd;
|
||||
dest->log_file = g_strdup(src->log_file);
|
||||
static void
|
||||
internal_log_config_copy_levels(struct log_config *dest,
|
||||
const struct log_config *src)
|
||||
{
|
||||
dest->log_level = src->log_level;
|
||||
dest->log_lock = src->log_lock;
|
||||
dest->log_lock_attr = src->log_lock_attr;
|
||||
dest->program_name = src->program_name;
|
||||
dest->enable_syslog = src->enable_syslog;
|
||||
dest->syslog_level = src->syslog_level;
|
||||
dest->enable_console = src->enable_console;
|
||||
dest->console_level = src->console_level;
|
||||
dest->enable_pid = src->enable_pid;
|
||||
dest->dump_on_start = src->dump_on_start;
|
||||
|
||||
#ifdef LOG_PER_LOGGER_LEVEL
|
||||
if (dest->per_logger_level == NULL)
|
||||
{
|
||||
dest->per_logger_level = list_create();
|
||||
if (dest->per_logger_level == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
dest->per_logger_level->auto_free = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
list_clear(dest->per_logger_level);
|
||||
}
|
||||
|
||||
if (src->per_logger_level == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 0; i < src->per_logger_level->count; ++i)
|
||||
{
|
||||
struct log_logger_level *dst_logger =
|
||||
(struct log_logger_level *)g_malloc(sizeof(struct log_logger_level), 1);
|
||||
|
||||
g_memcpy(dst_logger,
|
||||
(struct log_logger_level *) list_get_item(src->per_logger_level, i),
|
||||
sizeof(struct log_logger_level));
|
||||
*dst_logger = *(struct log_logger_level *) list_get_item(src->per_logger_level, i),
|
||||
|
||||
list_add_item(dest->per_logger_level, (tbus) dst_logger);
|
||||
list_add_item(dest->per_logger_level, (tbus) dst_logger);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
internal_log_config_copy(struct log_config *dest, const struct log_config *src)
|
||||
{
|
||||
if (src != NULL && dest != NULL)
|
||||
{
|
||||
dest->fd = src->fd;
|
||||
g_free(dest->log_file);
|
||||
dest->log_file = g_strdup(src->log_file);
|
||||
#ifdef LOG_ENABLE_THREAD
|
||||
dest->log_lock = src->log_lock;
|
||||
dest->log_lock_attr = src->log_lock_attr;
|
||||
#endif
|
||||
dest->program_name = src->program_name;
|
||||
dest->enable_pid = src->enable_pid;
|
||||
dest->dump_on_start = src->dump_on_start;
|
||||
|
||||
internal_log_config_copy_levels(dest, src);
|
||||
}
|
||||
}
|
||||
|
||||
@ -571,6 +617,7 @@ internal_log_location_overrides_level(const char *function_name,
|
||||
const char *file_name,
|
||||
enum logLevels *log_level_return)
|
||||
{
|
||||
#ifdef LOG_PER_LOGGER_LEVEL
|
||||
struct log_logger_level *logger = NULL;
|
||||
int i;
|
||||
|
||||
@ -591,6 +638,7 @@ internal_log_location_overrides_level(const char *function_name,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -641,7 +689,7 @@ log_config_init_from_config(const char *iniFilename,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = g_file_open_ex(iniFilename, 1, 0, 0, 0);
|
||||
fd = g_file_open_ro(iniFilename);
|
||||
|
||||
if (-1 == fd)
|
||||
{
|
||||
@ -662,17 +710,82 @@ log_config_free(struct log_config *config)
|
||||
{
|
||||
if (config != NULL)
|
||||
{
|
||||
#ifdef LOG_PER_LOGGER_LEVEL
|
||||
if (config->per_logger_level != NULL)
|
||||
{
|
||||
list_delete(config->per_logger_level);
|
||||
config->per_logger_level = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (0 != config->log_file)
|
||||
{
|
||||
g_free(config->log_file);
|
||||
config->log_file = 0;
|
||||
}
|
||||
|
||||
g_free(config);
|
||||
}
|
||||
|
||||
return LOG_STARTUP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restarts the logging.
|
||||
*
|
||||
* The logging file is never changed, as it is common in xrdp to share a
|
||||
* log file between parents and children. The end result would be
|
||||
* confusing for the user.
|
||||
*/
|
||||
static enum logReturns
|
||||
log_restart_from_param(const struct log_config *lc)
|
||||
{
|
||||
enum logReturns rv = LOG_GENERAL_ERROR;
|
||||
|
||||
if (g_staticLogConfig == NULL)
|
||||
{
|
||||
log_message(LOG_LEVEL_ALWAYS, "Log not already initialized");
|
||||
}
|
||||
else if (lc == NULL)
|
||||
{
|
||||
g_writeln("lc to log_start_from_param is NULL");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_staticLogConfig->fd >= 0 &&
|
||||
g_strcmp(g_staticLogConfig->log_file, lc->log_file) != 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_WARNING,
|
||||
"Unable to change log file name from %s to %s",
|
||||
g_staticLogConfig->log_file,
|
||||
lc->log_file);
|
||||
}
|
||||
/* Reconfigure syslog logging, allowing for a program_name change */
|
||||
if (g_staticLogConfig->enable_syslog)
|
||||
{
|
||||
closelog();
|
||||
}
|
||||
if (lc->enable_syslog)
|
||||
{
|
||||
openlog(lc->program_name, LOG_CONS | LOG_PID, LOG_DAEMON);
|
||||
}
|
||||
|
||||
/* Copy over simple values... */
|
||||
#ifdef LOG_ENABLE_THREAD
|
||||
g_staticLogConfig->log_lock = lc->log_lock;
|
||||
g_staticLogConfig->log_lock_attr = lc->log_lock_attr;
|
||||
#endif
|
||||
g_staticLogConfig->program_name = lc->program_name;
|
||||
g_staticLogConfig->enable_pid = lc->enable_pid;
|
||||
g_staticLogConfig->dump_on_start = lc->dump_on_start;
|
||||
|
||||
/* ... and the log levels */
|
||||
internal_log_config_copy_levels(g_staticLogConfig, lc);
|
||||
rv = LOG_STARTUP_OK;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
enum logReturns
|
||||
log_start_from_param(const struct log_config *src_log_config)
|
||||
{
|
||||
@ -721,7 +834,7 @@ log_start_from_param(const struct log_config *src_log_config)
|
||||
*/
|
||||
enum logReturns
|
||||
log_start(const char *iniFile, const char *applicationName,
|
||||
bool_t dump_on_start)
|
||||
unsigned int flags)
|
||||
{
|
||||
enum logReturns ret = LOG_GENERAL_ERROR;
|
||||
struct log_config *config;
|
||||
@ -730,14 +843,24 @@ log_start(const char *iniFile, const char *applicationName,
|
||||
|
||||
if (config != NULL)
|
||||
{
|
||||
config->dump_on_start = dump_on_start;
|
||||
ret = log_start_from_param(config);
|
||||
log_config_free(config);
|
||||
|
||||
if (ret != LOG_STARTUP_OK)
|
||||
config->dump_on_start = (flags & LOG_START_DUMP_CONFIG) ? 1 : 0;
|
||||
if (flags & LOG_START_RESTART)
|
||||
{
|
||||
g_writeln("Could not start log");
|
||||
ret = log_restart_from_param(config);
|
||||
if (ret != LOG_STARTUP_OK)
|
||||
{
|
||||
g_writeln("Could not restart log");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = log_start_from_param(config);
|
||||
if (ret != LOG_STARTUP_OK)
|
||||
{
|
||||
g_writeln("Could not start log");
|
||||
}
|
||||
}
|
||||
log_config_free(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -767,9 +890,9 @@ log_end(void)
|
||||
/* log a hex dump */
|
||||
enum logReturns
|
||||
log_hexdump(const enum logLevels log_level,
|
||||
const char *message,
|
||||
const char *src,
|
||||
int len)
|
||||
const char *message,
|
||||
const char *src,
|
||||
int len)
|
||||
{
|
||||
return log_hexdump_with_location("", "", 0, log_level, message, src, len);
|
||||
}
|
||||
@ -787,7 +910,7 @@ log_hexdump_with_location(const char *function_name,
|
||||
{
|
||||
char *dump_buffer;
|
||||
enum logReturns rv = LOG_STARTUP_OK;
|
||||
enum logLevels override_log_level;
|
||||
enum logLevels override_log_level = LOG_LEVEL_NEVER;
|
||||
bool_t override_destination_level = 0;
|
||||
|
||||
override_destination_level = internal_log_location_overrides_level(
|
||||
@ -820,12 +943,12 @@ log_hexdump_with_location(const char *function_name,
|
||||
if (g_strlen(file_name) > 0)
|
||||
{
|
||||
rv = log_message_with_location(function_name, file_name, line_number,
|
||||
log_level, "%s %s%s",
|
||||
log_level, "%s %s%s",
|
||||
message, HEX_DUMP_HEADER, dump_buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = log_message(log_level, "%s %s%s",
|
||||
rv = log_message(log_level, "%s %s%s",
|
||||
message, HEX_DUMP_HEADER, dump_buffer);
|
||||
}
|
||||
g_free(dump_buffer);
|
||||
@ -894,12 +1017,10 @@ internal_log_message(const enum logLevels lvl,
|
||||
const char *msg,
|
||||
va_list ap)
|
||||
{
|
||||
char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */
|
||||
char buff[LOG_BUFFER_SIZE + 43]; /* 31 ("[2022-10-07T19:58:33.065+0900] ") + 8 (log level) + 4 (space+cr+lf+\0) */
|
||||
int len = 0;
|
||||
enum logReturns rv = LOG_STARTUP_OK;
|
||||
int writereply = 0;
|
||||
time_t now_t;
|
||||
struct tm *now;
|
||||
|
||||
if (g_staticLogConfig == NULL)
|
||||
{
|
||||
@ -919,20 +1040,18 @@ internal_log_message(const enum logLevels lvl,
|
||||
return LOG_STARTUP_OK;
|
||||
}
|
||||
|
||||
now_t = time(&now_t);
|
||||
now = localtime(&now_t);
|
||||
getFormattedDateTime(buff, 32);
|
||||
|
||||
strftime(buff, 21, "[%Y%m%d-%H:%M:%S] ", now);
|
||||
|
||||
internal_log_lvl2str(lvl, buff + 20);
|
||||
internal_log_lvl2str(lvl, buff + 31);
|
||||
|
||||
if (g_staticLogConfig->enable_pid)
|
||||
{
|
||||
g_snprintf(buff + 28, LOG_BUFFER_SIZE, "[pid:%d tid:%lld] ",
|
||||
/* 31 (datetime) + 8 (log level) = 39 */
|
||||
g_snprintf(buff + 39, LOG_BUFFER_SIZE, "[pid:%d tid:%lld] ",
|
||||
g_getpid(), (long long) tc_get_threadid());
|
||||
len = g_strlen(buff + 28);
|
||||
len = g_strlen(buff + 39);
|
||||
}
|
||||
len += vsnprintf(buff + 28 + len, LOG_BUFFER_SIZE - len, msg, ap);
|
||||
len += vsnprintf(buff + 39 + len, LOG_BUFFER_SIZE - len, msg, ap);
|
||||
|
||||
/* checking for truncated messages */
|
||||
if (len > LOG_BUFFER_SIZE)
|
||||
@ -942,17 +1061,18 @@ internal_log_message(const enum logLevels lvl,
|
||||
}
|
||||
|
||||
/* forcing the end of message string */
|
||||
/* 31 (datetime) + 8 (log level) = 39 */
|
||||
#ifdef _WIN32
|
||||
buff[len + 28] = '\r';
|
||||
buff[len + 29] = '\n';
|
||||
buff[len + 30] = '\0';
|
||||
buff[len + 39] = '\r';
|
||||
buff[len + 40] = '\n';
|
||||
buff[len + 41] = '\0';
|
||||
#else
|
||||
#ifdef _MACOS
|
||||
buff[len + 28] = '\r';
|
||||
buff[len + 29] = '\0';
|
||||
buff[len + 39] = '\r';
|
||||
buff[len + 40] = '\0';
|
||||
#else
|
||||
buff[len + 28] = '\n';
|
||||
buff[len + 29] = '\0';
|
||||
buff[len + 39] = '\n';
|
||||
buff[len + 40] = '\0';
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -962,7 +1082,7 @@ internal_log_message(const enum logLevels lvl,
|
||||
{
|
||||
/* log to syslog*/
|
||||
/* %s fix compiler warning 'not a string literal' */
|
||||
syslog(internal_log_xrdp2syslog(lvl), "%s", buff + 20);
|
||||
syslog(internal_log_xrdp2syslog(lvl), "%s", buff + 31);
|
||||
}
|
||||
|
||||
if (g_staticLogConfig->enable_console
|
||||
@ -1024,3 +1144,56 @@ getLogFile(char *replybuf, int bufsize)
|
||||
|
||||
return replybuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted datetime for log
|
||||
* @return
|
||||
*/
|
||||
char *
|
||||
getFormattedDateTime(char *replybuf, int bufsize)
|
||||
{
|
||||
char buf_datetime[21]; /* 2022-10-07T16:36:04 + . */
|
||||
char buf_millisec[4]; /* 357 */
|
||||
char buf_timezone[6]; /* +0900 */
|
||||
|
||||
struct tm *now;
|
||||
struct timeval tv;
|
||||
int millisec;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
now = localtime(&tv.tv_sec);
|
||||
|
||||
millisec = (tv.tv_usec + 500 / 1000);
|
||||
g_snprintf(buf_millisec, sizeof(buf_millisec), "%03d", millisec);
|
||||
|
||||
strftime(buf_datetime, sizeof(buf_datetime), "%FT%T.", now);
|
||||
strftime(buf_timezone, sizeof(buf_timezone), "%z", now);
|
||||
g_snprintf(replybuf, bufsize, "[%s%s%s] ", buf_datetime, buf_millisec, buf_timezone);
|
||||
|
||||
return replybuf;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
#ifdef USE_DEVEL_LOGGING
|
||||
void
|
||||
log_devel_leaking_fds(const char *exe, int min, int max)
|
||||
{
|
||||
struct list *fd_list = g_get_open_fds(min, max);
|
||||
|
||||
if (fd_list != NULL)
|
||||
{
|
||||
int i;
|
||||
for (i = 0 ; i < fd_list->count ; ++i)
|
||||
{
|
||||
int fd = (int)fd_list->items[i];
|
||||
if (g_file_get_cloexec(fd) == 0)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_WARNING,
|
||||
"File descriptor %d is not CLOEXEC when running %s",
|
||||
fd, exe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // USE_DEVEL_LOGGING
|
||||
|
||||
|
91
common/log.h
91
common/log.h
@ -25,6 +25,13 @@
|
||||
#include "defines.h"
|
||||
#include "list.h"
|
||||
|
||||
/* Check the config_ac.h file is included so we know whether to enable the
|
||||
* development macros
|
||||
*/
|
||||
#ifndef CONFIG_AC_H
|
||||
# error config_ac.h not visible in log.h
|
||||
#endif
|
||||
|
||||
/* logging buffer size */
|
||||
#define LOG_BUFFER_SIZE 8192
|
||||
#define LOGGER_NAME_SIZE 50
|
||||
@ -66,7 +73,7 @@ enum logReturns
|
||||
/* enable threading */
|
||||
/*#define LOG_ENABLE_THREAD*/
|
||||
|
||||
#ifdef XRDP_DEBUG
|
||||
#ifdef USE_DEVEL_LOGGING
|
||||
|
||||
#define LOG_PER_LOGGER_LEVEL
|
||||
|
||||
@ -74,12 +81,13 @@ enum logReturns
|
||||
* @brief Logging macro for messages that are for an XRDP developer to
|
||||
* understand and debug XRDP code.
|
||||
*
|
||||
* Note: all log levels are relavant to help a developer understand XRDP at
|
||||
* Note: all log levels are relevant to help a developer understand XRDP at
|
||||
* different levels of granularity.
|
||||
*
|
||||
* Note: the logging function calls are removed when XRDP_DEBUG is NOT defined.
|
||||
* Note: the logging function calls are removed when USE_DEVEL_LOGGING is
|
||||
* NOT defined.
|
||||
*
|
||||
* Note: when the build is configured with --enable-xrdpdebug, then
|
||||
* Note: when the build is configured with --enable-devel-logging, then
|
||||
* the log level can be configured per the source file name or method name
|
||||
* (with the suffix "()") in the [LoggingPerLogger]
|
||||
* section of the configuration file.
|
||||
@ -99,11 +107,11 @@ enum logReturns
|
||||
log_message_with_location(__func__, __FILE__, __LINE__, log_level, args)
|
||||
|
||||
/**
|
||||
* @brief Logging macro for messages that are for a systeam administrator to
|
||||
* @brief Logging macro for messages that are for a system administrator to
|
||||
* configure and run XRDP on their machine.
|
||||
*
|
||||
* Note: the logging function calls contain additional code location info when
|
||||
* XRDP_DEBUG is defined.
|
||||
* USE_DEVEL_LOGGING is defined.
|
||||
*
|
||||
* @param lvl, the log level
|
||||
* @param msg, the log text as a printf format c-string
|
||||
@ -116,7 +124,8 @@ enum logReturns
|
||||
* @brief Logging macro for logging the contents of a byte array using a hex
|
||||
* dump format.
|
||||
*
|
||||
* Note: the logging function calls are removed when XRDP_DEBUG is NOT defined.
|
||||
* Note: the logging function calls are removed when USE_DEVEL_LOGGING is
|
||||
* NOT defined.
|
||||
*
|
||||
* @param log_level, the log level
|
||||
* @param message, a message prefix for the hex dump. Note: no printf like
|
||||
@ -140,6 +149,8 @@ enum logReturns
|
||||
#define LOG_HEXDUMP(log_level, message, buffer, length) \
|
||||
log_hexdump_with_location(__func__, __FILE__, __LINE__, log_level, message, buffer, length)
|
||||
|
||||
#define LOG_DEVEL_LEAKING_FDS(exe,min,max) log_devel_leaking_fds(exe,min,max)
|
||||
|
||||
#else
|
||||
#define LOG(log_level, args...) log_message(log_level, args)
|
||||
#define LOG_HEXDUMP(log_level, message, buffer, length) \
|
||||
@ -151,8 +162,26 @@ enum logReturns
|
||||
#define LOG_DEVEL(log_level, args...) UNUSED_VAR(LOG_STARTUP_OK)
|
||||
#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length) UNUSED_VAR(LOG_STARTUP_OK)
|
||||
|
||||
#define LOG_DEVEL_LEAKING_FDS(exe,min,max)
|
||||
#endif
|
||||
|
||||
/* Flags values for log_start() */
|
||||
|
||||
/**
|
||||
* Dump the log config on startup
|
||||
*/
|
||||
#define LOG_START_DUMP_CONFIG (1<<0)
|
||||
|
||||
/**
|
||||
* Restart the logging system.
|
||||
*
|
||||
* On a restart, existing files are not closed. This is because the
|
||||
* files may be shared by sub-processes, and the result will not be what the
|
||||
* user expects
|
||||
*/
|
||||
#define LOG_START_RESTART (1<<1)
|
||||
|
||||
#ifdef LOG_PER_LOGGER_LEVEL
|
||||
enum log_logger_type
|
||||
{
|
||||
LOG_TYPE_FILE = 0,
|
||||
@ -165,22 +194,27 @@ struct log_logger_level
|
||||
enum log_logger_type logger_type;
|
||||
char logger_name[LOGGER_NAME_SIZE + 1];
|
||||
};
|
||||
#endif
|
||||
|
||||
struct log_config
|
||||
{
|
||||
const char *program_name;
|
||||
char *log_file;
|
||||
const char *program_name; /* Pointer to static storage */
|
||||
char *log_file; /* Dynamically allocated */
|
||||
int fd;
|
||||
enum logLevels log_level;
|
||||
int enable_console;
|
||||
enum logLevels console_level;
|
||||
int enable_syslog;
|
||||
enum logLevels syslog_level;
|
||||
#ifdef LOG_PER_LOGGER_LEVEL
|
||||
struct list *per_logger_level;
|
||||
#endif
|
||||
int dump_on_start;
|
||||
int enable_pid;
|
||||
#ifdef LOG_ENABLE_THREAD
|
||||
pthread_mutex_t log_lock;
|
||||
pthread_mutexattr_t log_lock_attr;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* internal functions, only used in log.c if this ifdef is defined.*/
|
||||
@ -266,8 +300,8 @@ internal_log_is_enabled_for_level(const enum logLevels log_level,
|
||||
const enum logLevels override_log_level);
|
||||
|
||||
/**
|
||||
* @param function_name, the function name (typicaly the __func__ macro)
|
||||
* @param file_name, the file name (typicaly the __FILE__ macro)
|
||||
* @param function_name, the function name (typically the __func__ macro)
|
||||
* @param file_name, the file name (typically the __FILE__ macro)
|
||||
* @param[out] log_level_return, the log level to use instead of the destination log level
|
||||
* @return true if the logger location overrides the destination log levels
|
||||
*/
|
||||
@ -285,13 +319,12 @@ internal_log_location_overrides_level(const char *function_name,
|
||||
* @param iniFile
|
||||
* @param applicationName the name that is used in the log for the running
|
||||
* application
|
||||
* @param dump_on_start Whether to dump the config on stdout before
|
||||
* logging is started
|
||||
* @param flags Flags to affect the operation of the call
|
||||
* @return LOG_STARTUP_OK on success
|
||||
*/
|
||||
enum logReturns
|
||||
log_start(const char *iniFile, const char *applicationName,
|
||||
bool_t dump_on_start);
|
||||
unsigned int flags);
|
||||
|
||||
/**
|
||||
* An alternative log_start where the caller gives the params directly.
|
||||
@ -372,9 +405,9 @@ log_hexdump(const enum logLevels log_level,
|
||||
*
|
||||
* Please prefer to use the LOG and LOG_DEVEL macros instead of this function directly.
|
||||
*
|
||||
* @param function_name, the function name (typicaly the __func__ macro)
|
||||
* @param file_name, the file name (typicaly the __FILE__ macro)
|
||||
* @param line_number, the line number in the file (typicaly the __LINE__ macro)
|
||||
* @param function_name, the function name (typically the __func__ macro)
|
||||
* @param file_name, the file name (typically the __FILE__ macro)
|
||||
* @param line_number, the line number in the file (typically the __LINE__ macro)
|
||||
* @param lvl, the loglevel
|
||||
* @param msg, the logtext.
|
||||
* @param ...
|
||||
@ -404,4 +437,28 @@ log_hexdump_with_location(const char *function_name,
|
||||
* @return
|
||||
*/
|
||||
char *getLogFile(char *replybuf, int bufsize);
|
||||
|
||||
/**
|
||||
* Returns formatted datetime for log
|
||||
* @return
|
||||
*/
|
||||
char *getFormattedDateTime(char *replybuf, int bufsize);
|
||||
|
||||
#ifdef USE_DEVEL_LOGGING
|
||||
/**
|
||||
* Log open file descriptors not cloexec before execing another program
|
||||
*
|
||||
* Used to ensure file descriptors aren't leaking when running
|
||||
* non-privileged executables
|
||||
*
|
||||
* Use the LOG_DEVEL_LEAKING_FDS() macro to invoke this function
|
||||
*
|
||||
* @param exe Executable we're about to launch
|
||||
* @param min Minimum FD to consider
|
||||
* @param max Maximum FD to consider + 1, or -1 for no upper FD
|
||||
*/
|
||||
void
|
||||
log_devel_leaking_fds(const char *exe, int min, int max);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -52,18 +52,35 @@
|
||||
|
||||
/* TS_UD_HEADER: type ((2.2.1.3.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define SEC_TAG_CLI_INFO 0xc001 /* CS_CORE? */
|
||||
#define SEC_TAG_CLI_CRYPT 0xc002 /* CS_SECURITY? */
|
||||
#define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */
|
||||
#define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */
|
||||
#define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */
|
||||
#define SEC_TAG_CLI_INFO 0xc001 /* CS_CORE? */
|
||||
#define SEC_TAG_CLI_CRYPT 0xc002 /* CS_SECURITY? */
|
||||
#define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */
|
||||
#define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */
|
||||
#define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */
|
||||
#define SEC_TAG_CLI_MONITOR_EX 0xc008 /* CS_MONITOR_EX */
|
||||
#define SEC_TAG_SRV_INFO 0x0c01 /* SC_CORE */
|
||||
#define SEC_TAG_SRV_CRYPT 0x0c02 /* SC_SECURITY */
|
||||
#define SEC_TAG_SRV_CHANNELS 0x0c03 /* SC_NET? */
|
||||
|
||||
|
||||
/* Client Core Data: colorDepth, postBeta2ColorDepth (2.2.1.3.2) */
|
||||
#define RNS_UD_COLOR_4BPP 0xCA00
|
||||
#define RNS_UD_COLOR_8BPP 0xCA01
|
||||
#define RNS_UD_COLOR_16BPP_555 0xCA02
|
||||
#define RNS_UD_COLOR_16BPP_565 0xCA03
|
||||
#define RNS_UD_COLOR_24BPP 0xCA04
|
||||
#define RNS_UD_COLOR_4BPP 0xCA00
|
||||
#define RNS_UD_COLOR_8BPP 0xCA01
|
||||
#define RNS_UD_COLOR_16BPP_555 0xCA02
|
||||
#define RNS_UD_COLOR_16BPP_565 0xCA03
|
||||
#define RNS_UD_COLOR_24BPP 0xCA04
|
||||
|
||||
/* Client Core Data: supportedColorDepths (2.2.1.3.2) */
|
||||
#define RNS_UD_24BPP_SUPPORT 0x0001
|
||||
#define RNS_UD_16BPP_SUPPORT 0x0002
|
||||
#define RNS_UD_15BPP_SUPPORT 0x0004
|
||||
#define RNS_UD_32BPP_SUPPORT 0x0008
|
||||
|
||||
/* Client Core Data: earlyCapabilityFlags (2.2.1.3.2) */
|
||||
#define RNS_UD_CS_WANT_32BPP_SESSION 0x0002
|
||||
#define RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU 0x0040
|
||||
#define RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL 0x0100
|
||||
#define RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN 0x0800
|
||||
|
||||
/* Client Core Data: connectionType (2.2.1.3.2) */
|
||||
#define CONNECTION_TYPE_MODEM 0x01
|
||||
@ -74,14 +91,37 @@
|
||||
#define CONNECTION_TYPE_LAN 0x06
|
||||
#define CONNECTION_TYPE_AUTODETECT 0x07
|
||||
|
||||
/* Channel definition structure CHANNEL_DEF (2.2.1.3.4.1) */
|
||||
/* TS_UD_CS_NET (2.2.1.3.4) */
|
||||
/* This isn't explicitly named in MS-RDPBCGR */
|
||||
#define CHANNEL_NAME_LEN 7
|
||||
#define MAX_STATIC_CHANNELS 31
|
||||
|
||||
/* 2.2.1.3.6 Client Monitor Data - */
|
||||
/* Channel definition structure CHANNEL_DEF (2.2.1.3.4.1) */
|
||||
#define CHANNEL_NAME_LEN 7
|
||||
/* These names are also not explicitly defined in MS-RDPBCGR */
|
||||
#define CLIPRDR_SVC_CHANNEL_NAME "cliprdr"
|
||||
#define DRDYNVC_SVC_CHANNEL_NAME "drdynvc"
|
||||
#define RAIL_SVC_CHANNEL_NAME "rail"
|
||||
#define RDPSND_SVC_CHANNEL_NAME "rdpsnd"
|
||||
#define RDPDR_SVC_CHANNEL_NAME "rdpdr"
|
||||
|
||||
/* 2.2.1.3.6 Client Monitor Data */
|
||||
/* monitorCount (4 bytes): A 32-bit, unsigned integer. The number of display */
|
||||
/* monitor definitions in the monitorDefArray field (the maximum allowed is 16). */
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_MONITORS 16
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_MONITORS 16
|
||||
|
||||
/* 2.2.1.3.6 Client Monitor Data */
|
||||
/* The maximum width of the virtual desktop resulting from the union of the monitors */
|
||||
/* contained in the monitorDefArray field MUST NOT exceed 32,766 pixels. Similarly, */
|
||||
/* the maximum height of the virtual desktop resulting from the union of the monitors */
|
||||
/* contained in the monitorDefArray field MUST NOT exceed 32,766 pixels. */
|
||||
/* The minimum permitted size of the virtual desktop is 200 x 200 pixels. */
|
||||
#define CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_DESKTOP_WIDTH 0xC8 // 200
|
||||
#define CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_DESKTOP_HEIGHT 0xC8 // 200
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_WIDTH 0x7FFE // 32766
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_HEIGHT 0x7FFE // 32766
|
||||
|
||||
/* 2.2.1.3.6.1 Monitor Definition (TS_MONITOR_DEF) */
|
||||
#define TS_MONITOR_PRIMARY 0x00000001
|
||||
|
||||
/* Options field */
|
||||
/* NOTE: XR_ prefixed to avoid conflict with FreeRDP */
|
||||
@ -97,6 +137,9 @@
|
||||
#define XR_CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
|
||||
#define REMOTE_CONTROL_PERSISTENT 0x00100000
|
||||
|
||||
/* Server earlyCapabilityFlags (2.2.1.4.2) */
|
||||
#define RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED 0x00000008
|
||||
|
||||
/* Server Proprietary Certificate (2.2.1.4.3.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define SEC_TAG_PUBKEY 0x0006 /* BB_RSA_KEY_BLOB */
|
||||
@ -111,6 +154,9 @@
|
||||
#define RDP_LOGON_LEAVE_AUDIO 0x2000
|
||||
#define RDP_LOGON_RAIL 0x8000
|
||||
|
||||
/* Extended Info Packet: clientAddress (2.2.1.11.1.1.1) */
|
||||
#define EXTENDED_INFO_MAX_CLIENT_ADDR_LENGTH 80
|
||||
|
||||
/* Extended Info Packet: performanceFlags (2.2.1.11.1.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP5_DISABLE_NOTHING 0x00
|
||||
@ -121,9 +167,16 @@
|
||||
#define RDP5_NO_CURSOR_SHADOW 0x20
|
||||
#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */
|
||||
|
||||
/* LICENSE_PREAMBLE (2.2.1.12.1.1) */
|
||||
#define ERROR_ALERT 0xff
|
||||
#define PREAMBLE_VERSION_3_0 0x03
|
||||
|
||||
/* LICENSE_BINARY_BLOB (2.2.1.12.1.2) */
|
||||
#define LICENCE_TAG_USER 0x000f /* BB_CLIENT_USER_NAME_BLOB */
|
||||
#define LICENCE_TAG_HOST 0x0010 /* BB_CLIENT_MACHINE_NAME_BLOB */
|
||||
#define BB_ERROR_BLOB 0x0004
|
||||
|
||||
/* LICENSE_ERROR_MESSAGE (2.2.1.12.1.3) */
|
||||
#define STATUS_VALID_CLIENT 0x00000007
|
||||
#define ST_NO_TRANSITION 0x00000002
|
||||
|
||||
/* Maps to generalCapabilitySet in T.128 page 138 */
|
||||
|
||||
@ -236,6 +289,15 @@
|
||||
#define exDiscReasonLicenseCantUpgradeLicense 0x0109
|
||||
#define exDiscReasonLicenseNoRemoteConnections 0x010a
|
||||
|
||||
/* Virtual channel PDU (2.2.6.1) */
|
||||
#define CHANNEL_CHUNK_LENGTH 1600
|
||||
|
||||
/* Channel PDU Header flags (2.2.6.1.1) */
|
||||
/* NOTE: XR_ prefixed to avoid conflict with FreeRDP */
|
||||
#define XR_CHANNEL_FLAG_FIRST 0x00000001
|
||||
#define XR_CHANNEL_FLAG_LAST 0x00000002
|
||||
#define XR_CHANNEL_FLAG_SHOW_PROTOCOL 0x00000010
|
||||
|
||||
/* General Capability Set: osMajorType (2.2.7.1.1) */
|
||||
#define OSMAJORTYPE_UNSPECIFIED 0x0000
|
||||
#define OSMAJORTYPE_WINDOWS 0x0001
|
||||
@ -343,11 +405,11 @@
|
||||
|
||||
/* Bitmap Codec: codecGUID (2.2.7.2.10.1.1) */
|
||||
|
||||
/* CODEC_GUID_NSCODEC CA8D1BB9-000F-154F-589FAE2D1A87E2D6 */
|
||||
/* CODEC_GUID_NSCODEC CA8D1BB9-000F-154F-589F-AE2D1A87E2D6 */
|
||||
#define XR_CODEC_GUID_NSCODEC \
|
||||
"\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6"
|
||||
|
||||
/* CODEC_GUID_REMOTEFX 76772F12-BD72-4463-AFB3B73C9C6F7886 */
|
||||
/* CODEC_GUID_REMOTEFX 76772F12-BD72-4463-AFB3-B73C9C6F7886 */
|
||||
#define XR_CODEC_GUID_REMOTEFX \
|
||||
"\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
|
||||
|
||||
@ -355,18 +417,22 @@
|
||||
#define XR_CODEC_GUID_IMAGE_REMOTEFX \
|
||||
"\xD4\xCC\x44\x27\x8A\x9D\x74\x4E\x80\x3C\x0E\xCB\xEE\xA1\x9C\x54"
|
||||
|
||||
/* MFVideoFormat_H264 0x34363248-0000-0010-800000AA00389B71 */
|
||||
/* MFVideoFormat_H264 34363248-0000-0010-8000-00AA00389B71 */
|
||||
#define XR_CODEC_GUID_H264 \
|
||||
"\x48\x32\x36\x34\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"
|
||||
|
||||
/* CODEC_GUID_JPEG 1BAF4CE6-9EED-430C-869ACB8B37B66237 */
|
||||
/* CODEC_GUID_JPEG 1BAF4CE6-9EED-430C-869A-CB8B37B66237 */
|
||||
#define XR_CODEC_GUID_JPEG \
|
||||
"\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
|
||||
|
||||
/* CODEC_GUID_PNG 0E0C858D-28E0-45DB-ADAA0F83E57CC560 */
|
||||
/* CODEC_GUID_PNG 0E0C858D-28E0-45DB-ADAA-0F83E57CC560 */
|
||||
#define XR_CODEC_GUID_PNG \
|
||||
"\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60"
|
||||
|
||||
/* CODEC_GUID_IGNORE 0C4351A6-3535-42AE-910C-CDFCE5760B58 */
|
||||
#define XR_CODEC_GUID_IGNORE \
|
||||
"\xA6\x51\x43\x0C\x35\x35\xAE\x42\x91\x0C\xCD\xFC\xE5\x76\x0B\x58"
|
||||
|
||||
/* PDU Types (2.2.8.1.1.1.1) */
|
||||
#define PDUTYPE_DEMANDACTIVEPDU 0x1
|
||||
#define PDUTYPE_CONFIRMACTIVEPDU 0x3
|
||||
@ -398,17 +464,14 @@
|
||||
#define RDP_DATA_PDU_LOGON 38
|
||||
#define RDP_DATA_PDU_FONT2 39
|
||||
#define RDP_DATA_PDU_DISCONNECT 47
|
||||
#define PDUTYPE2_MONITOR_LAYOUT_PDU 55
|
||||
|
||||
/* TS_SECURITY_HEADER: flags (2.2.8.1.1.2.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define SEC_CLIENT_RANDOM 0x0001 /* SEC_EXCHANGE_PKT? */
|
||||
#define SEC_EXCHANGE_PKT 0x0001
|
||||
#define SEC_ENCRYPT 0x0008
|
||||
#define SEC_LOGON_INFO 0x0040 /* SEC_INFO_PKT */
|
||||
#define SEC_LICENCE_NEG 0x0080 /* SEC_LICENSE_PKT */
|
||||
|
||||
#define SEC_TAG_SRV_INFO 0x0c01 /* SC_CORE */
|
||||
#define SEC_TAG_SRV_CRYPT 0x0c02 /* SC_SECURITY */
|
||||
#define SEC_TAG_SRV_CHANNELS 0x0c03 /* SC_NET? */
|
||||
#define SEC_INFO_PKT 0x0040
|
||||
#define SEC_LICENSE_PKT 0x0080
|
||||
#define SEC_LICENSE_ENCRYPT_CS 0x0280
|
||||
|
||||
/* Slow-Path Input Event: messageType (2.2.8.1.1.3.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
@ -421,12 +484,10 @@
|
||||
#define RDP_INPUT_MOUSEX 0x8002
|
||||
|
||||
/* Keyboard Event: keyboardFlags (2.2.8.1.1.3.1.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define KBD_FLAG_RIGHT 0x0001
|
||||
#define KBD_FLAG_EXT 0x0100 /* KBDFLAGS_EXTENDED */
|
||||
#define KBD_FLAG_QUIET 0x1000
|
||||
#define KBD_FLAG_DOWN 0x4000
|
||||
#define KBD_FLAG_UP 0x8000
|
||||
#define KBDFLAGS_EXTENDED 0x0100
|
||||
#define KBDFLAGS_EXTENDED1 0x0200
|
||||
#define KBDFLAGS_DOWN 0x4000
|
||||
#define KBDFLAGS_RELEASE 0x8000
|
||||
|
||||
/* Mouse Event: pointerFlags (2.2.8.1.1.3.1.1.3) */
|
||||
#define PTRFLAGS_HWHEEL 0x0400
|
||||
@ -445,10 +506,9 @@
|
||||
#define PTRXFLAGS_BUTTON2 0x0002
|
||||
|
||||
/* Synchronize Event: toggleFlags (2.2.8.1.1.3.1.1.5) */
|
||||
/* TODO: to be renamed */
|
||||
#define KBD_FLAG_SCROLL 0x0001 /* TS_SYNC_SCROLL_LOCK */
|
||||
#define KBD_FLAG_NUMLOCK 0x0002
|
||||
#define KBD_FLAG_CAPITAL 0x0004
|
||||
#define TS_SYNC_SCROLL_LOCK 0x0001
|
||||
#define TS_SYNC_NUM_LOCK 0x0002
|
||||
#define TS_SYNC_CAPS_LOCK 0x0004
|
||||
#define TS_SYNC_KANA_LOCK 0x0008
|
||||
|
||||
/* Client Fast-Path Input Event PDU 2.2.8.1.2 */
|
||||
@ -534,4 +594,8 @@
|
||||
#define RDP_MPPC_FLUSH 0x80
|
||||
#define RDP_MPPC_DICT_SIZE 8192 /* RDP 4.0 | MS-RDPBCGR 3.1.8 */
|
||||
|
||||
/* largePointerSupprtFlags (2.2.7.2.7) */
|
||||
#define LARGE_POINTER_FLAG_96x96 0x00000001
|
||||
#define LARGE_POINTER_FLAG_384x384 0x00000002
|
||||
|
||||
#endif /* MS_RDPBCGR_H */
|
||||
|
90
common/ms-rdpeclip.h
Normal file
90
common/ms-rdpeclip.h
Normal file
@ -0,0 +1,90 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* MS-RDPECLIP : Definitions from [MS-RDPECLIP]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* References to MS-RDPECLIP are currently correct for v220210407 of that
|
||||
* document
|
||||
*/
|
||||
|
||||
#if !defined(MS_RDPECLIP_H)
|
||||
#define MS_RDPECLIP_H
|
||||
|
||||
/* Clipboard PDU header message codes 2.2.1 */
|
||||
#define CB_MONITOR_READY 1
|
||||
#define CB_FORMAT_LIST 2
|
||||
#define CB_FORMAT_LIST_RESPONSE 3
|
||||
#define CB_FORMAT_DATA_REQUEST 4
|
||||
#define CB_FORMAT_DATA_RESPONSE 5
|
||||
#define CB_TEMP_DIRECTORY 6
|
||||
#define CB_CLIP_CAPS 7
|
||||
#define CB_FILECONTENTS_REQUEST 8
|
||||
#define CB_FILECONTENTS_RESPONSE 9
|
||||
#define CB_LOCK_CLIPDATA 10
|
||||
#define CB_UNLOCK_CLIPDATA 11
|
||||
|
||||
#define CB_PDUTYPE_TO_STR(pdu_type) \
|
||||
((pdu_type) == CB_MONITOR_READY ? "CB_MONITOR_READY" : \
|
||||
(pdu_type) == CB_FORMAT_LIST ? "CB_FORMAT_LIST" : \
|
||||
(pdu_type) == CB_FORMAT_LIST_RESPONSE ? "CB_FORMAT_LIST_RESPONSE" : \
|
||||
(pdu_type) == CB_FORMAT_DATA_REQUEST ? "CB_FORMAT_DATA_REQUEST" : \
|
||||
(pdu_type) == CB_FORMAT_DATA_RESPONSE ? "CB_FORMAT_DATA_RESPONSE" : \
|
||||
(pdu_type) == CB_TEMP_DIRECTORY ? "CB_TEMP_DIRECTORY" : \
|
||||
(pdu_type) == CB_CLIP_CAPS ? "CB_CLIP_CAPS" : \
|
||||
(pdu_type) == CB_FILECONTENTS_REQUEST ? "CB_FILECONTENTS_REQUEST" : \
|
||||
(pdu_type) == CB_FILECONTENTS_RESPONSE ? "CB_FILECONTENTS_RESPONSE" : \
|
||||
(pdu_type) == CB_LOCK_CLIPDATA ? "CB_LOCK_CLIPDATA" : \
|
||||
(pdu_type) == CB_UNLOCK_CLIPDATA ? "CB_UNLOCK_CLIPDATA" : \
|
||||
"unknown" \
|
||||
)
|
||||
|
||||
/* Clipboard PDU header message flags 2.2.1 */
|
||||
#define CB_RESPONSE_OK 0x0001
|
||||
#define CB_RESPONSE_FAIL 0x0002
|
||||
#define CB_ASCII_NAMES 0x0004
|
||||
|
||||
/* Capability set codes 2.2.2.1.1 */
|
||||
#define CB_CAPSTYPE_GENERAL 1
|
||||
#define CB_CAPS_VERSION_1 1
|
||||
#define CB_CAPS_VERSION_2 2
|
||||
|
||||
/* General capability set general flags 2.2.2.1.1.1 */
|
||||
#define CB_USE_LONG_FORMAT_NAMES 0x00000002
|
||||
#define CB_STREAM_FILECLIP_ENABLED 0x00000004
|
||||
#define CB_FILECLIP_NO_FILE_PATHS 0x00000008
|
||||
#define CB_CAN_LOCK_CLIPDATA 0x00000010
|
||||
|
||||
/* File contents request PDU 2.2.5.3 */
|
||||
/* Note that in the document these do not have a CB_ prefix */
|
||||
#define CB_FILECONTENTS_SIZE 0x00000001
|
||||
#define CB_FILECONTENTS_RANGE 0x00000002
|
||||
|
||||
/* File descriptor structure flags 2.2.5.2.3.1 */
|
||||
/* Note that in the document these do not have a CB_ prefix */
|
||||
#define CB_FD_ATTRIBUTES 0x00000004
|
||||
#define CB_FD_FILESIZE 0x00000040
|
||||
#define CB_FD_WRITESTIME 0x00000020
|
||||
#define CB_FD_PROGRESSUI 0x00004000
|
||||
|
||||
/* File descriptor structure file attributes 2.2.5.2.3.1 */
|
||||
/* Note that in the document these do not have a CB_ prefix */
|
||||
#define CB_FILE_ATTRIBUTE_READONLY 0x00000001
|
||||
#define CB_FILE_ATTRIBUTE_HIDDEN 0x00000002
|
||||
#define CB_FILE_ATTRIBUTE_SYSTEM 0x00000004
|
||||
#define CB_FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
||||
#define CB_FILE_ATTRIBUTE_ARCHIVE 0x00000020
|
||||
#define CB_FILE_ATTRIBUTE_NORMAL 0x00000080
|
||||
|
||||
#endif /* MS_RDPECLIP_H */
|
@ -23,7 +23,22 @@
|
||||
#define MS_RDPEDISP_H
|
||||
|
||||
/* Display Control Messages: Display Virtual Channel Extension (2.2.2) */
|
||||
#define DISPLAYCONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002
|
||||
#define DISPLAYCONTROL_PDU_TYPE_CAPS 0x00000005
|
||||
#define DISPLAYCONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002
|
||||
#define DISPLAYCONTROL_PDU_TYPE_CAPS 0x00000005
|
||||
|
||||
/* Display Control Monitor Layout (2.2.2.2.1) */
|
||||
#define DISPLAYCONTROL_MONITOR_PRIMARY 0x00000001
|
||||
#define CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_MONITOR_WIDTH 0xC8
|
||||
#define CLIENT_MONITOR_DATA_MINIMUM_VIRTUAL_MONITOR_HEIGHT 0xC8
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_MONITOR_WIDTH 0x2000
|
||||
#define CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_MONITOR_HEIGHT 0x2000
|
||||
|
||||
#define ORIENTATION_LANDSCAPE 0
|
||||
#define ORIENTATION_PORTRAIT 90
|
||||
#define ORIENTATION_LANDSCAPE_FLIPPED 180
|
||||
#define ORIENTATION_PORTRAIT_FLIPPED 270
|
||||
|
||||
/* Display Control Monitor Layout (2.2.2.2.1) */
|
||||
#define DISPLAYCONTROL_MONITOR_PRIMARY 0x00000001
|
||||
|
||||
#endif /* MS_RDPEDISP_H */
|
||||
|
@ -119,5 +119,10 @@ enum IRP_MN
|
||||
IRP_MN_NOTIFY_CHANGE_DIRECTORY = 0x00000002
|
||||
};
|
||||
|
||||
/*
|
||||
* General Capability Set (2.2.2.7.1)
|
||||
*/
|
||||
/* extendedPDU fields */
|
||||
#define RDPDR_USER_LOGGEDON_PDU 0x00000004
|
||||
|
||||
#endif /* MS_RDPEFS_H */
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
/* LicensingMessage (MS-RDPELE 2.2.2) */
|
||||
/* TODO: to be renamed */
|
||||
#define LICENCE_TAG_DEMAND 0x01 /* LICNSE_REQUEST */
|
||||
#define LICENCE_TAG_DEMAND 0x01 /* LICENSE_REQUEST */
|
||||
#define LICENCE_TAG_AUTHREQ 0x02 /* PLATFORM_CHALLENGE */
|
||||
#define LICENCE_TAG_ISSUE 0x03 /* NEW_LICENSE */
|
||||
#define LICENCE_TAG_REISSUE 0x04 /* UPGRADE_LICENSE */
|
||||
|
1942
common/os_calls.c
1942
common/os_calls.c
File diff suppressed because it is too large
Load Diff
@ -23,15 +23,21 @@
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
struct exit_status
|
||||
enum proc_exit_reason
|
||||
{
|
||||
/* set to -1 when the process exited via a signal */
|
||||
uint8_t exit_code;
|
||||
|
||||
/* set to 0 when the process exited normally */
|
||||
uint8_t signal_no;
|
||||
E_PXR_STATUS_CODE = 0, ///< 'val' contains exit status
|
||||
E_PXR_SIGNAL, ///< 'val' contains a signal number
|
||||
E_PXR_UNEXPECTED
|
||||
};
|
||||
|
||||
struct proc_exit_status
|
||||
{
|
||||
enum proc_exit_reason reason;
|
||||
int val;
|
||||
};
|
||||
|
||||
struct list;
|
||||
|
||||
#define g_tcp_can_recv g_sck_can_recv
|
||||
#define g_tcp_can_send g_sck_can_send
|
||||
#define g_tcp_recv g_sck_recv
|
||||
@ -47,11 +53,8 @@ struct exit_status
|
||||
#define g_close_wait_obj g_delete_wait_obj
|
||||
|
||||
int g_rm_temp_dir(void);
|
||||
int g_mk_socket_path(const char *app_name);
|
||||
void g_init(const char *app_name);
|
||||
void g_deinit(void);
|
||||
void *g_malloc(int size, int zero);
|
||||
void g_free(void *ptr);
|
||||
void g_printf(const char *format, ...) printflike(1, 2);
|
||||
void g_sprintf(char *dest, const char *format, ...) \
|
||||
printflike(2, 3);
|
||||
@ -60,8 +63,6 @@ printflike(3, 4);
|
||||
void g_writeln(const char *format, ...) printflike(1, 2);
|
||||
void g_write(const char *format, ...) printflike(1, 2);
|
||||
void g_hexdump(const char *p, int len);
|
||||
void g_memset(void *ptr, int val, int size);
|
||||
void g_memcpy(void *d_ptr, const void *s_ptr, int size);
|
||||
int g_getchar(void);
|
||||
int g_tcp_set_no_delay(int sck);
|
||||
int g_tcp_set_keepalive(int sck);
|
||||
@ -71,6 +72,7 @@ int g_sck_get_send_buffer_bytes(int sck, int *bytes);
|
||||
int g_sck_set_recv_buffer_bytes(int sck, int bytes);
|
||||
int g_sck_get_recv_buffer_bytes(int sck, int *bytes);
|
||||
int g_sck_local_socket(void);
|
||||
int g_sck_local_socketpair(int sck[2]);
|
||||
int g_sck_vsock_socket(void);
|
||||
int g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid);
|
||||
void g_sck_close(int sck);
|
||||
@ -83,18 +85,107 @@ int g_sck_vsock_bind(int sck, const char *port);
|
||||
int g_sck_vsock_bind_address(int sck, const char *port, const char *address);
|
||||
int g_tcp_bind_address(int sck, const char *port, const char *address);
|
||||
int g_sck_listen(int sck);
|
||||
int g_tcp_accept(int sck);
|
||||
int g_sck_accept(int sck, char *addr, int addr_bytes,
|
||||
char *port, int port_bytes);
|
||||
int g_sck_recv(int sck, void *ptr, int len, int flags);
|
||||
int g_sck_send(int sck, const void *ptr, int len, int flags);
|
||||
int g_sck_accept(int sck);
|
||||
int g_sck_recv(int sck, void *ptr, unsigned int len, int flags);
|
||||
int g_sck_send(int sck, const void *ptr, unsigned int len, int flags);
|
||||
/**
|
||||
* Receives data and file descriptors on a unix domain socket
|
||||
*
|
||||
* @param sck - Socket to receive data + file descriptors from
|
||||
* @param ptr - Pointer to buffer for incoming data
|
||||
* @param len - Length of data. Must be > 0
|
||||
* @param[out] fds - Array of file descriptors
|
||||
* @param [in] maxfd - Max number of elements in fds
|
||||
* @param[out] fdcount - Actual number of file descriptors received
|
||||
* @return Bytes received, or < 0 for error.
|
||||
*
|
||||
* If the result is > 0 but less than len, the file descriptors have
|
||||
* been received. Get the rest of the data with normal g_sck_recv() calls.
|
||||
*
|
||||
* fdcount may be more that maxfd. This indicates that more file descriptors
|
||||
* were received than there was space for. The excess file descriptors
|
||||
* are closed and discarded.
|
||||
*/
|
||||
int g_sck_recv_fd_set(int sck, void *ptr, unsigned int len,
|
||||
int fds[], unsigned int maxfd,
|
||||
unsigned int *fdcount);
|
||||
/**
|
||||
* Sends data and file descriptors on a unix domain socket
|
||||
*
|
||||
* @param sck - Socket to send data + file descriptors on
|
||||
* @param ptr - Data to send
|
||||
* @param len - Length of data. Must be > 0
|
||||
* @param fds - Array of file descriptors
|
||||
* @param fdcount - Number of file descriptors
|
||||
* @return Bytes sent, or < 0 for error.
|
||||
*
|
||||
* If the result is > 0 but less than len, the file descriptors have
|
||||
* been sent. Send the rest of the data with normal g_sck_send() calls.
|
||||
*/
|
||||
int g_sck_send_fd_set(int sck, const void *ptr, unsigned int len,
|
||||
int fds[], unsigned int fdcount);
|
||||
int g_sck_last_error_would_block(int sck);
|
||||
int g_sck_socket_ok(int sck);
|
||||
/**
|
||||
* Checks socket writeability with an optional wait
|
||||
*
|
||||
* @param sck - Socket to check
|
||||
* @param millis - Maximum milliseconds to wait for writeability to be true
|
||||
*
|
||||
* @note The wait time may not be reached in the event of an incoming signal
|
||||
* so do not use this call to impose a hard timeout */
|
||||
int g_sck_can_send(int sck, int millis);
|
||||
/**
|
||||
* Checks socket readability with an optional wait
|
||||
*
|
||||
* @param sck - Socket to check
|
||||
* @param millis - Maximum milliseconds to wait for readability to be true
|
||||
*
|
||||
* @note The wait time may not be reached in the event of an incoming signal
|
||||
* so do not use this call to impose a hard timeout */
|
||||
int g_sck_can_recv(int sck, int millis);
|
||||
int g_sck_select(int sck1, int sck2);
|
||||
void g_write_ip_address(int rcv_sck, char *ip_address, int bytes);
|
||||
|
||||
/**
|
||||
* Gets the IP address of a connected peer, if it has one
|
||||
* @param sck File descriptor for peer
|
||||
* @param ip buffer to write IP address to
|
||||
* @param bytes Size of ip buffer. Should be at least MAX_IP_ADDRSTRLEN
|
||||
* @param[out] portptr Optional variable to receive the port number
|
||||
* @return Pointer to IP for convenience
|
||||
*
|
||||
* If the peer has no IP address (for example, it is a Unix Domain Socket),
|
||||
* or the specified buffer is too small, the returned string is ""
|
||||
*/
|
||||
const char *
|
||||
g_sck_get_peer_ip_address(int sck,
|
||||
char *ip, unsigned int bytes,
|
||||
unsigned short *port);
|
||||
/**
|
||||
* Gets a description for a connected peer
|
||||
* @param sck File descriptor for peer
|
||||
* @param desc buffer to write description to
|
||||
* @param bytes Size of description buffer. Should be at least
|
||||
* MAX_PEER_DESCSTRLEN
|
||||
* @return Pointer to desc for convenience
|
||||
*
|
||||
* Unlike g_sck_get_peer_ip_address(), this will return a
|
||||
* description of some sort for any socket type.
|
||||
*/
|
||||
const char *
|
||||
g_sck_get_peer_description(int sck,
|
||||
char *desc, unsigned int bytes);
|
||||
/**
|
||||
* Sleep for the specified number of milli-seconds
|
||||
* @param msecs Milli-seconds
|
||||
*
|
||||
* If a signal is processed, it is possible that this call will
|
||||
* sleep for less than the specified number of milli-seconds. This
|
||||
* is platform-specific
|
||||
*/
|
||||
void g_sleep(int msecs);
|
||||
int g_pipe(int fd[2]);
|
||||
|
||||
tintptr g_create_wait_obj(const char *name);
|
||||
tintptr g_create_wait_obj_from_socket(tintptr socket, int write);
|
||||
void g_delete_wait_obj_from_socket(tintptr wait_obj);
|
||||
@ -102,20 +193,63 @@ int g_set_wait_obj(tintptr obj);
|
||||
int g_reset_wait_obj(tintptr obj);
|
||||
int g_is_wait_obj_set(tintptr obj);
|
||||
int g_delete_wait_obj(tintptr obj);
|
||||
/**
|
||||
* Wait for the specified readable and writeable objs
|
||||
*
|
||||
* The wait finishes when at least one of the objects becomes
|
||||
* readable or writeable
|
||||
*
|
||||
* @param read_objs Array of read objects
|
||||
* @param rcount Number of elements in read_objs
|
||||
* @param write_objs Array of write objects
|
||||
* @param rcount Number of elements in write_objs
|
||||
* @param mstimeout Timeout in milliseconds. < 0 means an infinite timeout.
|
||||
*
|
||||
* @return 0 for success. The objects will need to be polled to
|
||||
* find out what is readable or writeable.
|
||||
*
|
||||
* An mstimeout of zero will return immediately, although
|
||||
* error conditions may be checked for.
|
||||
*/
|
||||
int g_obj_wait(tintptr *read_objs, int rcount, tintptr *write_objs,
|
||||
int wcount, int mstimeout);
|
||||
void g_random(char *data, int len);
|
||||
int g_abs(int i);
|
||||
int g_memcmp(const void *s1, const void *s2, int len);
|
||||
int g_file_open(const char *file_name);
|
||||
int g_file_open_rw(const char *file_name);
|
||||
int g_file_open_ex(const char *file_name, int aread, int awrite,
|
||||
int acreate, int atrunc);
|
||||
int g_file_open_ro(const char *file_name);
|
||||
int g_file_close(int fd);
|
||||
/**
|
||||
* Returns 1 if a file is open (i.e. the file descriptor is valid)
|
||||
* @param fd File descriptor
|
||||
* @return 1 for file open, 0 for not open
|
||||
*/
|
||||
int g_file_is_open(int fd);
|
||||
int g_file_read(int fd, char *ptr, int len);
|
||||
int g_file_write(int fd, const char *ptr, int len);
|
||||
int g_file_seek(int fd, int offset);
|
||||
int g_file_lock(int fd, int start, int len);
|
||||
int
|
||||
g_file_map(int fd, int aread, int awrite, size_t length, void **addr);
|
||||
int
|
||||
g_munmap(void *addr, size_t length);
|
||||
int g_file_duplicate_on(int fd, int target_fd);
|
||||
int g_file_get_cloexec(int fd);
|
||||
int g_file_set_cloexec(int fd, int status);
|
||||
/**
|
||||
* Get a list of open file descriptors
|
||||
*
|
||||
* @param min Min FD to consider
|
||||
* @param max Max FD to consider (+1), or -1 for no limit
|
||||
* @result Array of file descriptors, in ascending order.
|
||||
*
|
||||
* Call delete_list() on the result when you've finished with it.
|
||||
*/
|
||||
struct list *g_get_open_fds(int min, int max);
|
||||
int g_chmod_hex(const char *filename, int flags);
|
||||
int g_umask_hex(int flags);
|
||||
int g_chown(const char *name, int uid, int gid);
|
||||
int g_mkdir(const char *dirname);
|
||||
char *g_get_current_dir(char *dirname, int maxlen);
|
||||
@ -123,47 +257,141 @@ int g_set_current_dir(const char *dirname);
|
||||
int g_file_exist(const char *filename);
|
||||
int g_file_readable(const char *filename);
|
||||
int g_directory_exist(const char *dirname);
|
||||
int g_executable_exist(const char *dirname);
|
||||
int g_create_dir(const char *dirname);
|
||||
int g_create_path(const char *path);
|
||||
int g_remove_dir(const char *dirname);
|
||||
int g_file_delete(const char *filename);
|
||||
int g_file_get_size(const char *filename);
|
||||
int g_file_get_device_number(const char *filename);
|
||||
int g_file_get_inode_num(const char *filename);
|
||||
long g_load_library(char *in);
|
||||
int g_free_library(long lib);
|
||||
void *g_get_proc_address(long lib, const char *name);
|
||||
int g_system(char *aexec);
|
||||
int g_system(const char *aexec);
|
||||
char *g_get_strerror(void);
|
||||
int g_get_errno(void);
|
||||
int g_execvp(const char *p1, char *args[]);
|
||||
/**
|
||||
* Issues an execvp() call
|
||||
*
|
||||
* @param file Executable
|
||||
* @param argv Argument list for executable.
|
||||
*
|
||||
* argv does not need to be NULL terminated - the call takes care
|
||||
* of this.
|
||||
*
|
||||
* @return Only if an error has occurred - use g_get_errno() or equivalent
|
||||
*/
|
||||
int g_execvp_list(const char *file, struct list *argv);
|
||||
int g_execlp3(const char *a1, const char *a2, const char *a3);
|
||||
/**
|
||||
* Set an alarm using SIGALRM
|
||||
* @param func Signal handler, or NULL to cancel an alarm
|
||||
* @param secs Number of seconds until an alarm is raised
|
||||
* @return Number of seconds remaining before a previously requested
|
||||
* alarm is raised
|
||||
*/
|
||||
unsigned int g_set_alarm(void (*func)(int), unsigned int secs);
|
||||
/**
|
||||
* Set a handler up for SIGCHLD
|
||||
* @param func signal handler, or NULL to restore the default handler
|
||||
* The handler remains in place until explicitly replaced.
|
||||
*/
|
||||
void g_signal_child_stop(void (*func)(int));
|
||||
/**
|
||||
* Set a handler up for SIGSEGV
|
||||
* @param func signal handler, or NULL to restore the default handler
|
||||
* The handler can only be called once, at which point the
|
||||
* default handler is restored. This is to avoid infinite loops
|
||||
*/
|
||||
void g_signal_segfault(void (*func)(int));
|
||||
/**
|
||||
* Set a handler up for SIGHUP
|
||||
* @param func signal handler, or NULL to restore the default handler
|
||||
* The handler remains in place until explicitly replaced.
|
||||
*/
|
||||
void g_signal_hang_up(void (*func)(int));
|
||||
/**
|
||||
* Set a handler up for SIGINT
|
||||
* @param func signal handler, or NULL to restore the default handler
|
||||
* The handler remains in place until explicitly replaced.
|
||||
*/
|
||||
void g_signal_user_interrupt(void (*func)(int));
|
||||
/**
|
||||
* Set a handler up for SIGTERM
|
||||
* @param func signal handler, or NULL to restore the default handler
|
||||
* The handler remains in place until explicitly replaced.
|
||||
*/
|
||||
void g_signal_terminate(void (*func)(int));
|
||||
/**
|
||||
* Set a handler up for SIGPIPE
|
||||
* @param func signal handler, or NULL to restore the default handler
|
||||
* The handler remains in place until explicitly replaced.
|
||||
*/
|
||||
void g_signal_pipe(void (*func)(int));
|
||||
/**
|
||||
* Set a handler up for SIGUSR1
|
||||
* @param func signal handler, or NULL to restore the default handler
|
||||
* The handler remains in place until explicitly replaced.
|
||||
*/
|
||||
void g_signal_usr1(void (*func)(int));
|
||||
int g_fork(void);
|
||||
int g_setgid(int pid);
|
||||
int g_initgroups(const char *user, int gid);
|
||||
int g_drop_privileges(const char *user, const char *group);
|
||||
int g_initgroups(const char *user);
|
||||
int g_getuid(void);
|
||||
int g_getgid(void);
|
||||
int g_setuid(int pid);
|
||||
int g_setsid(void);
|
||||
int g_getlogin(char *name, unsigned int len);
|
||||
int g_setlogin(const char *name);
|
||||
int g_waitchild(void);
|
||||
#ifdef HAVE_SETUSERCONTEXT
|
||||
/** Sets the login user context (BSD systems only)
|
||||
* @param uid UID of suer
|
||||
* @return 0 for success
|
||||
*/
|
||||
int g_set_allusercontext(int uid);
|
||||
#endif
|
||||
int g_waitchild(struct proc_exit_status *e);
|
||||
int g_waitpid(int pid);
|
||||
struct exit_status g_waitpid_status(int pid);
|
||||
struct proc_exit_status g_waitpid_status(int pid);
|
||||
/*
|
||||
* Sets the process group ID of the indicated process to the specified value.
|
||||
* (POSIX.1)
|
||||
*
|
||||
* Errors are logged.
|
||||
*
|
||||
* May do nothing if process groups are not supported
|
||||
*/
|
||||
int g_setpgid(int pid, int pgid);
|
||||
void g_clearenv(void);
|
||||
int g_setenv(const char *name, const char *value, int rewrite);
|
||||
char *g_getenv(const char *name);
|
||||
int g_exit(int exit_code);
|
||||
int g_getpid(void);
|
||||
int g_sigterm(int pid);
|
||||
int g_getuser_info(const char *username, int *gid, int *uid, char **shell,
|
||||
char **dir, char **gecos);
|
||||
int g_sighup(int pid);
|
||||
/*
|
||||
* Is a particular PID active?
|
||||
* @param pid PID to check
|
||||
* Returns boolean
|
||||
*/
|
||||
int g_pid_is_active(int pid);
|
||||
int g_getuser_info_by_name(const char *username, int *uid, int *gid,
|
||||
char **shell, char **dir, char **gecos);
|
||||
int g_getuser_info_by_uid(int uid, char **username, int *gid,
|
||||
char **shell, char **dir, char **gecos);
|
||||
int g_getgroup_info(const char *groupname, int *gid);
|
||||
/**
|
||||
* Checks whether a user is in the specified group
|
||||
* @param username Name of user
|
||||
* @param gid GID of group
|
||||
* @param[out] ok Whether user is in group
|
||||
* @return Non-zero if a system error occurred. In this instance OK is not set
|
||||
*
|
||||
* Primary group of username is also checked
|
||||
*/
|
||||
int g_check_user_in_group(const char *username, int gid, int *ok);
|
||||
int g_time1(void);
|
||||
int g_time2(void);
|
||||
@ -178,6 +406,10 @@ int g_tcp4_socket(void);
|
||||
int g_tcp4_bind_address(int sck, const char *port, const char *address);
|
||||
int g_tcp6_socket(void);
|
||||
int g_tcp6_bind_address(int sck, const char *port, const char *address);
|
||||
int g_no_new_privs(void);
|
||||
void
|
||||
g_qsort(void *base, size_t nitems, size_t size,
|
||||
int (*compar)(const void *, const void *));
|
||||
|
||||
/* glib-style wrappers */
|
||||
#define g_new(struct_type, n_structs) \
|
||||
@ -185,4 +417,11 @@ int g_tcp6_bind_address(int sck, const char *port, const char *address);
|
||||
#define g_new0(struct_type, n_structs) \
|
||||
(struct_type *) calloc((n_structs), sizeof(struct_type))
|
||||
|
||||
/* remove these when no longer used */
|
||||
#define g_malloc(_size, _zero) (_zero ? calloc(1, _size) : malloc(_size))
|
||||
#define g_free free
|
||||
#define g_memset memset
|
||||
#define g_memcpy memcpy
|
||||
#define g_memmove memmove
|
||||
|
||||
#endif
|
||||
|
324
common/parse.c
Normal file
324
common/parse.c
Normal file
@ -0,0 +1,324 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) 2021 Matt Burt
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Enforce stream primitive checking
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "arch.h"
|
||||
#include "parse.h"
|
||||
#include "log.h"
|
||||
#include "string_calls.h"
|
||||
#include "unicode_defines.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
|
||||
#define out_uint16_le_unchecked(s, v) do \
|
||||
{ \
|
||||
*((s)->p) = (unsigned char)((v) >> 0); \
|
||||
(s)->p++; \
|
||||
*((s)->p) = (unsigned char)((v) >> 8); \
|
||||
(s)->p++; \
|
||||
} while (0)
|
||||
#else
|
||||
#define out_uint16_le_unchecked(s, v) do \
|
||||
{ \
|
||||
*((unsigned short*)((s)->p)) = (unsigned short)(v); \
|
||||
(s)->p += 2; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
|
||||
#define in_uint16_le_unchecked(s, v) do \
|
||||
{ \
|
||||
(v) = (unsigned short) \
|
||||
( \
|
||||
(*((unsigned char*)((s)->p + 0)) << 0) | \
|
||||
(*((unsigned char*)((s)->p + 1)) << 8) \
|
||||
); \
|
||||
(s)->p += 2; \
|
||||
} while (0)
|
||||
#else
|
||||
#define in_uint16_le_unchecked(s, v) do \
|
||||
{ \
|
||||
(v) = *((unsigned short*)((s)->p)); \
|
||||
(s)->p += 2; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
void
|
||||
parser_stream_overflow_check(const struct stream *s, int n, int is_out,
|
||||
const char *file, int line)
|
||||
{
|
||||
/* Sanity checks */
|
||||
if (n < 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ALWAYS, "%s:%d "
|
||||
"stream primitive called with negative n=%d",
|
||||
file, line, n);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (is_out)
|
||||
{
|
||||
/* Output overflow */
|
||||
if (!s_check_rem_out(s, n))
|
||||
{
|
||||
LOG(LOG_LEVEL_ALWAYS, "%s:%d Stream output buffer overflow. "
|
||||
"Size=%d, pos=%d, requested=%d", file, line,
|
||||
s->size, (int)(s->p - s->data), n);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Input overflow */
|
||||
if (!s_check_rem(s, n))
|
||||
{
|
||||
LOG(LOG_LEVEL_ALWAYS, "%s:%d Stream input buffer overflow. "
|
||||
"Max=%d, pos=%d, requested=%d", file, line,
|
||||
(int)(s->end - s->data), (int)(s->p - s->data), n);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void
|
||||
out_utf8_as_utf16_le_proc(struct stream *s, const char *v,
|
||||
unsigned int vn,
|
||||
const char *file, int line)
|
||||
{
|
||||
// Expansion of S_CHECK_REM_OUT(s, <octet_count>) using passed-in
|
||||
// file and line
|
||||
#ifdef USE_DEVEL_STREAMCHECK
|
||||
int octet_cnt = utf8_as_utf16_word_count(v, vn) * 2;
|
||||
parser_stream_overflow_check(s, octet_cnt, 1, file, line);
|
||||
#endif
|
||||
|
||||
while (vn > 0)
|
||||
{
|
||||
char32_t c32 = utf8_get_next_char(&v, &vn);
|
||||
char16_t low;
|
||||
if (c32 < 0x10000)
|
||||
{
|
||||
low = (char16_t)c32;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Need a surrogate pair */
|
||||
low = LOW_SURROGATE_FROM_C32(c32);
|
||||
char16_t high = HIGH_SURROGATE_FROM_C32(c32);
|
||||
out_uint16_le_unchecked(s, high);
|
||||
}
|
||||
out_uint16_le_unchecked(s, low);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* Gets the next Unicode character from a code stream
|
||||
* @param s Stream
|
||||
* @return Unicode character
|
||||
*
|
||||
* Non-characters and illegally coded characters are mapped to
|
||||
* UCS_REPLACEMENT_CHARACTER
|
||||
*
|
||||
* @pre Two bytes are assumed to be available on the stram on entry
|
||||
*/
|
||||
static char32_t
|
||||
get_c32_from_stream(struct stream *s)
|
||||
{
|
||||
char32_t c32 = UCS_REPLACEMENT_CHARACTER; // Assume failure
|
||||
char16_t w;
|
||||
|
||||
in_uint16_le_unchecked(s, w);
|
||||
|
||||
if (IS_HIGH_SURROGATE(w))
|
||||
{
|
||||
if (s_check_rem(s, 2))
|
||||
{
|
||||
char16_t low;
|
||||
in_uint16_le_unchecked(s, low);
|
||||
if (IS_LOW_SURROGATE(low))
|
||||
{
|
||||
/* Valid surrogate pair */
|
||||
char32_t v = C32_FROM_SURROGATE_PAIR(low, w);
|
||||
|
||||
/* Ignore some values which can be successfully encoded
|
||||
* in this way */
|
||||
if (!IS_PLANE_END_NON_CHARACTER(c32))
|
||||
{
|
||||
c32 = v;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Invalid low surrogate - pop character back */
|
||||
s->p -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!IS_LOW_SURROGATE(w) &&
|
||||
!IS_PLANE_END_NON_CHARACTER(w) &&
|
||||
!IS_ARABIC_NON_CHARACTER(w))
|
||||
{
|
||||
/* Character from the Basic Multilingual Plane */
|
||||
c32 = (char32_t)w;
|
||||
}
|
||||
|
||||
return c32;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
unsigned int
|
||||
in_utf16_le_fixed_as_utf8_proc(struct stream *s, unsigned int n,
|
||||
char *v, unsigned int vn,
|
||||
const char *file, int line)
|
||||
{
|
||||
unsigned int rv = 0;
|
||||
char32_t c32;
|
||||
char u8str[MAXLEN_UTF8_CHAR];
|
||||
unsigned int u8len;
|
||||
char *saved_s_end = s->end;
|
||||
|
||||
// Expansion of S_CHECK_REM(s, n*2) using passed-in file and line
|
||||
#ifdef USE_DEVEL_STREAMCHECK
|
||||
parser_stream_overflow_check(s, n * 2, 0, file, line);
|
||||
#endif
|
||||
// Temporarily set the stream end pointer to allow us to use
|
||||
// s_check_rem() when reading in UTF-16 words
|
||||
if (s->end - s->p > (int)(n * 2))
|
||||
{
|
||||
s->end = s->p + (int)(n * 2);
|
||||
}
|
||||
|
||||
while (s_check_rem(s, 2))
|
||||
{
|
||||
c32 = get_c32_from_stream(s);
|
||||
|
||||
u8len = utf_char32_to_utf8(c32, u8str);
|
||||
if (u8len + 1 <= vn)
|
||||
{
|
||||
/* Room for this character and a terminator. Add the character */
|
||||
unsigned int i;
|
||||
for (i = 0 ; i < u8len ; ++i)
|
||||
{
|
||||
v[i] = u8str[i];
|
||||
}
|
||||
vn -= u8len;
|
||||
v += u8len;
|
||||
}
|
||||
else if (vn > 1)
|
||||
{
|
||||
/* We've skipped a character, but there's more than one byte
|
||||
* remaining in the output buffer. Mark the output buffer as
|
||||
* full so we don't get a smaller character being squeezed into
|
||||
* the remaining space */
|
||||
vn = 1;
|
||||
}
|
||||
|
||||
rv += u8len;
|
||||
}
|
||||
|
||||
// Restore stream to full length
|
||||
s->end = saved_s_end;
|
||||
|
||||
if (vn > 0)
|
||||
{
|
||||
*v = '\0';
|
||||
}
|
||||
++rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
unsigned int
|
||||
in_utf16_le_fixed_as_utf8_length(struct stream *s, unsigned int n)
|
||||
{
|
||||
char *saved_s_p = s->p;
|
||||
unsigned int rv = in_utf16_le_fixed_as_utf8(s, n, NULL, 0);
|
||||
s->p = saved_s_p;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
unsigned int
|
||||
in_utf16_le_terminated_as_utf8(struct stream *s,
|
||||
char *v, unsigned int vn)
|
||||
{
|
||||
unsigned int rv = 0;
|
||||
char32_t c32;
|
||||
char u8str[MAXLEN_UTF8_CHAR];
|
||||
unsigned int u8len;
|
||||
while (s_check_rem(s, 2))
|
||||
{
|
||||
c32 = get_c32_from_stream(s);
|
||||
if (c32 == 0)
|
||||
{
|
||||
break; // Terminator encountered
|
||||
}
|
||||
|
||||
u8len = utf_char32_to_utf8(c32, u8str);
|
||||
if (u8len + 1 <= vn)
|
||||
{
|
||||
/* Room for this character and a terminator. Add the character */
|
||||
unsigned int i;
|
||||
for (i = 0 ; i < u8len ; ++i)
|
||||
{
|
||||
v[i] = u8str[i];
|
||||
}
|
||||
vn -= u8len;
|
||||
v += u8len;
|
||||
}
|
||||
else if (vn > 1)
|
||||
{
|
||||
/* We've skipped a character, but there's more than one byte
|
||||
* remaining in the output buffer. Mark the output buffer as
|
||||
* full so we don't get a smaller character being squeezed into
|
||||
* the remaining space */
|
||||
vn = 1;
|
||||
}
|
||||
rv += u8len;
|
||||
}
|
||||
|
||||
if (vn > 0)
|
||||
{
|
||||
*v = '\0';
|
||||
}
|
||||
++rv;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
unsigned int
|
||||
in_utf16_le_terminated_as_utf8_length(struct stream *s)
|
||||
{
|
||||
char *saved_s_p = s->p;
|
||||
unsigned int rv = in_utf16_le_terminated_as_utf8(s, NULL, 0);
|
||||
s->p = saved_s_p;
|
||||
return rv;
|
||||
}
|
186
common/parse.h
186
common/parse.h
@ -28,6 +28,13 @@
|
||||
#include "arch.h"
|
||||
#include "log.h"
|
||||
|
||||
/* Check the config_ac.h file is included so we know whether to enable the
|
||||
* development macros
|
||||
*/
|
||||
#ifndef CONFIG_AC_H
|
||||
# error config_ac.h not visible in parse.h
|
||||
#endif
|
||||
|
||||
#if defined(L_ENDIAN)
|
||||
#elif defined(B_ENDIAN)
|
||||
#else
|
||||
@ -54,8 +61,129 @@ struct stream
|
||||
int *source;
|
||||
};
|
||||
|
||||
/** Check arguments to stream primitives
|
||||
*
|
||||
* This adds a function call overhead to every stream primitive and is
|
||||
* intended for development only
|
||||
*
|
||||
* @param s stream
|
||||
* @param n Bytes being requested for input/output
|
||||
* @param is_out (0=input, !0=output)
|
||||
* @param file __file__for caller
|
||||
* @param line __line__ for caller
|
||||
*
|
||||
* On any kind of violation a message is output and the program is
|
||||
* aborted.
|
||||
*/
|
||||
void
|
||||
parser_stream_overflow_check(const struct stream *s, int n, int is_out,
|
||||
const char *file, int line);
|
||||
|
||||
#ifdef USE_DEVEL_STREAMCHECK
|
||||
# define S_CHECK_REM(s,n) \
|
||||
parser_stream_overflow_check((s), (n), 0, __FILE__, __LINE__)
|
||||
# define S_CHECK_REM_OUT(s,n) \
|
||||
parser_stream_overflow_check((s), (n), 1, __FILE__, __LINE__)
|
||||
#else
|
||||
# define S_CHECK_REM(s,n)
|
||||
# define S_CHECK_REM_OUT(s,n)
|
||||
#endif
|
||||
|
||||
/******************************************************************************/
|
||||
#define s_check(s) s_check_rem(s, 0)
|
||||
/**
|
||||
* Copies a UTF-8 string to a stream as little-endian UTF-16
|
||||
*
|
||||
* @param s Stream
|
||||
* @param v UTF-8 string
|
||||
* @param vn Length of UTF-8 string.
|
||||
* @param file Caller location (from __FILE__)
|
||||
* @param line Caller location (from __LINE__)
|
||||
*
|
||||
* Caller is expected to check there is room for the result in s
|
||||
*/
|
||||
void
|
||||
out_utf8_as_utf16_le_proc(struct stream *s, const char *v,
|
||||
unsigned int vn,
|
||||
const char *file, int line);
|
||||
|
||||
#define out_utf8_as_utf16_le(s,v,vn) \
|
||||
out_utf8_as_utf16_le_proc((s), (v), (vn), __FILE__, __LINE__)
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* Copies a fixed-size little-endian UTF-16 string from a stream as UTF-8
|
||||
*
|
||||
* @param s Stream
|
||||
* @param n Number of 16-bit words to copy
|
||||
* @param v Pointer to result buffer
|
||||
* @param vn Max size of result buffer
|
||||
*
|
||||
* @return number of characters which would be written to v, INCLUDING
|
||||
* an additional terminator. This can be used to check for a buffer
|
||||
* overflow. A terminator is added whether or not the input
|
||||
* includes one.
|
||||
*
|
||||
* Output is unconditionally NULL-terminated.
|
||||
* Input is not checked for NULLs - these are copied verbatim
|
||||
*/
|
||||
unsigned int
|
||||
in_utf16_le_fixed_as_utf8_proc(struct stream *s, unsigned int n,
|
||||
char *v, unsigned int vn,
|
||||
const char *file, int line);
|
||||
|
||||
#define in_utf16_le_fixed_as_utf8(s,n,v,vn) \
|
||||
in_utf16_le_fixed_as_utf8_proc((s), (n), (v), (vn), __FILE__, __LINE__)
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* Returns the size of the buffer needed to store a fixed-size
|
||||
* little-endian UTF-16 string in a stream as a UTF-8 string
|
||||
*
|
||||
* @param s Stream
|
||||
* @param n Number of 16-bit words to consider
|
||||
* @return number of characters needed to store the UTF-8 string. This
|
||||
* includes a terminator, which is written whether the parsed
|
||||
* string includes one or not.
|
||||
* @post Stream position is not moved between start and end of this call
|
||||
*/
|
||||
unsigned int
|
||||
in_utf16_le_fixed_as_utf8_length(struct stream *s, unsigned int n);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* Copies a terminated little-endian UTF-16 string from a stream as UTF-8
|
||||
*
|
||||
* @param s Stream
|
||||
* @param v Pointer to result buffer
|
||||
* @param vn Max size of result buffer
|
||||
*
|
||||
* @return number of characters which would be written to v, INCLUDING
|
||||
* the terminator. This can be used to check for a buffer overflow.
|
||||
*
|
||||
* Output is unconditionally NULL-terminated.
|
||||
* Input processing stops when a NULL is encountered, or the end of the buffer
|
||||
* is reached.
|
||||
*/
|
||||
unsigned int
|
||||
in_utf16_le_terminated_as_utf8(struct stream *s,
|
||||
char *v, unsigned int vn);
|
||||
|
||||
/******************************************************************************/
|
||||
/**
|
||||
* Returns the size of the buffer needed to store a terminated
|
||||
* little-endian UTF-16 string in a stream as a terminated UTF-8 string
|
||||
*
|
||||
* @param s Stream
|
||||
* @return number of characters needed to store the UTF-8 string,
|
||||
* including the terminator
|
||||
* @post Stream position is not moved between start and end of this call
|
||||
*
|
||||
* Input processing stops when a NULL is encountered, or the end of the buffer
|
||||
* is reached.
|
||||
*/
|
||||
unsigned int
|
||||
in_utf16_le_terminated_as_utf8_length(struct stream *s);
|
||||
|
||||
/******************************************************************************/
|
||||
#define s_check_rem(s, n) ((s)->p + (n) <= (s)->end)
|
||||
@ -157,6 +285,7 @@ struct stream
|
||||
|
||||
#define in_sint8(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 1); \
|
||||
(v) = *((signed char*)((s)->p)); \
|
||||
(s)->p++; \
|
||||
} while (0)
|
||||
@ -164,15 +293,21 @@ struct stream
|
||||
/******************************************************************************/
|
||||
#define in_uint8(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 1); \
|
||||
(v) = *((unsigned char*)((s)->p)); \
|
||||
(s)->p++; \
|
||||
} while (0)
|
||||
/******************************************************************************/
|
||||
#define in_uint8_peek(s, v) do { v = *s->p; } while (0)
|
||||
#define in_uint8_peek(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 1); \
|
||||
v = *s->p; \
|
||||
} while (0)
|
||||
/******************************************************************************/
|
||||
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
|
||||
#define in_sint16_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 2); \
|
||||
(v) = (signed short) \
|
||||
( \
|
||||
(*((unsigned char*)((s)->p + 0)) << 0) | \
|
||||
@ -183,6 +318,7 @@ struct stream
|
||||
#else
|
||||
#define in_sint16_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 2); \
|
||||
(v) = *((signed short*)((s)->p)); \
|
||||
(s)->p += 2; \
|
||||
} while (0)
|
||||
@ -192,6 +328,7 @@ struct stream
|
||||
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
|
||||
#define in_uint16_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 2); \
|
||||
(v) = (unsigned short) \
|
||||
( \
|
||||
(*((unsigned char*)((s)->p + 0)) << 0) | \
|
||||
@ -202,6 +339,7 @@ struct stream
|
||||
#else
|
||||
#define in_uint16_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 2); \
|
||||
(v) = *((unsigned short*)((s)->p)); \
|
||||
(s)->p += 2; \
|
||||
} while (0)
|
||||
@ -210,6 +348,7 @@ struct stream
|
||||
/******************************************************************************/
|
||||
#define in_uint16_be(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 2); \
|
||||
(v) = *((unsigned char*)((s)->p)); \
|
||||
(s)->p++; \
|
||||
(v) <<= 8; \
|
||||
@ -221,6 +360,7 @@ struct stream
|
||||
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
|
||||
#define in_uint32_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 4); \
|
||||
(v) = (unsigned int) \
|
||||
( \
|
||||
(*((unsigned char*)((s)->p + 0)) << 0) | \
|
||||
@ -233,6 +373,7 @@ struct stream
|
||||
#else
|
||||
#define in_uint32_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 4); \
|
||||
(v) = *((unsigned int*)((s)->p)); \
|
||||
(s)->p += 4; \
|
||||
} while (0)
|
||||
@ -242,6 +383,7 @@ struct stream
|
||||
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
|
||||
#define in_uint64_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 8); \
|
||||
(v) = (tui64) \
|
||||
( \
|
||||
(((tui64)(*((unsigned char*)((s)->p + 0)))) << 0) | \
|
||||
@ -258,6 +400,7 @@ struct stream
|
||||
#else
|
||||
#define in_uint64_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 8); \
|
||||
(v) = *((tui64*)((s)->p)); \
|
||||
(s)->p += 8; \
|
||||
} while (0)
|
||||
@ -266,6 +409,7 @@ struct stream
|
||||
/******************************************************************************/
|
||||
#define in_uint32_be(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), 4); \
|
||||
(v) = *((unsigned char*)((s)->p)); \
|
||||
(s)->p++; \
|
||||
(v) <<= 8; \
|
||||
@ -282,6 +426,7 @@ struct stream
|
||||
/******************************************************************************/
|
||||
#define out_uint8(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), 1); \
|
||||
*((s)->p) = (unsigned char)(v); \
|
||||
(s)->p++; \
|
||||
} while (0)
|
||||
@ -290,6 +435,7 @@ struct stream
|
||||
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
|
||||
#define out_uint16_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), 2); \
|
||||
*((s)->p) = (unsigned char)((v) >> 0); \
|
||||
(s)->p++; \
|
||||
*((s)->p) = (unsigned char)((v) >> 8); \
|
||||
@ -298,6 +444,7 @@ struct stream
|
||||
#else
|
||||
#define out_uint16_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), 2); \
|
||||
*((unsigned short*)((s)->p)) = (unsigned short)(v); \
|
||||
(s)->p += 2; \
|
||||
} while (0)
|
||||
@ -306,6 +453,7 @@ struct stream
|
||||
/******************************************************************************/
|
||||
#define out_uint16_be(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), 2); \
|
||||
*((s)->p) = (unsigned char)((v) >> 8); \
|
||||
(s)->p++; \
|
||||
*((s)->p) = (unsigned char)((v) >> 0); \
|
||||
@ -316,6 +464,7 @@ struct stream
|
||||
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
|
||||
#define out_uint32_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), 4); \
|
||||
*((s)->p) = (unsigned char)((v) >> 0); \
|
||||
(s)->p++; \
|
||||
*((s)->p) = (unsigned char)((v) >> 8); \
|
||||
@ -328,6 +477,7 @@ struct stream
|
||||
#else
|
||||
#define out_uint32_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), 4); \
|
||||
*((unsigned int*)((s)->p)) = (v); \
|
||||
(s)->p += 4; \
|
||||
} while (0)
|
||||
@ -337,6 +487,7 @@ struct stream
|
||||
#if defined(B_ENDIAN) || defined(NEED_ALIGN)
|
||||
#define out_uint64_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), 8); \
|
||||
*((s)->p) = (unsigned char)((v) >> 0); \
|
||||
(s)->p++; \
|
||||
*((s)->p) = (unsigned char)((v) >> 8); \
|
||||
@ -357,6 +508,7 @@ struct stream
|
||||
#else
|
||||
#define out_uint64_le(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), 8); \
|
||||
*((tui64*)((s)->p)) = (v); \
|
||||
(s)->p += 8; \
|
||||
} while (0)
|
||||
@ -365,6 +517,7 @@ struct stream
|
||||
/******************************************************************************/
|
||||
#define out_uint32_be(s, v) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), 4); \
|
||||
*((s)->p) = (unsigned char)((v) >> 24); \
|
||||
s->p++; \
|
||||
*((s)->p) = (unsigned char)((v) >> 16); \
|
||||
@ -378,6 +531,7 @@ struct stream
|
||||
/******************************************************************************/
|
||||
#define in_uint8p(s, v, n) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), (n)); \
|
||||
(v) = (s)->p; \
|
||||
(s)->p += (n); \
|
||||
} while (0)
|
||||
@ -385,17 +539,22 @@ struct stream
|
||||
/******************************************************************************/
|
||||
#define in_uint8a(s, v, n) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), (n)); \
|
||||
g_memcpy((v), (s)->p, (n)); \
|
||||
(s)->p += (n); \
|
||||
} while (0)
|
||||
|
||||
/******************************************************************************/
|
||||
#define in_uint8s(s, n) \
|
||||
(s)->p += (n)
|
||||
#define in_uint8s(s, n) do \
|
||||
{ \
|
||||
S_CHECK_REM((s), (n)); \
|
||||
(s)->p += (n); \
|
||||
} while (0);
|
||||
|
||||
/******************************************************************************/
|
||||
#define out_uint8p(s, v, n) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), (n)); \
|
||||
g_memcpy((s)->p, (v), (n)); \
|
||||
(s)->p += (n); \
|
||||
} while (0)
|
||||
@ -407,6 +566,7 @@ struct stream
|
||||
/******************************************************************************/
|
||||
#define out_uint8s(s, n) do \
|
||||
{ \
|
||||
S_CHECK_REM_OUT((s), (n)); \
|
||||
g_memset((s)->p, 0, (n)); \
|
||||
(s)->p += (n); \
|
||||
} while (0)
|
||||
@ -431,6 +591,8 @@ struct stream
|
||||
*****************************************************************************/
|
||||
#define xstream_free(_s) free_stream(_s)
|
||||
|
||||
#define xstream_skip_u8(_s, _n) in_uint8s(_s, _n)
|
||||
|
||||
#define xstream_rd_u8(_s, _var) in_uint8(_s, _var)
|
||||
#define xstream_rd_u16_le(_s, _var) in_uint16_le(_s, _var)
|
||||
#define xstream_rd_u32_le(_s, _var) in_uint32_le(_s, _var)
|
||||
@ -451,14 +613,14 @@ struct stream
|
||||
do \
|
||||
{ \
|
||||
_v = \
|
||||
(tui64)(*((unsigned char *)_s->p)) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 1))) << 8) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 2))) << 16) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 3))) << 24) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 4))) << 32) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 5))) << 40) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 6))) << 48) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 7))) << 56); \
|
||||
(tui64)(*((unsigned char *)_s->p)) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 1))) << 8) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 2))) << 16) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 3))) << 24) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 4))) << 32) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 5))) << 40) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 6))) << 48) | \
|
||||
(((tui64) (*(((unsigned char *)_s->p) + 7))) << 56); \
|
||||
_s->p += 8; \
|
||||
} while (0)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@
|
||||
* region, from pixman.h
|
||||
*/
|
||||
|
||||
#if !defined(PIXMAN_PIXMAN_H__)
|
||||
#ifndef PIXMAN_PIXMAN_H__
|
||||
#define PIXMAN_PIXMAN_H__
|
||||
|
||||
typedef int pixman_bool_t;
|
||||
@ -54,23 +54,22 @@ typedef struct pixman_box16 pixman_box16_t;
|
||||
typedef struct pixman_region16 pixman_region16_t;
|
||||
|
||||
/* creation/destruction */
|
||||
void pixman_region_init (pixman_region16_t *region);
|
||||
void pixman_region_init_rect (pixman_region16_t *region,
|
||||
/**/ int x,
|
||||
/**/ int y,
|
||||
/**/ unsigned int width,
|
||||
/**/ unsigned int height);
|
||||
void pixman_region_fini (pixman_region16_t *region);
|
||||
pixman_bool_t pixman_region_union (pixman_region16_t *new_reg,
|
||||
/**/ pixman_region16_t *reg1,
|
||||
/**/ pixman_region16_t *reg2);
|
||||
pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d,
|
||||
/**/ pixman_region16_t *reg_m,
|
||||
/**/ pixman_region16_t *reg_s);
|
||||
pixman_bool_t pixman_region_intersect (pixman_region16_t *new_reg,
|
||||
/**/ pixman_region16_t *reg1,
|
||||
/**/ pixman_region16_t *reg2);
|
||||
pixman_box16_t *pixman_region_rectangles (pixman_region16_t *region,
|
||||
/**/ int *n_rects);
|
||||
void pixman_region_init (pixman_region16_t *region);
|
||||
void pixman_region_init_rect (pixman_region16_t *region, int x, int y,
|
||||
unsigned int width, unsigned int height);
|
||||
void pixman_region_fini (pixman_region16_t *region);
|
||||
pixman_bool_t pixman_region_union (pixman_region16_t *new_reg,
|
||||
pixman_region16_t *reg1,
|
||||
pixman_region16_t *reg2);
|
||||
pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d,
|
||||
pixman_region16_t *reg_m,
|
||||
pixman_region16_t *reg_s);
|
||||
pixman_bool_t pixman_region_intersect (pixman_region16_t *new_reg,
|
||||
pixman_region16_t *reg1,
|
||||
pixman_region16_t *reg2);
|
||||
pixman_box16_t *pixman_region_rectangles (pixman_region16_t *region,
|
||||
int *n_rects);
|
||||
pixman_bool_t pixman_region_not_empty (pixman_region16_t *region);
|
||||
pixman_box16_t *pixman_region_extents (pixman_region16_t *region);
|
||||
|
||||
#endif
|
||||
|
@ -68,7 +68,7 @@ typedef signed int overflow_int_t;
|
||||
|
||||
#define critical_if_fail(expr)
|
||||
|
||||
int _pixman_log_error(const char *func, const char *format, ...)
|
||||
static int _pixman_log_error(const char *func, const char *format, ...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
488
common/scancode.c
Normal file
488
common/scancode.c
Normal file
@ -0,0 +1,488 @@
|
||||
/**
|
||||
* Copyright (C) 2022 Matt Burt, all xrdp contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file common/scancode.c
|
||||
* @brief Scancode handling
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "scancode.h"
|
||||
|
||||
struct scancode_to_keycode
|
||||
{
|
||||
unsigned short scancode; // 0x1xx implies an extended key
|
||||
unsigned char keycode;
|
||||
};
|
||||
|
||||
#define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
// Sources:-
|
||||
// file:/usr/share/X11/xkb/keycodes/evdev
|
||||
// https://wiki.osdev.org/PS/2_Keyboard
|
||||
// https://www.kbdlayout.info/
|
||||
static const struct scancode_to_keycode
|
||||
evdev_scancode_to_keycode_map[] =
|
||||
{
|
||||
// Virtual XKB
|
||||
// Key (US) Symbol
|
||||
// -------- ------
|
||||
{ 0x001, 9 }, // VK_ESCAPE ESC
|
||||
{ 0x002, 10 }, // VK_1 AE01
|
||||
{ 0x003, 11 }, // VK_2 AE02
|
||||
{ 0x004, 12 }, // VK_3 AE03
|
||||
{ 0x005, 13 }, // VK_4 AE04
|
||||
{ 0x006, 14 }, // VK_5 AE05
|
||||
{ 0x007, 15 }, // VK_6 AE06
|
||||
{ 0x008, 16 }, // VK_7 AE07
|
||||
{ 0x009, 17 }, // VK_8 AE08
|
||||
{ 0x00a, 18 }, // VK_9 AE09
|
||||
{ 0x00b, 19 }, // VK_0 AE10
|
||||
{ 0x00c, 20 }, // VK_OEM_MINUS AE11
|
||||
{ 0x00d, 21 }, // VK_OEM_PLUS AE12
|
||||
{ 0x00e, 22 }, // VK_BACK BKSP
|
||||
{ 0x00f, 23 }, // VK_TAB TAB
|
||||
{ 0x010, 24 }, // VK_Q AD01
|
||||
{ 0x011, 25 }, // VK_W AD02
|
||||
{ 0x012, 26 }, // VK_E AD03
|
||||
{ 0x013, 27 }, // VK_R AD04
|
||||
{ 0x014, 28 }, // VK_T AD05
|
||||
{ 0x015, 29 }, // VK_Y AD06
|
||||
{ 0x016, 30 }, // VK_U AD07
|
||||
{ 0x017, 31 }, // VK_I AD08
|
||||
{ 0x018, 32 }, // VK_O AD09
|
||||
{ 0x019, 33 }, // VK_P AD10
|
||||
{ 0x01a, 34 }, // VK_OEM_4 AD11
|
||||
{ 0x01b, 35 }, // VK_OEM_6 AD12
|
||||
{ 0x01c, 36 }, // VK_RETURN RTRN
|
||||
{ 0x01d, 37 }, // VK_LCONTROL LCTL
|
||||
{ 0x01e, 38 }, // VK_A AC01
|
||||
{ 0x01f, 39 }, // VK_S AC02
|
||||
{ 0x020, 40 }, // VK_D AC03
|
||||
{ 0x021, 41 }, // VK_F AC04
|
||||
{ 0x022, 42 }, // VK_G AC05
|
||||
{ 0x023, 43 }, // VK_H AC06
|
||||
{ 0x024, 44 }, // VK_J AC07
|
||||
{ 0x025, 45 }, // VK_K AC08
|
||||
{ 0x026, 46 }, // VK_L AC09
|
||||
{ 0x027, 47 }, // VK_OEM_1 AC10
|
||||
{ 0x028, 48 }, // VK_OEM_7 AC11
|
||||
{ 0x029, 49 }, // VK_OEM_3 TLDE
|
||||
{ 0x02a, 50 }, // VK_LSHIFT LFSH
|
||||
{ 0x02b, 51 }, // VK_OEM_5 BKSL
|
||||
{ 0x02c, 52 }, // VK_Z AB01
|
||||
{ 0x02d, 53 }, // VK_X AB02
|
||||
{ 0x02e, 54 }, // VK_C AB03
|
||||
{ 0x02f, 55 }, // VK_V AB04
|
||||
{ 0x030, 56 }, // VK_B AB05
|
||||
{ 0x031, 57 }, // VK_N AB06
|
||||
{ 0x032, 58 }, // VK_M AB07
|
||||
{ 0x033, 59 }, // VK_OEM_COMMA AB08
|
||||
{ 0x034, 60 }, // VK_OEM_PERIOD AB09
|
||||
{ 0x035, 61 }, // VK_OEM_2 AB10
|
||||
{ 0x036, 62 }, // VK_RSHIFT RTSH
|
||||
{ 0x037, 63 }, // VK_MULTIPLY KPMU
|
||||
{ 0x038, 64 }, // VK_LMENU LALT
|
||||
{ 0x039, 65 }, // VK_SPACE SPCE
|
||||
{ 0x03a, 66 }, // VK_CAPITAL CAPS
|
||||
{ 0x03b, 67 }, // VK_F1 FK01
|
||||
{ 0x03c, 68 }, // VK_F2 FK02
|
||||
{ 0x03d, 69 }, // VK_F3 FK03
|
||||
{ 0x03e, 70 }, // VK_F4 FK04
|
||||
{ 0x03f, 71 }, // VK_F5 FK05
|
||||
{ 0x040, 72 }, // VK_F6 FK06
|
||||
{ 0x041, 73 }, // VK_F7 FK07
|
||||
{ 0x042, 74 }, // VK_F8 FK08
|
||||
{ 0x043, 75 }, // VK_F9 FK09
|
||||
{ 0x044, 76 }, // VK_F10 FK10
|
||||
{ 0x045, 77 }, // VK_NUMLOCK NMLK
|
||||
{ 0x046, 78 }, // VK_SCROLL SCLK
|
||||
{ 0x047, 79 }, // VK_HOME KP7
|
||||
{ 0x048, 80 }, // VK_UP KP8
|
||||
{ 0x049, 81 }, // VK_PRIOR KP9
|
||||
{ 0x04a, 82 }, // VK_SUBTRACT KPSU
|
||||
{ 0x04b, 83 }, // VK_LEFT KP4
|
||||
{ 0x04c, 84 }, // VK_CLEAR KP5
|
||||
{ 0x04d, 85 }, // VK_RIGHT KP6
|
||||
{ 0x04e, 86 }, // VK_ADD KPAD
|
||||
{ 0x04f, 87 }, // VK_END KP1
|
||||
{ 0x050, 88 }, // VK_DOWN KP2
|
||||
{ 0x051, 89 }, // VK_NEXT KP3
|
||||
{ 0x052, 90 }, // VK_INSERT KP0
|
||||
{ 0x053, 91 }, // VK_DELETE KPDL
|
||||
{ 0x056, 94 }, // VK_OEM_102 LSGT
|
||||
{ 0x057, 95 }, // VK_F11 FK11
|
||||
{ 0x058, 96 }, // VK_F12 FK12
|
||||
{ 0x070, 101 }, // - HKTG
|
||||
{ 0x073, 97 }, // VK_ABNT_C1 AB11
|
||||
{ 0x079, 100 }, // - HENK
|
||||
{ 0x07b, 102 }, // VK_OEM_PA1 MUHE
|
||||
{ 0x07d, 132 }, // - AE13
|
||||
{ 0x07e, 129 }, // VK_ABNT_C2 KPPT (Brazil ABNT2)
|
||||
{ 0x110, 173 }, // VK_MEDIA_PREV_TRACK I173 (KEY_PREVIOUSSONG)
|
||||
{ 0x119, 171 }, // VK_MEDIA_NEXT_TRACK I171 (KEY_NEXTSONG)
|
||||
{ 0x11c, 104 }, // VK_RETURN KPEN
|
||||
{ 0x11d, 105 }, // VK_RCONTROL RCTL
|
||||
{ 0x120, 121 }, // VK_VOLUME_MUTE MUTE
|
||||
{ 0x121, 148 }, // VK_LAUNCH_APP2 I148 (KEY_CALC)
|
||||
{ 0x122, 172 }, // VK_PLAY_PAUSE I172 (KEY_PLAYPAUSE)
|
||||
{ 0x124, 174 }, // VK_MEDIA_STOP I174 (KEY_STOPCD)
|
||||
{ 0x12e, 122 }, // VK_VOLUME_DOWN VOL-
|
||||
{ 0x130, 123 }, // VK_VOLUME_UP VOL+
|
||||
{ 0x132, 180 }, // VK_BROWSER_HOME I180 (KEY_HOMEPAGE)
|
||||
{ 0x135, 106 }, // VK_DIVIDE KPDV
|
||||
{ 0x137, 107 }, // VK_SNAPSHOT PRSC
|
||||
{ 0x138, 108 }, // VK_RMENU RALT
|
||||
{ 0x147, 110 }, // VK_HOME HOME
|
||||
{ 0x148, 111 }, // VK_UP UP
|
||||
{ 0x149, 112 }, // VK_PRIOR PGUP (KEY_COMPUTER)
|
||||
{ 0x14b, 113 }, // VK_LEFT LEFT
|
||||
{ 0x14d, 114 }, // VK_RIGHT RGHT
|
||||
{ 0x14f, 115 }, // VK_END END
|
||||
{ 0x150, 116 }, // VK_DOWN DOWN
|
||||
{ 0x151, 117 }, // VK_NEXT PGDN
|
||||
{ 0x152, 118 }, // VK_INSERT INS
|
||||
{ 0x153, 119 }, // VK_DELETE DELE
|
||||
{ 0x15b, 133 }, // VK_LWIN LWIN
|
||||
{ 0x15c, 134 }, // VK_RWIN RWIN
|
||||
{ 0x15d, 135 }, // VK_APPS COMP
|
||||
{ 0x165, 225 }, // VK_BROWSER_SEARCH I225 (KEY_SEARCH)
|
||||
{ 0x166, 164 }, // VK_BROWSER_FAVORITES I164 (KEY_BOOKMARKS)
|
||||
{ 0x16b, 165 }, // VK_LAUNCH_APP1 I165 (KEY_COMPUTER)
|
||||
{ 0x16c, 163 }, // VK_LAUNCH_MAIL I163 (KEY_MAIL)
|
||||
{ 0x21d, 127 } // VK_PAUSE PAUS (KEY_PAUSE)
|
||||
};
|
||||
|
||||
// Sources:-
|
||||
// file:/usr/share/X11/xkb/keycodes/xfree86
|
||||
// https://wiki.osdev.org/PS/2_Keyboard
|
||||
// https://www.kbdlayout.info/
|
||||
static const struct scancode_to_keycode
|
||||
base_scancode_to_keycode_map[] =
|
||||
{
|
||||
// Virtual XKB
|
||||
// Key (US) Symbol
|
||||
// -------- ------
|
||||
{ 0x001, 9 }, // VK_ESCAPE ESC
|
||||
{ 0x002, 10 }, // VK_1 AE01
|
||||
{ 0x003, 11 }, // VK_2 AE02
|
||||
{ 0x004, 12 }, // VK_3 AE03
|
||||
{ 0x005, 13 }, // VK_4 AE04
|
||||
{ 0x006, 14 }, // VK_5 AE05
|
||||
{ 0x007, 15 }, // VK_6 AE06
|
||||
{ 0x008, 16 }, // VK_7 AE07
|
||||
{ 0x009, 17 }, // VK_8 AE08
|
||||
{ 0x00a, 18 }, // VK_9 AE09
|
||||
{ 0x00b, 19 }, // VK_0 AE10
|
||||
{ 0x00c, 20 }, // VK_OEM_MINUS AE11
|
||||
{ 0x00d, 21 }, // VK_OEM_PLUS AE12
|
||||
{ 0x00e, 22 }, // VK_BACK BKSP
|
||||
{ 0x00f, 23 }, // VK_TAB TAB
|
||||
{ 0x010, 24 }, // VK_Q AD01
|
||||
{ 0x011, 25 }, // VK_W AD02
|
||||
{ 0x012, 26 }, // VK_E AD03
|
||||
{ 0x013, 27 }, // VK_R AD04
|
||||
{ 0x014, 28 }, // VK_T AD05
|
||||
{ 0x015, 29 }, // VK_Y AD06
|
||||
{ 0x016, 30 }, // VK_U AD07
|
||||
{ 0x017, 31 }, // VK_I AD08
|
||||
{ 0x018, 32 }, // VK_O AD09
|
||||
{ 0x019, 33 }, // VK_P AD10
|
||||
{ 0x01a, 34 }, // VK_OEM_4 AD11
|
||||
{ 0x01b, 35 }, // VK_OEM_6 AD12
|
||||
{ 0x01c, 36 }, // VK_RETURN RTRN
|
||||
{ 0x01d, 37 }, // VK_LCONTROL LCTL
|
||||
{ 0x01e, 38 }, // VK_A AC01
|
||||
{ 0x01f, 39 }, // VK_S AC02
|
||||
{ 0x020, 40 }, // VK_D AC03
|
||||
{ 0x021, 41 }, // VK_F AC04
|
||||
{ 0x022, 42 }, // VK_G AC05
|
||||
{ 0x023, 43 }, // VK_H AC06
|
||||
{ 0x024, 44 }, // VK_J AC07
|
||||
{ 0x025, 45 }, // VK_K AC08
|
||||
{ 0x026, 46 }, // VK_L AC09
|
||||
{ 0x027, 47 }, // VK_OEM_1 AC10
|
||||
{ 0x028, 48 }, // VK_OEM_7 AC11
|
||||
{ 0x029, 49 }, // VK_OEM_3 TLDE
|
||||
{ 0x02a, 50 }, // VK_LSHIFT LFSH
|
||||
{ 0x02b, 51 }, // VK_OEM_5 BKSL
|
||||
{ 0x02c, 52 }, // VK_Z AB01
|
||||
{ 0x02d, 53 }, // VK_X AB02
|
||||
{ 0x02e, 54 }, // VK_C AB03
|
||||
{ 0x02f, 55 }, // VK_V AB04
|
||||
{ 0x030, 56 }, // VK_B AB05
|
||||
{ 0x031, 57 }, // VK_N AB06
|
||||
{ 0x032, 58 }, // VK_M AB07
|
||||
{ 0x033, 59 }, // VK_OEM_COMMA AB08
|
||||
{ 0x034, 60 }, // VK_OEM_PERIOD AB09
|
||||
{ 0x035, 61 }, // VK_OEM_2 AB10
|
||||
{ 0x036, 62 }, // VK_RSHIFT RTSH
|
||||
{ 0x037, 63 }, // VK_MULTIPLY KPMU
|
||||
{ 0x038, 64 }, // VK_LMENU LALT
|
||||
{ 0x039, 65 }, // VK_SPACE SPCE
|
||||
{ 0x03a, 66 }, // VK_CAPITAL CAPS
|
||||
{ 0x03b, 67 }, // VK_F1 FK01
|
||||
{ 0x03c, 68 }, // VK_F2 FK02
|
||||
{ 0x03d, 69 }, // VK_F3 FK03
|
||||
{ 0x03e, 70 }, // VK_F4 FK04
|
||||
{ 0x03f, 71 }, // VK_F5 FK05
|
||||
{ 0x040, 72 }, // VK_F6 FK06
|
||||
{ 0x041, 73 }, // VK_F7 FK07
|
||||
{ 0x042, 74 }, // VK_F8 FK08
|
||||
{ 0x043, 75 }, // VK_F9 FK09
|
||||
{ 0x044, 76 }, // VK_F10 FK10
|
||||
{ 0x045, 77 }, // VK_NUMLOCK NMLK
|
||||
{ 0x046, 78 }, // VK_SCROLL SCLK
|
||||
{ 0x047, 79 }, // VK_HOME KP7
|
||||
{ 0x048, 80 }, // VK_UP KP8
|
||||
{ 0x049, 81 }, // VK_PRIOR KP9
|
||||
{ 0x04a, 82 }, // VK_SUBTRACT KPSU
|
||||
{ 0x04b, 83 }, // VK_LEFT KP4
|
||||
{ 0x04c, 84 }, // VK_CLEAR KP5
|
||||
{ 0x04d, 85 }, // VK_RIGHT KP6
|
||||
{ 0x04e, 86 }, // VK_ADD KPAD
|
||||
{ 0x04f, 87 }, // VK_END KP1
|
||||
{ 0x050, 88 }, // VK_DOWN KP2
|
||||
{ 0x051, 89 }, // VK_NEXT KP3
|
||||
{ 0x052, 90 }, // VK_INSERT KP0
|
||||
{ 0x053, 91 }, // VK_DELETE KPDL
|
||||
{ 0x056, 94 }, // VK_OEM_102 LSGT
|
||||
{ 0x057, 95 }, // VK_F11 FK11
|
||||
{ 0x058, 96 }, // VK_F12 FK12
|
||||
{ 0x070, 208 }, // - HKTG
|
||||
{ 0x073, 211 }, // VK_ABNT_C1 AB11
|
||||
{ 0x079, 129 }, // - XFER
|
||||
{ 0x07b, 131 }, // VK_OEM_PA1 NFER
|
||||
{ 0x07d, 133 }, // - AE13
|
||||
{ 0x07e, 134 }, // VK_ABNT_C2 KPPT (Brazil ABNT2)
|
||||
{ 0x11c, 108 }, // VK_RETURN KPEN
|
||||
{ 0x11d, 109 }, // VK_RCONTROL RCTL
|
||||
{ 0x120, 141 }, // VK_VOLUME_MUTE MUTE
|
||||
{ 0x12e, 142 }, // VK_VOLUME_DOWN VOL-
|
||||
{ 0x130, 143 }, // VK_VOLUME_UP VOL+
|
||||
{ 0x135, 112 }, // VK_DIVIDE KPDV
|
||||
{ 0x137, 121 }, // VK_SNAPSHOT PRSC
|
||||
{ 0x138, 113 }, // VK_RMENU RALT
|
||||
{ 0x147, 97 }, // VK_HOME HOME
|
||||
{ 0x148, 98 }, // VK_UP UP
|
||||
{ 0x149, 99 }, // VK_PRIOR PGUP (KEY_COMPUTER)
|
||||
{ 0x14b, 100 }, // VK_LEFT LEFT
|
||||
{ 0x14d, 102 }, // VK_RIGHT RGHT
|
||||
{ 0x14f, 103 }, // VK_END END
|
||||
{ 0x150, 104 }, // VK_DOWN DOWN
|
||||
{ 0x151, 105 }, // VK_NEXT PGDN
|
||||
{ 0x152, 106 }, // VK_INSERT INS
|
||||
{ 0x153, 107 }, // VK_DELETE DELE
|
||||
{ 0x15b, 115 }, // VK_LWIN LWIN
|
||||
{ 0x15c, 116 }, // VK_RWIN RWIN
|
||||
{ 0x15d, 117 }, // VK_APPS COMP
|
||||
{ 0x21d, 110 } // VK_PAUSE PAUS (KEY_PAUSE)
|
||||
};
|
||||
|
||||
struct map_settings
|
||||
{
|
||||
const struct scancode_to_keycode *map;
|
||||
const char *name;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
enum settings_index
|
||||
{
|
||||
SI_EVDEV = 0,
|
||||
SI_BASE
|
||||
};
|
||||
|
||||
const struct map_settings global_settings[] =
|
||||
{
|
||||
{
|
||||
// SI_EVDEV
|
||||
.map = evdev_scancode_to_keycode_map,
|
||||
.name = "evdev",
|
||||
.size = ELEMENTS(evdev_scancode_to_keycode_map),
|
||||
},
|
||||
{
|
||||
// SI_BASE
|
||||
.map = base_scancode_to_keycode_map,
|
||||
.name = "base",
|
||||
.size = ELEMENTS(base_scancode_to_keycode_map)
|
||||
}
|
||||
};
|
||||
|
||||
// Default mapping set is "evdev"
|
||||
const struct map_settings *settings = &global_settings[SI_EVDEV];
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
scancode_to_index(unsigned short scancode)
|
||||
{
|
||||
if (scancode <= 0x7f)
|
||||
{
|
||||
return scancode;
|
||||
}
|
||||
if (scancode <= 0xff)
|
||||
{
|
||||
// 0x80 - 0xff : Invalid code
|
||||
return -1;
|
||||
}
|
||||
if (scancode <= 0x177)
|
||||
{
|
||||
// 01x100 - 0x177 : Move bit 9 to bit 8
|
||||
return (scancode & 0x7f) | 0x80;
|
||||
}
|
||||
|
||||
if (scancode == SCANCODE_PAUSE_KEY)
|
||||
{
|
||||
return SCANCODE_INDEX_PAUSE_KEY;
|
||||
}
|
||||
|
||||
// This leaves the following which are all rejected
|
||||
// 0x178 - 0x17f (currently unused). These would map to indexes 0xf8
|
||||
// to 0xff which we are reserving for extended1 keys.
|
||||
// 0x180 - 0x1ff Illegal format
|
||||
// >0x200 Anything not mentioned explicitly above (e.g.
|
||||
// SCANCODE_PAUSE_KEY)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
unsigned short
|
||||
scancode_from_index(int index)
|
||||
{
|
||||
index &= 0xff;
|
||||
unsigned short result;
|
||||
if (index == SCANCODE_INDEX_PAUSE_KEY)
|
||||
{
|
||||
result = SCANCODE_PAUSE_KEY;
|
||||
}
|
||||
else if (index < 0x80)
|
||||
{
|
||||
result = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (index & 0x7f) | 0x100;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
unsigned short
|
||||
scancode_to_x11_keycode(unsigned short scancode)
|
||||
{
|
||||
unsigned int min = 0;
|
||||
unsigned int max = settings->size;
|
||||
unsigned short rv = 0;
|
||||
|
||||
// Check scancode is in range of map
|
||||
if (scancode >= settings->map[min].scancode &&
|
||||
scancode <= settings->map[max - 1].scancode)
|
||||
{
|
||||
// Use a binary chop to locate the correct index
|
||||
// in logarithmic time.
|
||||
while (1)
|
||||
{
|
||||
unsigned int index = (min + max) / 2;
|
||||
if (scancode == settings->map[index].scancode)
|
||||
{
|
||||
rv = settings->map[index].keycode;
|
||||
break;
|
||||
}
|
||||
// Adjust min or max, checking for end
|
||||
// of iteration
|
||||
if (scancode < settings->map[index].scancode)
|
||||
{
|
||||
max = index;
|
||||
}
|
||||
else if (min == index)
|
||||
{
|
||||
// We've already checked this value
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
min = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
unsigned short
|
||||
scancode_get_next(unsigned int *iter)
|
||||
{
|
||||
unsigned short rv = 0;
|
||||
if (*iter < settings->size)
|
||||
{
|
||||
rv = settings->map[*iter].scancode;
|
||||
++(*iter);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
scancode_set_keycode_set(const char *kk_set)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (kk_set == NULL)
|
||||
{
|
||||
rv = 1;
|
||||
}
|
||||
else if (strncmp(kk_set, "evdev", 5) == 0)
|
||||
{
|
||||
settings = &global_settings[SI_EVDEV];
|
||||
}
|
||||
else if (strncmp(kk_set, "base", 4) == 0)
|
||||
{
|
||||
settings = &global_settings[SI_BASE];
|
||||
}
|
||||
else if (strncmp(kk_set, "xfree86", 7) == 0)
|
||||
{
|
||||
settings = &global_settings[SI_BASE];
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = 1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
const char *
|
||||
scancode_get_keycode_set(void)
|
||||
{
|
||||
return settings->name;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
const char *
|
||||
scancode_get_xkb_rules(void)
|
||||
{
|
||||
// Currently supported keycods map directly to the same name for
|
||||
// the rules which use them.
|
||||
return settings->name;
|
||||
}
|
169
common/scancode.h
Normal file
169
common/scancode.h
Normal file
@ -0,0 +1,169 @@
|
||||
/**
|
||||
* Copyright (C) 2024 Matt Burt, all xrdp contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file common/scancode.h
|
||||
* @brief Scancode handling
|
||||
*
|
||||
* This module provides functionality for the following:-
|
||||
* 1) Mapping from TS_KEYBOARD_EVENT PDU values to an 'RDP scancode'
|
||||
* 2) Handling RDP scancodes
|
||||
* 3) Convert between RDP scancodes and X11 keycodes.
|
||||
*
|
||||
* The values received in TS_KEYBOARD_EVENT PDUs are largely the same as
|
||||
* Windows scancodes. These are indirectly documented in the Microsoft
|
||||
* "Keyboard Scan Code Specification", Rev 1.3a (March 16th 2000) and
|
||||
* are otherwise known as "Scan code set 1" scancodes. This document no
|
||||
* longer appears to be available directly from the Microsoft website.
|
||||
*
|
||||
* A TS_KEYBOARD_EVENT_PDU contains two important values:-
|
||||
* 1) key_code This is not unique. For example, left-shift and
|
||||
* right-shift share a key_code of 0x2a
|
||||
* 2) keyboard_flags Among other flags, contains KBDFLAGS_EXTENDED and
|
||||
* KBDFLAGS_EXTENDED1. These combine with the key_code
|
||||
* to allow a specific key to be determined.
|
||||
*
|
||||
* An 'RDP scancode' as defined by this module is a mapping of the
|
||||
* Windows key_code and keyboard_flags into a single value which
|
||||
* represents a unique key. For example:-
|
||||
* Left control : key_code=0x1d, KBDFLAGS_EXTENDED=0 scancode = 0x1d
|
||||
* Right control : key_code=0x1d, KBDFLAGS_EXTENDED=1 scancode = 0x11d
|
||||
*
|
||||
* This model of unique keys more closely maps what X11 does with its
|
||||
* own keycodes.
|
||||
*
|
||||
* X11 keycodes are the X11 equivalent of RDP scancodes. In general, these
|
||||
* are specific to an X server. In practice however, these are nowadays
|
||||
* handled by the XKB extension and only two sets are in common use:-
|
||||
* - evdev : Linux, FreeBSD and possibly others
|
||||
* - base : Everything else.
|
||||
*
|
||||
* This module presents a single source of truth for conversions between
|
||||
* RDP scancodes and X11 keycodes.
|
||||
*/
|
||||
|
||||
#if !defined(SCANCODE_H)
|
||||
#define SCANCODE_H
|
||||
|
||||
#include "xrdp_scancode_defs.h"
|
||||
|
||||
enum
|
||||
{
|
||||
/**
|
||||
* Scancodes for keys used in the code are defined in the global
|
||||
* file xrdp_scancode_defs.h
|
||||
*/
|
||||
|
||||
/**
|
||||
* Scancode indexes for some of the keys in xrdp_scancode_defs.h
|
||||
*/
|
||||
SCANCODE_INDEX_LSHIFT_KEY = SCANCODE_LSHIFT_KEY,
|
||||
SCANCODE_INDEX_RSHIFT_KEY = SCANCODE_RSHIFT_KEY,
|
||||
SCANCODE_INDEX_RALT_KEY = (SCANCODE_RALT_KEY & 0x7f) | 0x80,
|
||||
SCANCODE_INDEX_PAUSE_KEY = 0xf8,
|
||||
// 0xf9 - 0xff reserved for future extended1 mappings
|
||||
|
||||
/**
|
||||
* Maximum value returned by scancode_to_index()
|
||||
*/
|
||||
SCANCODE_MAX_INDEX = 255
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert a scancode to an index
|
||||
* @param scancode scancode in the range 0x00 - 0x2ff
|
||||
* @return index in the range 0..SCANCODE_MAX_INDEX (inclusive) or -1
|
||||
*
|
||||
* This function converts a 10-bit scancode into an 8-bit array index,
|
||||
* independent of the currently loaded keymap
|
||||
*
|
||||
* This is possible as the scancodes from 0x80 - 0x2ff are sparsely allocated.
|
||||
*
|
||||
* For scancodes in the range 0x00 - 0x7f, the index is identical to the
|
||||
* scancode. This includes scancodes for all the keys affected by
|
||||
* numlock.
|
||||
*/
|
||||
int
|
||||
scancode_to_index(unsigned short scancode);
|
||||
|
||||
/**
|
||||
* Convert an index back to a scancode.
|
||||
* @param index in the range 0..SCANCODE_MAX_INDEX
|
||||
*
|
||||
* @result scancode which is mapped to the index value
|
||||
*
|
||||
* The result is always a valid scancode, even if the index is
|
||||
* not valid.
|
||||
*/
|
||||
unsigned short
|
||||
scancode_from_index(int index);
|
||||
|
||||
/**
|
||||
* Looks up an RDP scancode and converts to an x11 keycode
|
||||
*
|
||||
* @param scancode Scancode. Extended scancodes have bit 9 set
|
||||
* (i.e. are in 0x100 - 0x1ff). Extended1 scancodes
|
||||
* (currently just the pause key) are in the range 0x200-0x2ff
|
||||
* @return keycode, or 0 for no keycode
|
||||
*/
|
||||
unsigned short
|
||||
scancode_to_x11_keycode(unsigned short scancode);
|
||||
|
||||
/**
|
||||
* Gets the next valid scancode from the list of valid scancodes
|
||||
* @param iter Value (initialised to zero), used to iterate
|
||||
* over available scancodes.
|
||||
* @return Next valid scancode, or zero.
|
||||
*
|
||||
* The iterator is updated on a successful call. Use like this:-
|
||||
*
|
||||
* iter = 0;
|
||||
* while ((scancode = scancode_get_next(&iter)) != 0)
|
||||
* {
|
||||
* . . .
|
||||
* }
|
||||
*/
|
||||
unsigned short
|
||||
scancode_get_next(unsigned int *iter);
|
||||
|
||||
/**
|
||||
* Sets the keycode set used for the scancode translation
|
||||
*
|
||||
* @param kk_set "evdev", "base", or something more
|
||||
* complex (e.g. "evdev+aliases(qwerty)")
|
||||
* @result 0 for success
|
||||
*/
|
||||
int
|
||||
scancode_set_keycode_set(const char *kk_set);
|
||||
|
||||
/**
|
||||
* Gets the keycode set used for the scancode translation
|
||||
*
|
||||
* @result "evdev", or "base"
|
||||
*/
|
||||
const char *
|
||||
scancode_get_keycode_set(void);
|
||||
|
||||
/**
|
||||
* Gets the XKB rules set which can be used to access the currently
|
||||
* loaded keycode set
|
||||
*
|
||||
* @result "evdev", or "base"
|
||||
*/
|
||||
const char *
|
||||
scancode_get_xkb_rules(void);
|
||||
|
||||
#endif /* SCANCODE_H */
|
@ -44,6 +44,27 @@
|
||||
|
||||
#define SSL_WANT_READ_WRITE_TIMEOUT 100
|
||||
|
||||
/*
|
||||
* Globals used by openssl 3 and later */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
static EVP_MD *g_md_md5; /* MD5 message digest */
|
||||
static EVP_MD *g_md_sha1; /* SHA1 message digest */
|
||||
static EVP_CIPHER *g_cipher_des_ede3_cbc; /* DES3 CBC cipher */
|
||||
static EVP_MAC *g_mac_hmac; /* HMAC MAC */
|
||||
#endif
|
||||
|
||||
/* definition of ssl_tls */
|
||||
struct ssl_tls
|
||||
{
|
||||
SSL *ssl; /* SSL * */
|
||||
SSL_CTX *ctx; /* SSL_CTX * */
|
||||
char *cert;
|
||||
char *key;
|
||||
struct trans *trans;
|
||||
tintptr rwo; /* wait obj */
|
||||
int error_logged; /* Error has already been logged */
|
||||
};
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
static inline HMAC_CTX *
|
||||
HMAC_CTX_new(void)
|
||||
@ -106,12 +127,41 @@ DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
static void
|
||||
dump_error_stack(const char *prefix)
|
||||
{
|
||||
/* Dump the error stack from the SSL library */
|
||||
unsigned long code;
|
||||
char buff[256];
|
||||
while ((code = ERR_get_error()) != 0L)
|
||||
{
|
||||
ERR_error_string_n(code, buff, sizeof(buff));
|
||||
LOG(LOG_LEVEL_ERROR, "%s: %s", prefix, buff);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* As above, but used for TLS connection errors where only the first
|
||||
error is logged */
|
||||
static void
|
||||
dump_ssl_error_stack(struct ssl_tls *self)
|
||||
{
|
||||
if (!self->error_logged)
|
||||
{
|
||||
dump_error_stack("SSL");
|
||||
self->error_logged = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
ssl_init(void)
|
||||
{
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -119,16 +169,44 @@ ssl_init(void)
|
||||
int
|
||||
ssl_finish(void)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
/* De-allocate any allocated globals
|
||||
* For OpenSSL 3, these can all safely be passed a NULL pointer */
|
||||
EVP_MD_free(g_md_md5);
|
||||
EVP_MD_free(g_md_sha1);
|
||||
EVP_CIPHER_free(g_cipher_des_ede3_cbc);
|
||||
EVP_MAC_free(g_mac_hmac);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* rc4 stuff */
|
||||
/* rc4 stuff
|
||||
*
|
||||
* For OpenSSL 3.0, the rc4 encryption algorithm is only provided by the
|
||||
* legacy provider (see crypto(7)). Since RC4 is so simple, we can implement
|
||||
* it directly rather than having to load the legacy provider. This will
|
||||
* avoids problems if running on a system where openssl has been built
|
||||
* without the legacy provider */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
struct rc4_data
|
||||
{
|
||||
/* See https://en.wikipedia.org/wiki/RC4 */
|
||||
unsigned char S[256];
|
||||
int i;
|
||||
int j;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
void *
|
||||
ssl_rc4_info_create(void)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
return g_malloc(sizeof(RC4_KEY), 1);
|
||||
#else
|
||||
return g_malloc(sizeof(struct rc4_data), 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -140,16 +218,77 @@ ssl_rc4_info_delete(void *rc4_info)
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_rc4_set_key(void *rc4_info, char *key, int len)
|
||||
ssl_rc4_set_key(void *rc4_info, const char *key, int len)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
RC4_set_key((RC4_KEY *)rc4_info, len, (tui8 *)key);
|
||||
#else
|
||||
unsigned char *S = ((struct rc4_data *)rc4_info)->S;
|
||||
int i;
|
||||
int j = 0;
|
||||
unsigned char t;
|
||||
for (i = 0 ; i < 256; ++i)
|
||||
{
|
||||
S[i] = i;
|
||||
}
|
||||
for (i = 0 ; i < 256; ++i)
|
||||
{
|
||||
j = (j + S[i] + key[i % len]) & 0xff;
|
||||
t = S[i];
|
||||
S[i] = S[j];
|
||||
S[j] = t;
|
||||
}
|
||||
((struct rc4_data *)rc4_info)->i = 0;
|
||||
((struct rc4_data *)rc4_info)->j = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_rc4_crypt(void *rc4_info, char *data, int len)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
RC4((RC4_KEY *)rc4_info, len, (tui8 *)data, (tui8 *)data);
|
||||
#else
|
||||
unsigned char *S = ((struct rc4_data *)rc4_info)->S;
|
||||
int i = ((struct rc4_data *)rc4_info)->i;
|
||||
int j = ((struct rc4_data *)rc4_info)->j;
|
||||
unsigned char *p = (unsigned char *)data;
|
||||
unsigned char t;
|
||||
unsigned char k;
|
||||
|
||||
/*
|
||||
* Do some loop-unrolling for performance. Here are the steps
|
||||
* for each byte */
|
||||
#define RC4_ROUND \
|
||||
i = (i + 1) & 0xff; \
|
||||
j = (j + S[i]) & 0xff; \
|
||||
t = S[i]; \
|
||||
S[i] = S[j]; \
|
||||
S[j] = t; \
|
||||
k = S[(S[i] + S[j]) & 0xff]; \
|
||||
*p++ ^= k
|
||||
|
||||
while (len >= 8)
|
||||
{
|
||||
RC4_ROUND;
|
||||
RC4_ROUND;
|
||||
RC4_ROUND;
|
||||
RC4_ROUND;
|
||||
RC4_ROUND;
|
||||
RC4_ROUND;
|
||||
RC4_ROUND;
|
||||
RC4_ROUND;
|
||||
len -= 8;
|
||||
}
|
||||
while (len-- > 0)
|
||||
{
|
||||
RC4_ROUND;
|
||||
}
|
||||
|
||||
((struct rc4_data *)rc4_info)->i = i;
|
||||
((struct rc4_data *)rc4_info)->j = j;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* sha1 stuff */
|
||||
@ -158,35 +297,78 @@ ssl_rc4_crypt(void *rc4_info, char *data, int len)
|
||||
void *
|
||||
ssl_sha1_info_create(void)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
return g_malloc(sizeof(SHA_CTX), 1);
|
||||
#else
|
||||
/*
|
||||
* If we can't get the digest loaded, there's a problem with the
|
||||
* library providers, so there's no point in us returning anything useful.
|
||||
* If we do load the digest, it's used later */
|
||||
if (g_md_sha1 == NULL)
|
||||
{
|
||||
if ((g_md_sha1 = EVP_MD_fetch(NULL, "sha1", NULL)) == NULL)
|
||||
{
|
||||
dump_error_stack("sha1");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (void *)EVP_MD_CTX_new();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_sha1_info_delete(void *sha1_info)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
g_free(sha1_info);
|
||||
#else
|
||||
EVP_MD_CTX_free((EVP_MD_CTX *)sha1_info);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_sha1_clear(void *sha1_info)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
SHA1_Init((SHA_CTX *)sha1_info);
|
||||
#else
|
||||
if (sha1_info != NULL)
|
||||
{
|
||||
EVP_DigestInit_ex((EVP_MD_CTX *)sha1_info, g_md_sha1, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_sha1_transform(void *sha1_info, const char *data, int len)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
SHA1_Update((SHA_CTX *)sha1_info, data, len);
|
||||
#else
|
||||
if (sha1_info != NULL)
|
||||
{
|
||||
EVP_DigestUpdate((EVP_MD_CTX *)sha1_info, data, len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_sha1_complete(void *sha1_info, char *data)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
SHA1_Final((tui8 *)data, (SHA_CTX *)sha1_info);
|
||||
#else
|
||||
if (sha1_info != NULL)
|
||||
{
|
||||
EVP_DigestFinal_ex((EVP_MD_CTX *)sha1_info, (unsigned char *)data,
|
||||
NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* md5 stuff */
|
||||
@ -195,35 +377,77 @@ ssl_sha1_complete(void *sha1_info, char *data)
|
||||
void *
|
||||
ssl_md5_info_create(void)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
return g_malloc(sizeof(MD5_CTX), 1);
|
||||
#else
|
||||
/*
|
||||
* If we can't get the digest loaded, there's a problem with the
|
||||
* library providers, so there's no point in us returning anything useful.
|
||||
* If we do load the digest, it's used later */
|
||||
if (g_md_md5 == NULL)
|
||||
{
|
||||
if ((g_md_md5 = EVP_MD_fetch(NULL, "md5", NULL)) == NULL)
|
||||
{
|
||||
dump_error_stack("md5");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (void *)EVP_MD_CTX_new();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_md5_info_delete(void *md5_info)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
g_free(md5_info);
|
||||
#else
|
||||
EVP_MD_CTX_free((EVP_MD_CTX *)md5_info);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_md5_clear(void *md5_info)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
MD5_Init((MD5_CTX *)md5_info);
|
||||
#else
|
||||
if (md5_info != NULL)
|
||||
{
|
||||
EVP_DigestInit_ex((EVP_MD_CTX *)md5_info, g_md_md5, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_md5_transform(void *md5_info, char *data, int len)
|
||||
ssl_md5_transform(void *md5_info, const char *data, int len)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
MD5_Update((MD5_CTX *)md5_info, data, len);
|
||||
#else
|
||||
if (md5_info != NULL)
|
||||
{
|
||||
EVP_DigestUpdate((EVP_MD_CTX *)md5_info, data, len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_md5_complete(void *md5_info, char *data)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
MD5_Final((tui8 *)data, (MD5_CTX *)md5_info);
|
||||
#else
|
||||
if (md5_info != NULL)
|
||||
{
|
||||
EVP_DigestFinal_ex((EVP_MD_CTX *)md5_info, (unsigned char *)data, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* FIPS stuff */
|
||||
@ -236,10 +460,30 @@ ssl_des3_encrypt_info_create(const char *key, const char *ivec)
|
||||
const tui8 *lkey;
|
||||
const tui8 *livec;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
/*
|
||||
* For these versions of OpenSSL, there are no long-term guarantees the
|
||||
* DES3 cipher will be available. We'll try to load it here so we
|
||||
* can log any errors */
|
||||
if (g_cipher_des_ede3_cbc == NULL)
|
||||
{
|
||||
g_cipher_des_ede3_cbc = EVP_CIPHER_fetch(NULL, "des-ede3-cbc", NULL);
|
||||
if (g_cipher_des_ede3_cbc == NULL)
|
||||
{
|
||||
dump_error_stack("DES-EDE3-CBC");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
des3_ctx = EVP_CIPHER_CTX_new();
|
||||
lkey = (const tui8 *) key;
|
||||
livec = (const tui8 *) ivec;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
EVP_EncryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
|
||||
#else
|
||||
EVP_EncryptInit_ex(des3_ctx, g_cipher_des_ede3_cbc, NULL, lkey, livec);
|
||||
#endif
|
||||
EVP_CIPHER_CTX_set_padding(des3_ctx, 0);
|
||||
return des3_ctx;
|
||||
}
|
||||
@ -252,10 +496,30 @@ ssl_des3_decrypt_info_create(const char *key, const char *ivec)
|
||||
const tui8 *lkey;
|
||||
const tui8 *livec;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
/*
|
||||
* For these versions of OpenSSL, there are no long-term guarantees the
|
||||
* DES3 cipher will be available. We'll try to load it here so we
|
||||
* can log any errors */
|
||||
if (g_cipher_des_ede3_cbc == NULL)
|
||||
{
|
||||
g_cipher_des_ede3_cbc = EVP_CIPHER_fetch(NULL, "des-ede3-cbc", NULL);
|
||||
if (g_cipher_des_ede3_cbc == NULL)
|
||||
{
|
||||
dump_error_stack("DES-EDE3-CBC");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
des3_ctx = EVP_CIPHER_CTX_new();
|
||||
lkey = (const tui8 *) key;
|
||||
livec = (const tui8 *) ivec;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
EVP_DecryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
|
||||
#else
|
||||
EVP_DecryptInit_ex(des3_ctx, g_cipher_des_ede3_cbc, NULL, lkey, livec);
|
||||
#endif
|
||||
EVP_CIPHER_CTX_set_padding(des3_ctx, 0);
|
||||
return des3_ctx;
|
||||
}
|
||||
@ -283,10 +547,13 @@ ssl_des3_encrypt(void *des3, int length, const char *in_data, char *out_data)
|
||||
tui8 *lout_data;
|
||||
|
||||
des3_ctx = (EVP_CIPHER_CTX *) des3;
|
||||
lin_data = (const tui8 *) in_data;
|
||||
lout_data = (tui8 *) out_data;
|
||||
len = 0;
|
||||
EVP_EncryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
|
||||
if (des3_ctx != NULL)
|
||||
{
|
||||
lin_data = (const tui8 *) in_data;
|
||||
lout_data = (tui8 *) out_data;
|
||||
len = 0;
|
||||
EVP_EncryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -300,10 +567,13 @@ ssl_des3_decrypt(void *des3, int length, const char *in_data, char *out_data)
|
||||
tui8 *lout_data;
|
||||
|
||||
des3_ctx = (EVP_CIPHER_CTX *) des3;
|
||||
lin_data = (const tui8 *) in_data;
|
||||
lout_data = (tui8 *) out_data;
|
||||
len = 0;
|
||||
EVP_DecryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
|
||||
if (des3_ctx != NULL)
|
||||
{
|
||||
lin_data = (const tui8 *) in_data;
|
||||
lout_data = (tui8 *) out_data;
|
||||
len = 0;
|
||||
EVP_DecryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -311,16 +581,28 @@ ssl_des3_decrypt(void *des3, int length, const char *in_data, char *out_data)
|
||||
void *
|
||||
ssl_hmac_info_create(void)
|
||||
{
|
||||
HMAC_CTX *hmac_ctx;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
return (HMAC_CTX *)HMAC_CTX_new();
|
||||
#else
|
||||
/* Need a MAC algorithm loaded */
|
||||
if (g_mac_hmac == NULL)
|
||||
{
|
||||
if ((g_mac_hmac = EVP_MAC_fetch(NULL, "hmac", NULL)) == NULL)
|
||||
{
|
||||
dump_error_stack("hmac");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
hmac_ctx = HMAC_CTX_new();
|
||||
return hmac_ctx;
|
||||
return (void *)EVP_MAC_CTX_new(g_mac_hmac);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_hmac_info_delete(void *hmac)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
HMAC_CTX *hmac_ctx;
|
||||
|
||||
hmac_ctx = (HMAC_CTX *) hmac;
|
||||
@ -328,34 +610,61 @@ ssl_hmac_info_delete(void *hmac)
|
||||
{
|
||||
HMAC_CTX_free(hmac_ctx);
|
||||
}
|
||||
#else
|
||||
EVP_MAC_CTX_free((EVP_MAC_CTX *)hmac);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_hmac_sha1_init(void *hmac, const char *data, int len)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
HMAC_CTX *hmac_ctx;
|
||||
|
||||
hmac_ctx = (HMAC_CTX *) hmac;
|
||||
HMAC_Init_ex(hmac_ctx, data, len, EVP_sha1(), NULL);
|
||||
#else
|
||||
if (hmac != NULL)
|
||||
{
|
||||
char digest[] = "sha1";
|
||||
OSSL_PARAM params[3];
|
||||
size_t n = 0;
|
||||
params[n++] = OSSL_PARAM_construct_utf8_string("digest", digest, 0);
|
||||
params[n++] = OSSL_PARAM_construct_end();
|
||||
if (EVP_MAC_init((EVP_MAC_CTX *)hmac, (unsigned char *)data,
|
||||
len, params) == 0)
|
||||
{
|
||||
dump_error_stack("hmac-sha1");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_hmac_transform(void *hmac, const char *data, int len)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
HMAC_CTX *hmac_ctx;
|
||||
const tui8 *ldata;
|
||||
|
||||
hmac_ctx = (HMAC_CTX *) hmac;
|
||||
ldata = (const tui8 *) data;
|
||||
HMAC_Update(hmac_ctx, ldata, len);
|
||||
#else
|
||||
if (hmac != NULL)
|
||||
{
|
||||
EVP_MAC_update((EVP_MAC_CTX *)hmac, (unsigned char *)data, len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
ssl_hmac_complete(void *hmac, char *data, int len)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
HMAC_CTX *hmac_ctx;
|
||||
tui8 *ldata;
|
||||
tui32 llen;
|
||||
@ -364,6 +673,12 @@ ssl_hmac_complete(void *hmac, char *data, int len)
|
||||
ldata = (tui8 *) data;
|
||||
llen = len;
|
||||
HMAC_Final(hmac_ctx, ldata, &llen);
|
||||
#else
|
||||
if (hmac != NULL)
|
||||
{
|
||||
EVP_MAC_final((EVP_MAC_CTX *)hmac, (unsigned char *)data, NULL, len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -455,7 +770,6 @@ ssl_gen_key_xrdp1(int key_size_in_bits, const char *exp, int exp_len,
|
||||
char *mod, int mod_len, char *pri, int pri_len)
|
||||
{
|
||||
BIGNUM *my_e;
|
||||
RSA *my_key;
|
||||
char *lexp;
|
||||
char *lmod;
|
||||
char *lpri;
|
||||
@ -477,12 +791,44 @@ ssl_gen_key_xrdp1(int key_size_in_bits, const char *exp, int exp_len,
|
||||
ssl_reverse_it(lexp, exp_len);
|
||||
my_e = BN_new();
|
||||
BN_bin2bn((tui8 *)lexp, exp_len, my_e);
|
||||
my_key = RSA_new();
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
const BIGNUM *n = NULL;
|
||||
const BIGNUM *d = NULL;
|
||||
RSA *my_key = RSA_new();
|
||||
error = RSA_generate_key_ex(my_key, key_size_in_bits, my_e, 0) == 0;
|
||||
|
||||
const BIGNUM *n;
|
||||
const BIGNUM *d;
|
||||
/* After this call, n and d point directly into my_key, and are valid
|
||||
* until my_key is free'd */
|
||||
RSA_get0_key(my_key, &n, NULL, &d);
|
||||
#else
|
||||
BIGNUM *n = NULL;
|
||||
BIGNUM *d = NULL;
|
||||
OSSL_PARAM params[] =
|
||||
{
|
||||
OSSL_PARAM_construct_int("bits", &key_size_in_bits),
|
||||
OSSL_PARAM_construct_end()
|
||||
};
|
||||
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
if (pctx != NULL &&
|
||||
EVP_PKEY_keygen_init(pctx) > 0 &&
|
||||
EVP_PKEY_CTX_set_params(pctx, params) > 0 &&
|
||||
EVP_PKEY_generate(pctx, &pkey) > 0 &&
|
||||
EVP_PKEY_get_bn_param(pkey, "n", &n) > 0 &&
|
||||
EVP_PKEY_get_bn_param(pkey, "d", &d) > 0)
|
||||
{
|
||||
error = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
error = 1;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
EVP_PKEY_free(pkey);
|
||||
#endif
|
||||
|
||||
if (error == 0)
|
||||
{
|
||||
@ -517,7 +863,12 @@ ssl_gen_key_xrdp1(int key_size_in_bits, const char *exp, int exp_len,
|
||||
}
|
||||
|
||||
BN_free(my_e);
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
RSA_free(my_key);
|
||||
#else
|
||||
BN_free(n);
|
||||
BN_clear_free(d);
|
||||
#endif
|
||||
g_free(lexp);
|
||||
g_free(lmod);
|
||||
g_free(lpri);
|
||||
@ -529,7 +880,11 @@ ssl_gen_key_xrdp1(int key_size_in_bits, const char *exp, int exp_len,
|
||||
see also
|
||||
* https://wiki.openssl.org/index.php/Diffie-Hellman_parameters
|
||||
* https://wiki.openssl.org/index.php/Manual:SSL_CTX_set_tmp_dh_callback(3)
|
||||
*
|
||||
* We dont do this for OpenSSL 3 - we use SSL_CTX_set_dh_auto() instead, as this
|
||||
* can cater for different key sizes on the certificate
|
||||
*/
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
static DH *ssl_get_dh2236()
|
||||
{
|
||||
static unsigned char dh2236_p[] =
|
||||
@ -591,6 +946,7 @@ static DH *ssl_get_dh2236()
|
||||
|
||||
return dh;
|
||||
}
|
||||
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
|
||||
|
||||
/*****************************************************************************/
|
||||
struct ssl_tls *
|
||||
@ -613,36 +969,61 @@ ssl_tls_create(struct trans *trans, const char *key, const char *cert)
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
ssl_tls_log_error(const char *func, SSL *connection, int value)
|
||||
ssl_tls_log_error(struct ssl_tls *self, const char *func, int value)
|
||||
{
|
||||
switch (SSL_get_error(connection, value))
|
||||
int result = 1;
|
||||
int ssl_error = SSL_get_error(self->ssl, value);
|
||||
|
||||
if (ssl_error == SSL_ERROR_WANT_READ || ssl_error == SSL_ERROR_WANT_WRITE)
|
||||
{
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
LOG(LOG_LEVEL_ERROR, "%s: Server closed TLS connection", func);
|
||||
return 1;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
return 0;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
LOG(LOG_LEVEL_ERROR, "%s: I/O error", func);
|
||||
return 1;
|
||||
|
||||
case SSL_ERROR_SSL:
|
||||
LOG(LOG_LEVEL_ERROR, "%s: Failure in SSL library (protocol error?)", func);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
LOG(LOG_LEVEL_ERROR, "%s: Unknown SSL error", func);
|
||||
return 1;
|
||||
result = 0;
|
||||
}
|
||||
else if (!self->error_logged)
|
||||
{
|
||||
switch (ssl_error)
|
||||
{
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
LOG(LOG_LEVEL_ERROR, "%s: Server closed TLS connection", func);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
LOG(LOG_LEVEL_ERROR, "%s: I/O error", func);
|
||||
break;
|
||||
|
||||
case SSL_ERROR_SSL:
|
||||
LOG(LOG_LEVEL_ERROR, "%s: Failure in SSL library "
|
||||
"(protocol error?)", func);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(LOG_LEVEL_ERROR, "%s: Unknown SSL error", func);
|
||||
break;
|
||||
}
|
||||
|
||||
dump_ssl_error_stack(self); /* Sets self->error_logged */
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Log an attempt to use an encrypted file
|
||||
*
|
||||
* For example, a private key could have a password set on it. We don't
|
||||
* support this.
|
||||
*/
|
||||
static int
|
||||
log_encrypted_file_unsupported(char *buf, int size, int rwflag, void *u)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Encryption is not supported for %s",
|
||||
(const char *)u);
|
||||
return -1; /* See pem_password_cb(3ssl) */
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
const char *tls_ciphers)
|
||||
@ -650,6 +1031,8 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
int connection_status;
|
||||
long options = 0;
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
/**
|
||||
* SSL_OP_NO_SSLv2
|
||||
* SSLv3 is used by, eg. Microsoft RDC for Mac OS X.
|
||||
@ -695,6 +1078,7 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
if (self->ctx == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to negotiate a TLS connection with the client");
|
||||
dump_ssl_error_stack(self);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -705,6 +1089,7 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
SSL_CTX_set_options(self->ctx, options);
|
||||
|
||||
/* set DH parameters */
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
DH *dh = ssl_get_dh2236();
|
||||
if (dh == NULL)
|
||||
{
|
||||
@ -715,11 +1100,16 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
if (SSL_CTX_set_tmp_dh(self->ctx, dh) != 1)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to setup DHE parameters for TLS");
|
||||
dump_ssl_error_stack(self);
|
||||
return 1;
|
||||
}
|
||||
DH_free(dh); // ok to free, copied into ctx by SSL_CTX_set_tmp_dh()
|
||||
#endif
|
||||
|
||||
#if defined(SSL_CTX_set_ecdh_auto)
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10000020L) && \
|
||||
OPENSSL_VERSION_NUMBER < (0x10100000L)
|
||||
// SSL_CTX_set_ecdh_auto() added in OpenSSL 1.0.2 and
|
||||
// removed for OpenSSL 1.1.0
|
||||
if (!SSL_CTX_set_ecdh_auto(self->ctx, 1))
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "TLS ecdh auto failed to be enabled");
|
||||
@ -732,30 +1122,56 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
if (SSL_CTX_set_cipher_list(self->ctx, tls_ciphers) == 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Invalid TLS cipher options %s", tls_ciphers);
|
||||
dump_ssl_error_stack(self);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
SSL_CTX_set_read_ahead(self->ctx, 0);
|
||||
|
||||
/*
|
||||
* We don't currently handle encrypted private keys - set a callback
|
||||
* to tell the user if one is provided */
|
||||
SSL_CTX_set_default_passwd_cb(self->ctx, log_encrypted_file_unsupported);
|
||||
SSL_CTX_set_default_passwd_cb_userdata(self->ctx, self->key);
|
||||
|
||||
if (SSL_CTX_use_PrivateKey_file(self->ctx, self->key, SSL_FILETYPE_PEM)
|
||||
<= 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Error loading TLS private key from %s", self->key);
|
||||
dump_ssl_error_stack(self);
|
||||
return 1;
|
||||
}
|
||||
SSL_CTX_set_default_passwd_cb(self->ctx, NULL);
|
||||
SSL_CTX_set_default_passwd_cb_userdata(self->ctx, NULL);
|
||||
|
||||
if (SSL_CTX_use_certificate_chain_file(self->ctx, self->cert) <= 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Error loading TLS certificate chain from %s", self->cert);
|
||||
dump_ssl_error_stack(self);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't call SSL_check_private_key() for openSSL prior to 1.0.2, as
|
||||
* certificate chains are not handled in the same way - see
|
||||
* SSL_CTX_check_private_key(3ssl) */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
if (!SSL_CTX_check_private_key(self->ctx))
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Private key %s and certificate %s do not match",
|
||||
self->key, self->cert);
|
||||
dump_ssl_error_stack(self);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
self->ssl = SSL_new(self->ctx);
|
||||
|
||||
if (self->ssl == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to create an SSL structure");
|
||||
dump_ssl_error_stack(self);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -763,16 +1179,23 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to set up an SSL structure on fd %d",
|
||||
(int)self->trans->sck);
|
||||
dump_ssl_error_stack(self);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
/*
|
||||
* Make sure the error queue is clear before (re-) attempting the
|
||||
* accept. If the accept is successful, the error queue will
|
||||
* remain clear for normal SSL operation */
|
||||
ERR_clear_error();
|
||||
|
||||
connection_status = SSL_accept(self->ssl);
|
||||
|
||||
if (connection_status <= 0)
|
||||
{
|
||||
if (ssl_tls_log_error("SSL_accept", self->ssl, connection_status))
|
||||
if (ssl_tls_log_error(self, "SSL_accept", connection_status))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -823,7 +1246,7 @@ ssl_tls_disconnect(struct ssl_tls *self)
|
||||
status = SSL_shutdown(self->ssl);
|
||||
if (status <= 0)
|
||||
{
|
||||
if (ssl_tls_log_error("SSL_shutdown", self->ssl, status))
|
||||
if (ssl_tls_log_error(self, "SSL_shutdown", status))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -893,7 +1316,7 @@ ssl_tls_read(struct ssl_tls *tls, char *data, int length)
|
||||
return 0;
|
||||
|
||||
default:
|
||||
ssl_tls_log_error("SSL_read", tls->ssl, status);
|
||||
ssl_tls_log_error(tls, "SSL_read", status);
|
||||
status = -1;
|
||||
break_flag = 1;
|
||||
break;
|
||||
@ -947,7 +1370,7 @@ ssl_tls_write(struct ssl_tls *tls, const char *data, int length)
|
||||
return 0;
|
||||
|
||||
default:
|
||||
ssl_tls_log_error("SSL_write", tls->ssl, status);
|
||||
ssl_tls_log_error(tls, "SSL_write", status);
|
||||
status = -1;
|
||||
break_flag = 1;
|
||||
break;
|
||||
@ -977,16 +1400,23 @@ ssl_tls_can_recv(struct ssl_tls *tls, int sck, int millis)
|
||||
|
||||
/*****************************************************************************/
|
||||
const char *
|
||||
ssl_get_version(const struct ssl_st *ssl)
|
||||
ssl_get_version(const struct ssl_tls *ssl)
|
||||
{
|
||||
return SSL_get_version(ssl);
|
||||
return SSL_get_version(ssl->ssl);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
const char *
|
||||
ssl_get_cipher_name(const struct ssl_st *ssl)
|
||||
ssl_get_cipher_name(const struct ssl_tls *ssl)
|
||||
{
|
||||
return SSL_get_cipher_name(ssl);
|
||||
return SSL_get_cipher_name(ssl->ssl);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
tintptr
|
||||
ssl_get_rwo(const struct ssl_tls *ssl)
|
||||
{
|
||||
return ssl->rwo;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -1092,7 +1522,7 @@ ssl_get_protocols_from_string(const char *str, long *ssl_protocols)
|
||||
|
||||
/*****************************************************************************/
|
||||
const char
|
||||
*get_openssl_version()
|
||||
*get_openssl_version(void)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
return SSLeay_version(SSLEAY_VERSION);
|
||||
|
@ -22,6 +22,10 @@
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
/* Incomplete types */
|
||||
struct ssl_tls;
|
||||
struct trans;
|
||||
|
||||
int
|
||||
ssl_init(void);
|
||||
int
|
||||
@ -31,7 +35,7 @@ ssl_rc4_info_create(void);
|
||||
void
|
||||
ssl_rc4_info_delete(void *rc4_info);
|
||||
void
|
||||
ssl_rc4_set_key(void *rc4_info, char *key, int len);
|
||||
ssl_rc4_set_key(void *rc4_info, const char *key, int len);
|
||||
void
|
||||
ssl_rc4_crypt(void *rc4_info, char *data, int len);
|
||||
void *
|
||||
@ -51,7 +55,7 @@ ssl_md5_info_delete(void *md5_info);
|
||||
void
|
||||
ssl_md5_clear(void *md5_info);
|
||||
void
|
||||
ssl_md5_transform(void *md5_info, char *data, int len);
|
||||
ssl_md5_transform(void *md5_info, const char *data, int len);
|
||||
void
|
||||
ssl_md5_complete(void *md5_info, char *data);
|
||||
void *
|
||||
@ -81,17 +85,6 @@ int
|
||||
ssl_gen_key_xrdp1(int key_size_in_bits, const char *exp, int exp_len,
|
||||
char *mod, int mod_len, char *pri, int pri_len);
|
||||
|
||||
/* ssl_tls */
|
||||
struct ssl_tls
|
||||
{
|
||||
struct ssl_st *ssl; /* SSL * */
|
||||
struct ssl_ctx_st *ctx; /* SSL_CTX * */
|
||||
char *cert;
|
||||
char *key;
|
||||
struct trans *trans;
|
||||
tintptr rwo; /* wait obj */
|
||||
};
|
||||
|
||||
/* xrdp_tls.c */
|
||||
struct ssl_tls *
|
||||
ssl_tls_create(struct trans *trans, const char *key, const char *cert);
|
||||
@ -109,12 +102,14 @@ ssl_tls_write(struct ssl_tls *tls, const char *data, int length);
|
||||
int
|
||||
ssl_tls_can_recv(struct ssl_tls *tls, int sck, int millis);
|
||||
const char *
|
||||
ssl_get_version(const struct ssl_st *ssl);
|
||||
ssl_get_version(const struct ssl_tls *ssl);
|
||||
const char *
|
||||
ssl_get_cipher_name(const struct ssl_st *ssl);
|
||||
ssl_get_cipher_name(const struct ssl_tls *ssl);
|
||||
int
|
||||
ssl_get_protocols_from_string(const char *str, long *ssl_protocols);
|
||||
const char *
|
||||
get_openssl_version();
|
||||
get_openssl_version(void);
|
||||
tintptr
|
||||
ssl_get_rwo(const struct ssl_tls *ssl);
|
||||
|
||||
#endif
|
||||
|
@ -21,16 +21,17 @@
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config_ac.h"
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
#include "log.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "defines.h"
|
||||
#include "unicode_defines.h"
|
||||
|
||||
unsigned int
|
||||
g_format_info_string(char *dest, unsigned int len,
|
||||
@ -188,7 +189,7 @@ g_strlen(const char *text)
|
||||
|
||||
/*****************************************************************************/
|
||||
/* locates char in text */
|
||||
const char *
|
||||
char *
|
||||
g_strchr(const char *text, int c)
|
||||
{
|
||||
if (text == NULL)
|
||||
@ -196,7 +197,35 @@ g_strchr(const char *text, int c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strchr(text, c);
|
||||
/* Cast needed to compile with C++ */
|
||||
return (char *)strchr(text, c);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* locates char in text */
|
||||
char *
|
||||
g_strrchr(const char *text, int c)
|
||||
{
|
||||
if (text == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Cast needed to compile with C++ */
|
||||
return (char *)strrchr(text, c);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* locates char in text with length */
|
||||
char *
|
||||
g_strnchr(const char *text, int c, int len)
|
||||
{
|
||||
if (text == NULL || len <= 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (char *)memchr(text, c, len);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -394,6 +423,30 @@ g_atoi(const char *str)
|
||||
return atoi(str);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* As g_atoi() but allows for hexadecimal too */
|
||||
int
|
||||
g_atoix(const char *str)
|
||||
{
|
||||
int base = 10;
|
||||
if (str == NULL)
|
||||
{
|
||||
str = "0";
|
||||
}
|
||||
|
||||
while (isspace(*str))
|
||||
{
|
||||
++str;
|
||||
}
|
||||
|
||||
if (*str == '0' && tolower(*(str + 1)) == 'x')
|
||||
{
|
||||
str += 2;
|
||||
base = 16;
|
||||
}
|
||||
return strtol(str, NULL, base);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_htoi(char *str)
|
||||
@ -537,7 +590,7 @@ g_bytes_to_hexdump(const char *src, int len)
|
||||
+ HEX_DUMP_NEWLINE_SIZE);
|
||||
|
||||
dump_number_lines = (len / HEX_DUMP_SOURCE_BYTES_PER_LINE) + 1; /* +1 to round up */
|
||||
dump_length = (dump_number_lines *dump_line_length /* hex dump lines */
|
||||
dump_length = (dump_number_lines * dump_line_length /* hex dump lines */
|
||||
+ 1); /* terminating NULL */
|
||||
dump_buffer = (char *)g_malloc(dump_length, 1);
|
||||
if (dump_buffer == NULL)
|
||||
@ -644,168 +697,76 @@ g_pos(const char *str, const char *to_find)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_mbstowcs(twchar *dest, const char *src, int n)
|
||||
|
||||
char *
|
||||
g_strstr(const char *haystack, const char *needle)
|
||||
{
|
||||
wchar_t *ldest;
|
||||
int rv;
|
||||
if (haystack == NULL || needle == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ldest = (wchar_t *)dest;
|
||||
rv = mbstowcs(ldest, src, n);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_wcstombs(char *dest, const twchar *src, int n)
|
||||
{
|
||||
const wchar_t *lsrc;
|
||||
int rv;
|
||||
|
||||
lsrc = (const wchar_t *)src;
|
||||
rv = wcstombs(dest, lsrc, n);
|
||||
return rv;
|
||||
/* Cast needed to compile with C++ */
|
||||
return (char *)strstr(haystack, needle);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
/* trim spaces and tabs, anything <= space */
|
||||
/* trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through */
|
||||
/* this will always shorten the string or not change it */
|
||||
int
|
||||
g_strtrim(char *str, int trim_flags)
|
||||
{
|
||||
#define TRIMMABLE_CHAR(c) ((unsigned char)(c) <= ' ')
|
||||
int rv = 0;
|
||||
int index;
|
||||
int len;
|
||||
int text1_index;
|
||||
int got_char;
|
||||
wchar_t *text;
|
||||
wchar_t *text1;
|
||||
|
||||
len = mbstowcs(0, str, 0);
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((trim_flags < 1) || (trim_flags > 4))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
text = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
|
||||
text1 = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
|
||||
if (text == NULL || text1 == NULL)
|
||||
{
|
||||
free(text);
|
||||
free(text1);
|
||||
return 1;
|
||||
}
|
||||
text1_index = 0;
|
||||
mbstowcs(text, str, len + 1);
|
||||
int j;
|
||||
|
||||
switch (trim_flags)
|
||||
{
|
||||
case 4: /* trim through */
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
j = 0;
|
||||
for (index = 0; str[index] != '\0'; index++)
|
||||
{
|
||||
if (text[index] > 32)
|
||||
if (!TRIMMABLE_CHAR(str[index]))
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
str[j++] = str[index];
|
||||
}
|
||||
}
|
||||
|
||||
text1[text1_index] = 0;
|
||||
str[j] = '\0';
|
||||
break;
|
||||
|
||||
case 3: /* trim both */
|
||||
got_char = 0;
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
if (got_char)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (text[index] > 32)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
got_char = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text1[text1_index] = 0;
|
||||
len = text1_index;
|
||||
|
||||
/* trim right */
|
||||
for (index = len - 1; index >= 0; index--)
|
||||
{
|
||||
if (text1[index] > 32)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
text1_index = index + 1;
|
||||
text1[text1_index] = 0;
|
||||
rv = g_strtrim(str, 1) || g_strtrim(str, 2);
|
||||
break;
|
||||
|
||||
case 2: /* trim right */
|
||||
|
||||
/* copy it */
|
||||
for (index = 0; index < len; index++)
|
||||
index = strlen(str);
|
||||
while (index > 0 && TRIMMABLE_CHAR(str[index - 1]))
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
--index;
|
||||
}
|
||||
|
||||
/* trim right */
|
||||
for (index = len - 1; index >= 0; index--)
|
||||
{
|
||||
if (text1[index] > 32)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
text1_index = index + 1;
|
||||
text1[text1_index] = 0;
|
||||
str[index] = '\0';
|
||||
break;
|
||||
|
||||
case 1: /* trim left */
|
||||
got_char = 0;
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
index = 0;
|
||||
while (str[index] != '\0' && TRIMMABLE_CHAR(str[index]))
|
||||
{
|
||||
if (got_char)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (text[index] > 32)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
got_char = 1;
|
||||
}
|
||||
}
|
||||
++index;
|
||||
}
|
||||
if (index > 0)
|
||||
{
|
||||
memmove(str, str + index, strlen(str) + 1 - index);
|
||||
}
|
||||
|
||||
text1[text1_index] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = 1;
|
||||
}
|
||||
|
||||
wcstombs(str, text1, text1_index + 1);
|
||||
free(text);
|
||||
free(text1);
|
||||
return 0;
|
||||
return rv;
|
||||
#undef TRIMMABLE_CHAR
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -818,7 +779,7 @@ g_strnjoin(char *dest, int dest_len, const char *joiner, const char *src[], int
|
||||
int dest_remaining;
|
||||
char *dest_pos = dest;
|
||||
char *dest_end;
|
||||
|
||||
|
||||
if (dest == NULL || dest_len < 1)
|
||||
{
|
||||
return dest;
|
||||
@ -854,3 +815,672 @@ g_strnjoin(char *dest, int dest_len, const char *joiner, const char *src[], int
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_bitmask_to_str(int bitmask, const struct bitmask_string bitdefs[],
|
||||
char delim, char *buff, int bufflen)
|
||||
{
|
||||
int rlen = 0; /* Returned length */
|
||||
|
||||
if (bufflen <= 0) /* Caller error */
|
||||
{
|
||||
rlen = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p = buff;
|
||||
/* Find the last writeable character in the buffer */
|
||||
const char *last = buff + (bufflen - 1);
|
||||
|
||||
const struct bitmask_string *b;
|
||||
|
||||
for (b = &bitdefs[0] ; b->mask != 0; ++b)
|
||||
{
|
||||
if ((bitmask & b->mask) != 0)
|
||||
{
|
||||
if (p > buff)
|
||||
{
|
||||
/* Not first item - append separator */
|
||||
if (p < last)
|
||||
{
|
||||
*p++ = delim;
|
||||
}
|
||||
++rlen;
|
||||
}
|
||||
|
||||
int slen = g_strlen(b->str);
|
||||
int copylen = MIN(slen, last - p);
|
||||
g_memcpy(p, b->str, copylen);
|
||||
p += copylen;
|
||||
rlen += slen;
|
||||
|
||||
/* Remove the bit so we can check for undefined bits later*/
|
||||
bitmask &= ~b->mask;
|
||||
}
|
||||
}
|
||||
|
||||
if (bitmask != 0)
|
||||
{
|
||||
/* Bits left which aren't named by the user */
|
||||
if (p > buff)
|
||||
{
|
||||
if (p < last)
|
||||
{
|
||||
*p++ = delim;
|
||||
}
|
||||
++rlen;
|
||||
}
|
||||
/* This call will terminate the return buffer */
|
||||
rlen += g_snprintf(p, last - p + 1, "0x%x", bitmask);
|
||||
}
|
||||
else
|
||||
{
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_str_to_bitmask(const char *str, const struct bitmask_string bitdefs[],
|
||||
const char *delim, char *unrecognised, int unrecognised_len)
|
||||
{
|
||||
char *properties = NULL;
|
||||
char *p = NULL;
|
||||
int mask = 0;
|
||||
|
||||
if (unrecognised_len < 1)
|
||||
{
|
||||
/* No space left to tell unrecognised tokens */
|
||||
return 0;
|
||||
}
|
||||
if (!unrecognised)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* ensure not to return with uninitialized buffer */
|
||||
unrecognised[0] = '\0';
|
||||
if (!str || !bitdefs || !delim)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
properties = g_strdup(str);
|
||||
if (!properties)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
p = strtok(properties, delim);
|
||||
while (p != NULL)
|
||||
{
|
||||
g_strtrim(p, 3);
|
||||
const struct bitmask_string *b;
|
||||
int found = 0;
|
||||
for (b = &bitdefs[0] ; b->str != NULL; ++b)
|
||||
{
|
||||
if (0 == g_strcasecmp(p, b->str))
|
||||
{
|
||||
mask |= b->mask;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == 0)
|
||||
{
|
||||
int length = g_strlen(unrecognised);
|
||||
if (length > 0)
|
||||
{
|
||||
/* adding ",property" */
|
||||
if (length + g_strlen(p) + 1 < unrecognised_len)
|
||||
{
|
||||
unrecognised[length] = delim[0];
|
||||
length += 1;
|
||||
g_strcpy(unrecognised + length, p);
|
||||
}
|
||||
}
|
||||
else if (g_strlen(p) < unrecognised_len)
|
||||
{
|
||||
g_strcpy(unrecognised, p);
|
||||
}
|
||||
}
|
||||
p = strtok(NULL, delim);
|
||||
}
|
||||
|
||||
g_free(properties);
|
||||
return mask;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_bitmask_to_charstr(int bitmask, const struct bitmask_char bitdefs[],
|
||||
char *buff, int bufflen, int *rest)
|
||||
{
|
||||
int rlen = 0; /* Returned length */
|
||||
|
||||
if (bufflen <= 0) /* Caller error */
|
||||
{
|
||||
rlen = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p = buff;
|
||||
/* Find the last writeable character in the buffer */
|
||||
const char *last = buff + (bufflen - 1);
|
||||
|
||||
const struct bitmask_char *b;
|
||||
|
||||
for (b = &bitdefs[0] ; b->c != '\0'; ++b)
|
||||
{
|
||||
if ((bitmask & b->mask) != 0)
|
||||
{
|
||||
if (p < last)
|
||||
{
|
||||
*p++ = b->c;
|
||||
}
|
||||
++rlen;
|
||||
|
||||
/* Remove the bit so we don't report it back */
|
||||
bitmask &= ~b->mask;
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
|
||||
if (rest != NULL)
|
||||
{
|
||||
*rest = bitmask;
|
||||
}
|
||||
}
|
||||
|
||||
return rlen;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_charstr_to_bitmask(const char *str, const struct bitmask_char bitdefs[],
|
||||
char *unrecognised, int unrecognised_len)
|
||||
{
|
||||
int bitmask = 0;
|
||||
const char *cp;
|
||||
int j = 0;
|
||||
|
||||
if (str != NULL && bitdefs != NULL)
|
||||
{
|
||||
for (cp = str ; *cp != '\0' ; ++cp)
|
||||
{
|
||||
const struct bitmask_char *b;
|
||||
char c = toupper(*cp);
|
||||
|
||||
for (b = &bitdefs[0] ; b->c != '\0'; ++b)
|
||||
{
|
||||
if (toupper(b->c) == c)
|
||||
{
|
||||
bitmask |= b->mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (b->c == '\0')
|
||||
{
|
||||
if (unrecognised != NULL && j < (unrecognised_len - 1))
|
||||
{
|
||||
unrecognised[j++] = *cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (unrecognised != NULL && j < unrecognised_len)
|
||||
{
|
||||
unrecognised[j] = '\0';
|
||||
}
|
||||
|
||||
return bitmask;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* Looks for a simple mapping of signal number to name
|
||||
*/
|
||||
static const char *
|
||||
find_sig_name(int signum)
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
int num;
|
||||
const char *name;
|
||||
} sig_to_name_type;
|
||||
|
||||
// Map a string 'zzz' to { SIGzzz, "zzz"} for making
|
||||
// typo-free sig_to_name_type objects
|
||||
# define DEFSIG(sig) { SIG ## sig, # sig }
|
||||
|
||||
// Entries in this array are taken from
|
||||
// The Single UNIX ® Specification, Version 2 (1997)
|
||||
// plus additions from specific operating systems.
|
||||
//
|
||||
// The SUS requires these to be positive integer constants with a
|
||||
// macro definition. Note that SIGRTMIN and SIGRTMAX on Linux are
|
||||
// NOT constants, so have to be handled separately.
|
||||
static const sig_to_name_type sigmap[] =
|
||||
{
|
||||
// Names from SUS v2, in the order they are listed in that document
|
||||
// that *should* be defined everywhere
|
||||
//
|
||||
// Commented out definitions below are NOT used everywhere
|
||||
DEFSIG(ABRT), DEFSIG(ALRM), DEFSIG(FPE), DEFSIG(HUP),
|
||||
DEFSIG(ILL), DEFSIG(INT), DEFSIG(KILL), DEFSIG(PIPE),
|
||||
DEFSIG(QUIT), DEFSIG(SEGV), DEFSIG(TERM), DEFSIG(USR1),
|
||||
DEFSIG(USR2), DEFSIG(CHLD), DEFSIG(CONT), DEFSIG(STOP),
|
||||
DEFSIG(TSTP), DEFSIG(TTIN), DEFSIG(TTOU), DEFSIG(BUS),
|
||||
/* DEFSIG(POLL), */ /* DEFSIG(PROF), */ DEFSIG(SYS), DEFSIG(TRAP),
|
||||
DEFSIG(URG), DEFSIG(VTALRM), DEFSIG(XCPU), DEFSIG(XFSZ),
|
||||
|
||||
// SIGPOLL and SIGPROF are marked as obselescent in 1003.1-2017,
|
||||
// Also SIGPOLL isn't in *BSD operating systems which use SIGIO
|
||||
#ifdef SIGPOLL
|
||||
DEFSIG(POLL),
|
||||
#endif
|
||||
#ifdef SIGPROF
|
||||
DEFSIG(PROF),
|
||||
#endif
|
||||
|
||||
// BSD signals (from FreeBSD/OpenBSD sys/signal.h and
|
||||
// Darwin/Illumos signal.h)
|
||||
#ifdef SIGEMT
|
||||
DEFSIG(EMT),
|
||||
#endif
|
||||
#ifdef SIGIO
|
||||
DEFSIG(IO),
|
||||
#endif
|
||||
#ifdef SIGWINCH
|
||||
DEFSIG(WINCH),
|
||||
#endif
|
||||
#ifdef SIGINFO
|
||||
DEFSIG(INFO),
|
||||
#endif
|
||||
#ifdef SIGTHR
|
||||
DEFSIG(THR),
|
||||
#endif
|
||||
#ifdef SIGLIBRT
|
||||
DEFSIG(LIBRT),
|
||||
#endif
|
||||
#ifdef SIGPWR
|
||||
DEFSIG(PWR),
|
||||
#endif
|
||||
#ifdef SIGWAITING
|
||||
DEFSIG(WAITING),
|
||||
#endif
|
||||
#ifdef SIGLWP
|
||||
DEFSIG(LWP),
|
||||
#endif
|
||||
|
||||
// Linux additions to *BSD (signal(7))
|
||||
#ifdef SIGLOST
|
||||
DEFSIG(LOST),
|
||||
#endif
|
||||
#ifdef SIGSTKFLT
|
||||
DEFSIG(STKFLT),
|
||||
#endif
|
||||
|
||||
// Terminator
|
||||
{0, NULL}
|
||||
#undef DEFSIG
|
||||
};
|
||||
|
||||
const sig_to_name_type *p;
|
||||
|
||||
for (p = &sigmap[0] ; p->name != NULL ; ++p)
|
||||
{
|
||||
if (p->num == signum)
|
||||
{
|
||||
return p->name;
|
||||
}
|
||||
}
|
||||
|
||||
// These aren't constants on Linux
|
||||
#ifdef SIGRTMIN
|
||||
if (signum == SIGRTMIN)
|
||||
{
|
||||
return "RTMIN";
|
||||
}
|
||||
#endif
|
||||
#ifdef SIGRTMAX
|
||||
if (signum == SIGRTMAX)
|
||||
{
|
||||
return "RTMAX";
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
char *
|
||||
g_sig2text(int signum, char sigstr[])
|
||||
{
|
||||
if (signum >= 0)
|
||||
{
|
||||
const char *name = find_sig_name(signum);
|
||||
|
||||
if (name != NULL)
|
||||
{
|
||||
g_snprintf(sigstr, MAXSTRSIGLEN, "SIG%s", name);
|
||||
return sigstr;
|
||||
}
|
||||
|
||||
#if defined(SIGRTMIN) && defined(SIGRTMAX)
|
||||
if (signum > SIGRTMIN && signum < SIGRTMAX)
|
||||
{
|
||||
g_snprintf(sigstr, MAXSTRSIGLEN, "SIGRTMIN+%d", signum - SIGRTMIN);
|
||||
return sigstr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// If all else fails...
|
||||
g_snprintf(sigstr, MAXSTRSIGLEN, "SIG#%d", signum);
|
||||
return sigstr;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
char32_t
|
||||
utf8_get_next_char(const char **utf8str_ref, unsigned int *len_ref)
|
||||
{
|
||||
/*
|
||||
* Macro used to parse a continuation character
|
||||
* @param cp Character Pointer (incremented on success)
|
||||
* @param end One character past end of input string
|
||||
* @param value The value we're constructing
|
||||
* @param finish_label Where to go in the event of an error */
|
||||
#define PARSE_CONTINUATION_CHARACTER(cp, end, value, finish_label) \
|
||||
{ \
|
||||
/* Error if we're out of data, or this char isn't a continuation */ \
|
||||
if (cp == end || !IS_VALID_CONTINUATION_CHAR(*cp)) \
|
||||
{ \
|
||||
value = UCS_REPLACEMENT_CHARACTER; \
|
||||
goto finish_label; \
|
||||
} \
|
||||
value = (value) << 6 | (*cp & 0x3f); \
|
||||
++cp; \
|
||||
}
|
||||
|
||||
char32_t rv;
|
||||
|
||||
/* Easier to work with unsigned chars and no indirection */
|
||||
const unsigned char *cp = (const unsigned char *)*utf8str_ref;
|
||||
const unsigned char *end = (len_ref != NULL) ? cp + *len_ref : cp + 6;
|
||||
|
||||
if (cp == end)
|
||||
{
|
||||
return 0; // Pathological case
|
||||
}
|
||||
|
||||
unsigned int c0 = *cp++;
|
||||
|
||||
if (c0 < 0x80)
|
||||
{
|
||||
rv = c0;
|
||||
}
|
||||
else if (c0 < 0xc0)
|
||||
{
|
||||
/* Unexpected continuation character */
|
||||
rv = UCS_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
else if (c0 < 0xe0)
|
||||
{
|
||||
/* Valid start character for sequence of length 2
|
||||
* U-00000080 – U-000007FF */
|
||||
rv = (c0 & 0x1f);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
|
||||
if (rv < 0x80 || INVALID_UNICODE_80_TO_7FF(rv))
|
||||
{
|
||||
rv = UCS_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
}
|
||||
else if (c0 < 0xf0)
|
||||
{
|
||||
/* Valid start character for sequence of length 3
|
||||
* U-00000800 – U-0000FFFF */
|
||||
rv = (c0 & 0xf);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
if (rv < 0x800 || INVALID_UNICODE_800_TO_FFFF(rv))
|
||||
{
|
||||
rv = UCS_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
}
|
||||
else if (c0 < 0xf8)
|
||||
{
|
||||
/* Valid start character for sequence of length 4
|
||||
* U-00010000 – U-0001FFFFF */
|
||||
rv = (c0 & 0x7);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
if (rv < 0x10000 || INVALID_UNICODE_10000_TO_1FFFFF(rv))
|
||||
{
|
||||
rv = UCS_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
}
|
||||
else if (c0 < 0xfc)
|
||||
{
|
||||
/* Valid start character for sequence of length 5
|
||||
* U-00200000 – U-03FFFFFF */
|
||||
rv = (c0 & 0x3);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
|
||||
// These values are currently unsupported
|
||||
rv = UCS_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
|
||||
else if (c0 < 0xfe)
|
||||
{
|
||||
/* Valid start character for sequence of length 6
|
||||
* U-04000000 – U-7FFFFFFF */
|
||||
rv = (c0 & 0x1);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
PARSE_CONTINUATION_CHARACTER(cp, end, rv, finish);
|
||||
|
||||
// These values are currently unsupported
|
||||
rv = UCS_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid characters
|
||||
rv = UCS_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
|
||||
finish:
|
||||
|
||||
if (len_ref)
|
||||
{
|
||||
*len_ref -= ((const char *)cp - *utf8str_ref);
|
||||
}
|
||||
*utf8str_ref = (const char *)cp;
|
||||
|
||||
return rv;
|
||||
#undef PARSE_CONTINUATION_CHARACTER
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
unsigned int
|
||||
utf_char32_to_utf8(char32_t c32, char *u8str)
|
||||
{
|
||||
unsigned int rv;
|
||||
|
||||
if (INVALID_UNICODE(c32))
|
||||
{
|
||||
c32 = UCS_REPLACEMENT_CHARACTER;
|
||||
}
|
||||
|
||||
if (c32 < 0x80)
|
||||
{
|
||||
rv = 1;
|
||||
if (u8str != NULL)
|
||||
{
|
||||
u8str[0] = (char)c32;
|
||||
}
|
||||
}
|
||||
else if (c32 < 0x800)
|
||||
{
|
||||
rv = 2;
|
||||
// 11 bits. Five in first byte, six in second
|
||||
if (u8str != NULL)
|
||||
{
|
||||
u8str[1] = (c32 & 0x3f) | 0x80;
|
||||
c32 >>= 6;
|
||||
u8str[0] = (c32 & 0x1f) | 0xc0;
|
||||
}
|
||||
}
|
||||
else if (c32 < 0xffff)
|
||||
{
|
||||
rv = 3;
|
||||
// 16 bits. Four in first byte, six in second and third
|
||||
if (u8str != NULL)
|
||||
{
|
||||
u8str[2] = (c32 & 0x3f) | 0x80;
|
||||
c32 >>= 6;
|
||||
u8str[1] = (c32 & 0x3f) | 0x80;
|
||||
c32 >>= 6;
|
||||
u8str[0] = (c32 & 0xf) | 0xe0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = 4;
|
||||
// 21 bits. Three in first byte, six in second, third and fourth
|
||||
if (u8str != NULL)
|
||||
{
|
||||
u8str[3] = (c32 & 0x3f) | 0x80;
|
||||
c32 >>= 6;
|
||||
u8str[2] = (c32 & 0x3f) | 0x80;
|
||||
c32 >>= 6;
|
||||
u8str[1] = (c32 & 0x3f) | 0x80;
|
||||
c32 >>= 6;
|
||||
u8str[0] = (c32 & 0x7) | 0xf0;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
unsigned int
|
||||
utf8_char_count(const char *utf8str)
|
||||
{
|
||||
unsigned int rv = 0;
|
||||
char32_t c;
|
||||
|
||||
if (utf8str != NULL)
|
||||
{
|
||||
while ((c = utf8_get_next_char(&utf8str, NULL)) != 0)
|
||||
{
|
||||
++rv;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
unsigned int
|
||||
utf8_as_utf16_word_count(const char *utf8str, unsigned int len)
|
||||
{
|
||||
unsigned int rv = 0;
|
||||
while (len > 0)
|
||||
{
|
||||
char32_t c = utf8_get_next_char(&utf8str, &len);
|
||||
// Characters not in the BMP (i.e. over 0xffff) need a high/low
|
||||
// surrogate pair
|
||||
rv += (c >= 0x10000) ? 2 : 1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
utf8_add_char_at(char *utf8str, unsigned int len, char32_t c32,
|
||||
unsigned int index)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
char c8[MAXLEN_UTF8_CHAR];
|
||||
unsigned int c8len = utf_char32_to_utf8(c32, c8);
|
||||
|
||||
// Find out where to insert the character
|
||||
char *insert_pos = utf8str;
|
||||
|
||||
while (index > 0 && *insert_pos != '\0')
|
||||
{
|
||||
utf8_get_next_char((const char **)&insert_pos, NULL);
|
||||
--index;
|
||||
}
|
||||
|
||||
// Did we get to where we need to be?
|
||||
if (index == 0)
|
||||
{
|
||||
unsigned int bytes_to_move = strlen(insert_pos) + 1; // Include terminator
|
||||
// Is there room to insert the character?
|
||||
//
|
||||
// <----------- len ---------->
|
||||
// <--> (bytes_to_move)
|
||||
// +----------------------------+
|
||||
// |ABCDEFGHIJLMN\0 |
|
||||
// +----------------------------+
|
||||
// ^ ^
|
||||
// +-utf8str +-insert_pos
|
||||
//
|
||||
if ((insert_pos - utf8str) + bytes_to_move + c8len <= len)
|
||||
{
|
||||
memmove(insert_pos + c8len, insert_pos, bytes_to_move);
|
||||
memcpy(insert_pos, c8, c8len);
|
||||
rv = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
char32_t
|
||||
utf8_remove_char_at(char *utf8str, unsigned int index)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
// Find out where to remove the character
|
||||
char *remove_pos = utf8str;
|
||||
|
||||
while (index > 0)
|
||||
{
|
||||
// Any characters left in string?
|
||||
if (*remove_pos == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
utf8_get_next_char((const char **)&remove_pos, NULL);
|
||||
--index;
|
||||
}
|
||||
|
||||
// Did we get to where we need to be?
|
||||
if (index == 0)
|
||||
{
|
||||
// Find the position after the character
|
||||
char *after_pos = remove_pos;
|
||||
rv = utf8_get_next_char((const char **)&after_pos, NULL);
|
||||
|
||||
// Move everything up
|
||||
memmove(remove_pos, after_pos, strlen(after_pos) + 1);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
* Map a character to a string value
|
||||
*
|
||||
* This structure is used by g_format_info_string() to specify the
|
||||
* string which chould be output for %'ch', where ch is a character
|
||||
* string which could be output for %'ch', where ch is a character
|
||||
*/
|
||||
struct info_string_tag
|
||||
{
|
||||
@ -37,6 +37,65 @@ struct info_string_tag
|
||||
|
||||
#define INFO_STRING_END_OF_LIST { '\0', NULL }
|
||||
|
||||
/**
|
||||
* Map a bitmask to a string value
|
||||
*
|
||||
*
|
||||
* This structure is used by g_bitmask_to_str() to specify the
|
||||
* string for each bit in the bitmask
|
||||
*/
|
||||
struct bitmask_string
|
||||
{
|
||||
int mask;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
#define BITMASK_STRING_END_OF_LIST { 0, NULL }
|
||||
|
||||
/**
|
||||
* Map a bitmask to a char value
|
||||
*
|
||||
*
|
||||
* This structure is used by g_bitmask_to_charstr() to specify the
|
||||
* char for each bit in the bitmask
|
||||
*/
|
||||
struct bitmask_char
|
||||
{
|
||||
int mask;
|
||||
char c;
|
||||
};
|
||||
|
||||
#define BITMASK_CHAR_END_OF_LIST { 0, '\0' }
|
||||
|
||||
enum
|
||||
{
|
||||
// See g_sig2text()
|
||||
// Must be able to hold "SIG#%d" for INT_MIN
|
||||
//
|
||||
// ((sizeof(int) * 5 + 1) / 2) provides a very slight overestimate of
|
||||
// the bytes requires to store a decimal expansion of 'int':-
|
||||
// sizeof INT_MAX display bytes ((sizeof(int) * 5 + 1)
|
||||
// (int) needed / 2)
|
||||
// ------ ------- ------------- ---------------------------
|
||||
// 1 127 3 3
|
||||
// 2 32767 5 5
|
||||
// 3 8388607 7 8
|
||||
// 4 2147483637 10 10
|
||||
// 8 9*(10**18) 19 20
|
||||
// 16 2*(10**38) 39 40
|
||||
// 32 6*(10**76) 77 80
|
||||
MAXSTRSIGLEN = (3 + 1 + 1 + ((sizeof(int) * 5 + 1) / 2) + 1)
|
||||
};
|
||||
|
||||
/*
|
||||
* Significant Universal Character Set (Unicode) characters
|
||||
*/
|
||||
enum
|
||||
{
|
||||
UCS_WHITE_SQUARE = 0x25a1,
|
||||
UCS_REPLACEMENT_CHARACTER = 0xfffd
|
||||
};
|
||||
|
||||
/**
|
||||
* Processes a format string for general info
|
||||
*
|
||||
@ -102,7 +161,7 @@ g_text2bool(const char *s);
|
||||
* @param[in] src An array of strings to join. The array must be non-null.
|
||||
* Array items may be NULL and are processed as zero length strings.
|
||||
* @param[in] src_len The number of strings to join in the src array. Must be > 0
|
||||
* @return A pointer to the begining of the joined string (ie. returns dest).
|
||||
* @return A pointer to the beginning of the joined string (ie. returns dest).
|
||||
*/
|
||||
char *
|
||||
g_strnjoin(char *dest, int dest_len, const char *joiner, const char *src[], int src_len);
|
||||
@ -140,8 +199,90 @@ g_bytes_to_hexdump(const char *src, int len);
|
||||
int
|
||||
g_get_display_num_from_display(const char *display_text);
|
||||
|
||||
/**
|
||||
* Converts a bitmask into a string for output purposes
|
||||
*
|
||||
* Similar to g_bitmask_to_charstr(), but tokens are strings, separated
|
||||
* by delimiters.
|
||||
*
|
||||
* @param bitmask Bitmask to convert
|
||||
* @param bitdefs Definitions for strings for bits
|
||||
* @param delim Delimiter to use between strings
|
||||
* @param buff Output buff
|
||||
* @param bufflen Length of buff, including terminator '`\0'
|
||||
*
|
||||
* @return Total length excluding terminator which would be written, as
|
||||
* in snprintf(). Can be used to check for overflow
|
||||
*
|
||||
* @note Any undefined bits in the bitmask are appended to the output as
|
||||
* a hexadecimal constant.
|
||||
*/
|
||||
int
|
||||
g_bitmask_to_str(int bitmask, const struct bitmask_string bitdefs[],
|
||||
char delim, char *buff, int bufflen);
|
||||
|
||||
/***
|
||||
* Converts a string containing a series of tokens to a bitmask.
|
||||
*
|
||||
* Similar to g_charstr_to_bitmask(), but tokens are strings, separated
|
||||
* by delimiters.
|
||||
*
|
||||
* @param str Input string
|
||||
* @param bitdefs Array mapping tokens to bitmask values
|
||||
* @param delim Delimiter for tokens in str
|
||||
* @param[out] unrecognised Buffer for any unrecognised tokens
|
||||
* @param unrecognised_len Length of unrecognised including '\0';
|
||||
* @return bitmask value for recognised tokens
|
||||
*/
|
||||
int
|
||||
g_str_to_bitmask(const char *str, const struct bitmask_string bitdefs[],
|
||||
const char *delim, char *unrecognised,
|
||||
int unrecognised_len);
|
||||
|
||||
/**
|
||||
* Converts a bitmask into a string for output purposes
|
||||
*
|
||||
* Similar to g_bitmask_to_str(), but tokens are individual characters, and
|
||||
* there are no delimiters.
|
||||
*
|
||||
* @param bitmask Bitmask to convert
|
||||
* @param bitdefs Definitions for strings for bits
|
||||
* @param buff Output buff
|
||||
* @param bufflen Length of buff, including terminator '`\0'
|
||||
* @param[out] rest Any unused bits which weren't covered by bitdefs.
|
||||
* May be NULL.
|
||||
*
|
||||
* @return Total length excluding terminator which would be written, as
|
||||
* in snprintf(). Can be used to check for overflow
|
||||
*
|
||||
* @note Any undefined bits in the bitmask are appended to the output as
|
||||
* a hexadecimal constant.
|
||||
*/
|
||||
int
|
||||
g_bitmask_to_charstr(int bitmask, const struct bitmask_char bitdefs[],
|
||||
char *buff, int bufflen, int *rest);
|
||||
|
||||
/***
|
||||
* Converts a string containing a series of characters to a bitmask.
|
||||
*
|
||||
* Similar to g_str_to_bitmask(), but tokens are individual characters, and
|
||||
* there are no delimiters.
|
||||
*
|
||||
* @param str Input string
|
||||
* @param bitdefs Array mapping tokens to bitmask values
|
||||
* @param delim Delimiter for tokens in str
|
||||
* @param[out] unrecognised Buffer for any unrecognised tokens
|
||||
* @param unrecognised_len Length of unrecognised including '\0';
|
||||
* @return bitmask value for recognised tokens
|
||||
*/
|
||||
int
|
||||
g_charstr_to_bitmask(const char *str, const struct bitmask_char bitdefs[],
|
||||
char *unrecognised, int unrecognised_len);
|
||||
|
||||
int g_strlen(const char *text);
|
||||
const char *g_strchr(const char *text, int c);
|
||||
char *g_strchr(const char *text, int c);
|
||||
char *g_strrchr(const char *text, int c);
|
||||
char *g_strnchr(const char *text, int c, int len);
|
||||
char *g_strcpy(char *dest, const char *src);
|
||||
char *g_strncpy(char *dest, const char *src, int len);
|
||||
char *g_strcat(char *dest, const char *src);
|
||||
@ -154,11 +295,112 @@ int g_strncmp_d(const char *c1, const char *c2, const char delim, int len);
|
||||
int g_strcasecmp(const char *c1, const char *c2);
|
||||
int g_strncasecmp(const char *c1, const char *c2, int len);
|
||||
int g_atoi(const char *str);
|
||||
|
||||
/**
|
||||
* Extends g_atoi(), Converts decimal and hexadecimal number String to integer
|
||||
*
|
||||
* Prefix hexadecimal numbers with '0x'
|
||||
*
|
||||
* @param str String to convert to an integer
|
||||
* @return int Integer expression of a string
|
||||
*/
|
||||
int g_atoix(const char *str);
|
||||
int g_htoi(char *str);
|
||||
int g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
|
||||
int bytes_out_str);
|
||||
int g_pos(const char *str, const char *to_find);
|
||||
int g_mbstowcs(twchar *dest, const char *src, int n);
|
||||
int g_wcstombs(char *dest, const twchar *src, int n);
|
||||
char *g_strstr(const char *haystack, const char *needle);
|
||||
|
||||
/** trim spaces and tabs, anything <= space
|
||||
*
|
||||
* @param str (assumed to be UTF-8)
|
||||
* @param trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through
|
||||
* @return != 0 - trim_flags not recognised
|
||||
* this will always shorten the string or not change it */
|
||||
int g_strtrim(char *str, int trim_flags);
|
||||
|
||||
/**
|
||||
* Maps a signal number to a string, i.e. SIGHUP -> "SIGHUP"
|
||||
*
|
||||
* @param signum Signal number
|
||||
* @param sigstr buffer for result
|
||||
* @return sigstr, for convenience
|
||||
*
|
||||
* Buffer is assumed to be at least MAXSTRSIGLEN
|
||||
*
|
||||
* The string "SIG#<num>" is returned for unrecognised signums
|
||||
*/
|
||||
char *g_sig2text(int signum, char sigstr[]);
|
||||
|
||||
/**
|
||||
* Get the next Unicode character from a UTF-8 string
|
||||
*
|
||||
* @param utf8str_ref UTF 8 string [by reference]
|
||||
* @param len_ref Length of string [by reference] or NULL
|
||||
* @return Unicode character
|
||||
*
|
||||
* On return, utf8str and len are updated to point past the decoded character.
|
||||
* Unrecognised characters are mapped to UCS_REPLACEMENT_CHARACTER
|
||||
*
|
||||
* len is not needed if your utf8str has a terminator, or is known to
|
||||
* be well-formed.
|
||||
*/
|
||||
char32_t
|
||||
utf8_get_next_char(const char **utf8str_ref, unsigned int *len_ref);
|
||||
|
||||
/**
|
||||
* Convert a Unicode character to UTF-8
|
||||
* @param c32 Unicode character
|
||||
* @param u8str buffer containing at least MAXLEN_UTF8_CHAR bytes for result
|
||||
* @return Number of bytes written to u8str. Can be NULL if only the
|
||||
* length is needed.
|
||||
*
|
||||
* The bytes written to u8str are unterminated
|
||||
*/
|
||||
#define MAXLEN_UTF8_CHAR 4
|
||||
unsigned int
|
||||
utf_char32_to_utf8(char32_t c32, char *u8str);
|
||||
|
||||
/**
|
||||
* Returns the number of Unicode characters in a UTF-8 string
|
||||
* @param utf8str UTF-8 string
|
||||
* @result Number of Unicode characters in the string (terminator not included)
|
||||
*/
|
||||
unsigned int
|
||||
utf8_char_count(const char *utf8str);
|
||||
|
||||
/**
|
||||
* Returns the number of UTF-16 words required to store a UTF-8 string
|
||||
* @param utf8str UTF-8 string
|
||||
* @param len Length of UTF-8 string
|
||||
* @result number of words to store UTF-8 string as UTF-16.
|
||||
*/
|
||||
unsigned int
|
||||
utf8_as_utf16_word_count(const char *utf8str, unsigned int len);
|
||||
|
||||
/**
|
||||
* Add a Unicode character into a UTF-8 string
|
||||
* @param utf8str Pointer to UTF-8 string
|
||||
* @param len Length of buffer for UTF-8 string (includes NULL)
|
||||
* @param c32 character to add
|
||||
* @param index Where to add the codepoint
|
||||
* @return 1 for success, 0 if no character was inserted
|
||||
*
|
||||
* This routine has to parse the string as it goes, so can be slow.
|
||||
*/
|
||||
int
|
||||
utf8_add_char_at(char *utf8str, unsigned int len, char32_t c32,
|
||||
unsigned int index);
|
||||
|
||||
/**
|
||||
* Remove a Unicode character from a UTF-8 string
|
||||
* @param utf8str Pointer to UTF-8 string
|
||||
* @param index Where to remove the codepoint from (0-based)
|
||||
* @return Character removed, or 0 if no character was removed
|
||||
*
|
||||
* This routine has to parse the string as it goes, so can be slow.
|
||||
*/
|
||||
char32_t
|
||||
utf8_remove_char_at(char *utf8str, unsigned int index);
|
||||
|
||||
#endif
|
||||
|
@ -122,8 +122,11 @@ tc_mutex_delete(tbus mutex)
|
||||
pthread_mutex_t *lmutex;
|
||||
|
||||
lmutex = (pthread_mutex_t *)mutex;
|
||||
pthread_mutex_destroy(lmutex);
|
||||
g_free(lmutex);
|
||||
if (lmutex != NULL)
|
||||
{
|
||||
pthread_mutex_destroy(lmutex);
|
||||
g_free(lmutex);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
333
common/trans.c
333
common/trans.c
@ -32,8 +32,13 @@
|
||||
|
||||
#define MAX_SBYTES 0
|
||||
|
||||
/** Time between polls of is_term when connecting */
|
||||
#define CONNECT_TERM_POLL_MS 3000
|
||||
/** Time we wait before another connect() attempt if one fails immediately */
|
||||
#define CONNECT_DELAY_ON_FAIL_MS 2000
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
static int
|
||||
trans_tls_recv(struct trans *self, char *ptr, int len)
|
||||
{
|
||||
if (self->tls == NULL)
|
||||
@ -44,7 +49,7 @@ trans_tls_recv(struct trans *self, char *ptr, int len)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
static int
|
||||
trans_tls_send(struct trans *self, const char *data, int len)
|
||||
{
|
||||
if (self->tls == NULL)
|
||||
@ -55,7 +60,7 @@ trans_tls_send(struct trans *self, const char *data, int len)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
static int
|
||||
trans_tls_can_recv(struct trans *self, int sck, int millis)
|
||||
{
|
||||
if (self->tls == NULL)
|
||||
@ -66,21 +71,21 @@ trans_tls_can_recv(struct trans *self, int sck, int millis)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
static int
|
||||
trans_tcp_recv(struct trans *self, char *ptr, int len)
|
||||
{
|
||||
return g_tcp_recv(self->sck, ptr, len, 0);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
static int
|
||||
trans_tcp_send(struct trans *self, const char *data, int len)
|
||||
{
|
||||
return g_tcp_send(self->sck, data, len, 0);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
static int
|
||||
trans_tcp_can_recv(struct trans *self, int sck, int millis)
|
||||
{
|
||||
return g_sck_can_recv(sck, millis);
|
||||
@ -96,6 +101,7 @@ trans_create(int mode, int in_size, int out_size)
|
||||
|
||||
if (self != NULL)
|
||||
{
|
||||
self->sck = -1;
|
||||
make_stream(self->in_s);
|
||||
init_stream(self->in_s, in_size);
|
||||
make_stream(self->out_s);
|
||||
@ -120,15 +126,21 @@ trans_delete(struct trans *self)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Call the user-specified destructor if one exists */
|
||||
if (self->extra_destructor != NULL)
|
||||
{
|
||||
self->extra_destructor(self);
|
||||
}
|
||||
|
||||
free_stream(self->in_s);
|
||||
free_stream(self->out_s);
|
||||
|
||||
if (self->sck > 0)
|
||||
if (self->sck >= 0)
|
||||
{
|
||||
g_tcp_close(self->sck);
|
||||
}
|
||||
|
||||
self->sck = 0;
|
||||
self->sck = -1;
|
||||
|
||||
if (self->listen_filename != 0)
|
||||
{
|
||||
@ -179,13 +191,9 @@ trans_get_wait_objs(struct trans *self, tbus *objs, int *count)
|
||||
objs[*count] = self->sck;
|
||||
(*count)++;
|
||||
|
||||
if (self->tls != 0)
|
||||
if (self->tls != NULL && (objs[*count] = ssl_get_rwo(self->tls)) != 0)
|
||||
{
|
||||
if (self->tls->rwo != 0)
|
||||
{
|
||||
objs[*count] = self->tls->rwo;
|
||||
(*count)++;
|
||||
}
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -227,7 +235,7 @@ trans_get_wait_objs_rw(struct trans *self, tbus *robjs, int *rcount,
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
static int
|
||||
trans_send_waiting(struct trans *self, int block)
|
||||
{
|
||||
struct stream *temp_s;
|
||||
@ -301,8 +309,8 @@ trans_check_wait_objs(struct trans *self)
|
||||
tbus in_sck = (tbus) 0;
|
||||
struct trans *in_trans = (struct trans *) NULL;
|
||||
int read_bytes = 0;
|
||||
int to_read = 0;
|
||||
int read_so_far = 0;
|
||||
unsigned int to_read = 0;
|
||||
unsigned int read_so_far = 0;
|
||||
int rv = 0;
|
||||
enum xrdp_source cur_source;
|
||||
|
||||
@ -322,9 +330,7 @@ trans_check_wait_objs(struct trans *self)
|
||||
{
|
||||
if (g_sck_can_recv(self->sck, 0))
|
||||
{
|
||||
in_sck = g_sck_accept(self->sck, self->addr, sizeof(self->addr),
|
||||
self->port, sizeof(self->port));
|
||||
|
||||
in_sck = g_sck_accept(self->sck);
|
||||
if (in_sck == -1)
|
||||
{
|
||||
if (g_tcp_last_error_would_block(self->sck))
|
||||
@ -349,10 +355,7 @@ trans_check_wait_objs(struct trans *self)
|
||||
in_trans->type1 = TRANS_TYPE_SERVER;
|
||||
in_trans->status = TRANS_STATUS_UP;
|
||||
in_trans->is_term = self->is_term;
|
||||
g_strncpy(in_trans->addr, self->addr,
|
||||
sizeof(self->addr) - 1);
|
||||
g_strncpy(in_trans->port, self->port,
|
||||
sizeof(self->port) - 1);
|
||||
g_file_set_cloexec(in_sck, 1);
|
||||
g_sck_set_non_blocking(in_sck);
|
||||
if (self->trans_conn_in(self, in_trans) != 0)
|
||||
{
|
||||
@ -373,13 +376,24 @@ trans_check_wait_objs(struct trans *self)
|
||||
}
|
||||
else if (self->trans_can_recv(self, self->sck, 0))
|
||||
{
|
||||
/* CVE-2022-23479 - check a malicious caller hasn't managed
|
||||
* to set the header_size to an unreasonable value */
|
||||
if (self->header_size > (unsigned int)self->in_s->size)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"trans_check_wait_objs: Reading %u bytes beyond buffer",
|
||||
self->header_size - (unsigned int)self->in_s->size);
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
cur_source = XRDP_SOURCE_NONE;
|
||||
if (self->si != 0)
|
||||
{
|
||||
cur_source = self->si->cur_source;
|
||||
self->si->cur_source = self->my_source;
|
||||
}
|
||||
read_so_far = (int) (self->in_s->end - self->in_s->data);
|
||||
read_so_far = self->in_s->end - self->in_s->data;
|
||||
to_read = self->header_size - read_so_far;
|
||||
|
||||
if (to_read > 0)
|
||||
@ -419,7 +433,7 @@ trans_check_wait_objs(struct trans *self)
|
||||
}
|
||||
}
|
||||
|
||||
read_so_far = (int) (self->in_s->end - self->in_s->data);
|
||||
read_so_far = self->in_s->end - self->in_s->data;
|
||||
|
||||
if (read_so_far == self->header_size)
|
||||
{
|
||||
@ -669,143 +683,183 @@ trans_write_copy(struct trans *self)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Shim to apply the function signature of g_tcp_connect()
|
||||
* to g_tcp_local_connect()
|
||||
*/
|
||||
static int
|
||||
local_connect_shim(int fd, const char *server, const char *port)
|
||||
{
|
||||
return g_tcp_local_connect(fd, port);
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Waits for an asynchronous connect to complete.
|
||||
* @param self - Transport object
|
||||
* @param start_time Start time of connect (from g_time3())
|
||||
* @param timeout Total wait timeout
|
||||
* @return 0 - connect succeeded, 1 - Connect failed
|
||||
*
|
||||
* If the transport is set up for checking a termination object, this
|
||||
* on a regular basis.
|
||||
*/
|
||||
static int
|
||||
poll_for_async_connect(struct trans *self, int start_time, int timeout)
|
||||
{
|
||||
int rv = 1;
|
||||
int ms_remaining = timeout - (g_time3() - start_time);
|
||||
|
||||
while (ms_remaining > 0)
|
||||
{
|
||||
int poll_time = ms_remaining;
|
||||
/* Lower bound for waiting for a result */
|
||||
if (poll_time < 100)
|
||||
{
|
||||
poll_time = 100;
|
||||
}
|
||||
/* Limit the wait time if we need to poll for termination */
|
||||
if (self->is_term != NULL && poll_time > CONNECT_TERM_POLL_MS)
|
||||
{
|
||||
poll_time = CONNECT_TERM_POLL_MS;
|
||||
}
|
||||
|
||||
if (g_tcp_can_send(self->sck, poll_time))
|
||||
{
|
||||
/* Connect has finished - return the socket status */
|
||||
rv = g_sck_socket_ok(self->sck) ? 0 : 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for program termination */
|
||||
if (self->is_term != NULL && self->is_term())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ms_remaining = timeout - (g_time3() - start_time);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
trans_connect(struct trans *self, const char *server, const char *port,
|
||||
int timeout)
|
||||
{
|
||||
int start_time = g_time3();
|
||||
int error;
|
||||
int now;
|
||||
int start_time;
|
||||
int ms_before_next_connect;
|
||||
|
||||
start_time = g_time3();
|
||||
/*
|
||||
* Function pointers which we use in the main loop to avoid
|
||||
* having to switch on the socket mode */
|
||||
int (*f_alloc_socket)(void);
|
||||
int (*f_connect)(int fd, const char *server, const char *port);
|
||||
|
||||
if (self->sck != 0)
|
||||
switch (self->mode)
|
||||
{
|
||||
g_tcp_close(self->sck);
|
||||
self->sck = 0;
|
||||
case TRANS_MODE_TCP:
|
||||
f_alloc_socket = g_tcp_socket;
|
||||
f_connect = g_tcp_connect;
|
||||
break;
|
||||
|
||||
case TRANS_MODE_UNIX:
|
||||
f_alloc_socket = g_tcp_local_socket;
|
||||
f_connect = local_connect_shim;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(LOG_LEVEL_ERROR, "Bad socket mode %d", self->mode);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (self->mode == TRANS_MODE_TCP) /* tcp */
|
||||
while (1)
|
||||
{
|
||||
self->sck = g_tcp_socket();
|
||||
/* Check the program isn't terminating */
|
||||
if (self->is_term != NULL && self->is_term())
|
||||
{
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Allocate a new socket */
|
||||
if (self->sck >= 0)
|
||||
{
|
||||
g_tcp_close(self->sck);
|
||||
}
|
||||
self->sck = f_alloc_socket();
|
||||
|
||||
if (self->sck < 0)
|
||||
{
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Try to connect asynchronously */
|
||||
g_file_set_cloexec(self->sck, 1);
|
||||
g_tcp_set_non_blocking(self->sck);
|
||||
while (1)
|
||||
error = f_connect(self->sck, server, port);
|
||||
if (error == 0)
|
||||
{
|
||||
error = g_tcp_connect(self->sck, server, port);
|
||||
if (error == 0)
|
||||
/* Connect was immediately successful */
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_tcp_last_error_would_block(self->sck))
|
||||
{
|
||||
/* Async connect is in progress */
|
||||
if (poll_for_async_connect(self, start_time, timeout) == 0)
|
||||
{
|
||||
/* Async connect was successful */
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* No need to wait any more before the next connect attempt */
|
||||
ms_before_next_connect = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Connect failed immediately. Wait a bit before the next
|
||||
* attempt */
|
||||
ms_before_next_connect = CONNECT_DELAY_ON_FAIL_MS;
|
||||
}
|
||||
|
||||
/* Have we reached the total timeout yet? */
|
||||
int ms_left = timeout - (g_time3() - start_time);
|
||||
if (ms_left <= 0)
|
||||
{
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sleep a bit before trying again */
|
||||
if (ms_before_next_connect > 0)
|
||||
{
|
||||
if (ms_before_next_connect > ms_left)
|
||||
{
|
||||
if (timeout < 1)
|
||||
{
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
}
|
||||
now = g_time3();
|
||||
if (now - start_time < timeout)
|
||||
{
|
||||
g_sleep(100);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
}
|
||||
if (self->is_term != NULL)
|
||||
{
|
||||
if (self->is_term())
|
||||
{
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
ms_before_next_connect = ms_left;
|
||||
}
|
||||
g_sleep(ms_before_next_connect);
|
||||
}
|
||||
}
|
||||
else if (self->mode == TRANS_MODE_UNIX) /* unix socket */
|
||||
|
||||
if (error != 0)
|
||||
{
|
||||
self->sck = g_tcp_local_socket();
|
||||
if (self->sck < 0)
|
||||
if (self->sck >= 0)
|
||||
{
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
}
|
||||
g_tcp_set_non_blocking(self->sck);
|
||||
while (1)
|
||||
{
|
||||
error = g_tcp_local_connect(self->sck, port);
|
||||
if (error == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (timeout < 1)
|
||||
{
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
}
|
||||
now = g_time3();
|
||||
if (now - start_time < timeout)
|
||||
{
|
||||
g_sleep(100);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
}
|
||||
if (self->is_term != NULL)
|
||||
{
|
||||
if (self->is_term())
|
||||
{
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_tcp_close(self->sck);
|
||||
self->sck = -1;
|
||||
}
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->status = TRANS_STATUS_DOWN;
|
||||
return 1;
|
||||
self->status = TRANS_STATUS_UP; /* ok */
|
||||
self->type1 = TRANS_TYPE_CLIENT; /* client */
|
||||
}
|
||||
|
||||
if (error == -1)
|
||||
{
|
||||
if (g_tcp_last_error_would_block(self->sck))
|
||||
{
|
||||
now = g_time3();
|
||||
if (now - start_time < timeout)
|
||||
{
|
||||
timeout = timeout - (now - start_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
timeout = 0;
|
||||
}
|
||||
if (g_tcp_can_send(self->sck, timeout))
|
||||
{
|
||||
self->status = TRANS_STATUS_UP; /* ok */
|
||||
self->type1 = TRANS_TYPE_CLIENT; /* client */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
self->status = TRANS_STATUS_UP; /* ok */
|
||||
self->type1 = TRANS_TYPE_CLIENT; /* client */
|
||||
return 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -814,9 +868,9 @@ trans_connect(struct trans *self, const char *server, const char *port,
|
||||
* @return 0 on success, 1 on failure
|
||||
*/
|
||||
int
|
||||
trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
trans_listen_address(struct trans *self, const char *port, const char *address)
|
||||
{
|
||||
if (self->sck != 0)
|
||||
if (self->sck >= 0)
|
||||
{
|
||||
g_tcp_close(self->sck);
|
||||
}
|
||||
@ -829,6 +883,7 @@ trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_file_set_cloexec(self->sck, 1);
|
||||
g_tcp_set_non_blocking(self->sck);
|
||||
|
||||
if (g_tcp_bind_address(self->sck, port, address) == 0)
|
||||
@ -853,6 +908,7 @@ trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_file_set_cloexec(self->sck, 1);
|
||||
g_tcp_set_non_blocking(self->sck);
|
||||
|
||||
if (g_tcp_local_bind(self->sck, port) == 0)
|
||||
@ -876,6 +932,7 @@ trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_file_set_cloexec(self->sck, 1);
|
||||
g_tcp_set_non_blocking(self->sck);
|
||||
|
||||
if (g_sck_vsock_bind_address(self->sck, port, address) == 0)
|
||||
@ -895,6 +952,7 @@ trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
g_file_set_cloexec(self->sck, 1);
|
||||
g_tcp_set_non_blocking(self->sck);
|
||||
if (g_tcp4_bind_address(self->sck, port, address) == 0)
|
||||
{
|
||||
@ -913,6 +971,7 @@ trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
g_file_set_cloexec(self->sck, 1);
|
||||
g_tcp_set_non_blocking(self->sck);
|
||||
if (g_tcp6_bind_address(self->sck, port, address) == 0)
|
||||
{
|
||||
@ -929,7 +988,7 @@ trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
trans_listen(struct trans *self, char *port)
|
||||
trans_listen(struct trans *self, const char *port)
|
||||
{
|
||||
return trans_listen_address(self, port, "0.0.0.0");
|
||||
}
|
||||
@ -995,8 +1054,8 @@ trans_set_tls_mode(struct trans *self, const char *key, const char *cert,
|
||||
self->trans_send = trans_tls_send;
|
||||
self->trans_can_recv = trans_tls_can_recv;
|
||||
|
||||
self->ssl_protocol = ssl_get_version(self->tls->ssl);
|
||||
self->cipher_name = ssl_get_cipher_name(self->tls->ssl);
|
||||
self->ssl_protocol = ssl_get_version(self->tls);
|
||||
self->cipher_name = ssl_get_cipher_name(self->tls);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ enum xrdp_source
|
||||
* While input is being read from a 'struct trans' and processed, the
|
||||
* cur_source member is set to the my_source member from the transport.
|
||||
* During this processing, trans_write_copy() may be called to send output
|
||||
* on another struct trans. If this happens, and the ouput needs to be
|
||||
* on another struct trans. If this happens, and the output needs to be
|
||||
* buffered, trans_write_copy() can add the number of bytes generated by
|
||||
* the input trans to the source field for the cur_source. This allows us to
|
||||
* see how much output has been buffered for each input source.
|
||||
@ -98,16 +98,17 @@ struct trans
|
||||
ttrans_data_in trans_data_in;
|
||||
ttrans_conn_in trans_conn_in;
|
||||
void *callback_data;
|
||||
int header_size;
|
||||
unsigned int header_size;
|
||||
struct stream *in_s;
|
||||
struct stream *out_s;
|
||||
char *listen_filename;
|
||||
tis_term is_term; /* used to test for exit */
|
||||
struct stream *wait_s;
|
||||
char addr[256];
|
||||
char port[256];
|
||||
int no_stream_init_on_data_in;
|
||||
int extra_flags; /* user defined */
|
||||
void *extra_data; /* user defined */
|
||||
void (*extra_destructor)(struct trans *); /* user defined */
|
||||
|
||||
struct ssl_tls *tls;
|
||||
const char *ssl_protocol; /* e.g. TLSv1, TLSv1.1, TLSv1.2, unknown */
|
||||
const char *cipher_name; /* e.g. AES256-GCM-SHA384 */
|
||||
@ -144,13 +145,27 @@ int
|
||||
trans_write_copy(struct trans *self);
|
||||
int
|
||||
trans_write_copy_s(struct trans *self, struct stream *out_s);
|
||||
/**
|
||||
* Connect the transport to the specified destination
|
||||
*
|
||||
* @param self Transport
|
||||
* @param server Destination server (TCP transports only)
|
||||
* @param port TCP port, or UNIX socket to connect to
|
||||
* @param timeout in milli-seconds for the operation
|
||||
* @return 0 for success
|
||||
*
|
||||
* Multiple connection attempts may be made within the timeout period.
|
||||
*
|
||||
* If the operation is successful, 0 is returned and self->status will
|
||||
* be TRANS_STATUS_UP
|
||||
*/
|
||||
int
|
||||
trans_connect(struct trans *self, const char *server, const char *port,
|
||||
int timeout);
|
||||
int
|
||||
trans_listen_address(struct trans *self, char *port, const char *address);
|
||||
trans_listen_address(struct trans *self, const char *port, const char *address);
|
||||
int
|
||||
trans_listen(struct trans *self, char *port);
|
||||
trans_listen(struct trans *self, const char *port);
|
||||
struct stream *
|
||||
trans_get_in_s(struct trans *self);
|
||||
struct stream *
|
||||
|
100
common/unicode_defines.h
Normal file
100
common/unicode_defines.h
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2004-2023
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/**
|
||||
* @file common/unicode_defines.h
|
||||
*
|
||||
* Defines used internally by the implementations of the Unicode routines
|
||||
*/
|
||||
|
||||
#if !defined(UNICODE_DEFINES_H)
|
||||
#define UNICODE_DEFINES_H
|
||||
|
||||
/**
|
||||
* Is this byte a valid UTF-8 continuation character?
|
||||
*/
|
||||
#define IS_VALID_CONTINUATION_CHAR(c) ((c) >= 0x80 && (c) < 0xc0)
|
||||
|
||||
/**
|
||||
* Is this character one of the end-of-plane non-characters?
|
||||
*
|
||||
* These are U+xFFFE and U+xFFFF for x in (0..10}
|
||||
*/
|
||||
#define IS_PLANE_END_NON_CHARACTER(c32) (((c32) & 0xfffe) == 0xfffe)
|
||||
|
||||
/**
|
||||
* Is this character one of the additional non-characters?
|
||||
*
|
||||
* 32 additional non-charactersare defined in the
|
||||
* "Arabic Presentation Forms-A" Unicode block */
|
||||
#define IS_ARABIC_NON_CHARACTER(c32) ((c32) >= 0xfdd0 && (c32) <= 0xfdef)
|
||||
|
||||
// Invalid characters, based on UTF-8 decoding range
|
||||
//
|
||||
// By 'invalid' we mean characters that should not be encoded or
|
||||
// decoded when switching between UTF-8 and UTF-32
|
||||
//
|
||||
// See "UTF-8 decoder capability and stress test" Markus Kuhn 2015-08-28
|
||||
#define INVALID_UNICODE_0_TO_7F(c) (0) // No invalid characters
|
||||
#define INVALID_UNICODE_80_TO_7FF(c) (0) // No invalid characters
|
||||
#define INVALID_UNICODE_800_TO_FFFF(c) \
|
||||
(((c) >= 0xd800 && (c) <= 0xdfff) || /* Surrogate pairs */ \
|
||||
IS_ARABIC_NON_CHARACTER(c) || \
|
||||
IS_PLANE_END_NON_CHARACTER(c))
|
||||
|
||||
#define INVALID_UNICODE_10000_TO_1FFFFF(c) \
|
||||
(IS_PLANE_END_NON_CHARACTER(c) || (c) > 0x10ffff)
|
||||
|
||||
// Returns true for all 'invalid' Unicode chars
|
||||
#define INVALID_UNICODE(c) \
|
||||
( \
|
||||
INVALID_UNICODE_0_TO_7F(c) || \
|
||||
INVALID_UNICODE_80_TO_7FF(c) || \
|
||||
INVALID_UNICODE_800_TO_FFFF(c) || \
|
||||
INVALID_UNICODE_10000_TO_1FFFFF(c) \
|
||||
)
|
||||
|
||||
/**
|
||||
* Is this character a UTF-16 high surrogate?
|
||||
*/
|
||||
#define IS_HIGH_SURROGATE(u16) (((u16) & 0xfc00) == 0xd800)
|
||||
|
||||
/**
|
||||
* Is this character a UTF-16 low surrogate?
|
||||
*/
|
||||
#define IS_LOW_SURROGATE(u16) (((u16) & 0xfc00) == 0xdc00)
|
||||
|
||||
/**
|
||||
* Extract the UTF-16 high surrogate from a character
|
||||
*/
|
||||
#define HIGH_SURROGATE_FROM_C32(c32) \
|
||||
(((((c32) - 0x10000) >> 10) & 0x3ff) | 0xd800)
|
||||
|
||||
/**
|
||||
* Extract the UTF-16 low surrogate from a character
|
||||
*/
|
||||
#define LOW_SURROGATE_FROM_C32(c32) (((c32) & 0x3ff) | 0xdc00)
|
||||
|
||||
/**
|
||||
* Reconstruct a character from a UTF-16 surrogate pair
|
||||
*
|
||||
* This macro cannot return values higher than 0x10ffff
|
||||
*/
|
||||
#define C32_FROM_SURROGATE_PAIR(low,high) \
|
||||
((char32_t)(((high) & 0x3ff) << 10) + ((low) & 0x3ff) + 0x10000)
|
||||
|
||||
#endif // UNICODE_DEFINES_H
|
@ -24,15 +24,75 @@
|
||||
#if !defined(XRDP_CLIENT_INFO_H)
|
||||
#define XRDP_CLIENT_INFO_H
|
||||
|
||||
/*
|
||||
* 2.2.1.3.6.1 Monitor Definition (TS_MONITOR_DEF)
|
||||
* 2.2.1.3.9.1 Monitor Attributes (TS_MONITOR_ATTRIBUTES)
|
||||
* 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT
|
||||
*/
|
||||
struct monitor_info
|
||||
{
|
||||
/* From 2.2.1.3.6.1 Monitor Definition (TS_MONITOR_DEF) */
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
int bottom;
|
||||
int is_primary;
|
||||
int flags;
|
||||
|
||||
/* From [MS-RDPEDISP] 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT, or
|
||||
* [MS-RDPBCGR] 2.2.1.3.9.1 (TS_MONITOR_ATTRIBUTES) */
|
||||
unsigned int physical_width;
|
||||
unsigned int physical_height;
|
||||
unsigned int orientation;
|
||||
unsigned int desktop_scale_factor;
|
||||
unsigned int device_scale_factor;
|
||||
|
||||
/* Derived setting */
|
||||
unsigned int is_primary;
|
||||
};
|
||||
|
||||
/* xrdp keyboard overrids */
|
||||
struct xrdp_keyboard_overrides
|
||||
{
|
||||
int type;
|
||||
int subtype;
|
||||
int layout;
|
||||
};
|
||||
|
||||
struct display_size_description
|
||||
{
|
||||
unsigned int monitorCount; /* 2.2.2.2 DISPLAYCONTROL_MONITOR_LAYOUT_PDU: number of monitors detected (max = 16) */
|
||||
struct monitor_info minfo[CLIENT_MONITOR_DATA_MAXIMUM_MONITORS]; /* client monitor data */
|
||||
struct monitor_info minfo_wm[CLIENT_MONITOR_DATA_MAXIMUM_MONITORS]; /* client monitor data, non-negative values */
|
||||
unsigned int session_width;
|
||||
unsigned int session_height;
|
||||
};
|
||||
|
||||
enum client_resize_mode
|
||||
{
|
||||
CRMODE_NONE,
|
||||
CRMODE_SINGLE_SCREEN,
|
||||
CRMODE_MULTI_SCREEN
|
||||
};
|
||||
|
||||
enum xrdp_capture_code
|
||||
{
|
||||
CC_SIMPLE = 0,
|
||||
CC_SUF_A16 = 1,
|
||||
CC_SUF_RFX = 2,
|
||||
CC_SUF_A2 = 3,
|
||||
CC_GFX_PRO = 4,
|
||||
CC_GFX_A2 = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* Type describing Unicode input state
|
||||
*/
|
||||
enum unicode_input_state
|
||||
{
|
||||
UIS_UNSUPPORTED = 0, ///< Client does not support Unicode
|
||||
UIS_SUPPORTED, ///< Client supports Unicode, but it's not active
|
||||
UIS_ACTIVE ///< Unicode input is active
|
||||
};
|
||||
/**
|
||||
* Information about the xrdp client
|
||||
*
|
||||
@ -46,8 +106,6 @@ struct xrdp_client_info
|
||||
int size; /* bytes for this structure */
|
||||
int version; /* Should be CLIENT_INFO_CURRENT_VERSION */
|
||||
int bpp;
|
||||
int width;
|
||||
int height;
|
||||
/* bitmap cache info */
|
||||
int cache1_entries;
|
||||
int cache1_size;
|
||||
@ -83,7 +141,7 @@ struct xrdp_client_info
|
||||
int rdp5_performanceflags;
|
||||
int brush_cache_code; /* 0 = no cache 1 = 8x8 standard cache
|
||||
2 = arbitrary dimensions */
|
||||
char client_ip[256];
|
||||
|
||||
int max_bpp;
|
||||
int jpeg; /* non standard bitmap cache v2 cap */
|
||||
int offscreen_support_level;
|
||||
@ -115,14 +173,10 @@ struct xrdp_client_info
|
||||
int pointer_flags; /* 0 color, 1 new, 2 no new */
|
||||
int use_fast_path;
|
||||
int require_credentials; /* when true, credentials *must* be passed on cmd line */
|
||||
char client_addr[256];
|
||||
char client_port[256];
|
||||
|
||||
int security_layer; /* 0 = rdp, 1 = tls , 2 = hybrid */
|
||||
int multimon; /* 0 = deny , 1 = allow */
|
||||
int monitorCount; /* number of monitors detected (max = 16) */
|
||||
struct monitor_info minfo[CLIENT_MONITOR_DATA_MAXIMUM_MONITORS]; /* client monitor data */
|
||||
struct monitor_info minfo_wm[CLIENT_MONITOR_DATA_MAXIMUM_MONITORS]; /* client monitor data, non-negative values */
|
||||
struct display_size_description display_sizes;
|
||||
|
||||
int keyboard_type;
|
||||
int keyboard_subtype;
|
||||
@ -135,7 +189,7 @@ struct xrdp_client_info
|
||||
int mcs_early_capability_flags;
|
||||
|
||||
int max_fastpath_frag_bytes;
|
||||
int capture_code;
|
||||
int pad0; /* unused */
|
||||
int capture_format;
|
||||
|
||||
char certificate[1024];
|
||||
@ -146,6 +200,11 @@ struct xrdp_client_info
|
||||
char layout[16];
|
||||
char variant[16];
|
||||
char options[256];
|
||||
char xkb_rules[32];
|
||||
// A few x11 keycodes are needed by the xup module
|
||||
int x11_keycode_caps_lock;
|
||||
int x11_keycode_num_lock;
|
||||
int x11_keycode_scroll_lock;
|
||||
|
||||
/* ==================================================================== */
|
||||
/* Private to xrdp below this line */
|
||||
@ -162,19 +221,59 @@ struct xrdp_client_info
|
||||
long ssl_protocols;
|
||||
char *tls_ciphers;
|
||||
|
||||
char client_ip[MAX_PEER_ADDRSTRLEN];
|
||||
char client_description[MAX_PEER_DESCSTRLEN];
|
||||
|
||||
int client_os_major;
|
||||
int client_os_minor;
|
||||
|
||||
int no_orders_supported;
|
||||
int use_cache_glyph_v2;
|
||||
int rail_enable;
|
||||
int suppress_output;
|
||||
// Mask of reasons why output may be suppressed
|
||||
// (see enum suppress_output_reason)
|
||||
unsigned int suppress_output_mask;
|
||||
|
||||
int enable_token_login;
|
||||
char domain_user_separator[16];
|
||||
|
||||
/* xrdp.override_* values */
|
||||
struct xrdp_keyboard_overrides xrdp_keyboard_overrides;
|
||||
|
||||
/* These values are optionally send over as part of TS_UD_CS_CORE.
|
||||
* They can be used as a fallback for a single monitor session
|
||||
* if physical sizes are not available in the monitor-specific
|
||||
* data */
|
||||
unsigned int session_physical_width; /* in mm */
|
||||
unsigned int session_physical_height; /* in mm */
|
||||
|
||||
int large_pointer_support_flags;
|
||||
int gfx;
|
||||
|
||||
// Can we resize the desktop by using a Deactivation-Reactivation Sequence?
|
||||
enum client_resize_mode client_resize_mode;
|
||||
|
||||
enum unicode_input_state unicode_input_support;
|
||||
enum xrdp_capture_code capture_code;
|
||||
};
|
||||
|
||||
enum xrdp_encoder_flags
|
||||
{
|
||||
NONE = 0,
|
||||
ENCODE_COMPLETE = 1 << 0,
|
||||
GFX_PROGRESSIVE_RFX = 1 << 1,
|
||||
GFX_H264 = 1 << 2,
|
||||
KEY_FRAME_REQUESTED = 1 << 3
|
||||
};
|
||||
|
||||
/*
|
||||
* Return true if output is suppressed for a particular reason
|
||||
*/
|
||||
#define OUTPUT_SUPPRESSED_FOR_REASON(ci,reason) \
|
||||
(((ci)->suppress_output_mask & (unsigned int)reason) != 0)
|
||||
|
||||
/* yyyymmdd of last incompatible change to xrdp_client_info */
|
||||
#define CLIENT_INFO_CURRENT_VERSION 20210225
|
||||
/* also used for changes to all the xrdp installed headers */
|
||||
#define CLIENT_INFO_CURRENT_VERSION 20240805
|
||||
|
||||
#endif
|
||||
|
@ -29,7 +29,7 @@
|
||||
*
|
||||
* xrdp constants
|
||||
*
|
||||
* Constants defined in publically available Microsoft documents are not
|
||||
* Constants defined in publicly available Microsoft documents are not
|
||||
* stored here, but are stored in the include files ms-*.h, where the name
|
||||
* of the file is the name of the document defining the constant.
|
||||
*
|
||||
@ -37,7 +37,22 @@
|
||||
* ms-erref.h
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Size of buffer including terminator for an IP address as returned
|
||||
* by g_sck_get_peer_ip_address(). See POSIX INET6_ADDRSTRLEN
|
||||
*/
|
||||
#define MAX_PEER_ADDRSTRLEN 46
|
||||
|
||||
/**
|
||||
* Size of buffer including terminator for a socket description, as
|
||||
* returned by g_sck_get_peer_description()
|
||||
* Currently the largest is an IPv6 address (INET6_ADDRSTRLEN), plus
|
||||
* []:<port> characters
|
||||
*/
|
||||
#define MAX_PEER_DESCSTRLEN (46 + 2 + 1 + 5)
|
||||
|
||||
#define INFO_CLIENT_NAME_BYTES 32
|
||||
|
||||
/**
|
||||
* Maximum length of a string including the mandatory null terminator
|
||||
* [MS-RDPBCGR] TS_INFO_PACKET(2.2.1.11.1.1)
|
||||
@ -48,9 +63,6 @@
|
||||
#define XRDP_MAX_BITMAP_CACHE_IDX 2000
|
||||
#define XRDP_BITMAP_CACHE_ENTRIES 2048
|
||||
|
||||
#define XR_MIN_KEY_CODE 8
|
||||
#define XR_MAX_KEY_CODE 256
|
||||
|
||||
/*
|
||||
* Constants come from ITU-T Recommendations
|
||||
*/
|
||||
@ -232,10 +244,17 @@
|
||||
#define BUTTON_STATE_UP 0
|
||||
#define BUTTON_STATE_DOWN 1
|
||||
|
||||
/* touch gestures */
|
||||
#define TOUCH_TWO_FINGERS_DOWN 0
|
||||
#define TOUCH_TWO_FINGERS_UP 1
|
||||
#define TOUCH_TWO_FINGERS_LEFT 2
|
||||
#define TOUCH_TWO_FINGERS_RIGHT 3
|
||||
|
||||
/* messages */
|
||||
#define WM_PAINT 3
|
||||
#define WM_KEYDOWN 15
|
||||
#define WM_KEYUP 16
|
||||
#define WM_KEYBRD_SYNC 17
|
||||
#define WM_MOUSEMOVE 100
|
||||
#define WM_LBUTTONUP 101
|
||||
#define WM_LBUTTONDOWN 102
|
||||
@ -255,13 +274,61 @@
|
||||
#define WM_BUTTON8DOWN 116
|
||||
#define WM_BUTTON9UP 117
|
||||
#define WM_BUTTON9DOWN 118
|
||||
|
||||
#define WM_TOUCH_VSCROLL 140
|
||||
#define WM_TOUCH_HSCROLL 141
|
||||
|
||||
#define WM_INVALIDATE 200
|
||||
#define WM_CHANNEL_DATA 201
|
||||
|
||||
#define CB_ITEMCHANGE 300
|
||||
|
||||
#define FASTPATH_MAX_PACKET_SIZE 0x3fff
|
||||
|
||||
#define XR_RDP_SCAN_LSHIFT 42
|
||||
#define XR_RDP_SCAN_ALT 56
|
||||
// Since we're not guaranteed to have pixman, copy these directives.
|
||||
#define XRDP_PIXMAN_TYPE_ARGB 2
|
||||
#define XRDP_PIXMAN_TYPE_ABGR 3
|
||||
#define XRDP_PIXMAN_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \
|
||||
((type) << 16) | \
|
||||
((a) << 12) | \
|
||||
((r) << 8) | \
|
||||
((g) << 4) | \
|
||||
((b)))
|
||||
|
||||
#define XRDP_a8b8g8r8 \
|
||||
XRDP_PIXMAN_FORMAT(32, XRDP_PIXMAN_TYPE_ABGR, 8, 8, 8, 8)
|
||||
|
||||
#define XRDP_a8r8g8b8 \
|
||||
XRDP_PIXMAN_FORMAT(32, XRDP_PIXMAN_TYPE_ARGB, 8, 8, 8, 8)
|
||||
|
||||
#define XRDP_r5g6b5 \
|
||||
XRDP_PIXMAN_FORMAT(16, XRDP_PIXMAN_TYPE_ARGB, 0, 5, 6, 5)
|
||||
|
||||
#define XRDP_a1r5g5b5 \
|
||||
XRDP_PIXMAN_FORMAT(16, XRDP_PIXMAN_TYPE_ARGB, 1, 5, 5, 5)
|
||||
|
||||
#define XRDP_r3g3b2 \
|
||||
XRDP_PIXMAN_FORMAT(8, XRDP_PIXMAN_TYPE_ARGB, 0, 3, 3, 2)
|
||||
|
||||
// The last used constant in pixman is 63, so use 64+
|
||||
#define XRDP_nv12 \
|
||||
XRDP_PIXMAN_FORMAT(12, 64, 0, 0, 0, 0)
|
||||
|
||||
#define XRDP_i420 \
|
||||
XRDP_PIXMAN_FORMAT(12, 65, 0, 0, 0, 0)
|
||||
|
||||
#define XRDP_nv12_709fr \
|
||||
XRDP_PIXMAN_FORMAT(12, 66, 0, 0, 0, 0)
|
||||
|
||||
#define XRDP_yuv444_709fr \
|
||||
XRDP_PIXMAN_FORMAT(32, 67, 0, 0, 0, 0)
|
||||
|
||||
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpegfx/8131c1bc-1af8-4907-a05a-f72f4581160f
|
||||
#define XRDP_yuv444_v1_stream_709fr \
|
||||
XRDP_PIXMAN_FORMAT(32, 68, 0, 0, 0, 0)
|
||||
|
||||
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpegfx/781406c3-5e24-4f2b-b6ff-42b76bf64f6d
|
||||
#define XRDP_yuv444_v2_stream_709fr \
|
||||
XRDP_PIXMAN_FORMAT(32, 69, 0, 0, 0, 0)
|
||||
|
||||
#endif
|
||||
|
88
common/xrdp_scancode_defs.h
Normal file
88
common/xrdp_scancode_defs.h
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Copyright (C) 2024 Matt Burt, all xrdp contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file common/xrdp_scancode_defs.h
|
||||
* @brief Scancode global definitions, shared with xorgxrdp
|
||||
*/
|
||||
|
||||
#if !defined(XRDP_SCANCODE_DEFS_H)
|
||||
#define XRDP_SCANCODE_DEFS_H
|
||||
|
||||
enum
|
||||
{
|
||||
/**
|
||||
* Scancodes for keys received from the RDP client
|
||||
*/
|
||||
SCANCODE_LSHIFT_KEY = 0x2a,
|
||||
SCANCODE_RSHIFT_KEY = 0x36,
|
||||
SCANCODE_LCTRL_KEY = 0x1d,
|
||||
SCANCODE_RCTRL_KEY = 0x11d,
|
||||
SCANCODE_CAPS_KEY = 0x3a,
|
||||
SCANCODE_NUMLOCK_KEY = 0x45,
|
||||
SCANCODE_SCROLL_KEY = 0x46, // Scroll lock
|
||||
SCANCODE_LALT_KEY = 0x38,
|
||||
SCANCODE_RALT_KEY = 0x138,
|
||||
SCANCODE_LWIN_KEY = 0x15b,
|
||||
SCANCODE_RWIN_KEY = 0x15c,
|
||||
SCANCODE_MENU_KEY = 0x15d,
|
||||
|
||||
SCANCODE_ESC_KEY = 0x01,
|
||||
SCANCODE_BACKSPACE_KEY = 0x0e,
|
||||
SCANCODE_ENTER_KEY = 0x1c,
|
||||
SCANCODE_TAB_KEY = 0x0f,
|
||||
SCANCODE_PAUSE_KEY = 0x21d,
|
||||
|
||||
SCANCODE_KP_ENTER_KEY = 0x11c,
|
||||
SCANCODE_KP_DEL_KEY = 0x53,
|
||||
SCANCODE_KP_1_KEY = 0x4f,
|
||||
SCANCODE_KP_2_KEY = 0x50,
|
||||
SCANCODE_KP_4_KEY = 0x4b,
|
||||
SCANCODE_KP_6_KEY = 0x4d,
|
||||
SCANCODE_KP_7_KEY = 0x47,
|
||||
SCANCODE_KP_8_KEY = 0x48,
|
||||
|
||||
SCANCODE_LEFT_ARROW_KEY = 0x14b,
|
||||
SCANCODE_RIGHT_ARROW_KEY = 0x14d,
|
||||
SCANCODE_UP_ARROW_KEY = 0x148,
|
||||
SCANCODE_DOWN_ARROW_KEY = 0x150,
|
||||
|
||||
SCANCODE_HOME_KEY = 0x147,
|
||||
SCANCODE_DEL_KEY = 0x153,
|
||||
SCANCODE_END_KEY = 0x14f,
|
||||
|
||||
/**
|
||||
* Keys affected by numlock
|
||||
* (this is not the whole keypad)
|
||||
*/
|
||||
SCANCODE_MIN_NUMLOCK = SCANCODE_KP_7_KEY,
|
||||
SCANCODE_MAX_NUMLOCK = SCANCODE_KP_DEL_KEY
|
||||
};
|
||||
|
||||
// Convert key_code and flags values received from a TS_KEYBOARD_EVENT
|
||||
// into a value suitable for use by this module
|
||||
#define SCANCODE_FROM_KBD_EVENT(key_code,keyboard_flags) \
|
||||
(((key_code) & 0x7f) | ((keyboard_flags) & 0x300))
|
||||
|
||||
// Convert a scancode used by this module back into a
|
||||
// TS_KEYBOARD_EVENT keyCode value
|
||||
#define SCANCODE_TO_KBD_EVENT_KEY_CODE(scancode) ((scancode) & 0x7f)
|
||||
|
||||
// Convert a scancode used by this module back into a
|
||||
// TS_KEYBOARD_EVENT keyboardFlags value
|
||||
#define SCANCODE_TO_KBD_EVENT_KBD_FLAGS(scancode) ((scancode) & 0x300)
|
||||
|
||||
#endif /* XRDP_SCANCODE_DEFS_H */
|
@ -21,7 +21,31 @@
|
||||
#if !defined(XRDP_SOCKETS_H)
|
||||
#define XRDP_SOCKETS_H
|
||||
|
||||
/* basename of socket files */
|
||||
/* XRDP_SOCKET_ROOT_PATH must be defined to include this file */
|
||||
#ifdef __cppcheck__
|
||||
/* avoid syntax errors */
|
||||
# define XRDP_SOCKET_ROOT_PATH "/dummy"
|
||||
#elif !defined(XRDP_SOCKET_ROOT_PATH)
|
||||
# error "XRDP_SOCKET_ROOT_PATH must be defined"
|
||||
#endif
|
||||
|
||||
/* Buffer size for code for fullpath declarations
|
||||
*
|
||||
* This needs to fit in the sun_path field of a sockaddr_un. POSIX
|
||||
* does not define this size, so the value below is the lower of
|
||||
* the FreeBSD/OpenBSD/NetBSD(104) and Linux(108) values */
|
||||
#define XRDP_SOCKETS_MAXPATH 104
|
||||
|
||||
/* The socketdir is rooted at XRDP_SOCKET_ROOT_PATH. User-specific
|
||||
* sockets live in a user-specific sub-directory of this called
|
||||
* XRDP_SOCKET_PATH. The sub-directory is the UID of the user */
|
||||
#define XRDP_SOCKET_PATH XRDP_SOCKET_ROOT_PATH "/%d"
|
||||
|
||||
/* Sockets in XRDP_SOCKET_ROOT_PATH */
|
||||
#define SCP_LISTEN_PORT_BASE_STR "sesman.socket"
|
||||
|
||||
/* names of socket files within XRDP_SOCKET_PATH, qualified by
|
||||
* display number */
|
||||
#define XRDP_CHANSRV_BASE_STR "xrdp_chansrv_socket_%d"
|
||||
#define CHANSRV_PORT_OUT_BASE_STR "xrdp_chansrv_audio_out_socket_%d"
|
||||
#define CHANSRV_PORT_IN_BASE_STR "xrdp_chansrv_audio_in_socket_%d"
|
||||
@ -29,7 +53,7 @@
|
||||
#define XRDP_X11RDP_BASE_STR "xrdp_display_%d"
|
||||
#define XRDP_DISCONNECT_BASE_STR "xrdp_disconnect_display_%d"
|
||||
|
||||
/* fullpath of sockets */
|
||||
/* fullpath declarations */
|
||||
#define XRDP_CHANSRV_STR XRDP_SOCKET_PATH "/" XRDP_CHANSRV_BASE_STR
|
||||
#define CHANSRV_PORT_OUT_STR XRDP_SOCKET_PATH "/" CHANSRV_PORT_OUT_BASE_STR
|
||||
#define CHANSRV_PORT_IN_STR XRDP_SOCKET_PATH "/" CHANSRV_PORT_IN_BASE_STR
|
||||
|
330
configure.ac
330
configure.ac
@ -1,13 +1,15 @@
|
||||
# Process this file with autoconf to produce a configure script
|
||||
|
||||
AC_PREREQ(2.65)
|
||||
AC_INIT([xrdp], [0.9.15], [xrdp-devel@googlegroups.com])
|
||||
AC_PREREQ([2.69])
|
||||
AC_INIT([xrdp], [0.10.80], [xrdp-devel@googlegroups.com])
|
||||
AC_DEFINE([VERSION_YEAR], 2024, [Copyright year])
|
||||
AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in)
|
||||
AM_INIT_AUTOMAKE([1.7.2 foreign])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_PROG_CC
|
||||
AC_C_CONST
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_CXX
|
||||
LT_INIT
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
if test "x$PKG_CONFIG" = "x"; then
|
||||
@ -46,10 +48,19 @@ AM_CONDITIONAL(OPENBSD, [test "x$openbsd" = xyes])
|
||||
AM_CONDITIONAL(NETBSD, [test "x$netbsd" = xyes])
|
||||
AM_CONDITIONAL(MACOS, [test "x$macos" = xyes])
|
||||
|
||||
AC_CHECK_SIZEOF([int])
|
||||
AC_CHECK_SIZEOF([long])
|
||||
AC_CHECK_SIZEOF([void *])
|
||||
|
||||
# runstatedir not available for autoconf <= 2.69
|
||||
if test "x$runstatedir" = "x" ; then
|
||||
runstatedir='${localstatedir}/run'
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([socketdir],
|
||||
[AS_HELP_STRING([--with-socketdir=DIR],
|
||||
[Use directory for UNIX sockets (default: /tmp/.xrdp)])],
|
||||
[], [with_socketdir="/tmp/.xrdp"])
|
||||
[Use directory for UNIX sockets for XRDP sessions (default: RUNSTATEDIR/xrdp)])],
|
||||
[], [with_socketdir="$runstatedir/xrdp"])
|
||||
AC_SUBST([socketdir], [$with_socketdir])
|
||||
|
||||
AC_ARG_WITH([systemdsystemunitdir],
|
||||
@ -66,7 +77,7 @@ fi
|
||||
AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
|
||||
|
||||
AC_ARG_ENABLE(tests,
|
||||
AC_HELP_STRING([--enable-tests],
|
||||
AS_HELP_STRING([--enable-tests],
|
||||
[Ensure dependencies for the tests are installed]),
|
||||
[ensure_tests_deps=yes], [])
|
||||
AC_ARG_ENABLE(pam, AS_HELP_STRING([--enable-pam],
|
||||
@ -98,14 +109,32 @@ AC_ARG_ENABLE(pam-config, AS_HELP_STRING([--enable-pam-config=CONF],
|
||||
[Select PAM config to install: arch, debian, redhat, suse, freebsd, macos, unix
|
||||
(default: autodetect)]))
|
||||
|
||||
AC_ARG_ENABLE(xrdpdebug, AS_HELP_STRING([--enable-xrdpdebug],
|
||||
[Build debug (default: no)]),
|
||||
[], [enable_xrdpdebug=no])
|
||||
AM_CONDITIONAL(XRDP_DEBUG, [test x$enable_xrdpdebug = xyes])
|
||||
# Development options. devel_all is first as this provides a default for
|
||||
# the others
|
||||
AC_ARG_ENABLE(devel_all, AS_HELP_STRING([--enable-devel-all],
|
||||
[Enable all development options (default: no)]),
|
||||
[devel_all=$enableval], [devel_all=no])
|
||||
AC_ARG_ENABLE(devel_debug, AS_HELP_STRING([--enable-devel-debug],
|
||||
[Build exes with no optimisation and debugging symbols (default: no)]),
|
||||
[devel_debug=$enableval], [devel_debug=$devel_all])
|
||||
AM_CONDITIONAL(DEVEL_DEBUG, [test x$devel_debug = xyes ])
|
||||
AC_ARG_ENABLE(devel_logging, AS_HELP_STRING([--enable-devel-logging],
|
||||
[Enable development logging (default: no)]),
|
||||
[devel_logging=$enableval], [devel_logging=$devel_all])
|
||||
AC_ARG_ENABLE(devel_streamcheck, AS_HELP_STRING([--enable-devel-streamcheck],
|
||||
[Add range-check/abort to stream primitives (default: no)]),
|
||||
[devel_streamcheck=$enableval], [devel_streamcheck=$devel_all])
|
||||
|
||||
AC_ARG_ENABLE(neutrinordp, AS_HELP_STRING([--enable-neutrinordp],
|
||||
[Build neutrinordp module (default: no)]),
|
||||
[], [enable_neutrinordp=no])
|
||||
AM_CONDITIONAL(XRDP_NEUTRINORDP, [test x$enable_neutrinordp = xyes])
|
||||
|
||||
AC_ARG_ENABLE(ulalaca, AS_HELP_STRING([--enable-ulalaca],
|
||||
[Build ulalaca module (experimental) (default: no)]),
|
||||
[], [enable_ulalaca=no])
|
||||
AM_CONDITIONAL(XRDP_ULALACA, [test x$enable_ulalaca = xyes])
|
||||
|
||||
AC_ARG_ENABLE(jpeg, AS_HELP_STRING([--enable-jpeg],
|
||||
[Build jpeg module (default: no)]),
|
||||
[], [enable_jpeg=no])
|
||||
@ -134,11 +163,18 @@ AC_ARG_ENABLE(mp3lame, AS_HELP_STRING([--enable-mp3lame],
|
||||
[Build lame mp3(audio codec) (default: no)]),
|
||||
[], [enable_mp3lame=no])
|
||||
AM_CONDITIONAL(XRDP_MP3LAME, [test x$enable_mp3lame = xyes])
|
||||
AC_ARG_ENABLE(ibus, AS_HELP_STRING([--enable-ibus],
|
||||
[Allow unicode input via IBus) (default: no)]),
|
||||
[], [enable_ibus=no])
|
||||
AM_CONDITIONAL(XRDP_IBUS, [test x$enable_ibus = xyes])
|
||||
AC_ARG_ENABLE(pixman, AS_HELP_STRING([--enable-pixman],
|
||||
[Use pixman library (default: no)]),
|
||||
[], [enable_pixman=no])
|
||||
AM_CONDITIONAL(XRDP_PIXMAN, [test x$enable_pixman = xyes])
|
||||
|
||||
AC_ARG_ENABLE(x264, AS_HELP_STRING([--enable-x264],
|
||||
[Use x264 library (default: no)]),
|
||||
[], [enable_x264=no])
|
||||
AM_CONDITIONAL(XRDP_X264, [test x$enable_x264 = xyes])
|
||||
AC_ARG_ENABLE(painter, AS_HELP_STRING([--disable-painter],
|
||||
[Do not use included painter library (default: no)]),
|
||||
[], [enable_painter=yes])
|
||||
@ -154,19 +190,46 @@ AC_ARG_ENABLE(rdpsndaudin, AS_HELP_STRING([--enable-rdpsndaudin],
|
||||
[], [enable_rdpsndaudin=no])
|
||||
AM_CONDITIONAL(XRDP_RDPSNDAUDIN, [test x$enable_rdpsndaudin = xyes])
|
||||
|
||||
AC_ARG_ENABLE(utmp, AS_HELP_STRING([--enable-utmp],
|
||||
[Update utmp (default: no)]),
|
||||
[], [enable_utmp=no])
|
||||
AM_CONDITIONAL(XRDP_UTMP, [test x$enable_utmp = xyes])
|
||||
|
||||
AC_ARG_WITH(imlib2, AS_HELP_STRING([--with-imlib2=ARG], [imlib2 library to use for non-BMP backgrounds (ARG=yes/no/<abs-path>)]),,)
|
||||
|
||||
AC_ARG_WITH(freetype2, AS_HELP_STRING([--with-freetype2=ARG], [freetype2 library to use for rendering fonts (ARG=yes/no/<abs-path>)]),,)
|
||||
|
||||
# Obsolete options
|
||||
AC_ARG_ENABLE(xrdpdebug, AS_HELP_STRING([--enable-xrdpdebug],
|
||||
[This option is no longer supported - use --enable-devel-all]))
|
||||
|
||||
if test "x$enable_xrdpdebug" != x; then
|
||||
AC_MSG_ERROR([--enable-xrdpdebug must be replaced with one or more --enable-devel-* options])
|
||||
fi
|
||||
|
||||
# configure compiler options and CFLAGS
|
||||
AX_GCC_FUNC_ATTRIBUTE([format])
|
||||
AX_TYPE_SOCKLEN_T
|
||||
AX_CFLAGS_WARN_ALL
|
||||
AX_APPEND_COMPILE_FLAGS([-Wwrite-strings])
|
||||
AX_APPEND_COMPILE_FLAGS([-Wmissing-prototypes], ,[-Werror])
|
||||
|
||||
AM_COND_IF([LINUX],
|
||||
[AX_APPEND_COMPILE_FLAGS([-Werror])]) # bsd has warnings that have not been fixed yet
|
||||
|
||||
AM_COND_IF([XRDP_DEBUG],
|
||||
AM_COND_IF([DEVEL_DEBUG],
|
||||
[AX_APPEND_COMPILE_FLAGS([-g -O0])],
|
||||
[AX_APPEND_COMPILE_FLAGS([-O2])])
|
||||
|
||||
# Function setusercontext() is in BSD -lutil but N/A on Solaris or GNU systems
|
||||
AC_SEARCH_LIBS([setusercontext], [util])
|
||||
|
||||
# Define HAVE_XXXXX macros for some system functions
|
||||
AC_CHECK_FUNCS([setusercontext getgrouplist clearenv])
|
||||
|
||||
# The type used by getgrouplist() is the same type used by getgroups()
|
||||
AC_TYPE_GETGROUPS
|
||||
|
||||
# Don't fail without working nasm if rfxcodec is not enabled
|
||||
if test "x$enable_rfxcodec" != xyes; then
|
||||
with_simd=no
|
||||
@ -196,28 +259,118 @@ AC_CHECK_HEADER([security/_pam_types.h],
|
||||
AC_CHECK_HEADER([security/pam_constants.h],
|
||||
[AC_DEFINE([HAVE_PAM_CONSTANTS_H], 1, [Using OpenPAM], [])])
|
||||
|
||||
# Find imlib2
|
||||
case "$with_imlib2" in
|
||||
'' | no) AC_MSG_NOTICE([imlib2 will not be supported])
|
||||
use_imlib2=no
|
||||
;;
|
||||
yes)
|
||||
PKG_CHECK_MODULES([IMLIB2], [imlib2 >= 1.4.5],
|
||||
[use_imlib2=yes],
|
||||
[AC_MSG_ERROR([please install libimlib2-dev or imlib2-devel])])
|
||||
;;
|
||||
/*) AC_MSG_CHECKING([for imlib2 in $with_imlib2])
|
||||
if test -d $with_imlib2/lib; then
|
||||
IMLIB2_LIBS="-L$with_imlib2/lib -lImlib2"
|
||||
elif test -d $with_imlib2/lib64; then
|
||||
IMLIB2_LIBS="-L$with_imlib2/lib64 -lImlib2"
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([Can't find libImlib2 in $with_imlib2])
|
||||
fi
|
||||
|
||||
if test -f $with_imlib2/include/Imlib2.h; then
|
||||
IMLIB2_CFLAGS="-I $with_imlib2/include"
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([Can't find $with_imlib2/include/Imlib2.h])
|
||||
fi
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_SUBST([IMLIB2_LIBS])
|
||||
AC_SUBST([IMLIB2_CFLAGS])
|
||||
use_imlib2=yes
|
||||
;;
|
||||
*) AC_MSG_ERROR([--with-imlib2 needs yes/no or absolute path])
|
||||
esac
|
||||
|
||||
if test x$use_imlib2 = xyes; then
|
||||
AC_DEFINE([USE_IMLIB2],1, [Compile with imlib2 support])
|
||||
fi
|
||||
|
||||
# Find freetype2
|
||||
#
|
||||
# The modversion used by pkgcheck does not correspond to the
|
||||
# freetype2 release. See docs/VERSIONS.TXT in the freetype2
|
||||
# source for a table of correspondences. If you change one
|
||||
# of the below defines, change both.
|
||||
m4_define([FT2_REQUIRED_VERSION], [2_8_0])
|
||||
m4_define([FT2_REQUIRED_MODVERSION], [20.0.14])
|
||||
case "$with_freetype2" in
|
||||
'' | no) AC_MSG_NOTICE([freetype2 will not be supported])
|
||||
use_freetype2=no
|
||||
;;
|
||||
yes)
|
||||
PKG_CHECK_MODULES([FREETYPE2], [freetype2 >= FT2_REQUIRED_MODVERSION],
|
||||
[use_freetype2=yes],
|
||||
[AC_MSG_ERROR([please install version FT2_REQUIRED_VERSION or later of libfreetype6-dev or freetype-devel])])
|
||||
;;
|
||||
/*) AC_MSG_CHECKING([for freetype2 in $with_freetype2])
|
||||
if test -d $with_freetype2/lib; then
|
||||
FREETYPE2_LIBS="-L$with_freetype2/lib -llibfreetype"
|
||||
elif test -d $with_freetype2/lib64; then
|
||||
FREETYPE2_LIBS="-L$with_freetype2/lib64 -llibfreetype"
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([Can't find libfreetype in $with_freetype2])
|
||||
fi
|
||||
|
||||
if test -f $with_freetype2/include/freetype2/ft2build.h; then
|
||||
FREETYPE2_CFLAGS="-I $with_freetype2/include/freetype2"
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([Can't find $with_freetype2/include/freetype2/ft2build.h])
|
||||
fi
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_SUBST([FREETYPE2_LIBS])
|
||||
AC_SUBST([FREETYPE2_CFLAGS])
|
||||
use_freetype2=yes
|
||||
;;
|
||||
*) AC_MSG_ERROR([--with-freetype2 needs yes/no or absolute path])
|
||||
esac
|
||||
AM_CONDITIONAL([USE_FREETYPE2], [test "x$use_freetype2" = xyes])
|
||||
|
||||
# Check only one auth mechanism is specified, and give it a name
|
||||
auth_cnt=0
|
||||
auth_mech="Builtin"
|
||||
AUTHMOD_OBJ=verify_user.lo
|
||||
AUTHMOD_LIB=-lcrypt
|
||||
if test x$enable_pam = xyes
|
||||
then
|
||||
auth_cnt=`expr $auth_cnt + 1`
|
||||
auth_mech="PAM"
|
||||
AUTHMOD_OBJ=verify_user_pam.lo
|
||||
AUTHMOD_LIB=-lpam
|
||||
fi
|
||||
if test x$bsd = xtrue
|
||||
then
|
||||
auth_cnt=`expr $auth_cnt + 1`
|
||||
auth_mech="BSD"
|
||||
AUTHMOD_OBJ=verify_user_bsd.lo
|
||||
AUTHMOD_LIB=
|
||||
fi
|
||||
if test x$enable_kerberos = xyes
|
||||
then
|
||||
auth_cnt=`expr $auth_cnt + 1`
|
||||
auth_mech="Kerberos"
|
||||
AUTHMOD_OBJ=verify_user_kerberos.lo
|
||||
AUTHMOD_LIB=-lkrb5
|
||||
fi
|
||||
if test x$enable_pamuserpass = xyes
|
||||
then
|
||||
auth_cnt=`expr $auth_cnt + 1`
|
||||
auth_mech="PAM userpass"
|
||||
AUTHMOD_OBJ=verify_user_pam_userpass.lo
|
||||
AUTHMOD_LIB="-lpam -lpam_userpass"
|
||||
fi
|
||||
|
||||
if test $auth_cnt -gt 1
|
||||
@ -225,6 +378,9 @@ then
|
||||
AC_MSG_ERROR([--enable-pam, --enable-bsd, --enable-pamuserpass and --enable-kerberos are mutually exclusive])
|
||||
fi
|
||||
|
||||
AC_SUBST([AUTHMOD_OBJ])
|
||||
AC_SUBST([AUTHMOD_LIB])
|
||||
|
||||
# checking if pam should be autodetected.
|
||||
if test "x$enable_pam" = "xyes"
|
||||
then
|
||||
@ -247,13 +403,31 @@ fi
|
||||
|
||||
AC_SUBST(PAM_RULES)
|
||||
|
||||
# Add define for development options to config_ac.h
|
||||
AC_DEFINE([CONFIG_AC_H],1, [Allow sources to check config_ac.h is included])
|
||||
if test x$devel_logging = xyes
|
||||
then
|
||||
AC_DEFINE([USE_DEVEL_LOGGING],1,[Enable development logging])
|
||||
fi
|
||||
|
||||
if test x$devel_streamcheck = xyes
|
||||
then
|
||||
AC_DEFINE([USE_DEVEL_STREAMCHECK],1,[Enable development stream checking])
|
||||
fi
|
||||
|
||||
if test "x$enable_vsock" = "xyes"
|
||||
then
|
||||
enable_vsock=yes
|
||||
AC_CHECK_HEADERS([linux/socket.h linux/vm_sockets.h],
|
||||
[AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_VSOCK])],
|
||||
[],
|
||||
[#include <sys/socket.h>])
|
||||
if test "x$freebsd" = "xyes"
|
||||
then
|
||||
# Determine if we have AF_HYPERV defined (FreeBSD 13+)
|
||||
AC_CHECK_DECL([AF_HYPERV], [AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_HYPERV])], [], [#include <sys/socket.h>])
|
||||
else
|
||||
AC_CHECK_HEADERS([linux/socket.h linux/vm_sockets.h],
|
||||
[AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_VSOCK])],
|
||||
[],
|
||||
[#include <sys/socket.h>])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$enable_ipv6only" = "xyes"
|
||||
@ -267,11 +441,6 @@ then
|
||||
AC_DEFINE([XRDP_ENABLE_IPV6],1,[Enable IPv6])
|
||||
fi
|
||||
|
||||
if test "x$enable_pam" = "xyes"
|
||||
then
|
||||
AC_DEFINE([USE_PAM],1,[Enable PAM])
|
||||
fi
|
||||
|
||||
AS_IF( [test "x$enable_neutrinordp" = "xyes"] , [PKG_CHECK_MODULES(FREERDP, freerdp >= 1.0.0)] )
|
||||
|
||||
# checking for libjpeg
|
||||
@ -284,8 +453,8 @@ fi
|
||||
# checking for fuse
|
||||
if test "x$enable_fuse" = "xyes"
|
||||
then
|
||||
PKG_CHECK_MODULES([FUSE], [fuse >= 2.6], [],
|
||||
[AC_MSG_ERROR([please install libfuse-dev or fuse-devel])])
|
||||
PKG_CHECK_MODULES([FUSE], [fuse3 >= 3.1.0], [],
|
||||
[AC_MSG_ERROR([please install libfuse3-dev or fuse3-devel])])
|
||||
fi
|
||||
|
||||
# checking for fdk aac
|
||||
@ -309,8 +478,21 @@ then
|
||||
[AC_MSG_ERROR([please install libmp3lame-dev or lamemp3-devel])])
|
||||
fi
|
||||
|
||||
# checking for ibus includes
|
||||
if test "x$enable_ibus" = "xyes"
|
||||
then
|
||||
PKG_CHECK_MODULES([IBUS], [ibus-1.0 >= 1.5], [],
|
||||
[AC_MSG_ERROR([please install libibus-1.0-dev or ibus-devel])])
|
||||
|
||||
# ibus uses dbus which depends on glib
|
||||
PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.56], [],
|
||||
[AC_MSG_ERROR([please install libglib2.0-dev or glib2.0-devel])])
|
||||
fi
|
||||
|
||||
AS_IF( [test "x$enable_pixman" = "xyes"] , [PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.1.0)] )
|
||||
|
||||
AS_IF( [test "x$enable_x264" = "xyes"] , [PKG_CHECK_MODULES(XRDP_X264, x264 >= 0.3.0)] )
|
||||
|
||||
# checking for TurboJPEG
|
||||
if test "x$enable_tjpeg" = "xyes"
|
||||
then
|
||||
@ -359,16 +541,40 @@ AC_CHECK_HEADER([X11/extensions/Xrandr.h], [],
|
||||
[AC_MSG_ERROR([please install libxrandr-dev or libXrandr-devel])],
|
||||
[#include <X11/Xlib.h>])
|
||||
|
||||
# checking for XKB
|
||||
AC_CHECK_HEADER([X11/extensions/XKBrules.h], [],
|
||||
[AC_MSG_ERROR([please install libxkbfile-dev or libxkbfile-devel])],
|
||||
[#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <stdio.h>])
|
||||
|
||||
if test "x$enable_utmp" = "xyes"
|
||||
then
|
||||
AC_CHECK_HEADERS(utmp.h utmpx.h)
|
||||
|
||||
# Test for non-standard extensions in struct utmpx
|
||||
AXRDP_CHECK_UTMPX_MEMBER_EXISTS([ut_host], [HAVE_UTMPX_UT_HOST])
|
||||
AXRDP_CHECK_UTMPX_MEMBER_EXISTS([ut_exit], [HAVE_UTMPX_UT_EXIT])
|
||||
fi
|
||||
|
||||
CFLAGS="$save_CFLAGS"
|
||||
|
||||
# perform unit tests if libcheck found
|
||||
# perform unit tests if libcheck and libmocka found
|
||||
perform_unit_tests=yes; # Assume packages will be found
|
||||
if test "x$ensure_tests_deps" == "xyes"; then
|
||||
PKG_CHECK_MODULES([CHECK], [check >= 0.10.0],
|
||||
[perform_unit_tests=yes],
|
||||
[],
|
||||
[AC_MSG_ERROR([please install check, the unit test framework])])
|
||||
# Check if cmocka is available - needed for unit testing
|
||||
PKG_CHECK_MODULES([CMOCKA], [cmocka],
|
||||
[],
|
||||
[AC_MSG_ERROR([please install cmocka, the mocking framework])])
|
||||
else
|
||||
PKG_CHECK_MODULES([CHECK], [check >= 0.10.0],
|
||||
[perform_unit_tests=yes],
|
||||
[],
|
||||
[perform_unit_tests=no])
|
||||
PKG_CHECK_MODULES([CMOCKA], [cmocka],
|
||||
[],
|
||||
[perform_unit_tests=no])
|
||||
fi
|
||||
|
||||
@ -392,14 +598,21 @@ if test "x$enable_strict_locations" != "xyes"; then
|
||||
localstatedir="/var";
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([pamconfdir],
|
||||
[AS_HELP_STRING([--with-pamconfdir=DIR],
|
||||
[Use directory for pam.d config (default: /etc/pam.d)])],
|
||||
[], [with_pamconfdir="$sysconfdir/pam.d"])
|
||||
AC_SUBST([pamconfdir], [$with_pamconfdir])
|
||||
|
||||
PKG_INSTALLDIR
|
||||
|
||||
AC_CHECK_HEADERS([sys/prctl.h])
|
||||
AC_CHECK_HEADERS([sys/prctl.h uchar.h])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
common/Makefile
|
||||
docs/Makefile
|
||||
docs/man/Makefile
|
||||
fontutils/Makefile
|
||||
genkeymap/Makefile
|
||||
instfiles/default/Makefile
|
||||
instfiles/init.d/Makefile
|
||||
@ -408,28 +621,38 @@ AC_CONFIG_FILES([
|
||||
instfiles/pulse/Makefile
|
||||
instfiles/rc.d/Makefile
|
||||
keygen/Makefile
|
||||
waitforx/Makefile
|
||||
libipm/Makefile
|
||||
libxrdp/Makefile
|
||||
Makefile
|
||||
mc/Makefile
|
||||
neutrinordp/Makefile
|
||||
ulalaca/Makefile
|
||||
pkgconfig/Makefile
|
||||
pkgconfig/xrdp.pc
|
||||
pkgconfig/xrdp-uninstalled.pc
|
||||
sesman/libsesman/Makefile
|
||||
sesman/chansrv/Makefile
|
||||
sesman/libscp/Makefile
|
||||
sesman/Makefile
|
||||
sesman/sesexec/Makefile
|
||||
sesman/tools/Makefile
|
||||
tests/Makefile
|
||||
tests/common/Makefile
|
||||
tests/libipm/Makefile
|
||||
tests/libxrdp/Makefile
|
||||
tests/memtest/Makefile
|
||||
tests/xrdp/Makefile
|
||||
tools/Makefile
|
||||
tools/devel/Makefile
|
||||
tools/devel/tcp_proxy/Makefile
|
||||
tools/chkpriv/Makefile
|
||||
vnc/Makefile
|
||||
xrdpapi/Makefile
|
||||
xrdp/Makefile
|
||||
xrdpvr/Makefile
|
||||
xup/Makefile
|
||||
third_party/Makefile
|
||||
third_party/tomlc99/Makefile
|
||||
])
|
||||
|
||||
AC_REQUIRE_AUX_FILE([tap-driver.sh])
|
||||
@ -438,21 +661,35 @@ AC_OUTPUT
|
||||
echo ""
|
||||
echo "xrdp will be compiled with:"
|
||||
echo ""
|
||||
echo " mp3lame $enable_mp3lame"
|
||||
echo " opus $enable_opus"
|
||||
echo " fdkaac $enable_fdkaac"
|
||||
echo " jpeg $enable_jpeg"
|
||||
echo " turbo jpeg $enable_tjpeg"
|
||||
echo " rfxcodec $enable_rfxcodec"
|
||||
echo " painter $enable_painter"
|
||||
echo " pixman $enable_pixman"
|
||||
echo " fuse $enable_fuse"
|
||||
echo " ipv6 $enable_ipv6"
|
||||
echo " ipv6only $enable_ipv6only"
|
||||
echo " vsock $enable_vsock"
|
||||
echo " auth mechanism $auth_mech"
|
||||
echo " debug $enable_xrdpdebug"
|
||||
echo " rdpsndaudin $enable_rdpsndaudin"
|
||||
echo " mp3lame $enable_mp3lame"
|
||||
echo " opus $enable_opus"
|
||||
echo " fdkaac $enable_fdkaac"
|
||||
echo " jpeg $enable_jpeg"
|
||||
echo " turbo jpeg $enable_tjpeg"
|
||||
echo " rfxcodec $enable_rfxcodec"
|
||||
echo " x264 $enable_x264"
|
||||
echo " painter $enable_painter"
|
||||
echo " pixman $enable_pixman"
|
||||
echo " fuse $enable_fuse"
|
||||
echo " ipv6 $enable_ipv6"
|
||||
echo " ipv6only $enable_ipv6only"
|
||||
echo " vsock $enable_vsock"
|
||||
echo " ibus $enable_ibus"
|
||||
echo " auth mechanism $auth_mech"
|
||||
echo " rdpsndaudin $enable_rdpsndaudin"
|
||||
echo " utmp support $enable_utmp"
|
||||
if test x$enable_utmp = xyes; then
|
||||
echo " utmpx.ut_host $ac_cv_utmpx_has_ut_host"
|
||||
echo " utmpx.ut_exit $ac_cv_utmpx_has_ut_exit"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo " with imlib2 $use_imlib2"
|
||||
echo " with freetype2 $use_freetype2"
|
||||
|
||||
echo
|
||||
echo " development logging $devel_logging"
|
||||
echo " development streamcheck $devel_streamcheck"
|
||||
echo ""
|
||||
echo " strict_locations $enable_strict_locations"
|
||||
echo " prefix $prefix"
|
||||
@ -460,6 +697,10 @@ echo " exec_prefix $exec_prefix"
|
||||
echo " libdir $libdir"
|
||||
echo " bindir $bindir"
|
||||
echo " sysconfdir $sysconfdir"
|
||||
echo " pamconfdir $pamconfdir"
|
||||
echo " localstatedir $localstatedir"
|
||||
echo " runstatedir $runstatedir"
|
||||
echo " socketdir $socketdir"
|
||||
echo ""
|
||||
echo " unit tests performable $perform_unit_tests"
|
||||
echo ""
|
||||
@ -470,4 +711,3 @@ echo " LDFLAGS = $LDFLAGS"
|
||||
echo '#define XRDP_CONFIGURE_OPTIONS \' > ./xrdp_configure_options.h
|
||||
./config.status --config | xargs -n 1 | sed -e 's/^/" /' -e 's/$/\\n" \\/' >> ./xrdp_configure_options.h
|
||||
echo '""' >> ./xrdp_configure_options.h
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
RDP server for Linux
|
35
design.txt
35
design.txt
@ -1,35 +0,0 @@
|
||||
|
||||
This document is intended to explain xrdp server design.
|
||||
|
||||
Many connections, all capable of running different modules
|
||||
one connection could be using a vnc connection
|
||||
one could be running a custom app made for xrdp
|
||||
one could be running a X11 session
|
||||
clients control the screen size and color depth
|
||||
|
||||
all controlled by a configuration file.
|
||||
|
||||
you can create a lib or use a lib with your executable that talks
|
||||
to xrdp server.
|
||||
|
||||
------ ----------
|
||||
-xrdp---linked-------mylib.so- session 1
|
||||
------ ----------
|
||||
|
|
||||
| -------------------------
|
||||
|----unix socket--myapp linked to libxrdp- session 2
|
||||
| -------------------------
|
||||
|
|
||||
| -----------
|
||||
|----linked-------mylib2.so- session 3
|
||||
-----------
|
||||
|
||||
Any of the above sessions can repeat or have different session
|
||||
numbers or not even be used.
|
||||
If a session is disconnected, all that changes is the rdp connection
|
||||
is lost, the session remains.
|
||||
|
||||
For X11, start the XServer after the user is
|
||||
authenticated. First check for the next available X11 display,
|
||||
create a user session, start the XServer and set the DISPLAY environment
|
||||
variable.
|
@ -2,15 +2,21 @@ man_MANS = \
|
||||
xrdp-dis.1 \
|
||||
sesman.ini.5 \
|
||||
xrdp.ini.5 \
|
||||
xrdp-km.toml.5 \
|
||||
xrdp.8 \
|
||||
xrdp-chansrv.8 \
|
||||
xrdp-genkeymap.8 \
|
||||
xrdp-keygen.8 \
|
||||
xrdp-sesadmin.8 \
|
||||
xrdp-sesman.8 \
|
||||
xrdp-sesrun.8
|
||||
xrdp-sesrun.8 \
|
||||
xrdp-dumpfv1.8
|
||||
|
||||
EXTRA_DIST = $(man_MANS:=.in)
|
||||
EXTRA_DIST = xrdp-mkfv1.8.in $(man_MANS:=.in)
|
||||
|
||||
if USE_FREETYPE2
|
||||
man_MANS += xrdp-mkfv1.8
|
||||
endif
|
||||
|
||||
SUBST_VARS = sed \
|
||||
-e 's|@PACKAGE_VERSION[@]|$(PACKAGE_VERSION)|g' \
|
||||
@ -20,6 +26,7 @@ SUBST_VARS = sed \
|
||||
-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
|
||||
-e 's|@socketdir[@]|$(socketdir)|g' \
|
||||
-e 's|@xrdpconfdir[@]|$(sysconfdir)/xrdp|g' \
|
||||
-e 's|@xrdpdatadir[@]|$(datadir)/xrdp|g' \
|
||||
-e 's|@xrdphomeurl[@]|http://www.xrdp.org/|g'
|
||||
|
||||
subst_verbose = $(subst_verbose_@AM_V@)
|
||||
|
@ -24,10 +24,6 @@ Session management
|
||||
\fB[Security]\fR
|
||||
Access control
|
||||
|
||||
.TP
|
||||
\fB[X11rdp]\fR, \fB[Xvnc]\fR, \fB[Xorg]\fR
|
||||
X11 server settings for supported servers
|
||||
|
||||
.TP
|
||||
\fB[Chansrv]\fR
|
||||
Settings for xrdp-chansrv(8)
|
||||
@ -50,13 +46,19 @@ outside their proper section will be \fIignored\fR.
|
||||
Following parameters can be used in the \fB[Globals]\fR section.
|
||||
|
||||
.TP
|
||||
\fBListenAddress\fR=\fIip address\fR
|
||||
xrdp-sesman listening address. If not specified, defaults to \fI0.0.0.0\fR
|
||||
(all interfaces).
|
||||
|
||||
.TP
|
||||
\fBListenPort\fR=\fIport number\fR
|
||||
xrdp-sesman listening port. If not specified, defaults to \fI3350\fR.
|
||||
\fBListenPort\fR=\fIpath-to-socket\fR
|
||||
UNIX domain socket for xrdp-sesman(8) to listen on.
|
||||
.PP
|
||||
.RS
|
||||
The default value of this setting is 'sesman.socket'.
|
||||
.PP
|
||||
An absolute path can be specified by starting this parameter with a '/'.
|
||||
In this instance, the system administrator is responsible for ensuring
|
||||
the socket can only be created by a suitably privileged process.
|
||||
.PP
|
||||
If the parameter does not start with a '/', a name within
|
||||
@socketdir@ is used.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fBEnableUserWindowManager\fR=\fI[true|false]\fR
|
||||
@ -91,7 +93,10 @@ sections.
|
||||
.TP
|
||||
\fBLogFile\fR=\fIfilename\fR
|
||||
Log file path. It can be either absolute or relative. If not specified,
|
||||
defaults to \fI./sesman.log\fR It is ignored in the [ChansrvLogging] section
|
||||
defaults to \fI./sesman.log\fR. If set to \fB<stdout>\fR, log will go to
|
||||
stdout. Use for debugging only\fR
|
||||
|
||||
It is ignored in the [ChansrvLogging] section
|
||||
since the channel server creates one log file per display and instead uses the
|
||||
following log file naming convention \fIxrdp-chansrv.${DISPLAY}.log\fR
|
||||
|
||||
@ -150,6 +155,13 @@ defaults to \fI10\fR.
|
||||
Sets the maximum number of simultaneous sessions. If not set or set to
|
||||
\fI0\fR, unlimited session are allowed.
|
||||
|
||||
.TP
|
||||
\fBMaxDisplayNumber\fR=\fInumber\fR
|
||||
Sets the maximum number which can be assigned to an X11 $DISPLAY. The
|
||||
default is compatible with IANA TCP port allocations. If you are not
|
||||
allowing TCP connections to your X servers you may safely increase this
|
||||
number.
|
||||
|
||||
.TP
|
||||
\fBKillDisconnected\fR=\fI[true|false]\fR
|
||||
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, every session will be killed
|
||||
@ -170,30 +182,34 @@ If set to \fI0\fR, idle sessions will never be disconnected by timeout.
|
||||
This works only with xorgxrdp sessions. Moreover, xorgxrdp must be v0.2.9 or later.
|
||||
|
||||
.TP
|
||||
\fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR
|
||||
\fBPolicy\fR=\fI[Default|Separate|{UBDI}]\fR
|
||||
Session allocation policy. Used to decide when to allocate a
|
||||
new session. Set to one of the following values:
|
||||
.br
|
||||
|
||||
.br
|
||||
\fBDefault\fR - session per <User,BitPerPixel>
|
||||
.br
|
||||
\fBUBD\fR - session per <User,BitPerPixel,DisplaySize>
|
||||
.br
|
||||
\fBUBI\fR - session per <User,BitPerPixel,IPAddr>
|
||||
.br
|
||||
\fBUBC\fR - session per <User,BitPerPixel,Connection>
|
||||
.br
|
||||
\fBUBDI\fR - session per <User,BitPerPixel,DisplaySize,IPAddr>
|
||||
.br
|
||||
\fBUBDC\fR - session per <User,BitPerPixel,DisplaySize,Connection>
|
||||
.br
|
||||
.RS
|
||||
.HP 12
|
||||
\fBDefault\fR - Currently the same as "UB" for all session types
|
||||
.HP 12
|
||||
\fBSeparate\fR - All sessions are separate. Sessions can never be rejoined,
|
||||
and will need to be cleaned up manually, or automatically by setting other
|
||||
sesman options.
|
||||
.P
|
||||
Alternatively combine one-or-more of the following options
|
||||
.HP 4
|
||||
\fBU\fR - Sessions are separated per user
|
||||
.HP 4
|
||||
\fBB\fR - Sessions are separated by bits-per-pixel
|
||||
.HP 4
|
||||
\fBD\fR - Sessions are separated by initial display size
|
||||
.HP 4
|
||||
\fBI\fR - Sessions are separated by IP address
|
||||
.RE
|
||||
|
||||
.br
|
||||
Note that the \fBUser\fR and \fBBitPerPixel\fR criteria cannot be turned
|
||||
.IP
|
||||
Note that the \fBU\fR and \fBB\fR criteria cannot be turned
|
||||
off. \fBDisplaySize\fR refers to the initial geometry of a connection,
|
||||
as actual display sizes can change dynamically.
|
||||
.br
|
||||
|
||||
.SH "SECURITY"
|
||||
Following parameters can be used in the \fB[Security]\fR section.
|
||||
@ -221,18 +237,89 @@ login for all users is enabled.
|
||||
have session management rights.
|
||||
|
||||
.TP
|
||||
\fBRestrictOutboundClipboard\fR=\fI[true|false]\fR
|
||||
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, will restrict the clipboard
|
||||
\fBRestrictOutboundClipboard\fR=\fI[all|none|text|file|image]\fR
|
||||
If set to \fBall\fR, will restrict the clipboard
|
||||
outbound from the server, to prevent data copied inside the xrdp session
|
||||
to be be pasted in the client host. Default value is \fBfalse\fR.
|
||||
to be pasted in the client. Default value is \fBnone\fR.
|
||||
In addition, you can control text/file/image transfer restrictions
|
||||
respectively. It also accepts comma separated list such as text,file,image.
|
||||
.br
|
||||
|
||||
.br
|
||||
\fBnone\fR - No restriction about copying inbound clipboard data.
|
||||
.br
|
||||
\fBall\fR - Restrict to copy inbound clipboard data.
|
||||
.br
|
||||
\fBtext\fR - Restrict to copy only inbound text clipboard data.
|
||||
.br
|
||||
\fBfile\fR - Restrict to copy only inbound file clipboard data.
|
||||
.br
|
||||
\fBimage\fR - Restrict to copy only inbound image clipboard data.
|
||||
.br
|
||||
|
||||
To keep compatibility, the following aliases are also available.
|
||||
.br
|
||||
\fBtrue\fR - an alias of \fBall\fR.
|
||||
.br
|
||||
\fBfalse\fR - an alias of \fBnone\fR.
|
||||
.br
|
||||
\fByes\fR - an alias of \fBall\fR.
|
||||
|
||||
.TP
|
||||
\fBRestrictInboundClipboard\fR=\fI[none|all|text|file|image]\fR
|
||||
If set to \fBall\fR, will restrict the clipboard
|
||||
inbound from the client, to prevent data copied inside the client
|
||||
to be pasted in the xrdp session. Default value is \fBnone\fR.
|
||||
In addition, you can control text/file/image transfer restrictions
|
||||
respectively. It also accepts comma separated list such as text,file,image.
|
||||
.br
|
||||
|
||||
.br
|
||||
\fBnone\fR - No restriction about copying inbound clipboard data.
|
||||
.br
|
||||
\fBall\fR - Restrict to copy inbound clipboard data.
|
||||
.br
|
||||
\fBtext\fR - Restrict to copy only inbound text clipboard data.
|
||||
.br
|
||||
\fBfile\fR - Restrict to copy only inbound file clipboard data.
|
||||
.br
|
||||
\fBimage\fR - Restrict to copy only inbound image clipboard data.
|
||||
.br
|
||||
|
||||
To keep compatibility, the following aliases are also available.
|
||||
.br
|
||||
\fBtrue\fR - an alias of \fBall\fR.
|
||||
.br
|
||||
\fBfalse\fR - an alias of \fBnone\fR.
|
||||
.br
|
||||
\fByes\fR - an alias of \fBall\fR.
|
||||
|
||||
.TP
|
||||
\fBAlwaysGroupCheck\fR=\fI[true|false]\fR
|
||||
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, require group membership even
|
||||
if the group specified in \fBTerminalServerUsers\fR doesn't exist.
|
||||
|
||||
.TP
|
||||
\fBAllowAlternateShell\fR=\fI[true|false]\fR
|
||||
If set to \fB0\fR, \fBfalse\fR or \fBno\fR, prevent usage of alternate shells by users.
|
||||
|
||||
.TP
|
||||
\fBXorgNoNewPrivileges\fR=\fI[true|false]\fR
|
||||
Only applicable on Linux. If set to \fB0\fR, \fBfalse\fR or \fBno\fR, do
|
||||
not use the kernel's \fIno_new_privs\fR restriction when invoking the Xorg
|
||||
X11 server. The use of \fIno_new_privs\fR is intended to prevent issues due
|
||||
to a setuid Xorg executable. However, if a kernel security module (such as
|
||||
AppArmor) is used to confine xrdp, \fIno_new_privs\fR may interfere with
|
||||
transitions between confinement domains.
|
||||
|
||||
.TP
|
||||
\fBSessionSockdirGroup\fR=\fIgroup\fR
|
||||
Sets the group owner of the directories containing session sockets. This
|
||||
MUST be the same as runtime_group in xrdp.ini, or xrdp will not
|
||||
be able to connect to any sessions.
|
||||
|
||||
.SH "X11 SERVER"
|
||||
Following parameters can be used in the \fB[X11rdp]\fR, \fB[Xvnc]\fR and
|
||||
Following parameters can be used in the \fB[Xvnc]\fR and
|
||||
\fB[Xorg]\fR sections.
|
||||
|
||||
.TP
|
||||
@ -251,13 +338,12 @@ Created if it doesn't exist. If not specified, defaults to \fIxrdp_client\fR.
|
||||
If first character is not a '/', this is relative to $HOME.
|
||||
.P
|
||||
.RS
|
||||
If first character is a '/' this is an absolute path. The following
|
||||
substitutions are made in this string:-
|
||||
The following substitutions are made in this string:-
|
||||
%U - Username
|
||||
%u - Numeric UID
|
||||
%d - Numeric display number (ex 10)
|
||||
%D - Display environment variable (ex :10.0)
|
||||
%% - Percent character
|
||||
.P
|
||||
If this format is used:-
|
||||
.HP 3
|
||||
1) The directory path permissions MUST be configured correctly by
|
||||
the system administrator or the system itself - xrdp-chansrv will not
|
||||
@ -268,12 +354,18 @@ the user).
|
||||
drive. To fix this, consult the docs for your chosen desktop.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fBFuseDirectIO\fR=\fI[false|true]\fR
|
||||
Defaults to \fIfalse\fR. Set to \fItrue\fR to disable page caching in
|
||||
FUSE when opening files on a redirected drive. Direct I/O can impact
|
||||
the performance of file operations.
|
||||
|
||||
.TP
|
||||
\fBFileUmask\fR=\fImode\fR
|
||||
Additional umask to apply to files in the \fBFuseMountName\fR directory.
|
||||
The default value of 077 prevents other users on the system from reading
|
||||
files on your redirected drives. This may not be approprate for all
|
||||
environents, and so you can change this value to allow other users to
|
||||
files on your redirected drives. This may not be appropriate for all
|
||||
environments, and so you can change this value to allow other users to
|
||||
access your remote files if required.
|
||||
|
||||
.TP
|
||||
@ -290,6 +382,32 @@ features:-
|
||||
.P
|
||||
- copying-and-pasting of files
|
||||
.RE
|
||||
.TP
|
||||
\fBUseNautilus3FlistFormat\fR=\fI[false|true]\fR
|
||||
Defaults to \fIfalse\fR.
|
||||
Set to \fItrue\fR to make file copy-paste compatible with Nautilus from
|
||||
GNOME 3 versions later than 3.29.92. Do not use this for any other reason.
|
||||
|
||||
This setting will be removed in a later version of xrdp, when GNOME 3 is
|
||||
no longer supported.
|
||||
|
||||
.TP
|
||||
\fBSoundNumSilentFramesAAC\fR=\fInumber\fR
|
||||
Sets the \fInumber\fR of silent frames which are sent to client before close
|
||||
message is sent, when AAC is selected. If set to 0, no silent frame is sent.
|
||||
If not specified, defaults to \fI4\fR.
|
||||
|
||||
.TP
|
||||
\fBSoundNumSilentFramesMP3\fR=\fInumber\fR
|
||||
Sets the \fInumber\fR of silent frames which are sent to client before close
|
||||
message is sent, when MP3 is selected. If set to 0, no silent frame is sent.
|
||||
If not specified, defaults to \fI2\fR.
|
||||
|
||||
.TP
|
||||
\fBSoundMsecDoNotSend\fR=\fInumber\fR
|
||||
Sets the duration(msec). Sound data is not send to client during \fInumber\fR
|
||||
millisecond(s) after close message is sent, when AAC/MP3 is selected.
|
||||
If set to 0, all the data is sent. If not specified, defaults to \fI1000\fR.
|
||||
|
||||
.SH "SESSIONS VARIABLES"
|
||||
All entries in the \fB[SessionVariables]\fR section are set as
|
||||
|
58
docs/man/xrdp-dumpfv1.8.in
Normal file
58
docs/man/xrdp-dumpfv1.8.in
Normal file
@ -0,0 +1,58 @@
|
||||
.TH "xrdp-dumpfv1" "8" "@PACKAGE_VERSION@" "xrdp team"
|
||||
.SH NAME
|
||||
xrdp\-dumpfv1 \- Display content of .fv1 font files
|
||||
|
||||
.SH SYNOPSIS
|
||||
\fBxrdp-dumpfv1\fR [ options ] fv1_file
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBxrdp\-dumpfv1\fP can be used to display the contents of an fv1 file.
|
||||
|
||||
.SH OPTIONS
|
||||
A summary of options is included below.
|
||||
|
||||
One of \fB\-i\fR, \fB\-t\fR, or \fB\-c\fR must be specified.
|
||||
.TP
|
||||
\fB\-i\fR
|
||||
Displays general information about the fv1 file.
|
||||
|
||||
.TP
|
||||
\fB\-t\fR
|
||||
Displays a CSV table of all the glyphs in the font. This table can be
|
||||
imported into a spreadsheet program for further manipulation.
|
||||
|
||||
.TP
|
||||
\fB\-c\fR <character>
|
||||
Displays detailed information about a particular glyph in the font,
|
||||
including a representation of the bitmap for the glyph.
|
||||
|
||||
Specify the character using one of the following strings:
|
||||
|
||||
\fBU+<hex>\fR - Unicode character, e.g. \fBU+25\fR for a percentage symbol (%).
|
||||
|
||||
\fB@<char>\fR - Unicode character, e.g. \fB@%\fR for a percentage symbol.
|
||||
|
||||
\fBnumber\fR - Unicode value as an integer, e.g. \fB37\fR for a
|
||||
percentage symbol
|
||||
|
||||
Note that the row numbers shown in the font data are relative to the
|
||||
natural font baseline. If comparing two fonts, be aware that when the
|
||||
glyph is drawn, the row number may be affected by the global descender
|
||||
value for the font (displayed with \fB\-i\fR).
|
||||
|
||||
.SH "EXAMPLES"
|
||||
.TP
|
||||
\fBxrdp\-dumpfv1 -i @xrdpdatadir@/sans-10.fv1\fR
|
||||
Displays global information about the sans 10 font file distributed with xrdp.
|
||||
|
||||
.TP
|
||||
\fBxrdp\-dumpfv1 -c @'*' @xrdpdatadir@/sans-10.fv1\fR
|
||||
Displays information about the asterisk symbol in the sans 10 font file distributed with xrdp.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR xrdp\-mkfv1(8).
|
||||
|
||||
More info on \fBxrdp\fR can be found on the
|
||||
.UR @xrdphomeurl@
|
||||
xrdp homepage
|
||||
.UE
|
@ -9,48 +9,44 @@
|
||||
|
||||
.SH "SYNTAX"
|
||||
.B xrdp\-genkeymap
|
||||
.I file
|
||||
.I [ options ] file
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
\fBxrdp\-genkeymap\fR extracts the key map used by the currently running X session to generated a mapping from Remote Desktop Protocol (RDP) key codes to X keysyms and Unicode code points.
|
||||
\fBxrdp\-genkeymap\fR extracts the current key map from the X server
|
||||
X session to generate a mapping from Remote Desktop Protocol (RDP)
|
||||
scan codes to X keysyms and Unicode code points.
|
||||
|
||||
Before running this utility, make sure the keymap is correct, by issuing
|
||||
the correct \fIsetxkbmap\fP command(s).
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I outfile
|
||||
.B -k 'keycode_set'
|
||||
Inform \fBxrdp\-genkeymap\fR of the keycode set in operation (evdev or
|
||||
base), so that the correct scan code to keycode mapping table is selected
|
||||
to generate the keymap.
|
||||
|
||||
If you omit this option, the XKB extension is asked to provide the
|
||||
name of the keycode set.
|
||||
|
||||
.TP
|
||||
.B -c 'comment'
|
||||
Adds a comment to the top of the generated file.
|
||||
|
||||
This option may be repeated more than once to add multiple comments to
|
||||
the top of the file.
|
||||
.TP
|
||||
.B outfile
|
||||
The key map information is stored in the file named \fIoutfile\fP.
|
||||
|
||||
.SH "FILES"
|
||||
.TP
|
||||
.I @sysconfdir@/xrdp/km-XXXXXXXX.ini
|
||||
Files containing the keyboard mapping for language \fIXXXXXXXX\fP, which is a 8 digit hexadecimal number identifying the country and language code.
|
||||
.RS 8
|
||||
.TP
|
||||
.B 00000405
|
||||
cs Czech
|
||||
.TP
|
||||
.B 00000407
|
||||
de German
|
||||
.TP
|
||||
.B 00000409
|
||||
en-us US English
|
||||
.TP
|
||||
.B 0000040c
|
||||
fr French
|
||||
.TP
|
||||
.B 00000410
|
||||
it Italian
|
||||
.TP
|
||||
.B 00000416
|
||||
br Portuguese (Brazil)
|
||||
.TP
|
||||
.B 00000419
|
||||
ru Russian
|
||||
.TP
|
||||
.B 0000041d
|
||||
se Swedish
|
||||
.TP
|
||||
.B 00000809
|
||||
en-uk UK English
|
||||
.I @sysconfdir@/xrdp/km-XXXXXXXX.toml
|
||||
Files containing the keyboard mapping for country and language \fIXXXXXXXX\fP.
|
||||
\fIXXXXXXXX\fP is a 8 digit hexadecimal number, representing the \fIinput
|
||||
locale identifier\fP.
|
||||
|
||||
The input locale identifier is passed from the RDP client when it connects.
|
||||
.RE
|
||||
|
||||
.SH "AUTHORS"
|
||||
@ -60,8 +56,15 @@ Simone Fedele <ilsimo@users.sourceforge.net>
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR xrdp (8),
|
||||
.BR xrdp-km.toml (5),
|
||||
.BR setxkbmap (1),
|
||||
.BR unicode (7)
|
||||
|
||||
.PP
|
||||
Input locale identifiers on the
|
||||
.UR https://go.microsoft.com/fwlink/?LinkId=202824
|
||||
Microsoft website
|
||||
.UE
|
||||
.PP
|
||||
Description of Keyboard Input mapping on the
|
||||
.UR https://github.com/FreeRDP/FreeRDP/wiki/Keyboard
|
||||
|
129
docs/man/xrdp-km.toml.5.in
Normal file
129
docs/man/xrdp-km.toml.5.in
Normal file
@ -0,0 +1,129 @@
|
||||
.\"
|
||||
.TH "xrdp-km.toml" "5" "@PACKAGE_VERSION@" "xrdp team" ""
|
||||
.SH "NAME"
|
||||
\fBxrdp-km.toml\fR \- \fBxrdp\fP key mapping file
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
Key mapping files are located at \fB@sysconfdir@/xrdp/km-XXXXXXXX.toml\fP
|
||||
where \fBXXXXXXXX\fP is the input locale identifier sent by the RDP client.
|
||||
|
||||
The key mapping files are used to translate RDP scan codes into one of
|
||||
the following forms:-
|
||||
.TP
|
||||
.B X11 KeySyms
|
||||
These are used when \fBxrdp\fP connects to a VNC server.
|
||||
.TP
|
||||
.B Unicode characters
|
||||
These are used on the \fBxrdp\fP login screen.
|
||||
.RE
|
||||
.PP
|
||||
Each keymap file consists of several sections. Each section starts with
|
||||
the section name in square brackets, followed by a list of
|
||||
\fIparameter\fR=\fIvalue\fR lines.
|
||||
|
||||
.SH "SECTIONS"
|
||||
The following sections are recognized:
|
||||
.TP
|
||||
\fB[Globals]\fR
|
||||
Global configuration
|
||||
|
||||
.TP
|
||||
\fB[noshift]\fR
|
||||
Key mappings if no modifier keys (i.e. shift, alt gr, caps lock) are down.
|
||||
.TP
|
||||
\fB[shift]\fR
|
||||
Key mappings if the shift key is down.
|
||||
.TP
|
||||
\fB[altgr]\fR
|
||||
Key mappings if the alt gr key is down.
|
||||
.TP
|
||||
\fB[shiftaltgr]\fR
|
||||
Key mappings if the shift and alt gr keys are down.
|
||||
.TP
|
||||
\fB[capslock]\fR
|
||||
Key mappings if the caps lock key is down.
|
||||
.TP
|
||||
\fB[shiftcapslock]\fR
|
||||
Key mappings if the caps lock and shift keys are down.
|
||||
.TP
|
||||
\fB[shiftcapslockaltgr]\fR
|
||||
Key mappings if the shift, caps lock and alt gr keys are down.
|
||||
.TP
|
||||
\fB[numlock]\fR
|
||||
Key mappings if the numlock key is down.
|
||||
|
||||
.LP
|
||||
All parameters and values are case
|
||||
insensitive, and are described in detail below. If any parameter is
|
||||
specified more than once, the last entry will be used. Options specified
|
||||
outside their proper section will be \fIignored\fR.
|
||||
|
||||
.SH "GLOBALS Section"
|
||||
Following parameters can be used in the \fB[Globals]\fR section.
|
||||
|
||||
.TP
|
||||
\fBVersion\fR=\fInumber\fR
|
||||
Version of the file format in use.
|
||||
Can be used to check for file format mis-matches when a file is loaded.
|
||||
.RE
|
||||
|
||||
.SH "Keymap Sections"
|
||||
All other sections contain lines formatted in one of the following
|
||||
ways:-
|
||||
|
||||
.TP
|
||||
<scancode>=<KeySym>
|
||||
.TP
|
||||
<scancode>=<KeySymNum>:<unicode-char>
|
||||
.RE
|
||||
|
||||
Each line may also be followed by a comment (preceded by '#') which
|
||||
contains more information about the key, for example a KeySym string.
|
||||
|
||||
.TP
|
||||
.B scancode
|
||||
A \fBscancode\fP is an RDP scancode received from the client. These
|
||||
correspond to Windows "Scan Code Set 1" scan codes, and can be displayed
|
||||
in Windows by using an appropriate utility.
|
||||
|
||||
The \fBscancode\fP is in one of these two forms:-
|
||||
|
||||
.RS 8
|
||||
.TP
|
||||
.B <hex-digit><hex-digit>
|
||||
Standard scancodes. For example, '1C' refers to the enter key.
|
||||
These are 'key down' scancodes, and so are always between 00 and 7F.
|
||||
.TP
|
||||
.B E0_<hex-digit><hex-digit>
|
||||
Extended scancodes. For example, 'E0_1C' refers to the enter key on the numeric keypad.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.B KeySymNum
|
||||
A decimal number representing an X11 KeySym
|
||||
|
||||
.TP
|
||||
.B unicode-char
|
||||
A string of the format \fBU+XXXX\fP \fBU+XXXXX\fP,, \fBU+XXXXX\fP,
|
||||
where \fBX\fP is a hexadecimal digit.
|
||||
.RE
|
||||
|
||||
.SH "Limitations"
|
||||
This file format has the following limitations.
|
||||
.IP \(bu
|
||||
Not all combinations of shift keys are stored in the file. For example,
|
||||
at present there is no section for shift and numlock combined.
|
||||
.IP \(bu
|
||||
Modifier keys, other than the ones supported above, are not supported.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR xrdp-genkeymap (8)
|
||||
|
||||
.PP
|
||||
Scancode mappings for most keyboards at
|
||||
.UR https://kbdlayout.info
|
||||
.UE
|
||||
|
||||
For more info on \fBxrdp\fR see
|
||||
.UR @xrdphomeurl@
|
||||
.UE
|
81
docs/man/xrdp-mkfv1.8.in
Normal file
81
docs/man/xrdp-mkfv1.8.in
Normal file
@ -0,0 +1,81 @@
|
||||
.TH "xrdp-mkfv1" "8" "@PACKAGE_VERSION@" "xrdp team"
|
||||
.SH NAME
|
||||
xrdp\-mkfv1 \- Create .fv1 font files from other font files
|
||||
|
||||
.SH SYNOPSIS
|
||||
\fBxrdp-mkfv1\fR [ options ] font_file fv1_file
|
||||
|
||||
.SH DESCRIPTION
|
||||
\fBxrdp\-mkfv1\fP can be used to convert a font file such as a TrueType
|
||||
font to a fv1 file.
|
||||
|
||||
.SH OPTIONS
|
||||
A summary of options is included below.
|
||||
|
||||
.TP
|
||||
\fB\-n\fR <font_name>
|
||||
Give the font a name, which is stored in the font header.
|
||||
|
||||
The default is to use the font family name from the source font.
|
||||
|
||||
.TP
|
||||
\fB\-p\fR <number>
|
||||
Set the point size of the font. A fixed DPI value of 96 is used for
|
||||
converting this value into a pixel size.
|
||||
|
||||
The default value for this option is '10'.
|
||||
|
||||
.TP
|
||||
\fB\-m\fR <glyph>
|
||||
Set the limit on the glyphs stored in the font file. The argument is the last
|
||||
glyph stored in the font file.
|
||||
|
||||
Specify the glyph using one of the following strings:
|
||||
|
||||
\fBU+<hex>\fR - Unicode character, e.g. \fBU+25\fR for a percentage symbol (%).
|
||||
|
||||
\fB@<char>\fR - Unicode character, e.g. \fB@%\fR for a percentage symbol.
|
||||
|
||||
\fBnumber\fR - Unicode value as an integer, e.g. \fB37\fR for a
|
||||
percentage symbol
|
||||
|
||||
The default value for this option is 'U+4DFF'.
|
||||
|
||||
.TP
|
||||
\fB\-C\fR
|
||||
When used with the "DejaVu Sans" font at a point-size of 10, a small
|
||||
number of glyphs are assigned a different x-offset than they have
|
||||
when the original Windows font generation program is used.
|
||||
|
||||
This switch can be used to preserve the original x-offsets for glyphs in
|
||||
the range U+0020 - U+00FF when a 10 point DajaVu Sans font is generated.
|
||||
|
||||
Use one of the following arguments to this option:-
|
||||
|
||||
\fBauto\fR - Automatic mode. Offsets are preserved if a "DajaVu Sans" 10-point font is converted.
|
||||
|
||||
\fBon / true / yes\fR - Preserve offsets if automatic font detection does not work.
|
||||
|
||||
\fBoff / false / no\fR - Do not tamper with the offsets generated by the program.
|
||||
|
||||
The default value of this switch is \fRauto\fR.
|
||||
|
||||
To see the effects of this switch, set the \fBMKFV1_LOG_LEVEL\fR environment
|
||||
variable to \fBinfo\fR before running the program.
|
||||
|
||||
.SH "EXAMPLES"
|
||||
.TP
|
||||
\fBxrdp-mkfv1 -p18 /path/to/DejaVuSans.ttf ./sans-18.fv1\fR
|
||||
Generate an 18-point Deja Sans font.
|
||||
|
||||
.TP
|
||||
\fBxrdp-mkfv1 -C off -p10 /path/to/DejaVuSans.ttf ./sans-10.fv1\fR
|
||||
Generate a 10-point DajaVu Sans font using natural offsets.
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR xrdp\-dumpfv1(8).
|
||||
|
||||
More info on \fBxrdp\fR can be found on the
|
||||
.UR @xrdphomeurl@
|
||||
xrdp homepage
|
||||
.UE
|
@ -18,23 +18,17 @@ command.
|
||||
A summary of options is included below.
|
||||
.TP
|
||||
.BI \-u= username
|
||||
\fIUsername\fP for authentication on the server.
|
||||
Defaults to \fBroot\fP.
|
||||
Retained for compatibility, but ignored.
|
||||
|
||||
.TP
|
||||
.BI \-p= password
|
||||
The \fIpassword\fP to authenticate with.
|
||||
The default is to ask for the password interactively.
|
||||
|
||||
.TP
|
||||
.BI \-s= server
|
||||
The host address of the \fIserver\fP to connect to.
|
||||
Defaults to \fBlocalhost\fP.
|
||||
Retained for compatibility, but ignored.
|
||||
|
||||
.TP
|
||||
.BI \-i= port
|
||||
The TCP \fIport\fP number to connect to.
|
||||
Defaults to \fB3350\fP.
|
||||
The sesman \fIUNIX domain socket\fP to connect to.
|
||||
Defaults to \fBsesman.socket\fP.
|
||||
If no path is specified for the socket, a default of @socketdir@ is used.
|
||||
|
||||
.TP
|
||||
.BI \-c= command
|
||||
@ -43,7 +37,7 @@ Valid commands are:
|
||||
.RS 4
|
||||
.TP
|
||||
.B list
|
||||
List currently active sessions.
|
||||
List active sessions for the current user.
|
||||
.TP
|
||||
.BI kill: sid
|
||||
Kills the session specified the given \fIsession id\fP.
|
||||
|
@ -7,6 +7,9 @@ xrdp\-sesman \- \fBxrdp\fR(8) session manager
|
||||
\-\-kill
|
||||
.br
|
||||
.B xrdp\-sesman
|
||||
\-\-reload
|
||||
.br
|
||||
.B xrdp\-sesman
|
||||
\-\-help
|
||||
.br
|
||||
.B xrdp\-sesman
|
||||
@ -25,6 +28,9 @@ It manages user sessions by authenticating the user and starting the appropriate
|
||||
\fB\-k\fR, \fB\-\-kill\fR
|
||||
Kills running \fBxrdp\-sesman\fR daemon.
|
||||
.TP
|
||||
\fB\-r\fR, \fB\-\-reload\fR
|
||||
Reloads running \fBxrdp\-sesman\fR daemon.
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
Output help information and exit.
|
||||
.TP
|
||||
@ -48,6 +54,11 @@ If you use this option, be aware that you will have to have a
|
||||
the system (notably \fBxrdp(8)\fR and \fBxrdp\-chansrv(8)\fR) will want
|
||||
to read it.
|
||||
.RE
|
||||
.SH "SIGNALS"
|
||||
.TP
|
||||
\fBSIGHUP\fR
|
||||
Causes \fBxrdp\-sesman\fR to reload its configuration. Needed if you're
|
||||
not running \fBxrdp\-sesman\fR as a daemon.
|
||||
.SH "FILES"
|
||||
@sbindir@/xrdp\-sesman
|
||||
.br
|
||||
@ -58,6 +69,8 @@ to read it.
|
||||
@localstatedir@/log/xrdp\-sesman.log
|
||||
.br
|
||||
@localstatedir@/run/xrdp\-sesman.pid
|
||||
.br
|
||||
@socketdir@/sesman.socket
|
||||
|
||||
.SH "AUTHORS"
|
||||
Jay Sorg <jsorg71@users.sourceforge.net>
|
||||
|
@ -4,18 +4,28 @@
|
||||
|
||||
.SH "SYNTAX"
|
||||
.B xrdp\-sesrun
|
||||
.I [ options ] username
|
||||
.I --help
|
||||
.br
|
||||
|
||||
.B xrdp\-sesrun
|
||||
.I [ options ] [ username ]
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
\fBxrdp\-sesrun\fR starts a session using \fBxrdp\-sesman\fR(8).
|
||||
.br
|
||||
This is a tool useful for testing, it simply behaves like xrdp when some
|
||||
This is a tool useful for testing. It simply behaves like xrdp when some
|
||||
user logs in a new session and authenticates, thus starting a new session.
|
||||
|
||||
Default values for the options are set at compile-time. Run the utility without
|
||||
a username to see what the defaults are for your installation.
|
||||
Default values for the options are set at compile-time. Run the utility with
|
||||
the '--help' option to see what the defaults are for your installation.
|
||||
|
||||
The utility prompts for a password if neither \fB-p\fR or \fB-F\fR is used.
|
||||
If no username is used, the current username is used, and no password
|
||||
needs to be provided. In this instance, it is important that any necessary
|
||||
authentication tokens for a GUI session (e.g. a Kerberos ticket) have
|
||||
already been acquired.
|
||||
|
||||
If a username is provided, a password must also be provided. In this instance
|
||||
the utility prompts for a password if neither \fB-p\fR or \fB-F\fR is used.
|
||||
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
@ -29,13 +39,8 @@ option may not do what you expect.
|
||||
Set session bits-per-pixel (colour depth). Some session types (i.e. Xorg)
|
||||
will ignore this setting.
|
||||
.TP
|
||||
.B -s <server>
|
||||
Server on which sesman is running (probably 'localhost').
|
||||
.br
|
||||
Use of this option is discouraged as it will be removed in the future.
|
||||
.TP
|
||||
.B -t <session-type>
|
||||
Session type - one of Xorg, Xvnc or X11rdp. Alternatively, for testing
|
||||
Session type - one of Xorg or Xvnc. Alternatively, for testing
|
||||
only, use the numeric session code.
|
||||
.TP
|
||||
.B -D <directory>
|
||||
@ -65,6 +70,10 @@ Override the default logging level. One of "error", "warn", "info",
|
||||
.SH "EXAMPLES"
|
||||
.TP
|
||||
.B
|
||||
xrdp-sesrun
|
||||
Create a default session for the current user.
|
||||
.TP
|
||||
.B
|
||||
xrdp-sesrun -F 0 user1 <passwd.txt
|
||||
Create a default session for user \fBuser1\fR with a password from
|
||||
a file
|
||||
|
@ -107,7 +107,9 @@ If not specified or set to \fB0\fP, unlimited.
|
||||
|
||||
.TP
|
||||
\fBpamerrortxt\fP=\fIerror_text\fP
|
||||
Specify text passed to PAM when authentication failed. The maximum length is \fB256\fP.
|
||||
Specify additional text displayed to user if authentication fails. The maximum length is \fB256\fP.
|
||||
|
||||
The use of 'pam' in the name of this option is historic
|
||||
|
||||
.TP
|
||||
\fBport\fP=\fIport\fP
|
||||
@ -118,22 +120,48 @@ Multiple address:port instances must be separated by spaces or commas. Check the
|
||||
Specifying interfaces requires said interfaces to be UP before xrdp starts.
|
||||
|
||||
.TP
|
||||
\fBrequire_credentials\fP=\fI[true|false]\fP
|
||||
\fBruntime_user\fP=\fIusername\fP
|
||||
.TP
|
||||
\fBruntime_group\fP=\fIgroupname\fP
|
||||
User name and group to run the xrdp daemon under.
|
||||
|
||||
After xrdp starts, it sets its UID and GID to values derived from these
|
||||
settings, so that it's running without system privilege.
|
||||
|
||||
The \fBruntime_group\fP MUST be set to the same value as
|
||||
\fBSessionSockdirGroup\fP in \fBsesman.ini\fP if you want to run sessions.
|
||||
|
||||
A suitable user and group can be added with a command like this (Linux):-
|
||||
|
||||
useradd xrdp -d / -c 'xrdp daemon' -s /usr/sbin/nologin
|
||||
|
||||
In order to establish secure connections, the xrdp daemon needs permission
|
||||
to access sensitive cryptographic files. After changing either or both
|
||||
of these values, check that xrdp has access to required files by running
|
||||
this script:-
|
||||
|
||||
@xrdpdatadir@/xrdp-chkpriv
|
||||
|
||||
.TP
|
||||
\fBenable_token_login\fP=\fI[true|false]\fP
|
||||
If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP will scan the user name provided by the
|
||||
client for the ASCII field separator character (0x1F). It will then copy over what is after the
|
||||
separator as the password supplied by the user and treats it as autologon. If not specified,
|
||||
defaults to \fBfalse\fP.
|
||||
|
||||
.TP
|
||||
\domain_user_separator\fP=\separator\fP
|
||||
\fBdomain_user_separator\fP=\fBseparator\fP
|
||||
If specified the domain name supplied by the client is appended to the username separated
|
||||
by \fBseparator\fP.
|
||||
|
||||
.TP
|
||||
\enable_token_login\fP=\fI[true|false]\fP
|
||||
If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP requires clients to include username and
|
||||
password initial connection phase. In other words, xrdp doesn't allow clients to show login
|
||||
screen if set to true. If not specified, defaults to \fBfalse\fP.
|
||||
\fBrequire_credentials\fP=\fI[true|false]\fP
|
||||
If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP requires clients
|
||||
to include username and password initial connection phase. In other
|
||||
words, xrdp doesn't allow clients to show login screen if set to true.
|
||||
It follows that an incorrect password will cause the login to immediately
|
||||
fail without displaying the login screen. If not specified, defaults
|
||||
to \fBfalse\fP.
|
||||
|
||||
.TP
|
||||
\fBsecurity_layer\fP=\fI[tls|rdp|negotiate]\fP
|
||||
@ -175,7 +203,9 @@ If set to \fB1\fP, \fBtrue\fP or \fByes\fP, no buffering will be performed in th
|
||||
\fBtcp_send_buffer_bytes\fP=\fIbuffer_size\fP
|
||||
.TP
|
||||
\fBtcp_recv_buffer_bytes\fP=\fIbuffer_size\fP
|
||||
Specify send/recv buffer sizes in bytes. The default value depends on operating system.
|
||||
Specify send/recv buffer sizes in bytes. The default value depends on
|
||||
the operating system. It is recommended not to set these on systems with
|
||||
dynamic TCP buffer sizing
|
||||
|
||||
.TP
|
||||
\fBtls_ciphers\fP=\fIcipher_suite\fP
|
||||
@ -212,13 +242,25 @@ These options override the colors used internally by \fBxrdp\fP(8) to draw the l
|
||||
Colors are defined using a hexadecimal (hex) notation for the combination of Red, Green, and Blue color values (RGB).
|
||||
The lowest value that can be given to one of the light sources is 0 (hex 00).
|
||||
The highest value is 255 (hex FF).
|
||||
.TP
|
||||
\fBfv1_select\fP=\fI130:sans-18.fv1,0:sans-10.fv1\fP
|
||||
Selects a default fv1 font.
|
||||
This parameter is a comma-separated list of DPI:name pairs. The list
|
||||
is scanned from left-to-right. The font used is the first font whose DPI
|
||||
value is less-than-or-equal to the vertical DPI of the monitor used for
|
||||
the login screen.
|
||||
.TP
|
||||
\fBdefault_dpi\fP=\fI96\fP
|
||||
Default DPI used for a monitor if the client does not send physical
|
||||
size information.
|
||||
|
||||
|
||||
.SH "LOGGING"
|
||||
The following parameters can be used in the \fB[Logging]\fR section:
|
||||
|
||||
.TP
|
||||
\fBLogFile\fR=\fI@localstatedir@/log/xrdp.log\fR
|
||||
This options contains the path to logfile. It can be either absolute or relative.\fR
|
||||
This options contains the path to logfile. It can be either absolute or relative. If set to \fB<stdout>\fR, log will go to stdout. Use for debugging only\fR
|
||||
|
||||
.TP
|
||||
\fBLogLevel\fR=\fIlevel\fR
|
||||
@ -322,7 +364,7 @@ Specifies the port number to connect to. If set to \fI\-1\fR, the default port f
|
||||
.TP
|
||||
\fBxserverbpp\fR=\fI<number>\fR
|
||||
Specifies color depth of the backend X server. The default is the color
|
||||
depth of the client. Only Xvnc and X11rdp use that setting. Xorg runs at
|
||||
depth of the client. Only Xvnc uses that setting. Xorg runs at
|
||||
\fI24\fR bpp.
|
||||
|
||||
.TP
|
||||
@ -335,18 +377,26 @@ values supported for a particular release of \fBxrdp\fR(8) are documented in
|
||||
|
||||
.TP
|
||||
\fBcode\fR=\fI<number>\fR|\fI0\fR
|
||||
Specifies the session type. The default, \fI0\fR, is Xvnc, \fI10\fR is
|
||||
X11rdp, and \fI20\fR is Xorg with xorgxrdp modules.
|
||||
Specifies the session type. The default, \fI0\fR, is Xvnc,
|
||||
and \fI20\fR is Xorg with xorgxrdp modules.
|
||||
|
||||
.TP
|
||||
\fBchansrvport\fR=\fBDISPLAY(\fR\fIn\fR\fB)\fR|\fI/path/to/domain-socket\fR
|
||||
\fBchansrvport\fR=\fBDISPLAY(\fR\fIn\fR\fB)\fR|\fBDISPLAY(\fR\fIn,u\fR\fB)\fR||\fI/path/to/domain-socket\fR
|
||||
Asks xrdp to connect to a manually started \fBxrdp-chansrv\fR instance.
|
||||
This can be useful if you wish to use to use xrdp to connect to a VNC session
|
||||
which has been started other than by \fBxrdp-sesman\fR, as you can then make
|
||||
use of \fBxrdp\-chansrv\fR facilities in the VNC session.
|
||||
|
||||
The first form of this setting is recommended, replacing \fIn\fR with the
|
||||
X11 display number of the session.
|
||||
Either the first or second form of this setting is recommended. Replace
|
||||
\fIn\fR with the X11 display number of the session, and (if applicable)
|
||||
\fIu\fR with the numeric ID of the session. The second form is only
|
||||
required if \fBxrdp\fR is unable to determine the session uid from the
|
||||
other values in the connection block.
|
||||
|
||||
.TP
|
||||
\fBkeycode_set\fR=\fI<string>\fR
|
||||
[Xorg only] Asks for the specified keycode set to be used by the X server.
|
||||
Normally "evdev" or "base". The default should be correct for your system.
|
||||
|
||||
.SH "EXAMPLES"
|
||||
This is an example \fBxrdp.ini\fR:
|
||||
|
@ -1,56 +0,0 @@
|
||||
Compile FAQ
|
||||
|
||||
Q. I get one of the following errors:
|
||||
- "security/pam_appl.h: File or directory doesn't exist"
|
||||
- "configure: error: please install libpam0g-dev or pam-devel"
|
||||
What is wrong?
|
||||
|
||||
A. You need to install the pam development package.
|
||||
For Debian / Ubuntu this package is called libpam0g-dev.
|
||||
For Red Hat / SUSE this package is called pam-devel.
|
||||
|
||||
|
||||
Q. I get an error: "configure: error: please install libssl-dev or openssl-devel"
|
||||
|
||||
A. You need to install the openssl development package.
|
||||
For Debian / Ubuntu this package is called libssl-dev.
|
||||
For Red Hat / Fedora this package is called openssl-devel.
|
||||
For SUSE / openSUSE this package is called libopenssl-devel.
|
||||
|
||||
|
||||
Q. I get one of the following errors:
|
||||
- "configure: error: please install libx11-dev or libX11-devel"
|
||||
- "configure: error: please install libx11-dev and libxfixes-dev or libXfixes-devel"
|
||||
|
||||
A. You need to install the X11 and X11 Xfixes development package(s).
|
||||
For Debian: libx11-dev and libxfixes-dev.
|
||||
For Red Hat / SUSE: libX11-devel and libXfixes-devel.
|
||||
|
||||
|
||||
Q. I get an error: "rail.c:31:35: fatal error: X11/extensions/Xrandr.h: No such file or directory"
|
||||
|
||||
A. You need to install the Xrandr development package.
|
||||
For Debian / Ubuntu this package is called libxrandr-dev.
|
||||
For SUSE / openSUSE this package is called libXrandr-devel.
|
||||
|
||||
Q. How do I configure the same continuous integration bulids for my XRDP fork as the official XRDP repository?
|
||||
|
||||
A. The XRDP project uses both Travis-CI.org and Cirrus-CI.com for continuous integration.
|
||||
Both of these services are free for open source projects (both the official
|
||||
repository and forks), and these services integrate with Github to build any
|
||||
changes pushed to public Github repositories.
|
||||
|
||||
To configure Travis CI for your XRDP fork on github:
|
||||
1. Follow Travis CI instructions for connecting your github account to Travis CI
|
||||
https://docs.travis-ci.com/user/tutorial/#to-get-started-with-travis-ci-using-github
|
||||
2. In the Travis CI dashboard setting page select your XRDP fork repository for building pushed branches.
|
||||
3. Push a commit to a branch in your XRDP fork on github and Travis CI should
|
||||
start building the branch because the XRDP repository already contain a .travis.yml file.
|
||||
|
||||
To configure Cirrus CI for your XRDP fork on github:
|
||||
1. Follow Cirrus CI instructions for connecting your github account to Cirrus CI
|
||||
https://cirrus-ci.org/guide/quick-start/
|
||||
2. In the Github setting page for the Cirrus CI application, enable Cirrus CI
|
||||
access to your XRDP fork repository.
|
||||
3. Push a commit to a branch in your XRDP fork on github and Cirrus CI should
|
||||
start building the branch because the XRDP repository already contain a .cirrus.yml file.
|
@ -1,22 +0,0 @@
|
||||
General FAQ
|
||||
|
||||
Q. What is RDP?
|
||||
|
||||
A. RDP stands for Remote Desktop Protocol. It's the protocol used by Windows
|
||||
terminal servers to talk to the terminal server clients.
|
||||
|
||||
|
||||
Q. What is xrdp?
|
||||
|
||||
A. xrdp, usually spelled in lower case, is as open source implementation of the
|
||||
RDP protocol.
|
||||
|
||||
|
||||
Q. I can't get xrdp to compile in Ubuntu. What can I do?
|
||||
|
||||
A. See faq-compile.txt.
|
||||
|
||||
|
||||
Q. Can I use LDAP?
|
||||
|
||||
A. Yes, xrdp uses PAM and thus can be configured to use LDAP for authentication.
|
78
file-loc.txt
78
file-loc.txt
@ -1,78 +0,0 @@
|
||||
|
||||
default build will install the following
|
||||
|
||||
/usr/local/lib/xrdp
|
||||
libcommon.so
|
||||
libmc.so
|
||||
libscp.so
|
||||
libvnc.so
|
||||
libxrdp.so
|
||||
libxrdpapi.so
|
||||
libxup.so
|
||||
|
||||
/usr/local/bin
|
||||
xrdp-dis
|
||||
xrdp-genkeymap
|
||||
xrdp-keygen
|
||||
xrdp-sesadmin
|
||||
xrdp-sesrun
|
||||
|
||||
/usr/local/sbin
|
||||
xrdp
|
||||
xrdp-sesman
|
||||
xrdp-sessvc
|
||||
xrdp-chansrv
|
||||
|
||||
/etc/xrdp
|
||||
km-xxxxxxxx.ini
|
||||
sesman.ini
|
||||
rsakeys.ini
|
||||
startwm.sh
|
||||
xrdp.ini
|
||||
xrdp_keyboard.ini
|
||||
|
||||
/etc/xrdp/pulse
|
||||
default.pa
|
||||
|
||||
/etc/pam.d
|
||||
xrdp-sesman
|
||||
|
||||
/usr/local/share/man/man1
|
||||
xrdp-dis.1
|
||||
|
||||
/usr/local/share/man/man5
|
||||
sesman.ini.5
|
||||
xrdp.ini.5
|
||||
|
||||
/usr/local/share/man/man8
|
||||
xrdp-chansrv.8
|
||||
xrdp-genkeymap.8
|
||||
xrdp-keygen.8
|
||||
xrdp-sesadmin.8
|
||||
xrdp-sesman.8
|
||||
xrdp-sesrun.8
|
||||
xrdp-sessvc.8
|
||||
xrdp.8
|
||||
|
||||
/usr/local/share/xrdp
|
||||
ad24b.bmp
|
||||
ad256.bmp
|
||||
cursor0.cur
|
||||
cursor1.cur
|
||||
sans-10.fv1
|
||||
xrdp24b.bmp
|
||||
xrdp256.bmp
|
||||
xrdp_logo.bmp
|
||||
|
||||
when running, the following are created and written to
|
||||
|
||||
/var/run
|
||||
xrdp.pid
|
||||
sesman.pid
|
||||
|
||||
/var/log
|
||||
xrdp.log
|
||||
xrdp-sesman.log
|
||||
|
||||
/tmp/.xrdp
|
||||
xrdp*
|
34
fontutils/Makefile.am
Normal file
34
fontutils/Makefile.am
Normal file
@ -0,0 +1,34 @@
|
||||
EXTRA_DIST = windows
|
||||
|
||||
# Some programs need freetype2 to build
|
||||
if USE_FREETYPE2
|
||||
MKFV1 = xrdp-mkfv1
|
||||
else
|
||||
MKFV1 =
|
||||
endif
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_builddir) \
|
||||
-I$(top_srcdir)/common \
|
||||
$(FREETYPE2_CFLAGS)
|
||||
|
||||
bin_PROGRAMS = \
|
||||
$(MKFV1) \
|
||||
xrdp-dumpfv1
|
||||
|
||||
xrdp_mkfv1_SOURCES = \
|
||||
mkfv1.c \
|
||||
fv1.c \
|
||||
fv1.h
|
||||
|
||||
xrdp_mkfv1_LDADD = \
|
||||
$(top_builddir)/common/libcommon.la \
|
||||
$(FREETYPE2_LIBS)
|
||||
|
||||
xrdp_dumpfv1_SOURCES = \
|
||||
dumpfv1.c \
|
||||
fv1.c \
|
||||
fv1.h
|
||||
|
||||
xrdp_dumpfv1_LDADD = \
|
||||
$(top_builddir)/common/libcommon.la
|
87
fontutils/README_fv1.txt
Normal file
87
fontutils/README_fv1.txt
Normal file
@ -0,0 +1,87 @@
|
||||
The fv1 font format has the following characteristics:-
|
||||
|
||||
1) Bitmap fonts (i.e. pixels are on or off)
|
||||
2) 96 DPI is assumed
|
||||
3) Glyphs from U+0020 up to a pre-defined limit are stored in the file.
|
||||
At the time of writing this limit is U+4DFF. To change the limit
|
||||
requires a change to xrdp/xrdp_types.h and (potentially)
|
||||
fontutils/mkfv1.c
|
||||
4) Font format is header, plus a variable data area for each glyph.
|
||||
|
||||
The intention (over time) is to build support for the freetype2 library
|
||||
directly into xrdp. This will allow for modern font features like
|
||||
anti-aliasing and kerning to be supported.
|
||||
|
||||
General Info
|
||||
------------
|
||||
All numeric values are 2 octets, and stored in twos-complement
|
||||
little-endian format.
|
||||
|
||||
Dimensions are all measured in pixels.
|
||||
|
||||
Font header
|
||||
-----------
|
||||
|
||||
signature 4 octets File signature - "FNT1"
|
||||
font~name 32 octets Null-terminated if less that 32 octets long
|
||||
point_size 2 octets Assumes 96 DPI.
|
||||
style 2 octets Unused. Set to 1.
|
||||
body_height 2 octets Line spacing for font.
|
||||
min_descender 2 octets The common lowest descender value in the font
|
||||
glyphs (A few glyphs may be lower than
|
||||
this). Used to calculate where the font baseline
|
||||
is in relation to the text box for the font.
|
||||
<padding> 4 octets Set to zero.
|
||||
|
||||
Older fonts, generated for xrdp v.0.9x and earlier, have zero values
|
||||
for the body_height and min_descender. For these fonts, the body height is
|
||||
calculated as (-baseline + 1) for the first glyph, and the glyphs are
|
||||
all offset so that a min_descender of 0 works OK.
|
||||
|
||||
Glyph data
|
||||
----------
|
||||
The header is followed by a number of glyphs representing U+0020 upwards. The
|
||||
glyphs have a variable size. The format of each glyph is as follows:-
|
||||
|
||||
width 2 octets Width of character data
|
||||
height 2 octets Height of character data
|
||||
baseline 2 octets Offset from font baseline to 1st row of glyph data
|
||||
offset 2 octets Space before glyph is drawn (can be -ve)
|
||||
inc_by 2 octets Total width of glyph + spacing. The width of
|
||||
a string is obtained by adding up all the inc_by
|
||||
fields for all the glyphs
|
||||
data <variable> Bitmap data.
|
||||
|
||||
Bitmap data is laid out in rows from top to bottom. Within each row the
|
||||
most significant bit of each octet is on the left. Row data is padded
|
||||
to the nearest octet (e.g. a 14 bit width would be padded by 2 bits to
|
||||
16 bits (2 octets). The total data is padded out with between 0 and 3
|
||||
octets to end on a 4-octet boundary.
|
||||
|
||||
Example glyph:-
|
||||
|
||||
Glyph : U+0067
|
||||
Width : 12
|
||||
Height : 18
|
||||
Baseline : -13
|
||||
Offset : 1
|
||||
Inc By : 15
|
||||
Data :
|
||||
-13: ...XXXXX..XX 1F 30
|
||||
-12: ..XXXXXXXXXX 3F F0
|
||||
-11: .XXX....XXXX 70 F0
|
||||
-10: XXX......XXX E0 70
|
||||
-9: XX........XX C0 30
|
||||
-8: XX........XX C0 30
|
||||
-7: XX........XX C0 30
|
||||
-6: XX........XX C0 30
|
||||
-5: XX........XX C0 30
|
||||
-4: XXX......XXX E0 70
|
||||
-3: .XXX....XXXX 70 F0
|
||||
-2: ..XXXXXXXXXX 3F F0
|
||||
-1: ...XXXXX..XX 1F 30
|
||||
+0: ..........XX 00 30
|
||||
+1: .........XXX 00 70
|
||||
+2: ..X.....XXX. 20 E0
|
||||
+3: ..XXXXXXXX.. 3F C0
|
||||
+4: ...XXXXXX... 1F 80
|
413
fontutils/dumpfv1.c
Normal file
413
fontutils/dumpfv1.c
Normal file
@ -0,0 +1,413 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2004-2022
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* fonts
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "os_calls.h"
|
||||
#include "parse.h"
|
||||
#include "string_calls.h"
|
||||
#include "fv1.h"
|
||||
|
||||
/**
|
||||
* What the program is doing
|
||||
*/
|
||||
enum program_mode
|
||||
{
|
||||
PM_UNSPECIFIED = 0,
|
||||
PM_INFO,
|
||||
PM_GLYPH_INFO_TABLE,
|
||||
PM_SHOW_CHAR
|
||||
};
|
||||
|
||||
/**
|
||||
* Parsed program arguments
|
||||
*/
|
||||
struct program_args
|
||||
{
|
||||
const char *font_file;
|
||||
enum program_mode mode;
|
||||
int ucode; /* Unicode character to display in 'c' mode */
|
||||
};
|
||||
|
||||
/**************************************************************************//**
|
||||
* Parses the program args
|
||||
*
|
||||
* @param argc Passed to main
|
||||
* @param @argv Passed to main
|
||||
* @param pa program_pargs structure for resulting values
|
||||
* @return !=0 for success
|
||||
*/
|
||||
static int
|
||||
parse_program_args(int argc, char *argv[], struct program_args *pa)
|
||||
{
|
||||
int params_ok = 1;
|
||||
int opt;
|
||||
|
||||
pa->font_file = NULL;
|
||||
pa->mode = PM_UNSPECIFIED;
|
||||
pa->ucode = 0;
|
||||
|
||||
while ((opt = getopt(argc, argv, "c:it")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'i':
|
||||
if (pa->mode == PM_UNSPECIFIED)
|
||||
{
|
||||
pa->mode = PM_INFO;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Can't have two modes set");
|
||||
params_ok = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (pa->mode == PM_UNSPECIFIED)
|
||||
{
|
||||
pa->mode = PM_GLYPH_INFO_TABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Can't have two modes set");
|
||||
params_ok = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (pa->mode == PM_UNSPECIFIED)
|
||||
{
|
||||
pa->mode = PM_SHOW_CHAR;
|
||||
if (toupper(optarg[0]) == 'U' && optarg[1] == '+')
|
||||
{
|
||||
char *hex = g_strdup(optarg);
|
||||
hex[0] = '0';
|
||||
hex[1] = 'x';
|
||||
pa->ucode = g_atoix(hex);
|
||||
g_free(hex);
|
||||
}
|
||||
else if (optarg[0] == '@')
|
||||
{
|
||||
pa->ucode = optarg[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
pa->ucode = g_atoix(optarg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Can't have two modes set");
|
||||
params_ok = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(LOG_LEVEL_ERROR, "Unrecognised switch '%c'", (char)opt);
|
||||
params_ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc <= optind)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "No font file specified");
|
||||
params_ok = 0;
|
||||
}
|
||||
else if ((argc - optind) > 1)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Unexpected arguments after font file");
|
||||
params_ok = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pa->font_file = argv[optind];
|
||||
}
|
||||
|
||||
return params_ok;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Displays information about a font file
|
||||
*
|
||||
* @param fv1 loaded font file
|
||||
*/
|
||||
static void
|
||||
display_font_file_info(const struct fv1_file *fv1)
|
||||
{
|
||||
g_printf("Font name : %s\n", fv1->font_name);
|
||||
g_printf("Point size (%d DPI) : %d\n", FV1_DEVICE_DPI, fv1->point_size);
|
||||
g_printf("Style : %d\n", fv1->style);
|
||||
if (fv1->body_height == 0 && fv1->glyphs->count > 0)
|
||||
{
|
||||
const struct fv1_glyph *g =
|
||||
(const struct fv1_glyph *)fv1->glyphs->items[0];
|
||||
g_printf("Body height : %d (from 1st glyph)\n", -g->baseline + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_printf("Body height : %d\n", fv1->body_height);
|
||||
}
|
||||
g_printf("Descender : %d\n", fv1->min_descender);
|
||||
|
||||
if (fv1->glyphs->count == 0)
|
||||
{
|
||||
g_printf("\nFile contains no glyphs\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_printf("Min glyph index : U+%04X\n", FV1_MIN_CHAR);
|
||||
g_printf("Max glyph index : U+%04X\n", FV1_GLYPH_END(fv1) - 1);
|
||||
|
||||
/* Work out the statistics */
|
||||
unsigned short max_width = 0;
|
||||
int max_width_ucode = 0;
|
||||
unsigned short max_height = 0;
|
||||
int max_height_ucode = 0;
|
||||
short min_baseline = 0;
|
||||
int min_baseline_ucode = 0;
|
||||
short min_offset = 0;
|
||||
int min_offset_ucode = 0;
|
||||
short max_offset = 0;
|
||||
int max_offset_ucode = 0;
|
||||
unsigned short max_inc_by = 0;
|
||||
int max_inc_by_ucode = 0;
|
||||
|
||||
/* Derived quantities */
|
||||
short min_y_descender = SHRT_MAX;
|
||||
int min_y_descender_ucode = 0;
|
||||
int max_datasize = -1;
|
||||
int max_datasize_ucode = 0;
|
||||
|
||||
/* Loop and output macros */
|
||||
#define SET_MIN(ucode,field,val) \
|
||||
if ((field) < (val)) \
|
||||
{ \
|
||||
val = (field); \
|
||||
val##_ucode = (ucode); \
|
||||
}
|
||||
|
||||
#define SET_MAX(ucode,field,val) \
|
||||
if ((field) > (val)) \
|
||||
{ \
|
||||
val = (field); \
|
||||
val##_ucode = (ucode); \
|
||||
}
|
||||
|
||||
#define OUTPUT_INFO(string, val) \
|
||||
if (val##_ucode > 0) \
|
||||
{ \
|
||||
g_printf(string, val, val##_ucode); \
|
||||
}
|
||||
int u;
|
||||
for (u = FV1_MIN_CHAR ; u < FV1_GLYPH_END(fv1); ++u)
|
||||
{
|
||||
const struct fv1_glyph *g = FV1_GET_GLYPH(fv1, u);
|
||||
if (g != NULL)
|
||||
{
|
||||
short y_descender = - (g->baseline + g->height);
|
||||
int datasize = FONT_DATASIZE(g);
|
||||
|
||||
SET_MAX(u, g->width, max_width);
|
||||
SET_MAX(u, g->height, max_height);
|
||||
SET_MIN(u, g->baseline, min_baseline);
|
||||
SET_MIN(u, g->offset, min_offset);
|
||||
SET_MAX(u, g->offset, max_offset);
|
||||
SET_MAX(u, g->inc_by, max_inc_by);
|
||||
SET_MIN(u, y_descender, min_y_descender);
|
||||
SET_MAX(u, datasize, max_datasize);
|
||||
}
|
||||
}
|
||||
|
||||
OUTPUT_INFO("Max glyph width : %d (U+%04X)\n", max_width);
|
||||
OUTPUT_INFO("Max glyph height : %d (U+%04X)\n", max_height);
|
||||
OUTPUT_INFO("Min glyph y-baseline : %d (U+%04X)\n", min_baseline);
|
||||
OUTPUT_INFO("Min glyph y-descender : %d (U+%04X)\n", min_y_descender);
|
||||
OUTPUT_INFO("Min glyph x-offset : %d (U+%04X)\n", min_offset);
|
||||
OUTPUT_INFO("Max glyph x-offset : %d (U+%04X)\n", max_offset);
|
||||
OUTPUT_INFO("Max glyph x-inc_by : %d (U+%04X)\n", max_inc_by);
|
||||
OUTPUT_INFO("Max glyph datasize : %d (U+%04X)\n", max_datasize);
|
||||
|
||||
#undef SET_MIN
|
||||
#undef SET_MAX
|
||||
#undef OUTPUT_INFO
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Display info in a table about all the glyphs
|
||||
* @param fv1 font file
|
||||
*/
|
||||
static void
|
||||
display_glyph_info_table(const struct fv1_file *fv1)
|
||||
{
|
||||
int u;
|
||||
g_printf("character,width,height,baseline,offset,inc_by,datasize\n");
|
||||
|
||||
for (u = FV1_MIN_CHAR; u < FV1_GLYPH_END(fv1); ++u)
|
||||
{
|
||||
const struct fv1_glyph *g = FV1_GET_GLYPH(fv1, u);
|
||||
if (g != NULL)
|
||||
{
|
||||
int datasize = FONT_DATASIZE(g);
|
||||
g_printf("%d,%hu,%hu,%hd,%hd,%hu,%d\n",
|
||||
u, g->width, g->height, g->baseline,
|
||||
g->offset, g->inc_by, datasize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Converts a font data row to a printable string
|
||||
*
|
||||
* @param rowdata Pointer to the first byte of the row data
|
||||
* @param width Number of pixels in the row
|
||||
* @param out Output buffer. Must be sized by the caller to be at
|
||||
* least width+1 bytes
|
||||
*/
|
||||
static void
|
||||
row_to_str(const unsigned char *rowdata, int width, char *out)
|
||||
{
|
||||
int x;
|
||||
int mask = 1 << 7;
|
||||
for (x = 0 ; x < width ; ++x)
|
||||
{
|
||||
out[x] = ((*rowdata & mask) != 0) ? 'X' : '.';
|
||||
mask >>= 1;
|
||||
if (mask == 0)
|
||||
{
|
||||
mask = 1 << 7;
|
||||
++rowdata;
|
||||
}
|
||||
}
|
||||
out[width] = '\0';
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Display info about a specific glyph
|
||||
* @param ucode Unicode character value
|
||||
* @param g Glyph
|
||||
*/
|
||||
static void
|
||||
display_glyph_info(int ucode, const struct fv1_glyph *g)
|
||||
{
|
||||
|
||||
char *row_buffer = (char *)g_malloc(g->width + 1, 0);
|
||||
if (row_buffer == NULL)
|
||||
{
|
||||
g_printf("<No memory>\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_printf("Glyph : U+%04X\n", ucode);
|
||||
g_printf(" Width : %d\n", g->width);
|
||||
g_printf(" Height : %d\n", g->height);
|
||||
g_printf(" Baseline : %d\n", g->baseline);
|
||||
g_printf(" Offset : %d\n", g->offset);
|
||||
g_printf(" Inc By : %d\n", g->inc_by);
|
||||
|
||||
g_printf(" Data :\n");
|
||||
int y;
|
||||
const unsigned char *dataptr = g->data;
|
||||
|
||||
for (y = 0 ; y < g->height; ++y)
|
||||
{
|
||||
row_to_str(dataptr, g->width, row_buffer);
|
||||
g_printf(" %+3d: %s\n", y + g->baseline, row_buffer);
|
||||
dataptr += (g->width + 7) / 8;
|
||||
}
|
||||
g_free(row_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Main
|
||||
*
|
||||
* @param argc Argument count
|
||||
* @param argv Arguments
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct fv1_file *fv1 = NULL;
|
||||
struct log_config *logging;
|
||||
struct program_args pa;
|
||||
int rv = 1;
|
||||
|
||||
logging = log_config_init_for_console(LOG_LEVEL_WARNING,
|
||||
g_getenv("DUMPFV1_LOG_LEVEL"));
|
||||
log_start_from_param(logging);
|
||||
log_config_free(logging);
|
||||
|
||||
if (parse_program_args(argc, argv, &pa) &&
|
||||
(fv1 = fv1_file_load(pa.font_file)) != NULL)
|
||||
{
|
||||
switch (pa.mode)
|
||||
{
|
||||
case PM_INFO:
|
||||
display_font_file_info(fv1);
|
||||
rv = 0;
|
||||
break;
|
||||
|
||||
case PM_GLYPH_INFO_TABLE:
|
||||
display_glyph_info_table(fv1);
|
||||
rv = 0;
|
||||
break;
|
||||
|
||||
case PM_SHOW_CHAR:
|
||||
if (pa.ucode < FV1_MIN_CHAR)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Value for -c must be at least U+%04X",
|
||||
FV1_MIN_CHAR);
|
||||
}
|
||||
else if (pa.ucode >= FV1_GLYPH_END(fv1))
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"Value for -c must be less than U+%04X",
|
||||
FV1_GLYPH_END(fv1));
|
||||
}
|
||||
else
|
||||
{
|
||||
const struct fv1_glyph *g =
|
||||
(const struct fv1_glyph *)
|
||||
list_get_item(fv1->glyphs, pa.ucode - FV1_MIN_CHAR);
|
||||
display_glyph_info(pa.ucode, g);
|
||||
rv = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(LOG_LEVEL_ERROR, "Specify one of '-i' or '-c'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fv1_file_free(fv1);
|
||||
log_end();
|
||||
|
||||
return rv;
|
||||
}
|
352
fontutils/fv1.c
Normal file
352
fontutils/fv1.c
Normal file
@ -0,0 +1,352 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2004-2022
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fontutils/fv1.c
|
||||
* @brief Definitions relating to fv1 font files
|
||||
*/
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "os_calls.h"
|
||||
#include "parse.h"
|
||||
#include "string_calls.h"
|
||||
#include "fv1.h"
|
||||
|
||||
const static char FV1_SIGNATURE[] = {'F', 'N', 'T', '1'};
|
||||
|
||||
/*****************************************************************************/
|
||||
struct fv1_glyph *
|
||||
fv1_alloc_glyph(int ucode,
|
||||
unsigned short width,
|
||||
unsigned short height)
|
||||
{
|
||||
int datasize = FONT_DATASIZE_FROM_GEOMETRY(width, height);
|
||||
struct fv1_glyph *glyph = NULL;
|
||||
char ucode_str[16] = {'\0'};
|
||||
if (ucode < 0)
|
||||
{
|
||||
g_snprintf(ucode_str, sizeof(ucode_str), "Glyph");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_snprintf(ucode_str, sizeof(ucode_str), "Glyph:U+%04X", ucode);
|
||||
}
|
||||
|
||||
if (datasize < 0 || datasize > FV1_MAX_GLYPH_DATASIZE)
|
||||
{
|
||||
|
||||
/* shouldn't happen */
|
||||
LOG(LOG_LEVEL_ERROR, "%s - datasize %d out of bounds",
|
||||
ucode_str, datasize);
|
||||
}
|
||||
else
|
||||
{
|
||||
glyph = (struct fv1_glyph *)
|
||||
g_malloc( offsetof(struct fv1_glyph, data) + datasize, 1);
|
||||
|
||||
if (glyph == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "%s - out of memory", ucode_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
glyph->width = width;
|
||||
glyph->height = height;
|
||||
}
|
||||
}
|
||||
|
||||
return glyph;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
struct fv1_file *
|
||||
fv1_file_create(void)
|
||||
{
|
||||
struct fv1_file *fv1 = (struct fv1_file *)g_new0(struct fv1_file, 1);
|
||||
if (fv1 == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "fv1_file_create - out of memory");
|
||||
}
|
||||
else
|
||||
{
|
||||
fv1->style = 1; /* Unused at present - compatibility value */
|
||||
fv1->glyphs = list_create();
|
||||
fv1->glyphs->auto_free = 1;
|
||||
}
|
||||
return fv1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static void
|
||||
add_glyphs_from_stream(struct fv1_file *fv1, struct stream *s)
|
||||
{
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
int datasize;
|
||||
|
||||
struct fv1_glyph *glyph;
|
||||
|
||||
while (s_check_rem(s, 4))
|
||||
{
|
||||
in_sint16_le(s, width);
|
||||
in_sint16_le(s, height);
|
||||
|
||||
datasize = FONT_DATASIZE_FROM_GEOMETRY(width, height);
|
||||
|
||||
if (datasize < 0 || datasize > FV1_MAX_GLYPH_DATASIZE)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"Font:%s Glyph:%d - datasize %d out of bounds",
|
||||
fv1->font_name, FV1_GLYPH_END(fv1), datasize);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, 6 + 6 + datasize))
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"Font:%s Glyph:%d - not enough data for glyph",
|
||||
fv1->font_name, FV1_GLYPH_END(fv1));
|
||||
break;
|
||||
}
|
||||
|
||||
if ((glyph = fv1_alloc_glyph(FV1_GLYPH_END(fv1), width, height)) == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
in_sint16_le(s, glyph->baseline);
|
||||
in_sint16_le(s, glyph->offset);
|
||||
in_sint16_le(s, glyph->inc_by);
|
||||
in_uint8s(s, 6);
|
||||
|
||||
in_uint8a(s, glyph->data, datasize);
|
||||
|
||||
list_add_item(fv1->glyphs, (tintptr)glyph);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
struct fv1_file *
|
||||
fv1_file_load(const char *filename)
|
||||
{
|
||||
struct fv1_file *fv1 = NULL;
|
||||
|
||||
if (!g_file_exist(filename))
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Can't find font file %s", filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
int file_size = g_file_get_size(filename);
|
||||
if (file_size < FV1_MIN_FILE_SIZE || file_size > FV1_MAX_FILE_SIZE)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Font file %s has bad size %d",
|
||||
filename, file_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct stream *s;
|
||||
int fd;
|
||||
make_stream(s);
|
||||
init_stream(s, file_size + 1024);
|
||||
fd = g_file_open_ro(filename);
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Can't open font file %s", filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
int b = g_file_read(fd, s->data, file_size + 1024);
|
||||
g_file_close(fd);
|
||||
|
||||
if (b < FV1_MIN_FILE_SIZE)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Font file %s is too small",
|
||||
filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
char sig[sizeof(FV1_SIGNATURE)];
|
||||
s->end = s->data + b;
|
||||
in_uint8a(s, sig, sizeof(FV1_SIGNATURE));
|
||||
if (g_memcmp(sig, FV1_SIGNATURE, sizeof(sig)) != 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"Font file %s has wrong signature",
|
||||
filename);
|
||||
}
|
||||
else if ((fv1 = fv1_file_create()) != NULL)
|
||||
{
|
||||
in_uint8a(s, fv1->font_name, FV1_MAX_FONT_NAME_SIZE);
|
||||
fv1->font_name[FV1_MAX_FONT_NAME_SIZE] = '\0';
|
||||
in_uint16_le(s, fv1->point_size);
|
||||
in_uint16_le(s, fv1->style);
|
||||
in_uint16_le(s, fv1->body_height);
|
||||
in_uint16_le(s, fv1->min_descender);
|
||||
in_uint8s(s, 4);
|
||||
|
||||
add_glyphs_from_stream(fv1, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_stream(s);
|
||||
}
|
||||
}
|
||||
|
||||
return fv1;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
void
|
||||
fv1_file_free(struct fv1_file *fv1)
|
||||
{
|
||||
if (fv1 != NULL)
|
||||
{
|
||||
list_delete(fv1->glyphs);
|
||||
g_free(fv1);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
write_stream(int fd, struct stream *s)
|
||||
{
|
||||
const char *p = s->data;
|
||||
int rv = 1;
|
||||
|
||||
while (p < s->end)
|
||||
{
|
||||
int len = g_file_write(fd, p, s->end - p);
|
||||
if (len <= 0)
|
||||
{
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
p += len;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
fv1_file_save(const struct fv1_file *fv1, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
struct fv1_glyph *blank_glyph; /* Needed for bad characters */
|
||||
|
||||
fd = g_file_open_ex(filename, 0, 1, 1, 1);
|
||||
int rv = 1;
|
||||
if (fd < 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to open %s for writing [%s]", filename,
|
||||
g_get_strerror());
|
||||
}
|
||||
else
|
||||
{
|
||||
struct stream *s;
|
||||
make_stream(s);
|
||||
init_stream(s, 1024);
|
||||
|
||||
/* Write the header */
|
||||
out_uint8a(s, FV1_SIGNATURE, sizeof(FV1_SIGNATURE));
|
||||
int len = g_strlen(fv1->font_name);
|
||||
if (len > FV1_MAX_FONT_NAME_SIZE)
|
||||
{
|
||||
len = FV1_MAX_FONT_NAME_SIZE;
|
||||
}
|
||||
out_uint8a(s, fv1->font_name, len);
|
||||
while (len++ < FV1_MAX_FONT_NAME_SIZE)
|
||||
{
|
||||
out_uint8(s, '\0');
|
||||
}
|
||||
out_uint16_le(s, fv1->point_size);
|
||||
out_uint16_le(s, fv1->style);
|
||||
out_uint16_le(s, fv1->body_height);
|
||||
out_uint16_le(s, fv1->min_descender);
|
||||
out_uint8a(s, "\0\0\0\0", 4);
|
||||
s_mark_end(s);
|
||||
if (!write_stream(fd, s))
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to write file header [%s]",
|
||||
g_get_strerror());
|
||||
}
|
||||
else if ((blank_glyph = fv1_alloc_glyph(-1, 0, 0)) == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to allocate blank glyph");
|
||||
}
|
||||
else
|
||||
{
|
||||
int u;
|
||||
|
||||
for (u = FV1_MIN_CHAR; u < FV1_GLYPH_END(fv1); ++u)
|
||||
{
|
||||
const struct fv1_glyph *g = FV1_GET_GLYPH(fv1, u);
|
||||
int datasize;
|
||||
if (g == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "Glyph %d is not set", u);
|
||||
g = blank_glyph;
|
||||
}
|
||||
else
|
||||
{
|
||||
datasize = FONT_DATASIZE(g);
|
||||
if (datasize > FV1_MAX_GLYPH_DATASIZE)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"glyph %d datasize %d exceeds max of %d"
|
||||
" - glyph will be blank",
|
||||
u, datasize, FV1_MAX_GLYPH_DATASIZE);
|
||||
g = blank_glyph;
|
||||
}
|
||||
}
|
||||
init_stream(s, 16 + FONT_DATASIZE(g));
|
||||
out_uint16_le(s, g->width);
|
||||
out_uint16_le(s, g->height);
|
||||
out_uint16_le(s, g->baseline);
|
||||
out_uint16_le(s, g->offset);
|
||||
out_uint16_le(s, g->inc_by);
|
||||
out_uint8a(s, "\0\0\0\0\0\0", 6);
|
||||
out_uint8a(s, g->data, FONT_DATASIZE(g));
|
||||
s_mark_end(s);
|
||||
|
||||
if (!write_stream(fd, s))
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to write glyph %d [%s]",
|
||||
u, g_get_strerror());
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_free(blank_glyph);
|
||||
|
||||
rv = (u == FV1_GLYPH_END(fv1)) ? 0 : 1;
|
||||
}
|
||||
free_stream(s);
|
||||
g_file_close(fd);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
100
fontutils/fv1.h
Normal file
100
fontutils/fv1.h
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2004-2022
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file fontutils/fv1.h
|
||||
* @brief Definitions relating to fv1 font files
|
||||
*/
|
||||
#if !defined(FV1_H)
|
||||
#define FV1_H
|
||||
|
||||
struct list;
|
||||
|
||||
#define FV1_DEVICE_DPI 96
|
||||
|
||||
#define FV1_MIN_CHAR 0x20 /* First character value in file */
|
||||
|
||||
#define FV1_MIN_FILE_SIZE 48
|
||||
#define FV1_MAX_FILE_SIZE (10 * 1024 * 1024)
|
||||
#define FV1_MAX_FONT_NAME_SIZE 32
|
||||
|
||||
#define FV1_MAX_GLYPH_DATASIZE 512
|
||||
|
||||
struct fv1_glyph
|
||||
{
|
||||
unsigned short width; /* Width of glyph */
|
||||
unsigned short height; /* Height of glyph */
|
||||
short baseline; /* Offset from cursor pos to 1st row of glyph */
|
||||
short offset; /* Space before glyph (can be -ve) */
|
||||
unsigned short inc_by; /* Total width of glyph + spacing */
|
||||
/* Standard C++ does not yet support C99 flexible array members */
|
||||
#ifdef __cplusplus
|
||||
unsigned char data[1];
|
||||
#else
|
||||
unsigned char data[];
|
||||
#endif
|
||||
};
|
||||
|
||||
struct fv1_file
|
||||
{
|
||||
char font_name[FV1_MAX_FONT_NAME_SIZE + 1];
|
||||
short point_size; /* Input point size (for reference) */
|
||||
short style;
|
||||
short body_height; /* Body height (pixels) */
|
||||
short min_descender; /* Min descender of the glyphs in the font */
|
||||
struct list *glyphs; /* Glyphs are struct fv1_glyph * */
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a glyph pointer for a unicode character
|
||||
*/
|
||||
#define FV1_GET_GLYPH(fv1,ucode) \
|
||||
(((ucode) < FV1_MIN_CHAR) \
|
||||
? NULL \
|
||||
: (struct fv1_glyph *)list_get_item(fv1->glyphs, (ucode) - FV1_MIN_CHAR))
|
||||
|
||||
/**
|
||||
* First glyph not in file
|
||||
*/
|
||||
#define FV1_GLYPH_END(fv1) (fv1->glyphs->count + FV1_MIN_CHAR)
|
||||
|
||||
struct fv1_file *
|
||||
fv1_file_load(const char *filename);
|
||||
|
||||
void
|
||||
fv1_file_free(struct fv1_file *);
|
||||
|
||||
struct fv1_file *
|
||||
fv1_file_create(void);
|
||||
|
||||
struct fv1_glyph *
|
||||
fv1_alloc_glyph(int ucode, /* Unicode character for error reporting if known */
|
||||
unsigned short width,
|
||||
unsigned short height);
|
||||
|
||||
enum fv1_realloc_mode
|
||||
{
|
||||
FV1_AT_TOP,
|
||||
FV1_AT_BOTTOM
|
||||
};
|
||||
|
||||
int
|
||||
fv1_file_save(const struct fv1_file *fv1, const char *filename);
|
||||
|
||||
#endif
|
585
fontutils/mkfv1.c
Normal file
585
fontutils/mkfv1.c
Normal file
@ -0,0 +1,585 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2004-2012
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
/* See the FT2 documentation - this builds an error table */
|
||||
#undef FTERRORS_H_
|
||||
#define FT_ERRORDEF( e, v, s ) { e, s },
|
||||
#define FT_ERROR_START_LIST {
|
||||
#define FT_ERROR_END_LIST { 0, NULL } };
|
||||
|
||||
static const struct
|
||||
{
|
||||
int err_code;
|
||||
const char *err_msg;
|
||||
} ft_errors[] =
|
||||
#include <freetype/fterrors.h>
|
||||
#ifdef __cppcheck__
|
||||
// avoid syntaxError by providing the array contents
|
||||
{};
|
||||
#endif
|
||||
|
||||
|
||||
#include "arch.h"
|
||||
#include "defines.h"
|
||||
#include "log.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
#include "fv1.h"
|
||||
|
||||
#define DEFAULT_POINT_SIZE 10
|
||||
#define DEFAULT_MAX_CHAR 0x4dff
|
||||
|
||||
/**
|
||||
* sans10 compatibility choices
|
||||
*/
|
||||
enum sans10_compat
|
||||
{
|
||||
S10_OFF = 0,
|
||||
S10_ON,
|
||||
S10_AUTO
|
||||
};
|
||||
|
||||
/**
|
||||
* Parsed program arguments
|
||||
*/
|
||||
struct program_args
|
||||
{
|
||||
const char *input_file;
|
||||
const char *output_file;
|
||||
char font_name[FV1_MAX_FONT_NAME_SIZE + 1];
|
||||
unsigned short point_size;
|
||||
/** Last character value in file */
|
||||
unsigned int max_ucode;
|
||||
/** Are we generating san10 in compatibility mode? */
|
||||
enum sans10_compat sans10_compatibility;
|
||||
};
|
||||
|
||||
struct x_dimensions
|
||||
{
|
||||
unsigned short width;
|
||||
short offset;
|
||||
unsigned short inc_by;
|
||||
};
|
||||
|
||||
/**
|
||||
* Table of some character settings in the original sans-10.fv1 font
|
||||
*/
|
||||
static const struct x_dimensions
|
||||
original_sans10_data[] =
|
||||
{
|
||||
/* 0x20 - 0x3f */
|
||||
{1, 0, 4}, {1, 2, 5}, {3, 1, 5}, {9, 1, 11},
|
||||
{7, 1, 8}, {11, 0, 12}, {9, 1, 11}, {1, 1, 3},
|
||||
{3, 1, 5}, {3, 1, 5}, {7, 0, 7}, {9, 1, 11},
|
||||
{2, 1, 4}, {3, 1, 5}, {1, 2, 4}, {4, 0, 4},
|
||||
{6, 1, 8}, {5, 2, 8}, {6, 1, 8}, {6, 1, 8},
|
||||
{6, 1, 8}, {6, 1, 8}, {6, 1, 8}, {6, 1, 8},
|
||||
{6, 1, 8}, {6, 1, 8}, {1, 2, 4}, {2, 1, 4},
|
||||
{8, 1, 11}, {8, 1, 11}, {8, 1, 11}, {5, 1, 7},
|
||||
/* 0x40 - 0x5f */
|
||||
{11, 1, 13}, {9, 0, 9}, {7, 1, 9}, {7, 1, 9},
|
||||
{8, 1, 10}, {6, 1, 8}, {5, 1, 7}, {8, 1, 10},
|
||||
{8, 1, 10}, {1, 1, 3}, {3, -1, 3}, {7, 1, 8},
|
||||
{6, 1, 7}, {9, 1, 11}, {8, 1, 10}, {8, 1, 10},
|
||||
{6, 1, 8}, {8, 1, 10}, {7, 1, 8}, {7, 1, 9},
|
||||
{7, 0, 7}, {8, 1, 10}, {9, 0, 9}, {11, 0, 11},
|
||||
{8, 0, 8}, {7, 0, 7}, {8, 1, 10}, {3, 1, 5},
|
||||
{4, 0, 4}, {3, 1, 5}, {8, 1, 11}, {7, 0, 7},
|
||||
/* 0x60 - 0x7f */
|
||||
{3, 1, 7}, {6, 1, 8}, {6, 1, 8}, {5, 1, 7},
|
||||
{6, 1, 8}, {6, 1, 8}, {4, 0, 4}, {6, 1, 8},
|
||||
{6, 1, 8}, {1, 1, 3}, {2, 0, 3}, {6, 1, 7},
|
||||
{1, 1, 3}, {11, 1, 13}, {6, 1, 8}, {6, 1, 8},
|
||||
{6, 1, 8}, {6, 1, 8}, {4, 1, 5}, {5, 1, 7},
|
||||
{4, 0, 5}, {6, 1, 8}, {7, 0, 7}, {9, 0, 9},
|
||||
{7, 0, 7}, {7, 0, 7}, {5, 1, 7}, {5, 2, 8},
|
||||
{1, 2, 4}, {5, 2, 8}, {8, 1, 11}, {7, 1, 8},
|
||||
/* 0x80 - 0x9f */
|
||||
{7, 1, 8}, {7, 1, 8}, {7, 1, 8}, {7, 1, 8},
|
||||
{7, 1, 8}, {7, 1, 8}, {7, 1, 8}, {7, 1, 8},
|
||||
{7, 1, 8}, {7, 1, 8}, {7, 1, 8}, {7, 1, 8},
|
||||
{7, 1, 8}, {7, 1, 8}, {7, 1, 8}, {7, 1, 8},
|
||||
{7, 1, 8}, {7, 1, 8}, {7, 1, 8}, {7, 1, 8},
|
||||
{7, 1, 8}, {7, 1, 8}, {7, 1, 8}, {7, 1, 8},
|
||||
{7, 1, 8}, {7, 1, 8}, {7, 1, 8}, {7, 1, 8},
|
||||
{7, 1, 8}, {7, 1, 8}, {7, 1, 8}, {7, 1, 8},
|
||||
/* 0xa0 - 0xbf */
|
||||
{1, 0, 4}, {1, 2, 5}, {6, 1, 8}, {7, 0, 8},
|
||||
{7, 0, 8}, {7, 1, 8}, {1, 2, 4}, {5, 1, 7},
|
||||
{3, 2, 7}, {9, 2, 13}, {5, 1, 6}, {6, 1, 8},
|
||||
{8, 1, 11}, {3, 1, 5}, {9, 2, 13}, {4, 1, 7},
|
||||
{4, 1, 7}, {9, 1, 11}, {4, 1, 5}, {4, 1, 5},
|
||||
{3, 2, 7}, {7, 1, 8}, {6, 1, 8}, {1, 1, 4},
|
||||
{3, 2, 7}, {3, 1, 5}, {5, 1, 6}, {6, 1, 8},
|
||||
{12, 1, 13}, {11, 1, 13}, {12, 1, 13}, {5, 1, 7},
|
||||
/* 0xc0 - 0xdf */
|
||||
{9, 0, 9}, {9, 0, 9}, {9, 0, 9}, {9, 0, 9},
|
||||
{9, 0, 9}, {9, 0, 9}, {12, 0, 13}, {7, 1, 9},
|
||||
{6, 1, 8}, {6, 1, 8}, {6, 1, 8}, {6, 1, 8},
|
||||
{2, 0, 3}, {2, 1, 3}, {5, -1, 3}, {3, 0, 3},
|
||||
{9, 0, 10}, {8, 1, 10}, {8, 1, 10}, {8, 1, 10},
|
||||
{8, 1, 10}, {8, 1, 10}, {8, 1, 10}, {7, 2, 11},
|
||||
{8, 1, 10}, {8, 1, 10}, {8, 1, 10}, {8, 1, 10},
|
||||
{8, 1, 10}, {7, 0, 7}, {6, 1, 8}, {6, 1, 8},
|
||||
/* 0xe0 - 0xff */
|
||||
{6, 1, 8}, {6, 1, 8}, {6, 1, 8}, {6, 1, 8},
|
||||
{6, 1, 8}, {6, 1, 8}, {11, 1, 13}, {5, 1, 7},
|
||||
{6, 1, 8}, {6, 1, 8}, {6, 1, 8}, {6, 1, 8},
|
||||
{3, 0, 3}, {3, 1, 3}, {5, -1, 3}, {3, 0, 3},
|
||||
{6, 1, 8}, {6, 1, 8}, {6, 1, 8}, {6, 1, 8},
|
||||
{6, 1, 8}, {6, 1, 8}, {6, 1, 8}, {8, 1, 11},
|
||||
{6, 1, 8}, {6, 1, 8}, {6, 1, 8}, {6, 1, 8},
|
||||
{6, 1, 8}, {7, 0, 7}, {6, 1, 8}, {7, 0, 7}
|
||||
};
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* Parses a unicode character value
|
||||
*
|
||||
* @param str String containing value
|
||||
* @return Resulting character value
|
||||
*/
|
||||
static unsigned int
|
||||
parse_ucode_name(const char *str)
|
||||
{
|
||||
unsigned int rv;
|
||||
if (toupper(str[0]) == 'U' && str[1] == '+')
|
||||
{
|
||||
char *hex = g_strdup(str);
|
||||
hex[0] = '0';
|
||||
hex[1] = 'x';
|
||||
rv = g_atoix(hex);
|
||||
g_free(hex);
|
||||
}
|
||||
else if (str[0] == '@')
|
||||
{
|
||||
rv = str[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = g_atoix(str);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Parses the program args
|
||||
*
|
||||
* @param argc Passed to main
|
||||
* @param @argv Passed to main
|
||||
* @param pa program_pargs structure for resulting values
|
||||
* @return !=0 for success
|
||||
*/
|
||||
static int
|
||||
parse_program_args(int argc, char *argv[], struct program_args *pa)
|
||||
{
|
||||
int params_ok = 1;
|
||||
int opt;
|
||||
|
||||
pa->input_file = NULL;
|
||||
pa->output_file = NULL;
|
||||
pa->font_name[0] = '\0';
|
||||
pa->point_size = DEFAULT_POINT_SIZE;
|
||||
pa->max_ucode = DEFAULT_MAX_CHAR;
|
||||
pa->sans10_compatibility = S10_AUTO;
|
||||
|
||||
while ((opt = getopt(argc, argv, "n:p:m:C:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'n':
|
||||
g_snprintf(pa->font_name, FV1_MAX_FONT_NAME_SIZE + 1, "%s",
|
||||
optarg);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
pa->point_size = g_atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
pa->max_ucode = parse_ucode_name(optarg);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
if (toupper(optarg[0]) == 'A')
|
||||
{
|
||||
pa->sans10_compatibility = S10_AUTO;
|
||||
}
|
||||
else if (g_text2bool(optarg))
|
||||
{
|
||||
pa->sans10_compatibility = S10_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
pa->sans10_compatibility = S10_OFF;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(LOG_LEVEL_ERROR, "Unrecognised switch '%c'", (char)opt);
|
||||
params_ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pa->max_ucode < FV1_MIN_CHAR)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "-m argument must be at least %d",
|
||||
FV1_MIN_CHAR);
|
||||
params_ok = 0;
|
||||
}
|
||||
|
||||
switch (argc - optind)
|
||||
{
|
||||
case 0:
|
||||
LOG(LOG_LEVEL_ERROR, "No input file specified");
|
||||
params_ok = 0;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
LOG(LOG_LEVEL_ERROR, "No output file specified");
|
||||
params_ok = 0;
|
||||
break;
|
||||
case 2:
|
||||
pa->input_file = argv[optind];
|
||||
pa->output_file = argv[optind + 1];
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(LOG_LEVEL_ERROR, "Unexpected arguments after output file");
|
||||
params_ok = 0;
|
||||
}
|
||||
|
||||
return params_ok;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Checks whether the specified glyph row is blank
|
||||
* @param g Glyph
|
||||
* @param row Row number between 0 and g->height - 1
|
||||
* @result Boolean
|
||||
*/
|
||||
static int
|
||||
is_blank_glyph_row(const struct fv1_glyph *g, unsigned int row)
|
||||
{
|
||||
if (g->width == 0 || row >= g->height)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
const unsigned int glyph_row_size = ((g->width + 7) / 8);
|
||||
const unsigned char *dataptr = g->data + (row * glyph_row_size);
|
||||
const unsigned int masks[] =
|
||||
{ 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
|
||||
|
||||
/* Check for set pixels in all the leading bytes */
|
||||
unsigned int x;
|
||||
for (x = g->width ; x > 8 ; x -= 8)
|
||||
{
|
||||
if (*dataptr++ != 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use a single test to check the pixels in the last byte */
|
||||
return ((*dataptr & masks[x - 1]) == 0);
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Returns a string for a freetype2 error
|
||||
* @param error Freetype2 error code
|
||||
* @param buff Pointer to buffer for error string
|
||||
* @param bufflen Length of above
|
||||
*/
|
||||
static void
|
||||
get_ft_error(FT_Error error, char *buff, unsigned int bufflen)
|
||||
{
|
||||
const char *errstr = NULL;
|
||||
unsigned int i;
|
||||
for (i = 0 ; i < (sizeof(ft_errors) / sizeof(ft_errors[0])); ++i)
|
||||
{
|
||||
if (ft_errors[i].err_code == error)
|
||||
{
|
||||
errstr = ft_errors[i].err_msg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (errstr != NULL)
|
||||
{
|
||||
g_snprintf(buff, bufflen, "[%s]", errstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_snprintf(buff, bufflen,
|
||||
"[errorcode %d (no description)]", (int)error);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Implement sans10 compatibility for a glyph
|
||||
*
|
||||
* The original Windows font generator made a few different choices for the
|
||||
* character x offset than freetype2 does. These are particularly noticeable
|
||||
* with a small font.
|
||||
*
|
||||
* This routine checks the glyph, and implements the original offset size
|
||||
* for popular English characters, which are all that the user will probably
|
||||
* be displaying with xrdp v0.9.x
|
||||
*
|
||||
* @param g Glyph to check
|
||||
*/
|
||||
static void
|
||||
implement_sans10_compatibility(struct fv1_glyph *g, unsigned int ucode)
|
||||
{
|
||||
const unsigned int max_index =
|
||||
sizeof(original_sans10_data) / sizeof(original_sans10_data[0]);
|
||||
|
||||
if (ucode < FV1_MIN_CHAR || ucode >= max_index + FV1_MIN_CHAR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const struct x_dimensions *d =
|
||||
&original_sans10_data[ucode - FV1_MIN_CHAR];
|
||||
|
||||
if (g->offset != d->offset)
|
||||
{
|
||||
if (g->width != d->width)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"Can't set compatibility offset for U+%04X: width %d != %d",
|
||||
ucode, g->width, d->width);
|
||||
}
|
||||
else if (g->inc_by != d->inc_by)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"Can't set compatibility offset for U+%04X: inc_by %d != %d",
|
||||
ucode, g->inc_by, d->inc_by);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"Changing compatibility offset for U+%04X: from %d to %d",
|
||||
ucode, g->offset, d->offset);
|
||||
}
|
||||
|
||||
g->offset = d->offset;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Converts a freetype 2 bitmap to a fv1 glyph
|
||||
* @param ft_glyph Freetype2 glyph. Must be a monochrome bitmap
|
||||
* @param ucode Unicode character for error reporting
|
||||
* @param pa Program args
|
||||
* @return fv1 glyph, or NULL for error
|
||||
*/
|
||||
static struct fv1_glyph *
|
||||
convert_mono_glyph(FT_GlyphSlot ft_glyph, unsigned int ucode,
|
||||
const struct program_args *pa)
|
||||
{
|
||||
short width = ft_glyph->bitmap.width;
|
||||
short height = ft_glyph->bitmap.rows;
|
||||
struct fv1_glyph *g;
|
||||
|
||||
/* Number of bytes in a glyph row */
|
||||
const unsigned int glyph_row_size = ((width + 7) / 8);
|
||||
|
||||
if ((g = fv1_alloc_glyph(ucode, width, height)) != NULL)
|
||||
{
|
||||
g->baseline = -(ft_glyph->metrics.horiBearingY / 64);
|
||||
g->offset = ft_glyph->metrics.horiBearingX / 64;
|
||||
g->inc_by = ft_glyph->metrics.horiAdvance / 64;
|
||||
|
||||
if (FONT_DATASIZE(g) > 0)
|
||||
{
|
||||
const unsigned char *srcptr = ft_glyph->bitmap.buffer;
|
||||
unsigned char *dstptr = g->data;
|
||||
unsigned int y;
|
||||
|
||||
for (y = 0; y < g->height; ++y)
|
||||
{
|
||||
g_memcpy(dstptr, srcptr, glyph_row_size);
|
||||
dstptr += glyph_row_size;
|
||||
srcptr += ft_glyph->bitmap.pitch;
|
||||
}
|
||||
|
||||
/* Optimise the glyph by removing any blank lines at the bottom
|
||||
* and top */
|
||||
if (g->width > 0)
|
||||
{
|
||||
while (g->height > 0 &&
|
||||
is_blank_glyph_row(g, g->height - 1))
|
||||
{
|
||||
--g->height;
|
||||
}
|
||||
|
||||
y = 0;
|
||||
while (y < g->height && is_blank_glyph_row(g, y))
|
||||
{
|
||||
++y;
|
||||
}
|
||||
|
||||
if (y > 0)
|
||||
{
|
||||
g->baseline += y;
|
||||
g->height -= y;
|
||||
g_memmove(g->data, g->data + (y * glyph_row_size),
|
||||
g->height * glyph_row_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pa->sans10_compatibility != S10_OFF)
|
||||
{
|
||||
implement_sans10_compatibility(g, ucode);
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Main
|
||||
*
|
||||
* @param argc Argument count
|
||||
* @param argv Arguments
|
||||
*/
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
FT_Library library = NULL; /* handle to library */
|
||||
FT_Face face = NULL; /* handle to face object */
|
||||
FT_Error error;
|
||||
struct fv1_glyph *g;
|
||||
struct program_args pa;
|
||||
struct log_config *logging;
|
||||
int rv = 1;
|
||||
|
||||
logging = log_config_init_for_console(LOG_LEVEL_WARNING,
|
||||
g_getenv("MKFV1_LOG_LEVEL"));
|
||||
log_start_from_param(logging);
|
||||
log_config_free(logging);
|
||||
|
||||
struct fv1_file *fv1 = fv1_file_create();
|
||||
|
||||
if (fv1 == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Memory allocation failure");
|
||||
}
|
||||
else if (parse_program_args(argc, argv, &pa))
|
||||
{
|
||||
char errstr[128];
|
||||
|
||||
if ((error = FT_Init_FreeType(&library)) != 0)
|
||||
{
|
||||
get_ft_error(error, errstr, sizeof(errstr));
|
||||
LOG(LOG_LEVEL_ERROR, "Error initializing freetype library %s",
|
||||
errstr);
|
||||
}
|
||||
else if ((error = FT_New_Face(library, pa.input_file, 0, &face)) != 0)
|
||||
{
|
||||
get_ft_error(error, errstr, sizeof(errstr));
|
||||
LOG(LOG_LEVEL_ERROR, "Error loading font file %s %s",
|
||||
pa.input_file, errstr);
|
||||
}
|
||||
else if ((error = FT_Set_Char_Size(face, 0,
|
||||
pa.point_size * 64,
|
||||
FV1_DEVICE_DPI, 0)) != 0)
|
||||
{
|
||||
get_ft_error(error, errstr, sizeof(errstr));
|
||||
LOG(LOG_LEVEL_ERROR, "Error setting point size to %u %s",
|
||||
pa.point_size, errstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *fname =
|
||||
(pa.font_name[0] != '\0') ? pa.font_name :
|
||||
(face->family_name != NULL) ? face->family_name :
|
||||
/* Default */ "";
|
||||
|
||||
g_snprintf(fv1->font_name, FV1_MAX_FONT_NAME_SIZE + 1, "%s", fname);
|
||||
fv1->point_size = pa.point_size;
|
||||
fv1->body_height = face->size->metrics.height / 64;
|
||||
fv1->min_descender = face->size->metrics.descender / 64;
|
||||
|
||||
if (pa.sans10_compatibility == S10_AUTO)
|
||||
{
|
||||
if (g_strcmp(fv1->font_name, "DejaVu Sans") == 0 &&
|
||||
fv1->point_size == 10)
|
||||
{
|
||||
pa.sans10_compatibility = S10_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
pa.sans10_compatibility = S10_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int u;
|
||||
for (u = FV1_MIN_CHAR; u <= pa.max_ucode; ++u)
|
||||
{
|
||||
/* retrieve glyph index from character code */
|
||||
FT_UInt glyph_index = FT_Get_Char_Index(face, u);
|
||||
|
||||
/* load glyph image into the slot (erase previous one) */
|
||||
error = FT_Load_Glyph(face, glyph_index,
|
||||
FT_LOAD_RENDER | FT_LOAD_TARGET_MONO);
|
||||
if (error)
|
||||
{
|
||||
get_ft_error(error, errstr, sizeof(errstr));
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"Unable to get bitmap for U+%04X %s", u, errstr);
|
||||
g = NULL;
|
||||
}
|
||||
else if (face->glyph->format != FT_GLYPH_FORMAT_BITMAP ||
|
||||
face->glyph->bitmap.pixel_mode != FT_PIXEL_MODE_MONO)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"Internal error; U+%04X was not loaded as a bitmap",
|
||||
u);
|
||||
g = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
g = convert_mono_glyph(face->glyph, u, &pa);
|
||||
}
|
||||
list_add_item(fv1->glyphs, (tintptr)g);
|
||||
}
|
||||
|
||||
rv = fv1_file_save(fv1, pa.output_file);
|
||||
}
|
||||
}
|
||||
|
||||
FT_Done_FreeType(library);
|
||||
fv1_file_free(fv1);
|
||||
log_end();
|
||||
|
||||
return rv;
|
||||
}
|
@ -72,14 +72,18 @@ msg(char *msg1, ...)
|
||||
static int
|
||||
show_last_error(void)
|
||||
{
|
||||
LPVOID lpMsgBuf;
|
||||
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&lpMsgBuf, 0, NULL);
|
||||
msg("GetLastError - %s", lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
LPVOID lpMsgBuf = NULL;
|
||||
DWORD len;
|
||||
len = FormatMessageA(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL, GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPSTR)&lpMsgBuf, 0, NULL);
|
||||
if (len > 0)
|
||||
{
|
||||
msg("GetLastError - %s", lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -151,7 +155,7 @@ font_dump(void)
|
||||
g_snprintf(filename, 255, "%s-%d.fv1", g_font_name, g_font_size);
|
||||
msg("creating file %s", filename);
|
||||
g_file_delete(filename);
|
||||
fd = g_file_open(filename);
|
||||
fd = g_file_open_rw(filename);
|
||||
g_file_write(fd, "FNT1", 4);
|
||||
strlen1 = g_strlen(g_font_name);
|
||||
g_file_write(fd, g_font_name, strlen1);
|
||||
@ -462,8 +466,6 @@ create_window(void)
|
||||
{
|
||||
WNDCLASS wc;
|
||||
DWORD style;
|
||||
HDC dc;
|
||||
int height;
|
||||
int left;
|
||||
int top;
|
||||
|
@ -2,15 +2,19 @@ EXTRA_DIST = \
|
||||
dump-keymaps.sh \
|
||||
readme.txt
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/common
|
||||
|
||||
AM_CFLAGS = $(X_CFLAGS)
|
||||
|
||||
bin_PROGRAMS = \
|
||||
xrdp-genkeymap
|
||||
|
||||
xrdp_genkeymap_SOURCES = genkeymap.c evdev-map.c
|
||||
xrdp_genkeymap_SOURCES = genkeymap.c
|
||||
|
||||
xrdp_genkeymap_LDFLAGS = \
|
||||
$(X_LIBS)
|
||||
|
||||
xrdp_genkeymap_LDADD = \
|
||||
$(X_PRE_LIBS) -lX11 $(X_EXTRA_LIBS)
|
||||
$(top_builddir)/common/libcommon.la \
|
||||
$(X_PRE_LIBS) -lxkbfile -lX11 $(X_EXTRA_LIBS)
|
||||
|
@ -1,57 +1,99 @@
|
||||
#!/bin/sh
|
||||
|
||||
which setxkbmap
|
||||
if test $? -ne 0
|
||||
then
|
||||
echo "error, setxkbmap not found"
|
||||
exit 1
|
||||
# Use evdev rules to obtain the mappings
|
||||
XKB_RULES=evdev
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# K B G E N
|
||||
#
|
||||
# Generates a keyboard mapping
|
||||
# $1 - LCID (See [MS-LCID])
|
||||
# $2 - Language tag (See [MS-LCID])
|
||||
# $3 - Current operating system
|
||||
# $4.. Arguments to setxkbmap to select the required keyboard
|
||||
# -----------------------------------------------------------------------------
|
||||
kbgen()
|
||||
{
|
||||
file=$(printf "../instfiles/km-%08s.toml" "$1" | tr ' ' '0')
|
||||
desc="$2"
|
||||
os="$3"
|
||||
shift 3
|
||||
setxkbmap "$@"
|
||||
./xrdp-genkeymap \
|
||||
-c "Description: $desc" \
|
||||
-c "Operating system: $os" \
|
||||
"$file"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# M A I N
|
||||
# -----------------------------------------------------------------------------
|
||||
# Run the keymap extraction in a clean X session
|
||||
if [ "$1" != _IN_XVFB_SESSION_ ]; then
|
||||
# All commands available?
|
||||
ok=1
|
||||
for cmd in setxkbmap xvfb-run xauth; do
|
||||
if ! command -v $cmd >/dev/null
|
||||
then
|
||||
echo "Error. $cmd not found" >&2
|
||||
ok=
|
||||
fi
|
||||
done
|
||||
if [ -z "$ok" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
xvfb-run --auto-servernum --server-args="-noreset" "$0" _IN_XVFB_SESSION_
|
||||
exit $?
|
||||
fi
|
||||
|
||||
# English - US 'en-us' 0x00000409
|
||||
setxkbmap -model pc104 -layout us
|
||||
./xrdp-genkeymap ../instfiles/km-00000409.ini
|
||||
|
||||
# English - US 'dvorak' 0x00010409
|
||||
setxkbmap -model pc104 -layout dvorak
|
||||
./xrdp-genkeymap ../instfiles/km-00010409.ini
|
||||
|
||||
# English - US 'dvp' 0x19360409
|
||||
OLD_SETTINGS=$(setxkbmap -query -verbose 4 | sed "s/^\([a-z]\+\):\s*\(.*\)$/-\1 \2/;s/^-options/-option \"\" -option/;s/,/ -option /g" | xargs -d \\n)
|
||||
setxkbmap -rules xfree86 -model pc105 -layout us -variant dvp -option "" -option compose:102 -option caps:shift -option numpad:sg -option numpad:shift3 -option keypad:hex -option keypad:atm -option kpdl:semi -option lv3:ralt_alt
|
||||
./xrdp-genkeymap ../instfiles/km-19360409.ini
|
||||
|
||||
setxkbmap -rules "$XKB_RULES"
|
||||
|
||||
# Assign NumLock to mod2
|
||||
xmodmap -e "clear mod2" -e "add mod2 = Num_Lock"
|
||||
|
||||
# Find the operating system
|
||||
if command -v hostnamectl >/dev/null; then
|
||||
os=$(hostnamectl status | sed -ne 's/^i *Operating[^:]*: *//p')
|
||||
fi
|
||||
if [ -z "$os" ] && command -v lsb_release -v >/dev/null; then
|
||||
os=$(lsb_release --description --short)
|
||||
fi
|
||||
if [ -z "$os" ]; then
|
||||
os="Unknown"
|
||||
fi
|
||||
|
||||
kbgen 0406 "da-DK" "$os" -model pc105 -layout dk
|
||||
kbgen 0407 "de-DE" "$os" -model pc104 -layout de
|
||||
kbgen 0409 "en-US" "$os" -model pc104 -layout us
|
||||
kbgen 10409 "en-US" "$os" -model pc104 -layout dvorak
|
||||
kbgen 040a "es-ES_tradnl" "$os" -model pc105 -layout es
|
||||
kbgen 040b "fi-FI" "$os" -model pc105 -layout 'fi'
|
||||
kbgen 040c "fr-FR" "$os" -model pc105 -layout fr
|
||||
kbgen 0410 "it-IT" "$os" -model pc104 -layout it
|
||||
kbgen 0411 "ja-JP" "$os" -model pc105 -layout jp -variant OADG109A
|
||||
kbgen 0412 "ko-KR" "$os" -model pc105 -layout kr
|
||||
kbgen 0414 "nb-NO" "$os" -model pc105 -layout no
|
||||
kbgen 0415 "pl-PL" "$os" -model pc104 -layout pl
|
||||
kbgen 0416 "pt-BR" "$os" -model pc105 -layout br
|
||||
kbgen 0419 "ru-RU" "$os" -model pc104 -layout ru
|
||||
kbgen 041d "sv-SE" "$os" -model pc104 -layout se
|
||||
kbgen 0807 "de-CH" "$os" -model pc105 -layout ch
|
||||
kbgen 0809 "en-GB" "$os" -model pc105 -layout gb
|
||||
kbgen 080a "es-MX" "$os" -model pc105 -layout latam
|
||||
kbgen 080c "fr-BE" "$os" -model pc105 -layout be -variant oss
|
||||
kbgen 0813 "nl-BE" "$os" -model pc105 -layout be
|
||||
kbgen 0816 "pt-PT" "$os" -model pc104 -layout pt
|
||||
kbgen 100c "fr-CH" "$os" -model pc105 -layout ch -variant fr
|
||||
|
||||
# Put keyboards which change options below the ones that don't to
|
||||
# prevent unexpected things happening to keypads, etc
|
||||
kbgen 19360409 "en-US" "$os" -model pc105 -layout us -variant dvp \
|
||||
-option "" -option compose:102 -option caps:shift -option numpad:sg \
|
||||
-option numpad:shift3 -option keypad:hex -option keypad:atm \
|
||||
-option kpdl:semi -option lv3:ralt_alt
|
||||
# set back to entry settings
|
||||
# shellcheck disable=SC2086
|
||||
setxkbmap ${OLD_SETTINGS}
|
||||
|
||||
# English - UK 'en-GB' 0x00000809
|
||||
setxkbmap -model pc105 -layout gb
|
||||
./xrdp-genkeymap ../instfiles/km-00000809.ini
|
||||
|
||||
# German 'de' 0x00000407
|
||||
setxkbmap -model pc104 -layout de
|
||||
./xrdp-genkeymap ../instfiles/km-00000407.ini
|
||||
|
||||
# Italian 'it' 0x00000410
|
||||
setxkbmap -model pc104 -layout it
|
||||
./xrdp-genkeymap ../instfiles/km-00000410.ini
|
||||
|
||||
# Japanese 'jp' 0x00000411
|
||||
setxkbmap -model pc105 -layout jp -variant OADG109A
|
||||
./xrdp-genkeymap ../instfiles/km-00000411.ini
|
||||
|
||||
# Polish 'pl' 0x00000415
|
||||
setxkbmap -model pc104 -layout pl
|
||||
./xrdp-genkeymap ../instfiles/km-00000415.ini
|
||||
|
||||
# Russia 'ru' 0x00000419
|
||||
setxkbmap -model pc104 -layout ru
|
||||
./xrdp-genkeymap ../instfiles/km-00000419.ini
|
||||
|
||||
# Sweden 'se' 0x0000041d
|
||||
setxkbmap -model pc104 -layout se
|
||||
./xrdp-genkeymap ../instfiles/km-0000041d.ini
|
||||
|
||||
# Portuguese -PT 'pt-pt' 0x00000816
|
||||
setxkbmap -model pc104 -layout pt
|
||||
./xrdp-genkeymap ../instfiles/km-00000816.ini
|
||||
|
||||
# set back to en-us
|
||||
setxkbmap -model pc104 -layout us
|
||||
|
@ -1,156 +0,0 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
|
||||
/*
|
||||
* evdev-map.c
|
||||
* Copyright (C) Michał Górny 2014 <mgorny@gentoo.org>
|
||||
*
|
||||
* You may redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License, as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* main.cc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with main.cc. If not, write to:
|
||||
* The Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301, USA
|
||||
*
|
||||
* xfree86(base)->evdev keycode mapping
|
||||
*/
|
||||
|
||||
int xfree86_to_evdev[137-8+1] = {
|
||||
/* MDSW */ 203,
|
||||
/* ESC */ 9,
|
||||
/* AE01 */ 10,
|
||||
/* AE02 */ 11,
|
||||
/* AE03 */ 12,
|
||||
/* AE04 */ 13,
|
||||
/* AE05 */ 14,
|
||||
/* AE06 */ 15,
|
||||
/* AE07 */ 16,
|
||||
/* AE08 */ 17,
|
||||
/* AE09 */ 18,
|
||||
/* AE10 */ 19,
|
||||
/* AE11 */ 20,
|
||||
/* AE12 */ 21,
|
||||
/* BKSP */ 22,
|
||||
/* TAB */ 23,
|
||||
/* AD01 */ 24,
|
||||
/* AD02 */ 25,
|
||||
/* AD03 */ 26,
|
||||
/* AD04 */ 27,
|
||||
/* AD05 */ 28,
|
||||
/* AD06 */ 29,
|
||||
/* AD07 */ 30,
|
||||
/* AD08 */ 31,
|
||||
/* AD09 */ 32,
|
||||
/* AD10 */ 33,
|
||||
/* AD11 */ 34,
|
||||
/* AD12 */ 35,
|
||||
/* RTRN */ 36,
|
||||
/* LCTL */ 37,
|
||||
/* AC01 */ 38,
|
||||
/* AC02 */ 39,
|
||||
/* AC03 */ 40,
|
||||
/* AC04 */ 41,
|
||||
/* AC05 */ 42,
|
||||
/* AC06 */ 43,
|
||||
/* AC07 */ 44,
|
||||
/* AC08 */ 45,
|
||||
/* AC09 */ 46,
|
||||
/* AC10 */ 47,
|
||||
/* AC11 */ 48,
|
||||
/* TLDE */ 49,
|
||||
/* LFSH */ 50,
|
||||
/* BKSL */ 51,
|
||||
/* AB01 */ 52,
|
||||
/* AB02 */ 53,
|
||||
/* AB03 */ 54,
|
||||
/* AB04 */ 55,
|
||||
/* AB05 */ 56,
|
||||
/* AB06 */ 57,
|
||||
/* AB07 */ 58,
|
||||
/* AB08 */ 59,
|
||||
/* AB09 */ 60,
|
||||
/* AB10 */ 61,
|
||||
/* RTSH */ 62,
|
||||
/* KPMU */ 63,
|
||||
/* LALT */ 64,
|
||||
/* SPCE */ 65,
|
||||
/* CAPS */ 66,
|
||||
/* FK01 */ 67,
|
||||
/* FK02 */ 68,
|
||||
/* FK03 */ 69,
|
||||
/* FK04 */ 70,
|
||||
/* FK05 */ 71,
|
||||
/* FK06 */ 72,
|
||||
/* FK07 */ 73,
|
||||
/* FK08 */ 74,
|
||||
/* FK09 */ 75,
|
||||
/* FK10 */ 76,
|
||||
/* NMLK */ 77,
|
||||
/* SCLK */ 78,
|
||||
/* KP7 */ 79,
|
||||
/* KP8 */ 80,
|
||||
/* KP9 */ 81,
|
||||
/* KPSU */ 82,
|
||||
/* KP4 */ 83,
|
||||
/* KP5 */ 84,
|
||||
/* KP6 */ 85,
|
||||
/* KPAD */ 86,
|
||||
/* KP1 */ 87,
|
||||
/* KP2 */ 88,
|
||||
/* KP3 */ 89,
|
||||
/* KP0 */ 90,
|
||||
/* KPDL */ 91,
|
||||
/* SYRQ */ 107,
|
||||
/* II5D */ 0,
|
||||
/* LSGT */ 94,
|
||||
/* FK11 */ 95,
|
||||
/* FK12 */ 96,
|
||||
/* HOME */ 110,
|
||||
/* UP */ 111,
|
||||
/* PGUP */ 112,
|
||||
/* LEFT */ 113,
|
||||
/* II65 */ 0,
|
||||
/* RGHT */ 114,
|
||||
/* END */ 115,
|
||||
/* DOWN */ 116,
|
||||
/* PGDN */ 117,
|
||||
/* INS */ 118,
|
||||
/* DELE */ 119,
|
||||
/* KPEN */ 104,
|
||||
/* RCTL */ 105,
|
||||
/* PAUS */ 127,
|
||||
/* PRSC */ 107,
|
||||
/* KPDV */ 106,
|
||||
/* RALT */ 108,
|
||||
/* BRK */ 419,
|
||||
/* LWIN */ 133,
|
||||
/* RWIN */ 134,
|
||||
/* MENU */ 0,
|
||||
/* FK13 */ 191,
|
||||
/* FK14 */ 192,
|
||||
/* FK15 */ 193,
|
||||
/* FK16 */ 194,
|
||||
/* FK17 */ 195,
|
||||
/* KPDC */ 0,
|
||||
/* LVL3 */ 92,
|
||||
/* ALT */ 204,
|
||||
/* KPEQ */ 125,
|
||||
/* SUPR */ 206,
|
||||
/* HYPR */ 207,
|
||||
/* XFER */ 0,
|
||||
/* I02 */ 0,
|
||||
/* NFER */ 0,
|
||||
/* I04 */ 0,
|
||||
/* AE13 */ 132,
|
||||
/* I06 */ 0,
|
||||
/* I07 */ 0,
|
||||
0,
|
||||
0
|
||||
};
|
@ -42,126 +42,411 @@
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/XKBrules.h>
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern int xfree86_to_evdev[137-8+1];
|
||||
#include "scancode.h"
|
||||
#include "xrdp_constants.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
// cppcheck doesn't always set this macro to something in double-quotes
|
||||
#if defined(__cppcheck__)
|
||||
#undef PACKAGE_VERSION
|
||||
#endif
|
||||
|
||||
#if !defined(PACKAGE_VERSION)
|
||||
#define PACKAGE_VERSION "???"
|
||||
#endif
|
||||
|
||||
#define NUM_STATES 9
|
||||
|
||||
#define KEYMAP_FILE_FORMAT_VERSION "2"
|
||||
|
||||
// Scancodes affected by numlock
|
||||
#define IS_KEYPAD_SCANCODE(s) \
|
||||
((s) >= SCANCODE_MIN_NUMLOCK && (s) <= SCANCODE_MAX_NUMLOCK)
|
||||
|
||||
#define MAX_COMMENTS 10
|
||||
|
||||
/**
|
||||
* Contains info about the current keyboard setting
|
||||
*/
|
||||
struct kbd_info
|
||||
{
|
||||
const char *programname;
|
||||
char text[256];
|
||||
char *displayname = NULL;
|
||||
char *outfname;
|
||||
const char *sections[8] = {
|
||||
"noshift", "shift", "altgr", "shiftaltgr",
|
||||
"capslock", "capslockaltgr", "shiftcapslock", "shiftcapslockaltgr"
|
||||
char *keycode_set; ///< See 'setxkbmap -v'
|
||||
char *rules; ///< See 'setxkbmap -query'
|
||||
char *model; ///< See 'setxkbmap -query'
|
||||
char *layout; ///< See 'setxkbmap -query'
|
||||
char *variant; ///< See 'setxkbmap -query'
|
||||
char *options; ///< See 'setxkbmap -query' (comma separated)
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Print brief info about program usage and exit
|
||||
* @param programname Unqualified name of program
|
||||
* @param status Exit status
|
||||
*/
|
||||
static void
|
||||
usage(const char *programname, int status)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [ -k keycode_set] [-c comment] [-c comment...]"
|
||||
" out_filename\n", programname);
|
||||
fprintf(stderr, "Example: %s -r evdev -c \"en-US pc104 keyboard\""
|
||||
" /etc/xrdp/km-00000409.toml\n", programname);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Free a kbd_info struct
|
||||
* @param kbd_info struct to free. May be incomplete or NULL
|
||||
*/
|
||||
static void
|
||||
free_kbd_info(struct kbd_info *kbd_info)
|
||||
{
|
||||
if (kbd_info != NULL)
|
||||
{
|
||||
free(kbd_info->keycode_set);
|
||||
free(kbd_info->rules);
|
||||
free(kbd_info->model);
|
||||
free(kbd_info->layout);
|
||||
free(kbd_info->variant);
|
||||
free(kbd_info->options);
|
||||
free(kbd_info);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Queries the X server to get information about the current keyboard
|
||||
* @param dpy X11 Display
|
||||
* @param programname Unqualified name of program
|
||||
* @return kbd_info struct, or NULL
|
||||
*
|
||||
* The structure may be incomplete if some data could not be obtained
|
||||
*/
|
||||
static struct kbd_info *
|
||||
get_kbd_info(Display *dpy, const char *programname)
|
||||
{
|
||||
struct kbd_info *kbd_info;
|
||||
char *rules;
|
||||
XkbRF_VarDefsRec vd;
|
||||
XkbDescPtr kbdesc = NULL;
|
||||
|
||||
if ((kbd_info = (struct kbd_info *)malloc( sizeof(*kbd_info))) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: Out of memory\n", programname);
|
||||
}
|
||||
else if ((kbdesc = XkbAllocKeyboard()) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: unable to allocate keyboard desc\n",
|
||||
programname);
|
||||
free_kbd_info(kbd_info);
|
||||
kbd_info = NULL;
|
||||
}
|
||||
else if (XkbGetNames(dpy, XkbKeycodesNameMask, kbdesc) != Success)
|
||||
{
|
||||
fprintf(stderr, "%s: unable to obtain keycode name for keyboard\n",
|
||||
programname);
|
||||
free_kbd_info(kbd_info);
|
||||
kbd_info = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *symatom = XGetAtomName(dpy, kbdesc->names->keycodes);
|
||||
kbd_info->keycode_set = strdup(symatom);
|
||||
XFree(symatom);
|
||||
|
||||
if (XkbRF_GetNamesProp(dpy, &rules, &vd) == 0 || rules == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: Couldn't interpret %s property\n",
|
||||
programname, _XKB_RF_NAMES_PROP_ATOM);
|
||||
kbd_info->rules = NULL;
|
||||
kbd_info->model = NULL;
|
||||
kbd_info->layout = NULL;
|
||||
kbd_info->variant = NULL;
|
||||
kbd_info->options = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
kbd_info->rules = rules;
|
||||
kbd_info->model = vd.model;
|
||||
kbd_info->layout = vd.layout;
|
||||
kbd_info->variant = vd.variant;
|
||||
kbd_info->options = vd.options;
|
||||
}
|
||||
}
|
||||
|
||||
if (kbdesc != NULL)
|
||||
{
|
||||
XkbFreeKeyboard(kbdesc, 0, True);
|
||||
}
|
||||
|
||||
return kbd_info;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Outputs a comment containing the last setxkbmap command
|
||||
*
|
||||
* @param outf Output file
|
||||
* @param kbd_info Keyboard info struct
|
||||
*
|
||||
*/
|
||||
static void
|
||||
output_setxkbmap_comment(FILE *outf, const struct kbd_info *kbd_info)
|
||||
{
|
||||
if (kbd_info->model != NULL || kbd_info->layout != NULL ||
|
||||
kbd_info->variant != NULL || kbd_info->options != NULL)
|
||||
{
|
||||
fprintf(outf, "# setxkbmap -rules %s", kbd_info->rules);
|
||||
if (kbd_info->model != NULL)
|
||||
{
|
||||
fprintf(outf, " -model %s", kbd_info->model);
|
||||
}
|
||||
if (kbd_info->layout != NULL)
|
||||
{
|
||||
fprintf(outf, " -layout %s", kbd_info->layout);
|
||||
}
|
||||
if (kbd_info->variant != NULL)
|
||||
{
|
||||
fprintf(outf, " -variant %s", kbd_info->variant);
|
||||
}
|
||||
if (kbd_info->options != NULL)
|
||||
{
|
||||
// Options is comma-separated, but to achieve the same effect
|
||||
// with the command we need to use multiple '-option' args
|
||||
char *optionstr = strdup(kbd_info->options);
|
||||
if (optionstr != NULL)
|
||||
{
|
||||
char *p = strtok(optionstr, ",");
|
||||
fprintf(outf, " -option \"\"");
|
||||
while (p != NULL)
|
||||
{
|
||||
fprintf(outf, " -option %s", p);
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
free(optionstr);
|
||||
}
|
||||
}
|
||||
putc('\n', outf);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Output a section of the keymap file
|
||||
* @param outf Output file
|
||||
* @param dpy X display
|
||||
* @param section name Section name (e.g. 'shift')
|
||||
* @param event_state Modifier state needed for XKeyPressedEvent
|
||||
*/
|
||||
static void
|
||||
output_file_section(FILE *outf,
|
||||
Display *dpy,
|
||||
const char *section_name,
|
||||
unsigned int event_state)
|
||||
{
|
||||
XKeyPressedEvent e =
|
||||
{
|
||||
.type = KeyPress,
|
||||
.serial = 16,
|
||||
.send_event = True,
|
||||
.display = dpy,
|
||||
.state = event_state,
|
||||
.same_screen = True
|
||||
};
|
||||
int states[8] = {0, 1, 0x80, 0x81, 2, 0x82, 3, 0x83};
|
||||
int i;
|
||||
int idx;
|
||||
int char_count;
|
||||
int nbytes = 0;
|
||||
int unicode;
|
||||
Display *dpy;
|
||||
KeySym ks;
|
||||
FILE *outf;
|
||||
XKeyPressedEvent e;
|
||||
const char *ksstr;
|
||||
unsigned short scancode;
|
||||
unsigned int iter = 0;
|
||||
char text[256];
|
||||
wchar_t wtext[256];
|
||||
XkbDescPtr kbdesc;
|
||||
char *symatom;
|
||||
int is_evdev;
|
||||
|
||||
int is_numlock_section = (strcmp(section_name, "numlock") == 0);
|
||||
|
||||
fprintf(outf, "\n[%s]\n", section_name);
|
||||
|
||||
while ((scancode = scancode_get_next(&iter)) != 0)
|
||||
{
|
||||
// Numlock state table can be very small
|
||||
if (is_numlock_section && !IS_KEYPAD_SCANCODE(scancode))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
e.keycode = scancode_to_x11_keycode(scancode);
|
||||
nbytes = XLookupString(&e, text, 255, &ks, NULL);
|
||||
if (ks == NoSymbol)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ksstr = XKeysymToString(ks);
|
||||
if (ksstr == NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
text[nbytes] = 0;
|
||||
char_count = mbstowcs(wtext, text, 255);
|
||||
unicode = 0;
|
||||
|
||||
if (char_count == 1)
|
||||
{
|
||||
unicode = wtext[0];
|
||||
}
|
||||
|
||||
if (scancode > 0x1ff)
|
||||
{
|
||||
fputs("E1_", outf);
|
||||
}
|
||||
else if (scancode > 0xff)
|
||||
{
|
||||
fputs("E0_", outf);
|
||||
}
|
||||
fprintf(outf, "%02X=\"%d", (scancode & 0xff), (int)ks);
|
||||
if (unicode != 0)
|
||||
{
|
||||
fprintf(outf, ":U+%04X", unicode);
|
||||
}
|
||||
fprintf(outf, "\" # %s\n", ksstr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* Main
|
||||
* @param argc Argument count
|
||||
* @param argv Pointers to arguments
|
||||
* @return 0 for success
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *programname;
|
||||
int opt;
|
||||
char *displayname = NULL;
|
||||
char *outfname;
|
||||
const char *sections[NUM_STATES] =
|
||||
{
|
||||
"noshift", "shift", "altgr", "shiftaltgr",
|
||||
"capslock", "capslockaltgr", "shiftcapslock", "shiftcapslockaltgr",
|
||||
"numlock"
|
||||
};
|
||||
int states[NUM_STATES] = {0, 1, 0x80, 0x81, 2, 0x82, 3, 0x83, 0x10};
|
||||
int idx;
|
||||
Display *dpy = NULL;
|
||||
FILE *outf = NULL;
|
||||
const char *comment[MAX_COMMENTS] = {0};
|
||||
int comment_count = 0;
|
||||
const char *keycode_set = NULL;
|
||||
struct kbd_info *kbd_info = NULL;
|
||||
int status = 1;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
programname = argv[0];
|
||||
|
||||
if (argc != 2)
|
||||
if (strrchr(argv[0], '/') != NULL)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s out_filename\n", programname);
|
||||
fprintf(stderr, "Example: %s /etc/xrdp/km-00000409.ini\n", programname);
|
||||
return 1;
|
||||
programname = strrchr(argv[0], '/') + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
programname = argv[0];
|
||||
}
|
||||
|
||||
outfname = argv[1];
|
||||
dpy = XOpenDisplay(displayname);
|
||||
while ((opt = getopt(argc, argv, "c:k:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'c':
|
||||
if (comment_count < MAX_COMMENTS)
|
||||
{
|
||||
comment[comment_count++] = optarg;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
keycode_set = optarg;
|
||||
break;
|
||||
|
||||
default: /* '?' */
|
||||
usage(programname, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if ((optind + 1) != argc)
|
||||
{
|
||||
usage(programname, 1);
|
||||
}
|
||||
|
||||
outfname = argv[optind];
|
||||
|
||||
dpy = XOpenDisplay(displayname);
|
||||
if (!dpy)
|
||||
{
|
||||
fprintf(stderr, "%s: unable to open display '%s'\n",
|
||||
programname, XDisplayName(displayname));
|
||||
return 1;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* check whether evdev is used */
|
||||
kbdesc = XkbAllocKeyboard();
|
||||
if (!kbdesc)
|
||||
if ((kbd_info = get_kbd_info(dpy, programname)) == 0)
|
||||
{
|
||||
// An error has already been logged
|
||||
goto finish;
|
||||
}
|
||||
|
||||
// If the keycode set isn't specified, use the one returned
|
||||
// by the XKB extension
|
||||
if (keycode_set == NULL)
|
||||
{
|
||||
keycode_set = kbd_info->keycode_set;
|
||||
}
|
||||
|
||||
if (scancode_set_keycode_set(keycode_set) != 0)
|
||||
{
|
||||
fprintf(stderr, "%s: keycode set '%s' is not recognised\n",
|
||||
programname, keycode_set);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if ((outf = fopen(outfname, "w")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: unable to create file '%s'\n",
|
||||
programname, outfname);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
fprintf(outf, "# Created by %s V" PACKAGE_VERSION
|
||||
"\n# Key code set: %s\n",
|
||||
programname, keycode_set);
|
||||
|
||||
output_setxkbmap_comment(outf, kbd_info);
|
||||
|
||||
for (idx = 0; idx < comment_count; ++idx)
|
||||
{
|
||||
fprintf(outf, "# %s\n", comment[idx]);
|
||||
}
|
||||
|
||||
fprintf(outf, "\n[General]\nversion=" KEYMAP_FILE_FORMAT_VERSION "\n");
|
||||
|
||||
for (idx = 0; idx < NUM_STATES; idx++) /* Sections and states */
|
||||
{
|
||||
output_file_section(outf, dpy, sections[idx], states[idx]);
|
||||
}
|
||||
|
||||
status = 0; // Successful run
|
||||
|
||||
finish:
|
||||
free_kbd_info(kbd_info);
|
||||
if (dpy != NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: unable to allocate keyboard desc\n",
|
||||
programname);
|
||||
XCloseDisplay(dpy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (XkbGetNames(dpy, XkbKeycodesNameMask, kbdesc) != Success)
|
||||
if (outf != NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: unable to obtain keycode name for keyboard\n",
|
||||
programname);
|
||||
XkbFreeKeyboard(kbdesc, 0, True);
|
||||
XCloseDisplay(dpy);
|
||||
return 1;
|
||||
fclose(outf);
|
||||
}
|
||||
|
||||
symatom = XGetAtomName(dpy, kbdesc->names->keycodes);
|
||||
is_evdev = !strncmp(symatom, "evdev", 5);
|
||||
XFree(symatom);
|
||||
XkbFreeKeyboard(kbdesc, 0, True);
|
||||
|
||||
outf = fopen(outfname, "w");
|
||||
|
||||
if (outf == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: unable to create file '%s'\n", programname, outfname);
|
||||
XCloseDisplay(dpy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.type = KeyPress;
|
||||
e.serial = 16;
|
||||
e.send_event = True;
|
||||
e.display = dpy;
|
||||
e.same_screen = True;
|
||||
|
||||
for (idx = 0; idx < 8; idx++) /* Sections and states */
|
||||
{
|
||||
fprintf(outf, "[%s]\n", sections[idx]);
|
||||
e.state = states[idx];
|
||||
|
||||
for (i = 8; i < 137; i++) /* Keycodes */
|
||||
{
|
||||
if (is_evdev)
|
||||
e.keycode = xfree86_to_evdev[i-8];
|
||||
else
|
||||
e.keycode = i;
|
||||
nbytes = XLookupString(&e, text, 255, &ks, NULL);
|
||||
text[nbytes] = 0;
|
||||
char_count = mbstowcs(wtext, text, 255);
|
||||
unicode = 0;
|
||||
|
||||
if (char_count == 1)
|
||||
{
|
||||
unicode = wtext[0];
|
||||
}
|
||||
|
||||
fprintf(outf, "Key%d=%d:%d\n", i, (int) ks, unicode);
|
||||
}
|
||||
|
||||
if (idx != 7)
|
||||
{
|
||||
fprintf(outf, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
XCloseDisplay(dpy);
|
||||
fclose(outf);
|
||||
return 0;
|
||||
return status;
|
||||
}
|
||||
|
@ -1,43 +1,49 @@
|
||||
Creating a new keymap file.
|
||||
---------------------------
|
||||
Keymap file description
|
||||
-----------------------
|
||||
|
||||
The keymap files are used by the xrdp login screen, and also when
|
||||
sending keyboard input to a VNC server.
|
||||
|
||||
The names of the files are of the format;
|
||||
|
||||
km-xxxxxxxx.ini
|
||||
km-xxxxxxxx.toml
|
||||
|
||||
where the xxxxxxxx is replaced by the hex number of the layout of interest.
|
||||
|
||||
The files have 8 sections;
|
||||
The contents of the files are documented in xrdp-km.toml(5)
|
||||
|
||||
[noshift], [shift], [altgr], [shiftaltgr], [capslock], [capslockaltgr],
|
||||
[shiftcapslock], [shiftcapslockaltgr]
|
||||
See also xrdp-genkeymap(8) which describes the utility used to
|
||||
generate these files.
|
||||
|
||||
In each section there are multiple lines for each key.
|
||||
Creating a new file
|
||||
-------------------
|
||||
|
||||
An example line looks like;
|
||||
To create a new file:-
|
||||
1) Start an X server
|
||||
2) Use the 'setxkbmap' command to get the keyboard configured
|
||||
for the X server.
|
||||
3) Run the 'xrdp-genkeymap' command to extract the keyboard
|
||||
mappings
|
||||
|
||||
Key10=49:49
|
||||
Example: ./xrdp-genkeymap ./km-00000409.toml
|
||||
|
||||
In this line, 10 is the X11 scancode, the first 49 is the keysym value,
|
||||
the second 49 if the unicode value of the key. This is the definition
|
||||
for the 'noshift' '1' key on a en-us keyboard. In this case, the keysym
|
||||
and the unicode value are the same.
|
||||
4) Copy the generated file to /etc/xrdp/
|
||||
|
||||
Here is an example where they are not;
|
||||
Using the X server of your current session may not be a good idea, as
|
||||
session and window managers can interfere with key bindings. A good option
|
||||
is to use an 'Xvfb' dummy X server to do this.
|
||||
|
||||
This is the definition for the backspace key;
|
||||
Key22=65288:8
|
||||
Getting a file added to xrdp
|
||||
----------------------------
|
||||
|
||||
And this is the star on the keypad;
|
||||
Key63=65450:42
|
||||
|
||||
To create a new file run "xrdp-genkeymap <filename>"
|
||||
|
||||
Example: ./xrdp-genkeymap /etc/xrdp/km-00000409.ini
|
||||
|
||||
Note: You need to have enough rights to be able to write to the
|
||||
/etc/xrdp directory.
|
||||
|
||||
Alternatively, create the keymap file in a directory of your choice, then
|
||||
copy or move it over to /etc/xrdp using sudo/su.
|
||||
The file dump-keymaps.sh in this directory is used to auto-generate
|
||||
all keymap files. It runs on Linux currently, but will generate
|
||||
keymap files suitable for any xrdp platform.
|
||||
|
||||
1) Add a line towards the end of this file which causes your mapping to
|
||||
be generated. Use the other lines in this file as a guide.
|
||||
2) Run the dump-keymaps.sh script to generate a new file in
|
||||
instfiles/
|
||||
3) Add your mapping to the list in instfiless/Makefile.am
|
||||
4) Submit a pull request to the project containing the above three
|
||||
changes.
|
||||
|
54
install.txt
54
install.txt
@ -1,54 +0,0 @@
|
||||
|
||||
Installation directions for xrdp.
|
||||
|
||||
Things you need to compile and install. Most systems don't
|
||||
have these installed by default.
|
||||
gcc and make
|
||||
Header files for pam
|
||||
Header files for openssl
|
||||
|
||||
You can build sesman without pam, there is a Makefile parameter
|
||||
for that.
|
||||
I also have a replacement ssl_calls.c to avoid the openssl dependency
|
||||
email me(Jay) for it or see http://server1.xrdp.org/xrdp/openssl.
|
||||
Due to the license, I can't include it in this project.
|
||||
|
||||
http://server1.xrdp.org/xrdp/openssl/
|
||||
|
||||
unpack the tarball
|
||||
|
||||
tar -zxvf xrdp-0.1.tar.gz
|
||||
|
||||
this will create a folder xrdp
|
||||
|
||||
switch to the xrdp folder(cd xrdp)
|
||||
|
||||
run make
|
||||
|
||||
as root, run make install
|
||||
|
||||
This will install most of the files in /usr/local/xrdp.
|
||||
Some files install in /etc/xrdp. These are configuration
|
||||
files.
|
||||
|
||||
files and location
|
||||
/usr/local/xrdp/startwm.sh - script that starts the window manager
|
||||
You may need to edit this file to run your window manager.
|
||||
/etc/sesman.ini - sesman configuration file
|
||||
/etc/rsakeys.ini - rsa stuff
|
||||
/etc/xrdp.ini - xrdp configuration file
|
||||
/var/run/sesman.pid
|
||||
/var/rub/xrdp.pid
|
||||
|
||||
Sesman and xrdp both have to be running as root.
|
||||
You should set them to start when the system starts.
|
||||
You can use xrdp_control.sh script to start them.
|
||||
|
||||
To completely remove xrdp
|
||||
remove directory /usr/local/xrdp
|
||||
remove directory /etc/xrdp
|
||||
remove file /var/run/xrdp.pid
|
||||
remove file /var/run/sesman.pid
|
||||
remove any startup links added to /etc/init.d or /etc/rcX.d
|
||||
|
||||
jay.sorg@gmail.com
|
@ -29,29 +29,29 @@ SUFFIXES = .in
|
||||
startscriptdir=$(sysconfdir)/xrdp
|
||||
|
||||
dist_startscript_DATA = \
|
||||
km-00000406.ini \
|
||||
km-00000407.ini \
|
||||
km-00000409.ini \
|
||||
km-0000040a.ini \
|
||||
km-0000040b.ini \
|
||||
km-0000040c.ini \
|
||||
km-00000410.ini \
|
||||
km-00000411.ini \
|
||||
km-00000412.ini \
|
||||
km-00000414.ini \
|
||||
km-00000415.ini \
|
||||
km-00000416.ini \
|
||||
km-00000419.ini \
|
||||
km-0000041d.ini \
|
||||
km-00000807.ini \
|
||||
km-00000809.ini \
|
||||
km-0000080a.ini \
|
||||
km-0000080c.ini \
|
||||
km-00000813.ini \
|
||||
km-00000816.ini \
|
||||
km-0000100c.ini \
|
||||
km-00010409.ini \
|
||||
km-19360409.ini
|
||||
km-00000406.toml \
|
||||
km-00000407.toml \
|
||||
km-00000409.toml \
|
||||
km-0000040a.toml \
|
||||
km-0000040b.toml \
|
||||
km-0000040c.toml \
|
||||
km-00000410.toml \
|
||||
km-00000411.toml \
|
||||
km-00000412.toml \
|
||||
km-00000414.toml \
|
||||
km-00000415.toml \
|
||||
km-00000416.toml \
|
||||
km-00000419.toml \
|
||||
km-0000041d.toml \
|
||||
km-00000807.toml \
|
||||
km-00000809.toml \
|
||||
km-0000080a.toml \
|
||||
km-0000080c.toml \
|
||||
km-00000813.toml \
|
||||
km-00000816.toml \
|
||||
km-0000100c.toml \
|
||||
km-00010409.toml \
|
||||
km-19360409.toml
|
||||
|
||||
#
|
||||
# platform specific files
|
||||
@ -98,6 +98,9 @@ endif
|
||||
if FREEBSD
|
||||
# must be tab below
|
||||
install-data-hook:
|
||||
sed -i '' 's|%%PREFIX%%|$(prefix)|g' $(DESTDIR)$(sysconfdir)/rc.d/xrdp \
|
||||
$(DESTDIR)$(sysconfdir)/rc.d/xrdp-sesman
|
||||
sed -e 's|%%PREFIX%%|$(prefix)|g' \
|
||||
-e 's|%%LOCALSTATEDIR%%|$(localstatedir)|g' \
|
||||
-i '' \
|
||||
$(DESTDIR)$(sysconfdir)/rc.d/xrdp \
|
||||
$(DESTDIR)$(sysconfdir)/rc.d/xrdp-sesman
|
||||
endif
|
||||
|
@ -90,11 +90,11 @@ case "$1" in
|
||||
value=$?
|
||||
[ $value -gt 0 ] && exitval=$value
|
||||
fi
|
||||
# Make pidfile readables for all users (for status to work)
|
||||
# Make pidfile readable for all users (for status to work)
|
||||
[ -e $PIDDIR/xrdp-sesman.pid ] && chmod 0644 $PIDDIR/xrdp-sesman.pid
|
||||
[ -e $PIDDIR/$NAME.pid ] && chmod 0644 $PIDDIR/$NAME.pid
|
||||
# Note: Unfortunately, xrdp currently takes too long to create
|
||||
# the pidffile unless properly patched
|
||||
# the pidfile unless properly patched
|
||||
log_end_msg $exitval
|
||||
;;
|
||||
stop)
|
||||
@ -116,7 +116,7 @@ case "$1" in
|
||||
log_progress_msg $NAME
|
||||
if pidofproc -p $PIDDIR/$NAME.pid $DAEMON > /dev/null; then
|
||||
start-stop-daemon --stop --quiet --oknodo --pidfile $PIDDIR/$NAME.pid \
|
||||
--exec $DAEMON
|
||||
--remove-pidfile --exec $DAEMON
|
||||
value=$?
|
||||
[ $value -gt 0 ] && exitval=$value
|
||||
else
|
||||
|
@ -1,659 +0,0 @@
|
||||
[noshift]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=43:43
|
||||
Key21=65105:180
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=113:113
|
||||
Key25=119:119
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=229:229
|
||||
Key35=168:168
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=97:97
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=230:230
|
||||
Key48=248:248
|
||||
Key49=189:189
|
||||
Key50=65505:0
|
||||
Key51=39:39
|
||||
Key52=122:122
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=109:109
|
||||
Key59=44:44
|
||||
Key60=46:46
|
||||
Key61=45:45
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=0:0
|
||||
Key93=65406:0
|
||||
Key94=60:60
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[shift]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=33:33
|
||||
Key11=34:34
|
||||
Key12=35:35
|
||||
Key13=164:164
|
||||
Key14=37:37
|
||||
Key15=38:38
|
||||
Key16=47:47
|
||||
Key17=40:40
|
||||
Key18=41:41
|
||||
Key19=61:61
|
||||
Key20=63:63
|
||||
Key21=65104:96
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=81:81
|
||||
Key25=87:87
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=197:197
|
||||
Key35=94:94
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=65:65
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=198:198
|
||||
Key48=216:216
|
||||
Key49=167:167
|
||||
Key50=65505:0
|
||||
Key51=42:42
|
||||
Key52=90:90
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=77:77
|
||||
Key59=59:59
|
||||
Key60=58:58
|
||||
Key61=95:95
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65273:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65452:44
|
||||
Key92=0:0
|
||||
Key93=65406:0
|
||||
Key94=62:62
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[altgr]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=161:161
|
||||
Key11=64:64
|
||||
Key12=163:163
|
||||
Key13=36:36
|
||||
Key14=8364:8364
|
||||
Key15=165:165
|
||||
Key16=123:123
|
||||
Key17=91:91
|
||||
Key18=93:93
|
||||
Key19=125:125
|
||||
Key20=92:92
|
||||
Key21=124:124
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=64:64
|
||||
Key25=435:322
|
||||
Key26=8364:8364
|
||||
Key27=174:174
|
||||
Key28=254:254
|
||||
Key29=2299:8592
|
||||
Key30=2302:8595
|
||||
Key31=2301:8594
|
||||
Key32=5053:339
|
||||
Key33=254:254
|
||||
Key34=65111:168
|
||||
Key35=126:126
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=170:170
|
||||
Key39=223:223
|
||||
Key40=240:240
|
||||
Key41=496:273
|
||||
Key42=959:331
|
||||
Key43=689:295
|
||||
Key44=106:106
|
||||
Key45=930:312
|
||||
Key46=435:322
|
||||
Key47=248:248
|
||||
Key48=230:230
|
||||
Key49=182:182
|
||||
Key50=65505:0
|
||||
Key51=180:180
|
||||
Key52=171:171
|
||||
Key53=187:187
|
||||
Key54=169:169
|
||||
Key55=2770:8220
|
||||
Key56=2771:8221
|
||||
Key57=110:110
|
||||
Key58=181:181
|
||||
Key59=65115:184
|
||||
Key60=183:183
|
||||
Key61=65120:0
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=0:0
|
||||
Key93=65406:0
|
||||
Key94=92:92
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=0:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[capslock]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=43:43
|
||||
Key21=65105:180
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=81:81
|
||||
Key25=87:87
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=197:197
|
||||
Key35=65111:168
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=65:65
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=214:214
|
||||
Key48=196:196
|
||||
Key49=167:167
|
||||
Key50=65505:0
|
||||
Key51=39:39
|
||||
Key52=90:90
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=77:77
|
||||
Key59=44:44
|
||||
Key60=46:46
|
||||
Key61=45:45
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=0:0
|
||||
Key93=65406:0
|
||||
Key94=60:60
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[shiftcapslock]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=33:33
|
||||
Key11=34:34
|
||||
Key12=35:35
|
||||
Key13=164:164
|
||||
Key14=37:37
|
||||
Key15=38:38
|
||||
Key16=47:47
|
||||
Key17=40:40
|
||||
Key18=41:41
|
||||
Key19=61:61
|
||||
Key20=63:63
|
||||
Key21=65104:96
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=113:113
|
||||
Key25=119:119
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=229:229
|
||||
Key35=65106:94
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=97:97
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=246:246
|
||||
Key48=228:228
|
||||
Key49=189:189
|
||||
Key50=65505:0
|
||||
Key51=42:42
|
||||
Key52=122:122
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=109:109
|
||||
Key59=59:59
|
||||
Key60=58:58
|
||||
Key61=95:95
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65273:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65452:44
|
||||
Key92=0:0
|
||||
Key93=65406:0
|
||||
Key94=62:62
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
1013
instfiles/km-00000406.toml
Normal file
1013
instfiles/km-00000406.toml
Normal file
File diff suppressed because it is too large
Load Diff
@ -84,15 +84,13 @@ Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=60:60
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -104,31 +102,33 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025044:0
|
||||
Key173=269025046:0
|
||||
Key174=269025045:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[shift]
|
||||
Key8=65406:0
|
||||
@ -187,7 +187,7 @@ Key60=58:58
|
||||
Key61=95:95
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
@ -202,29 +202,27 @@ Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65452:44
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=62:62
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -236,31 +234,36 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65512:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key126=61:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025073:0
|
||||
Key173=269025046:0
|
||||
Key174=269025068:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[altgr]
|
||||
Key8=65406:0
|
||||
@ -348,15 +351,13 @@ Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=124:124
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -368,31 +369,33 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025044:0
|
||||
Key173=269025046:0
|
||||
Key174=269025045:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[shiftaltgr]
|
||||
Key8=65406:0
|
||||
@ -451,7 +454,7 @@ Key60=247:247
|
||||
Key61=2729:8212
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
@ -466,29 +469,27 @@ Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65452:44
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=166:166
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -500,31 +501,36 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65512:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key126=61:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025073:0
|
||||
Key173=269025046:0
|
||||
Key174=269025068:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[capslock]
|
||||
Key8=65406:0
|
||||
@ -612,15 +618,13 @@ Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=60:60
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -632,31 +636,166 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025044:0
|
||||
Key173=269025046:0
|
||||
Key174=269025045:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[capslockaltgr]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=185:185
|
||||
Key11=178:178
|
||||
Key12=179:179
|
||||
Key13=188:188
|
||||
Key14=189:189
|
||||
Key15=172:172
|
||||
Key16=123:123
|
||||
Key17=91:91
|
||||
Key18=93:93
|
||||
Key19=125:125
|
||||
Key20=92:92
|
||||
Key21=65115:184
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=64:64
|
||||
Key25=419:321
|
||||
Key26=8364:8364
|
||||
Key27=182:182
|
||||
Key28=940:358
|
||||
Key29=2299:8592
|
||||
Key30=2302:8595
|
||||
Key31=2301:8594
|
||||
Key32=216:216
|
||||
Key33=222:222
|
||||
Key34=65111:168
|
||||
Key35=126:126
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=198:198
|
||||
Key39=16777299:83
|
||||
Key40=208:208
|
||||
Key41=464:272
|
||||
Key42=957:330
|
||||
Key43=673:294
|
||||
Key44=65120:0
|
||||
Key45=930:312
|
||||
Key46=419:321
|
||||
Key47=65113:733
|
||||
Key48=65106:94
|
||||
Key49=16785458:8242
|
||||
Key50=65505:0
|
||||
Key51=2769:8217
|
||||
Key52=187:187
|
||||
Key53=171:171
|
||||
Key54=162:162
|
||||
Key55=2814:8222
|
||||
Key56=2770:8220
|
||||
Key57=2771:8221
|
||||
Key58=924:0
|
||||
Key59=183:183
|
||||
Key60=16785446:8230
|
||||
Key61=2730:8211
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key126=65469:61
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025044:0
|
||||
Key173=269025046:0
|
||||
Key174=269025045:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[shiftcapslock]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
@ -714,7 +853,7 @@ Key60=58:58
|
||||
Key61=95:95
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
@ -729,29 +868,27 @@ Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65452:44
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=62:62
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -763,29 +900,168 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65512:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key126=61:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025073:0
|
||||
Key173=269025046:0
|
||||
Key174=269025068:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[shiftcapslockaltgr]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=161:161
|
||||
Key11=2755:8539
|
||||
Key12=163:163
|
||||
Key13=164:164
|
||||
Key14=2756:8540
|
||||
Key15=2757:8541
|
||||
Key16=2758:8542
|
||||
Key17=2761:8482
|
||||
Key18=177:177
|
||||
Key19=176:176
|
||||
Key20=191:191
|
||||
Key21=65116:731
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=2009:937
|
||||
Key25=435:322
|
||||
Key26=8364:8364
|
||||
Key27=174:174
|
||||
Key28=956:359
|
||||
Key29=165:165
|
||||
Key30=2300:8593
|
||||
Key31=697:305
|
||||
Key32=248:248
|
||||
Key33=254:254
|
||||
Key34=65112:176
|
||||
Key35=175:175
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=230:230
|
||||
Key39=16785054:7838
|
||||
Key40=240:240
|
||||
Key41=170:170
|
||||
Key42=959:331
|
||||
Key43=689:295
|
||||
Key44=65110:729
|
||||
Key45=38:38
|
||||
Key46=435:322
|
||||
Key47=65120:0
|
||||
Key48=65114:711
|
||||
Key49=16785459:8243
|
||||
Key50=65505:0
|
||||
Key51=65109:728
|
||||
Key52=16785466:8250
|
||||
Key53=16785465:8249
|
||||
Key54=169:169
|
||||
Key55=2813:8218
|
||||
Key56=2768:8216
|
||||
Key57=2769:8217
|
||||
Key58=186:186
|
||||
Key59=215:215
|
||||
Key60=247:247
|
||||
Key61=2729:8212
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65512:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=61:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025073:0
|
||||
Key173=269025046:0
|
||||
Key174=269025068:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
1014
instfiles/km-00000407.toml
Normal file
1014
instfiles/km-00000407.toml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,791 +0,0 @@
|
||||
[noshift]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=45:45
|
||||
Key21=61:61
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=113:113
|
||||
Key25=119:119
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=91:91
|
||||
Key35=93:93
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=97:97
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=59:59
|
||||
Key48=39:39
|
||||
Key49=96:96
|
||||
Key50=65505:0
|
||||
Key51=92:92
|
||||
Key52=122:122
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=109:109
|
||||
Key59=44:44
|
||||
Key60=46:46
|
||||
Key61=47:47
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=60:60
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[shift]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=33:33
|
||||
Key11=64:64
|
||||
Key12=35:35
|
||||
Key13=36:36
|
||||
Key14=37:37
|
||||
Key15=94:94
|
||||
Key16=38:38
|
||||
Key17=42:42
|
||||
Key18=40:40
|
||||
Key19=41:41
|
||||
Key20=95:95
|
||||
Key21=43:43
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=81:81
|
||||
Key25=87:87
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=123:123
|
||||
Key35=125:125
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=65:65
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=58:58
|
||||
Key48=34:34
|
||||
Key49=126:126
|
||||
Key50=65505:0
|
||||
Key51=124:124
|
||||
Key52=90:90
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=77:77
|
||||
Key59=60:60
|
||||
Key60=62:62
|
||||
Key61=63:63
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65454:46
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=62:62
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65032:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[altgr]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=45:45
|
||||
Key21=61:61
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=113:113
|
||||
Key25=119:119
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=91:91
|
||||
Key35=93:93
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=97:97
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=59:59
|
||||
Key48=39:39
|
||||
Key49=96:96
|
||||
Key50=65505:0
|
||||
Key51=92:92
|
||||
Key52=122:122
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=109:109
|
||||
Key59=44:44
|
||||
Key60=46:46
|
||||
Key61=47:47
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=124:124
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[shiftaltgr]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=33:33
|
||||
Key11=64:64
|
||||
Key12=35:35
|
||||
Key13=36:36
|
||||
Key14=37:37
|
||||
Key15=94:94
|
||||
Key16=38:38
|
||||
Key17=42:42
|
||||
Key18=40:40
|
||||
Key19=41:41
|
||||
Key20=95:95
|
||||
Key21=43:43
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=81:81
|
||||
Key25=87:87
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=123:123
|
||||
Key35=125:125
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=65:65
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=58:58
|
||||
Key48=34:34
|
||||
Key49=126:126
|
||||
Key50=65505:0
|
||||
Key51=124:124
|
||||
Key52=90:90
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=77:77
|
||||
Key59=60:60
|
||||
Key60=62:62
|
||||
Key61=63:63
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65454:46
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=166:166
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65032:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[capslock]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=45:45
|
||||
Key21=61:61
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=81:81
|
||||
Key25=87:87
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=91:91
|
||||
Key35=93:93
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=65:65
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=59:59
|
||||
Key48=39:39
|
||||
Key49=96:96
|
||||
Key50=65505:0
|
||||
Key51=92:92
|
||||
Key52=90:90
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=77:77
|
||||
Key59=44:44
|
||||
Key60=46:46
|
||||
Key61=47:47
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=60:60
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
[shiftcapslock]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=33:33
|
||||
Key11=64:64
|
||||
Key12=35:35
|
||||
Key13=36:36
|
||||
Key14=37:37
|
||||
Key15=94:94
|
||||
Key16=38:38
|
||||
Key17=42:42
|
||||
Key18=40:40
|
||||
Key19=41:41
|
||||
Key20=95:95
|
||||
Key21=43:43
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=113:113
|
||||
Key25=119:119
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=123:123
|
||||
Key35=125:125
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=97:97
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=58:58
|
||||
Key48=34:34
|
||||
Key49=126:126
|
||||
Key50=65505:0
|
||||
Key51=124:124
|
||||
Key52=122:122
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=109:109
|
||||
Key59=60:60
|
||||
Key60=62:62
|
||||
Key61=63:63
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65454:46
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=62:62
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65032:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
1015
instfiles/km-00000409.toml
Normal file
1015
instfiles/km-00000409.toml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,659 +0,0 @@
|
||||
[noshift]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=39:39
|
||||
Key21=161:161
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=113:113
|
||||
Key25=119:119
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=65104:96
|
||||
Key35=43:43
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=97:97
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=241:241
|
||||
Key48=65105:180
|
||||
Key49=186:186
|
||||
Key50=65505:0
|
||||
Key51=231:231
|
||||
Key52=122:122
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=109:109
|
||||
Key59=44:44
|
||||
Key60=46:46
|
||||
Key61=45:45
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65364:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=0:0
|
||||
Key93=0:0
|
||||
Key94=60:60
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65514:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[shift]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=33:33
|
||||
Key11=34:34
|
||||
Key12=183:183
|
||||
Key13=36:36
|
||||
Key14=37:37
|
||||
Key15=38:38
|
||||
Key16=47:47
|
||||
Key17=40:40
|
||||
Key18=41:41
|
||||
Key19=61:61
|
||||
Key20=63:63
|
||||
Key21=191:191
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=81:81
|
||||
Key25=87:87
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=65106:94
|
||||
Key35=42:42
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=65:65
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=209:209
|
||||
Key48=65111:168
|
||||
Key49=170:170
|
||||
Key50=65505:0
|
||||
Key51=199:199
|
||||
Key52=90:90
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=77:77
|
||||
Key59=59:59
|
||||
Key60=58:58
|
||||
Key61=95:95
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65364:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65273:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65454:46
|
||||
Key92=0:0
|
||||
Key93=0:0
|
||||
Key94=62:62
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65512:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[altgr]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=124:124
|
||||
Key11=64:64
|
||||
Key12=35:35
|
||||
Key13=126:126
|
||||
Key14=189:189
|
||||
Key15=172:172
|
||||
Key16=123:123
|
||||
Key17=91:91
|
||||
Key18=93:93
|
||||
Key19=125:125
|
||||
Key20=92:92
|
||||
Key21=126:126
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=64:64
|
||||
Key25=435:322
|
||||
Key26=8364:8364
|
||||
Key27=182:182
|
||||
Key28=956:359
|
||||
Key29=2299:8592
|
||||
Key30=2302:8595
|
||||
Key31=2301:8594
|
||||
Key32=248:248
|
||||
Key33=254:254
|
||||
Key34=91:91
|
||||
Key35=93:93
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=230:230
|
||||
Key39=223:223
|
||||
Key40=240:240
|
||||
Key41=496:273
|
||||
Key42=959:331
|
||||
Key43=689:295
|
||||
Key44=106:106
|
||||
Key45=930:312
|
||||
Key46=435:322
|
||||
Key47=126:126
|
||||
Key48=123:123
|
||||
Key49=92:92
|
||||
Key50=65505:0
|
||||
Key51=125:125
|
||||
Key52=171:171
|
||||
Key53=187:187
|
||||
Key54=162:162
|
||||
Key55=2770:8220
|
||||
Key56=2771:8221
|
||||
Key57=110:110
|
||||
Key58=181:181
|
||||
Key59=2211:0
|
||||
Key60=183:183
|
||||
Key61=65120:0
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65364:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=0:0
|
||||
Key93=0:0
|
||||
Key94=124:124
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=0:0
|
||||
Key112=65455:47
|
||||
Key113=65514:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[capslock]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=39:39
|
||||
Key21=161:161
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=81:81
|
||||
Key25=87:87
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=65104:96
|
||||
Key35=43:43
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=65:65
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=209:209
|
||||
Key48=65105:180
|
||||
Key49=186:186
|
||||
Key50=65505:0
|
||||
Key51=199:199
|
||||
Key52=90:90
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=77:77
|
||||
Key59=44:44
|
||||
Key60=46:46
|
||||
Key61=45:45
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65364:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=0:0
|
||||
Key93=0:0
|
||||
Key94=60:60
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65514:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[shiftcapslock]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=33:33
|
||||
Key11=34:34
|
||||
Key12=183:183
|
||||
Key13=36:36
|
||||
Key14=37:37
|
||||
Key15=38:38
|
||||
Key16=47:47
|
||||
Key17=40:40
|
||||
Key18=41:41
|
||||
Key19=61:61
|
||||
Key20=63:63
|
||||
Key21=191:191
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=113:113
|
||||
Key25=119:119
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=65106:94
|
||||
Key35=42:42
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=97:97
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=241:241
|
||||
Key48=65111:168
|
||||
Key49=170:170
|
||||
Key50=65505:0
|
||||
Key51=231:231
|
||||
Key52=122:122
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=109:109
|
||||
Key59=59:59
|
||||
Key60=58:58
|
||||
Key61=95:95
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65364:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65273:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65454:46
|
||||
Key92=0:0
|
||||
Key93=0:0
|
||||
Key94=62:62
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65512:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
1013
instfiles/km-0000040a.toml
Normal file
1013
instfiles/km-0000040a.toml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,791 +0,0 @@
|
||||
[noshift]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=43:43
|
||||
Key21=65105:180
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=113:113
|
||||
Key25=119:119
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=229:229
|
||||
Key35=65111:168
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=97:97
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=246:246
|
||||
Key48=228:228
|
||||
Key49=167:167
|
||||
Key50=65505:0
|
||||
Key51=39:39
|
||||
Key52=122:122
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=109:109
|
||||
Key59=44:44
|
||||
Key60=46:46
|
||||
Key61=45:45
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=60:60
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[shift]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=33:33
|
||||
Key11=34:34
|
||||
Key12=35:35
|
||||
Key13=164:164
|
||||
Key14=37:37
|
||||
Key15=38:38
|
||||
Key16=47:47
|
||||
Key17=40:40
|
||||
Key18=41:41
|
||||
Key19=61:61
|
||||
Key20=63:63
|
||||
Key21=65104:96
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=81:81
|
||||
Key25=87:87
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=197:197
|
||||
Key35=65106:94
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=65:65
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=214:214
|
||||
Key48=196:196
|
||||
Key49=189:189
|
||||
Key50=65505:0
|
||||
Key51=42:42
|
||||
Key52=90:90
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=77:77
|
||||
Key59=59:59
|
||||
Key60=58:58
|
||||
Key61=95:95
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65452:44
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=62:62
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[altgr]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=161:161
|
||||
Key11=64:64
|
||||
Key12=163:163
|
||||
Key13=36:36
|
||||
Key14=8364:8364
|
||||
Key15=165:165
|
||||
Key16=123:123
|
||||
Key17=91:91
|
||||
Key18=93:93
|
||||
Key19=125:125
|
||||
Key20=92:92
|
||||
Key21=177:177
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=64:64
|
||||
Key25=435:322
|
||||
Key26=8364:8364
|
||||
Key27=174:174
|
||||
Key28=254:254
|
||||
Key29=2299:8592
|
||||
Key30=2302:8595
|
||||
Key31=2301:8594
|
||||
Key32=5053:339
|
||||
Key33=254:254
|
||||
Key34=65111:168
|
||||
Key35=65107:126
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=170:170
|
||||
Key39=223:223
|
||||
Key40=240:240
|
||||
Key41=496:273
|
||||
Key42=959:331
|
||||
Key43=689:295
|
||||
Key44=65121:0
|
||||
Key45=930:312
|
||||
Key46=435:322
|
||||
Key47=248:248
|
||||
Key48=230:230
|
||||
Key49=182:182
|
||||
Key50=65505:0
|
||||
Key51=180:180
|
||||
Key52=171:171
|
||||
Key53=187:187
|
||||
Key54=169:169
|
||||
Key55=2770:8220
|
||||
Key56=2771:8221
|
||||
Key57=110:110
|
||||
Key58=181:181
|
||||
Key59=65115:184
|
||||
Key60=183:183
|
||||
Key61=65120:0
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=124:124
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[shiftaltgr]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=185:185
|
||||
Key11=178:178
|
||||
Key12=179:179
|
||||
Key13=188:188
|
||||
Key14=162:162
|
||||
Key15=2757:8541
|
||||
Key16=247:247
|
||||
Key17=171:171
|
||||
Key18=187:187
|
||||
Key19=176:176
|
||||
Key20=191:191
|
||||
Key21=172:172
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=2009:937
|
||||
Key25=419:321
|
||||
Key26=162:162
|
||||
Key27=174:174
|
||||
Key28=222:222
|
||||
Key29=165:165
|
||||
Key30=2300:8593
|
||||
Key31=697:305
|
||||
Key32=5052:338
|
||||
Key33=222:222
|
||||
Key34=65112:176
|
||||
Key35=65114:711
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=186:186
|
||||
Key39=167:167
|
||||
Key40=208:208
|
||||
Key41=170:170
|
||||
Key42=957:330
|
||||
Key43=673:294
|
||||
Key44=65122:0
|
||||
Key45=38:38
|
||||
Key46=419:321
|
||||
Key47=216:216
|
||||
Key48=198:198
|
||||
Key49=190:190
|
||||
Key50=65505:0
|
||||
Key51=215:215
|
||||
Key52=60:60
|
||||
Key53=62:62
|
||||
Key54=169:169
|
||||
Key55=2768:8216
|
||||
Key56=2769:8217
|
||||
Key57=78:78
|
||||
Key58=186:186
|
||||
Key59=65116:731
|
||||
Key60=65110:729
|
||||
Key61=65110:729
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key65=160:160
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65452:44
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=166:166
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[capslock]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=43:43
|
||||
Key21=65105:180
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=81:81
|
||||
Key25=87:87
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=197:197
|
||||
Key35=65111:168
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=65:65
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=214:214
|
||||
Key48=196:196
|
||||
Key49=167:167
|
||||
Key50=65505:0
|
||||
Key51=39:39
|
||||
Key52=90:90
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=77:77
|
||||
Key59=44:44
|
||||
Key60=46:46
|
||||
Key61=45:45
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=60:60
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
[shiftcapslock]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=33:33
|
||||
Key11=34:34
|
||||
Key12=35:35
|
||||
Key13=164:164
|
||||
Key14=37:37
|
||||
Key15=38:38
|
||||
Key16=47:47
|
||||
Key17=40:40
|
||||
Key18=41:41
|
||||
Key19=61:61
|
||||
Key20=63:63
|
||||
Key21=65104:96
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=113:113
|
||||
Key25=119:119
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=229:229
|
||||
Key35=65106:94
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=97:97
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=246:246
|
||||
Key48=228:228
|
||||
Key49=189:189
|
||||
Key50=65505:0
|
||||
Key51=42:42
|
||||
Key52=122:122
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=109:109
|
||||
Key59=59:59
|
||||
Key60=58:58
|
||||
Key61=95:95
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65452:44
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=62:62
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
1006
instfiles/km-0000040b.toml
Normal file
1006
instfiles/km-0000040b.toml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,659 +0,0 @@
|
||||
[noshift]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=38:38
|
||||
Key11=233:233
|
||||
Key12=34:34
|
||||
Key13=39:39
|
||||
Key14=40:40
|
||||
Key15=45:45
|
||||
Key16=232:232
|
||||
Key17=95:95
|
||||
Key18=231:231
|
||||
Key19=224:224
|
||||
Key20=41:41
|
||||
Key21=61:61
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=97:97
|
||||
Key25=122:122
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=65106:94
|
||||
Key35=36:36
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=113:113
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=109:109
|
||||
Key48=249:249
|
||||
Key49=178:178
|
||||
Key50=65505:0
|
||||
Key51=42:42
|
||||
Key52=119:119
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=44:44
|
||||
Key59=59:59
|
||||
Key60=58:58
|
||||
Key61=33:33
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=0:0
|
||||
Key93=65406:0
|
||||
Key94=60:60
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[shift]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=176:176
|
||||
Key21=43:43
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=65:65
|
||||
Key25=90:90
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=65111:168
|
||||
Key35=163:163
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=81:81
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=77:77
|
||||
Key48=37:37
|
||||
Key49=126:126
|
||||
Key50=65505:0
|
||||
Key51=181:181
|
||||
Key52=87:87
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=63:63
|
||||
Key59=46:46
|
||||
Key60=47:47
|
||||
Key61=167:167
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65273:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65454:46
|
||||
Key92=0:0
|
||||
Key93=65406:0
|
||||
Key94=62:62
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[altgr]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=185:185
|
||||
Key11=126:126
|
||||
Key12=35:35
|
||||
Key13=123:123
|
||||
Key14=91:91
|
||||
Key15=124:124
|
||||
Key16=96:96
|
||||
Key17=92:92
|
||||
Key18=94:94
|
||||
Key19=64:64
|
||||
Key20=93:93
|
||||
Key21=125:125
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=230:230
|
||||
Key25=171:171
|
||||
Key26=8364:8364
|
||||
Key27=182:182
|
||||
Key28=956:359
|
||||
Key29=2299:8592
|
||||
Key30=2302:8595
|
||||
Key31=2301:8594
|
||||
Key32=248:248
|
||||
Key33=254:254
|
||||
Key34=65111:168
|
||||
Key35=164:164
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=64:64
|
||||
Key39=223:223
|
||||
Key40=240:240
|
||||
Key41=496:273
|
||||
Key42=959:331
|
||||
Key43=689:295
|
||||
Key44=106:106
|
||||
Key45=930:312
|
||||
Key46=435:322
|
||||
Key47=181:181
|
||||
Key48=65106:94
|
||||
Key49=172:172
|
||||
Key50=65505:0
|
||||
Key51=65104:96
|
||||
Key52=435:322
|
||||
Key53=187:187
|
||||
Key54=162:162
|
||||
Key55=2770:8220
|
||||
Key56=2771:8221
|
||||
Key57=110:110
|
||||
Key58=65105:180
|
||||
Key59=2211:0
|
||||
Key60=183:183
|
||||
Key61=65120:0
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=0:0
|
||||
Key93=65406:0
|
||||
Key94=124:124
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=0:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[capslock]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=38:38
|
||||
Key11=201:201
|
||||
Key12=34:34
|
||||
Key13=39:39
|
||||
Key14=40:40
|
||||
Key15=45:45
|
||||
Key16=200:200
|
||||
Key17=95:95
|
||||
Key18=199:199
|
||||
Key19=192:192
|
||||
Key20=41:41
|
||||
Key21=61:61
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=65:65
|
||||
Key25=90:90
|
||||
Key26=69:69
|
||||
Key27=82:82
|
||||
Key28=84:84
|
||||
Key29=89:89
|
||||
Key30=85:85
|
||||
Key31=73:73
|
||||
Key32=79:79
|
||||
Key33=80:80
|
||||
Key34=65106:94
|
||||
Key35=36:36
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=81:81
|
||||
Key39=83:83
|
||||
Key40=68:68
|
||||
Key41=70:70
|
||||
Key42=71:71
|
||||
Key43=72:72
|
||||
Key44=74:74
|
||||
Key45=75:75
|
||||
Key46=76:76
|
||||
Key47=77:77
|
||||
Key48=217:217
|
||||
Key49=178:178
|
||||
Key50=65505:0
|
||||
Key51=42:42
|
||||
Key52=87:87
|
||||
Key53=88:88
|
||||
Key54=67:67
|
||||
Key55=86:86
|
||||
Key56=66:66
|
||||
Key57=78:78
|
||||
Key58=44:44
|
||||
Key59=59:59
|
||||
Key60=58:58
|
||||
Key61=33:33
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=0:0
|
||||
Key93=65406:0
|
||||
Key94=60:60
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
|
||||
[shiftcapslock]
|
||||
Key8=0:0
|
||||
Key9=65307:27
|
||||
Key10=49:49
|
||||
Key11=50:50
|
||||
Key12=51:51
|
||||
Key13=52:52
|
||||
Key14=53:53
|
||||
Key15=54:54
|
||||
Key16=55:55
|
||||
Key17=56:56
|
||||
Key18=57:57
|
||||
Key19=48:48
|
||||
Key20=176:176
|
||||
Key21=43:43
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=97:97
|
||||
Key25=122:122
|
||||
Key26=101:101
|
||||
Key27=114:114
|
||||
Key28=116:116
|
||||
Key29=121:121
|
||||
Key30=117:117
|
||||
Key31=105:105
|
||||
Key32=111:111
|
||||
Key33=112:112
|
||||
Key34=65111:168
|
||||
Key35=163:163
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=113:113
|
||||
Key39=115:115
|
||||
Key40=100:100
|
||||
Key41=102:102
|
||||
Key42=103:103
|
||||
Key43=104:104
|
||||
Key44=106:106
|
||||
Key45=107:107
|
||||
Key46=108:108
|
||||
Key47=109:109
|
||||
Key48=37:37
|
||||
Key49=126:126
|
||||
Key50=65505:0
|
||||
Key51=924:0
|
||||
Key52=119:119
|
||||
Key53=120:120
|
||||
Key54=99:99
|
||||
Key55=118:118
|
||||
Key56=98:98
|
||||
Key57=110:110
|
||||
Key58=63:63
|
||||
Key59=46:46
|
||||
Key60=47:47
|
||||
Key61=167:167
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65273:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65454:46
|
||||
Key92=0:0
|
||||
Key93=65406:0
|
||||
Key94=62:62
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key114=0:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key117=65383:0
|
||||
Key118=0:0
|
||||
Key119=0:0
|
||||
Key120=0:0
|
||||
Key121=0:0
|
||||
Key122=0:0
|
||||
Key123=0:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
1012
instfiles/km-0000040c.toml
Normal file
1012
instfiles/km-0000040c.toml
Normal file
File diff suppressed because it is too large
Load Diff
@ -84,15 +84,13 @@ Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=60:60
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -104,31 +102,33 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025044:0
|
||||
Key173=269025046:0
|
||||
Key174=269025045:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[shift]
|
||||
Key8=65406:0
|
||||
@ -187,7 +187,7 @@ Key60=58:58
|
||||
Key61=95:95
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
@ -202,29 +202,27 @@ Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65454:46
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=62:62
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -236,31 +234,36 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65512:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key126=61:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025073:0
|
||||
Key173=269025046:0
|
||||
Key174=269025068:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[altgr]
|
||||
Key8=65406:0
|
||||
@ -348,15 +351,13 @@ Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=171:171
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -368,31 +369,33 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025044:0
|
||||
Key173=269025046:0
|
||||
Key174=269025045:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[shiftaltgr]
|
||||
Key8=65406:0
|
||||
@ -451,7 +454,7 @@ Key60=65111:168
|
||||
Key61=247:247
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
@ -466,29 +469,27 @@ Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65454:46
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=187:187
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -500,31 +501,36 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65512:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key126=61:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025073:0
|
||||
Key173=269025046:0
|
||||
Key174=269025068:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[capslock]
|
||||
Key8=65406:0
|
||||
@ -612,15 +618,13 @@ Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=60:60
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -632,31 +636,166 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=0:0
|
||||
Key126=65469:61
|
||||
Key127=0:0
|
||||
Key128=0:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025044:0
|
||||
Key173=269025046:0
|
||||
Key174=269025045:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[capslockaltgr]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=185:185
|
||||
Key11=178:178
|
||||
Key12=179:179
|
||||
Key13=188:188
|
||||
Key14=189:189
|
||||
Key15=172:172
|
||||
Key16=123:123
|
||||
Key17=91:91
|
||||
Key18=93:93
|
||||
Key19=125:125
|
||||
Key20=96:96
|
||||
Key21=126:126
|
||||
Key22=65288:8
|
||||
Key23=65289:9
|
||||
Key24=64:64
|
||||
Key25=419:321
|
||||
Key26=8364:8364
|
||||
Key27=182:182
|
||||
Key28=940:358
|
||||
Key29=2299:8592
|
||||
Key30=2302:8595
|
||||
Key31=2301:8594
|
||||
Key32=216:216
|
||||
Key33=222:222
|
||||
Key34=91:91
|
||||
Key35=93:93
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=198:198
|
||||
Key39=223:223
|
||||
Key40=208:208
|
||||
Key41=464:272
|
||||
Key42=957:330
|
||||
Key43=673:294
|
||||
Key44=65121:0
|
||||
Key45=930:312
|
||||
Key46=419:321
|
||||
Key47=64:64
|
||||
Key48=35:35
|
||||
Key49=172:172
|
||||
Key50=65505:0
|
||||
Key51=65104:96
|
||||
Key52=171:171
|
||||
Key53=187:187
|
||||
Key54=162:162
|
||||
Key55=2770:8220
|
||||
Key56=2771:8221
|
||||
Key57=209:209
|
||||
Key58=924:0
|
||||
Key59=65105:180
|
||||
Key60=183:183
|
||||
Key61=65108:175
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65513:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65514:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key126=65469:61
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025044:0
|
||||
Key173=269025046:0
|
||||
Key174=269025045:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[shiftcapslock]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
@ -714,7 +853,7 @@ Key60=58:58
|
||||
Key61=95:95
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65032:0
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
@ -729,29 +868,27 @@ Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65463:55
|
||||
Key80=65464:56
|
||||
Key81=65465:57
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65460:52
|
||||
Key84=65461:53
|
||||
Key85=65462:54
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65457:49
|
||||
Key88=65458:50
|
||||
Key89=65459:51
|
||||
Key90=65456:48
|
||||
Key91=65454:46
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key93=0:0
|
||||
Key94=62:62
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key101=0:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
@ -763,29 +900,168 @@ Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65027:0
|
||||
Key113=65512:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65312:0
|
||||
Key117=0:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025095:0
|
||||
Key122=269025096:0
|
||||
Key123=0:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=65469:61
|
||||
Key126=61:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key129=0:0
|
||||
Key130=0:0
|
||||
Key131=0:0
|
||||
Key132=0:0
|
||||
Key133=0:0
|
||||
Key134=0:0
|
||||
Key135=0:0
|
||||
Key136=0:0
|
||||
Key137=0:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025073:0
|
||||
Key173=269025046:0
|
||||
Key174=269025068:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
||||
[shiftcapslockaltgr]
|
||||
Key8=65406:0
|
||||
Key9=65307:27
|
||||
Key10=161:161
|
||||
Key11=65113:733
|
||||
Key12=65107:126
|
||||
Key13=2755:8539
|
||||
Key14=2756:8540
|
||||
Key15=2757:8541
|
||||
Key16=2758:8542
|
||||
Key17=2761:8482
|
||||
Key18=177:177
|
||||
Key19=65116:731
|
||||
Key20=191:191
|
||||
Key21=65106:94
|
||||
Key22=65288:8
|
||||
Key23=65056:0
|
||||
Key24=2009:937
|
||||
Key25=435:322
|
||||
Key26=162:162
|
||||
Key27=174:174
|
||||
Key28=956:359
|
||||
Key29=165:165
|
||||
Key30=2300:8593
|
||||
Key31=697:305
|
||||
Key32=248:248
|
||||
Key33=254:254
|
||||
Key34=123:123
|
||||
Key35=125:125
|
||||
Key36=65293:13
|
||||
Key37=65507:0
|
||||
Key38=230:230
|
||||
Key39=167:167
|
||||
Key40=240:240
|
||||
Key41=170:170
|
||||
Key42=959:331
|
||||
Key43=689:295
|
||||
Key44=65122:0
|
||||
Key45=38:38
|
||||
Key46=435:322
|
||||
Key47=65115:184
|
||||
Key48=65112:176
|
||||
Key49=166:166
|
||||
Key50=65505:0
|
||||
Key51=65109:728
|
||||
Key52=60:60
|
||||
Key53=62:62
|
||||
Key54=169:169
|
||||
Key55=2768:8216
|
||||
Key56=2769:8217
|
||||
Key57=241:241
|
||||
Key58=186:186
|
||||
Key59=215:215
|
||||
Key60=65111:168
|
||||
Key61=247:247
|
||||
Key62=65506:0
|
||||
Key63=65450:42
|
||||
Key64=65511:0
|
||||
Key65=32:32
|
||||
Key66=65509:0
|
||||
Key67=65470:0
|
||||
Key68=65471:0
|
||||
Key69=65472:0
|
||||
Key70=65473:0
|
||||
Key71=65474:0
|
||||
Key72=65475:0
|
||||
Key73=65476:0
|
||||
Key74=65477:0
|
||||
Key75=65478:0
|
||||
Key76=65479:0
|
||||
Key77=65407:0
|
||||
Key78=65300:0
|
||||
Key79=65429:0
|
||||
Key80=65431:0
|
||||
Key81=65434:0
|
||||
Key82=65453:45
|
||||
Key83=65430:0
|
||||
Key84=65437:0
|
||||
Key85=65432:0
|
||||
Key86=65451:43
|
||||
Key87=65436:0
|
||||
Key88=65433:0
|
||||
Key89=65435:0
|
||||
Key90=65438:0
|
||||
Key91=65439:0
|
||||
Key92=65377:0
|
||||
Key94=65312:0
|
||||
Key95=65480:0
|
||||
Key96=65481:0
|
||||
Key97=65360:0
|
||||
Key98=65362:0
|
||||
Key99=65365:0
|
||||
Key100=65361:0
|
||||
Key102=65363:0
|
||||
Key103=65367:0
|
||||
Key104=65364:0
|
||||
Key105=65366:0
|
||||
Key106=65379:0
|
||||
Key107=65535:127
|
||||
Key108=65421:13
|
||||
Key109=65508:0
|
||||
Key110=65299:0
|
||||
Key111=65377:0
|
||||
Key112=65455:47
|
||||
Key113=65512:0
|
||||
Key114=269025049:0
|
||||
Key115=65515:0
|
||||
Key116=65516:0
|
||||
Key118=269025153:0
|
||||
Key119=269025093:0
|
||||
Key120=269025094:0
|
||||
Key121=269025042:0
|
||||
Key122=269025041:0
|
||||
Key123=269025043:0
|
||||
Key124=65027:0
|
||||
Key125=65513:0
|
||||
Key126=61:61
|
||||
Key127=65515:0
|
||||
Key128=65517:0
|
||||
Key136=65385:0
|
||||
Key156=269025089:0
|
||||
Key157=269025090:0
|
||||
Key163=269025049:0
|
||||
Key164=269025072:0
|
||||
Key166=269025062:0
|
||||
Key167=269025063:0
|
||||
Key171=269025047:0
|
||||
Key172=269025073:0
|
||||
Key173=269025046:0
|
||||
Key174=269025068:0
|
||||
Key180=269025048:0
|
||||
Key181=269025139:0
|
||||
Key225=269025051:0
|
||||
Key234=269025074:0
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user