From 2265077c2befa47a5de644df25dbf73ae373ea45 Mon Sep 17 00:00:00 2001 From: dumblob Date: Thu, 3 Nov 2022 12:31:55 +0100 Subject: [PATCH] win platform: TODO: add CR for 3+ levels on Windows win platform: minor repo cleanup --- platform/win/README.md | 4 + .../amd64/gerdLTGT.dll | Bin 0 -> 4608 bytes .../amd64/gerdLTGT.exp | Bin 0 -> 671 bytes .../amd64/gerdLTGT.lib | Bin 0 -> 1768 bytes .../win/source-20180601-gerdLTGT/gerdLG00.klc | 327 +++++++++++ .../gerdLTGT - Kopie.C | 520 +++++++++++++++++ .../gerdLTGT - Kopie.H} | 0 .../gerdLTGT - Kopie.RC} | 0 .../gerdLTGT.C} | 0 .../gerdLTGT.DEF | 0 .../gerdLTGT.H} | 0 .../gerdLTGT.RC} | Bin .../win/source-20180601-gerdLTGT/gerdLTGT.klc | 327 +++++++++++ .../i386/gerdLTGT.dll | Bin 0 -> 4608 bytes .../i386/gerdLTGT.exp | Bin 0 -> 672 bytes .../i386/gerdLTGT.lib | Bin 0 -> 1766 bytes .../ia64/gerdLTGT.dll | Bin 0 -> 4608 bytes .../ia64/gerdLTGT.exp | Bin 0 -> 671 bytes .../ia64/gerdLTGT.lib | Bin 0 -> 1814 bytes .../make_pkg - Kopie (10).sh | 253 +++++++++ .../make_pkg - Kopie (11).sh | 249 ++++++++ .../make_pkg - Kopie (12).sh | 255 +++++++++ .../make_pkg - Kopie (2).cmd | 258 +++++++++ .../make_pkg - Kopie (2).sh | 184 ++++++ .../make_pkg - Kopie (3).sh | 198 +++++++ .../make_pkg - Kopie (4).sh | 208 +++++++ .../make_pkg - Kopie (5).sh | 222 ++++++++ .../make_pkg - Kopie (6).sh | 222 ++++++++ .../make_pkg - Kopie (7).sh | 225 ++++++++ .../make_pkg - Kopie (8).sh | 236 ++++++++ .../make_pkg - Kopie (9).sh | 252 +++++++++ .../make_pkg - Kopie.sh | 157 ++++++ .../win/source-20180601-gerdLTGT/make_pkg.cmd | 258 +++++++++ .../win/source-20180601-gerdLTGT/make_pkg.sh | 280 +++++++++ .../wow64/gerdLTGT.dll | Bin 0 -> 4608 bytes .../wow64/gerdLTGT.exp | Bin 0 -> 671 bytes .../wow64/gerdLTGT.lib | Bin 0 -> 1768 bytes platform/win/source-20180703-gerdLTGT.zip | Bin 0 -> 105645 bytes .../amd64/gerdLTGT.dll | Bin 0 -> 6656 bytes .../amd64/gerdLTGT.exp | Bin 0 -> 671 bytes .../amd64/gerdLTGT.lib | Bin 0 -> 1768 bytes .../win/source-20180703-gerdLTGT/gerdLG00.klc | 327 +++++++++++ .../gerdLTGT - Kopie.C | 524 +++++++++++++++++ .../gerdLTGT-purely_generated00.C | 344 +++++++++++ .../gerdLTGT-purely_generated00.H | 103 ++++ .../win/source-20180703-gerdLTGT/gerdLTGT.C | 525 +++++++++++++++++ .../gerdLTGT.DEF | 0 .../gerdLTGT.H | 0 .../win/source-20180703-gerdLTGT/gerdLTGT.RC | 51 ++ .../gerdLTGT.RC-purely_generated00 | Bin 0 -> 2528 bytes .../win/source-20180703-gerdLTGT/gerdLTGT.klc | 327 +++++++++++ .../i386/gerdLTGT.dll | Bin 0 -> 6144 bytes .../i386/gerdLTGT.exp | Bin 0 -> 672 bytes .../i386/gerdLTGT.lib | Bin 0 -> 1766 bytes .../ia64/gerdLTGT.dll | Bin 0 -> 7168 bytes .../ia64/gerdLTGT.exp | Bin 0 -> 671 bytes .../ia64/gerdLTGT.lib | Bin 0 -> 1814 bytes .../make_pkg - Kopie (10).sh | 253 +++++++++ .../make_pkg - Kopie (11).sh | 249 ++++++++ .../make_pkg - Kopie (12).sh | 255 +++++++++ .../make_pkg - Kopie (2).cmd | 258 +++++++++ .../make_pkg - Kopie (2).sh | 184 ++++++ .../make_pkg - Kopie (3).sh | 198 +++++++ .../make_pkg - Kopie (4).sh | 208 +++++++ .../make_pkg - Kopie (5).sh | 222 ++++++++ .../make_pkg - Kopie (6).sh | 222 ++++++++ .../make_pkg - Kopie (7).sh | 225 ++++++++ .../make_pkg - Kopie (8).sh | 236 ++++++++ .../make_pkg - Kopie (9).sh | 252 +++++++++ .../make_pkg - Kopie.sh | 157 ++++++ .../win/source-20180703-gerdLTGT/make_pkg.cmd | 258 +++++++++ .../make_pkg.sh | 0 .../map_esc_to_caps_lock.reg | Bin .../wow64/gerdLTGT.dll | Bin 0 -> 6656 bytes .../wow64/gerdLTGT.exp | Bin 0 -> 676 bytes .../wow64/gerdLTGT.lib | Bin 0 -> 1766 bytes platform/win/source-20180817-gerdLTGT.zip | Bin 0 -> 109692 bytes .../amd64/gerdLTGT.dll | Bin 0 -> 6656 bytes .../amd64/gerdLTGT.exp | Bin 0 -> 671 bytes .../amd64/gerdLTGT.lib | Bin 0 -> 1768 bytes .../win/source-20180817-gerdLTGT/gerdLG00.klc | 327 +++++++++++ .../gerdLTGT - Kopie.C | 524 +++++++++++++++++ .../gerdLTGT-purely_generated00.C | 344 +++++++++++ .../gerdLTGT-purely_generated00.H | 103 ++++ .../gerdLTGT.C} | 0 .../source-20180817-gerdLTGT/gerdLTGT.C.howto | 12 + .../gerdLTGT.DEF | 0 .../gerdLTGT.H | 0 .../win/source-20180817-gerdLTGT/gerdLTGT.RC | 51 ++ .../gerdLTGT.RC-purely_generated00 | Bin 0 -> 2528 bytes .../win/source-20180817-gerdLTGT/gerdLTGT.klc | 327 +++++++++++ .../i386/gerdLTGT.dll | Bin 0 -> 6144 bytes .../i386/gerdLTGT.exp | Bin 0 -> 672 bytes .../i386/gerdLTGT.lib | Bin 0 -> 1766 bytes .../ia64/gerdLTGT.dll | Bin 0 -> 7168 bytes .../ia64/gerdLTGT.exp | Bin 0 -> 671 bytes .../ia64/gerdLTGT.lib | Bin 0 -> 1814 bytes .../make_pkg - Kopie (10).sh | 253 +++++++++ .../make_pkg - Kopie (11).sh | 249 ++++++++ .../make_pkg - Kopie (12).sh | 255 +++++++++ .../make_pkg - Kopie (2).cmd | 258 +++++++++ .../make_pkg - Kopie (2).sh | 184 ++++++ .../make_pkg - Kopie (3).sh | 198 +++++++ .../make_pkg - Kopie (4).sh | 208 +++++++ .../make_pkg - Kopie (5).sh | 222 ++++++++ .../make_pkg - Kopie (6).sh | 222 ++++++++ .../make_pkg - Kopie (7).sh | 225 ++++++++ .../make_pkg - Kopie (8).sh | 236 ++++++++ .../make_pkg - Kopie (9).sh | 252 +++++++++ .../make_pkg - Kopie.sh | 157 ++++++ .../win/source-20180817-gerdLTGT/make_pkg.cmd | 258 +++++++++ .../make_pkg.sh} | 0 .../map_esc_to_caps_lock.reg} | Bin .../wow64/gerdLTGT.dll | Bin 0 -> 6656 bytes .../wow64/gerdLTGT.exp | Bin 0 -> 676 bytes .../wow64/gerdLTGT.lib | Bin 0 -> 1766 bytes .../gerd-ltgt.klc | Bin .../gerdLTGT.C | 0 .../gerdLTGT.DEF | 0 .../gerdLTGT.H | 0 .../gerdLTGT.RC | Bin ...rl-c open downloads window in Firefox.html | 0 .../gerdLTGT.C | 0 .../win/source-20181111-gerd04/gerdLTGT.DEF | 4 + .../win/source-20181111-gerd04/gerdLTGT.H | 103 ++++ .../gerdLTGT.RC-mod00 | 0 .../gerdLTGT.klc | Bin .../win_registry_uninstall.vbs | 0 .../gerdLTGT.C | 0 .../win/source-20181111-gerd05/gerdLTGT.DEF | 4 + .../win/source-20181111-gerd05/gerdLTGT.H | 103 ++++ .../source-20181111-gerd05/gerdLTGT.RC-mod00 | 50 ++ .../gerdLTGT.klc | Bin .../win_registry_uninstall.vbs | 0 ...rentControlSet_Control_Keyboard Layout.pdf | Bin .../gerdLTGT.C | 0 .../source-20220624-gerdLTGT/gerdLTGT.C.bak00 | 344 +++++++++++ .../source-20220624-gerdLTGT/gerdLTGT.C.bak01 | 533 ++++++++++++++++++ .../gerdLTGT.C.howto | 0 .../win/source-20220624-gerdLTGT/gerdLTGT.DEF | 4 + .../win/source-20220624-gerdLTGT/gerdLTGT.H | 103 ++++ .../source-20220624-gerdLTGT/gerdLTGT.H.bak00 | 103 ++++ .../gerdLTGT.RC | 0 .../gerdLTGT.RC.bak00 | Bin 0 -> 2528 bytes .../gerdLTGT.klc | 0 .../gerdLTGT.klc.bak00 | 0 .../win/source-20220624-gerdLTGT/make_pkg.sh | 274 +++++++++ .../make_pkg.sh.bak00 | 274 +++++++++ .../map_esc_to_caps_lock.reg | Bin 0 -> 384 bytes .../map_esc_to_caps_lock.reg.bak00 | Bin 0 -> 384 bytes 150 files changed, 16777 insertions(+) create mode 100644 platform/win/source-20180601-gerdLTGT/amd64/gerdLTGT.dll create mode 100644 platform/win/source-20180601-gerdLTGT/amd64/gerdLTGT.exp create mode 100644 platform/win/source-20180601-gerdLTGT/amd64/gerdLTGT.lib create mode 100644 platform/win/source-20180601-gerdLTGT/gerdLG00.klc create mode 100644 platform/win/source-20180601-gerdLTGT/gerdLTGT - Kopie.C rename platform/win/{20220624-gerdLTGT/gerdLTGT.H => source-20180601-gerdLTGT/gerdLTGT - Kopie.H} (100%) rename platform/win/{gerd04/gerdLTGT.RC-mod00 => source-20180601-gerdLTGT/gerdLTGT - Kopie.RC} (100%) rename platform/win/{20220624-gerdLTGT/gerdLTGT.C.bak00 => source-20180601-gerdLTGT/gerdLTGT.C} (100%) rename platform/win/{20220624-gerdLTGT => source-20180601-gerdLTGT}/gerdLTGT.DEF (100%) rename platform/win/{20220624-gerdLTGT/gerdLTGT.H.bak00 => source-20180601-gerdLTGT/gerdLTGT.H} (100%) rename platform/win/{20220624-gerdLTGT/gerdLTGT.RC.bak00 => source-20180601-gerdLTGT/gerdLTGT.RC} (100%) create mode 100644 platform/win/source-20180601-gerdLTGT/gerdLTGT.klc create mode 100644 platform/win/source-20180601-gerdLTGT/i386/gerdLTGT.dll create mode 100644 platform/win/source-20180601-gerdLTGT/i386/gerdLTGT.exp create mode 100644 platform/win/source-20180601-gerdLTGT/i386/gerdLTGT.lib create mode 100644 platform/win/source-20180601-gerdLTGT/ia64/gerdLTGT.dll create mode 100644 platform/win/source-20180601-gerdLTGT/ia64/gerdLTGT.exp create mode 100644 platform/win/source-20180601-gerdLTGT/ia64/gerdLTGT.lib create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (10).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (11).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (12).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (2).cmd create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (2).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (3).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (4).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (5).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (6).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (7).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (8).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (9).sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg - Kopie.sh create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg.cmd create mode 100644 platform/win/source-20180601-gerdLTGT/make_pkg.sh create mode 100644 platform/win/source-20180601-gerdLTGT/wow64/gerdLTGT.dll create mode 100644 platform/win/source-20180601-gerdLTGT/wow64/gerdLTGT.exp create mode 100644 platform/win/source-20180601-gerdLTGT/wow64/gerdLTGT.lib create mode 100644 platform/win/source-20180703-gerdLTGT.zip create mode 100644 platform/win/source-20180703-gerdLTGT/amd64/gerdLTGT.dll create mode 100644 platform/win/source-20180703-gerdLTGT/amd64/gerdLTGT.exp create mode 100644 platform/win/source-20180703-gerdLTGT/amd64/gerdLTGT.lib create mode 100644 platform/win/source-20180703-gerdLTGT/gerdLG00.klc create mode 100644 platform/win/source-20180703-gerdLTGT/gerdLTGT - Kopie.C create mode 100644 platform/win/source-20180703-gerdLTGT/gerdLTGT-purely_generated00.C create mode 100644 platform/win/source-20180703-gerdLTGT/gerdLTGT-purely_generated00.H create mode 100644 platform/win/source-20180703-gerdLTGT/gerdLTGT.C rename platform/win/{gerd02 => source-20180703-gerdLTGT}/gerdLTGT.DEF (100%) rename platform/win/{gerd02 => source-20180703-gerdLTGT}/gerdLTGT.H (100%) create mode 100644 platform/win/source-20180703-gerdLTGT/gerdLTGT.RC create mode 100644 platform/win/source-20180703-gerdLTGT/gerdLTGT.RC-purely_generated00 create mode 100644 platform/win/source-20180703-gerdLTGT/gerdLTGT.klc create mode 100644 platform/win/source-20180703-gerdLTGT/i386/gerdLTGT.dll create mode 100644 platform/win/source-20180703-gerdLTGT/i386/gerdLTGT.exp create mode 100644 platform/win/source-20180703-gerdLTGT/i386/gerdLTGT.lib create mode 100644 platform/win/source-20180703-gerdLTGT/ia64/gerdLTGT.dll create mode 100644 platform/win/source-20180703-gerdLTGT/ia64/gerdLTGT.exp create mode 100644 platform/win/source-20180703-gerdLTGT/ia64/gerdLTGT.lib create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (10).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (11).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (12).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (2).cmd create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (2).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (3).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (4).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (5).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (6).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (7).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (8).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (9).sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg - Kopie.sh create mode 100644 platform/win/source-20180703-gerdLTGT/make_pkg.cmd rename platform/win/{20220624-gerdLTGT => source-20180703-gerdLTGT}/make_pkg.sh (100%) rename platform/win/{20220624-gerdLTGT => source-20180703-gerdLTGT}/map_esc_to_caps_lock.reg (100%) create mode 100644 platform/win/source-20180703-gerdLTGT/wow64/gerdLTGT.dll create mode 100644 platform/win/source-20180703-gerdLTGT/wow64/gerdLTGT.exp create mode 100644 platform/win/source-20180703-gerdLTGT/wow64/gerdLTGT.lib create mode 100644 platform/win/source-20180817-gerdLTGT.zip create mode 100644 platform/win/source-20180817-gerdLTGT/amd64/gerdLTGT.dll create mode 100644 platform/win/source-20180817-gerdLTGT/amd64/gerdLTGT.exp create mode 100644 platform/win/source-20180817-gerdLTGT/amd64/gerdLTGT.lib create mode 100644 platform/win/source-20180817-gerdLTGT/gerdLG00.klc create mode 100644 platform/win/source-20180817-gerdLTGT/gerdLTGT - Kopie.C create mode 100644 platform/win/source-20180817-gerdLTGT/gerdLTGT-purely_generated00.C create mode 100644 platform/win/source-20180817-gerdLTGT/gerdLTGT-purely_generated00.H rename platform/win/{20220624-gerdLTGT/gerdLTGT.C.bak01 => source-20180817-gerdLTGT/gerdLTGT.C} (100%) create mode 100644 platform/win/source-20180817-gerdLTGT/gerdLTGT.C.howto rename platform/win/{gerd04 => source-20180817-gerdLTGT}/gerdLTGT.DEF (100%) rename platform/win/{gerd04 => source-20180817-gerdLTGT}/gerdLTGT.H (100%) create mode 100644 platform/win/source-20180817-gerdLTGT/gerdLTGT.RC create mode 100644 platform/win/source-20180817-gerdLTGT/gerdLTGT.RC-purely_generated00 create mode 100644 platform/win/source-20180817-gerdLTGT/gerdLTGT.klc create mode 100644 platform/win/source-20180817-gerdLTGT/i386/gerdLTGT.dll create mode 100644 platform/win/source-20180817-gerdLTGT/i386/gerdLTGT.exp create mode 100644 platform/win/source-20180817-gerdLTGT/i386/gerdLTGT.lib create mode 100644 platform/win/source-20180817-gerdLTGT/ia64/gerdLTGT.dll create mode 100644 platform/win/source-20180817-gerdLTGT/ia64/gerdLTGT.exp create mode 100644 platform/win/source-20180817-gerdLTGT/ia64/gerdLTGT.lib create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (10).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (11).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (12).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (2).cmd create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (2).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (3).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (4).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (5).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (6).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (7).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (8).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (9).sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg - Kopie.sh create mode 100644 platform/win/source-20180817-gerdLTGT/make_pkg.cmd rename platform/win/{20220624-gerdLTGT/make_pkg.sh.bak00 => source-20180817-gerdLTGT/make_pkg.sh} (100%) rename platform/win/{20220624-gerdLTGT/map_esc_to_caps_lock.reg.bak00 => source-20180817-gerdLTGT/map_esc_to_caps_lock.reg} (100%) create mode 100644 platform/win/source-20180817-gerdLTGT/wow64/gerdLTGT.dll create mode 100644 platform/win/source-20180817-gerdLTGT/wow64/gerdLTGT.exp create mode 100644 platform/win/source-20180817-gerdLTGT/wow64/gerdLTGT.lib rename platform/win/{gerd02 => source-20181111-gerd02}/gerd-ltgt.klc (100%) rename platform/win/{gerd02 => source-20181111-gerd02}/gerdLTGT.C (100%) rename platform/win/{gerd05 => source-20181111-gerd02}/gerdLTGT.DEF (100%) rename platform/win/{gerd05 => source-20181111-gerd02}/gerdLTGT.H (100%) rename platform/win/{gerd02 => source-20181111-gerd02}/gerdLTGT.RC (100%) rename platform/win/{gerd03 => source-20181111-gerd03}/Dvorak keyboard layout ... makes ctrl-c open downloads window in Firefox.html (100%) rename platform/win/{gerd04 => source-20181111-gerd04}/gerdLTGT.C (100%) create mode 100644 platform/win/source-20181111-gerd04/gerdLTGT.DEF create mode 100644 platform/win/source-20181111-gerd04/gerdLTGT.H rename platform/win/{gerd05 => source-20181111-gerd04}/gerdLTGT.RC-mod00 (100%) rename platform/win/{gerd04 => source-20181111-gerd04}/gerdLTGT.klc (100%) rename platform/win/{gerd04 => source-20181111-gerd04}/win_registry_uninstall.vbs (100%) rename platform/win/{gerd05 => source-20181111-gerd05}/gerdLTGT.C (100%) create mode 100644 platform/win/source-20181111-gerd05/gerdLTGT.DEF create mode 100644 platform/win/source-20181111-gerd05/gerdLTGT.H create mode 100644 platform/win/source-20181111-gerd05/gerdLTGT.RC-mod00 rename platform/win/{gerd05 => source-20181111-gerd05}/gerdLTGT.klc (100%) rename platform/win/{gerd05 => source-20181111-gerd05}/win_registry_uninstall.vbs (100%) rename platform/win/{20220624-gerdLTGT => source-20220624-gerdLTGT}/Registry_ HKEY_LOCAL_MACHINE_SYSTEM_CurrentControlSet_Control_Keyboard Layout.pdf (100%) rename platform/win/{20220624-gerdLTGT => source-20220624-gerdLTGT}/gerdLTGT.C (100%) create mode 100644 platform/win/source-20220624-gerdLTGT/gerdLTGT.C.bak00 create mode 100644 platform/win/source-20220624-gerdLTGT/gerdLTGT.C.bak01 rename platform/win/{20220624-gerdLTGT => source-20220624-gerdLTGT}/gerdLTGT.C.howto (100%) create mode 100644 platform/win/source-20220624-gerdLTGT/gerdLTGT.DEF create mode 100644 platform/win/source-20220624-gerdLTGT/gerdLTGT.H create mode 100644 platform/win/source-20220624-gerdLTGT/gerdLTGT.H.bak00 rename platform/win/{20220624-gerdLTGT => source-20220624-gerdLTGT}/gerdLTGT.RC (100%) create mode 100644 platform/win/source-20220624-gerdLTGT/gerdLTGT.RC.bak00 rename platform/win/{20220624-gerdLTGT => source-20220624-gerdLTGT}/gerdLTGT.klc (100%) rename platform/win/{20220624-gerdLTGT => source-20220624-gerdLTGT}/gerdLTGT.klc.bak00 (100%) create mode 100644 platform/win/source-20220624-gerdLTGT/make_pkg.sh create mode 100644 platform/win/source-20220624-gerdLTGT/make_pkg.sh.bak00 create mode 100644 platform/win/source-20220624-gerdLTGT/map_esc_to_caps_lock.reg create mode 100644 platform/win/source-20220624-gerdLTGT/map_esc_to_caps_lock.reg.bak00 diff --git a/platform/win/README.md b/platform/win/README.md index 657961f..daae151 100644 --- a/platform/win/README.md +++ b/platform/win/README.md @@ -2,6 +2,10 @@ ### LShift + RShift modifier combination doesn't work +1. add CR for 3+ levels + +1. maybe enforce LF for 2- levels (for 3+ levels CR is enforced)? + 1. re-read https://metacpan.org/pod/UI::KeyboardLayout#Keyboard-input-on-Windows,-Part-I:-what-is-the-kernel-doing? and come up with some hacks? 1. generate all possible `Ctrl + Shift + Alt + AltGr` combination by MSKLC and compare sources to gain more knowledge about `CharModifiers` table diff --git a/platform/win/source-20180601-gerdLTGT/amd64/gerdLTGT.dll b/platform/win/source-20180601-gerdLTGT/amd64/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..58c838c9dc9c597e87affbe0f727e18cf5205387 GIT binary patch literal 4608 zcmeHKTX0iV6kR7N+Cqxu;Rhq=ZD~tENO_cp3R-EQrA_IRQd+R2&21V;lX8;+6$E@C zA2@@*emKFZprTepWspaG{4&FrKO!)WA3jEn!|05IV_o~?CQW%LK7MpKXZGFa?7PoC z`>eh9xk*jy0XP9`34MWMPa4{tb(=B1dww03XnG7`88k!lvxiRSidpsAIdL8jU6}f%hsFy~*53q?+!H9YpwMI^11dU|l{@t;AUHwQZZ zFWLOh93PsH(BEw<8uq+9wO&_A%1n-$;F!p~n}$hRw$aveu$)M#mc^RO!e-pd9!4?y zCd^{*!5sFHwvox_#XNLiK02`gK9s=3LUdsf{8)@`EI|PGr4|fLO!(`x%YR>Tf5~&U zL3^&Qs*S{3DV?{~6b!0q7*Gb@P`P+t<>4KbkE6_0&&6l>9GOJ)0#4#I z>aY$gQGqhvNgkZR2gt^Yco?-#47(xu^aRT+ILN!`g(luC%X0+m< z+T?f%1}38yTVNrADEhD!+prz|IN*HFk?$&W<+^%M;BvWUxHe8fdk0aJ`D655IN}#D19=>u#B40ZB;z#Pco4ZnxR-Q@IQNqfU&)MINu3I2 zWd(ODW44xYw+7&c=TRmk;bqd*4!^{Ypta~7ngpJed#eOzzy9DS4;`aBkSl(OwwW1H=xK_5)|-$6TGTJllL z!%;uyebkh;gx`e`-KoXL5ZN?&SJ9t_*ARI%#KQH5dVl7QEWJ_}xLT4c>^28rL$8=V@zlhE{E>f%+0- zuSUm6#X5m#I?jK^_EL?Hhj#t?gpwJ(^hKiQXC4TOHQcL-9tA1uq-IEa0N(dmJY%h` zE14)5C38_`iLAOBD>+kQ-_iJ79i1D+rkv{)t4d;?+-)TDfqd2s=&|IM_!=Zn$A>q6 z#u!G$a zVi{&EM{to{w^3&CjgPoUjR`_GyZ<#l=Ggx~W0|qJvC>#&tT%Qk7LVcJHJY~s|3d_R E2RcIJK>z>% literal 0 HcmV?d00001 diff --git a/platform/win/source-20180601-gerdLTGT/amd64/gerdLTGT.exp b/platform/win/source-20180601-gerdLTGT/amd64/gerdLTGT.exp new file mode 100644 index 0000000000000000000000000000000000000000..a9c785c4e69c5b764e675a878e86344d3a6c4341 GIT binary patch literal 671 zcmZuu%}T>S5S|*V9t7Kq|40r6D@a;@5b~7JLsW#wA7#E#k?ar zLY;s}93AL&wz8~+f8}R3Bw;j8PoL->g@!o$xMv!|a;%CgCku13x|7RNlGS(wV!i78 z#7E<()NL#>_2Wdpw3(&q^UK@$?bQvy2l8oD*j&>}4i}ELyRU25=&@_rTGKoUYYG7_ zrvk5c_i}1WRpnH^R9p+|#%W~?t8ObMn|-{1cANU`-a6GGfpd}5>$tT=Jo${M+6^j$ m<`po06wNJQnt8$edVMC5OQS5ndKiPin=g5iJ{UvWV}ZYJu6AMo literal 0 HcmV?d00001 diff --git a/platform/win/source-20180601-gerdLTGT/amd64/gerdLTGT.lib b/platform/win/source-20180601-gerdLTGT/amd64/gerdLTGT.lib new file mode 100644 index 0000000000000000000000000000000000000000..92841a4122d1d1f0a8c4d1ff5b28976f501bfdfc GIT binary patch literal 1768 zcmcIlO;6iE5Ph*Jln9jwdO`vj2?@BQNr)Rj2pI?}QA|L=oO&=J4iE{H$fOd812<0m z5AIyKaN-I#j!5(;^as!xdp9`3X_Km~ANIOvgAAra;pgxm00`#8nW81m)&5fdEXIHmYin&c|qiF9}T*tJ&S+MQG zwrRfgz`1ns9jvwOLf+0USxd<8I%es#;$|zyWw%;y)Li;X^{8%#Y;?^>f92CdgsvmN zvkHt5vy)zrAbJpiLbDo<oPzpL*WOM zES6$4QyxhQo^b(pr`m2TQ z<2;GMUkB!e#)|@r=KtL^(IDkc>LsP80`;PJ^>X9EW02wX;`m$5IZ!V%(#Z94B^9x9 zy}VN$bduXqg3N;+-Z~N?t4)7Bl9=AXAnJz=cead|n90m;8XK86?zelNvmHpl! mzMaH&j3BhX#JaA^W>ISVzu{(eF8C(X=oq?O!fxbX0`VIKAWTO9 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180601-gerdLTGT/gerdLG00.klc b/platform/win/source-20180601-gerdLTGT/gerdLG00.klc new file mode 100644 index 0000000..1ea6ff1 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/gerdLG00.klc @@ -0,0 +1,327 @@ +// 2010-2017 Jan Pacner +// etaoin shrdlu! + +// The concept of this keyboard layout +// motto: be as much compatible with ISO dvorak as possible +// 4. level is the same as 3. level +// 2. level of ISO dvorak goes without modifications to the 3. level +// the whole national alphabet is accessible directly from 1. and 2. level +// without any exception +// 3. level has some additional non-alphabet characters (e.g. numbers) +// 3. level is accessible only by pressing both Shifts at once (and +// holding either of them) +// there are 2 variants which differ in placement and/or availability of +// characters ' " < > „ “ en_dash +// in `ltgt`, characters „ “ are not available and ' " < > are at their +// original dvorak places and ! is duplicated for better reachability +// in `writer`, all characters are available, but " < > are in +// the 3. level, thus less reachable + +// ----------- standard ISO dvorak, 1. and 2. level +// ~ ! @ # $ % ^ & * ( ) { } +// ` 1 2 3 4 5 6 7 8 9 0 [ ] +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// space +// space + +// ----------- german dvorak ltgt, 1. and 2. levelll +// ä Ö Ü ß +// ä ö ü ß +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak ltgt, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// nda ! § , 7 8 9 [ ] + | +// en dash +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak writer, 1. and 2. level +// ä Ö Ü ß +// ä ö ü ß +// +// “ nda ' P Y F G C R L ? + | +// en dash +// „ , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak writer, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// " < > § , 7 8 9 [ ] + | +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak (ltgt|writer), 4. level +// the same as 3. level + +// KBD identifier_max_8_bytes_long "Some description to show in keyboard settings and while switching layouts" + KBD gerdLTGT "German Dvorak ltgt (useful for text with lots of <>)" +//KBD gerdLTGT "German Dvorak writer (useful for text with lower/upper UTF-8 double quotes)" + +COPYRIGHT "MIT license" + +COMPANY "github.com/dumblob/ULKL/" + +LOCALENAME "de-DE" + + LOCALEID "00000407" +// LOCALEID "00000000" + +//FIXME 1.1 after unused keys produce the character +VERSION 1.0 + +//ATTRIBUTES + +//MODIFIERS + +SHIFTSTATE + +// shift_state_idx // column_below modifiers +0 // 4 +1 // 5 LSHIFT or RSHIFT pressed +2 // 6 both LSHIFT and RSHIFT pressed simultaneously + +LAYOUT +// an extra @ at the end is a dead key +// -1 denotes the character +// SC denotes a Virtual Scan Code +// Cap ~ CapsInfo (probably whether CapsLock is applicable) + +// topmost row + +//SC VK_ Cap 0 1 2 +29 OEM_3 0 -1 -1 007e // , , TILDE +02 1 0 -1 -1 0021 // , , EXCLAMATION MARK +03 2 0 00e4 00c4 0040 // adiaeresis, Adiaeresis, COMMERCIAL AT +04 3 0 00f6 00d6 0023 // odiaeresis, Odiaeresis, NUMBER SIGN +05 4 0 -1 -1 0024 // , , DOLLAR SIGN +06 5 0 00fc 00dc 0025 // udiaeresis, Udiaeresis, PERCENT SIGN +07 6 0 -1 -1 005e // , , CIRCUMFLEX ACCENT +08 7 0 -1 -1 0026 // , , AMPERSAND +09 8 0 -1 -1 002a // , , ASTERISK +0a 9 0 -1 -1 0028 // , , LEFT PARENTHESIS +0b 0 0 -1 -1 0029 // , , RIGHT PARENTHESIS +0c OEM_4 0 00df 1e9e 007b // ssharp, U1E9E, LEFT CURLY BRACKET (BRACELEFT) +0d OEM_6 0 -1 -1 007d // , , RIGHT CURLY BRACKET (BRACERIGHT) +// FIXME wtf is this key? is it really ? +56 OEM_102 0 -1 -1 -1 // , , +//0e ???? 0 ???? ???? ???? // backspace, backspace, backspace + +// top row + +//0f ???? 0 ???? ???? ???? // tab, tab, tab +// ltgt variant +10 OEM_7 0 0027 0022 -1 // APOSTROPHE, QUOTATION MARK (QUOTEDBL), +11 OEM_COMMA 0 002c 003c 2013 // COMMA, LESS-THAN SIGN, U2013 (EN DASH, pomlcka) +12 OEM_PERIOD 0 002e 003e 0021 // FULL STOP (PERIOD), GREATER-THAN SIGN, EXCLAMATION MARK +// writer variant +//10 OEM_7 0 201e 201c 0022 // U201E LOWER QUOTATION MARK (QUOTEDBL), U201C UPPER QUOTATION MARK (QUOTEDBL), QUOTATION MARK (QUOTEDBL) +//11 OEM_COMMA 0 002c 2013 003c // COMMA, U2013 (EN DASH, pomlcka), LESS-THAN SIGN +//12 OEM_PERIOD 0 002e 0027 003e // FULL STOP (PERIOD), APOSTROPHE, GREATER-THAN SIGN + +13 P 0 p P 00a7 // LATIN SMALL LETTER P, LATIN CAPITAL LETTER P, SECTION SIGN (PARAGRAPH) +14 Y 0 y Y -1 // LATIN SMALL LETTER Y, LATIN CAPITAL LETTER Y, +15 F 0 f F 002c // LATIN SMALL LETTER F, LATIN CAPITAL LETTER F, COMMA +16 G 0 g G 7 // LATIN SMALL LETTER G, LATIN CAPITAL LETTER G, DIGIT SEVEN +17 C 0 c C 8 // LATIN SMALL LETTER C, LATIN CAPITAL LETTER C, DIGIT EIGHT +18 R 0 r R 9 // LATIN SMALL LETTER R, LATIN CAPITAL LETTER R, DIGIT NINE +19 L 0 l L 005b // LATIN SMALL LETTER L, LATIN CAPITAL LETTER L, LEFT SQUARE BRACKET +1a OEM_2 0 002f 003f 005d // SOLIDUS (SLASH), QUESTION MARK, RIGHT SQUARE BRACKET +1b OEM_PLUS 0 003d 002b 002b // EQUALS SIGN, PLUS SIGN, PLUS SIGN +2b OEM_5 0 005c 007c 007c // REVERSE SOLIDUS (BACKSLASH), VERTICAL LINE (BAR), VERTICAL LINE (BAR) + +// home/middle row + +//CapsLk +//3a ???? 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +//3a SGCap 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +1e A 0 a A 0040 // LATIN SMALL LETTER A, LATIN CAPITAL LETTER A, COMMERCIAL AT +1f O 0 o O 00b0 // LATIN SMALL LETTER O, LATIN CAPITAL LETTER O, DEGREE +20 E 0 e E 20ac // LATIN SMALL LETTER E, LATIN CAPITAL LETTER E, EURO SIGN +21 U 0 u U 0060 // LATIN SMALL LETTER U, LATIN CAPITAL LETTER U, GRAVE ACCENT (GRAVE) +22 I 0 i I -1 // LATIN SMALL LETTER I, LATIN CAPITAL LETTER I, +23 D 0 d D 003a // LATIN SMALL LETTER D, LATIN CAPITAL LETTER D, COLON +24 H 0 h H 4 // LATIN SMALL LETTER H, LATIN CAPITAL LETTER H, DIGIT FOUR +25 T 0 t T 5 // LATIN SMALL LETTER T, LATIN CAPITAL LETTER T, DIGIT FIVE +26 N 0 n N 6 // LATIN SMALL LETTER N, LATIN CAPITAL LETTER N, DIGIT SIX +27 S 0 s S 003d // LATIN SMALL LETTER S, LATIN CAPITAL LETTER S, EQUALS SIGN +// pomlcka (= minus = dash) +28 OEM_MINUS 0 002d 005f 005c // HYPHEN-MINUS (FIXME is it the plain minus?), LOW LINE (UNDERSCORE), REVERSE SOLIDUS (BACKSLASH) +//1c ???? 0 ???? ???? ???? // enter/return, enter/return, enter/return + +// bottom row + +//2a ???? 0 ???? ???? ???? // left shift, left shift, left shift +// left bottom key, right from , which doesn't follow the kbd standard +// FIXME wtf is this key? is it really ? +56 OEM_102 0 -1 -1 -1 // , , +2c OEM_1 0 003b 003a -1 // SEMICOLON, COLON, +2d Q 0 q Q -1 // LATIN SMALL LETTER Q, LATIN CAPITAL LETTER Q, +2e J 0 j J -1 // LATIN SMALL LETTER J, LATIN CAPITAL LETTER J, +2f K 0 k K -1 // LATIN SMALL LETTER K, LATIN CAPITAL LETTER K, +30 X 0 x X -1 // LATIN SMALL LETTER X, LATIN CAPITAL LETTER X, +31 B 0 b B 0 // LATIN SMALL LETTER B, LATIN CAPITAL LETTER B, DIGIT ZERO +32 M 0 m M 1 // LATIN SMALL LETTER M, LATIN CAPITAL LETTER M, DIGIT ONE +33 W 0 w W 2 // LATIN SMALL LETTER W, LATIN CAPITAL LETTER W, DIGIT TWO +34 V 0 v V 3 // LATIN SMALL LETTER V, LATIN CAPITAL LETTER V, DIGIT THREE +35 Z 0 z Z 002e // LATIN SMALL LETTER Z, LATIN CAPITAL LETTER Z, FULL STOP (PERIOD) +// numpad dot +53 DECIMAL 0 002e 002e 002e // FULL STOP (PERIOD), FULL STOP (PERIOD), FULL STOP (PERIOD) +//36 ???? 0 ???? ???? ???? // right shift, right shift, right shift + +// bottom-most row + +//?? ???? 0 ???? ???? ???? // left ctrl, left ctrl, left ctrl +//5b ???? 0 ???? ???? ???? // left super (win), left super (win), left super (win) +//?? ???? 0 ???? ???? ???? // left alt (meta), left alt (meta), left alt (meta) +39 SPACE 0 0020 00a0 00a0 // SPACE, NO-BREAK SPACE, NO-BREAK SPACE +//38 ???? 0 ???? ???? ???? // right alt (meta), right alt (meta), right alt (meta) +//5c ???? 0 ???? ???? ???? // right super (win), right super (win), right super (win) +//?? ???? 0 ???? ???? ???? // menu, menu, menu +//5d ???? 0 ???? ???? ???? // menu, menu, menu +//56 ???? 0 ???? ???? ???? // menu, menu, menu +//1d ???? 0 ???? ???? ???? // right ctrl, right ctrl, right ctrl +//46 ???? 0 ???? ???? ???? // scroll lock, scroll lock, scroll lock + +//LIGATURE +// +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// a mod b c + +//KEYNAME +// +//01 Esc +//0e Backspace +//0f Tab +//1c Enter +//1d Ctrl +////2a Shift +//2a "Left Shift" +//36 "Right Shift" +//37 "Num *" +//38 Alt +//39 Space +//3a "Caps Lock" +//3b F1 +//3c F2 +//3d F3 +//3e F4 +//3f F5 +//40 F6 +//41 F7 +//42 F8 +//43 F9 +//44 F10 +//45 Pause +//46 "Scroll Lock" +//47 "Num 7" +//48 "Num 8" +//49 "Num 9" +//4a "Num -" +//4b "Num 4" +//4c "Num 5" +//4d "Num 6" +//4e "Num +" +//4f "Num 1" +//50 "Num 2" +//51 "Num 3" +//52 "Num 0" +//53 "Num Del" +//54 "Sys Req" +//57 F11 +//58 F12 +//7c F13 +//7d F14 +//7e F15 +//7f F16 +//80 F17 +//81 F18 +//82 F19 +//83 F20 +//84 F21 +//85 F22 +//86 F23 +//87 F24 +// +//KEYNAME_EXT +// +//1c "Num Enter" +//1d "Right Ctrl" +//35 "Num /" +//37 "Prnt Scrn" +//38 "Right Alt" +//45 "Num Lock" +//46 Break +//47 Home +//48 Up +//49 "Page Up" +//4b Left +//4d Right +//4f End +//50 Down +//51 "Page Down" +//52 Insert +//53 Delete +//54 <00> +//54 "Sys Req" +//56 Help +//5b "Left Windows" +//5c "Right Windows" +//5d Application + +DESCRIPTIONS + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German Dvorak ltgt (useful for text with lots of <>) +//0409 German Dvorak writer (useful for text with lower/upper UTF-8 double quotes) + +LANGUAGENAMES + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German or related (all locations world-wide) + +ENDKBD + +// vim: set ft=javascript: diff --git a/platform/win/source-20180601-gerdLTGT/gerdLTGT - Kopie.C b/platform/win/source-20180601-gerdLTGT/gerdLTGT - Kopie.C new file mode 100644 index 0000000..0338bfb --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/gerdLTGT - Kopie.C @@ -0,0 +1,520 @@ +/***************************************************************************\ + ä Ö Ü ß +* Module Name: gerdLTGT.C +* +* keyboard layout +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* History: +* KBDTOOL v3.40 - Created Mon May 29 08:05:02 2017 +\***************************************************************************/ + +#include +#include "kbd.h" +#include "winuser.h" +#include "gerdLTGT.h" + +#if defined(_M_IA64) +#pragma section(".data") +#define ALLOC_SECTION_LDATA __declspec(allocate(".data")) +#else +#pragma data_seg(".data") +#define ALLOC_SECTION_LDATA +#endif + +/***************************************************************************\ +* ausVK[] - Virtual Scan Code to Virtual Key conversion table +\***************************************************************************/ + +static ALLOC_SECTION_LDATA USHORT ausVK[] = { + T00, T01, T02, T03, T04, T05, T06, T07, + T08, T09, T0A, T0B, T0C, T0D, T0E, T0F, + T10, T11, T12, T13, T14, T15, T16, T17, + // 24 + + T18, T19, T1A, T1B, T1C, + // 5 + + + /* + * Left Ctrl FIXME + */ + T1D, + + T1E, T1F, + T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, + // 12 + + + /* + * Left-hand Shift FIXME + */ + T2A, + + T2B, T2C, T2D, T2E, T2F, + T30, T31, T32, T33, T34, T35, + // 11 + + + /* + * Right-hand Shift key must have KBDEXT bit set. + */ + T36 | KBDEXT, + + T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot + + T38, T39, T3A, T3B, T3C, T3D, T3E, + T3F, T40, T41, T42, T43, T44, + // 13 + + + /* + * NumLock Key: + * KBDEXT - VK_NUMLOCK is an Extended key + * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL) + */ + T45 | KBDEXT | KBDMULTIVK, + + T46 | KBDMULTIVK, + + /* + * Number Pad keys: + * KBDNUMPAD - digits 0-9 and decimal point. + * KBDSPECIAL - require special processing by Windows + */ + T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home) + T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up), + T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp), + T4A, + T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left), + T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear), + T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right), + T4E, + T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End), + T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down), + T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn), + T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins), + T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del), + + T54, T55, T56, T57, T58, T59, T5A, T5B, + T5C, T5D, T5E, T5F, T60, T61, T62, T63, + T64, T65, T66, T67, T68, T69, T6A, T6B, + T6C, T6D, T6E, T6F, T70, T71, T72, T73, + T74, T75, T76, T77, T78, T79, T7A, T7B, + // 40 + + T7C, T7D, T7E + // 3 = 127 + +}; + +static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = { + { 0x10, X10 | KBDEXT }, // Speedracer: Previous Track + { 0x19, X19 | KBDEXT }, // Speedracer: Next Track + { 0x1D, X1D | KBDEXT }, // RControl; Right Ctrl FIXME + { 0x20, X20 | KBDEXT }, // Speedracer: Volume Mute + { 0x21, X21 | KBDEXT }, // Speedracer: Launch App 2 + { 0x22, X22 | KBDEXT }, // Speedracer: Media Play/Pause + { 0x24, X24 | KBDEXT }, // Speedracer: Media Stop + { 0x2E, X2E | KBDEXT }, // Speedracer: Volume Down + { 0x30, X30 | KBDEXT }, // Speedracer: Volume Up + { 0x32, X32 | KBDEXT }, // Speedracer: Browser Home + { 0x35, X35 | KBDEXT }, // Numpad Divide + { 0x37, X37 | KBDEXT }, // Snapshot + { 0x38, X38 | KBDEXT }, // RMenu + { 0x47, X47 | KBDEXT }, // Home + { 0x48, X48 | KBDEXT }, // Up + { 0x49, X49 | KBDEXT }, // Prior + { 0x4B, X4B | KBDEXT }, // Left + { 0x4D, X4D | KBDEXT }, // Right + { 0x4F, X4F | KBDEXT }, // End + { 0x50, X50 | KBDEXT }, // Down + { 0x51, X51 | KBDEXT }, // Next + { 0x52, X52 | KBDEXT }, // Insert + { 0x53, X53 | KBDEXT }, // Delete + { 0x5B, X5B | KBDEXT }, // Left Win + { 0x5C, X5C | KBDEXT }, // Right Win + { 0x5D, X5D | KBDEXT }, // Application + { 0x5F, X5F | KBDEXT }, // Speedracer: Sleep + { 0x65, X65 | KBDEXT }, // Speedracer: Browser Search + { 0x66, X66 | KBDEXT }, // Speedracer: Browser Favorites + { 0x67, X67 | KBDEXT }, // Speedracer: Browser Refresh + { 0x68, X68 | KBDEXT }, // Speedracer: Browser Stop + { 0x69, X69 | KBDEXT }, // Speedracer: Browser Forward + { 0x6A, X6A | KBDEXT }, // Speedracer: Browser Back + { 0x6B, X6B | KBDEXT }, // Speedracer: Launch App 1 + { 0x6C, X6C | KBDEXT }, // Speedracer: Launch Mail + { 0x6D, X6D | KBDEXT }, // Speedracer: Launch Media Selector + { 0x1C, X1C | KBDEXT }, // Numpad Enter + { 0x46, X46 | KBDEXT }, // Break (Ctrl + Pause) + { 0, 0 } +}; + +static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = { + { 0x1D, Y1D }, // Pause + { 0 , 0 } +}; + +/***************************************************************************\ +* aVkToBits[] - map Virtual Keys to Modifier Bits +* +* See kbd.h for a full description. +* +*FIXME bad original description: +* The keyboard has only three shifter keys: +* SHIFT (L & R) affects alphabnumeric keys, +* CTRL (L & R) is used to generate control characters +* ALT (L & R) used for generating characters by number with numpad +\***************************************************************************/ +static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = { +// { VK_SHIFT , KBDSHIFT }, +// { VK_CONTROL , KBDCTRL }, +// { VK_MENU , KBDALT }, +// { 0 , 0 } + + // FIXME dumblob + // a hack to allow distinguishing left and right shift by propagating it to aModification[] + // make "KBDSHIFT | KBDCTRL" a unique bit combination for left shift + { VK_LSHIFT, KBDSHIFT | KBDCTRL }, + // make "KBDSHIFT | KBDCTRL" a unique bit combination for right shift + { VK_RSHIFT, KBDSHIFT | KBDALT }, + //{ VK_LCONTROL, KBDCTRL }, + //{ VK_RCONTROL, KBDCTRL }, + { 0, 0 } +}; + +/***************************************************************************\ +* aModification[] - map character modifier bits to modification number +* +* See kbd.h for a full description. +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = { + // Demonstration of the relationship (note: this demo is + // a complete nonsense in terms of an internal implementation): + // for( x in aVkToBits ){ + // if( x[0] == 0 && x[1] == 0 ) break + // if( x[1] <= wMaxModBits ){ + // // x[0] is not interesting + // if( aModification[x[1]] != SHFT_INVALID ){ + // shift_to_the_level( x[1] ) + // break + // } + // } + // } + + // PVK_TO_BIT pVkToBit; // Virtual Keys -> Mod bits + &aVkToBits[0], + // WORD wMaxModBits; // max Modification bit combination value + KBDSHIFT | KBDCTRL | KBDALT, + + // BYTE ModNumber[]; // Mod bits -> Modification Number + // mod_bits are an index to this array => order matters ( + // arithmetic progression with step 1 without any omission; + // use SHFT_INVALID as an ignored shift state) + { + // from kbd.h: + // #define KBDSHIFT (1 << 0) + // #define KBDCTRL (1 << 1) + // #define KBDALT (1 << 2) + // #define KBDKANA (1 << 3) + // #define KBDROYA (1 << 4) + // #define KBDLOYA (1 << 5) + // (1 << 6) doesn't exist (not defined anywhere) + // #define KBDGRPSELTAP (1 << 7) + + // FIXME test Ctrl and Alt key bindings (e.g. Ctrl+c, Alt+64, ...) + // shift_state_idx // KBDALT KBDCTRL KBDSHIFT + 0, // 0 0 0 + SHFT_INVALID, // 0 0 1 + SHFT_INVALID, // 0 1 0 + 1, // 0 1 1 (only LSHIFT pressed) + SHFT_INVALID, // 1 0 0 + 1, // 1 0 1 (only RSHIFT pressed) + SHFT_INVALID, // 1 1 0 + 2, // 1 1 1 (both LSHIFT and RSHIFT + // pressed simultaneously) + } +}; + +/***************************************************************************\ +* +* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states +* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states +* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states +* +* Table attributes: Unordered Scan, null-terminated +* +* Search this table for an entry with a matching Virtual Key to find the +* corresponding unshifted and shifted WCHAR characters. +* +* Special values for VirtualKey (column 1) +* 0xff - dead chars for the previous entry +* 0 - terminate the list +* +* Special values for Attributes (column 2) +* CAPLOK bit - CAPS-LOCK affect this key like SHIFT +* +* Special values for wch[*] (column 3 & 4) +* WCH_NONE - No character +* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none) +* WCH_LGTR - Ligature (generates multiple characters) +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VK_TO_WCHARS2 aVkToWch2[] = { +// | | Shift | +// |=========|=========| + {VK_TAB ,0 ,'\t' ,'\t' }, + {VK_ADD ,0 ,'+' ,'+' }, + {VK_DIVIDE ,0 ,'/' ,'/' }, + {VK_MULTIPLY ,0 ,'*' ,'*' }, + {VK_SUBTRACT ,0 ,'-' ,'-' }, + {0 ,0 ,0 ,0 } +}; + +// FIXME all unwanted VK_* keys should be redefined as WCH_NONE +static ALLOC_SECTION_LDATA VK_TO_WCHARS3 aVkToWch3[] = { +// | | Shift | Ctrl | +// |=========|=========|=========| + {VK_OEM_3 ,0 ,WCH_NONE ,WCH_NONE ,'~' }, + {'1' ,0 ,WCH_NONE ,WCH_NONE ,'!' }, + {'2' ,0 ,0x00e4 ,0x00c4 ,'@' }, + {'3' ,0 ,0x00f6 ,0x00d6 ,'#' }, + {'4' ,0 ,WCH_NONE ,WCH_NONE ,'$' }, + {'5' ,0 ,0x00fc ,0x00dc ,'%' }, + {'6' ,0 ,WCH_NONE ,WCH_NONE ,'^' }, + {'7' ,0 ,WCH_NONE ,WCH_NONE ,'&' }, + {'8' ,0 ,WCH_NONE ,WCH_NONE ,'*' }, + {'9' ,0 ,WCH_NONE ,WCH_NONE ,'(' }, + {'0' ,0 ,WCH_NONE ,WCH_NONE ,')' }, + {VK_OEM_4 ,0 ,0x00df ,0x1e9e ,'{' }, + {VK_OEM_6 ,0 ,WCH_NONE ,WCH_NONE ,'}' }, + {VK_OEM_102 ,0 ,WCH_NONE ,WCH_NONE ,WCH_NONE }, + {VK_OEM_7 ,0 ,'\'' ,'\"' ,WCH_NONE }, + {VK_OEM_COMMA ,0 ,',' ,'<' ,WCH_NONE }, + {VK_OEM_PERIOD,0 ,'.' ,'>' ,WCH_NONE }, + {'P' ,0 ,'p' ,'P' ,WCH_NONE }, + {'Y' ,0 ,'y' ,'Y' ,WCH_NONE }, + {'F' ,0 ,'f' ,'F' ,WCH_NONE }, + {'G' ,0 ,'g' ,'G' ,WCH_NONE }, + {'C' ,0 ,'c' ,'C' ,WCH_NONE }, + {'R' ,0 ,'r' ,'R' ,WCH_NONE }, + {'L' ,0 ,'l' ,'L' ,WCH_NONE }, + {VK_OEM_2 ,0 ,'/' ,'?' ,']' }, + {VK_OEM_PLUS ,0 ,'=' ,'+' ,'+' }, + {VK_OEM_5 ,0 ,'\\' ,'|' ,'|' }, + {'A' ,0 ,'a' ,'A' ,WCH_NONE }, + {'O' ,0 ,'o' ,'O' ,WCH_NONE }, + {'E' ,0 ,'e' ,'E' ,WCH_NONE }, + {'U' ,0 ,'u' ,'U' ,WCH_NONE }, + {'I' ,0 ,'i' ,'I' ,WCH_NONE }, + {'D' ,0 ,'d' ,'D' ,WCH_NONE }, + {'H' ,0 ,'h' ,'H' ,WCH_NONE }, + {'T' ,0 ,'t' ,'T' ,WCH_NONE }, + {'N' ,0 ,'n' ,'N' ,WCH_NONE }, + {'S' ,0 ,'s' ,'S' ,WCH_NONE }, + {VK_OEM_MINUS ,0 ,'-' ,'_' ,'\\' }, + {VK_OEM_1 ,0 ,';' ,':' ,WCH_NONE }, + {'Q' ,0 ,'q' ,'Q' ,WCH_NONE }, + {'J' ,0 ,'j' ,'J' ,WCH_NONE }, + {'K' ,0 ,'k' ,'K' ,WCH_NONE }, + {'X' ,0 ,'x' ,'X' ,WCH_NONE }, + {'B' ,0 ,'b' ,'B' ,WCH_NONE }, + {'M' ,0 ,'m' ,'M' ,WCH_NONE }, + {'W' ,0 ,'w' ,'W' ,WCH_NONE }, + {'V' ,0 ,'v' ,'V' ,WCH_NONE }, + {'Z' ,0 ,'z' ,'Z' ,WCH_NONE }, + {VK_DECIMAL ,0 ,'.' ,'.' ,'.' }, + {VK_SPACE ,0 ,' ' ,0x00a0 ,0x00a0 }, + {VK_BACK ,0 ,'\b' ,'\b' ,0x007f }, + {VK_ESCAPE ,0 ,0x001b ,0x001b ,0x001b }, + {VK_RETURN ,0 ,'\r' ,'\r' ,'\n' }, + {VK_CANCEL ,0 ,0x0003 ,0x0003 ,0x0003 }, + {0 ,0 ,0 ,0 ,0 } +}; + +// Put this last so that VkKeyScan interprets number characters +// as coming from the main section of the kbd (aVkToWch2 and +// aVkToWch5) before considering the numpad (aVkToWch1). + +static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = { + { VK_NUMPAD0 , 0 , '0' }, + { VK_NUMPAD1 , 0 , '1' }, + { VK_NUMPAD2 , 0 , '2' }, + { VK_NUMPAD3 , 0 , '3' }, + { VK_NUMPAD4 , 0 , '4' }, + { VK_NUMPAD5 , 0 , '5' }, + { VK_NUMPAD6 , 0 , '6' }, + { VK_NUMPAD7 , 0 , '7' }, + { VK_NUMPAD8 , 0 , '8' }, + { VK_NUMPAD9 , 0 , '9' }, + { 0 , 0 , '\0' } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = { + { (PVK_TO_WCHARS1)aVkToWch3, 3, sizeof(aVkToWch3[0]) }, + { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) }, + { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) }, + { NULL, 0, 0 }, +}; + +/***************************************************************************\ +* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables +* +* Table attributes: Ordered Scan (by scancode), null-terminated +* +* Only the names of Extended, NumPad, Dead and Non-Printable keys are here. +* (Keys producing printable characters are named by that character) +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNames[] = { + 0x01, L"Esc", + 0x0e, L"Backspace", + 0x0f, L"Tab", + 0x1c, L"Enter", + 0x1d, L"Ctrl", + 0x2a, L"Left Shift", + 0x36, L"Right Shift", + 0x37, L"Num *", + 0x38, L"Alt", + 0x39, L"Space", + 0x3a, L"Caps Lock", + 0x3b, L"F1", + 0x3c, L"F2", + 0x3d, L"F3", + 0x3e, L"F4", + 0x3f, L"F5", + 0x40, L"F6", + 0x41, L"F7", + 0x42, L"F8", + 0x43, L"F9", + 0x44, L"F10", + 0x45, L"Pause", + 0x46, L"Scroll Lock", + 0x47, L"Num 7", + 0x48, L"Num 8", + 0x49, L"Num 9", + 0x4a, L"Num -", + 0x4b, L"Num 4", + 0x4c, L"Num 5", + 0x4d, L"Num 6", + 0x4e, L"Num +", + 0x4f, L"Num 1", + 0x50, L"Num 2", + 0x51, L"Num 3", + 0x52, L"Num 0", + 0x53, L"Num Del", + 0x54, L"Sys Req", + 0x57, L"F11", + 0x58, L"F12", + 0x7c, L"F13", + 0x7d, L"F14", + 0x7e, L"F15", + 0x7f, L"F16", + 0x80, L"F17", + 0x81, L"F18", + 0x82, L"F19", + 0x83, L"F20", + 0x84, L"F21", + 0x85, L"F22", + 0x86, L"F23", + 0x87, L"F24", + 0 , NULL +}; + +static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNamesExt[] = { + 0x1c, L"Num Enter", + 0x1d, L"Right Ctrl", + 0x35, L"Num /", + 0x37, L"Prnt Scrn", + 0x38, L"Right Alt", + 0x45, L"Num Lock", + 0x46, L"Break", + 0x47, L"Home", + 0x48, L"Up", + 0x49, L"Page Up", + 0x4b, L"Left", + 0x4d, L"Right", + 0x4f, L"End", + 0x50, L"Down", + 0x51, L"Page Down", + 0x52, L"Insert", + 0x53, L"Delete", + 0x54, L"<00>", + 0x54, L"Sys Req", + 0x56, L"Help", + 0x5b, L"Left Windows", + 0x5c, L"Right Windows", + 0x5d, L"Application", + 0 , NULL +}; + +static ALLOC_SECTION_LDATA KBDTABLES KbdTables = { + /* + * Modifier keys + */ + &CharModifiers, + + /* + * Characters tables + */ + aVkToWcharTable, + + /* + * Diacritics + */ + NULL, + + /* + * Names of Keys + */ + aKeyNames, + aKeyNamesExt, + NULL, + +// /* +// * Scan codes to Virtual Keys +// */ +// USHORT *KBD_LONG_POINTER pusVSCtoVK; +// BYTE bMaxVSCtoVK; +// PVSC_VK pVSCtoVK_E0; // Scancode has E0 prefix +// PVSC_VK pVSCtoVK_E1; // Scancode has E1 prefix + /* + * Scan codes to Virtual Keys + */ + ausVK, + sizeof(ausVK) / sizeof(ausVK[0]), + aE0VscToVk, + aE1VscToVk, + + /* + * Locale-specific special processing + */ + MAKELONG(0, KBD_VERSION), + + /* + * Ligatures + */ + 0, + 0, + NULL +}; + +PKBDTABLES KbdLayerDescriptor(VOID) +{ + // There doesn't seem to be any easy reliable way to assign VK_ESCAPE to + // the CAPITAL virtual scancode in compile time due to a high diversity + // of keyboard types. + // FIXME supporting only HID keyboards would make it easy to assign + // VK_ESCAPE reliably in compile-time (2017: all widely used compilers + // can detect that the whole expression is static and compute it in + // compile time, but the MSKLC built-in compiler most probably can't) + int i; + for( i = 0; i < KbdTables.bMaxVSCtoVK; ++i ){ + if( KbdTables.pusVSCtoVK[i] == VK_CAPITAL ) + // CAPITAL (~ CapsLk) -> ESCAPE + KbdTables.pusVSCtoVK[i] = VK_ESCAPE; + } + + return &KbdTables; +} + +// vim: set wrap ft=c: diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.H b/platform/win/source-20180601-gerdLTGT/gerdLTGT - Kopie.H similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.H rename to platform/win/source-20180601-gerdLTGT/gerdLTGT - Kopie.H diff --git a/platform/win/gerd04/gerdLTGT.RC-mod00 b/platform/win/source-20180601-gerdLTGT/gerdLTGT - Kopie.RC similarity index 100% rename from platform/win/gerd04/gerdLTGT.RC-mod00 rename to platform/win/source-20180601-gerdLTGT/gerdLTGT - Kopie.RC diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.C.bak00 b/platform/win/source-20180601-gerdLTGT/gerdLTGT.C similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.C.bak00 rename to platform/win/source-20180601-gerdLTGT/gerdLTGT.C diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.DEF b/platform/win/source-20180601-gerdLTGT/gerdLTGT.DEF similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.DEF rename to platform/win/source-20180601-gerdLTGT/gerdLTGT.DEF diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.H.bak00 b/platform/win/source-20180601-gerdLTGT/gerdLTGT.H similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.H.bak00 rename to platform/win/source-20180601-gerdLTGT/gerdLTGT.H diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.RC.bak00 b/platform/win/source-20180601-gerdLTGT/gerdLTGT.RC similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.RC.bak00 rename to platform/win/source-20180601-gerdLTGT/gerdLTGT.RC diff --git a/platform/win/source-20180601-gerdLTGT/gerdLTGT.klc b/platform/win/source-20180601-gerdLTGT/gerdLTGT.klc new file mode 100644 index 0000000..24e4381 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/gerdLTGT.klc @@ -0,0 +1,327 @@ +// 2010-2017 Jan Pacner +// etaoin shrdlu! + +// The concept of this keyboard layout +// motto: be as much compatible with ISO dvorak as possible +// 4. level is the same as 3. level +// 2. level of ISO dvorak goes without modifications to the 3. level +// the whole national alphabet is accessible directly from 1. and 2. level +// without any exception +// 3. level has some additional non-alphabet characters (e.g. numbers) +// 3. level is accessible only by pressing both Shifts at once (and +// holding either of them) +// there are 2 variants which differ in placement and/or availability of +// characters ' " < > „ “ en_dash +// in `ltgt`, characters „ “ are not available and ' " < > are at their +// original dvorak places and ! is duplicated for better reachability +// in `writer`, all characters are available, but " < > are in +// the 3. level, thus less reachable + +// ----------- standard ISO dvorak, 1. and 2. level +// ~ ! @ # $ % ^ & * ( ) { } +// ` 1 2 3 4 5 6 7 8 9 0 [ ] +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// space +// space + +// ----------- german dvorak ltgt, 1. and 2. levelll +// ä Ö Ü ß +// ä ö ü ß +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak ltgt, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// nda ! § , 7 8 9 [ ] + | +// en dash +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak writer, 1. and 2. level +// ä Ö Ü ß +// ä ö ü ß +// +// “ nda ' P Y F G C R L ? + | +// en dash +// „ , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak writer, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// " < > § , 7 8 9 [ ] + | +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak (ltgt|writer), 4. level +// the same as 3. level + +// KBD identifier_max_8_bytes_long "Some description to show in keyboard settings and while switching layouts" +KBD gerdLTGT "German Dvorak ltgt (useful for text with lots of <>)" +//KBD gerdLTGT "German Dvorak writer (useful for text with lower/upper UTF-8 double quotes)" + +COPYRIGHT "MIT license" + +COMPANY "github.com/dumblob/ULKL/" + +LOCALENAME "de-DE" + +LOCALEID "00000407" +// LOCALEID "00000000" + +//FIXME 1.1 after unused keys produce the character +VERSION 1.0 + +//ATTRIBUTES + +//MODIFIERS + +SHIFTSTATE + +// shift_state_idx // column_below modifiers +0 // 4 +1 // 5 LSHIFT or RSHIFT pressed +2 // 6 both LSHIFT and RSHIFT pressed simultaneously + +LAYOUT +// an extra @ at the end is a dead key +// -1 denotes the character +// SC denotes a Virtual Scan Code +// Cap ~ CapsInfo (probably whether CapsLock is applicable) + +// topmost row + +//SC VK_ Cap 0 1 2 +29 OEM_3 0 -1 -1 007e // , , TILDE +02 1 0 -1 -1 0021 // , , EXCLAMATION MARK +03 2 0 00e4 00c4 0040 // adiaeresis, Adiaeresis, COMMERCIAL AT +04 3 0 00f6 00d6 0023 // odiaeresis, Odiaeresis, NUMBER SIGN +05 4 0 -1 -1 0024 // , , DOLLAR SIGN +06 5 0 00fc 00dc 0025 // udiaeresis, Udiaeresis, PERCENT SIGN +07 6 0 -1 -1 005e // , , CIRCUMFLEX ACCENT +08 7 0 -1 -1 0026 // , , AMPERSAND +09 8 0 -1 -1 002a // , , ASTERISK +0a 9 0 -1 -1 0028 // , , LEFT PARENTHESIS +0b 0 0 -1 -1 0029 // , , RIGHT PARENTHESIS +0c OEM_4 0 00df 1e9e 007b // ssharp, U1E9E, LEFT CURLY BRACKET (BRACELEFT) +0d OEM_6 0 -1 -1 007d // , , RIGHT CURLY BRACKET (BRACERIGHT) +// FIXME wtf is this key? is it really ? +56 OEM_102 0 -1 -1 -1 // , , +//0e ???? 0 ???? ???? ???? // backspace, backspace, backspace + +// top row + +//0f ???? 0 ???? ???? ???? // tab, tab, tab +// ltgt variant +10 OEM_7 0 0027 0022 -1 // APOSTROPHE, QUOTATION MARK (QUOTEDBL), +11 OEM_COMMA 0 002c 003c 2013 // COMMA, LESS-THAN SIGN, U2013 (EN DASH, pomlcka) +12 OEM_PERIOD 0 002e 003e 0021 // FULL STOP (PERIOD), GREATER-THAN SIGN, EXCLAMATION MARK +// writer variant +//10 OEM_7 0 201e 201c 0022 // U201E LOWER QUOTATION MARK (QUOTEDBL), U201C UPPER QUOTATION MARK (QUOTEDBL), QUOTATION MARK (QUOTEDBL) +//11 OEM_COMMA 0 002c 2013 003c // COMMA, U2013 (EN DASH, pomlcka), LESS-THAN SIGN +//12 OEM_PERIOD 0 002e 0027 003e // FULL STOP (PERIOD), APOSTROPHE, GREATER-THAN SIGN + +13 P 0 p P 00a7 // LATIN SMALL LETTER P, LATIN CAPITAL LETTER P, SECTION SIGN (PARAGRAPH) +14 Y 0 y Y -1 // LATIN SMALL LETTER Y, LATIN CAPITAL LETTER Y, +15 F 0 f F 002c // LATIN SMALL LETTER F, LATIN CAPITAL LETTER F, COMMA +16 G 0 g G 7 // LATIN SMALL LETTER G, LATIN CAPITAL LETTER G, DIGIT SEVEN +17 C 0 c C 8 // LATIN SMALL LETTER C, LATIN CAPITAL LETTER C, DIGIT EIGHT +18 R 0 r R 9 // LATIN SMALL LETTER R, LATIN CAPITAL LETTER R, DIGIT NINE +19 L 0 l L 005b // LATIN SMALL LETTER L, LATIN CAPITAL LETTER L, LEFT SQUARE BRACKET +1a OEM_2 0 002f 003f 005d // SOLIDUS (SLASH), QUESTION MARK, RIGHT SQUARE BRACKET +1b OEM_PLUS 0 003d 002b 002b // EQUALS SIGN, PLUS SIGN, PLUS SIGN +2b OEM_5 0 005c 007c 007c // REVERSE SOLIDUS (BACKSLASH), VERTICAL LINE (BAR), VERTICAL LINE (BAR) + +// home/middle row + +//CapsLk +//3a ???? 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +//3a SGCap 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +1e A 0 a A 0040 // LATIN SMALL LETTER A, LATIN CAPITAL LETTER A, COMMERCIAL AT +1f O 0 o O 00b0 // LATIN SMALL LETTER O, LATIN CAPITAL LETTER O, DEGREE +20 E 0 e E 20ac // LATIN SMALL LETTER E, LATIN CAPITAL LETTER E, EURO SIGN +21 U 0 u U 0060 // LATIN SMALL LETTER U, LATIN CAPITAL LETTER U, GRAVE ACCENT (GRAVE) +22 I 0 i I -1 // LATIN SMALL LETTER I, LATIN CAPITAL LETTER I, +23 D 0 d D 003a // LATIN SMALL LETTER D, LATIN CAPITAL LETTER D, COLON +24 H 0 h H 4 // LATIN SMALL LETTER H, LATIN CAPITAL LETTER H, DIGIT FOUR +25 T 0 t T 5 // LATIN SMALL LETTER T, LATIN CAPITAL LETTER T, DIGIT FIVE +26 N 0 n N 6 // LATIN SMALL LETTER N, LATIN CAPITAL LETTER N, DIGIT SIX +27 S 0 s S 003d // LATIN SMALL LETTER S, LATIN CAPITAL LETTER S, EQUALS SIGN +// pomlcka (= minus = dash) +28 OEM_MINUS 0 002d 005f 005c // HYPHEN-MINUS (FIXME is it the plain minus?), LOW LINE (UNDERSCORE), REVERSE SOLIDUS (BACKSLASH) +//1c ???? 0 ???? ???? ???? // enter/return, enter/return, enter/return + +// bottom row + +//2a ???? 0 ???? ???? ???? // left shift, left shift, left shift +// left bottom key, right from , which doesn't follow the kbd standard +// FIXME wtf is this key? is it really ? +//56 OEM_102 0 -1 -1 -1 // , , +2c OEM_1 0 003b 003a -1 // SEMICOLON, COLON, +2d Q 0 q Q -1 // LATIN SMALL LETTER Q, LATIN CAPITAL LETTER Q, +2e J 0 j J -1 // LATIN SMALL LETTER J, LATIN CAPITAL LETTER J, +2f K 0 k K -1 // LATIN SMALL LETTER K, LATIN CAPITAL LETTER K, +30 X 0 x X -1 // LATIN SMALL LETTER X, LATIN CAPITAL LETTER X, +31 B 0 b B 0 // LATIN SMALL LETTER B, LATIN CAPITAL LETTER B, DIGIT ZERO +32 M 0 m M 1 // LATIN SMALL LETTER M, LATIN CAPITAL LETTER M, DIGIT ONE +33 W 0 w W 2 // LATIN SMALL LETTER W, LATIN CAPITAL LETTER W, DIGIT TWO +34 V 0 v V 3 // LATIN SMALL LETTER V, LATIN CAPITAL LETTER V, DIGIT THREE +35 Z 0 z Z 002e // LATIN SMALL LETTER Z, LATIN CAPITAL LETTER Z, FULL STOP (PERIOD) +// numpad dot +53 DECIMAL 0 002e 002e 002e // FULL STOP (PERIOD), FULL STOP (PERIOD), FULL STOP (PERIOD) +//36 ???? 0 ???? ???? ???? // right shift, right shift, right shift + +// bottom-most row + +//?? ???? 0 ???? ???? ???? // left ctrl, left ctrl, left ctrl +//5b ???? 0 ???? ???? ???? // left super (win), left super (win), left super (win) +//?? ???? 0 ???? ???? ???? // left alt (meta), left alt (meta), left alt (meta) +39 SPACE 0 0020 00a0 00a0 // SPACE, NO-BREAK SPACE, NO-BREAK SPACE +//38 ???? 0 ???? ???? ???? // right alt (meta), right alt (meta), right alt (meta) +//5c ???? 0 ???? ???? ???? // right super (win), right super (win), right super (win) +//?? ???? 0 ???? ???? ???? // menu, menu, menu +//5d ???? 0 ???? ???? ???? // menu, menu, menu +//56 ???? 0 ???? ???? ???? // menu, menu, menu +//1d ???? 0 ???? ???? ???? // right ctrl, right ctrl, right ctrl +//46 ???? 0 ???? ???? ???? // scroll lock, scroll lock, scroll lock + +//LIGATURE +// +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// a mod b c + +//KEYNAME +// +//01 Esc +//0e Backspace +//0f Tab +//1c Enter +//1d Ctrl +////2a Shift +//2a "Left Shift" +//36 "Right Shift" +//37 "Num *" +//38 Alt +//39 Space +//3a "Caps Lock" +//3b F1 +//3c F2 +//3d F3 +//3e F4 +//3f F5 +//40 F6 +//41 F7 +//42 F8 +//43 F9 +//44 F10 +//45 Pause +//46 "Scroll Lock" +//47 "Num 7" +//48 "Num 8" +//49 "Num 9" +//4a "Num -" +//4b "Num 4" +//4c "Num 5" +//4d "Num 6" +//4e "Num +" +//4f "Num 1" +//50 "Num 2" +//51 "Num 3" +//52 "Num 0" +//53 "Num Del" +//54 "Sys Req" +//57 F11 +//58 F12 +//7c F13 +//7d F14 +//7e F15 +//7f F16 +//80 F17 +//81 F18 +//82 F19 +//83 F20 +//84 F21 +//85 F22 +//86 F23 +//87 F24 +// +//KEYNAME_EXT +// +//1c "Num Enter" +//1d "Right Ctrl" +//35 "Num /" +//37 "Prnt Scrn" +//38 "Right Alt" +//45 "Num Lock" +//46 Break +//47 Home +//48 Up +//49 "Page Up" +//4b Left +//4d Right +//4f End +//50 Down +//51 "Page Down" +//52 Insert +//53 Delete +//54 <00> +//54 "Sys Req" +//56 Help +//5b "Left Windows" +//5c "Right Windows" +//5d Application + +DESCRIPTIONS + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German Dvorak ltgt (useful for text with lots of <>) +//0409 German Dvorak writer (useful for text with lower/upper UTF-8 double quotes) + +LANGUAGENAMES + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German or related (all locations world-wide) + +ENDKBD + +// vim: set ft=javascript: diff --git a/platform/win/source-20180601-gerdLTGT/i386/gerdLTGT.dll b/platform/win/source-20180601-gerdLTGT/i386/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..c2210283090d8b9e97451fb7b6986c0f1a593cb8 GIT binary patch literal 4608 zcmeH~ZE%!V703TKn<}&$Or?J4SoB#4kYd;nHWaEpDy^th8Eh+BKH3>RIDQdZ#^Hl6qedN_aqJj>=k9Jcq134_ zGmZ}T&bjB_^PGF0bIo8stWU_RgMQq>#?U>*{W7D4SkZn|b}d%uP>K z==iCjr}|hQKXreZPnP+(=iRx%Vbgsp&$_lsNf*%{BJbK?(YdUe*iCLxX}P2#h1ZwK zW;U-W#X(x^i7zs|(E0VLB=~=LBV)N2W!7WmEX;~Tr>EaFZ1?BlV>9%W#|6Nf$ zohqg<^0@hCe!T>D>s;Yi-iq@i3Dwpx9_~e74wB&TArT zZRq*Q_2GXu0<(IrTC`pXwQ7Uz&_-?2oh1CH`k5AS4_?!YdRbk%PusLzTflfy-`Dq4 zr!VTG>eN>4(LHL{4)y9@_2?y?*R(F_oOWxcI@AY5cIjil^M? zopH-_$_0AP#q?dbT;FmH`lgHPdACkqck6Z9ZBW5&RFm7JFS+e%a67ch-J_W6&`P&U zt6is7xGpui-CFLtwbu10?)GcHJD>yZpbolz^}CF|>W1_+m({awSYL5DJ>w4R%kGH2 z}qBgRHFt0k-})I555nG#Fn4CX6>)DS+P& zK3>=7-}fLWvGv2`#<*r)(`qee{-T<+SxbYL71xIq13_cZGvH_n(#$pufv6@hm4!Bf ztU+iK_zIyrL0KN!57wIX5gi0^clonk(gAY)5ZFsWZ6L4!odJg#=yb3LMD5WbFqwli z)2=k={2=%ohFU>s5!wJ&N1;1F>^O86xLvD$Y@gGI(ALau5V{+_leq4LcM$6icpq5p zgWs(Iki8CUk3cOTd=gp@&W}O~(Eb1v=PhyH18_f0U*!7#vVWbP2Q zQ`jBA<{iK7u0-1TW|1|Oo$SStyIA6UJ zw&3~aApeD%dsv-RzNOuK;|!P;+QB*rbwQ6n{g9N+gz04O_TG3ppI65~I+>cvgzcH} z!7w*gEQD3Fes=Z>j=ge~@cQz<6oDH5b08p{29_Q0g^onHi~NW{z7>89o`j!#lb-V! zdG;Fe#o+Qhdloh)lV4mYWL1)1zJ~mr=+7X(*dRSQ?|I)!@7J7Un&)fgR!m~jbfhYn zjA|i8~Wk*QlmP(@=LY9`&$M1joek68@G5^tEJb#jpiC^4tqsv zT8>JP#afQKmcjBUH@Se~B{n$jdZoAes$#z-Z$-WZoe?T$3jHa(NwLa!^I0qvsR9#J zh&UC(^qQ#>6Yv4vQDAJQ5+`J*_iNSD=YgATF*XPymj+?0Ivfoevgmq7UnJ9nw?>vx7Cfl)O#SlXNx&wXIa;fXfdi_(N-l? zT^%bsQ|Y}6<8yU(-YPfk?04KM%X#H(Rpd(z+!^7qVat5Y!{^6GI#YWCS;_EiZs%_P zE3K7Z7yoHA+wCgiZvY=++{`Z=!_wPn_KRn}KX$VM$S_kyStIj2-EvtVm({q~TPKl) yJV_H5yJHrixBLD#`B-22KYF_5LgGh>A1AIPevx=1QQNwx^-(K~*W3Sj1pW^3@!10a literal 0 HcmV?d00001 diff --git a/platform/win/source-20180601-gerdLTGT/i386/gerdLTGT.exp b/platform/win/source-20180601-gerdLTGT/i386/gerdLTGT.exp new file mode 100644 index 0000000000000000000000000000000000000000..61eb13a6119d1ba0bcd745bf5bb57e1cbf861581 GIT binary patch literal 672 zcmZuuUrWMJ6hG6<9)k2G#3J?}Xb{U1LVQU|h;nI|J~gQ6t}@a#?v|$CAm|J9Df$3C z^b&pyKR^)ug?b3=oQ(|&5Br__yTAQ*ch0%85QO*O!pXM)Fb7Tu64O*$bvKkNh#SO+ zHW;&rJU)`f>X)s=F=-T!h&Y}z8F`58NE&AiyURR1j%4)D2Lbmj)#CZc;=$AYt}Vtj zxw==Cw00Ycbxl_Lj2D>I;JRrW9OltZ2Zv!9bI@TT<{5`2FoztLax(eWkWqhO$Mc5l z3=sn%iVNtO?3UvHlwFySg2iYU-_Y3{A*kDku=HbvzLb?r>*@Kme|LQg@PT?70lPV+W-)Fl2S=)cjh@?vsr2*;W({)!|0fjt|f;97>}v`$y=v7f?y3wY6ov^6L+q{TV|Ka mpm}+U>!P`NO0Uc{w_aCCl+qX*u-Cl zd@A=4Pf0cHDrv_C@C-060PB{-8DKQxM~Kq;=0?>Q#gAL7)zYTFQ5E}*F!1~}A3{{N zJ?~EooGX)#f&Xc{QWnJ(e+8nv8+f(TMp$ed*TZHzYK8Qf=22Vp+8LTruFGhIC|wx9 ztp&^ww`eq`h!GetX}0?K@-KY*Gw2@)6{2Ktc*s2emaXj4lFZwV?HLw+T9cnAiQhQ! zq+uk3#_q}f+*U^gR!R7x6uB0V_>gP{wWv0iQClxbxTfca1Sni6AayD2auUW15)3*| z*)d*#b7|5#jpwXlLMOF=>BJa;{6QY<=={~xdb1w3j$3{2IDJ07_1mKsA z+eH|k;I^h-iW zOCefs4}HK_A6%)7Eov`RtFn+*?DDnCJozHFT`nK0E_Ga9R$aP`zkOyV7Xq$&c~N`L z+TT8BpMCb(XP^H*=i7Vuf+CVCp_v)!3fxMo|Ni68G{eh3balC2sCuRLii^Ke+dYsO z35LU5I!p`(eTku=+-T673c|6WATt!S?du8#bIDY!x_ViC$@I#~)N2o>?s&XR=Pvd? z-b4S~#fM6Kyu?R5@67ZKnC|U7+rNX6iirLYdDoG$PC<3S9TiK9-Q{H|Jn-#FXUy6a z#W+Y+T4Eh5lMumqvS0FgH72B3zIY|k_&9Gb57&~I=y7RpwvE5cHA_Ul3I)GloY({X)Y-&3`| zqWiQ@J9JR(YSV6Y>j8D?MP1jFZs@8GXpcJ710?q96FQ{BdcvKo$OFdrYFG~`)QCnk zrqdeN8BORyOVtUp!={dJaPrEJ3xvg67TJ%-7OZ9HI*0^@nx(=;&d$rc> z(<--L4eo&IT&Fg;F2&pt9dSo>)E(0?cU;F^N?&*V`i4vEk{i(1Tt-j1lX}vf(sx`| zFStQ{+kHUQZl@ytsxc6))Sbpuw9PHG)> zP#dU=%XO)s!Z|QtycQ(_Vubk>?5MupLf)nFwK#TEpV8(a@ z$T5Bw_<2oV{@^2^$oh|RcE(kBRclp8` zfcJpq9{Bz01^G>2e-PS828=_S$b-|+X0qX7D8?!=Ujy=Din`R-^JHbQR+DMfTE-h) ztT&(F3D!tpzZctm*iEvB6#n<)dz!cn5VMS(PPx<-@e?UMhtp*|+514bzN$FxZh9+< zqtfM)examSmfw~KMSJJV3Z?l|C0=?}%cGu`-|m;|i=&2jqbu~ULD!)-pdUd}Iu$14 z-MhMD$!t~~y~%iDA{Dl!M*70c@MtbH6)UTYe$evy(^OyN%ierF(q2EQvrPd*m0H2q z)*`_smvW2zf0YXV{0GFyp7!1Fh5L_?YySD4+yOtscpQFVk)HE0ymSkBRVC-goQ1{7 zw9>-6KIhvZ@4?7CpEmLq z1VqWcoBg+$p19#_m}l{{bwhXpZ{{ME_R{16zc&*xn|&Aa_vn4h-_OjPk6s^k=4Oi% z2(ggx*3Iu;ybie0yL?=?)86Q<*&YsiTb=0J87F*ng4we!Ms$9h{~6oce0<{AP5T`h zGKTTRPA?4(EQ)(ss~eB9$okM6@*arys){}CE9n{%Ek>9=2 z0N&4c8-Fl{rMFV-k7m92k|ZvcV-}&ey8a>` n17VR!KT)`-d`-S7-;zI(AI_i2zmYHG-^?%4e_QZB6@kA4Z5!+= literal 0 HcmV?d00001 diff --git a/platform/win/source-20180601-gerdLTGT/ia64/gerdLTGT.exp b/platform/win/source-20180601-gerdLTGT/ia64/gerdLTGT.exp new file mode 100644 index 0000000000000000000000000000000000000000..ac6aa6027bd8aa50a457e2cbbf5ffe3e8f26619f GIT binary patch literal 671 zcmZuu%}T>S5S}zvJqV^3tyLt4LMuq>A0oY2v>@8pN^MUDByF}K*qX43t?kLH;0yQ^ zK7a==(#Pln2%=&^4?>+ynoy-fX6D;(XE(FoK!}GvKYRAg0ZfBu646vg9WF2x(eKcE zLuwLp20uw7l`B1dI;7zlK@9I1wG0S*l153@X%e50A?W?9gOIn&dhzR6iSIu5H|vCI za_OKXY4tkfDw?de3C$9_N)5{~Da>FwyI6oFjJ%6Pj1w-3V+^|}iE+wBs~Fk)1h?h` z(K&h)xCkaN)a@-L_$j%zAPI93cJhX8qcIH=-D9IlP1~$FVzRg*%7^(Jzyj<_6#ucHRbuK!d#za$6YT{7L9j7qt(Zbs(cpUWFd~aeqJgYr$bqv+TV0e)EQTe`lwcYi|8$B|dLF9jRs7T_KdW9%$Y;9I;QCQzztCqIx&8j$TxQ=Ciwjo4i$FiPl z;8Lmh3U+a)QWk|(dliZDzGKzS8*ZU-T6df6PRm6IBt-M1EkYIs_A{?M-iyb`(Ypws z6H^=luE=ZpAx2LG8qLxE?faLo^z^ECyi_0)&hat({!(5uOG}S=)uOnMj_;0>&m-g~ zkA&0MKRcY+_9bAAn6FBZ)P(*i(R6B^+Duw4y(8v3y}u+7C2AshBlQ*~jJL!@=scyz zxC!G%BRYvu7BLodY7Ue78v?)Z3Jo@N_I6^US$A8ft%Hs+SN&jErApab{c{>4fK8#g zrNIf-J)W{lGbGeNSfeys-w3TmE^U{iFl@M2E-iFMXC(q2luAJ_`;Lrs}hd!ddT! r5+r54SBP&vv7I6ldS7A#S7o;-4gNZDvqIyW%pis?m#{BJFoF0D?@Cta literal 0 HcmV?d00001 diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (10).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (10).sh new file mode 100644 index 0000000..a142239 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (10).sh @@ -0,0 +1,253 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=X64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + printf 'INFO Compiling %s...\n' "$outdir" + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + #"$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + "$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + printf '\nHOWK00\n\n' + + # FIXME WINVER and WIN32_IE higher than at rc.exe + #"$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 -DWINVER=x5 -D_WIN32_IE=x5 -MD -c -Zp8 -Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Z7 -Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + # FIXME -Gz (x86 only) + # FIXME -Gm + "$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0500 -D_WIN32_IE=0x0500 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox -Fo"$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + printf '\nHOWK11\n\n' + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + # FIXME -noentry will probably disable main(); we need main() though + # -section:init,d might have deleted it :( + #"$p\\link.exe" -nologo -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:0x04,0x01 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + # FIXME -merge:.rdata=.data + "$p\\link.exe" "-machine:$machine" -nologo -SECTION:INIT,d -noentry -OPT:REF -OPT:ICF -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-def:${kbdname}.def" "-out:$outdir\\${kbdname}.dll" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" + + printf '\nHOWK22\n\n' + + if [ -n "$(ls -1 "$TEMP_WIN\\my_layout."* 2>/dev/null)" ]; then + rm "$TEMP_WIN\\my_layout."* + fi +done + +# vim: set wrap: diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (11).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (11).sh new file mode 100644 index 0000000..cff44bf --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (11).sh @@ -0,0 +1,249 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=IA64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + printf '\nINFO Compiling %s...\n' "$outdir" + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + #"$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + "$msklc\\bin\\i386\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than at rc.exe + #"$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 -DWINVER=x5 -D_WIN32_IE=x5 -MD -c -Zp8 -Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Z7 -Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + # FIXME -Gz (x86 only) + # FIXME -Gm + "$p\\cl.exe" "-I$msklc\\inc" -nologo -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0500 -D_WIN32_IE=0x0500 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox -Fo"$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + # FIXME -noentry will probably disable main(); we need main() though + # -section:init,d might have deleted it :( + #"$p\\link.exe" -nologo -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:0x04,0x01 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + # FIXME -merge:.rdata=.data + # FIXME -SECTION:INIT,d + # LINK : warning LNK4039: section 'INIT' specified with /SECTION option does not exist + "$p\\link.exe" "-LIBPATH:$msklc\\lib\\$libdir" "-MACHINE:$machine" -nologo -noentry -OPT:REF -OPT:ICF -dll "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-DEF:${kbdname}.def" "-OUT:$outdir\\${kbdname}.dll" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" + + if [ -n "$(ls -1 "$TEMP_WIN\\my_layout."* 2>/dev/null)" ]; then + rm "$TEMP_WIN\\my_layout."* + fi +done + +# vim: set wrap: diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (12).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (12).sh new file mode 100644 index 0000000..84a4efe --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (12).sh @@ -0,0 +1,255 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 +readonly TMPDIR_WIN="$(cmd.exe /c "echo %TEMP%")" + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken automatically into account as it should + readonly t="$(mktemp -p "$TMPDIR_WIN" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR_WIN" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | + sed -r 's|^[^=]+=[^0-9]*([0-9]+).*|\1|')))" -ne 0 \ + -o "$c" -le 0 ]; then + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + +# FIXME +# INFO Waiting 10s... Keine Instanzen verf▒gbar. +# 9s... Keine Instanzen verf▒gbar. +# 8s... Keine Instanzen verf▒gbar. + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME avoid collision with the default MSKLC compile directory +readonly dockbd="$USERPROFILE\\documents\\$kbdname" +if [ -e "$dockbd" ]; then + mv "$dockbd" "${dockbd}-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry (for VBS)? +# FIXME open it with a different DLL directory than \Userprofile\Documents +"$msklc/MSKLC.exe" "$layoutpath\\${kbdname}.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN_PREFIX="$(cmd.exe /c "echo %TEMP%")\\my_layout" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # FIXME + # 32bit on 64bit systems +# if [ "$idx" -eq 0 ]; then +# idx=$((idx +1)) +# defwow64=-DBUILD_WOW6432 +# outdir=wow64 +# else + outdir=i386 +# fi + ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=amd64 + fi + #outdir=amd64 + ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=IA64 + subsys_native_ver=5.02 + outdir=ia64 + ;; + esac + + printf '\nINFO Compiling DLL for %s...\n' "$outdir" + + # make traps local + ( + trap "rm -f '${TEMP_WIN_PREFIX}.res' '${TEMP_WIN_PREFIX}.obj'" \ + INT HUP TERM EXIT RETURN + + "$msklc\\bin\\i386\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "${TEMP_WIN_PREFIX}.res" "${kbdname}.rc" + + # FIXME -Gz (x86 only) + "$p\\cl.exe" -nologo -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox "-I$msklc\\inc" -Fo"${TEMP_WIN_PREFIX}.obj" "${kbdname}.c" + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + "$p\\link.exe" "-LIBPATH:$msklc\\lib\\$libdir" "-MACHINE:$machine" -nologo -noentry -OPT:REF -OPT:ICF -dll "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-DEF:${kbdname}.def" "-OUT:$outdir\\${kbdname}.dll" "${TEMP_WIN_PREFIX}.res" "${TEMP_WIN_PREFIX}.obj" + ) +done + +# vim: set wrap: diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (2).cmd b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (2).cmd new file mode 100644 index 0000000..8e9bab9 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (2).cmd @@ -0,0 +1,258 @@ +@rem http://steve-jansen.github.io/guides/windows-batch-scripting/index.html + +@rem disable the default echoing of every executed command +@echo off + +rem adds setlocal, chdir, ... (nonexistent before cca Win2000) +setlocal enableextensions +rem make all variables local solely to this batch +setlocal +rem treat string !abc! as a variable and expand it each time it's +rem accessed (unlike %abc% which gets expanded only once while parsing +rem a block in parenthesis) +setlocal enabledelayedexpansion + +rem FIXME c:\users\jpa\desktop\win\gerdltgt\make_pkg.cmd + +rem https://stackoverflow.com/a/26079981 +rem prevent interpretation for the first time +goto :endtrim +rem :trim ... +:trim + setlocal + if "%~1"=="" set emsg=%%1 != "" + if not "%emsg%"=="" ( + echo ERR failed assert in %0 %emsg% >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set x=%* + for /f "tokens=1*" %%a in ("!x!") do endlocal & set %~1=%%b + exit /b +:endtrim + +rem double quotes are not allowed in paths => we can safely remove them +set ccline=%CMDCMDLINE:"=% +set cspec=%COMSPEC:"=% +call :trim ccline %ccline% + +set msklc=C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4 + +rem argument 0 (full path with file name of this script) +set layoutpath=%~dp0 +rem remove trailing backslash (otherwise the "basename" trick doesn't work) +set layoutpath=%layoutpath:~0,-1% +rem basename +for %%_ in ("%layoutpath%") do set kbdname=%%~n_ + +if not exist "%msklc%" ( + echo ERR Dir "%msklc%" not found. Is MSKLC installed? >&2 + rem wait for user input + rem (can't use %CMDCMDLINE%, because it doesn't work when double clicked) + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + rem /b exits the batch, not the cmd.exe process + exit /b 1 +) + +for %%f in ( + "%layoutpath%\%kbdname%.c" + "%layoutpath%\%kbdname%.def" + "%layoutpath%\%kbdname%.h" + "%layoutpath%\%kbdname%.klc" + "%layoutpath%\%kbdname%.rc") do ( + if not exist %%f ( + echo ERR %%f >&2 + echo ERR ^^^^^^File not found (the file name without >&2 + echo ERR extension must be the same as its parent directory^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 + ) +) + +rem switch all processing of octets to UTF-8 (useful e.g. for "for /f ...") +rem note: wrongly looking characters on stdout are just a font issue +rem note: switching to non-ANSI codepage draws find, more, ... unusable +rem chcp 65001 + +set productname= +for /f "usebackq tokens=1,2*" %%a in ("%layoutpath%\%kbdname%.klc") do ( + if "%%a"=="KBD" ( + if "%%b"=="%kbdname%" ( + set productname=%%~c + goto :endfor00 + ) + ) +) +:endfor00 +if "%productname%"=="" ( + echo ERR Could not parse keyboard description from "%kbdname%.klc" >&2 + echo ERR Try converting it to ANSI 850 or UTF-16 or UTF-8 ( >&2 + echo ERR disregarding whether with BOM or not^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 +) + +rem is_installed +goto :endis_installed +:is_installed + setlocal + if "%~1"=="" set emsg=%%1 != "" + if "%~2"=="" set emsg=%%2 != "" + if "%~3"=="" set emsg=%%3 != "" + if not "%~4"=="" set emsg=number_of_arguments = 3 + if not "%emsg%"=="" ( + echo ERR failed assert in %0 (%emsg%^) >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set found=0 + set guid32= + + rem list all installed apps: wmic product get name + for /f "tokens=1" %%a in ( + 'wmic product where name^="%~3" get IdentifyingNumber 2^> NUL') do ( + if "!found!" equ "1" ( + set guid32=%%a + goto :endfor01 + ) + if "%%a"=="IdentifyingNumber" ( + rem at least one such app is installed + set found=1 + ) + ) + :endfor01 + + rem can't use %errorlevel% because it gets inconveniently overwritten + endlocal & set "%~1=%found%" & set "%~2=%guid32%" + exit /b +:endis_installed + +echo INFO Checking if installed: "%productname%" + +call :is_installed found guid32 "%productname%" +echo FIXME DEBUGguid32=%guid32% +if /i "%found%" neq "0" ( + rem the kbd uninstaller sometimes leaves shareddlls entries in registry + rem the kbd uninstaller leaves some dll files even if SharedDlls is 0 + +rem CreateObject^( "Shell.Application" ^).ShellExecute ^ +rem "wmic", "product where IdentifyingNumber=""%guid32%"" call uninstall", "", "runas", 1 :^ + echo on error resume next :^ +CreateObject^( "Wscript.Shell" ^).Run ^ + "wmic product where IdentifyingNumber=""%guid32%"" call uninstall", 1, true :^ +const hklm = ^&H80000002 :^ +set reg = GetObject^( ^ + "winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv" ^) :^ +set fs = createobject^( "Scripting.FileSystemObject" ^) :^ +for each s in array^( ^ + "C:\Windows\System32\%kbdname%.dll", ^ + "C:\Windows\SysWOW64\%kbdname%.dll" ^) :^ + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s :^ + fs.DeleteFile s, true :^ +next :^ +fs.DeleteFile "%temp%\marker.txt", true > "%temp%\elevated.vbs" + + rem FIXME how will this work if the current account will not + rem have admin rights? will there be any issues with password? + rem https://stackoverflow.com/a/23825726 + echo on error resume next :^ +set fs = createObject^( "Scripting.FileSystemObject" ^) :^ +fs.createTextFile^( "%temp%\marker.txt" ^) :^ +createObject^( "Shell.Application" ^).ShellExecute ^ + "cscript", "%temp%\elevated.vbs", "", "runas", 1 :^ +x = 600 :^ +do while fs.fileExists^( "%temp%\marker.txt" ^) :^ + if x ^< 0 then : exit do : end if :^ + wscript.sleep 100 :^ + x = x -1 :^ +loop > "%temp%\elevate.vbs" + + echo INFO Uninstalling "%productname%" + + "%temp%\elevate.vbs" + rem del /f /q "%temp%\elevate.vbs" > NUL + rem del /f /q "%temp%\elevated.vbs" > NUL + + rem we can't read stdout nor any return values from elevated processes through pipe + rem (we could read a file, but checking again is the safest possible method) + call :is_installed found _ "%productname%" + if /i "%found%" neq "0" ( + echo ERR Can't uninstall the kbd layout. >&2 + echo ERR Please do it manually and re-run this script. >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) +) +:endif00 + +if exist "%userprofile%\documents\%kbdname%" ( + rem removes all files recursively (does leave all directories in place) + del /f /s /q "%userprofile%\documents\%kbdname%" > NUL + rem removes all empty directories recursively + rmdir /s /q "%userprofile%\documents\%kbdname%" > NUL +) + +echo INFO >&2 +echo INFO Instructions for the "Keyboard Layout Creator": >&2 +echo INFO 1. click "Project" in menu -^> "Build DLL and Setup Package" >&2 +echo INFO 2. click "No" to disable viewing of "KeyboardVerify.log" >&2 +echo INFO 3. click "No" to disable opening of the Installer package directory >&2 +echo INFO 4. close the window of the "Keyboard Layout Creator" >&2 +echo INFO >&2 + +rem MSKLC will correctly generate all the install and setup files +rem "pipe to more" trick to wait for closing +"%msklc%\MSKLC.exe" "%layoutpath%\%kbdname%.klc" | more + +if exist "%userprofile%\Documents\KeyboardVerify.log" ( + del /f /q "%userprofile%\Documents\KeyboardVerify.log" > NUL +) +rem FIXME +pause +exit /b 1 + +rem recompile just the DLLs (the rest is prepared from MSKLC) +rem x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +for %%p in ( + "%msklc%\bin\i386" + "%msklc%\bin\i386" + "%msklc%\bin\i386\amd64" + "%msklc%\bin\i386\ia64") do ( + if %%p=="%msklc%\bin\i368" ( + echo howk11 + rem the second iteration is the same compiler, but a wow64 binary + if "!outdir!"=="i386" ( + set defwow64=-DBUILD_WOW6432 + set outdir=wow64 + ) else ( + set outdir=i386 + ) + ) + if %%p=="%msklc%\bin\i368\amd64" ( + echo howk 1100 + set outdir=amd64 + ) + if %%p=="%msklc%\bin\i368\ia64" set outdir=ia64 + + echo INFO Compiling layout "!outdir!\%kbdname%.dll" >&2 + + echo howk22 + + rem FIXME call this once for all architectures? + rem %%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "%%p\rc.exe" -r "-i%msklc%\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 "%layoutpath%\%kbdname%.rc" + + rem %%p\cl.exe -nologo -I%msklc%\inc -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 %defwow64% /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs %TEMP%/my_layout.obj "%layoutpath%\%kbdname%.c" + + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text +) + +echo INFO Success! Find the kbd layout in: >&2 +echo INFO %userprofile%\Documents\%kbdname% >&2 +rem FIXME the condition is wrong - bad variables? +if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + +rem vim: set wrap: diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (2).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (2).sh new file mode 100644 index 0000000..f9a3200 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (2).sh @@ -0,0 +1,184 @@ +#!/bin/sh + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver without the last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + readonly f="$TMP/elevate.vbs" + readonly f2="$TMP/wmic.cmd" + readonly f2_win='%TMP%\wmic.cmd' + # VBS needs double quotes quoted by putting them twice + readonly f2_vbs='%TMP%\wmic.cmd' + readonly f2log="${f2}.log" + readonly f2log_win="${f2_win}.log" + #readonly p="$(printf %s "$productname_quoted" | sed -r 's|"|""|g')" + + #printf '%s\n%s\n%s\n%s\n%s\n' "$f" "$f2" "$f2log" "$productname_quoted" "$p" + + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2_vbs"'","","","runas",1' > "$f" + printf %s "wmic product where name=$productname_quoted call uninstall > $f2log_win" > "$f2" + + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME cscript wscript + #wscript "$f" + #rm -f "$f" "$f2" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$f2log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$f2log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + + # FIXME wmic does not remove it + for f in "C:/Windows/System32/$kbdname" "C:/Windows/SysWOW64/$kbdname"; do + # FIXME + #[ -e "$f" ] && rm -f "$f" + [ -e "$f" ] && printf 'DEBUG rm -f %s\n' "$f" || true + done + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + # FIXME change "-l 409" to the language in klc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 409"$(grep -E '^LOCALEID' "$layoutpath/${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" /fo "${TEMP}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP/my_layout."* +} diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (3).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (3).sh new file mode 100644 index 0000000..15aafa8 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (3).sh @@ -0,0 +1,198 @@ +#!/bin/sh + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver without the last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || return 1 + readonly t="$(mktemp run_elevated.XXXXXX "$TMP/elevate.vbs")" + #trap 'rm -f "$t"' int term hup +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + readonly f="$TMP/elevate.vbs" + readonly f2="$TMP/wmic.cmd" + readonly f2_win='%TMP%\wmic.cmd' + # VBS needs double quotes quoted by putting them twice + readonly f2_vbs='%TMP%\wmic.cmd' + readonly f2log="${f2}.log" + readonly f2log_win="${f2_win}.log" + #readonly p="$(printf %s "$productname_quoted" | sed -r 's|"|""|g')" + + #printf '%s\n%s\n%s\n%s\n%s\n' "$f" "$f2" "$f2log" "$productname_quoted" "$p" + + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2_vbs"'","","","runas",1' > "$f" + printf %s "wmic product where name=$productname_quoted call uninstall > $f2log_win" > "$f2" + + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME cscript wscript + #cscript "$f" + #rm -f "$f" "$f2" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$f2log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$f2log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + + # FIXME wmic does not remove it + # FIXME needs elevation + for f in "C:/Windows/System32/$kbdname" "C:/Windows/SysWOW64/$kbdname"; do + # FIXME + #[ -e "$f" ] && rm "$f" + [ -e "$f" ] && printf 'DEBUG rm -f %s\n' "$f" || true + done + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP/my_layout."* +} diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (4).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (4).sh new file mode 100644 index 0000000..c9f3ef9 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (4).sh @@ -0,0 +1,208 @@ +#!/bin/sh + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver without the last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + readonly t="$(mktemp run_elevated.XXXXXXXXXXXXXXXX).vbs" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + cscript "$t" +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps only sometimes accept forward slashes + readonly a="$(printf %s "$TMP/app.cmd" | sed -r 's|/|\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + # FIXME + printf '%s\n' "DEBUG run_elevated $a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME wmic does not remove it +cat > "$a" </dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP/my_layout."* +} diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (5).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (5).sh new file mode 100644 index 0000000..cf98187 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (5).sh @@ -0,0 +1,222 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + readonly t="$(mktemp run_elevated.XXXXXXXXXXXXXXXX).vbs" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + cscript "$t" +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\|g').cmd" + readonly a_log="${a}.log" + + # make traps local + ( + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + # FIXME + printf '%s\n' "DEBUG run_elevated $a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +# sntnh +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" +readonly TEMP_WIN="$(printf %s "$TEMP" | sed -r 's|/|\|g')" +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP_WIN}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP_WIN}\\my_layout.res" "${TEMP_WIN}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP_WIN/my_layout."* +} diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (6).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (6).sh new file mode 100644 index 0000000..cf98187 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (6).sh @@ -0,0 +1,222 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + readonly t="$(mktemp run_elevated.XXXXXXXXXXXXXXXX).vbs" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + cscript "$t" +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\|g').cmd" + readonly a_log="${a}.log" + + # make traps local + ( + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + # FIXME + printf '%s\n' "DEBUG run_elevated $a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +# sntnh +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" +readonly TEMP_WIN="$(printf %s "$TEMP" | sed -r 's|/|\|g')" +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP_WIN}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP_WIN}\\my_layout.res" "${TEMP_WIN}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP_WIN/my_layout."* +} diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (7).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (7).sh new file mode 100644 index 0000000..51cba02 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (7).sh @@ -0,0 +1,225 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' < "$layoutpath\\${kbdname}.klc" | grep -E '^[[:blank:]]*localeid' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +readonly TEMP_WIN="$(printf %s "$TEMP" | sed -r 's|/|\\|g')" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + +#FIXME +#Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0 +#Copyright (C) Microsoft Corporation. All rights reserved. +#fatal error RC1107: invalid usage; use RC /? for Help + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP_WIN}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP_WIN}\\my_layout.res" "${TEMP_WIN}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP_WIN/my_layout."* +done diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (8).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (8).sh new file mode 100644 index 0000000..efa2a7f --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (8).sh @@ -0,0 +1,236 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + "$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + printf '\nHOWK00\n\n' + + # FIXME WINVER and WIN32_IE higher than at rc.exe + "$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + printf '\nHOWK11\n\n' + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "$p\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + printf '\nHOWK22\n\n' + + rm "$TEMP_WIN\\my_layout."* +done diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (9).sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (9).sh new file mode 100644 index 0000000..a45afd3 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie (9).sh @@ -0,0 +1,252 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=X64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + printf 'INFO Compiling %s...\n' "$outdir" + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + #"$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + "$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + printf '\nHOWK00\n\n' + + # FIXME WINVER and WIN32_IE higher than at rc.exe + #"$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 -DWINVER=x5 -D_WIN32_IE=x5 -MD -c -Zp8 -Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Z7 -Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + # FIXME -Gz (x86 only) + # FIXME -Gm + "$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0500 -D_WIN32_IE=0x0500 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox -Fo"$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + printf '\nHOWK11\n\n' + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + # FIXME -noentry will probably disable main(); we need main() though + # -section:init,d might have deleted it :( + #"$p\\link.exe" -nologo -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:0x04,0x01 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + # FIXME -SECTION:INIT,d -noentry + # FIXME -merge:.rdata=.data + "$p\\link.exe" "-machine:$machine" -nologo -OPT:REF -OPT:ICF -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-def:${kbdname}.def" "-out:$outdir\\${kbdname}.dll" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" + + printf '\nHOWK22\n\n' + + [ -n "$(ls -1 "$TEMP_WIN\\my_layout."*)" ] && rm "$TEMP_WIN\\my_layout."* +done + +# vim: set wrap: diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie.sh b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie.sh new file mode 100644 index 0000000..2b8ba5c --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg - Kopie.sh @@ -0,0 +1,157 @@ +#!/bin/sh + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" + +[ -x "$msklc" ] || { + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +} +for f in \ + "$layoutpath/${kbdname}.C" \ + "$layoutpath/${kbdname}.DEF" \ + "$layoutpath/${kbdname}.H" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.RC"; do + [ -r "$f" ] || { + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + } +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +[ -z "$productname_quoted" ] && { + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +} + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# list all installed apps: wmic product get name +[ -n "$(wmic product where name="$productname_quoted")" ] && { + readonly f="$TMP/elevate.vbs" + readonly f2="$TMP/wmic.cmd" + readonly f2_win='%TMP%\wmic.cmd' + # VBS needs double quotes quoted by putting them twice + readonly f2_vbs='%TMP%\wmic.cmd' + readonly f2log="${f2}.log" + readonly f2log_win="${f2_win}.log" + #readonly p="$(printf %s "$productname_quoted" | sed -r 's|"|""|g')" + + #printf '%s\n%s\n%s\n%s\n%s\n' "$f" "$f2" "$f2log" "$productname_quoted" "$p" + + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2_vbs"'","","","runas",1' > "$f" + printf %s "wmic product where name=$productname_quoted call uninstall > $f2log_win" > "$f2" + + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME cscript wscript + #wscript "$f" + #rm -f "$f" "$f2" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + [ "$(($(grep -E ReturnValue "$f2log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ] && { + rm -f "$f2log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + } + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break + c=$((c-1)) + done + echo + + # FIXME wmic does not remove it + for f in "C:/Windows/System32/$kbdname" "C:/Windows/SysWOW64/$kbdname"; do + # FIXME + #[ -e "$f" ] && rm -f "$f" + [ -e "$f" ] && printf 'DEBUG rm -f %s\n' "$f" + done + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +} + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +printf '%s\n' "WARN Please do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. click "Project" in menu -> "Build DLL and Setup Package" +INFO 2. click "No" to disable viewing of "KeyboardVerify.log" +INFO 3. click "No" to disable opening of the Installer package directory +INFO 4. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? +[ -e "${USERPROFILE}/documents/$kbdname" ] && \ + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" + +exit 1 + +"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +[ -e "$userprofile/Documents/KeyboardVerify.log" ] && \ + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i368") + # 32bit for 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i368/amd64") outdir=amd64 ;; + "$msklc/bin/i368/ia64") outdir=ia64 ;; + esac + + # FIXME $outdir not used + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -r "-i${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 "${layoutpath}\\${kbdname}.rc" + + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${layoutpath}\\${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj-merge:.edata=.data" -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text +} diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg.cmd b/platform/win/source-20180601-gerdLTGT/make_pkg.cmd new file mode 100644 index 0000000..8e9bab9 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg.cmd @@ -0,0 +1,258 @@ +@rem http://steve-jansen.github.io/guides/windows-batch-scripting/index.html + +@rem disable the default echoing of every executed command +@echo off + +rem adds setlocal, chdir, ... (nonexistent before cca Win2000) +setlocal enableextensions +rem make all variables local solely to this batch +setlocal +rem treat string !abc! as a variable and expand it each time it's +rem accessed (unlike %abc% which gets expanded only once while parsing +rem a block in parenthesis) +setlocal enabledelayedexpansion + +rem FIXME c:\users\jpa\desktop\win\gerdltgt\make_pkg.cmd + +rem https://stackoverflow.com/a/26079981 +rem prevent interpretation for the first time +goto :endtrim +rem :trim ... +:trim + setlocal + if "%~1"=="" set emsg=%%1 != "" + if not "%emsg%"=="" ( + echo ERR failed assert in %0 %emsg% >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set x=%* + for /f "tokens=1*" %%a in ("!x!") do endlocal & set %~1=%%b + exit /b +:endtrim + +rem double quotes are not allowed in paths => we can safely remove them +set ccline=%CMDCMDLINE:"=% +set cspec=%COMSPEC:"=% +call :trim ccline %ccline% + +set msklc=C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4 + +rem argument 0 (full path with file name of this script) +set layoutpath=%~dp0 +rem remove trailing backslash (otherwise the "basename" trick doesn't work) +set layoutpath=%layoutpath:~0,-1% +rem basename +for %%_ in ("%layoutpath%") do set kbdname=%%~n_ + +if not exist "%msklc%" ( + echo ERR Dir "%msklc%" not found. Is MSKLC installed? >&2 + rem wait for user input + rem (can't use %CMDCMDLINE%, because it doesn't work when double clicked) + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + rem /b exits the batch, not the cmd.exe process + exit /b 1 +) + +for %%f in ( + "%layoutpath%\%kbdname%.c" + "%layoutpath%\%kbdname%.def" + "%layoutpath%\%kbdname%.h" + "%layoutpath%\%kbdname%.klc" + "%layoutpath%\%kbdname%.rc") do ( + if not exist %%f ( + echo ERR %%f >&2 + echo ERR ^^^^^^File not found (the file name without >&2 + echo ERR extension must be the same as its parent directory^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 + ) +) + +rem switch all processing of octets to UTF-8 (useful e.g. for "for /f ...") +rem note: wrongly looking characters on stdout are just a font issue +rem note: switching to non-ANSI codepage draws find, more, ... unusable +rem chcp 65001 + +set productname= +for /f "usebackq tokens=1,2*" %%a in ("%layoutpath%\%kbdname%.klc") do ( + if "%%a"=="KBD" ( + if "%%b"=="%kbdname%" ( + set productname=%%~c + goto :endfor00 + ) + ) +) +:endfor00 +if "%productname%"=="" ( + echo ERR Could not parse keyboard description from "%kbdname%.klc" >&2 + echo ERR Try converting it to ANSI 850 or UTF-16 or UTF-8 ( >&2 + echo ERR disregarding whether with BOM or not^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 +) + +rem is_installed +goto :endis_installed +:is_installed + setlocal + if "%~1"=="" set emsg=%%1 != "" + if "%~2"=="" set emsg=%%2 != "" + if "%~3"=="" set emsg=%%3 != "" + if not "%~4"=="" set emsg=number_of_arguments = 3 + if not "%emsg%"=="" ( + echo ERR failed assert in %0 (%emsg%^) >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set found=0 + set guid32= + + rem list all installed apps: wmic product get name + for /f "tokens=1" %%a in ( + 'wmic product where name^="%~3" get IdentifyingNumber 2^> NUL') do ( + if "!found!" equ "1" ( + set guid32=%%a + goto :endfor01 + ) + if "%%a"=="IdentifyingNumber" ( + rem at least one such app is installed + set found=1 + ) + ) + :endfor01 + + rem can't use %errorlevel% because it gets inconveniently overwritten + endlocal & set "%~1=%found%" & set "%~2=%guid32%" + exit /b +:endis_installed + +echo INFO Checking if installed: "%productname%" + +call :is_installed found guid32 "%productname%" +echo FIXME DEBUGguid32=%guid32% +if /i "%found%" neq "0" ( + rem the kbd uninstaller sometimes leaves shareddlls entries in registry + rem the kbd uninstaller leaves some dll files even if SharedDlls is 0 + +rem CreateObject^( "Shell.Application" ^).ShellExecute ^ +rem "wmic", "product where IdentifyingNumber=""%guid32%"" call uninstall", "", "runas", 1 :^ + echo on error resume next :^ +CreateObject^( "Wscript.Shell" ^).Run ^ + "wmic product where IdentifyingNumber=""%guid32%"" call uninstall", 1, true :^ +const hklm = ^&H80000002 :^ +set reg = GetObject^( ^ + "winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv" ^) :^ +set fs = createobject^( "Scripting.FileSystemObject" ^) :^ +for each s in array^( ^ + "C:\Windows\System32\%kbdname%.dll", ^ + "C:\Windows\SysWOW64\%kbdname%.dll" ^) :^ + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s :^ + fs.DeleteFile s, true :^ +next :^ +fs.DeleteFile "%temp%\marker.txt", true > "%temp%\elevated.vbs" + + rem FIXME how will this work if the current account will not + rem have admin rights? will there be any issues with password? + rem https://stackoverflow.com/a/23825726 + echo on error resume next :^ +set fs = createObject^( "Scripting.FileSystemObject" ^) :^ +fs.createTextFile^( "%temp%\marker.txt" ^) :^ +createObject^( "Shell.Application" ^).ShellExecute ^ + "cscript", "%temp%\elevated.vbs", "", "runas", 1 :^ +x = 600 :^ +do while fs.fileExists^( "%temp%\marker.txt" ^) :^ + if x ^< 0 then : exit do : end if :^ + wscript.sleep 100 :^ + x = x -1 :^ +loop > "%temp%\elevate.vbs" + + echo INFO Uninstalling "%productname%" + + "%temp%\elevate.vbs" + rem del /f /q "%temp%\elevate.vbs" > NUL + rem del /f /q "%temp%\elevated.vbs" > NUL + + rem we can't read stdout nor any return values from elevated processes through pipe + rem (we could read a file, but checking again is the safest possible method) + call :is_installed found _ "%productname%" + if /i "%found%" neq "0" ( + echo ERR Can't uninstall the kbd layout. >&2 + echo ERR Please do it manually and re-run this script. >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) +) +:endif00 + +if exist "%userprofile%\documents\%kbdname%" ( + rem removes all files recursively (does leave all directories in place) + del /f /s /q "%userprofile%\documents\%kbdname%" > NUL + rem removes all empty directories recursively + rmdir /s /q "%userprofile%\documents\%kbdname%" > NUL +) + +echo INFO >&2 +echo INFO Instructions for the "Keyboard Layout Creator": >&2 +echo INFO 1. click "Project" in menu -^> "Build DLL and Setup Package" >&2 +echo INFO 2. click "No" to disable viewing of "KeyboardVerify.log" >&2 +echo INFO 3. click "No" to disable opening of the Installer package directory >&2 +echo INFO 4. close the window of the "Keyboard Layout Creator" >&2 +echo INFO >&2 + +rem MSKLC will correctly generate all the install and setup files +rem "pipe to more" trick to wait for closing +"%msklc%\MSKLC.exe" "%layoutpath%\%kbdname%.klc" | more + +if exist "%userprofile%\Documents\KeyboardVerify.log" ( + del /f /q "%userprofile%\Documents\KeyboardVerify.log" > NUL +) +rem FIXME +pause +exit /b 1 + +rem recompile just the DLLs (the rest is prepared from MSKLC) +rem x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +for %%p in ( + "%msklc%\bin\i386" + "%msklc%\bin\i386" + "%msklc%\bin\i386\amd64" + "%msklc%\bin\i386\ia64") do ( + if %%p=="%msklc%\bin\i368" ( + echo howk11 + rem the second iteration is the same compiler, but a wow64 binary + if "!outdir!"=="i386" ( + set defwow64=-DBUILD_WOW6432 + set outdir=wow64 + ) else ( + set outdir=i386 + ) + ) + if %%p=="%msklc%\bin\i368\amd64" ( + echo howk 1100 + set outdir=amd64 + ) + if %%p=="%msklc%\bin\i368\ia64" set outdir=ia64 + + echo INFO Compiling layout "!outdir!\%kbdname%.dll" >&2 + + echo howk22 + + rem FIXME call this once for all architectures? + rem %%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "%%p\rc.exe" -r "-i%msklc%\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 "%layoutpath%\%kbdname%.rc" + + rem %%p\cl.exe -nologo -I%msklc%\inc -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 %defwow64% /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs %TEMP%/my_layout.obj "%layoutpath%\%kbdname%.c" + + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text +) + +echo INFO Success! Find the kbd layout in: >&2 +echo INFO %userprofile%\Documents\%kbdname% >&2 +rem FIXME the condition is wrong - bad variables? +if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + +rem vim: set wrap: diff --git a/platform/win/source-20180601-gerdLTGT/make_pkg.sh b/platform/win/source-20180601-gerdLTGT/make_pkg.sh new file mode 100644 index 0000000..7b83fc4 --- /dev/null +++ b/platform/win/source-20180601-gerdLTGT/make_pkg.sh @@ -0,0 +1,280 @@ +#!/bin/sh +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - +# FIXME +# msiexec /x c:\Windows\Installer\ba87.msi /l*v! c:\mylog00.txt +# FIXME the layout not installed for all users +# installation property (global variable) ALLUSERS +# FIXME installed for each system32, syswow64 +# SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs +# FIXME layouts in registry +# HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\00000401 +# FIXME +# http://www.microsoftpro.nl/2011/02/24/windows-2008-r2-language-bar-keeps-changing-keyboard-settings/ +# FIXME +# MSI (s) (18:64) [09:42:37:390]: Creating MSIHANDLE (2) of type 790536 for thread 4708 +# MSI (s) (18:C4) [09:42:37:390]: Invoking remote custom action. DLL: C:\WINDOWS\Installer\MSI2650.tmp, Entrypoint: CA04 +# MSI (s) (18:58) [09:42:37:390]: Generating random cookie. +# MSI (s) (18:58) [09:42:37:390]: Created Custom Action Server with PID 8 (0x8). +# MSI (s) (18:54) [09:42:37:421]: Running as a service. +# MSI (s) (18:54) [09:42:37:421]: Hello, I'm your 32bit Impersonated custom action server. +# CustomAction RemoveKeyboardFromLangBar.7A997F8B33EC4BF79A5E859E1F48AD36 returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) +# MSI (s) (18:C4) [09:42:37:421]: Closing MSIHANDLE (2) of type 790536 for thread 4708 +# Aktion beendet um 09:42:37: InstallFinalize. Rückgabewert 3. +# MSI (s) (18:64) [09:42:37:436]: Note: 1: 2265 2: 3: -2147287035 +# MSI (s) (18:64) [09:42:37:436]: User policy value 'DisableRollback' is 0 +# MSI (s) (18:64) [09:42:37:436]: Machine policy value 'DisableRollback' is 0 +# HKEY_CURRENT_USER\Software\Microsoft\CTF\LangBar + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 +readonly TMPDIR_WIN="$(cmd.exe /c "echo %TEMP%")" + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken automatically into account as it should + readonly t="$(mktemp -p "$TMPDIR_WIN" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR_WIN" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # kbd layout uninstallation doesn't complete successfully if the DLL files + # are present + cat > "$a" < $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | + sed -r 's|^[^=]+=[^0-9]*([0-9]+).*|\1|')))" -ne 0 \ + -o "$c" -le 0 ]; then + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + +# FIXME +# INFO Waiting 10s... Keine Instanzen verf▒gbar. +# 9s... Keine Instanzen verf▒gbar. +# 8s... Keine Instanzen verf▒gbar. + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME avoid collision with the default MSKLC compile directory +readonly dockbd="$USERPROFILE\\documents\\$kbdname" +if [ -e "$dockbd" ]; then + mv "$dockbd" "${dockbd}-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry (for VBS)? +# FIXME open it with a different DLL directory than \Userprofile\Documents +"$msklc/MSKLC.exe" "$layoutpath\\${kbdname}.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN_PREFIX="$(cmd.exe /c "echo %TEMP%")\\my_layout" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 +# # FIXME +# # 32bit on 64bit systems +# if [ "$idx" -eq 0 ]; then +# idx=$((idx +1)) +# defwow64=-DBUILD_WOW6432 +# outdir=wow64 +# else + outdir=i386 +# fi + ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=amd64 + fi + ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=IA64 + subsys_native_ver=5.02 + outdir=ia64 + ;; + esac + + printf '\nINFO Compiling DLL for %s...\n' "$outdir" + + # make traps local + ( + trap "rm -f '${TEMP_WIN_PREFIX}.res' '${TEMP_WIN_PREFIX}.obj'" \ + INT HUP TERM EXIT RETURN + # FIXME -DSTD_CALL + "$msklc\\bin\\i386\\rc.exe" -i "$msklc\\inc" -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "${TEMP_WIN_PREFIX}.res" "${kbdname}.rc" + + # FIXME -Gz (x86 only) + # -DSTD_CALL + # FIXME -EHs-c- + "$p\\cl.exe" -nologo -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -MD -c -Zp8 -Gy -W3 -WX -EHsc -GR- -GF -Z7 -Ox "-I$msklc\\inc" -Fo"${TEMP_WIN_PREFIX}.obj" "${kbdname}.c" + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + "$p\\link.exe" "-LIBPATH:$msklc\\lib\\$libdir" "-MACHINE:$machine" -nologo -noentry -OPT:REF -OPT:ICF -dll "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-DEF:${kbdname}.def" "-OUT:$outdir\\${kbdname}.dll" "${TEMP_WIN_PREFIX}.res" "${TEMP_WIN_PREFIX}.obj" + ) +done + +# vim: set wrap: diff --git a/platform/win/source-20180601-gerdLTGT/wow64/gerdLTGT.dll b/platform/win/source-20180601-gerdLTGT/wow64/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..58c838c9dc9c597e87affbe0f727e18cf5205387 GIT binary patch literal 4608 zcmeHKTX0iV6kR7N+Cqxu;Rhq=ZD~tENO_cp3R-EQrA_IRQd+R2&21V;lX8;+6$E@C zA2@@*emKFZprTepWspaG{4&FrKO!)WA3jEn!|05IV_o~?CQW%LK7MpKXZGFa?7PoC z`>eh9xk*jy0XP9`34MWMPa4{tb(=B1dww03XnG7`88k!lvxiRSidpsAIdL8jU6}f%hsFy~*53q?+!H9YpwMI^11dU|l{@t;AUHwQZZ zFWLOh93PsH(BEw<8uq+9wO&_A%1n-$;F!p~n}$hRw$aveu$)M#mc^RO!e-pd9!4?y zCd^{*!5sFHwvox_#XNLiK02`gK9s=3LUdsf{8)@`EI|PGr4|fLO!(`x%YR>Tf5~&U zL3^&Qs*S{3DV?{~6b!0q7*Gb@P`P+t<>4KbkE6_0&&6l>9GOJ)0#4#I z>aY$gQGqhvNgkZR2gt^Yco?-#47(xu^aRT+ILN!`g(luC%X0+m< z+T?f%1}38yTVNrADEhD!+prz|IN*HFk?$&W<+^%M;BvWUxHe8fdk0aJ`D655IN}#D19=>u#B40ZB;z#Pco4ZnxR-Q@IQNqfU&)MINu3I2 zWd(ODW44xYw+7&c=TRmk;bqd*4!^{Ypta~7ngpJed#eOzzy9DS4;`aBkSl(OwwW1H=xK_5)|-$6TGTJllL z!%;uyebkh;gx`e`-KoXL5ZN?&SJ9t_*ARI%#KQH5dVl7QEWJ_}xLT4c>^28rL$8=V@zlhE{E>f%+0- zuSUm6#X5m#I?jK^_EL?Hhj#t?gpwJ(^hKiQXC4TOHQcL-9tA1uq-IEa0N(dmJY%h` zE14)5C38_`iLAOBD>+kQ-_iJ79i1D+rkv{)t4d;?+-)TDfqd2s=&|IM_!=Zn$A>q6 z#u!G$a zVi{&EM{to{w^3&CjgPoUjR`_GyZ<#l=Ggx~W0|qJvC>#&tT%Qk7LVcJHJY~s|3d_R E2RcIJK>z>% literal 0 HcmV?d00001 diff --git a/platform/win/source-20180601-gerdLTGT/wow64/gerdLTGT.exp b/platform/win/source-20180601-gerdLTGT/wow64/gerdLTGT.exp new file mode 100644 index 0000000000000000000000000000000000000000..a783155846b29b4bd31110ded759f498d412babd GIT binary patch literal 671 zcmYdkV`liw%pd)Ok%57O0Rr?=QxZ!Op&TF;1jIc+d=Dzb2BaN;NG~NdsWe?B7%I$g z1jvvAnu81+7zCX3Qi@WOOUhDV;!;4yJv4O;Ob}U+TVU!yN?;f!hDxWW7Nz)vxQFPa zPtVuB#87eMkr018C)W4@WmMft_~ zX(b98L7ECao_^jSLo5Ut83eGo^9xXu1Q3IKE5IoIrANIOvgAAra;pgxm00`#8nW81m)&5fdEXIHmYin&c|qiF9}T*tJ&S+MQG zwrRfgz`1ns9jvwOLf+0USxd<8I%es#;$|zyWw%;y)Li;X^{8%#Y;?^>f92CdgsvmN zvkHt5vy)zrAbJpiLbDo<oPzpL*WOM zES6$4QyxhQo^b(pr`m2TQ z<2;GMUkB!e#)|@r=KtL^(IDkc>LsP80`;PJ^>X9EW02wX;`m$5IZ!V%(#Z94B^9x9 zy}VN$bduXqg3N;+-Z~N?t4)7Bl9=AXAnJz=cead|n90m;8XK86?zelNvmHpl! mzMaH&j3BhX#JaA^W>ISVzu{(eF8C(X=oq?O!fxbX0`VIKAWTO9 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180703-gerdLTGT.zip b/platform/win/source-20180703-gerdLTGT.zip new file mode 100644 index 0000000000000000000000000000000000000000..fbb5f4fc655a16c25174da807fa7962bffc89b77 GIT binary patch literal 105645 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 z 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%0Axf2kpKW#=>Y(6|Npn^{|l&ZIc>2a z_}?vq0MurC229Miq!(l?jPABR_-pIxA`7 zL|60{$!jn?5Y#r;Ue_X>;_?;Ku9M0loK?#dGM)M^io**hVjidBG!{4I&weMuJb50o z9v2KpLZgxpIg>C_eA!Z?EmE8nC}-~1O%|D)yB#Q+A!x1YFCz8i zk4W68cwWtr#3eN5aucwM(d5RbV@FDe>P3xnouR!fWl~(TF*I4jz#u3Mtye}^Q#FOb z#wj_;aTZI%jjB8}_xnUy?zVPhwQ0n4s&grbx^j>DhXOZaDkA-=jBFxm92 zS?7r$_em4?KoDwX^6bE0P91TqOjY*4?xD_jMZ2N)C8kxy?6t5$Rk;FS|01QgJgzR> zoR_1Ss#BgF!{##tjGWn_v7S}GR;zXGhl0y|SU#dok~&m^UtITQZA>GBNps((87QWWKzvJe z2_m{TIoKy9(UGD!#@1&IZ3$H6B{CpznT@X+++Ci_wr*XhsjICNLxzITwX@?rSyY#9 z$VCOYd_7;?>X+cC3Z`J&m}(hY&W;g05nLi;F>rBkGfnqd;EWb!W`Si-xVSkOkb7D# zfaa$m=B8i2B_^d9#`+zQPO+YO(tkcwzt*aYmsWQdRvz@O&W4iR=6_neSNZ66EGw6- zNV_b8jWAM%DLf2=Tz@_P>ut;do6xWhW+%NzwVu0Spxeg{zBb#vXW5#<(I) zK}^?6+}(Em4J}SJ9j$?f=T^6cliT4-rZlmE%z-{w7wulvPcV)$-422JfW~5a-t0f` zKVoK+;sKUgHMKZ-JUyjo0mF#FLZ}7zKy_q9XhiAL8gsvT<)JhuXPo)K zY7o^9kwD=2Q5wI_!*_k9+iUjvEIj^_62D=Lxk$=HqtsI$7MeTzkg~gqm-GqV;TsLh zXgWFY<3=C`Ot8@J)?vlf9^;;OYmv;+ln z2O=D6Gq19#((w9vJleh+SbBTwR(gm6vHTMjwtoGX(yJ5@M8FJH&?+EgD~=ku@xQc4 zqubT8-&N97Ol3lajIQT9u}RfSw!-rPQ%Qa3-2QvOc$qbg9aEBhdUz=Zpt+$BKB?u` z>e8_PcKEQ}@pr+s*&eP-_<)Z{P5MKltDCeIoWE?|0v9}cex|X&#ml$9oo{Sz@qFQm zFZIVj3_SYHnVgYKd#+ga!hhBJ`r50tZ^Qnotu2ow-|N{fUN|)~_O|cp+1TZHFZ^*i zDt>z(#)alDloNphM=l+KD8bdxn1Xp_zL-oeC7F~5t*kld_WUin<)yK%{9{Ql`{G$=9L5lxt#z#}@8NmOoHKz-x?bT>1mWUHm~=7En<(Z69B{OH#T^x*J8BB}78HyStG_KpI7)krWUCX%vx? zZj`R2L8L@L;9Gg$^;s|;-}5c!J{QX_=Qsar>YBM{=B_#>4qt>N7Yjgq6OK^}!aQl& zBCceqf@7BQXfb@+fK)?*ogjDJFQ?kqHGdbie%>!Xuj@dn85HgV%$?!{$wx%gz211P z%4_3RecsD|IALKAOqrHOZSl}C1dc!IAK!!%nBA6$B-%OUUR130Hl1qv7RlRJ!un|! z<)alTwE~;1rt3dOkA;Z|OL1j>n7jkYKIkU)7|$%+^fUo~bC%B3s;005)4AN-*4pG2Lk+@5bP|IioIWIf zy>l#;T_hxsJ}|j!x!|i8l4zifDLyPL3;zoK0IREJU5zC&5(P_2#oN z9-o)9jBonx7QwvAzTaU#6Zuilz?1lseMtk(y!5x{U23h5;A=aJ?d1S%iV;K3rR(0w z4FqK&E_+hk@8r1Y2wL2jeD}mY+aK;uPDgo6mCsn~Zn$;r;2DtxneBubCtJ!7jjT)A zd6nJL#+#7RJOOX6uTSN}4lyuW$|!sSOU0U(gWpV_jWEfTo6JJhArL=VEA1}3oxB<= zW|)~fyZQAk+kVny7tZdSt%zoJr?mwPLs zxHR8%(nK7vWODt>>+oRdow@yuzYya1yq;_(ScuTj7 z^S0bvON-pYr~Rt98-*n!T?W(-x7`}j=M6vF#)f5blpDWFs<#}y`ziPgS>+ajY%cnT z*m}jI56kl8PtaDg@5d*idyr;?63T7g#(sB?7Dw|F!^rq5A?5k-rg4OGNvJ;zX8T7a zT*^IKv>fzVpfg~_TIEih9-0GvGQOE<{Z0OuX^(q6JyDCH++Ap!3PMI^m?xRLq!R3_ zAsC8Z;ywa!XkH%I6c4YgLOt_(Ko-7Fb=L8dm{nP(gnba4Fnwu%$C zvhK?mZi~F_nSuH&TXu{GKhux30F{+J*|vYI9k<$#LBK6Fs@`0 ze%J)&Y~1Xe@h2Zj^$9C&Zr$V>6owv#!+ zgimJRsC3Bca?nRKp~O@91=czkfEEG@3dD*;QEoZu4j@;>9ix>OAWsffz`<&2vo*1% zNGwO<@R(h$ZNhVoc{jXOOPK zh^GN2O|!D-bnu?NEL#v*?c%sY8_->IO5cz=YR(?SKHxO4=tgS2%Y1*o%W2Bdt6;C? zdSDcaR-vy{mY@bER%(6uVWnym=%Bz2D~rR@huCCj z+{S7eHQdm($sqJdg_C@B`=~RzlpVWqMul&vD^tVaV_xBe?F-g{;gn5t&&~2wm8xv3 zEDLeI=(fSP1N0_~FK59!W7%U$ZF%_2_xy29RBApv9th=h5Y;hc3~Wye+&v9~>8OU$e*AF1#8boS`m1M~$0?dzYVn(3usgPhHjk$98h$Qyk;~urBY|hRQ z4enY=+(&6Dy1Dm`9P7yGIZ1~IG5GASq-?=-@>DrLTx4XkdARP(HiJyUUwq8&cINwRPB}Rd zS*CPz@TrI}N8^IC3C`*SHVAq*no%J6U~aJi>E8w6$+ zObI6#v|`gc8j2XJ#_mVZArHggsR%R6hKC4n!?RdQiGx5_0GfYW)U3QiyG% zpHa11II-dwZ{qf#_xxb3xAZ4wwg3@M-_RX;$JYm!hQ1E;a>hcP}SRD~B( zCupDPG;D$SESfnhk+zc(B|-2V6U7FnilWO@aeOygs-y$0RNk5 zK94AF!dR2{`xNo0rLuL|)4aJYQmK#r!88ibYb~>+|MO}ovsNjO-|V)}Gqts@yB&?p z1=XpgFD9lmCl5ymfS>hOG%C}n6@(L#Z+*m7llKk&h|v`N74e^y9cERnK(^=jq)p&C zrvMlL0KB;4mn%CQ4a{6j3|t)yOpF{|3~U`tY}lO5EFQ%u+Pu4oC)Hm+aIR9%mPg@w zcQq$OB1#U;&I*TSL1rL;mW%nRcp16*yo5@e(ekv*wol8X{TWjc(Va@;KKxm{hfJer zu+e>~R!pPtYyBcm9y`;CJ9Ve8Bt&@%Hx4`JE5;_VU(=TxP2uG{nH%O=39mlXOqWAZ z2r9@jrW!3r+!%Qwkxo%7$a)$UIP!s{PT{#VC{J&?wzq2d_HX5jR#KUhPL{5v+3+Mf*4q{uAAkkizJ~`5w zjGL6mg(V@wUoD94XXxDA8ndvztG_6{YL)0n!^6tnG$LA=>!~fLku5A-Tv%A!BTDx{ zkE`K*x&bH#DDOr{umbW93bv_k5oZl{rZ5AIX&)YFSNN^hyB1WA)L9n|Cw<#&MAz}> ze#0os5jZ6_18mp356;FijTEUu zx7#shn7@e_sr1cKC@X1b5n$t%AU!W#8ClH(eo0DtZ2HW?1x`KCTYQ>uo~e_Su`f)) z+Z;B4UVOIW{HUNHVR=87@b%hlgJYbSSO-}zu7BFCt-sTWOYjn#u*|E)MQk^wMs4C$5{sbx z2_1{s^=_?Zd5!X?yp1^t7GLT&r)nO{Z=qSMbmCKnJj-X20V-6J@FOWQ763_NQr$_p z$uUznFjMtOIsBOT=3Tk<-JcRoq}&sFA|RnCvZY8(rg+URI#!83g^xb;6Fq+H^?uJp zx%`y3@Z1q{^vQna%qP7(U!I73dFtz)y0*#1EntPp$RC=_U&z|A@$Y_6A)WcGN zVr6A(wcFy;aE5;j!?jPZ;PeahR<~c_8Yv08#LC#(SH&U45bnY2G+?dCk`xNa@FR}v zziq+Rq2S&bH|NMipR~-sW=GP(V{9uE*NZ%fCofyBm=yp&8MSZ7h%3--xKcI4kSOII zo@mC-oWMxm$rq`cV=Kd*I#}%l!nGig!;G&k2jSSHN?*6Ce#U5=WXGJBJCRW!ocJDu z4tL!!y@w^iPKGNzzIvyJa)vM6D|b?wBNTa35>@UMS+{QcM2r!piET%DfK#=UXPVpO zv~f*+rGnK94EJjKKy98x6q=|EU^e0SK7F_tXeha8--LJ`G*6d#mQ^$$h%)kFhF37_ z`K-_SiCxgwC88=Fg>%2EC3RvkACHD$w zyhF}dmWb3@3~Jt`_IjX8kM#%*WaJzpqT8251LE-tNu!kMig!-heDut$hLnas&SYub zIqh3r-7L)#s-V6T1f|&$O_pEB3&`wyd1z+3SU%+$II`JfC%%z>qc_>T zB)!9m68U~3`~!MAJXz_SxoA1}Ezt-W&yes3bMQz>v@*4hLbo51kz1+AcfFFu(^SpR z%DNTVN>Q7@MMuU|gq{Tqn0!|1be7p#CQYI3oOoPpz}iJ5 zC(SXJ^x!lt71@=-JbiiSQ66qOZS%pBQl+Tp6Fu)I;_o$v{n-=s6L;lbMj}~0Q{J3M zsqFyOdrB$>_}t5T(ZawU*L`w^eZwX5CBavgTd0D{A;?uHdawtiewal#$4ek?Yf#Vi z*9wAf=~AKvJxK@R1pM`%b|{~D&VbKMj?$ z{;>#7uiZrap|5hzrc3yI4$qziTnp+ZVJmwiw+(arhM>)`Oe^uD(T-w((oy z{PSE0cel# zKVXkgTv%mjU~LTWaM^FDfx~s)+b3xnP+nQ}P!*?H!GtXsJa3MMLa+o8iv#E_BNh;g%*J=u(sJVZt@9Iv~=F%q8SPe^>`U+@-wqlYer~GMw zE1pbKXbaUF&=;xrV1cXlt*|4ka8VOudIG-e35-2<)SDCq-orMeTulLapLBzI6dU!0 z{24;{T57j5qO?25&bS{0VN33azvbGR@SVw~r{d502As*b{YpFM@Y>OeaV4|Mz7x@a zFaP4~BgVRR))k$D%`$uk^7821dq$mamdDxU+1EJ=kXHL=v9?$(+Rh&P&rb{$1sTt} zAsxHyRZ?rVHOZB+JxNKEjD)Gk=}+>dj;;$A;~zCw|B&k=QS{y&qkDCLI=BtR8HGJU z&?0&%ecwdrG%Q#QT%Y}4u+33cD`<9uUOCgA)rYq80Nk@~_b;ZE1&UMMeZkVVM=Bao zA9nNDjZjtQc=R3>J@P&eY*A3M@s7mUp=_f!$QiyBe@1zcrFiRb^`0O_biy45;hUSX ze0E(C?Yrj_UCqGO8`(=vosq(=U(bou0}exWiu$YAs~oD{hUD85D0b(XTS}WxKkRL_ zeNvQi{bMACt>uRMV70AvxV!0xt&d8ZVd)boQfd)Fj1SibjYlGfEQz9X4lGF(bD}MY zd#PI=2|Q@2C9hfFA#Z=?DN5dv=t+~&UP<&~0hX}7UdNR+xjvhu&W+z4_i$Wsy2sC@ zf#3@pJlabCocJm4G0f%AsC9PJ)dL(;=EDAEXk_N;xNBr;UR$BhbBsj;2Zsbl#Ic^2 zPy3jb>+LOU>_fngC}SqZ1F`^Fb~@f79z8mu{7>-M3Y=V&fP3iyiTd()texewn1Mjl z2Nc;wCWf$yhBa?Ph~|k1WtCawcTk+L1{FFxjXo>M@5q$^S)JurmDsvi7(3aG=K_g) z`Y7ROQ<_;2C_7=zivV&O913ufLFJeu_cslBDFTV`uoKW922q}L?RED8jpwTKHShpc zkth|x7)UU(l(6~!J^b8tj74-%vp%>ayBb;O^((P6_ ztloh$dFeKq_LKXFfn`SAAL@h>q}=9o-(yI>=`}WTKd95)Y9zQNo5zG~fbVIZ zkax4uN<%(34%dY;ubTE1d4qMf@TbCE*}H1k)L1g6IxGD#LpCz*09?!`djb70mck>{ zn{$T4%KjT{=esAbgDL!jc&UdBu}?#5OzA6k=^aI83}PLy1PlrBbS2lTDZHBzfgrax zhPYauY%~=kL)y*o#bj%~!$(HTBBO2j`E0$eC+*lVYae~iiZB8QeRw={6hr3^1lEG_ zTn7g>U$S_pnUzf0oH?Ghvg6&LvkjhXT+2;KmnH{b5^Jph#$&ih*G|IBmBEj4lN5gZ z@($OeR=|s?@KH*KIQ4`uL=8o2Jx=Vm#C+cVeW+5j@Up7Hi;nS6^&bMGCjY7@LutM)e5fn|0^{wtrW=7Mu+ze695?G`M#9|ni_@iE9!-BWjHw4Y-~-Sc@;gO z@bl}#Fpx3>vCzI{%o_r#vgaJ|fQu^T$TeE9}=ef~I@6%GJM0N2FJ3D^?*UlSk;?Sbe#eb_tT1n7^! zUU&dvp*;WqFKUAJJLx44SV;US0hi_8d(9bA4fZ#L0i_8)0i>Wl_`k=^~1VHgMpVxf5|Z(4x+>K(QKa9h+1|9wFkbRAu>`Xf*E zQd#A*TLXoFad@dn7xEw$8uvZ(24DK%Jp$wAz>OWpB^Jb3`CD~ApjUdAm8Ve`(5s5C zLZRcx%g__Ae}`V_T>c&UZ~4gR`%9?Nl{f(si9jqw<~|;Nl7Z_aT?n>HQw` z!=>P9VCYiXg-Yi8JxqYWAoeP>k7C8n{l8(tW$4Gy->Uloy^@c3(nJ?fh*F5X3YCZX z^yPb$K!9{rX>9nvL$BoH-$1ov8-eOB#Y(l{o{JcKRx$IXYVt1PS5V0AQ%I*x$;ip^ z{pez7FJDhxYfJkw3}bYPa#33#7FsY~ZX?k3fLnA8%$E3>o%)w-&Z}&WP=G|mzpw)| zUIR;YXa*v|&5kzHRo#1~f63;$%I>B#R%AXLhVe8+zt9b_(7M?g7v!P$_+IvT+nc{* zgVEsKztBFH!I~KJ-W!4;e200#hFEBJwr)I-k#aab0UR#nQhz_28oI+_@B3@^hI9pS3RzZT%u_NMmy5tT&RXvXw`7~3BUt1 z6C);YD7^aYtxx4_(X}iT)0K@oanO5}qck zZ1)U241pja78?EY1L>gAu1tT2zIZ$xG`hSmSd@Eb7$#hS=t4EbLZg2^_#GM@F7$Wk zi(}xS(SG#@>p=&9M*n>97&JNv_&4Y)O*p(HvWwa1Fbt@a_(CznLM#6HxB_Tw%e_Bg zuQp$`CG?es-GAo&ynzFnM`ig(-sL9CU&;32_rVTiaspzZ<^6om9vYYK{cGH>@8Cn{ zC?NM)o+LO1fiNNVANJ1?*5#>~T%TXD|8v_Mnk4ds?IQCa_IH8D<(uo!DkuIx`VsD2 ziLq=Vv@XI{2o+-g(f6MK{qnpuH1#0l_xgTNuLM~+t!jTog$|Z4Pg1-H`wQxoDC_rB X1n^W30B{5R(|`*AOg#X{b%6f^ci=5Y literal 0 HcmV?d00001 diff --git a/platform/win/source-20180703-gerdLTGT/amd64/gerdLTGT.dll b/platform/win/source-20180703-gerdLTGT/amd64/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..eee9b7f5a7259b5ce01ffc91dce3c3661e95ce68 GIT binary patch literal 6656 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 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180703-gerdLTGT/amd64/gerdLTGT.exp b/platform/win/source-20180703-gerdLTGT/amd64/gerdLTGT.exp new file mode 100644 index 0000000000000000000000000000000000000000..084e454c2d95eb6dc55d5f8ec0116c116c4b8e3f GIT binary patch literal 671 zcmYdkV`jLzUNrg#BLf2m0|e-$rX-dmLODPx2#9-t_#RY<4M;lxkzPt_QfazMFjSb~ z2#_HKGzS?tFbFv5r4*$mmz1T##HE0YduZwym>{wsx4_hal)x}d43$n#ElTkTaSzc; z$;n~xPD=4ftV}I(Ni9w;$}A|!FJj;UDhCmIjby2eWj5 zB*=fvU^O3stOOvIWMC8oQVfZ?DP|@ya9dL=3K%pP!~{WFFM#BM02GMo$9yxBi}H)} z(@GRHf;1I;JpH^uhFAzPG6-OE=NF(R2_OdfR)A6ZPciHF7&+tgS8qR5uJ4@5!0;I; zZUDp#&Q>v@#i>QbF?7QFyrz8kY^4)vyo_*i42e z<$8IhI_M_1ZwW@nd#LBQW$yRcH60KnIy!Fu=`%xyiu;uNEIdq@vd?sBXTK|{h?V`G nA->(j_8md!e2Mj3m93&w`G3RB>YngTrqVHVxkTN_;RNCz8u(7Z literal 0 HcmV?d00001 diff --git a/platform/win/source-20180703-gerdLTGT/gerdLG00.klc b/platform/win/source-20180703-gerdLTGT/gerdLG00.klc new file mode 100644 index 0000000..1ea6ff1 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/gerdLG00.klc @@ -0,0 +1,327 @@ +// 2010-2017 Jan Pacner +// etaoin shrdlu! + +// The concept of this keyboard layout +// motto: be as much compatible with ISO dvorak as possible +// 4. level is the same as 3. level +// 2. level of ISO dvorak goes without modifications to the 3. level +// the whole national alphabet is accessible directly from 1. and 2. level +// without any exception +// 3. level has some additional non-alphabet characters (e.g. numbers) +// 3. level is accessible only by pressing both Shifts at once (and +// holding either of them) +// there are 2 variants which differ in placement and/or availability of +// characters ' " < > „ “ en_dash +// in `ltgt`, characters „ “ are not available and ' " < > are at their +// original dvorak places and ! is duplicated for better reachability +// in `writer`, all characters are available, but " < > are in +// the 3. level, thus less reachable + +// ----------- standard ISO dvorak, 1. and 2. level +// ~ ! @ # $ % ^ & * ( ) { } +// ` 1 2 3 4 5 6 7 8 9 0 [ ] +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// space +// space + +// ----------- german dvorak ltgt, 1. and 2. levelll +// ä Ö Ü ß +// ä ö ü ß +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak ltgt, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// nda ! § , 7 8 9 [ ] + | +// en dash +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak writer, 1. and 2. level +// ä Ö Ü ß +// ä ö ü ß +// +// “ nda ' P Y F G C R L ? + | +// en dash +// „ , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak writer, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// " < > § , 7 8 9 [ ] + | +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak (ltgt|writer), 4. level +// the same as 3. level + +// KBD identifier_max_8_bytes_long "Some description to show in keyboard settings and while switching layouts" + KBD gerdLTGT "German Dvorak ltgt (useful for text with lots of <>)" +//KBD gerdLTGT "German Dvorak writer (useful for text with lower/upper UTF-8 double quotes)" + +COPYRIGHT "MIT license" + +COMPANY "github.com/dumblob/ULKL/" + +LOCALENAME "de-DE" + + LOCALEID "00000407" +// LOCALEID "00000000" + +//FIXME 1.1 after unused keys produce the character +VERSION 1.0 + +//ATTRIBUTES + +//MODIFIERS + +SHIFTSTATE + +// shift_state_idx // column_below modifiers +0 // 4 +1 // 5 LSHIFT or RSHIFT pressed +2 // 6 both LSHIFT and RSHIFT pressed simultaneously + +LAYOUT +// an extra @ at the end is a dead key +// -1 denotes the character +// SC denotes a Virtual Scan Code +// Cap ~ CapsInfo (probably whether CapsLock is applicable) + +// topmost row + +//SC VK_ Cap 0 1 2 +29 OEM_3 0 -1 -1 007e // , , TILDE +02 1 0 -1 -1 0021 // , , EXCLAMATION MARK +03 2 0 00e4 00c4 0040 // adiaeresis, Adiaeresis, COMMERCIAL AT +04 3 0 00f6 00d6 0023 // odiaeresis, Odiaeresis, NUMBER SIGN +05 4 0 -1 -1 0024 // , , DOLLAR SIGN +06 5 0 00fc 00dc 0025 // udiaeresis, Udiaeresis, PERCENT SIGN +07 6 0 -1 -1 005e // , , CIRCUMFLEX ACCENT +08 7 0 -1 -1 0026 // , , AMPERSAND +09 8 0 -1 -1 002a // , , ASTERISK +0a 9 0 -1 -1 0028 // , , LEFT PARENTHESIS +0b 0 0 -1 -1 0029 // , , RIGHT PARENTHESIS +0c OEM_4 0 00df 1e9e 007b // ssharp, U1E9E, LEFT CURLY BRACKET (BRACELEFT) +0d OEM_6 0 -1 -1 007d // , , RIGHT CURLY BRACKET (BRACERIGHT) +// FIXME wtf is this key? is it really ? +56 OEM_102 0 -1 -1 -1 // , , +//0e ???? 0 ???? ???? ???? // backspace, backspace, backspace + +// top row + +//0f ???? 0 ???? ???? ???? // tab, tab, tab +// ltgt variant +10 OEM_7 0 0027 0022 -1 // APOSTROPHE, QUOTATION MARK (QUOTEDBL), +11 OEM_COMMA 0 002c 003c 2013 // COMMA, LESS-THAN SIGN, U2013 (EN DASH, pomlcka) +12 OEM_PERIOD 0 002e 003e 0021 // FULL STOP (PERIOD), GREATER-THAN SIGN, EXCLAMATION MARK +// writer variant +//10 OEM_7 0 201e 201c 0022 // U201E LOWER QUOTATION MARK (QUOTEDBL), U201C UPPER QUOTATION MARK (QUOTEDBL), QUOTATION MARK (QUOTEDBL) +//11 OEM_COMMA 0 002c 2013 003c // COMMA, U2013 (EN DASH, pomlcka), LESS-THAN SIGN +//12 OEM_PERIOD 0 002e 0027 003e // FULL STOP (PERIOD), APOSTROPHE, GREATER-THAN SIGN + +13 P 0 p P 00a7 // LATIN SMALL LETTER P, LATIN CAPITAL LETTER P, SECTION SIGN (PARAGRAPH) +14 Y 0 y Y -1 // LATIN SMALL LETTER Y, LATIN CAPITAL LETTER Y, +15 F 0 f F 002c // LATIN SMALL LETTER F, LATIN CAPITAL LETTER F, COMMA +16 G 0 g G 7 // LATIN SMALL LETTER G, LATIN CAPITAL LETTER G, DIGIT SEVEN +17 C 0 c C 8 // LATIN SMALL LETTER C, LATIN CAPITAL LETTER C, DIGIT EIGHT +18 R 0 r R 9 // LATIN SMALL LETTER R, LATIN CAPITAL LETTER R, DIGIT NINE +19 L 0 l L 005b // LATIN SMALL LETTER L, LATIN CAPITAL LETTER L, LEFT SQUARE BRACKET +1a OEM_2 0 002f 003f 005d // SOLIDUS (SLASH), QUESTION MARK, RIGHT SQUARE BRACKET +1b OEM_PLUS 0 003d 002b 002b // EQUALS SIGN, PLUS SIGN, PLUS SIGN +2b OEM_5 0 005c 007c 007c // REVERSE SOLIDUS (BACKSLASH), VERTICAL LINE (BAR), VERTICAL LINE (BAR) + +// home/middle row + +//CapsLk +//3a ???? 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +//3a SGCap 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +1e A 0 a A 0040 // LATIN SMALL LETTER A, LATIN CAPITAL LETTER A, COMMERCIAL AT +1f O 0 o O 00b0 // LATIN SMALL LETTER O, LATIN CAPITAL LETTER O, DEGREE +20 E 0 e E 20ac // LATIN SMALL LETTER E, LATIN CAPITAL LETTER E, EURO SIGN +21 U 0 u U 0060 // LATIN SMALL LETTER U, LATIN CAPITAL LETTER U, GRAVE ACCENT (GRAVE) +22 I 0 i I -1 // LATIN SMALL LETTER I, LATIN CAPITAL LETTER I, +23 D 0 d D 003a // LATIN SMALL LETTER D, LATIN CAPITAL LETTER D, COLON +24 H 0 h H 4 // LATIN SMALL LETTER H, LATIN CAPITAL LETTER H, DIGIT FOUR +25 T 0 t T 5 // LATIN SMALL LETTER T, LATIN CAPITAL LETTER T, DIGIT FIVE +26 N 0 n N 6 // LATIN SMALL LETTER N, LATIN CAPITAL LETTER N, DIGIT SIX +27 S 0 s S 003d // LATIN SMALL LETTER S, LATIN CAPITAL LETTER S, EQUALS SIGN +// pomlcka (= minus = dash) +28 OEM_MINUS 0 002d 005f 005c // HYPHEN-MINUS (FIXME is it the plain minus?), LOW LINE (UNDERSCORE), REVERSE SOLIDUS (BACKSLASH) +//1c ???? 0 ???? ???? ???? // enter/return, enter/return, enter/return + +// bottom row + +//2a ???? 0 ???? ???? ???? // left shift, left shift, left shift +// left bottom key, right from , which doesn't follow the kbd standard +// FIXME wtf is this key? is it really ? +56 OEM_102 0 -1 -1 -1 // , , +2c OEM_1 0 003b 003a -1 // SEMICOLON, COLON, +2d Q 0 q Q -1 // LATIN SMALL LETTER Q, LATIN CAPITAL LETTER Q, +2e J 0 j J -1 // LATIN SMALL LETTER J, LATIN CAPITAL LETTER J, +2f K 0 k K -1 // LATIN SMALL LETTER K, LATIN CAPITAL LETTER K, +30 X 0 x X -1 // LATIN SMALL LETTER X, LATIN CAPITAL LETTER X, +31 B 0 b B 0 // LATIN SMALL LETTER B, LATIN CAPITAL LETTER B, DIGIT ZERO +32 M 0 m M 1 // LATIN SMALL LETTER M, LATIN CAPITAL LETTER M, DIGIT ONE +33 W 0 w W 2 // LATIN SMALL LETTER W, LATIN CAPITAL LETTER W, DIGIT TWO +34 V 0 v V 3 // LATIN SMALL LETTER V, LATIN CAPITAL LETTER V, DIGIT THREE +35 Z 0 z Z 002e // LATIN SMALL LETTER Z, LATIN CAPITAL LETTER Z, FULL STOP (PERIOD) +// numpad dot +53 DECIMAL 0 002e 002e 002e // FULL STOP (PERIOD), FULL STOP (PERIOD), FULL STOP (PERIOD) +//36 ???? 0 ???? ???? ???? // right shift, right shift, right shift + +// bottom-most row + +//?? ???? 0 ???? ???? ???? // left ctrl, left ctrl, left ctrl +//5b ???? 0 ???? ???? ???? // left super (win), left super (win), left super (win) +//?? ???? 0 ???? ???? ???? // left alt (meta), left alt (meta), left alt (meta) +39 SPACE 0 0020 00a0 00a0 // SPACE, NO-BREAK SPACE, NO-BREAK SPACE +//38 ???? 0 ???? ???? ???? // right alt (meta), right alt (meta), right alt (meta) +//5c ???? 0 ???? ???? ???? // right super (win), right super (win), right super (win) +//?? ???? 0 ???? ???? ???? // menu, menu, menu +//5d ???? 0 ???? ???? ???? // menu, menu, menu +//56 ???? 0 ???? ???? ???? // menu, menu, menu +//1d ???? 0 ???? ???? ???? // right ctrl, right ctrl, right ctrl +//46 ???? 0 ???? ???? ???? // scroll lock, scroll lock, scroll lock + +//LIGATURE +// +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// a mod b c + +//KEYNAME +// +//01 Esc +//0e Backspace +//0f Tab +//1c Enter +//1d Ctrl +////2a Shift +//2a "Left Shift" +//36 "Right Shift" +//37 "Num *" +//38 Alt +//39 Space +//3a "Caps Lock" +//3b F1 +//3c F2 +//3d F3 +//3e F4 +//3f F5 +//40 F6 +//41 F7 +//42 F8 +//43 F9 +//44 F10 +//45 Pause +//46 "Scroll Lock" +//47 "Num 7" +//48 "Num 8" +//49 "Num 9" +//4a "Num -" +//4b "Num 4" +//4c "Num 5" +//4d "Num 6" +//4e "Num +" +//4f "Num 1" +//50 "Num 2" +//51 "Num 3" +//52 "Num 0" +//53 "Num Del" +//54 "Sys Req" +//57 F11 +//58 F12 +//7c F13 +//7d F14 +//7e F15 +//7f F16 +//80 F17 +//81 F18 +//82 F19 +//83 F20 +//84 F21 +//85 F22 +//86 F23 +//87 F24 +// +//KEYNAME_EXT +// +//1c "Num Enter" +//1d "Right Ctrl" +//35 "Num /" +//37 "Prnt Scrn" +//38 "Right Alt" +//45 "Num Lock" +//46 Break +//47 Home +//48 Up +//49 "Page Up" +//4b Left +//4d Right +//4f End +//50 Down +//51 "Page Down" +//52 Insert +//53 Delete +//54 <00> +//54 "Sys Req" +//56 Help +//5b "Left Windows" +//5c "Right Windows" +//5d Application + +DESCRIPTIONS + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German Dvorak ltgt (useful for text with lots of <>) +//0409 German Dvorak writer (useful for text with lower/upper UTF-8 double quotes) + +LANGUAGENAMES + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German or related (all locations world-wide) + +ENDKBD + +// vim: set ft=javascript: diff --git a/platform/win/source-20180703-gerdLTGT/gerdLTGT - Kopie.C b/platform/win/source-20180703-gerdLTGT/gerdLTGT - Kopie.C new file mode 100644 index 0000000..9176359 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/gerdLTGT - Kopie.C @@ -0,0 +1,524 @@ +/***************************************************************************\ + ä Ö Ü ß +* Module Name: gerdLTGT.C +* +* keyboard layout +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* History: +* KBDTOOL v3.40 - Created Mon May 29 08:05:02 2017 +\***************************************************************************/ + +#include +#include "kbd.h" +#include "winuser.h" +#include "gerdLTGT.h" + +#if defined(_M_IA64) +//FIXME +//#pragma section(".data",read,write) +#pragma section(".data") +#define ALLOC_SECTION_LDATA __declspec(allocate(".data")) +#else +//FIXME might need system-init of the DLL, not a process-specific init (it's a huge security risk) +//#pragma bss_seg(".data") +#pragma data_seg(".data") +#define ALLOC_SECTION_LDATA +#endif + +/***************************************************************************\ +* ausVK[] - Virtual Scan Code to Virtual Key conversion table +\***************************************************************************/ + +static ALLOC_SECTION_LDATA USHORT ausVK[] = { + T00, T01, T02, T03, T04, T05, T06, T07, + T08, T09, T0A, T0B, T0C, T0D, T0E, T0F, + T10, T11, T12, T13, T14, T15, T16, T17, + // 24 + + T18, T19, T1A, T1B, T1C, + // 5 + + + /* + * Left Ctrl FIXME + */ + T1D, + + T1E, T1F, + T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, + // 12 + + + /* + * Left-hand Shift FIXME + */ + T2A, + + T2B, T2C, T2D, T2E, T2F, + T30, T31, T32, T33, T34, T35, + // 11 + + + /* + * Right-hand Shift key must have KBDEXT bit set. + */ + T36 | KBDEXT, + + T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot + + T38, T39, T3A, T3B, T3C, T3D, T3E, + T3F, T40, T41, T42, T43, T44, + // 13 + + + /* + * NumLock Key: + * KBDEXT - VK_NUMLOCK is an Extended key + * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL) + */ + T45 | KBDEXT | KBDMULTIVK, + + T46 | KBDMULTIVK, + + /* + * Number Pad keys: + * KBDNUMPAD - digits 0-9 and decimal point. + * KBDSPECIAL - require special processing by Windows + */ + T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home) + T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up), + T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp), + T4A, + T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left), + T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear), + T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right), + T4E, + T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End), + T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down), + T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn), + T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins), + T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del), + + T54, T55, T56, T57, T58, T59, T5A, T5B, + T5C, T5D, T5E, T5F, T60, T61, T62, T63, + T64, T65, T66, T67, T68, T69, T6A, T6B, + T6C, T6D, T6E, T6F, T70, T71, T72, T73, + T74, T75, T76, T77, T78, T79, T7A, T7B, + // 40 + + T7C, T7D, T7E + // 3 = 127 + +}; + +static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = { + { 0x10, X10 | KBDEXT }, // Speedracer: Previous Track + { 0x19, X19 | KBDEXT }, // Speedracer: Next Track + { 0x1D, X1D | KBDEXT }, // RControl; Right Ctrl FIXME + { 0x20, X20 | KBDEXT }, // Speedracer: Volume Mute + { 0x21, X21 | KBDEXT }, // Speedracer: Launch App 2 + { 0x22, X22 | KBDEXT }, // Speedracer: Media Play/Pause + { 0x24, X24 | KBDEXT }, // Speedracer: Media Stop + { 0x2E, X2E | KBDEXT }, // Speedracer: Volume Down + { 0x30, X30 | KBDEXT }, // Speedracer: Volume Up + { 0x32, X32 | KBDEXT }, // Speedracer: Browser Home + { 0x35, X35 | KBDEXT }, // Numpad Divide + { 0x37, X37 | KBDEXT }, // Snapshot + { 0x38, X38 | KBDEXT }, // RMenu + { 0x47, X47 | KBDEXT }, // Home + { 0x48, X48 | KBDEXT }, // Up + { 0x49, X49 | KBDEXT }, // Prior + { 0x4B, X4B | KBDEXT }, // Left + { 0x4D, X4D | KBDEXT }, // Right + { 0x4F, X4F | KBDEXT }, // End + { 0x50, X50 | KBDEXT }, // Down + { 0x51, X51 | KBDEXT }, // Next + { 0x52, X52 | KBDEXT }, // Insert + { 0x53, X53 | KBDEXT }, // Delete + { 0x5B, X5B | KBDEXT }, // Left Win + { 0x5C, X5C | KBDEXT }, // Right Win + { 0x5D, X5D | KBDEXT }, // Application + { 0x5F, X5F | KBDEXT }, // Speedracer: Sleep + { 0x65, X65 | KBDEXT }, // Speedracer: Browser Search + { 0x66, X66 | KBDEXT }, // Speedracer: Browser Favorites + { 0x67, X67 | KBDEXT }, // Speedracer: Browser Refresh + { 0x68, X68 | KBDEXT }, // Speedracer: Browser Stop + { 0x69, X69 | KBDEXT }, // Speedracer: Browser Forward + { 0x6A, X6A | KBDEXT }, // Speedracer: Browser Back + { 0x6B, X6B | KBDEXT }, // Speedracer: Launch App 1 + { 0x6C, X6C | KBDEXT }, // Speedracer: Launch Mail + { 0x6D, X6D | KBDEXT }, // Speedracer: Launch Media Selector + { 0x1C, X1C | KBDEXT }, // Numpad Enter + { 0x46, X46 | KBDEXT }, // Break (Ctrl + Pause) + { 0, 0 } +}; + +static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = { + { 0x1D, Y1D }, // Pause + { 0 , 0 } +}; + +/***************************************************************************\ +* aVkToBits[] - map Virtual Keys to Modifier Bits +* +* See kbd.h for a full description. +* +*FIXME wrong original description: +* The keyboard has only three shifter keys: +* SHIFT (L & R) affects alphabnumeric keys, +* CTRL (L & R) is used to generate control characters +* ALT (L & R) used for generating characters by number with numpad +\***************************************************************************/ +static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = { +// { VK_SHIFT , KBDSHIFT }, +// { VK_CONTROL , KBDCTRL }, +// { VK_MENU , KBDALT }, +// { 0 , 0 } + + // FIXME dumblob + // a hack to allow distinguishing left and right shift by propagating it to aModification[] + // make "KBDSHIFT | KBDCTRL" a unique bit combination for left shift + { VK_LSHIFT, KBDSHIFT | KBDCTRL }, + // make "KBDSHIFT | KBDCTRL" a unique bit combination for right shift + { VK_RSHIFT, KBDSHIFT | KBDALT }, + //{ VK_LCONTROL, KBDCTRL }, + //{ VK_RCONTROL, KBDCTRL }, + { 0, 0 } +}; + +/***************************************************************************\ +* aModification[] - map character modifier bits to modification number +* +* See kbd.h for a full description. +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = { + // Demonstration of the relationship (note: this demo is + // a complete nonsense in terms of an internal implementation): + // for( x in aVkToBits ){ + // if( x[0] == 0 && x[1] == 0 ) break + // if( x[1] <= wMaxModBits ){ + // // x[0] is not interesting + // if( aModification[x[1]] != SHFT_INVALID ){ + // shift_to_the_level( x[1] ) + // break + // } + // } + // } + + // PVK_TO_BIT pVkToBit; // Virtual Keys -> Mod bits + &aVkToBits[0], + // WORD wMaxModBits; // max Modification bit combination value + KBDSHIFT | KBDCTRL | KBDALT, + + // BYTE ModNumber[]; // Mod bits -> Modification Number + // mod_bits are an index to this array => order matters ( + // arithmetic progression with step 1 without any omission; + // use SHFT_INVALID as an ignored shift state) + { + // from kbd.h: + // #define KBDSHIFT (1 << 0) + // #define KBDCTRL (1 << 1) + // #define KBDALT (1 << 2) + // #define KBDKANA (1 << 3) + // #define KBDROYA (1 << 4) + // #define KBDLOYA (1 << 5) + // (1 << 6) doesn't exist (not defined anywhere) + // #define KBDGRPSELTAP (1 << 7) + + // FIXME test Ctrl and Alt key bindings (e.g. Ctrl+c, Alt+64, ...) + // shift_state_idx // KBDALT KBDCTRL KBDSHIFT + 0, // 0 0 0 + SHFT_INVALID, // 0 0 1 + SHFT_INVALID, // 0 1 0 + 1, // 0 1 1 (only LSHIFT pressed) + SHFT_INVALID, // 1 0 0 + 1, // 1 0 1 (only RSHIFT pressed) + SHFT_INVALID, // 1 1 0 + 2, // 1 1 1 (both LSHIFT and RSHIFT + // pressed simultaneously) + } +}; + +/***************************************************************************\ +* +* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states +* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states +* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states +* +* Table attributes: Unordered Scan, null-terminated +* +* Search this table for an entry with a matching Virtual Key to find the +* corresponding unshifted and shifted WCHAR characters. +* +* Special values for VirtualKey (column 1) +* 0xff - dead chars for the previous entry +* 0 - terminate the list +* +* Special values for Attributes (column 2) +* CAPLOK bit - CAPS-LOCK affect this key like SHIFT +* +* Special values for wch[*] (column 3 & 4) +* WCH_NONE - No character +* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none) +* WCH_LGTR - Ligature (generates multiple characters) +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VK_TO_WCHARS2 aVkToWch2[] = { +// | | Shift | +// |=========|=========| + {VK_TAB ,0 ,'\t' ,'\t' }, + {VK_ADD ,0 ,'+' ,'+' }, + {VK_DIVIDE ,0 ,'/' ,'/' }, + {VK_MULTIPLY ,0 ,'*' ,'*' }, + {VK_SUBTRACT ,0 ,'-' ,'-' }, + {0 ,0 ,0 ,0 } +}; + +// FIXME all unwanted VK_* keys should be redefined as WCH_NONE +static ALLOC_SECTION_LDATA VK_TO_WCHARS3 aVkToWch3[] = { +// | | Shift | Ctrl | +// |=========|=========|=========| + {VK_OEM_3 ,0 ,WCH_NONE ,WCH_NONE ,'~' }, + {'1' ,0 ,WCH_NONE ,WCH_NONE ,'!' }, + {'2' ,0 ,0x00e4 ,0x00c4 ,'@' }, + {'3' ,0 ,0x00f6 ,0x00d6 ,'#' }, + {'4' ,0 ,WCH_NONE ,WCH_NONE ,'$' }, + {'5' ,0 ,0x00fc ,0x00dc ,'%' }, + {'6' ,0 ,WCH_NONE ,WCH_NONE ,'^' }, + {'7' ,0 ,WCH_NONE ,WCH_NONE ,'&' }, + {'8' ,0 ,WCH_NONE ,WCH_NONE ,'*' }, + {'9' ,0 ,WCH_NONE ,WCH_NONE ,'(' }, + {'0' ,0 ,WCH_NONE ,WCH_NONE ,')' }, + {VK_OEM_4 ,0 ,0x00df ,0x1e9e ,'{' }, + {VK_OEM_6 ,0 ,WCH_NONE ,WCH_NONE ,'}' }, + {VK_OEM_102 ,0 ,WCH_NONE ,WCH_NONE ,WCH_NONE }, + {VK_OEM_7 ,0 ,'\'' ,'\"' ,WCH_NONE }, + {VK_OEM_COMMA ,0 ,',' ,'<' ,WCH_NONE }, + {VK_OEM_PERIOD,0 ,'.' ,'>' ,WCH_NONE }, + {'P' ,0 ,'p' ,'P' ,WCH_NONE }, + {'Y' ,0 ,'y' ,'Y' ,WCH_NONE }, + {'F' ,0 ,'f' ,'F' ,WCH_NONE }, + {'G' ,0 ,'g' ,'G' ,WCH_NONE }, + {'C' ,0 ,'c' ,'C' ,WCH_NONE }, + {'R' ,0 ,'r' ,'R' ,WCH_NONE }, + {'L' ,0 ,'l' ,'L' ,WCH_NONE }, + {VK_OEM_2 ,0 ,'/' ,'?' ,']' }, + {VK_OEM_PLUS ,0 ,'=' ,'+' ,'+' }, + {VK_OEM_5 ,0 ,'\\' ,'|' ,'|' }, + {'A' ,0 ,'a' ,'A' ,WCH_NONE }, + {'O' ,0 ,'o' ,'O' ,WCH_NONE }, + {'E' ,0 ,'e' ,'E' ,WCH_NONE }, + {'U' ,0 ,'u' ,'U' ,WCH_NONE }, + {'I' ,0 ,'i' ,'I' ,WCH_NONE }, + {'D' ,0 ,'d' ,'D' ,WCH_NONE }, + {'H' ,0 ,'h' ,'H' ,WCH_NONE }, + {'T' ,0 ,'t' ,'T' ,WCH_NONE }, + {'N' ,0 ,'n' ,'N' ,WCH_NONE }, + {'S' ,0 ,'s' ,'S' ,WCH_NONE }, + {VK_OEM_MINUS ,0 ,'-' ,'_' ,'\\' }, + {VK_OEM_1 ,0 ,';' ,':' ,WCH_NONE }, + {'Q' ,0 ,'q' ,'Q' ,WCH_NONE }, + {'J' ,0 ,'j' ,'J' ,WCH_NONE }, + {'K' ,0 ,'k' ,'K' ,WCH_NONE }, + {'X' ,0 ,'x' ,'X' ,WCH_NONE }, + {'B' ,0 ,'b' ,'B' ,WCH_NONE }, + {'M' ,0 ,'m' ,'M' ,WCH_NONE }, + {'W' ,0 ,'w' ,'W' ,WCH_NONE }, + {'V' ,0 ,'v' ,'V' ,WCH_NONE }, + {'Z' ,0 ,'z' ,'Z' ,WCH_NONE }, + {VK_DECIMAL ,0 ,'.' ,'.' ,'.' }, + {VK_SPACE ,0 ,' ' ,0x00a0 ,0x00a0 }, + {VK_BACK ,0 ,'\b' ,'\b' ,0x007f }, + {VK_ESCAPE ,0 ,0x001b ,0x001b ,0x001b }, + {VK_RETURN ,0 ,'\r' ,'\r' ,'\n' }, + {VK_CANCEL ,0 ,0x0003 ,0x0003 ,0x0003 }, + {0 ,0 ,0 ,0 ,0 } +}; + +// Put this last so that VkKeyScan interprets number characters +// as coming from the main section of the kbd (aVkToWch2 and +// aVkToWch5) before considering the numpad (aVkToWch1). + +static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = { + { VK_NUMPAD0 , 0 , '0' }, + { VK_NUMPAD1 , 0 , '1' }, + { VK_NUMPAD2 , 0 , '2' }, + { VK_NUMPAD3 , 0 , '3' }, + { VK_NUMPAD4 , 0 , '4' }, + { VK_NUMPAD5 , 0 , '5' }, + { VK_NUMPAD6 , 0 , '6' }, + { VK_NUMPAD7 , 0 , '7' }, + { VK_NUMPAD8 , 0 , '8' }, + { VK_NUMPAD9 , 0 , '9' }, + { 0 , 0 , '\0' } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = { + { (PVK_TO_WCHARS1)aVkToWch3, 3, sizeof(aVkToWch3[0]) }, + { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) }, + { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) }, + { NULL, 0, 0 }, +}; + +/***************************************************************************\ +* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables +* +* Table attributes: Ordered Scan (by scancode), null-terminated +* +* Only the names of Extended, NumPad, Dead and Non-Printable keys are here. +* (Keys producing printable characters are named by that character) +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNames[] = { + 0x01, L"Esc", + 0x0e, L"Backspace", + 0x0f, L"Tab", + 0x1c, L"Enter", + 0x1d, L"Ctrl", + 0x2a, L"Left Shift", + 0x36, L"Right Shift", + 0x37, L"Num *", + 0x38, L"Alt", + 0x39, L"Space", + 0x3a, L"Caps Lock", + 0x3b, L"F1", + 0x3c, L"F2", + 0x3d, L"F3", + 0x3e, L"F4", + 0x3f, L"F5", + 0x40, L"F6", + 0x41, L"F7", + 0x42, L"F8", + 0x43, L"F9", + 0x44, L"F10", + 0x45, L"Pause", + 0x46, L"Scroll Lock", + 0x47, L"Num 7", + 0x48, L"Num 8", + 0x49, L"Num 9", + 0x4a, L"Num -", + 0x4b, L"Num 4", + 0x4c, L"Num 5", + 0x4d, L"Num 6", + 0x4e, L"Num +", + 0x4f, L"Num 1", + 0x50, L"Num 2", + 0x51, L"Num 3", + 0x52, L"Num 0", + 0x53, L"Num Del", + 0x54, L"Sys Req", + 0x57, L"F11", + 0x58, L"F12", + 0x7c, L"F13", + 0x7d, L"F14", + 0x7e, L"F15", + 0x7f, L"F16", + 0x80, L"F17", + 0x81, L"F18", + 0x82, L"F19", + 0x83, L"F20", + 0x84, L"F21", + 0x85, L"F22", + 0x86, L"F23", + 0x87, L"F24", + 0 , NULL +}; + +static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNamesExt[] = { + 0x1c, L"Num Enter", + 0x1d, L"Right Ctrl", + 0x35, L"Num /", + 0x37, L"Prnt Scrn", + 0x38, L"Right Alt", + 0x45, L"Num Lock", + 0x46, L"Break", + 0x47, L"Home", + 0x48, L"Up", + 0x49, L"Page Up", + 0x4b, L"Left", + 0x4d, L"Right", + 0x4f, L"End", + 0x50, L"Down", + 0x51, L"Page Down", + 0x52, L"Insert", + 0x53, L"Delete", + 0x54, L"<00>", + 0x54, L"Sys Req", + 0x56, L"Help", + 0x5b, L"Left Windows", + 0x5c, L"Right Windows", + 0x5d, L"Application", + 0 , NULL +}; + +static ALLOC_SECTION_LDATA KBDTABLES KbdTables = { + /* + * Modifier keys + */ + &CharModifiers, + + /* + * Characters tables + */ + aVkToWcharTable, + + /* + * Diacritics (deadkeys) + */ + NULL, + + /* + * Names of Keys + */ + aKeyNames, + aKeyNamesExt, + NULL, + +// /* +// * Scan codes to Virtual Keys +// */ +// USHORT *KBD_LONG_POINTER pusVSCtoVK; +// BYTE bMaxVSCtoVK; +// PVSC_VK pVSCtoVK_E0; // Scancode has E0 prefix +// PVSC_VK pVSCtoVK_E1; // Scancode has E1 prefix + /* + * Scan codes to Virtual Keys + */ + ausVK, + sizeof(ausVK) / sizeof(ausVK[0]), + aE0VscToVk, + aE1VscToVk, + + /* + * Locale-specific special processing + */ + MAKELONG(0, KBD_VERSION), + + /* + * Ligatures + */ + 0, + 0, + NULL +}; + +PKBDTABLES KbdLayerDescriptor(VOID) +{ + // There doesn't seem to be any easy reliable way to assign VK_ESCAPE to + // the CAPITAL virtual scancode in compile time due to a high diversity + // of keyboard types. + // FIXME supporting only HID keyboards would make it easy to assign + // VK_ESCAPE reliably in compile-time (2017: all widely used compilers + // can detect that the whole expression is static and compute it in + // compile time, but the MSKLC built-in compiler most probably can't) + //int i; + //for( i = 0; i < KbdTables.bMaxVSCtoVK; ++i ){ + // if( KbdTables.pusVSCtoVK[i] == VK_CAPITAL ) + // // CAPITAL (~ CapsLk) -> ESCAPE + // KbdTables.pusVSCtoVK[i] = VK_ESCAPE; + //} + + return &KbdTables; +} + +// vim: set wrap ft=c: diff --git a/platform/win/source-20180703-gerdLTGT/gerdLTGT-purely_generated00.C b/platform/win/source-20180703-gerdLTGT/gerdLTGT-purely_generated00.C new file mode 100644 index 0000000..386c3fb --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/gerdLTGT-purely_generated00.C @@ -0,0 +1,344 @@ +/***************************************************************************\ +* Module Name: gerdLTGT.C +* +* keyboard layout +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* History: +* KBDTOOL v3.40 - Created Wed May 30 21:52:25 2018 +\***************************************************************************/ + +#include +#include "kbd.h" +#include "gerdLTGT.h" + +#if defined(_M_IA64) +#pragma section(".data") +#define ALLOC_SECTION_LDATA __declspec(allocate(".data")) +#else +#pragma data_seg(".data") +#define ALLOC_SECTION_LDATA +#endif + +/***************************************************************************\ +* ausVK[] - Virtual Scan Code to Virtual Key conversion table +\***************************************************************************/ + +static ALLOC_SECTION_LDATA USHORT ausVK[] = { + T00, T01, T02, T03, T04, T05, T06, T07, + T08, T09, T0A, T0B, T0C, T0D, T0E, T0F, + T10, T11, T12, T13, T14, T15, T16, T17, + T18, T19, T1A, T1B, T1C, T1D, T1E, T1F, + T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T2A, T2B, T2C, T2D, T2E, T2F, + T30, T31, T32, T33, T34, T35, + + /* + * Right-hand Shift key must have KBDEXT bit set. + */ + T36 | KBDEXT, + + T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot + + T38, T39, T3A, T3B, T3C, T3D, T3E, + T3F, T40, T41, T42, T43, T44, + + /* + * NumLock Key: + * KBDEXT - VK_NUMLOCK is an Extended key + * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL) + */ + T45 | KBDEXT | KBDMULTIVK, + + T46 | KBDMULTIVK, + + /* + * Number Pad keys: + * KBDNUMPAD - digits 0-9 and decimal point. + * KBDSPECIAL - require special processing by Windows + */ + T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home) + T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up), + T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp), + T4A, + T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left), + T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear), + T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right), + T4E, + T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End), + T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down), + T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn), + T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins), + T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del), + + T54, T55, T56, T57, T58, T59, T5A, T5B, + T5C, T5D, T5E, T5F, T60, T61, T62, T63, + T64, T65, T66, T67, T68, T69, T6A, T6B, + T6C, T6D, T6E, T6F, T70, T71, T72, T73, + T74, T75, T76, T77, T78, T79, T7A, T7B, + T7C, T7D, T7E + +}; + +static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = { + { 0x10, X10 | KBDEXT }, // Speedracer: Previous Track + { 0x19, X19 | KBDEXT }, // Speedracer: Next Track + { 0x1D, X1D | KBDEXT }, // RControl + { 0x20, X20 | KBDEXT }, // Speedracer: Volume Mute + { 0x21, X21 | KBDEXT }, // Speedracer: Launch App 2 + { 0x22, X22 | KBDEXT }, // Speedracer: Media Play/Pause + { 0x24, X24 | KBDEXT }, // Speedracer: Media Stop + { 0x2E, X2E | KBDEXT }, // Speedracer: Volume Down + { 0x30, X30 | KBDEXT }, // Speedracer: Volume Up + { 0x32, X32 | KBDEXT }, // Speedracer: Browser Home + { 0x35, X35 | KBDEXT }, // Numpad Divide + { 0x37, X37 | KBDEXT }, // Snapshot + { 0x38, X38 | KBDEXT }, // RMenu + { 0x47, X47 | KBDEXT }, // Home + { 0x48, X48 | KBDEXT }, // Up + { 0x49, X49 | KBDEXT }, // Prior + { 0x4B, X4B | KBDEXT }, // Left + { 0x4D, X4D | KBDEXT }, // Right + { 0x4F, X4F | KBDEXT }, // End + { 0x50, X50 | KBDEXT }, // Down + { 0x51, X51 | KBDEXT }, // Next + { 0x52, X52 | KBDEXT }, // Insert + { 0x53, X53 | KBDEXT }, // Delete + { 0x5B, X5B | KBDEXT }, // Left Win + { 0x5C, X5C | KBDEXT }, // Right Win + { 0x5D, X5D | KBDEXT }, // Application + { 0x5F, X5F | KBDEXT }, // Speedracer: Sleep + { 0x65, X65 | KBDEXT }, // Speedracer: Browser Search + { 0x66, X66 | KBDEXT }, // Speedracer: Browser Favorites + { 0x67, X67 | KBDEXT }, // Speedracer: Browser Refresh + { 0x68, X68 | KBDEXT }, // Speedracer: Browser Stop + { 0x69, X69 | KBDEXT }, // Speedracer: Browser Forward + { 0x6A, X6A | KBDEXT }, // Speedracer: Browser Back + { 0x6B, X6B | KBDEXT }, // Speedracer: Launch App 1 + { 0x6C, X6C | KBDEXT }, // Speedracer: Launch Mail + { 0x6D, X6D | KBDEXT }, // Speedracer: Launch Media Selector + { 0x1C, X1C | KBDEXT }, // Numpad Enter + { 0x46, X46 | KBDEXT }, // Break (Ctrl + Pause) + { 0, 0 } +}; + +static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = { + { 0x1D, Y1D }, // Pause + { 0 , 0 } +}; + +/***************************************************************************\ +* aVkToBits[] - map Virtual Keys to Modifier Bits +* +* See kbd.h for a full description. +* +* The keyboard has only three shifter keys: +* SHIFT (L & R) affects alphabnumeric keys, +* CTRL (L & R) is used to generate control characters +* ALT (L & R) used for generating characters by number with numpad +\***************************************************************************/ +static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = { + { VK_SHIFT , KBDSHIFT }, + { VK_CONTROL , KBDCTRL }, + { VK_MENU , KBDALT }, + { 0 , 0 } +}; + +/***************************************************************************\ +* aModification[] - map character modifier bits to modification number +* +* See kbd.h for a full description. +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = { + &aVkToBits[0], + 2, + { + // Modification# // Keys Pressed + // ============= // ============= + 0, // + 1, // Shift + 2 // Control + } +}; + +/***************************************************************************\ +* +* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states +* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states +* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states +* +* Table attributes: Unordered Scan, null-terminated +* +* Search this table for an entry with a matching Virtual Key to find the +* corresponding unshifted and shifted WCHAR characters. +* +* Special values for VirtualKey (column 1) +* 0xff - dead chars for the previous entry +* 0 - terminate the list +* +* Special values for Attributes (column 2) +* CAPLOK bit - CAPS-LOCK affect this key like SHIFT +* +* Special values for wch[*] (column 3 & 4) +* WCH_NONE - No character +* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none) +* WCH_LGTR - Ligature (generates multiple characters) +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VK_TO_WCHARS2 aVkToWch2[] = { +// | | Shift | +// |=========|=========| + {VK_TAB ,0 ,'\t' ,'\t' }, + {VK_ADD ,0 ,'+' ,'+' }, + {VK_DIVIDE ,0 ,'/' ,'/' }, + {VK_MULTIPLY ,0 ,'*' ,'*' }, + {VK_SUBTRACT ,0 ,'-' ,'-' }, + {0 ,0 ,0 ,0 } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHARS3 aVkToWch3[] = { +// | | Shift | Ctrl | +// |=========|=========|=========| + {VK_OEM_3 ,0 ,WCH_NONE ,WCH_NONE ,'~' }, + {'1' ,0 ,WCH_NONE ,WCH_NONE ,'!' }, + {'2' ,0 ,0x00e4 ,0x00c4 ,'@' }, + {'3' ,0 ,0x00f6 ,0x00d6 ,'#' }, + {'4' ,0 ,WCH_NONE ,WCH_NONE ,'$' }, + {'5' ,0 ,0x00fc ,0x00dc ,'%' }, + {'6' ,0 ,WCH_NONE ,WCH_NONE ,'^' }, + {'7' ,0 ,WCH_NONE ,WCH_NONE ,'&' }, + {'8' ,0 ,WCH_NONE ,WCH_NONE ,'*' }, + {'9' ,0 ,WCH_NONE ,WCH_NONE ,'(' }, + {'0' ,0 ,WCH_NONE ,WCH_NONE ,')' }, + {VK_OEM_4 ,0 ,0x00df ,0x1e9e ,'{' }, + {VK_OEM_6 ,0 ,WCH_NONE ,WCH_NONE ,'}' }, + {VK_OEM_102 ,0 ,WCH_NONE ,WCH_NONE ,WCH_NONE }, + {VK_OEM_7 ,0 ,'\'' ,'\"' ,WCH_NONE }, + {VK_OEM_COMMA ,0 ,',' ,'<' ,0x2013 }, + {VK_OEM_PERIOD,0 ,'.' ,'>' ,'!' }, + {'P' ,0 ,'p' ,'P' ,0x00a7 }, + {'Y' ,0 ,'y' ,'Y' ,WCH_NONE }, + {'F' ,0 ,'f' ,'F' ,',' }, + {'G' ,0 ,'g' ,'G' ,'7' }, + {'C' ,0 ,'c' ,'C' ,'8' }, + {'R' ,0 ,'r' ,'R' ,'9' }, + {'L' ,0 ,'l' ,'L' ,'[' }, + {VK_OEM_2 ,0 ,'/' ,'?' ,']' }, + {VK_OEM_PLUS ,0 ,'=' ,'+' ,'+' }, + {VK_OEM_5 ,0 ,'\\' ,'|' ,'|' }, + {'A' ,0 ,'a' ,'A' ,'@' }, + {'O' ,0 ,'o' ,'O' ,0x00b0 }, + {'E' ,0 ,'e' ,'E' ,0x20ac }, + {'U' ,0 ,'u' ,'U' ,'`' }, + {'I' ,0 ,'i' ,'I' ,WCH_NONE }, + {'D' ,0 ,'d' ,'D' ,':' }, + {'H' ,0 ,'h' ,'H' ,'4' }, + {'T' ,0 ,'t' ,'T' ,'5' }, + {'N' ,0 ,'n' ,'N' ,'6' }, + {'S' ,0 ,'s' ,'S' ,'=' }, + {VK_OEM_MINUS ,0 ,'-' ,'_' ,'\\' }, + {VK_OEM_1 ,0 ,';' ,':' ,WCH_NONE }, + {'Q' ,0 ,'q' ,'Q' ,WCH_NONE }, + {'J' ,0 ,'j' ,'J' ,WCH_NONE }, + {'K' ,0 ,'k' ,'K' ,WCH_NONE }, + {'X' ,0 ,'x' ,'X' ,WCH_NONE }, + {'B' ,0 ,'b' ,'B' ,'0' }, + {'M' ,0 ,'m' ,'M' ,'1' }, + {'W' ,0 ,'w' ,'W' ,'2' }, + {'V' ,0 ,'v' ,'V' ,'3' }, + {'Z' ,0 ,'z' ,'Z' ,'.' }, + {VK_DECIMAL ,0 ,'.' ,'.' ,'.' }, + {VK_SPACE ,0 ,' ' ,0x00a0 ,0x00a0 }, + {VK_BACK ,0 ,'\b' ,'\b' ,0x007f }, + {VK_ESCAPE ,0 ,0x001b ,0x001b ,0x001b }, + {VK_RETURN ,0 ,'\r' ,'\r' ,'\n' }, + {VK_CANCEL ,0 ,0x0003 ,0x0003 ,0x0003 }, + {0 ,0 ,0 ,0 ,0 } +}; + +// Put this last so that VkKeyScan interprets number characters +// as coming from the main section of the kbd (aVkToWch2 and +// aVkToWch5) before considering the numpad (aVkToWch1). + +static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = { + { VK_NUMPAD0 , 0 , '0' }, + { VK_NUMPAD1 , 0 , '1' }, + { VK_NUMPAD2 , 0 , '2' }, + { VK_NUMPAD3 , 0 , '3' }, + { VK_NUMPAD4 , 0 , '4' }, + { VK_NUMPAD5 , 0 , '5' }, + { VK_NUMPAD6 , 0 , '6' }, + { VK_NUMPAD7 , 0 , '7' }, + { VK_NUMPAD8 , 0 , '8' }, + { VK_NUMPAD9 , 0 , '9' }, + { 0 , 0 , '\0' } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = { + { (PVK_TO_WCHARS1)aVkToWch3, 3, sizeof(aVkToWch3[0]) }, + { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) }, + { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) }, + { NULL, 0, 0 }, +}; + +/***************************************************************************\ +* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables +* +* Table attributes: Ordered Scan (by scancode), null-terminated +* +* Only the names of Extended, NumPad, Dead and Non-Printable keys are here. +* (Keys producing printable characters are named by that character) +\***************************************************************************/ + +static ALLOC_SECTION_LDATA KBDTABLES KbdTables = { + /* + * Modifier keys + */ + &CharModifiers, + + /* + * Characters tables + */ + aVkToWcharTable, + + /* + * Diacritics + */ + NULL, + + /* + * Names of Keys + */ + NULL, + NULL, + NULL, + + /* + * Scan codes to Virtual Keys + */ + ausVK, + sizeof(ausVK) / sizeof(ausVK[0]), + aE0VscToVk, + aE1VscToVk, + + /* + * Locale-specific special processing + */ + MAKELONG(0, KBD_VERSION), + + /* + * Ligatures + */ + 0, + 0, + NULL +}; + +PKBDTABLES KbdLayerDescriptor(VOID) +{ + return &KbdTables; +} diff --git a/platform/win/source-20180703-gerdLTGT/gerdLTGT-purely_generated00.H b/platform/win/source-20180703-gerdLTGT/gerdLTGT-purely_generated00.H new file mode 100644 index 0000000..733b58e --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/gerdLTGT-purely_generated00.H @@ -0,0 +1,103 @@ +/****************************** Module Header ******************************\ +* Module Name: gerdLTGT.H +* +* keyboard layout header +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* Various defines for use by keyboard input code. +* +* History: +* +* created by KBDTOOL v3.40 Wed May 30 21:52:25 2018 +* +\***************************************************************************/ + +/* + * kbd type should be controlled by cl command-line argument + */ +#define KBD_TYPE 4 + +/* +* Include the basis of all keyboard table values +*/ +#include "kbd.h" +/***************************************************************************\ +* The table below defines the virtual keys for various keyboard types where +* the keyboard differ from the US keyboard. +* +* _EQ() : all keyboard types have the same virtual key for this scancode +* _NE() : different virtual keys for this scancode, depending on kbd type +* +* +------+ +----------+----------+----------+----------+----------+----------+ +* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd | +* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 | +\****+-------+_+----------+----------+----------+----------+----------+----------+*/ + +#undef T0C + #define T0C _EQ( OEM_4 ) +#undef T0D + #define T0D _EQ( OEM_6 ) +#undef T10 + #define T10 _EQ( OEM_7 ) +#undef T11 + #define T11 _EQ( OEM_COMMA ) +#undef T12 + #define T12 _EQ( OEM_PERIOD ) +#undef T13 + #define T13 _EQ( 'P' ) +#undef T14 + #define T14 _EQ( 'Y' ) +#undef T15 + #define T15 _EQ( 'F' ) +#undef T16 + #define T16 _EQ( 'G' ) +#undef T17 + #define T17 _EQ( 'C' ) +#undef T18 + #define T18 _EQ( 'R' ) +#undef T19 + #define T19 _EQ( 'L' ) +#undef T1A + #define T1A _EQ( OEM_2 ) +#undef T1B + #define T1B _EQ( OEM_PLUS ) +#undef T1F + #define T1F _EQ( 'O' ) +#undef T20 + #define T20 _EQ( 'E' ) +#undef T21 + #define T21 _EQ( 'U' ) +#undef T22 + #define T22 _EQ( 'I' ) +#undef T23 + #define T23 _EQ( 'D' ) +#undef T24 + #define T24 _EQ( 'H' ) +#undef T25 + #define T25 _EQ( 'T' ) +#undef T26 + #define T26 _EQ( 'N' ) +#undef T27 + #define T27 _EQ( 'S' ) +#undef T28 + #define T28 _EQ( OEM_MINUS ) +#undef T2C + #define T2C _EQ( OEM_1 ) +#undef T2D + #define T2D _EQ( 'Q' ) +#undef T2E + #define T2E _EQ( 'J' ) +#undef T2F + #define T2F _EQ( 'K' ) +#undef T30 + #define T30 _EQ( 'X' ) +#undef T31 + #define T31 _EQ( 'B' ) +#undef T33 + #define T33 _EQ( 'W' ) +#undef T34 + #define T34 _EQ( 'V' ) +#undef T35 + #define T35 _EQ( 'Z' ) + diff --git a/platform/win/source-20180703-gerdLTGT/gerdLTGT.C b/platform/win/source-20180703-gerdLTGT/gerdLTGT.C new file mode 100644 index 0000000..5245233 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/gerdLTGT.C @@ -0,0 +1,525 @@ +/***************************************************************************\ + ä Ö Ü ß +* Module Name: gerdLTGT.C +* +* keyboard layout +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* History: +* KBDTOOL v3.40 - Created Mon May 29 08:05:02 2017 +\***************************************************************************/ + +#include +#include "kbd.h" +#include "winuser.h" +#include "gerdLTGT.h" + +#if defined(_M_IA64) +//FIXME +//#pragma section(".data",read,write) +#pragma section(".data") +#define ALLOC_SECTION_LDATA __declspec(allocate(".data")) +#else +//FIXME might need system-init of the DLL, not a process-specific init (it's a huge security risk) +//#pragma bss_seg(".data") +#pragma data_seg(".data") +#define ALLOC_SECTION_LDATA +#endif + +/***************************************************************************\ +* ausVK[] - Virtual Scan Code to Virtual Key conversion table +\***************************************************************************/ + +static ALLOC_SECTION_LDATA USHORT ausVK[] = { + T00, T01, T02, T03, T04, T05, T06, T07, + T08, T09, T0A, T0B, T0C, T0D, T0E, T0F, + T10, T11, T12, T13, T14, T15, T16, T17, + // 24 + + T18, T19, T1A, T1B, T1C, + // 5 + + + /* + * Left Ctrl FIXME + */ + T1D, + + T1E, T1F, + T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, + // 12 + + + /* + * Left-hand Shift FIXME + */ + T2A, + + T2B, T2C, T2D, T2E, T2F, + T30, T31, T32, T33, T34, T35, + // 11 + + + /* + * Right-hand Shift key must have KBDEXT bit set. + */ + T36 | KBDEXT, + + T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot + + T38, T39, T3A, T3B, T3C, T3D, T3E, + T3F, T40, T41, T42, T43, T44, + // 13 + + + /* + * NumLock Key: + * KBDEXT - VK_NUMLOCK is an Extended key + * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL) + */ + T45 | KBDEXT | KBDMULTIVK, + + T46 | KBDMULTIVK, + + /* + * Number Pad keys: + * KBDNUMPAD - digits 0-9 and decimal point. + * KBDSPECIAL - require special processing by Windows + */ + T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home) + T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up), + T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp), + T4A, + T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left), + T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear), + T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right), + T4E, + T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End), + T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down), + T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn), + T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins), + T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del), + + T54, T55, T56, T57, T58, T59, T5A, T5B, + T5C, T5D, T5E, T5F, T60, T61, T62, T63, + T64, T65, T66, T67, T68, T69, T6A, T6B, + T6C, T6D, T6E, T6F, T70, T71, T72, T73, + T74, T75, T76, T77, T78, T79, T7A, T7B, + // 40 + + T7C, T7D, T7E + // 3 = 127 + +}; + +static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = { + { 0x10, X10 | KBDEXT }, // Speedracer: Previous Track + { 0x19, X19 | KBDEXT }, // Speedracer: Next Track + { 0x1D, X1D | KBDEXT }, // RControl; Right Ctrl FIXME + { 0x20, X20 | KBDEXT }, // Speedracer: Volume Mute + { 0x21, X21 | KBDEXT }, // Speedracer: Launch App 2 + { 0x22, X22 | KBDEXT }, // Speedracer: Media Play/Pause + { 0x24, X24 | KBDEXT }, // Speedracer: Media Stop + { 0x2E, X2E | KBDEXT }, // Speedracer: Volume Down + { 0x30, X30 | KBDEXT }, // Speedracer: Volume Up + { 0x32, X32 | KBDEXT }, // Speedracer: Browser Home + { 0x35, X35 | KBDEXT }, // Numpad Divide + { 0x37, X37 | KBDEXT }, // Snapshot + { 0x38, X38 | KBDEXT }, // RMenu + { 0x47, X47 | KBDEXT }, // Home + { 0x48, X48 | KBDEXT }, // Up + { 0x49, X49 | KBDEXT }, // Prior + { 0x4B, X4B | KBDEXT }, // Left + { 0x4D, X4D | KBDEXT }, // Right + { 0x4F, X4F | KBDEXT }, // End + { 0x50, X50 | KBDEXT }, // Down + { 0x51, X51 | KBDEXT }, // Next + { 0x52, X52 | KBDEXT }, // Insert + { 0x53, X53 | KBDEXT }, // Delete + { 0x5B, X5B | KBDEXT }, // Left Win + { 0x5C, X5C | KBDEXT }, // Right Win + { 0x5D, X5D | KBDEXT }, // Application + { 0x5F, X5F | KBDEXT }, // Speedracer: Sleep + { 0x65, X65 | KBDEXT }, // Speedracer: Browser Search + { 0x66, X66 | KBDEXT }, // Speedracer: Browser Favorites + { 0x67, X67 | KBDEXT }, // Speedracer: Browser Refresh + { 0x68, X68 | KBDEXT }, // Speedracer: Browser Stop + { 0x69, X69 | KBDEXT }, // Speedracer: Browser Forward + { 0x6A, X6A | KBDEXT }, // Speedracer: Browser Back + { 0x6B, X6B | KBDEXT }, // Speedracer: Launch App 1 + { 0x6C, X6C | KBDEXT }, // Speedracer: Launch Mail + { 0x6D, X6D | KBDEXT }, // Speedracer: Launch Media Selector + { 0x1C, X1C | KBDEXT }, // Numpad Enter + { 0x46, X46 | KBDEXT }, // Break (Ctrl + Pause) + { 0, 0 } +}; + +static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = { + { 0x1D, Y1D }, // Pause + { 0 , 0 } +}; + +/***************************************************************************\ +* aVkToBits[] - map Virtual Keys to Modifier Bits +* +* See kbd.h for a full description. +* +*FIXME wrong original description: +* The keyboard has only three shifter keys: +* SHIFT (L & R) affects alphabnumeric keys, +* CTRL (L & R) is used to generate control characters +* ALT (L & R) used for generating characters by number with numpad +\***************************************************************************/ +static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = { +// { VK_SHIFT , KBDSHIFT }, +// { VK_CONTROL , KBDCTRL }, +// { VK_MENU , KBDALT }, +// { 0 , 0 } + + // FIXME dumblob + // a hack to allow distinguishing left and right shift by propagating it to aModification[] + // make "KBDSHIFT | KBDCTRL" a unique bit combination for left shift + { VK_LSHIFT, KBDSHIFT | KBDCTRL }, + // make "KBDSHIFT | KBDCTRL" a unique bit combination for right shift + { VK_RSHIFT, KBDSHIFT | KBDALT }, + //{ VK_LCONTROL, KBDCTRL }, + //{ VK_RCONTROL, KBDCTRL }, + { 0, 0 } +}; + +/***************************************************************************\ +* aModification[] - map character modifier bits to modification number +* +* See kbd.h for a full description. +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = { + // Demonstration of the relationship (note: this demo is + // a complete nonsense in terms of an internal implementation): + // for( x in aVkToBits ){ + // if( x[0] == 0 && x[1] == 0 ) break + // if( x[1] <= wMaxModBits ){ + // // x[0] is not interesting + // if( aModification[x[1]] != SHFT_INVALID ){ + // shift_to_the_level( x[1] ) + // break + // } + // } + // } + + // PVK_TO_BIT pVkToBit; // Virtual Keys -> Mod bits + &aVkToBits[0], + // WORD wMaxModBits; // max Modification bit combination value + KBDSHIFT | KBDCTRL | KBDALT, + + // BYTE ModNumber[]; // Mod bits -> Modification Number + // mod_bits are an index to this array => order matters ( + // arithmetic progression with step 1 without any omission; + // use SHFT_INVALID as an ignored shift state) + { + // from kbd.h: + // #define KBDSHIFT (1 << 0) + // #define KBDCTRL (1 << 1) + // #define KBDALT (1 << 2) + // #define KBDKANA (1 << 3) + // #define KBDROYA (1 << 4) + // #define KBDLOYA (1 << 5) + // (1 << 6) doesn't exist (not defined anywhere) + // #define KBDGRPSELTAP (1 << 7) + + // FIXME test Ctrl and Alt key bindings (e.g. Ctrl+c, Alt+64, ...) + // shift_state_idx // KBDALT KBDCTRL KBDSHIFT + 0, // 0 0 0 + SHFT_INVALID, // 0 0 1 + SHFT_INVALID, // 0 1 0 + 1, // 0 1 1 (only LSHIFT pressed) + SHFT_INVALID, // 1 0 0 + 1, // 1 0 1 (only RSHIFT pressed) + SHFT_INVALID, // 1 1 0 + 2, // 1 1 1 (both LSHIFT and RSHIFT + // pressed simultaneously) + } +}; + +/***************************************************************************\ +* +* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states +* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states +* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states +* +* Table attributes: Unordered Scan, null-terminated +* +* Search this table for an entry with a matching Virtual Key to find the +* corresponding unshifted and shifted WCHAR characters. +* +* Special values for VirtualKey (column 1) +* 0xff - dead chars for the previous entry +* 0 - terminate the list +* +* Special values for Attributes (column 2) +* CAPLOK bit - CAPS-LOCK affect this key like SHIFT +* +* Special values for wch[*] (column 3 & 4) +* WCH_NONE - No character +* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none) +* WCH_LGTR - Ligature (generates multiple characters) +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VK_TO_WCHARS2 aVkToWch2[] = { +// | | Shift | +// |=========|=========| + {VK_TAB ,0 ,'\t' ,'\t' }, + {VK_ADD ,0 ,'+' ,'+' }, + {VK_DIVIDE ,0 ,'/' ,'/' }, + {VK_MULTIPLY ,0 ,'*' ,'*' }, + {VK_SUBTRACT ,0 ,'-' ,'-' }, + {0 ,0 ,0 ,0 } +}; + +// FIXME all unwanted VK_* keys should be redefined as WCH_NONE +static ALLOC_SECTION_LDATA VK_TO_WCHARS3 aVkToWch3[] = { +// | | Shift | Ctrl | +// |=========|=========|=========| + {VK_OEM_3 ,0 ,WCH_NONE ,WCH_NONE ,'~' }, + {'1' ,0 ,WCH_NONE ,WCH_NONE ,'!' }, + {'2' ,0 ,0x00e4 ,0x00c4 ,'@' }, + {'3' ,0 ,0x00f6 ,0x00d6 ,'#' }, + {'4' ,0 ,WCH_NONE ,WCH_NONE ,'$' }, + {'5' ,0 ,0x00fc ,0x00dc ,'%' }, + {'6' ,0 ,WCH_NONE ,WCH_NONE ,'^' }, + {'7' ,0 ,WCH_NONE ,WCH_NONE ,'&' }, + {'8' ,0 ,WCH_NONE ,WCH_NONE ,'*' }, + {'9' ,0 ,WCH_NONE ,WCH_NONE ,'(' }, + {'0' ,0 ,WCH_NONE ,WCH_NONE ,')' }, + {VK_OEM_4 ,0 ,0x00df ,0x1e9e ,'{' }, + {VK_OEM_6 ,0 ,WCH_NONE ,WCH_NONE ,'}' }, + {VK_OEM_102 ,0 ,WCH_NONE ,WCH_NONE ,WCH_NONE }, + {VK_OEM_7 ,0 ,'\'' ,'\"' ,WCH_NONE }, + {VK_OEM_COMMA ,0 ,',' ,'<' ,WCH_NONE }, + {VK_OEM_PERIOD,0 ,'.' ,'>' ,WCH_NONE }, + {'P' ,0 ,'p' ,'P' ,WCH_NONE }, + {'Y' ,0 ,'y' ,'Y' ,WCH_NONE }, + {'F' ,0 ,'f' ,'F' ,WCH_NONE }, + {'G' ,0 ,'g' ,'G' ,WCH_NONE }, + {'C' ,0 ,'c' ,'C' ,WCH_NONE }, + {'R' ,0 ,'r' ,'R' ,WCH_NONE }, + {'L' ,0 ,'l' ,'L' ,WCH_NONE }, + {VK_OEM_2 ,0 ,'/' ,'?' ,']' }, + {VK_OEM_PLUS ,0 ,'=' ,'+' ,'+' }, + {VK_OEM_5 ,0 ,'\\' ,'|' ,'|' }, + {'A' ,0 ,'a' ,'A' ,WCH_NONE }, + {'O' ,0 ,'o' ,'O' ,WCH_NONE }, + {'E' ,0 ,'e' ,'E' ,WCH_NONE }, + {'U' ,0 ,'u' ,'U' ,WCH_NONE }, + {'I' ,0 ,'i' ,'I' ,WCH_NONE }, + {'D' ,0 ,'d' ,'D' ,WCH_NONE }, + {'H' ,0 ,'h' ,'H' ,WCH_NONE }, + {'T' ,0 ,'t' ,'T' ,WCH_NONE }, + {'N' ,0 ,'n' ,'N' ,WCH_NONE }, + {'S' ,0 ,'s' ,'S' ,WCH_NONE }, + {VK_OEM_MINUS ,0 ,'-' ,'_' ,'\\' }, + {VK_OEM_1 ,0 ,';' ,':' ,WCH_NONE }, + {'Q' ,0 ,'q' ,'Q' ,WCH_NONE }, + {'J' ,0 ,'j' ,'J' ,WCH_NONE }, + {'K' ,0 ,'k' ,'K' ,WCH_NONE }, + {'X' ,0 ,'x' ,'X' ,WCH_NONE }, + {'B' ,0 ,'b' ,'B' ,WCH_NONE }, + {'M' ,0 ,'m' ,'M' ,WCH_NONE }, + {'W' ,0 ,'w' ,'W' ,WCH_NONE }, + {'V' ,0 ,'v' ,'V' ,WCH_NONE }, + {'Z' ,0 ,'z' ,'Z' ,WCH_NONE }, + {VK_DECIMAL ,0 ,'.' ,'.' ,'.' }, + {VK_SPACE ,0 ,' ' ,0x00a0 ,0x00a0 }, + {VK_BACK ,0 ,'\b' ,'\b' ,0x007f }, + {VK_ESCAPE ,0 ,0x001b ,0x001b ,0x001b }, + {VK_RETURN ,0 ,'\r' ,'\r' ,'\n' }, + {VK_CANCEL ,0 ,0x0003 ,0x0003 ,0x0003 }, + {0 ,0 ,0 ,0 ,0 } +}; + +// Put this last so that VkKeyScan interprets number characters +// as coming from the main section of the kbd (aVkToWch2 and +// aVkToWch5) before considering the numpad (aVkToWch1). + +static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = { + { VK_NUMPAD0 , 0 , '0' }, + { VK_NUMPAD1 , 0 , '1' }, + { VK_NUMPAD2 , 0 , '2' }, + { VK_NUMPAD3 , 0 , '3' }, + { VK_NUMPAD4 , 0 , '4' }, + { VK_NUMPAD5 , 0 , '5' }, + { VK_NUMPAD6 , 0 , '6' }, + { VK_NUMPAD7 , 0 , '7' }, + { VK_NUMPAD8 , 0 , '8' }, + { VK_NUMPAD9 , 0 , '9' }, + { 0 , 0 , '\0' } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = { + { (PVK_TO_WCHARS1)aVkToWch3, 3, sizeof(aVkToWch3[0]) }, + { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) }, + { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) }, + { NULL, 0, 0 }, +}; + +/***************************************************************************\ +* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables +* +* Table attributes: Ordered Scan (by scancode), null-terminated +* +* Only the names of Extended, NumPad, Dead and Non-Printable keys are here. +* (Keys producing printable characters are named by that character) +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNames[] = { + 0x01, L"Esc", + 0x0e, L"Backspace", + 0x0f, L"Tab", + 0x1c, L"Enter", + 0x1d, L"Ctrl", + 0x2a, L"Left Shift", + 0x36, L"Right Shift", + 0x37, L"Num *", + 0x38, L"Alt", + 0x39, L"Space", + 0x3a, L"Caps Lock", + 0x3b, L"F1", + 0x3c, L"F2", + 0x3d, L"F3", + 0x3e, L"F4", + 0x3f, L"F5", + 0x40, L"F6", + 0x41, L"F7", + 0x42, L"F8", + 0x43, L"F9", + 0x44, L"F10", + 0x45, L"Pause", + 0x46, L"Scroll Lock", + 0x47, L"Num 7", + 0x48, L"Num 8", + 0x49, L"Num 9", + 0x4a, L"Num -", + 0x4b, L"Num 4", + 0x4c, L"Num 5", + 0x4d, L"Num 6", + 0x4e, L"Num +", + 0x4f, L"Num 1", + 0x50, L"Num 2", + 0x51, L"Num 3", + 0x52, L"Num 0", + 0x53, L"Num Del", + 0x54, L"Sys Req", + 0x57, L"F11", + 0x58, L"F12", + 0x7c, L"F13", + 0x7d, L"F14", + 0x7e, L"F15", + 0x7f, L"F16", + 0x80, L"F17", + 0x81, L"F18", + 0x82, L"F19", + 0x83, L"F20", + 0x84, L"F21", + 0x85, L"F22", + 0x86, L"F23", + 0x87, L"F24", + 0 , NULL +}; + +static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNamesExt[] = { + 0x1c, L"Num Enter", + 0x1d, L"Right Ctrl", + 0x35, L"Num /", + 0x37, L"Prnt Scrn", + 0x38, L"Right Alt", + 0x45, L"Num Lock", + 0x46, L"Break", + 0x47, L"Home", + 0x48, L"Up", + 0x49, L"Page Up", + 0x4b, L"Left", + 0x4d, L"Right", + 0x4f, L"End", + 0x50, L"Down", + 0x51, L"Page Down", + 0x52, L"Insert", + 0x53, L"Delete", + 0x54, L"<00>", + 0x54, L"Sys Req", + 0x56, L"Help", + 0x5b, L"Left Windows", + 0x5c, L"Right Windows", + 0x5d, L"Application", + 0 , NULL +}; + +static ALLOC_SECTION_LDATA KBDTABLES KbdTables = { + /* + * Modifier keys + */ + &CharModifiers, + + /* + * Characters tables + */ + aVkToWcharTable, + + /* + * Diacritics (deadkeys) + */ + NULL, + + /* + * Names of Keys + */ + aKeyNames, + aKeyNamesExt, + NULL, + +// /* +// * Scan codes to Virtual Keys +// */ +// USHORT *KBD_LONG_POINTER pusVSCtoVK; +// BYTE bMaxVSCtoVK; +// PVSC_VK pVSCtoVK_E0; // Scancode has E0 prefix +// PVSC_VK pVSCtoVK_E1; // Scancode has E1 prefix + /* + * Scan codes to Virtual Keys + */ + ausVK, + sizeof(ausVK) / sizeof(ausVK[0]), + // for aE0VscToVk are both LSHIFT and RSHIFT ignored in xlate.c + aE0VscToVk, + aE1VscToVk, + + /* + * Locale-specific special processing + */ + MAKELONG(0, KBD_VERSION), + + /* + * Ligatures + */ + 0, + 0, + NULL +}; + +PKBDTABLES KbdLayerDescriptor(VOID) +{ + // There doesn't seem to be any easy reliable way to assign VK_ESCAPE to + // the CAPITAL virtual scancode in compile time due to a high diversity + // of keyboard types. + // FIXME supporting only HID keyboards would make it easy to assign + // VK_ESCAPE reliably in compile-time (2017: all widely used compilers + // can detect that the whole expression is static and compute it in + // compile time, but the MSKLC built-in compiler most probably can't) + //int i; + //for( i = 0; i < KbdTables.bMaxVSCtoVK; ++i ){ + // if( KbdTables.pusVSCtoVK[i] == VK_CAPITAL ) + // // CAPITAL (~ CapsLk) -> ESCAPE + // KbdTables.pusVSCtoVK[i] = VK_ESCAPE; + //} + + return &KbdTables; +} + +// vim: set wrap ft=c: diff --git a/platform/win/gerd02/gerdLTGT.DEF b/platform/win/source-20180703-gerdLTGT/gerdLTGT.DEF similarity index 100% rename from platform/win/gerd02/gerdLTGT.DEF rename to platform/win/source-20180703-gerdLTGT/gerdLTGT.DEF diff --git a/platform/win/gerd02/gerdLTGT.H b/platform/win/source-20180703-gerdLTGT/gerdLTGT.H similarity index 100% rename from platform/win/gerd02/gerdLTGT.H rename to platform/win/source-20180703-gerdLTGT/gerdLTGT.H diff --git a/platform/win/source-20180703-gerdLTGT/gerdLTGT.RC b/platform/win/source-20180703-gerdLTGT/gerdLTGT.RC new file mode 100644 index 0000000..c758f8f --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/gerdLTGT.RC @@ -0,0 +1,51 @@ +#include "winver.h" +#include "winuser.h" +1 VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L +FILEOS 0x40004L + FILETYPE VFT_DLL + FILESUBTYPE VFT2_DRV_KEYBOARD +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004B0" + BEGIN + VALUE "CompanyName", "shit00\0" + VALUE "FileDescription", "German ULKL keyboard layout (LTGT variant)\0" + VALUE "FileVersion", "shit02\0" + VALUE "InternalName", "shit03\0" + VALUE "ProductName", "shit04\0" + VALUE "Release Information","shit05\0" + VALUE "LegalCopyright", "shit06\0" + VALUE "OriginalFilename", "kbdgr5.dll\0" + VALUE "ProductVersion", "shit08\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0000, 0x04B0 + END +END + +STRINGTABLE DISCARDABLE +LANGUAGE 9, 1 +BEGIN + 1200 "de-DE" +END + + +STRINGTABLE DISCARDABLE +LANGUAGE 9, 1 +BEGIN + 1000 "German Dvorak ltgt (useful for text with lots of <>)" +END + + +STRINGTABLE DISCARDABLE +LANGUAGE 9, 1 +BEGIN + 1100 "German or related (all locations world-wide)" +END diff --git a/platform/win/source-20180703-gerdLTGT/gerdLTGT.RC-purely_generated00 b/platform/win/source-20180703-gerdLTGT/gerdLTGT.RC-purely_generated00 new file mode 100644 index 0000000000000000000000000000000000000000..27f899a187f7d964ce29560b726988ad3e048970 GIT binary patch literal 2528 zcmc(gTWcCo6ovP5q5ol+zNC;gG4Z8P3b7iIPF2(hg+kD1jMPLK&F$a!TjzKjCoz;M zy)ewox$Lv|TKjh1*wk+9!e(}BBO6;}vE941J7%f9w<}g&+bb)v*SDH=tZNNxS(9(m zP8n%8V$`sN{k%-XPWF^+-wt_?dCQFa$u>G$R<$$xY`quG?>-r9o?`jL>LB~dziVHx zd1w#Vxnw7gFO&5$hii$TtHpW0BZPX&&vf+co3-I8kDP+}9Q4UEsVUoOFki z=iscdTY>!vKBzjR71rv`w;s2=S3!3R?}%3nz7>&C+$LC`61y?-H*lS=W92=*OH+tN zUZdyfxmIB8BOYXbtu09Q;gP^vo{7Obw`*J20Bn!s%7EFJ^?i236T@K&pDXfjNVZ+L zGY912Ez(1{&G{anGl6}===%%!g2p_C;GZg%muQ#Y7TBAj_hyYH#^1{IYlk!<4tMOP z%zl7#hV+CtvOO>@k-X$TV=jNE{8y|!I0;pbxI|zb!+D6r0GSah38P2mw@CaRhrUC( z%wZ3#W9n0WRdq$Kz9Ls)#Vjd{#3toGfa9*1DPocs{Ksr3vz3tY3`zZf#q#` z%AXWV1BXZ+9OA!-3Rit6>_%{w)nXhw=v2iFTr8ta<@oq-XU5+`kYIh{{HqFCz)D#; zA#YZj>WJalpm!+$rsVCIh$#1pac!+Nt5+zVp&B#`wfH=q#cbpwxI0ISW@n8|@ZHeo z_tSa4d-Y+HZnzcgg!z8aLzDW|5^pKxAyKCcWv5f8F)e53agPFWwWXh$DwF>kGQo-(jUjZb@q% z)xSjMeU~Bo^IccB#fsQP{4e=_v`=)T|INGfBqDj<{ti*6^BFgGx5XaWH{((L&#C_` U7sc+LwUnI^k=31}81Lr!6Hcr?$N&HU literal 0 HcmV?d00001 diff --git a/platform/win/source-20180703-gerdLTGT/gerdLTGT.klc b/platform/win/source-20180703-gerdLTGT/gerdLTGT.klc new file mode 100644 index 0000000..54cb1ce --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/gerdLTGT.klc @@ -0,0 +1,327 @@ +// 2010-2017 Jan Pacner +// etaoin shrdlu! + +// The concept of this keyboard layout +// motto: be as much compatible with ISO dvorak as possible +// 4. level is the same as 3. level +// 2. level of ISO dvorak goes without modifications to the 3. level +// the whole national alphabet is accessible directly from 1. and 2. level +// without any exception +// 3. level has some additional non-alphabet characters (e.g. numbers) +// 3. level is accessible only by pressing both Shifts at once (and +// holding either of them) +// there are 2 variants which differ in placement and/or availability of +// characters ' " < > „ “ en_dash +// in `ltgt`, characters „ “ are not available and ' " < > are at their +// original dvorak places and ! is duplicated for better reachability +// in `writer`, all characters are available, but " < > are in +// the 3. level, thus less reachable + +// ----------- standard ISO dvorak, 1. and 2. level +// ~ ! @ # $ % ^ & * ( ) { } +// ` 1 2 3 4 5 6 7 8 9 0 [ ] +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// space +// space + +// ----------- german dvorak ltgt, 1. and 2. levelll +// ä Ö Ü ß +// ä ö ü ß +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak ltgt, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// nda ! § , 7 8 9 [ ] + | +// en dash +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak writer, 1. and 2. level +// ä Ö Ü ß +// ä ö ü ß +// +// “ nda ' P Y F G C R L ? + | +// en dash +// „ , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak writer, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// " < > § , 7 8 9 [ ] + | +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak (ltgt|writer), 4. level +// the same as 3. level + +// KBD identifier_max_8_bytes_long "Some description to show in keyboard settings and while switching layouts" +KBD gerdLTGT "German Dvorak ltgt (useful for text with lots of <>)" +//KBD gerdLTGT "German Dvorak writer (useful for text with lower/upper UTF-8 double quotes)" + +COPYRIGHT "MIT license" + +COMPANY "github.com/dumblob/ULKL/" + +LOCALENAME "de-DE" + +// LOCALEID "00000000" +LOCALEID "00000407" + +//FIXME 1.1 after unused keys produce the character +VERSION 1.0 + +//ATTRIBUTES + +//MODIFIERS + +SHIFTSTATE + +// shift_state_idx // column_below modifiers +0 // 4 +1 // 5 LSHIFT or RSHIFT pressed +2 // 6 both LSHIFT and RSHIFT pressed simultaneously + +LAYOUT +// an extra @ at the end is a dead key +// -1 denotes the character +// SC denotes a Virtual Scan Code +// Cap ~ CapsInfo (probably whether CapsLock is applicable) + +// topmost row + +//SC VK_ Cap 0 1 2 +29 OEM_3 0 -1 -1 007e // , , TILDE +02 1 0 -1 -1 0021 // , , EXCLAMATION MARK +03 2 0 00e4 00c4 0040 // adiaeresis, Adiaeresis, COMMERCIAL AT +04 3 0 00f6 00d6 0023 // odiaeresis, Odiaeresis, NUMBER SIGN +05 4 0 -1 -1 0024 // , , DOLLAR SIGN +06 5 0 00fc 00dc 0025 // udiaeresis, Udiaeresis, PERCENT SIGN +07 6 0 -1 -1 005e // , , CIRCUMFLEX ACCENT +08 7 0 -1 -1 0026 // , , AMPERSAND +09 8 0 -1 -1 002a // , , ASTERISK +0a 9 0 -1 -1 0028 // , , LEFT PARENTHESIS +0b 0 0 -1 -1 0029 // , , RIGHT PARENTHESIS +0c OEM_4 0 00df 1e9e 007b // ssharp, U1E9E, LEFT CURLY BRACKET (BRACELEFT) +0d OEM_6 0 -1 -1 007d // , , RIGHT CURLY BRACKET (BRACERIGHT) +// FIXME wtf is this key? is it really ? +56 OEM_102 0 -1 -1 -1 // , , +//0e ???? 0 ???? ???? ???? // backspace, backspace, backspace + +// top row + +//0f ???? 0 ???? ???? ???? // tab, tab, tab +// ltgt variant +10 OEM_7 0 0027 0022 -1 // APOSTROPHE, QUOTATION MARK (QUOTEDBL), +11 OEM_COMMA 0 002c 003c 2013 // COMMA, LESS-THAN SIGN, U2013 (EN DASH, pomlcka) +12 OEM_PERIOD 0 002e 003e 0021 // FULL STOP (PERIOD), GREATER-THAN SIGN, EXCLAMATION MARK +// writer variant +//10 OEM_7 0 201e 201c 0022 // U201E LOWER QUOTATION MARK (QUOTEDBL), U201C UPPER QUOTATION MARK (QUOTEDBL), QUOTATION MARK (QUOTEDBL) +//11 OEM_COMMA 0 002c 2013 003c // COMMA, U2013 (EN DASH, pomlcka), LESS-THAN SIGN +//12 OEM_PERIOD 0 002e 0027 003e // FULL STOP (PERIOD), APOSTROPHE, GREATER-THAN SIGN + +13 P 0 p P 00a7 // LATIN SMALL LETTER P, LATIN CAPITAL LETTER P, SECTION SIGN (PARAGRAPH) +14 Y 0 y Y -1 // LATIN SMALL LETTER Y, LATIN CAPITAL LETTER Y, +15 F 0 f F 002c // LATIN SMALL LETTER F, LATIN CAPITAL LETTER F, COMMA +16 G 0 g G 7 // LATIN SMALL LETTER G, LATIN CAPITAL LETTER G, DIGIT SEVEN +17 C 0 c C 8 // LATIN SMALL LETTER C, LATIN CAPITAL LETTER C, DIGIT EIGHT +18 R 0 r R 9 // LATIN SMALL LETTER R, LATIN CAPITAL LETTER R, DIGIT NINE +19 L 0 l L 005b // LATIN SMALL LETTER L, LATIN CAPITAL LETTER L, LEFT SQUARE BRACKET +1a OEM_2 0 002f 003f 005d // SOLIDUS (SLASH), QUESTION MARK, RIGHT SQUARE BRACKET +1b OEM_PLUS 0 003d 002b 002b // EQUALS SIGN, PLUS SIGN, PLUS SIGN +2b OEM_5 0 005c 007c 007c // REVERSE SOLIDUS (BACKSLASH), VERTICAL LINE (BAR), VERTICAL LINE (BAR) + +// home/middle row + +//CapsLk +//3a ???? 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +//3a SGCap 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +1e A 0 a A 0040 // LATIN SMALL LETTER A, LATIN CAPITAL LETTER A, COMMERCIAL AT +1f O 0 o O 00b0 // LATIN SMALL LETTER O, LATIN CAPITAL LETTER O, DEGREE +20 E 0 e E 20ac // LATIN SMALL LETTER E, LATIN CAPITAL LETTER E, EURO SIGN +21 U 0 u U 0060 // LATIN SMALL LETTER U, LATIN CAPITAL LETTER U, GRAVE ACCENT (GRAVE) +22 I 0 i I -1 // LATIN SMALL LETTER I, LATIN CAPITAL LETTER I, +23 D 0 d D 003a // LATIN SMALL LETTER D, LATIN CAPITAL LETTER D, COLON +24 H 0 h H 4 // LATIN SMALL LETTER H, LATIN CAPITAL LETTER H, DIGIT FOUR +25 T 0 t T 5 // LATIN SMALL LETTER T, LATIN CAPITAL LETTER T, DIGIT FIVE +26 N 0 n N 6 // LATIN SMALL LETTER N, LATIN CAPITAL LETTER N, DIGIT SIX +27 S 0 s S 003d // LATIN SMALL LETTER S, LATIN CAPITAL LETTER S, EQUALS SIGN +// pomlcka (= minus = dash) +28 OEM_MINUS 0 002d 005f 005c // HYPHEN-MINUS (FIXME is it the plain minus?), LOW LINE (UNDERSCORE), REVERSE SOLIDUS (BACKSLASH) +//1c ???? 0 ???? ???? ???? // enter/return, enter/return, enter/return + +// bottom row + +//2a ???? 0 ???? ???? ???? // left shift, left shift, left shift +// left bottom key, right from , which doesn't follow the kbd standard +// FIXME wtf is this key? is it really ? +//56 OEM_102 0 -1 -1 -1 // , , +2c OEM_1 0 003b 003a -1 // SEMICOLON, COLON, +2d Q 0 q Q -1 // LATIN SMALL LETTER Q, LATIN CAPITAL LETTER Q, +2e J 0 j J -1 // LATIN SMALL LETTER J, LATIN CAPITAL LETTER J, +2f K 0 k K -1 // LATIN SMALL LETTER K, LATIN CAPITAL LETTER K, +30 X 0 x X -1 // LATIN SMALL LETTER X, LATIN CAPITAL LETTER X, +31 B 0 b B 0 // LATIN SMALL LETTER B, LATIN CAPITAL LETTER B, DIGIT ZERO +32 M 0 m M 1 // LATIN SMALL LETTER M, LATIN CAPITAL LETTER M, DIGIT ONE +33 W 0 w W 2 // LATIN SMALL LETTER W, LATIN CAPITAL LETTER W, DIGIT TWO +34 V 0 v V 3 // LATIN SMALL LETTER V, LATIN CAPITAL LETTER V, DIGIT THREE +35 Z 0 z Z 002e // LATIN SMALL LETTER Z, LATIN CAPITAL LETTER Z, FULL STOP (PERIOD) +// numpad dot +53 DECIMAL 0 002e 002e 002e // FULL STOP (PERIOD), FULL STOP (PERIOD), FULL STOP (PERIOD) +//36 ???? 0 ???? ???? ???? // right shift, right shift, right shift + +// bottom-most row + +//?? ???? 0 ???? ???? ???? // left ctrl, left ctrl, left ctrl +//5b ???? 0 ???? ???? ???? // left super (win), left super (win), left super (win) +//?? ???? 0 ???? ???? ???? // left alt (meta), left alt (meta), left alt (meta) +39 SPACE 0 0020 00a0 00a0 // SPACE, NO-BREAK SPACE, NO-BREAK SPACE +//38 ???? 0 ???? ???? ???? // right alt (meta), right alt (meta), right alt (meta) +//5c ???? 0 ???? ???? ???? // right super (win), right super (win), right super (win) +//?? ???? 0 ???? ???? ???? // menu, menu, menu +//5d ???? 0 ???? ???? ???? // menu, menu, menu +//56 ???? 0 ???? ???? ???? // menu, menu, menu +//1d ???? 0 ???? ???? ???? // right ctrl, right ctrl, right ctrl +//46 ???? 0 ???? ???? ???? // scroll lock, scroll lock, scroll lock + +//LIGATURE +// +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// a mod b c + +//KEYNAME +// +//01 Esc +//0e Backspace +//0f Tab +//1c Enter +//1d Ctrl +////2a Shift +//2a "Left Shift" +//36 "Right Shift" +//37 "Num *" +//38 Alt +//39 Space +//3a "Caps Lock" +//3b F1 +//3c F2 +//3d F3 +//3e F4 +//3f F5 +//40 F6 +//41 F7 +//42 F8 +//43 F9 +//44 F10 +//45 Pause +//46 "Scroll Lock" +//47 "Num 7" +//48 "Num 8" +//49 "Num 9" +//4a "Num -" +//4b "Num 4" +//4c "Num 5" +//4d "Num 6" +//4e "Num +" +//4f "Num 1" +//50 "Num 2" +//51 "Num 3" +//52 "Num 0" +//53 "Num Del" +//54 "Sys Req" +//57 F11 +//58 F12 +//7c F13 +//7d F14 +//7e F15 +//7f F16 +//80 F17 +//81 F18 +//82 F19 +//83 F20 +//84 F21 +//85 F22 +//86 F23 +//87 F24 +// +//KEYNAME_EXT +// +//1c "Num Enter" +//1d "Right Ctrl" +//35 "Num /" +//37 "Prnt Scrn" +//38 "Right Alt" +//45 "Num Lock" +//46 Break +//47 Home +//48 Up +//49 "Page Up" +//4b Left +//4d Right +//4f End +//50 Down +//51 "Page Down" +//52 Insert +//53 Delete +//54 <00> +//54 "Sys Req" +//56 Help +//5b "Left Windows" +//5c "Right Windows" +//5d Application + +DESCRIPTIONS + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German Dvorak ltgt (useful for text with lots of <>) +//0409 German Dvorak writer (useful for text with lower/upper UTF-8 double quotes) + +LANGUAGENAMES + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German or related (all locations world-wide) + +ENDKBD + +// vim: set ft=javascript: diff --git a/platform/win/source-20180703-gerdLTGT/i386/gerdLTGT.dll b/platform/win/source-20180703-gerdLTGT/i386/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..a0dfadda7b32c3753d0ccbb1dd9cf85534e38221 GIT binary patch literal 6144 zcmeI0UvSjb7016fi8bh=>4;V>v>S|y8e$;7-%4x5hyj8uB#;FIhC)b|WX&cUH$k8x zg5sYC9_WlS^?~VNrLAq#N^ROY7L~R<;*1YWUrLqf_+VSwZl|;}oie4LbAP++LTR08 zJJWH-`?!Vu?=bm%!xi?v{e!r?E)$pD>C%pzOwfWzF|ML#bSAF*Nt28z3?fTbT z^6mQ6P-Z+nmd_35`$ppZeWRnfiTLJpJim1`o*9j|cXr1|as%n6>C>-hC=NZVCjH*J z^p*Qc@2;1&?CYVt>!nAE+*ahc=ju%VkoEmnl65VXlCD}OUb*(6QlC?*s=w0JM#UMW zT3A!#S8*zDNcSW~P~=kzOm zQIFx+ztZ1-**jq)ivq6u34|R`I>a0a_%lQx&`{0TdD@v zp}xsp)QsstGmHEL~&J!Ri-%Bsug+)m<)KeYN9ZKTh+{ zu);Y?!J|}IszLlph5OZycd4)%zaWkllFH&~D!j$2?$ri7?jFC+lj_CRJMq0fUKKi7 zc_&<~G`^_98a!$ZT&4_usY1I3@Jfs3@+f?r_;+Fk)4#ETzk7``=qZ{_o6vM0R@;ol`mxpkmP%u#Em&v}>kMI;j9G^FzX-l)2(U=O?+cEOpj9nOLa;O#ID@dMRD{6J@KP#u1tGtg%I z0HPzEfOo^=5L@dQyayhE*j!WaUN{Nc;30_3bO53|JrA+D_Cai0u`{J&Zxq zLoYNvB%$e{6`CHJi!^=U%W9x(m#JFV3r}CCx()CI1U^mTd&lrQD|`T-ySCWI&B}Bo z+7IyhTa=Y6Qt7Vt>UB}8`KrAyQ=a5K%)9$W=`AP?rt<^I)Y4SbKsKx8n+KA8JJR{~ z^muBYdZA1Wc!0y^|$rkKI zTb2?1Pl!^t5?QhH_5CE0ds7uCg2#e!s@g z9{rj;IigN9=OSiHGtV#|tR(i0Fk6!LeqU2Lb{xHAy<}Z{GwRpcO+U+*zrFJUdE&(6 z33_Brob%(G+_q-Z^%CM!P-IJy^NZxn@$Jo?^L(^gLQJz*Vl>}2CWelui-^@b&~Y4FrisvHnIc=1%Qk08A2v=YZ)276HeM-zM@8P`Db<@yrM$^i%G>!` z%3Dk<5~HomXsa^X ziiFMj@E6lk*%P{{>BHLQH6=eN$!Rgaa&L6AM>2jll>ITzO3Jl1N7*kb{UOCHn;CDB zpKTZ^%JVL!)K6PwdaZ*X^0UgCkMsXO4OIC*2jhg>I)va%*?plb)!fB6*QmF1XgjoX zcmF^2b5Z=hME$gy;@^~fS58h=|4zB0n2YL9U84SS`WL8Q(7<_I(SDRNa-C1Ll+C}- zr+WS@u0CHPZ+mGi-o26E#q5J_?v0)7;f-)5d&*8u>5ZB{{JnfSS&g$FuMcAlPZhMc zlr~dvjAuK=PMbkS%Mb_Bj6BNz%F%J5?_+05^aSjjX6l=CIp5yzBfagQQR3c8Sc?1O zem73|uWY_u+>YJ(@huwKUbA_}n7?!aio3SO?GZm>oSSlzTWyj^F--jqc5aTAJf~6| zIs2%|5vAicB;7!$h9rZ37{THjhf%Xr1SWqG4m6|K+o5S=8WjFzof zVYz=4lY7yUnS za^A6)<1HszPPd$CIonbb#DW>Y%%CA?41%CFXb+M>D(DRcf^0Am>`-10#1HqwS zGMEaE1jmBo!HM8x@P2SQI1`)=YQk7JBb*sFgpFYkwubFtGE9ZN;Xs%TC&HcKzVP|* zKzJye45z{);j!>|cp^L*z8{_r&xB{gnnWxyBQZ14kZ4QxwLy2r+ NkNxTSarz%=;2*wB$7=up literal 0 HcmV?d00001 diff --git a/platform/win/source-20180703-gerdLTGT/i386/gerdLTGT.exp b/platform/win/source-20180703-gerdLTGT/i386/gerdLTGT.exp new file mode 100644 index 0000000000000000000000000000000000000000..3f979e2122a9938dbef239ce2303217e00547812 GIT binary patch literal 672 zcmZuu%}T>S5T3MZJ$PsjN~t0_6k0*jYC%db7A=T2R?+rkK+|MffGx~Kaa%6o_# z#DF#!6NoZCipiSi?esor6c30Lp7T4(5MNVF&J3@^0zHLf@XrSk|1H%L_{b6<(EhG% z#!a=pQCG~96R0*#Rlj7s!d!z}j%Rb2LOUHCgE`Dm!DP&1f~7H!3zij`e2d7aznJj6 zAv;1OK}z5PR-w3}g+FB%4rE~_5yLlhHU-Tv)8DoXZo78Nle2pZvbtHT;$)zhkRT3+ zBkKIXuaXGrHZIM6yW^kQe4+jH{Ce5Dz6E$kJ&%C(lGbn;ceSluUBgC?J=@W`)>&9o zNbqu6@N#!A=PIfy=XM(PQdl@nt8Cb(j$)aa{uK;|RR8Z=r#hnGUe)wdytQTA`3i44 p9V&z76)3)o<`yX39d7#d`bxT%$5?{Z(1S$GmsX01=zi2>egL?Fc4Pnm literal 0 HcmV?d00001 diff --git a/platform/win/source-20180703-gerdLTGT/i386/gerdLTGT.lib b/platform/win/source-20180703-gerdLTGT/i386/gerdLTGT.lib new file mode 100644 index 0000000000000000000000000000000000000000..dafec1462f87306306832a0432f9764af80d7935 GIT binary patch literal 1766 zcmcIlPfrs;6#wlmqHKsZqDRS+kbsv;mtCZWm?AaWbSb1PCl5pER%ilgv#bZh!7t$V z@aT;T7fxI~K*9$g;cMV~+Zj7(i><*)cILg`yxn=f_h)u$sTS9FU)wL7n+6hB1T}qq}l4@%fImL&!B%KREVUgmAf4h#$D-=BVXMEo8Q zPZ~xxYHWYnncnEAzzPXpl_J*yGHwWGTdB8v^jl z#_uAGPw^xNe;s%wHC{}FG~adO*gEAw>c#b4tzOKuUXD}u*va1Y5~W++NvoH6g>t=o zQ;J-ONdL9 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180703-gerdLTGT/ia64/gerdLTGT.dll b/platform/win/source-20180703-gerdLTGT/ia64/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..02dee5eade9d5576fa5bf2096b56a79a5ce75048 GIT binary patch literal 7168 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 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (10).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (10).sh new file mode 100644 index 0000000..a142239 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (10).sh @@ -0,0 +1,253 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=X64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + printf 'INFO Compiling %s...\n' "$outdir" + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + #"$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + "$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + printf '\nHOWK00\n\n' + + # FIXME WINVER and WIN32_IE higher than at rc.exe + #"$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 -DWINVER=x5 -D_WIN32_IE=x5 -MD -c -Zp8 -Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Z7 -Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + # FIXME -Gz (x86 only) + # FIXME -Gm + "$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0500 -D_WIN32_IE=0x0500 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox -Fo"$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + printf '\nHOWK11\n\n' + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + # FIXME -noentry will probably disable main(); we need main() though + # -section:init,d might have deleted it :( + #"$p\\link.exe" -nologo -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:0x04,0x01 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + # FIXME -merge:.rdata=.data + "$p\\link.exe" "-machine:$machine" -nologo -SECTION:INIT,d -noentry -OPT:REF -OPT:ICF -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-def:${kbdname}.def" "-out:$outdir\\${kbdname}.dll" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" + + printf '\nHOWK22\n\n' + + if [ -n "$(ls -1 "$TEMP_WIN\\my_layout."* 2>/dev/null)" ]; then + rm "$TEMP_WIN\\my_layout."* + fi +done + +# vim: set wrap: diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (11).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (11).sh new file mode 100644 index 0000000..cff44bf --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (11).sh @@ -0,0 +1,249 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=IA64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + printf '\nINFO Compiling %s...\n' "$outdir" + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + #"$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + "$msklc\\bin\\i386\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than at rc.exe + #"$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 -DWINVER=x5 -D_WIN32_IE=x5 -MD -c -Zp8 -Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Z7 -Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + # FIXME -Gz (x86 only) + # FIXME -Gm + "$p\\cl.exe" "-I$msklc\\inc" -nologo -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0500 -D_WIN32_IE=0x0500 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox -Fo"$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + # FIXME -noentry will probably disable main(); we need main() though + # -section:init,d might have deleted it :( + #"$p\\link.exe" -nologo -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:0x04,0x01 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + # FIXME -merge:.rdata=.data + # FIXME -SECTION:INIT,d + # LINK : warning LNK4039: section 'INIT' specified with /SECTION option does not exist + "$p\\link.exe" "-LIBPATH:$msklc\\lib\\$libdir" "-MACHINE:$machine" -nologo -noentry -OPT:REF -OPT:ICF -dll "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-DEF:${kbdname}.def" "-OUT:$outdir\\${kbdname}.dll" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" + + if [ -n "$(ls -1 "$TEMP_WIN\\my_layout."* 2>/dev/null)" ]; then + rm "$TEMP_WIN\\my_layout."* + fi +done + +# vim: set wrap: diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (12).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (12).sh new file mode 100644 index 0000000..84a4efe --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (12).sh @@ -0,0 +1,255 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 +readonly TMPDIR_WIN="$(cmd.exe /c "echo %TEMP%")" + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken automatically into account as it should + readonly t="$(mktemp -p "$TMPDIR_WIN" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR_WIN" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | + sed -r 's|^[^=]+=[^0-9]*([0-9]+).*|\1|')))" -ne 0 \ + -o "$c" -le 0 ]; then + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + +# FIXME +# INFO Waiting 10s... Keine Instanzen verf▒gbar. +# 9s... Keine Instanzen verf▒gbar. +# 8s... Keine Instanzen verf▒gbar. + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME avoid collision with the default MSKLC compile directory +readonly dockbd="$USERPROFILE\\documents\\$kbdname" +if [ -e "$dockbd" ]; then + mv "$dockbd" "${dockbd}-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry (for VBS)? +# FIXME open it with a different DLL directory than \Userprofile\Documents +"$msklc/MSKLC.exe" "$layoutpath\\${kbdname}.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN_PREFIX="$(cmd.exe /c "echo %TEMP%")\\my_layout" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # FIXME + # 32bit on 64bit systems +# if [ "$idx" -eq 0 ]; then +# idx=$((idx +1)) +# defwow64=-DBUILD_WOW6432 +# outdir=wow64 +# else + outdir=i386 +# fi + ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=amd64 + fi + #outdir=amd64 + ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=IA64 + subsys_native_ver=5.02 + outdir=ia64 + ;; + esac + + printf '\nINFO Compiling DLL for %s...\n' "$outdir" + + # make traps local + ( + trap "rm -f '${TEMP_WIN_PREFIX}.res' '${TEMP_WIN_PREFIX}.obj'" \ + INT HUP TERM EXIT RETURN + + "$msklc\\bin\\i386\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "${TEMP_WIN_PREFIX}.res" "${kbdname}.rc" + + # FIXME -Gz (x86 only) + "$p\\cl.exe" -nologo -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox "-I$msklc\\inc" -Fo"${TEMP_WIN_PREFIX}.obj" "${kbdname}.c" + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + "$p\\link.exe" "-LIBPATH:$msklc\\lib\\$libdir" "-MACHINE:$machine" -nologo -noentry -OPT:REF -OPT:ICF -dll "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-DEF:${kbdname}.def" "-OUT:$outdir\\${kbdname}.dll" "${TEMP_WIN_PREFIX}.res" "${TEMP_WIN_PREFIX}.obj" + ) +done + +# vim: set wrap: diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (2).cmd b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (2).cmd new file mode 100644 index 0000000..8e9bab9 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (2).cmd @@ -0,0 +1,258 @@ +@rem http://steve-jansen.github.io/guides/windows-batch-scripting/index.html + +@rem disable the default echoing of every executed command +@echo off + +rem adds setlocal, chdir, ... (nonexistent before cca Win2000) +setlocal enableextensions +rem make all variables local solely to this batch +setlocal +rem treat string !abc! as a variable and expand it each time it's +rem accessed (unlike %abc% which gets expanded only once while parsing +rem a block in parenthesis) +setlocal enabledelayedexpansion + +rem FIXME c:\users\jpa\desktop\win\gerdltgt\make_pkg.cmd + +rem https://stackoverflow.com/a/26079981 +rem prevent interpretation for the first time +goto :endtrim +rem :trim ... +:trim + setlocal + if "%~1"=="" set emsg=%%1 != "" + if not "%emsg%"=="" ( + echo ERR failed assert in %0 %emsg% >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set x=%* + for /f "tokens=1*" %%a in ("!x!") do endlocal & set %~1=%%b + exit /b +:endtrim + +rem double quotes are not allowed in paths => we can safely remove them +set ccline=%CMDCMDLINE:"=% +set cspec=%COMSPEC:"=% +call :trim ccline %ccline% + +set msklc=C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4 + +rem argument 0 (full path with file name of this script) +set layoutpath=%~dp0 +rem remove trailing backslash (otherwise the "basename" trick doesn't work) +set layoutpath=%layoutpath:~0,-1% +rem basename +for %%_ in ("%layoutpath%") do set kbdname=%%~n_ + +if not exist "%msklc%" ( + echo ERR Dir "%msklc%" not found. Is MSKLC installed? >&2 + rem wait for user input + rem (can't use %CMDCMDLINE%, because it doesn't work when double clicked) + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + rem /b exits the batch, not the cmd.exe process + exit /b 1 +) + +for %%f in ( + "%layoutpath%\%kbdname%.c" + "%layoutpath%\%kbdname%.def" + "%layoutpath%\%kbdname%.h" + "%layoutpath%\%kbdname%.klc" + "%layoutpath%\%kbdname%.rc") do ( + if not exist %%f ( + echo ERR %%f >&2 + echo ERR ^^^^^^File not found (the file name without >&2 + echo ERR extension must be the same as its parent directory^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 + ) +) + +rem switch all processing of octets to UTF-8 (useful e.g. for "for /f ...") +rem note: wrongly looking characters on stdout are just a font issue +rem note: switching to non-ANSI codepage draws find, more, ... unusable +rem chcp 65001 + +set productname= +for /f "usebackq tokens=1,2*" %%a in ("%layoutpath%\%kbdname%.klc") do ( + if "%%a"=="KBD" ( + if "%%b"=="%kbdname%" ( + set productname=%%~c + goto :endfor00 + ) + ) +) +:endfor00 +if "%productname%"=="" ( + echo ERR Could not parse keyboard description from "%kbdname%.klc" >&2 + echo ERR Try converting it to ANSI 850 or UTF-16 or UTF-8 ( >&2 + echo ERR disregarding whether with BOM or not^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 +) + +rem is_installed +goto :endis_installed +:is_installed + setlocal + if "%~1"=="" set emsg=%%1 != "" + if "%~2"=="" set emsg=%%2 != "" + if "%~3"=="" set emsg=%%3 != "" + if not "%~4"=="" set emsg=number_of_arguments = 3 + if not "%emsg%"=="" ( + echo ERR failed assert in %0 (%emsg%^) >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set found=0 + set guid32= + + rem list all installed apps: wmic product get name + for /f "tokens=1" %%a in ( + 'wmic product where name^="%~3" get IdentifyingNumber 2^> NUL') do ( + if "!found!" equ "1" ( + set guid32=%%a + goto :endfor01 + ) + if "%%a"=="IdentifyingNumber" ( + rem at least one such app is installed + set found=1 + ) + ) + :endfor01 + + rem can't use %errorlevel% because it gets inconveniently overwritten + endlocal & set "%~1=%found%" & set "%~2=%guid32%" + exit /b +:endis_installed + +echo INFO Checking if installed: "%productname%" + +call :is_installed found guid32 "%productname%" +echo FIXME DEBUGguid32=%guid32% +if /i "%found%" neq "0" ( + rem the kbd uninstaller sometimes leaves shareddlls entries in registry + rem the kbd uninstaller leaves some dll files even if SharedDlls is 0 + +rem CreateObject^( "Shell.Application" ^).ShellExecute ^ +rem "wmic", "product where IdentifyingNumber=""%guid32%"" call uninstall", "", "runas", 1 :^ + echo on error resume next :^ +CreateObject^( "Wscript.Shell" ^).Run ^ + "wmic product where IdentifyingNumber=""%guid32%"" call uninstall", 1, true :^ +const hklm = ^&H80000002 :^ +set reg = GetObject^( ^ + "winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv" ^) :^ +set fs = createobject^( "Scripting.FileSystemObject" ^) :^ +for each s in array^( ^ + "C:\Windows\System32\%kbdname%.dll", ^ + "C:\Windows\SysWOW64\%kbdname%.dll" ^) :^ + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s :^ + fs.DeleteFile s, true :^ +next :^ +fs.DeleteFile "%temp%\marker.txt", true > "%temp%\elevated.vbs" + + rem FIXME how will this work if the current account will not + rem have admin rights? will there be any issues with password? + rem https://stackoverflow.com/a/23825726 + echo on error resume next :^ +set fs = createObject^( "Scripting.FileSystemObject" ^) :^ +fs.createTextFile^( "%temp%\marker.txt" ^) :^ +createObject^( "Shell.Application" ^).ShellExecute ^ + "cscript", "%temp%\elevated.vbs", "", "runas", 1 :^ +x = 600 :^ +do while fs.fileExists^( "%temp%\marker.txt" ^) :^ + if x ^< 0 then : exit do : end if :^ + wscript.sleep 100 :^ + x = x -1 :^ +loop > "%temp%\elevate.vbs" + + echo INFO Uninstalling "%productname%" + + "%temp%\elevate.vbs" + rem del /f /q "%temp%\elevate.vbs" > NUL + rem del /f /q "%temp%\elevated.vbs" > NUL + + rem we can't read stdout nor any return values from elevated processes through pipe + rem (we could read a file, but checking again is the safest possible method) + call :is_installed found _ "%productname%" + if /i "%found%" neq "0" ( + echo ERR Can't uninstall the kbd layout. >&2 + echo ERR Please do it manually and re-run this script. >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) +) +:endif00 + +if exist "%userprofile%\documents\%kbdname%" ( + rem removes all files recursively (does leave all directories in place) + del /f /s /q "%userprofile%\documents\%kbdname%" > NUL + rem removes all empty directories recursively + rmdir /s /q "%userprofile%\documents\%kbdname%" > NUL +) + +echo INFO >&2 +echo INFO Instructions for the "Keyboard Layout Creator": >&2 +echo INFO 1. click "Project" in menu -^> "Build DLL and Setup Package" >&2 +echo INFO 2. click "No" to disable viewing of "KeyboardVerify.log" >&2 +echo INFO 3. click "No" to disable opening of the Installer package directory >&2 +echo INFO 4. close the window of the "Keyboard Layout Creator" >&2 +echo INFO >&2 + +rem MSKLC will correctly generate all the install and setup files +rem "pipe to more" trick to wait for closing +"%msklc%\MSKLC.exe" "%layoutpath%\%kbdname%.klc" | more + +if exist "%userprofile%\Documents\KeyboardVerify.log" ( + del /f /q "%userprofile%\Documents\KeyboardVerify.log" > NUL +) +rem FIXME +pause +exit /b 1 + +rem recompile just the DLLs (the rest is prepared from MSKLC) +rem x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +for %%p in ( + "%msklc%\bin\i386" + "%msklc%\bin\i386" + "%msklc%\bin\i386\amd64" + "%msklc%\bin\i386\ia64") do ( + if %%p=="%msklc%\bin\i368" ( + echo howk11 + rem the second iteration is the same compiler, but a wow64 binary + if "!outdir!"=="i386" ( + set defwow64=-DBUILD_WOW6432 + set outdir=wow64 + ) else ( + set outdir=i386 + ) + ) + if %%p=="%msklc%\bin\i368\amd64" ( + echo howk 1100 + set outdir=amd64 + ) + if %%p=="%msklc%\bin\i368\ia64" set outdir=ia64 + + echo INFO Compiling layout "!outdir!\%kbdname%.dll" >&2 + + echo howk22 + + rem FIXME call this once for all architectures? + rem %%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "%%p\rc.exe" -r "-i%msklc%\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 "%layoutpath%\%kbdname%.rc" + + rem %%p\cl.exe -nologo -I%msklc%\inc -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 %defwow64% /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs %TEMP%/my_layout.obj "%layoutpath%\%kbdname%.c" + + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text +) + +echo INFO Success! Find the kbd layout in: >&2 +echo INFO %userprofile%\Documents\%kbdname% >&2 +rem FIXME the condition is wrong - bad variables? +if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + +rem vim: set wrap: diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (2).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (2).sh new file mode 100644 index 0000000..f9a3200 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (2).sh @@ -0,0 +1,184 @@ +#!/bin/sh + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver without the last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + readonly f="$TMP/elevate.vbs" + readonly f2="$TMP/wmic.cmd" + readonly f2_win='%TMP%\wmic.cmd' + # VBS needs double quotes quoted by putting them twice + readonly f2_vbs='%TMP%\wmic.cmd' + readonly f2log="${f2}.log" + readonly f2log_win="${f2_win}.log" + #readonly p="$(printf %s "$productname_quoted" | sed -r 's|"|""|g')" + + #printf '%s\n%s\n%s\n%s\n%s\n' "$f" "$f2" "$f2log" "$productname_quoted" "$p" + + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2_vbs"'","","","runas",1' > "$f" + printf %s "wmic product where name=$productname_quoted call uninstall > $f2log_win" > "$f2" + + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME cscript wscript + #wscript "$f" + #rm -f "$f" "$f2" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$f2log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$f2log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + + # FIXME wmic does not remove it + for f in "C:/Windows/System32/$kbdname" "C:/Windows/SysWOW64/$kbdname"; do + # FIXME + #[ -e "$f" ] && rm -f "$f" + [ -e "$f" ] && printf 'DEBUG rm -f %s\n' "$f" || true + done + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + # FIXME change "-l 409" to the language in klc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 409"$(grep -E '^LOCALEID' "$layoutpath/${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" /fo "${TEMP}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP/my_layout."* +} diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (3).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (3).sh new file mode 100644 index 0000000..15aafa8 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (3).sh @@ -0,0 +1,198 @@ +#!/bin/sh + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver without the last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || return 1 + readonly t="$(mktemp run_elevated.XXXXXX "$TMP/elevate.vbs")" + #trap 'rm -f "$t"' int term hup +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + readonly f="$TMP/elevate.vbs" + readonly f2="$TMP/wmic.cmd" + readonly f2_win='%TMP%\wmic.cmd' + # VBS needs double quotes quoted by putting them twice + readonly f2_vbs='%TMP%\wmic.cmd' + readonly f2log="${f2}.log" + readonly f2log_win="${f2_win}.log" + #readonly p="$(printf %s "$productname_quoted" | sed -r 's|"|""|g')" + + #printf '%s\n%s\n%s\n%s\n%s\n' "$f" "$f2" "$f2log" "$productname_quoted" "$p" + + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2_vbs"'","","","runas",1' > "$f" + printf %s "wmic product where name=$productname_quoted call uninstall > $f2log_win" > "$f2" + + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME cscript wscript + #cscript "$f" + #rm -f "$f" "$f2" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$f2log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$f2log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + + # FIXME wmic does not remove it + # FIXME needs elevation + for f in "C:/Windows/System32/$kbdname" "C:/Windows/SysWOW64/$kbdname"; do + # FIXME + #[ -e "$f" ] && rm "$f" + [ -e "$f" ] && printf 'DEBUG rm -f %s\n' "$f" || true + done + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP/my_layout."* +} diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (4).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (4).sh new file mode 100644 index 0000000..c9f3ef9 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (4).sh @@ -0,0 +1,208 @@ +#!/bin/sh + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver without the last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + readonly t="$(mktemp run_elevated.XXXXXXXXXXXXXXXX).vbs" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + cscript "$t" +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps only sometimes accept forward slashes + readonly a="$(printf %s "$TMP/app.cmd" | sed -r 's|/|\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + # FIXME + printf '%s\n' "DEBUG run_elevated $a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME wmic does not remove it +cat > "$a" </dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP/my_layout."* +} diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (5).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (5).sh new file mode 100644 index 0000000..cf98187 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (5).sh @@ -0,0 +1,222 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + readonly t="$(mktemp run_elevated.XXXXXXXXXXXXXXXX).vbs" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + cscript "$t" +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\|g').cmd" + readonly a_log="${a}.log" + + # make traps local + ( + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + # FIXME + printf '%s\n' "DEBUG run_elevated $a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +# sntnh +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" +readonly TEMP_WIN="$(printf %s "$TEMP" | sed -r 's|/|\|g')" +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP_WIN}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP_WIN}\\my_layout.res" "${TEMP_WIN}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP_WIN/my_layout."* +} diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (6).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (6).sh new file mode 100644 index 0000000..cf98187 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (6).sh @@ -0,0 +1,222 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + readonly t="$(mktemp run_elevated.XXXXXXXXXXXXXXXX).vbs" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + cscript "$t" +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\|g').cmd" + readonly a_log="${a}.log" + + # make traps local + ( + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + # FIXME + printf '%s\n' "DEBUG run_elevated $a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +# sntnh +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" +readonly TEMP_WIN="$(printf %s "$TEMP" | sed -r 's|/|\|g')" +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP_WIN}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP_WIN}\\my_layout.res" "${TEMP_WIN}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP_WIN/my_layout."* +} diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (7).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (7).sh new file mode 100644 index 0000000..51cba02 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (7).sh @@ -0,0 +1,225 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' < "$layoutpath\\${kbdname}.klc" | grep -E '^[[:blank:]]*localeid' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +readonly TEMP_WIN="$(printf %s "$TEMP" | sed -r 's|/|\\|g')" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + +#FIXME +#Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0 +#Copyright (C) Microsoft Corporation. All rights reserved. +#fatal error RC1107: invalid usage; use RC /? for Help + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP_WIN}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP_WIN}\\my_layout.res" "${TEMP_WIN}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP_WIN/my_layout."* +done diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (8).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (8).sh new file mode 100644 index 0000000..efa2a7f --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (8).sh @@ -0,0 +1,236 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + "$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + printf '\nHOWK00\n\n' + + # FIXME WINVER and WIN32_IE higher than at rc.exe + "$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + printf '\nHOWK11\n\n' + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "$p\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + printf '\nHOWK22\n\n' + + rm "$TEMP_WIN\\my_layout."* +done diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (9).sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (9).sh new file mode 100644 index 0000000..a45afd3 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie (9).sh @@ -0,0 +1,252 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=X64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + printf 'INFO Compiling %s...\n' "$outdir" + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + #"$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + "$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + printf '\nHOWK00\n\n' + + # FIXME WINVER and WIN32_IE higher than at rc.exe + #"$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 -DWINVER=x5 -D_WIN32_IE=x5 -MD -c -Zp8 -Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Z7 -Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + # FIXME -Gz (x86 only) + # FIXME -Gm + "$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0500 -D_WIN32_IE=0x0500 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox -Fo"$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + printf '\nHOWK11\n\n' + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + # FIXME -noentry will probably disable main(); we need main() though + # -section:init,d might have deleted it :( + #"$p\\link.exe" -nologo -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:0x04,0x01 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + # FIXME -SECTION:INIT,d -noentry + # FIXME -merge:.rdata=.data + "$p\\link.exe" "-machine:$machine" -nologo -OPT:REF -OPT:ICF -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-def:${kbdname}.def" "-out:$outdir\\${kbdname}.dll" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" + + printf '\nHOWK22\n\n' + + [ -n "$(ls -1 "$TEMP_WIN\\my_layout."*)" ] && rm "$TEMP_WIN\\my_layout."* +done + +# vim: set wrap: diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie.sh b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie.sh new file mode 100644 index 0000000..2b8ba5c --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg - Kopie.sh @@ -0,0 +1,157 @@ +#!/bin/sh + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" + +[ -x "$msklc" ] || { + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +} +for f in \ + "$layoutpath/${kbdname}.C" \ + "$layoutpath/${kbdname}.DEF" \ + "$layoutpath/${kbdname}.H" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.RC"; do + [ -r "$f" ] || { + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + } +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +[ -z "$productname_quoted" ] && { + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +} + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# list all installed apps: wmic product get name +[ -n "$(wmic product where name="$productname_quoted")" ] && { + readonly f="$TMP/elevate.vbs" + readonly f2="$TMP/wmic.cmd" + readonly f2_win='%TMP%\wmic.cmd' + # VBS needs double quotes quoted by putting them twice + readonly f2_vbs='%TMP%\wmic.cmd' + readonly f2log="${f2}.log" + readonly f2log_win="${f2_win}.log" + #readonly p="$(printf %s "$productname_quoted" | sed -r 's|"|""|g')" + + #printf '%s\n%s\n%s\n%s\n%s\n' "$f" "$f2" "$f2log" "$productname_quoted" "$p" + + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2_vbs"'","","","runas",1' > "$f" + printf %s "wmic product where name=$productname_quoted call uninstall > $f2log_win" > "$f2" + + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME cscript wscript + #wscript "$f" + #rm -f "$f" "$f2" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + [ "$(($(grep -E ReturnValue "$f2log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ] && { + rm -f "$f2log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + } + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break + c=$((c-1)) + done + echo + + # FIXME wmic does not remove it + for f in "C:/Windows/System32/$kbdname" "C:/Windows/SysWOW64/$kbdname"; do + # FIXME + #[ -e "$f" ] && rm -f "$f" + [ -e "$f" ] && printf 'DEBUG rm -f %s\n' "$f" + done + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +} + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +printf '%s\n' "WARN Please do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. click "Project" in menu -> "Build DLL and Setup Package" +INFO 2. click "No" to disable viewing of "KeyboardVerify.log" +INFO 3. click "No" to disable opening of the Installer package directory +INFO 4. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? +[ -e "${USERPROFILE}/documents/$kbdname" ] && \ + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" + +exit 1 + +"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +[ -e "$userprofile/Documents/KeyboardVerify.log" ] && \ + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i368") + # 32bit for 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i368/amd64") outdir=amd64 ;; + "$msklc/bin/i368/ia64") outdir=ia64 ;; + esac + + # FIXME $outdir not used + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -r "-i${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 "${layoutpath}\\${kbdname}.rc" + + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${layoutpath}\\${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj-merge:.edata=.data" -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text +} diff --git a/platform/win/source-20180703-gerdLTGT/make_pkg.cmd b/platform/win/source-20180703-gerdLTGT/make_pkg.cmd new file mode 100644 index 0000000..8e9bab9 --- /dev/null +++ b/platform/win/source-20180703-gerdLTGT/make_pkg.cmd @@ -0,0 +1,258 @@ +@rem http://steve-jansen.github.io/guides/windows-batch-scripting/index.html + +@rem disable the default echoing of every executed command +@echo off + +rem adds setlocal, chdir, ... (nonexistent before cca Win2000) +setlocal enableextensions +rem make all variables local solely to this batch +setlocal +rem treat string !abc! as a variable and expand it each time it's +rem accessed (unlike %abc% which gets expanded only once while parsing +rem a block in parenthesis) +setlocal enabledelayedexpansion + +rem FIXME c:\users\jpa\desktop\win\gerdltgt\make_pkg.cmd + +rem https://stackoverflow.com/a/26079981 +rem prevent interpretation for the first time +goto :endtrim +rem :trim ... +:trim + setlocal + if "%~1"=="" set emsg=%%1 != "" + if not "%emsg%"=="" ( + echo ERR failed assert in %0 %emsg% >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set x=%* + for /f "tokens=1*" %%a in ("!x!") do endlocal & set %~1=%%b + exit /b +:endtrim + +rem double quotes are not allowed in paths => we can safely remove them +set ccline=%CMDCMDLINE:"=% +set cspec=%COMSPEC:"=% +call :trim ccline %ccline% + +set msklc=C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4 + +rem argument 0 (full path with file name of this script) +set layoutpath=%~dp0 +rem remove trailing backslash (otherwise the "basename" trick doesn't work) +set layoutpath=%layoutpath:~0,-1% +rem basename +for %%_ in ("%layoutpath%") do set kbdname=%%~n_ + +if not exist "%msklc%" ( + echo ERR Dir "%msklc%" not found. Is MSKLC installed? >&2 + rem wait for user input + rem (can't use %CMDCMDLINE%, because it doesn't work when double clicked) + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + rem /b exits the batch, not the cmd.exe process + exit /b 1 +) + +for %%f in ( + "%layoutpath%\%kbdname%.c" + "%layoutpath%\%kbdname%.def" + "%layoutpath%\%kbdname%.h" + "%layoutpath%\%kbdname%.klc" + "%layoutpath%\%kbdname%.rc") do ( + if not exist %%f ( + echo ERR %%f >&2 + echo ERR ^^^^^^File not found (the file name without >&2 + echo ERR extension must be the same as its parent directory^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 + ) +) + +rem switch all processing of octets to UTF-8 (useful e.g. for "for /f ...") +rem note: wrongly looking characters on stdout are just a font issue +rem note: switching to non-ANSI codepage draws find, more, ... unusable +rem chcp 65001 + +set productname= +for /f "usebackq tokens=1,2*" %%a in ("%layoutpath%\%kbdname%.klc") do ( + if "%%a"=="KBD" ( + if "%%b"=="%kbdname%" ( + set productname=%%~c + goto :endfor00 + ) + ) +) +:endfor00 +if "%productname%"=="" ( + echo ERR Could not parse keyboard description from "%kbdname%.klc" >&2 + echo ERR Try converting it to ANSI 850 or UTF-16 or UTF-8 ( >&2 + echo ERR disregarding whether with BOM or not^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 +) + +rem is_installed +goto :endis_installed +:is_installed + setlocal + if "%~1"=="" set emsg=%%1 != "" + if "%~2"=="" set emsg=%%2 != "" + if "%~3"=="" set emsg=%%3 != "" + if not "%~4"=="" set emsg=number_of_arguments = 3 + if not "%emsg%"=="" ( + echo ERR failed assert in %0 (%emsg%^) >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set found=0 + set guid32= + + rem list all installed apps: wmic product get name + for /f "tokens=1" %%a in ( + 'wmic product where name^="%~3" get IdentifyingNumber 2^> NUL') do ( + if "!found!" equ "1" ( + set guid32=%%a + goto :endfor01 + ) + if "%%a"=="IdentifyingNumber" ( + rem at least one such app is installed + set found=1 + ) + ) + :endfor01 + + rem can't use %errorlevel% because it gets inconveniently overwritten + endlocal & set "%~1=%found%" & set "%~2=%guid32%" + exit /b +:endis_installed + +echo INFO Checking if installed: "%productname%" + +call :is_installed found guid32 "%productname%" +echo FIXME DEBUGguid32=%guid32% +if /i "%found%" neq "0" ( + rem the kbd uninstaller sometimes leaves shareddlls entries in registry + rem the kbd uninstaller leaves some dll files even if SharedDlls is 0 + +rem CreateObject^( "Shell.Application" ^).ShellExecute ^ +rem "wmic", "product where IdentifyingNumber=""%guid32%"" call uninstall", "", "runas", 1 :^ + echo on error resume next :^ +CreateObject^( "Wscript.Shell" ^).Run ^ + "wmic product where IdentifyingNumber=""%guid32%"" call uninstall", 1, true :^ +const hklm = ^&H80000002 :^ +set reg = GetObject^( ^ + "winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv" ^) :^ +set fs = createobject^( "Scripting.FileSystemObject" ^) :^ +for each s in array^( ^ + "C:\Windows\System32\%kbdname%.dll", ^ + "C:\Windows\SysWOW64\%kbdname%.dll" ^) :^ + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s :^ + fs.DeleteFile s, true :^ +next :^ +fs.DeleteFile "%temp%\marker.txt", true > "%temp%\elevated.vbs" + + rem FIXME how will this work if the current account will not + rem have admin rights? will there be any issues with password? + rem https://stackoverflow.com/a/23825726 + echo on error resume next :^ +set fs = createObject^( "Scripting.FileSystemObject" ^) :^ +fs.createTextFile^( "%temp%\marker.txt" ^) :^ +createObject^( "Shell.Application" ^).ShellExecute ^ + "cscript", "%temp%\elevated.vbs", "", "runas", 1 :^ +x = 600 :^ +do while fs.fileExists^( "%temp%\marker.txt" ^) :^ + if x ^< 0 then : exit do : end if :^ + wscript.sleep 100 :^ + x = x -1 :^ +loop > "%temp%\elevate.vbs" + + echo INFO Uninstalling "%productname%" + + "%temp%\elevate.vbs" + rem del /f /q "%temp%\elevate.vbs" > NUL + rem del /f /q "%temp%\elevated.vbs" > NUL + + rem we can't read stdout nor any return values from elevated processes through pipe + rem (we could read a file, but checking again is the safest possible method) + call :is_installed found _ "%productname%" + if /i "%found%" neq "0" ( + echo ERR Can't uninstall the kbd layout. >&2 + echo ERR Please do it manually and re-run this script. >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) +) +:endif00 + +if exist "%userprofile%\documents\%kbdname%" ( + rem removes all files recursively (does leave all directories in place) + del /f /s /q "%userprofile%\documents\%kbdname%" > NUL + rem removes all empty directories recursively + rmdir /s /q "%userprofile%\documents\%kbdname%" > NUL +) + +echo INFO >&2 +echo INFO Instructions for the "Keyboard Layout Creator": >&2 +echo INFO 1. click "Project" in menu -^> "Build DLL and Setup Package" >&2 +echo INFO 2. click "No" to disable viewing of "KeyboardVerify.log" >&2 +echo INFO 3. click "No" to disable opening of the Installer package directory >&2 +echo INFO 4. close the window of the "Keyboard Layout Creator" >&2 +echo INFO >&2 + +rem MSKLC will correctly generate all the install and setup files +rem "pipe to more" trick to wait for closing +"%msklc%\MSKLC.exe" "%layoutpath%\%kbdname%.klc" | more + +if exist "%userprofile%\Documents\KeyboardVerify.log" ( + del /f /q "%userprofile%\Documents\KeyboardVerify.log" > NUL +) +rem FIXME +pause +exit /b 1 + +rem recompile just the DLLs (the rest is prepared from MSKLC) +rem x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +for %%p in ( + "%msklc%\bin\i386" + "%msklc%\bin\i386" + "%msklc%\bin\i386\amd64" + "%msklc%\bin\i386\ia64") do ( + if %%p=="%msklc%\bin\i368" ( + echo howk11 + rem the second iteration is the same compiler, but a wow64 binary + if "!outdir!"=="i386" ( + set defwow64=-DBUILD_WOW6432 + set outdir=wow64 + ) else ( + set outdir=i386 + ) + ) + if %%p=="%msklc%\bin\i368\amd64" ( + echo howk 1100 + set outdir=amd64 + ) + if %%p=="%msklc%\bin\i368\ia64" set outdir=ia64 + + echo INFO Compiling layout "!outdir!\%kbdname%.dll" >&2 + + echo howk22 + + rem FIXME call this once for all architectures? + rem %%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "%%p\rc.exe" -r "-i%msklc%\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 "%layoutpath%\%kbdname%.rc" + + rem %%p\cl.exe -nologo -I%msklc%\inc -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 %defwow64% /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs %TEMP%/my_layout.obj "%layoutpath%\%kbdname%.c" + + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text +) + +echo INFO Success! Find the kbd layout in: >&2 +echo INFO %userprofile%\Documents\%kbdname% >&2 +rem FIXME the condition is wrong - bad variables? +if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + +rem vim: set wrap: diff --git a/platform/win/20220624-gerdLTGT/make_pkg.sh b/platform/win/source-20180703-gerdLTGT/make_pkg.sh similarity index 100% rename from platform/win/20220624-gerdLTGT/make_pkg.sh rename to platform/win/source-20180703-gerdLTGT/make_pkg.sh diff --git a/platform/win/20220624-gerdLTGT/map_esc_to_caps_lock.reg b/platform/win/source-20180703-gerdLTGT/map_esc_to_caps_lock.reg similarity index 100% rename from platform/win/20220624-gerdLTGT/map_esc_to_caps_lock.reg rename to platform/win/source-20180703-gerdLTGT/map_esc_to_caps_lock.reg diff --git a/platform/win/source-20180703-gerdLTGT/wow64/gerdLTGT.dll b/platform/win/source-20180703-gerdLTGT/wow64/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..461fd22d092c30dc8bbb9a92267728491336b288 GIT binary patch literal 6656 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 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180703-gerdLTGT/wow64/gerdLTGT.lib b/platform/win/source-20180703-gerdLTGT/wow64/gerdLTGT.lib new file mode 100644 index 0000000000000000000000000000000000000000..dafec1462f87306306832a0432f9764af80d7935 GIT binary patch literal 1766 zcmcIlPfrs;6#wlmqHKsZqDRS+kbsv;mtCZWm?AaWbSb1PCl5pER%ilgv#bZh!7t$V z@aT;T7fxI~K*9$g;cMV~+Zj7(i><*)cILg`yxn=f_h)u$sTS9FU)wL7n+6hB1T}qq}l4@%fImL&!B%KREVUgmAf4h#$D-=BVXMEo8Q zPZ~xxYHWYnncnEAzzPXpl_J*yGHwWGTdB8v^jl z#_uAGPw^xNe;s%wHC{}FG~adO*gEAw>c#b4tzOKuUXD}u*va1Y5~W++NvoH6g>t=o zQ;J-ONdL9 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180817-gerdLTGT.zip b/platform/win/source-20180817-gerdLTGT.zip new file mode 100644 index 0000000000000000000000000000000000000000..fa464c27f4ac332f117c3219c23180135e2f45b5 GIT binary patch literal 109692 zcmagl1CZ#>pCItD-`KWo+qUP8tv9x9+qP}Iv2EKnZ+`#V-Mih|+e=kBj6 z`;%|WO96vG0sOPQWTD9XYv!0#pVvkcyjYv}|(3grc?;KM4JHWWL*~d$T+w)ry5jQi$W@V(SK^bHKu=K7J zcWT2!F!jNkVJjyP%+Qx|3gv15{GYBZMJJ~Hu0A_4#iG64Wk{E@CJoS<)tbS%xvMJ4_~U0ce}F29gMR8;YFhyYeGJomL?QtZCN| zRGBS|jZ`{E>nadLNpdJzX7J!^0TZ0Q1J+O`hVhvmA9}h+49X?h(j8iqk)0bF#I*TX ziLdGGWtQ5-hC|pz#&;)(-KIUX{wjJ@q#}XA@Z!7VbchyqbQ9xkKb(< zaUXRgN@y8^dOAtbGUt4VC*u^1WWvErkE8ZA6)RzlId>#cLX_Sn@167_kP<0~=@itl zIAax=hX;Qmy_KuY|Kg3oax(|$GgCN=fK?3?25|7B@grI;OQLd7s6`TCInc$5g z8W7By^H@v-ds7EN$h5U_@F7k{hG2}LI^nN~L9$7=X)xHKvh)}=Uhvj$xRh~{wvvix zf9MU!SyLu3`(ju~ZbndhR+8XjfNIA?3ey4o1>F0h7v!8Zs=c<%Ryhqb@KEg0)U$3I zkcE`HcwWp`M;kjtM0=(dX+8bMy@XDTM4TAIU@)iv#TP2DyYZa^I{6Io-&Kd;c{VYfB=DZD_>7eB1%PoBysrSPnKIa5 zB?=ssNln$)GM<|RXaLUYf83nY7d4Z2JtlyEwG~&yfuj@3c!5I4W6DEt=O8D|?SgS+ zJWoC7X~sP<1xxJAH+rgp=SjYUQc!h~Gz6t3u^w&2NM8&?60yITSqVyv*{?j8F_rLY zsP`pCq$>OkxKBUj?M;5uZgI+R>vTYUV}jE|J54ZT2>xuI0^&7P0;(XGsX|UFmOGw(!?-i&Gw?4!g5v!(#&wI;r)z#aTU0CE0ocJ3u zg7@fILPs(hNEpPz15XQ!K0MfVat0!v;brcz&BodwB$=3Xl*uteQ(Lp6XyIa^T&C$3 zCm)KR7jJwQX2Rojo`83KOOTt7o21wEQ$}ARD2E9T`YuDRreSOvPSZ}y`8E?TMVIdcF+QyKsB3>qU*))%C51BJPq&V1KfSsAc zJ&G?PB$BO1E`2UrPxrWFn^tHB01!%9DRQD=5lFPKx68gLDN{laMXeJAGpXZ;?l;F{ zTZpy7jM_~^#7xL^lq{%6#Z7e#z9V1`cwD^hkf`hoOKU%D$fiZjnj*MGO^larpdpG6 z4`yJuN5wh;35p^&4R+7qRgG;B{^tyiAOPz!;KP9$$UOZ`u%kp2eQ)UzPOpQZIB7=T z{)_n2b1&bwK==XD+XY>W^~6ynmwi*dLJSfE_Q*jKjUGg=dj81$fa9OYhpV3 zY;Y^2O-$;`p1?Xaj6XS-FT0&S2C`|j^+d6>Md&&=5p7SEIk z0Pi5^5CO>IufNcn_#%A#Z&N(N;rQtoGiXXAgyYoMF;yfAM?}ep;dlDya@4ploDB%qHi{ulF zdQ17>ME^2Ce&F>(#r#QCjQj{Fu0kQw&^PlyQa_CNQt=~$JPelRLU$wZPrET(Nk`z! z8fx+m#S=G1>y?nh*?3r^DDc;OPvmzQL8_N$@1=KU0N|+09Ox^NG7lK+tA7#;jj=Td zA_6@gCgb}B)GNk&O+T-a$$qMc4?3Zw2CK2vEZTilb0^iz*~Ry}Zo*oZgKLzMGlK@S zEO8tGd&n|%r?B^me?-a6V(#8mRX%{&eB_3&b2PePyWG0mKQj8&ylmbgaWNmu~PgH5o zTyBAX=IL(T;O`=fODsq?W2Pb+QLO6&f#+yOt_LgB9aj!D=Gg!yC z?~L6$GRWD?c$<_-#1PeAq)hXCY^b$ z3C2VdlO2%imjOp^#spGQ4yo!8r3BLF8r%eK7C$#{%FRsdS}GtzKtylE>7&Tnfh=<6 z@q-(JB=t~9-b9&=G$bGY=JO+pba_%!DS1&C#<190yM^f;j!jhC`9@aqoT0dC>RXuN zF^hQKH917;=CwA=RXGn!8Ff|Jq99(wKKa7(n-V~%MvHZEU;Tzal!h>3i?F&)lp~-W0cfhd&Ps=PGEn`-AoqD^a#Q$8cHqnE1}csukMLKtC&V?f+oRQhdfq1p1kUP z0nK-TssJ8xIn-}xc22g1B1=LAKKaFz-JcLv2W;LheGMEG|!Cj_Aa zhvlHsvY9`kw^F1ICFi%h1t%(L!72HZD00J_UfAoKL>pzkqkm#;YrCD~ZP%cZfyVig zCPpz85EQ;5ZA2GZIN%%$H$<+qf;G~hYpB-43@k{g5h_0fX3{fLbT?)mEKdE%*R8f} zuC1TzUk_9ywB7FT<>!*RiV&}A;iSNnpf(@a85*N~Ntj>?Hm|1TOD9@P8I^hIX@HV_ zuv~RJ=2)nXtXG#wSMSKq90q-^gU7xg&p%ExoF{mR!L8gIz(#1U zVf*(Hv8BnG$My>NN#L-s@tn(k&hS<4y%jXc zfK^e*=Mtk!NEjErH^q^CH(xUw>INT-2K%aj#t`d$sc_EqeDYd4FbeFcj`Eb=K0xR} z%3eo)%;F|liVTtxynkH9ftOIT>#-h13z<7D8()8g8s_&(Y~dra6ytLAZUK82>8FiL z3bgKNlv7U2NzIEUSC}u|u9iKdv@^@NOw7-*iK%nKgcdyU)N^x93Jf%})5J~O&O+#c z?k<@_;tjB5-i=ukP<_opy$Z(?A!lC4e+0a6mP>giIhptEss z7H>4(5ty%OnTqF9Sy2fwmRZepGGrXKH6MFTIFwq-kECn=xsAQJktQP@>PNUR2?bor zyz9t`S0pEvy4-kmcTQaH-IeH6Z6Uhv4G5~m>K-|FI+!f5990R#L_H zyItY4uZaU-a4zvQ7-A#7QdB$2ZE9lg^+iBA50G^5qxI;|ANqOE04fUN?0To(=Rdg` z)dC0ZKJs`=EY+zBc9Kov>v0ym$3(ZZO2k6%=vjso9U?=AwOK{WacGt0dB zP$f=EC4Hb72iM4irT%e;k+$HZ9li)Xq;v&7X~b)thYl;z%r-Y z#jEBm{9Fe-YSu!iTjrzOYdBr_>$lnhmZR6s%08!LYKrfs&T{AX;F?SdJhsZ7&i1P2 zFCGTwb64AuV;+A$+T?np4`l3YFI&`9vA!C1VAQ$d+O36~_Jft9gN385*gOWfUg+Lk z%c@z|yubg9cPYpP0o>L@*+Glf{W%TExi=l@#Zy#T{)eB%E7N2+YJ`R#g`VIY`*T>=Zp)w<87*XwimB61{! zif|j}uaEl6o!rayh_Gr+s#Wi^F&rPQ-U*%X74<5T>yv0t$*ol(ZF?+ju>S`kW5$(T zVA@LWHPMEs>ld5%_u?(q>Jbk5Z>`J3q$3$Q{Z~i`!-IQZ{AinUb40Xo3(n-{k4ZfQ z!bK0)H4Hw3Yy!d&h%s=O?@_O&VBG2rGd3^|q}FrTF`h?3Zf1*{nN|?-^252?4DHht zrc5}uO1KVYYpjhZmVW-K$VOplm^5*Xz`-`8pb^+dvc}4nV%!sypl?^ftEK6V#Xc1b ze(;kMxbmj+yZS^eR0&+fy!vwi%y+QlyA|z3&2f_4##Y##fJO^#Sp#8Lq7K8c zOVL=z2~3pA-DB2{GS&mH3iAQ=jehd)SIe}XBTv1mq9@wLyISbvJb%1%)CB;7aND}x zFH&6o34Q)0M(jN&`#gN8+OVVr83!z=jLna+L4#8wDUDThR%mEFru(iq-hQm@(*EO< z}W9By+hVL+2j)VashBG$mmwR71 zKy6JTZfA&_YV&tO8DY6wh{yLBd!f_!MF8L)Y)`8)|3=a8?iYsA#1r3vB)#{LnC-~7 z>_(pNB}iG?ppD^mIj0gp6hoByAWKD3=*{D#bCdUWWp-~RQUos7fK7C4MAm{}mS%vq zPR{h0Py_`y$!dd>IfFhmqn@L>K3}w) zRQ%7*SFX^DrR#LJL67IgOFZc7xVFPwLJ*_f^M<=|wC`X4S*z#=Nsw#d003s00RV9S zTdn#Rq>0hf(^^^?{*OYXHEF*;64y;7crE|;6Qj8b&lj1byy}!y*dI~z!_r?_YQKpE zUm=km2oM%PvOwc{XozD-S-WBIs^L=rp8E5{$OfEHJDLmMiXpAf4sC!hgrJZmX>2(I zpLb?vq4$*^(8Hd z+*M_7x-d6{M%wk}6@x7UR>9*LhoY*;c7Xdn87o}q{$_n0oI{4o6!XuR5Bp;sz89Z~C3!FE|xa7o_J*{IYaJp5@u=)AZR|772 zU(;~dDW43V*0}DWme-iXxqqvc?_+&hfX{HFqps@4=9S*J=TE`U`wtqwv1@U zaBrX2iD{dSrWgUwtYt_P0t{6XHeHcCC$`IsW?(DqUtwYy$lHgjGd+C}FY~D?e{V8A z^lubIUcgWI2bbI)@K4|qvRoe!FF0keE}&1Q6J4Vgx<6%eAO-XVuMp*aumWPaoG0jo zzTO~j3{FzNpu`{@f!u-50;&aQW-v+tF@4u^TXL@hywfkgD9pec!P5h>`ITm9MBvE* z+VIcrFivuoSZ4TnVqr1;VC0b;VKM#N@sS)8E=?2?ec8O)!PeZ2LTizbDYus#qqh);&nSWOD?_Ga0)vVXVFWIs>ziSD9vJjPfSUmNN`<8#b zrkU&D90&m3cYH@<9PBxUBc6sGih|%^OAblNK9Qb2cIfUsg!p`eCSb(D+KY2yp$bcG z35+skDL?o z1^K>v{rGlSOQxXvQck~LoT@)T=(?-GwL9Ny9L2`+uwG!{ZcWqB-CnRAl0$&A)y7+Y ziI-3bn*1xV6FL@9o_#arQ;2h3uMJ(-Fj%Z><5ib6{KO%=$=FsP$-iW;Z|)%_9!ip+QA-ggA%&SewXQ0$ zmayGmk7sU*d8z&u7$%y@rSfSfPB~Uw%3TFPIVeaFD(epNhJUP@a*(f0oZK zajwM@HWd7#^%Waau6GUZhx?O0bIMP^J?=~m3&*(&JFmE$8inIEL*K|czatoAQ2mB& z|)=d_9AB>M=+6xBeROHK?|FP~ zJGOXMU@hw@vFsyto*5HK51kNef@DN|F~-S_0>vs4?9$Sia|RRbEjH;?ummf0H5{h^ z@2JAV$VYpV+tp62J0Kxq%#b;$M(9v#xnh z)=Y(CT=g~WM%BO`Jy+CkCIqor zjl*%`P0XhC3GAo0O6r_|ep6ta3}1olfya$sk*+mOjeB3-**JORCG*0VNT1>^IPckT z;;mR0VlgZ$rQ6#d>bo>~@^P0zuYtf&RyhvHtDXhRfvAJD2n?!+BDA9%clq?k>JFrn zXh}=MUuOi0ft0^Tm5|Rvku?1_sHJ7mkB8ek|<^F1H z@LS?5@h#ML%R-SPX+9uHpb|TIG|5{oqY(X>M^gDC1{^?!97mX0qt3>6!2CiaN69uO z*{BaB>*vw!Up0Yj-DIAUH%)yjg2gKXSsWS5V-dSM8??vFIAliT;H(0T6_O9A#CD%1 za2p=92g^8wLFCXWh`=e36u+!QPa)y9(ij3YSj!mPX;zn>d?uov9<>K|YxK)aQ`Hy^ zcrRfdJyAxYDqXe2nv5GAGr>Z7U1j#*o0~M|l-P_PKTq$qqpsb?O_TCd$ta9IgamSW zu*f*q(8kU;ovI?i>v$HHq~WQ=ELtdd0igiSg5vXH=~N<5gF$Es77d_=7@n!}!*+q? z`)ztH|8_l%y)Nq4sckEwVlStr!uZ&bq^7W7cP324w%cZ!Mj6wxM^`t=RBq61XqD7V zxE3xqLM(k3A5TPvU&nhOn%}G%TAJwQu7U6nFL#G*tWBJ+h7a^n9PJ7FNCi@CTE`*f ziZVzk>F5r~`toKrBefS9e@hN6cTGYfrvMwFjEB-2W2Tm;b7nW%HxB~%4C#_dgvN;$0g-F#SYX} zvulEyyQ?ReI}YuBcM{0;MyXAyu*h|Ja4e@TZJ$Q)Db2M^jzPo{(|9y`w#W#Z%x7${ zsca(UXHXecrR1WCPb_1+BpP-sDGh;Pqt zjEIL_8WV?c(P9Cc@-P-%TXbLP0a6lH-SA1ex(KLi&pMScA-u_YMmk=(($@_bzJzs` zhU=H0i4>9-3FKBPgbZ~MZLA)2cI}xO(?hXgBC0OmM>0yAHUz3^S7O}?&&;6E0?hdf z%U@ogupv|ryhOYTcg5iK=I!h2JUAz7B4@voNj7wR+B%rRyM0Ndzw^5UvGL7?dIBHq z*QZ-sT$@8tY6It|2+xpUCg&vv5xhaZh+}d_Pl!;;k8w^{MdKhY_tR-fElpxcg6!}49AYX?jwMSsQ|E8Ft zO{Z!nibxAHy5Nv{$Pb#m?zwAYuq@j%=+{KC({E5!(f+f<36G|`S8GLM$lBKi#sm;u?Xb5_)cyt*4T&Q5sfHKOMB_toVnDIH&U`UuzWIef zWPtoeRJ21AR;75VJ*l%lCEyZqbNYFyZsgpqv=q4QEpfm-arIyW_tBJ~|&eK_AE-@4aBIhL%=y6-dM_5i%R<>hGgniRQZ z4aAH)62Rmkvt3qa{;-;|6hOjf=F!#lDE6Nn;6Y{B3K$3gU=joX0O$Yh06$qew2DIi z69W_}>qP9)BYUBJz@|iEW*Va<2Q4irPBhLf_4oQ4SuN;ElSFZTz0348_MiQ= zfs(Pm;(4wJ;ia$Jc~A7WGuq=n9A7(e#$DUtt(oN|mPL2-yMEozUH7XC$-?xrc=RZB zZM4P&d$K}qnLyL(!!n$Y+L|;2IyrX=TQ3!j1q=6(*A9lr)89w%k;V}py4@K1g*;ga zhBI+VpC*?HM@28xv0jJ0eBXrS8x$}L5-Bc0s%kh?MwXnWkTxaz$4+<;wBwadZc45Gh#TAn6kmKN8ab$#Wes? zQC31W554`W?yN1pb2C@3ozU}VMiF1NR4%Km(7l-pvX*rEJDef3nA7k+t@>bHYV7sX zyBb{0_-(70y;~~ zF*(AaB|v67E3F!s&wa*r9P14@aI9VF&5CP?W1$CB$f@=xA%q~o2w1zS5&rR7ukARO zkC^CokdH(z8O80oloOm&yfPx!w%Bfg{V-Pz!?cnr2uIM529_~Ls zS#7JnA`Sn4VfyFE`u_^krv3SdUAJ1&mVWZ92Cfz#07dx1=&A!uTy7xI7moiz+)`Z= zK0{(H5FjmpWJOehcC7Xmw`32i8^a0AvO?~&m?K4 z20;d0iOUI_u6i7k9fyZwK9@x&3-;vgEVZtuM*D zhbgE^^MQcaq}RSn!29HTNX?pTB4d>Yo>De9g9u;tEt-rM`WCn23BnEV;Xa>Am@c(5 zg9FyhkvvudLD%GI-Kr=gehK*?9(6xMx89$mpdBT3=U~{-gdj_q*Gvy)llK|8)JHvz zY8E?fGIyXoNmMDga|cxe+ZC;+^`38(laxpgwq}&ADjTpHH5*4Pucnl%qzxHLH}AyI z{+Uq>NK&0av%D^(!oqhyhx6F7eRYKJko;p)BXN(mKNOm+lP2h39{_38JE+L91*2xq z=edH5ny#5xshVnQI09n4s zGjala1vX^@yJ|pPfL)-!_?L58Phb{6ehJ{raLvRB^o%%vV>g0x0?_cwEx%f>l04c2f+OS`v}UQIba4CmgA{RXx_lzzAP$Z3AJHLd3mp2c7&bSXL92!Sa-K2J+$ zoZ-VkrRsi5P2i)IC?$%^QL_=A4Cfhj9vIQZ|L*x>!}flM`yMkAEyUv>&iVySNOCRq zk1@gh7?a$;8PnbSc1~@hxD?#%#yd_i^`|1NB++;Hr#b6)oQVUXHQ$S;EZIxS^znDk ze6zIME!tdW&6BD~%t?~&W2h8b3C+>Uie*9dZr|j_+f%U}lUul}>;BuyP>OUpr4_C$ zu$VHg@?)UO7ty7<+M#A>77gpC{dvSCck?vCS@J243Q&DAv{VNdF^uMV*6eC%(p2GB zm6N9Fq49{Rl-fly(U&!G1=q4zoUh>C1_QzEP4g%4Wug5G>=_-yfm*-g-y{1{n|@0jCPiAgG-Tl9LU7g#3e|iZ*e?VrQl3K#a**N0Hx7l4yAm@wz&{-#>h zb5L&dwxpDHj?~%8AK$i|yX(6gE8?Y#_JnkY2hNEWkOFXqW3(S#$E?Ml2A8Adm%u zPWY|ru1;;G@Qdh;M&E@4Sf!B%Dh23#AGe{ceb^vH7M@0dC|xPk?5%l2jjal_9y>a3 zchXZeSd5H(CY#=)l|1uQaX4oS8U-~!TDY(~+za_Nq76@!`UZ~#oRE&r22lvU{ZCY_ z8|YGj)$(!&+oBWhnp#3Y{sPB8#zgmHOuUSoH2+~ttUt!II@`V$O4v~Gi|*fz=_e;> zZdd$2j0tyM@i;Y7$7_YT5%xcf$vHAWCggt`6Q9!-mW$jY!H+TF{uootzl_Nm%d}$q z)QsvMV+vMPnhS^h$C#ATBbAPUe~c*#ky^7Y`X6I@)SpLZ9o}>n`!S}3A7dKV^BQN5 zX#up*DK)j|LiHtY$JFwztl~cs$HOEA1+fm1ZQfyS-gR`Gc=Tf(SebH~=eJiPWe`W$ z8fE2fgD?U#XA_@4A-|OM7*h7`H^-ELpofY3g^FlYc}CXGodm@?{CA3l3&&y-+G}9U zF@GL(!fG&jHs*e@YCT7l4eqygoZQYq{vG<{!C(2;kw+Ys%+PGawh?|?W}T{Tua*ua zuINXF!3m$@7@&h*Ea?w!uGN_dQ)evB#oq6!vB z_=0s0{C^wMW1|+86Q{B&@FJL(1M>yk6q3*0v;GENl@cbEl9p|jb1kqIjfVw{EToi{ z-~2_5?5RMzxb)s0CR;Sx{03f@B~KgxBieAjuEup;vPt%JT@as3$unwZrK*8lYL;kE zQfR?R<(*2rO$--~N%R}AYVxzdZbM$QOfS9Mp2-!MXy>A)#_bLLbhLcpygp@An0H}E z^yG{f@dnLP!FswCH@a0%)lIy7>Bv*RXFnil^Ykmqs%ORjZA`C+BKlLdf76(Cl{N9e z&ojgk%3XfoqLPzh&W~fZq(UGknimKPtI}vRLdIGzvhl%K$rg$%mK=s3%feL1`j0H2 zMB5!FRU(wts1&JM^vwCCV2zSer0R;ZDhLVKC=%>6+Uyo>K8*_oCb2vv_qb%MF{E6e zM|WVuCE}kpJyy3};MA@%HpL)berU;(D8`eg9uX|wp* zJW^HphHVB-!-S+sSkk)&^C$hvj0(s2cH)%fUw#SdJGo4(YCsjN5?Ld_AZI6w3~UXp zFJajnDXN|qTSyd5549GFis!e0iou*H-f!-%CGw0IgtSqSq#E$ic~U|gSJ>X2Q(JjA ze3@L$QE#qITjAvg*;D04XQos&`K1X9exf%04%3V(xVDqJ`WdFmgCD&sl-44REIF|f zsRtw^VzT@OUL#S$)&=ki6!#AegeM3&2NYw4;=(=rATKmHuh?g55Yp2I4#_u^;VOwI z4?tEokGHis0~jRxcBt9el9Ji^*l1K=wmKrIN6%qcEBFHXRy@Zbe2IB1UZ+58lwI~KF~X85jc)e) z15>MHtGly=`kX-HYi2()$dV%)#5)8eOvWM;eYguX-m-yjp>HeRe9${a^+FDnWaIDE zEB($aR+&fvsyTU&fW9NS>KC+et}r}>MgO*-8;sl|}J0{c~6Z(CQy z!84UDr}aH{lkNvg$h6S4gZ7<{yODTvSI$aB%&*_SBb_H25Ksz2LbiLbb-wS~&Iz01 zk)O`ioI{txq|qRo%UpiNK{E1ZWSXuddh%Aj2Flp#6WdBvzsu88@fOCX!~#|;*@h{m^ozUKqH8${`l)K*Zlc16W^(yXX~uBcI1oq44X7XL~- z2pbl7T`2)wDUpbOSHyerlbc=saXhSlIa3Gd%O*&VoX3wd>Eiu}lD+I5<=_n-^bQ~C zO+ic{PnBZI&z-*}b6Yfc83%e9NBL-5DNr^~dt;>9;Yz*{-prue83zK~v0WM>^m845 z?XQosjLotzSX|Bk!$+!+9=OewkKrxt@CWYG`~jOW^^OTK^605_Jzi0_%;WGG*O+s_U>p zq|%opvH2Syl`dUv8&1h9E_==@?X)gQWJHW^jx`f(1%P2WXN!z|UBf=xC6dXS8TV{- z88DGPOA9)KkM{v@e8N2{OL@n&#p8kTiKPJTX$7K2_wegsbNWfWQM>hH^1#XdoSD~< zqo?I!5suC*W)+L@yVw5-J!X2zpW1%_RgW^tBTsjJ{NI=fv!{ezr^gDO4o&pV3()zY z9j#|mM4V+G9p1x+X%%O`b0Keon7zogjQp3#N};Qh>KV=Pg;)`LhgtPWG_?t7eBCki zYyqmMt?!{1(vs@nXkru9-hjzvIs0y<7qP5Kr4CYES?yCDyMjgstt@5bCOnzS5-$Ro z*pD)4ME$BX{x@Y(%a1V#I%kMWgZLD#O*i`bWdn z^wDHWO%{=6%KD-)Rh565k)K9$Bk7VT@{qzv=qt)72fl66R+{s-iy%CS4At#Hy#HvQiINpc+VnRcj$KVz%&y)QCCS?x)HXI3$Pc zWQVnVs8HxvG$absqZ*t=6@v%Of(c6RJpF?r8_+8hC<9CfS=I_oSb^-J{-ECRkeZd> z+a9y&aW(CBv3^Tvci!86XhvFHI1GdCD zTKq94)Ya*KHztAq+n9z~X3Y`)WlTkL3qOB(|1l<%A7euLF(%GjI@Cm@rw&gL68m|R z9UblMXA23h4#cR;G5fWe)MM)0p&x4FDgAU48?N1%$Q!xrTJ6!XgGuLH zeUe9Hs#eqYbI}|0&Yv0xHG_uwxOAO=1O5i^G4Tv1Ee#+cPlIw8SkQE(2J*nwX8Kd? zCZ2>16x62F{TYEpg&udQO`vty6CIqhmP@a-ti#<94qlOhFT$8#ms8ybjv~ z*yxB~uwGtxIATXsm1c~75fob*;3brbPnspv27iWrO^K+`ddf6#A-K75u0RMzx{;AV~2!bff;Vy_;{01iG_ecRf?rtuL=)b9B+`Rg~ zN;75*X`ab&8^|MCWw1AZkDKmtV8#xqj}BMZ-MJZMM*vy2XH#D!E(a&=mLYA`8Y9rF zNotI*L8QPM5h?LunfA4M|M;WWRLY}GlPqq{LZOVD`E}tzb&_S8Rfl_x^4GqVn zppg|cTZ;L?6f<}s%O&)NV_Rs*^)VK6V$l_<&}N!?lcv+4MNT8)$fdBS(1}pF^7A9L zJkzYuVyE0etlgVK6UogU95!vZkWrhvpB@tJ`0EUSJQ46nO`Wp)3g;(LH90VoqI%Ml zVyR#BM`rPhe;=o+3OIgGAe`GhdYm%rPMzK>Qig!T1Zdk-K6ck}mjL!YT#>=n1ReFf z8z%GnOCQSm$&oB+1Kq*w{bE~7-G7|dJLLkkkhFl~Z9Zd1^zIG7`AGK9*3iMa*}#0&?bD;?qmI(Bi8xR7yb%&l$VcJ z8EW+_WdGNx`Qtr~a~D?6_=ft^lk8`k>QP+2Uvv|joJ=rHsEmz|3u?4^T_Sd0QZ9+D zAh9veiCM5RAtLL<hE6K_~|LM2J9A?$eWy}4^vkMK@1 z(3HQhzN$O~8zNrhAHz&D13g7$a}>}o7~WZEe-BcV>8cT+CUL?_qNqRWq8FMy_0-hx z`|=cridKrVk+_iYm!q0qSWIWJzZf(0xdQZf)ZL@~5y+JNujbkPKE%jcGV_G{ z{39>9is>iFf5lC%`Ne>QA{jVq=_#8Z-^qmGD}hPB65;@IdJxAlh#3UWrvZFmi$UV} zZn>;?B6!-U_wq%2>pTzc{5fQI*nJ;G&8E_#V;y+6A+lUA1j@4F`-(e&mZJ2KqU?~G zdP>gZN$B_D+txUuLqkG{3OHq#0gN4+S>;Q3#yS7xLiYW%AlJ5`N#S+Ccv-19e_tsd zgTwh=*Q8km56M-9TAihdv5Z;h5b{ZEZ+&0(>#MT~jX$cfqNjp_gxo>~+}^Q7&evXS zG=DPhdFc^1)ApAp|y)phIZlImbj@fGH6^#`tZ252~&BsgV!OICz`gsK6p!A z_y+o|yvC7pxJ@ax&MiQt(KS8_O;%=IN|$ZM#;%{BWrM?J(VO-PB|zK!qfSLfb^P^RI=u2fX9juV&wPtHRJfm0csEHT_LxXN zJ=~~s^1U^noY-f6t*38$K)23yja9& z0O?A!4F)S~^&ozGFk_;KD!>mE6m}`&49MzE$V2kpeAYJ; zQ}b%!4vY#0-hpqP?_R2GYoj$`jJ`4MF~2eq0}DhgvE%xIrp0EB1(uI39R^o34p`AK z*taUBV$oEd{1y&+VPK7yxvuA^^!8QG>i;W@X-QV<)yu6;-~lMEJXjgd=2C7+F-ia2 zvjb_+1vSgCDaRa=7k@~-QoFgzo!nDYh@OUIQ_XXFp?(HKA^b6jFl9>-rS`69nv%rU zqfF~6IE~ovLT~83c%?3alP?)p8Z$FcA-dASIb8A_I6#;_^i< zHPo|TlV61s$a~@&cC^9t0FAp}_)riLx2$dWcD9ZPrP%APrm3af(hFD<6OcSNkmt>Fg3T*+cWzsA`B|O ziT9a~bGfh%FuKL>do+!#dU;I>5X77@5pIM8h&hu-b zWWAFhLLcXDI9@BL`@|$wmTM`BITg{Urr>makO9qL`of=g24F4mO(P)wsGMflH9c`_ zb-lai9LM@Bamu1fyo?zykcXS)q{Z{4u9}BI`vWItUJc@*}Kq81aPm1dKYmASNiHzDsej zcN>y`z_HHMO*eb?>+3`%9du+)e>9CH#O1v9 zjTY>BsG)_RVYMY|j z_6&6kF0E+FH{S^U7i0GrWJ$Co3b<_Bwr!hTwry8+*|u$4UAAr8>awj@cl2f^Chp8R zf7aP?BJ;=2$jFs@uW#K#VSlJlbzrvH6tA_uB~0f1WdDCoW^-j_zl% z_`JL~7SwNmIadAdrfdY9+u5T{KPy(cvAl4~%x)Igzym9>nLY7fzSpI4zD zR$^@$?j>V0;`Ew}wryG*Fh4hYum}pzpAy#Kx3uD{o$YQ{SvS0$WzGK7Xd@R6{a zpGSIko_&Zmy!BZ>F6OOV-&u@RPg*t99xa@cp_lo(-z$26u*brP7(5JrbZGs`} zSOX(s*szzGE8W`dk)qn=l(~6^`06oy(SK+imYe&;xnuX(y?q>H-1)u-M{J3&?$#K9 zCDzvZ2yYFNcOHJC2{|QvAA_4_N7t`ku!NSv9d&dWG}-B%3pT_E-h-_&Ri2pH$<6q- z9e!@Ac@^+HL)_BmUz)WODHo!R2p%^}J?0a*M|M8I)+BNT5r~K`39af{zcj?R>*ME)LLXS$9uK5t+ zQc#jnBvG-&lB@dd>37FcpY`ag`a%0{$L(83SP<)FkFL`68&$*L@n-k>zpmp?&MB9H z{kSF&KduSo|F}cs-;?+M@0xJ_@2tuB?{$ghuiU0PxTQb1!r(uw$p)e9ABIslBU|XY zY(9m4h;o1?mwXkZ)R=qIdplk0rN1^T_yIG9cAtMB)~$={C6jxyv|Bharx7Z zrfEa})`TCeFFxZ?JBOjh^|p}pvK+uf2~EHmWAv3>VK2zC)oW#(B10vi(=pomZE`qA z_ugq!Ha)f3Zq}#U%J=hxf~5dw#*-;cXbffnCrpL@et5Q4`PL3}%y5jf%RXog*oyN{tiTjJ!S zJUF+7%IF*-ttErMwun-IbHK%^O=4}hH)|7)md^3LGz)RKLhb^>?12X$+2Hi9>s z5rNrRTraT_ftiw_8{Dpxc)Ft)j@TumUWD9jc^6U6MEHAB@Nd7-_^9%$b1?yLO8V2n zc)1faaza9OrwI@=F>1cCOa;A@#8s$Y%aXm&5U?OljGbO*elQNmuKw)AOmjAwIHeks zZU(*jfcoRQM+kJ1q*qAM@gH_H{17glhqV5?pS`e9e*nhNSm2Msi|7JD zYqKG}zF=9j&g3F;m`=bBAIe`ojsh-h4j3;dvxw41cW85z+oV1&q6Hhb; zBo|N!Aei0yC^N%SCM3nN+I%}XBj};1Ka~@b;qvpEzdayykCcMFg7pqR*eiSS@kQa4 zPMbcTMy()yjIR-(E&B)((tg72qP{tA4Ks$10$;^l{Yr4gl$RHTpHkPCDX+8lqUxQ6 z!XS!m2h8DR6>wM8AQh$IGZMN<0?f8hK}Dk%2pHHAV!$M;kfG@em+Sjoc6hT83V#$| z-Qju^i|^aXRg2F@`0<_w1bh$b$ZPz(LBdu+&+oNfWu0_=4X>c^3OLp?Pyqkxt(=-r z2!QCnzCE-I7FDpP#mo|54AbrGU89w`nok-odk3>sf|j~$OUcUJWT|B16<7uoHxuf} z0er9f%13D7)D&A@&+i|N0W#HVI;azY-gq{3H=n>$vV z7)g~B6LYw5R_;-Rc3!*Ku#Zl;a?JLX@V0v>>3#M3hFc#fDZqq)A0?cbSqqRPk><7m z91Pg?`YNkBz9p~;f>0(QTAYVNO=?eamubb$l%7r_<6kYD$C!W6^KEnH1iw*`SG$Xj zo)4dkoelM*n*UExlic8cM@I^8_H zd%?u&g8acp%+vE^IH`B))_5JAw#n&=$;287Z38xl$-3QU*`Nan#^DHlX{&<`rCVYD zsk&H~EV!BPBH5B_MLO^xTHL^IY=0DsZNT)CbMSY75Of*15n`8^gOBTW0*@yOGX;AX zQVt(wf*vull1zFHD-J5?+<8Ne1n-8s_YNH;82#LpCyIXZ>+HBf0&t8hyT%6YGy0P$ zj5j$q{a4Li8nc|gxVc){jCq4e#4S_BEpuEDpl^-vWr_G@Qu5|Hj(NhWH)py?8!;xJ zV;i>c5j<66xRNIiPo#h?C~%a1@HymzUDnhXys(cX2X_Uu?ILitVy2;iqdCCM31-qU zi{vTg9Xdrs!*j41W5fh${uZZ51}(;9&=zMt-wzyI((*`*9oW3A@{MSl` zY+D3xU0BVimk^jcfWYKKP&WoxFm5SI#2*xl$I?D?4l@65Vf8&gIHidAo|VQXLlSBj z8#|y%ujL*J`2=~}(Z;}dbfPp!{*Y?S`~?f`^UxQ6<==o=4~u;+wb@KmWlgb=&Y?Vn z(80hkM(DtC$PNqr3zCkZ9RH__`_C8*B3j_dOhxc&IIz!=!bfAj8JT6CZ zM>bZ6=U-Gk#+3^l2dER956KOQRRs-eig8kHIDH14A&|eIF5rSL7DrgxeCWhqDN9mV z7?N;1+Lmaiy#~t_DA7bL7=!&d6ljq1D zAvke`yequCH2TVzpjT7+I#Bl|R6fS=^pZx|eit(V(jmYlyJZ*g9&0-h7uLa*-e?kX zI>2lbT1LP{o6q~82wNol`B6zeVZRJmNTodY;XrKoy)@$>l(+qm9MuMCp&BT|OnI51 zzPj~p=R#uyI<98Z!F?o*BE&#{^~Oc6Rhc77ifY1q1U1w{K?#J^$dT(06YPm`E@sNk zMUK=4B4XxCL!AuMI3DFyJ8}6#b~%us4$!}7c{`S3&lWn?7wowzUw2V z_2Iq;neOoUg7NuV3mlx}vNq}Xe!<)U05DGWT45rTK?5G#n^DdP6=@kP2Xn_usGbI2 z{kq&ioR*qDF|7B|Ry+rNt@{0&DAkgGi6D=cKT%FMJ3HBONptUS!4oK$?HUB7cto4T zTQC1#H0zJ)-vk0)w?74--!X%v{~a~4{uk7QonN*Svyw#iL7Jbz(;4XYMY~^E*wP4W z5QYwjzGMa6B9U9+hOcynK7Y{A3u`>ANx0pV@6(;FOLVINWWvwiN*@Hfi-ZA1# z-=$y{D%8~@!wpVvQC}b=0POH0W^eIPxSKx)}sSF>{uxzRD^?~PO7q8;Cl&dx7QyyS_Ryec zYwiB?`@-td0H4}^N{}A3(>G3@*61)hBSwk#^OA1MN}D;0iYzlPa8?YqpW)D)0M*6s z;~kcRQ^q@=;h@X7RB-gWzK+0U!S6h6y6+eRXHDAIra!3GVG{$q0>AxZIrw}b!mkqU zwdtUW?t1$K9cNtfa78NdZZ`6#Xv~#zeQt$nii~pi@59`dBv~SO3lv3i{g%Zd9?Oi+ z!(o2wyD1IpyY*Pv(lCBu)ZbS4F$G=fPl9u=;g?m@g;3zga8aQ8@&iT*Rq)*lV39QZ zD#s`$!RO#90az7TmJwZWK`HCu|o*QQi{dVzXtT3ubVU}CeXg6aiRV% zuu15@!6s_|3^sw@$E402U>sObjM-KGk^*6!hj3nj%C5RGfsu0!0lQLYZgB8}3Wr@y zg<>0)jftUTukMt~cv{9p`U|x&9w$SU$znHY>Rxl{j(?AHhK2Hn3|*Utgqvp}JiOi> zqyy8?kG1sUva|>VYD|&awL1s*h}GT=si$%y-hH=EXcboP@QCZ~c#a*{=~VUb?bW4F z1K)AQt215_fI|VtOL-Xn7=m6VQz3^@q=^-UarO^s!v0@Klf?f| zn!MDk*RW$>PDmkUYy|GPu+#kuX%dn5HX`2Xu!@JW1MiNAwE;Xg`W{+f;4XBx>RR|j zHK91aAup=3m|@w(8{`s7OJPss@>ntkjlLD5-cysKrzb=wBUKybwFk+a=&CAgaECIQ zI!Y|I!`{kJ^f}W&uSo(A&=PzNrcE#lg*3-<%CAb1Nl*34sEgwjGsR*}M@mZhsJ)M^ zNRqXdVop>QsQ<-NKl&|HKdMbruiPz4@eRgANdrwDEJTD}mg>eEKh=IJmoihrJHP3g zy-_J7=u{}ZPeP3nbwA5un*I;mWT#W05i~sv!2w8kAV%cM!)-!{q^+Lx_4mo2?J|{) zYRm76nR9`T;-~i|X&0Rz+{8kx>5Kj|h3hY?Wx=}Q#!A7WU!WFzxr-)kTvpk0g|~z& z_f{GD6FA9vwpQ8iMOC>=*BVdOWLH)2Y&81CjOZ)(()G$n&C<2g@cDnxCPN;z9^CRf z@cXhi*VIibs+pauwqi6n;#tl6>2>~8!+`}r8`a(DLtmudSI$dM?LB(uE*SwtA_?r# zVM_Y#v}wY4K@x@zE_8HnX9Nk`9p>P)_4SpO@ALsnu9giG&bu#@ zDuHFO^M)LW6GSP@y86B3x6z@oPr4*Ei0u`&I*d>Y_%fFSnLoivaSzB$ii+f6=70I^ z@we43&(f!0Uk($P0Uc}!ww3CJ2^E3`50mDp(5A-d9ZB(L?|F^7cq8~(Z0r_QAr3p4 z6p;d%jjE0l{hrRI5cyrkpKmh6{wPpO@d1wJ*y6KY4Y!>P7z>c~m8aQ3MK9fE5`Rdj zLDhj*)LyGk89O!PV%-Lk#5NvhyoQ3zE73K4M3NMQwTA0q%id2oSf$X1qONJDTFodID@k+vHlF5~{<1h5Di1lIIAa;1vz}M1Bik2nYNpWe*`Y3mVix zG8037i=`#MZfz>pgeHaWPZD5^K|>t?8}knKDX|x7j4dGUmLv1piW~5RUa3g-F8wyy z!po&u7ym>P5I`lcgOotYTb5W4`!PQ-omqlBshGFnMGxQ&rJuA_&nl&}Dhehpemd&+tvLdApyd@5_h7^pj){kz@NwuGJ4stAb7SNB50d2G?EAm% z62V*h^+E{)0APU!06_YGdeQX1*ttjQ8czEXNItGX-@?__SPg+eoEQ10`P_9R*2CI_ zbz98Uwn7r1=2d|Tl3>G6{2MKwMwu$4kmI-2vl>z4 zKem1VV5eMjVjm`Wj#wWbh48_Axa+r;*>I=jCAxfe<~>_8--Po+&#`XHcoWyjudKc( zgcGh2H9cd0<3GY%@h4+An zSLK9o13U`PYh+Xeo5h6&9O@no@Wnfug_Zeu-1vCX{I8e^#JREs1lm=)oIfzAUueeq zpD9q9K6NrGuN4^>dxQ(e`nio?lOU?F0JdnX=04f7i`RVz3Lf;+Ma=;4ARnVVqa;vv zouhEi$KlWk(2hD%Np(Y4iJPwpS0JW9^Wx~tq`m80BxdI!>d@z%2FUX4l;U(5q^H3N zIS2)?d;lL!cD3R$6@3zSi1`Q6hV%>@-ThJ}loh@vO68)vgUmi#|#u{^T?oe**8GL&~^d_X_&ZaVJ>w9=X7~uN;@;N9&BQw{f z5;mRC+-yCFxT3sZZG?i0{}ov=kySy}!G;-b-#pz?#d2*{tCk7TW+^x7Q&???zMOiG z=N=MNai`ysc<7yJ2$+n+6quDCdz4qLy_%=vuRizFyoe_$Y(0Rj;Ni{~Axjf+!ePo| z25@6R>rT_9weRK4Z$rlprr}cTo$+(q#7?OT#E(LdhF2o$Bq*qrf?$0NHV!^Ed&$sgRgaM`ON z_;1q5wIo+*Q;+2*MXwVRq3OUyKaYRP);>khBM!s!pp;6{#`nAvFApvtl{OSOc|iW9 zu*JgnyvE{a73!LVa9~DB$iVg1?<)b9D4n}G_l%kPW=b^ZP>nOx@CY;7FZ7?;mqxDy zShX42-+;mf!jkg=igDPaqm3y&M8$IfYNBAIqAGOc>HDqnIyhW z$#pKNL&4=g{BrxCR_TFQ+~ieo@H!#%C0Y-rCkj*ipc2sBJ%wj;GQ<(^CQOPom6Da} z=~iY2Gd>DoRAxkVcs#XgR}NFWG%Y4(1X_{Hf{3Wl6);4qWP$-eg8TQk9r7dGoK*Nt z`2D#0P$-=+x&{rXm^R0i1=`m$USo#6HX$bfq6Do%#O>8fqio6s!s43Tp^|s;cY8{!d0QftI>H;9>ciGd0F`Q+YlqmPY z>pbL_NQ0*PT0l5B($2fEWH=zqN^fd&=dW_gqR+P-rEF6MyPjS1rv1kYSttrUL8jI8 zR(Ynx8Bba5Vja!Q@4@s*=eNV1(UNFghtSFbX?spheg#SR-3`H4k%HlB;!TEW(&m## z=7Q60J5C4gu%3Qdjb8yk0b$ovYLapzZ|Td4^Vjv7sq;7W{4B7}%1k7|@L6ZbuZmcP0-8HV0ja*^J7Z*unF`X-&UPda<&dle)O*g zkum$~`}Ok$WxSLf_jD7*l~Q&n1jC((`*wMWvm)ZbE_Sdv+%fZPW(au~7vW>V8 zoi~`{%c6$IMQjCmP*B}x)wm9(^Z45=ACqlMeb;CP?0tFKFv+Ta`Lfsw-PbJCs;=%9 z@zeQc)sewGjd;aP$-VTx!6g6Ptgc{PX}Yu)KhoJguc-b4dCGps>r10Jvq@!L9{}9R z^(^?Cx2{Ff{JE(fyx}^wCF2GYmnS1sI~dqoH0+nw5F{}$MOa5cvOW?!NyGq0hWItj z2Kd;#9>|woYvPZow{M7?_RAV*rgVsUHUB;t_bpJmn7AdRYx%Fo;2VLe9B#B`s^vO< zwD0L~*BpIe4%adl)AiHh7p$F2Zxm%X&)-J@^6eGP!ukr>klTx;T{v~BK<>YAi#a7R zVC)%Hf5w*GW{qImHZXNzG&A}=1Fr-QsvTNf$1)?9+p#P0N5YXVysIs}n?3KZ669%;de|r|i z7@g}3VLh}Ou2g@`XfIMXaT`Z-a1U#i+o&8oVZs@L9>%`U0TpJ<)UeRsbVBzZkN}wO zx;-Jq_$}rHNRd%}wpSI-AAu!bRor|duKV`(P!}Y4h>9R@r($_G#=o4$ma(WWT>oJ0 zl7LED^ud30UeJ`0i~furt#0$i>M+VX1$~7RtCZNT{e9p*AliHbA8-&>+UT5%&!1}p zaVwA3e6*>5GRm$ArGaiLhj8J3iR3NjW~ZP>l69A|nDrb5rpu9(aCTrAfu*d=OR$x? z@T}obrVFXQRRIP7A?L+vIXoY3SJh5c7}E=Zoe8D7q_sXu1lL_<&kI3jzEt#cU!xA# z!ru4`!rRE7aS0c2i!{f89?j=E+N3>_45B@$*ZA?)y@KgaN}u8@#<= zHy4=ZGIuqWeD51k{(|iT{~rt9|JtwQAB{YIT8sS02jhRtLtO1#*;xLyYso)ac6k4@ zt|k9CV%Z;+u@^u9fMYNK0Fr-l#Q*4BVr^mg&vwBpHA>P*P1haFs|kRHl!&2)kR7Lp zk(KR(*}G#<`$ziw`zQPRJ75C?-!l^^#rXSIg9IHM@OlG(1PblzXa{Bo@&F5c1nw^= zMJjp;Z3<)TAAAaVdoidmEDj_Ipai)Ey}6HcaD;F$4SJFnzmTYwptTjDk)xZSB^{yz zMvqO>hK-O3|B0PM;4=jDu)rn;9$+>F1LMrwky`E5HP$!KH`WJAnB>?Lit%-L2XK|> zC3#SEbbJWE$qX+h-L&J2nuJkXjug8G{v7E80E_aVESD@krRsx`--Q|Eg(>Ux7wna! zXC|#DQ5b?CBLf;d@qb}Vnt@R@vj?b{hAD}GH-;n@!X4xZ29^=fO!G&cJP~|K0t>7I z;9e9!0N_;qOpCKKbyVztj`VL(i1!4_{j565%t*;Nj%^3)|7C5O7gUSe4ZXlp)6oCK;C`#hWvy(5>)x1I2?JwX;*1d_yLy4Js%v`lp0rFFkQIPsiI|cRs9PD6AMK+7 zNH7frHDf>ly!2Xl!dTmX%a;dtE}UI|uBxIRzT^LNRhhWi|Ff&=-oV(j^^Y#g8$2;E zFgP#-6$pYfBU2s#I2a&#S5m>^ zVZtBfv@{e1ej%liUXXkNTYpGKB7+M8-X@A6@_Z!9K`}7E5H}h)&;WV? z8oWAO%w3l0}<66rlUMVPO%ufCv~&s{^7KdAEKN00cWm&^Z5X zQg@9!XR;uF?mt-n$4ND|w*F_6dYPtWtvrG`@@>Q&4hhW>-24P|$(SY$k=E3eDhxE} zX9LrG8xY-wPQN{*+xbLig`BsyPeO7E3}2I!Dy4A5Vj;cJ=%Cdiih}ff*DGB3MpzM- zL8dw+e7#j+DXOCUmdm;0F@r@sUs170<>dS^WjDQf!oM@wZt~3l1&DInvu%LSkAh_n>v_Q(4nAbtWxl zlD$Q8<1D)j#U>cqrPVmtPD$k`#lvqqm+Gc4v;iq#Iqwe?F3xoRr zX!M-E;!Cb9MjVK^UhPyQ?9}i%8LXMtz{DGO74Q)4Js9Z4@2J*2m3*pBG!}I*Z^p|` z(Z#*v>x_UO^6k+Y7+faAYPl;8AQ+@?gp2-h@&X#s2ERR^(izV1lngG|u*f8HP*f6Ygsxg)Gg_JwIaI*{lg6tF6 zvq%5JtaQD5tscqD5$VJcOUM&wc8f!|>)z?NbAMj@`qg{rIrp(NW5@Z2`-Sj9^|gd* zpiDDLEjhTh($Pzfwy#A6w7Zz<7WQZWy8^4W5+H#pXlZ;HeMwchOpHctL%t@XPNqpe z*m6h_by%tiS$dJKO2MW~8Qfj~cTms;B6QIJN0re_1$SsgnVqg2&r5XZ*2D!yPqFKz zMoM4iagW;)@wf~Og{q4!l5wYMPGXN*Dd(_B9H;gkfx#|kUum~!hDnYd?;!Eet7?d` zYJVY=)yvTUXOzGx#;V4KQ|*h)XEIwmuxH;)T?+N@1C-?+o07} z0`YpyVvYZk!r76x*B7#!5^KhcV|AnGF>h5b(r~RI>+(W(xRiAftP-%ny0`YLcOxu^ zR4`!!>eeDAlh&+g6JbLnSH9j93$fr4;XRu86A7GxKlY^h&X8cuC#EH1KYF@qOm}iK z9-}34`j+yl?Yd2vQt9X-p;QymLKvPUTKaFxy6oTJZ{>Q%>t*9?>sDD!16A)(IlTvm z*~%Bc)-SVGE*oXD&dJuh7O!;Ir#K3-4N8KUrwfT1LMyg~Hw3+1XRk_sKQBBveZ1Ab zMBPxb&A49)ounJ(gu0V)%dt5-mJn+<5o_1e)u<*>qaIM<9znS{xp=fPIdoAWF%={V zaX!^Rqx1Z|DSm~kv@jE4qo}V$=YBngN`;z1rbE;v(I)9se_199RfCj+0uQc*4h^b> z+UPgxUyIj4^3i@F-6Id8hpI*ICg>FWIltJR;2wD}a(`35!k%nDcyI%_UdIjEp6MRf z&)361t5t9nX`8B3pjDw&-7WLxG8oPdeHwxtatFm0t($O@=mU8VxBsBO`sV}&d(!>f z!Fp)Z+b$u&8$qE#8^KEbozIv$t{3CGWXJEtR)nioVpo)(x z$Zq`k;^?#eMsRN>7#^}mneF}~HlnA4k^kHC6liW|q%@g&Yz4LGVmBUY1Ga>GeL1WeP0Qp0Z8@8%A<3#Xni6r?$kdmEYxK!!sgc#LFgg;->AgQY zf=8$IaduiY217?oW&*h8_qn9bD1542Qo*4UfB&~Q1;aO7om-W8=}H>6Dk(~ary}{n zqq}p2>JD?r^>}I2cL$5`TNTl3Za>T^^0P#47U5?;(I;@=i81I6=1S@<)Ix2!ymowt zXNLSVx8;@QRO_-K_>x1K?|FG4+gqQil4fiAMTtyqbCEGjT(;|%Z^NZ)nkty~;c<;i11bC6X~+XrjS zhrvN)!G#if&lC@SjNO{~-E{&oogq&$E9><%49xT@|A@Fs=H0rdb7szIvV;TQd`$zL z8X1Mnv}wBP7;-A3$w`rKMN3!K358S9nkuOguY#}cS= znlDiEz13jWRk+2$vFz9fke46rup8B)>=w&+({64_6;}m`h2|xzCf1=FE-q*3u!5#{ z0Y{|)CTbQF=dX<0$23LB;Rnt*W4=h&)aZid_t2$By_(oP7B8uWuO&hcA3yO_#!BHP#kOnw}ZGbNF}ePs;B&-&Ov7{KwdL z@{h!?D183}KhzsgOW-{LGXhi$C>U@tphExKUJ-q!I7k9@q{e`5eH#Xx3z(7s;l90H z340a}yex=cV9bI+QbMYu=oPRoA&U9=v-ajBELd3ZvO#3R=?E7{8-KiiSK~HwUncPy z!*38jmGRo{)RA9Cc~8*ks^zP;U*L~I#8qQ(gumAwLtN;M?|6`K) z@980}y^EuXwY#2~iLHsFfwPJ657PfnZN4t8SJ!n3q%YpCoold3T&Y9Yqo^ zI!rZ1E2!!1Lpz7^Ht>3|b6Lcx-8|v(&uDKk$5-=roD=x0+pEpwxU@jXuayyeeaP^k zam3UX#F)6%Tu%cR>{n~c!PBgS3#z5yw{G8qj;=f&m#tV8g5Qel&oWxNsl(TW&w4tZ z|DBOIjO*1K?GGj(_CJ`>?QZ=Hf#vsp-9L)Nrx~eRArs^0*Ni#kdn1o*NiVIvGCLmI zS9yZG#C3zAKOP-)n&>liUr%pV7OjXYrIzc_IvX7UW9j}l8(akbMC}YuieI;V##+c< z#%S``vgjy}QD(``Sgrd+WgBm|=>R*0jR2u&_Rew~xG#^rej)~MHPUn{yFX>W7@GBZ zXyR}Cx`~h48@vl>vMtQd=Qe(k3W&h!+H$_?{?GyJ(daG4slV)~LI5(ABm-d$Zw2*DFHtCQ} z@Y3A%kNwlZP5&(@o#bJ-@0|o@hX40KE*(@K%})cs6fo`I0)HmxUK)S~fJq>Re-BL1 z{53#K5z|EVe}bgS*?~M~50uZ?m|1{=-diD885V8z!E4E0fr%#kyx=dtzL};>#0(9< z+t6JS|7@~g%D+xk!eiowv>vONE#lQFvvX<# z!PrI0vyOmM%>FCkB;F#H4n@wc$xq3EdrZFrx@rCWL7BXMf=I0zVcL6PXW zJRJjWs7a(jGR?#WzWDM}%_02p{1e+Rp*KJ@=-V<%Y4Q3B~5yRNBkyAu;pH3lvu+l}@ zS)i4LkEmV4sUfed2Euw5BFM1k>1u+e(V;WXz2V#R@Vg^LP2#VD#7!u5nB3KxQ)iZ%$f(AqZ35xj> z6o!TW0h)wjpzf^#X!y54-V`(qRbSOl1MnD&Va2ZvY?5_c8~8tB{Te_g*fgu8e~jzb zSj?W$^IxW^k`D|g4btiykaaUUl0UDtq1MQSc?N{vgq+N;CUtZx5AfmFFtG7%^=^Zn zdA{^HuJB>SgFnNpamHm|%PkMd2@)zGhh^xIW3gzH-)M8g2fsdxapVaiujtYc)) zGTinKUe7Epuf)^~oLL5ggh&BU8TeMfvC-l_j?I5H$}NjpPm$y$!WCnKT}2Si`$=%O zHV{Z0rt3R6660-O8kLCEHMSwb|1ED9Hzi>r?;q@!9}^(;&8C7Qmp$)e((r=4X~I<@ zgvRFAUOmh+1K`~-=)t|Hy61q5NcxS^wx$Rfk@y>BRaHs2H+DWpS_-m+91U)_HJ9Kck}PvrE$1g zI_opBtkC4~Xvf|`8SFEU*!B?)bQ*VClt=sKw_%Z5KU`|=3%3cJ31(&em2tQZy1cW$ zXbnMrM;p<92F4@P3N%t$D-r7ykncd*KVsI06623S(qP;5%je;wt3B0w$lqgn8^*r4 zwb_*&S#CqJg@;yBh0&5fR?w1*fPIN4T4;v`l_rMULpCelm9IC<#>t+ETYf!F6fqhj zcP^@}U8KRU{fV*Cbb_`{D;u&{ARMNU5iQ_cdpkGpZnpWe@B}-fDfqx0{wM~WWom`q z9;-d#Bi7eX?1uk`B#3Q$T3qXHPvzWEzFg$MyLj7Lw6{sZO0rlOIDiUB z04BIFAR7Gm8rJ-E*VVopJpIv|K21za=xhvH$~n0@OYADjz7PTPUr|BXz7hT;e#l1z z{W9W7SFguw{k3a5kIsvk%UXq-c?!@UAW#a=L(3r8qlfH_T~V5aE4Z*8HWg?t`yra* z=P?Q)v}d)Qn#;x-$X_w0*qA0POC=@Jq0qF*h1r61VQB+Qz+vEb1X^Fz4gJ}=4K8c* zV8V+8uu>m0awBgpmVlchZWKYr68np5ltOF2-Uz*r-dNT~-UgSIy4csCa}M!}{HekV z=0qRn)p*{iq&iEWfDBRgX{`(HwycB2+Mb7n!emG@zsXB(yB&(*Ji$!}A_Ym-!Nl?qb+{ss0pH<>vS+s{>C+H^Frj8?!9mtS!^ni3BP#s>caRZQ zO(|*eymI+$m$eM;2WSM%;Ua~$7Pz{m_3Yq{vjl%6yOI97{9N#bc#DoVX90ARW zsVfpUO5HIV2vabaxs8PVw9~AouIksF zJf>_!emrb&R&Hn?Qi0aoBPX?JK9u)Y1Q%=wCM3`bIfY*Jh~?7iaz*h*-k`)>6y%#_ zLtFm0QFyZAr>WJvrKS7l0upuc+a94*&!?8^ciEs+`Io&mKJ4N!MWwH{VX->@iL7$2 zQSL=s!8A-x8gy+aJl?Ii`UgH=R3`BH0+$lwj=-58X8A*p*GkfhqTmV&(f2SxFcHb~ zpo6*;32~Ctw_)5q+o85333HMZKZAtD_4-$~;JDTVi+Os!@*8-d@)O???6a+{}W&R7z>+=DthepI4l-tiB`utQD*^aLq)V_H4a z(`J#tol2yE6md3>?3fHeRg2YE&iGyRKy-G?jTNwJU1rf7`9m$LdfjDutmOHKv*(4M zr|(*mxE@rZTuLVQp1J9H6GF#d@u|ucOikWuVV#9<*Ja8^anV9Wf{)nBTt;z$LPg?_ z;L2QPahF0xvX2|eZ}R5eK!Gykt-gwa| z*UQnGl}g{Jl2;|Rs72b9`Q7m~ccLZ;nuJJ7BxpsUvTTjx4ulRfh(?s(;FUI13Fiym z#@=Nk?a+v1Bdirq11Rq+5ZdzI)RYr24$BZQh2Y*Tg^k8V+B6a;Bq{&YBzQ9hc4jB5L&i0^ z!R&iq8`ykKvkAmD^%4-G|@(wRqd~# z4LPaa^3l1-Z}uDi%$ia*SIvtU<^QSf>9}{ypxWhA zWqRC-K&y~g6@Y#(c%?dQ!DN{!fUdo2-Kr7V@4PXGpWQhR3KD^Rxrh877_od4_Jq2# zFoU2G`_SMaffl45hq9AnerA$1RnFlh<|iw+mgameP~t}t%tJy5O_+(Pw7=U}8T&Tq zMq(P#S>e1&OhY~@*{g#;CBdMTNRQ(YJGwzII%+#!_Zw|2Xis0@5)d#T%i0KbNb0Wo zXu_0wsYI%KCv4A2H!w4Wb7aEjSTIsGcerEuntpM)!YTWE|5t4N!T7-uCTamyfrWPK zhGrfH4SU^wj(lxQU)OG#V;Ch8TPB~>AM|xH*UXv)_)DIMO!@;6Pi5BPiv7j3D#Zsx z3jgLbFuI~qN4VwI;RW?23+D9rWLGAc>#S+{%4H`xJTb98=T~E2T$E379M7-9hN=CE z*YEt?gwfdTqL)LyCUtd9iIlSEsEd z)CpPhn&L2;jBkct&E79R>hC+ZkO-m<#TmBuV~5=7s5^-E>0a>D3J& z+4*KJ7^t0qAbVIO1&Iz3n0Z33Th_xAOvqo{l7^4lqH;YBv`y0%@CeSY)hMW$8QZuG zGJ>pQM{Q(pP$JS)MW_%|3 zGh_fKj;60lf0HG7lEY*`UB&OH+(~w?aPN5`d3K2$h39dmGSd7lf_Y{gGdOX;K9=JN zSo)8b>;3z0e&OAj@h}__I)IP;lJo|J*GO5Q@GJ9%SCavCQ&_J=dB5z%2R}~A7G5GK z9XgdP*|D$cMdy3CC+@+1izBGabme=|1q_;nR~O{p)&f2mUrNXPCAB`?eF>5SY1o+E znKHNByai*Una3-9!?oR5&rj@9JyF`iqwhqXCD9Jj;>BQL3O0+1ClSb`vo|rMfimee z%B8wrP7G4rQ37!k?$Un^=BG7&ZWo4+aBcR)o}#mBJBAeP?JmvGc`}3HcJ8(pc8Qq{ zw}I+yXV-MTH8C)StJmXG{St4L*dK?HgdmtXZ5hDYj(?77nAym&5FF680~Sx8XBm7l zBL?>sI7d7`%~#EEp>xaGa!-4F?222OyJ~Phm*`0*cNOQxS5IEo*usFip2Wc3d#n&q zzoEgc$+QO^MJhzmZv;4_%BiC`6E%o;ZsZ)ySJjJ2>~Iag+5vf5 zV|Lf0YOyxE~>HpkyjT)u|JGgRWGYX>VQCQ)$k z4dh422eTB)I~b+G*Xx2xTqn?Y1UP@rs`1m&-)X=&7SPbbB1MFTw z`>DJ*Si>P2CFUb6g@|CG1oTMxf9$;W*ghK?X1|gZLZkPif!ArZQIF;ZQIt# zzpJX9w(IOu`)_sqU5qyG=FOZJV?3k3y)!TLsF(vry@*q{HtB+vlv_gRuJ91;WJe3wYoY!yCL^;EJL-F9+#Ad+dfDP zkR7a@dcn(*EHPki|0{()ryIXrpbZZhq9al5*It?Mp&Y`yzfP8O+DMyBo1U<+xERSo zjI^zZ0>-c#^RM!@-}ansPIwV>tdgq5)ti=UpXyk*Yh|&rGPbdlQ;H8KIjp>xpDq*! zs|*aL($K{;(7YFc9#|DD9v1_~83ORwlP}8Wl<}&g7h|1aEy3S{%&W`o$XD&|Zmf>D zQit}KI@6en!J~ms2ypPXUb(yYcP&m8!zO( zf@VjPD_V;SwY$Vc5iiR!w%1-}1+j<|*GpDE6Di}Wc}2g`?i7lAhZOeI3CnQZTF8t|ETCL8#in@P z@^#h|lbj>Bj7!p*uQl&Ghmx-{CgEP6A;L*y>`=#z2+$I7%I+n~xFLl?c~df=*5^wk zc=8H9#_Z{_!!pldfSFn+Xa_gPre?ENdd|*DYM9z7O(IZAnRV?OE3r&d(9QAb%;jX) z?A|EaW1sJQp&HLLSgRvTulDkaYzd#&oJgD*DOJm2)e2rg!VaN8wU(Vl2|bd|=fuvK z9?X4A`EGO08O5azoL=Zm@7FWY1>8@y4=hh7Dv*p#F;D)W^%3P5d7dRa9v0D@&nZ&n z6~`dCI?Pz`3Upo%ZD^U0E6-FbhdJnz5Z1|S=&gq-#djCi93GiJ%iv4OE}R5WbqksC zbSsQE%yD59JY4+pK%fJ+OeWvgK0C$*2qIbN6PHK89w69*6s`b)R9_V&D=<;E$u~zAjcubg7AdFqQ4nA)_vq4_n zKQ*07x%5JbAql0@FwP8>vJ)7Y@H^Y>`vcRHSxYHu+xr}Q>g?Whv?OnUUEmXdVL|BY z@k3*Lp6ODP!{~5}C3%)Bu4S>xY7CC$QY%lMhm*DZ^}_t{!TG86&Jy%>ch&sqF=Kvy zU$QNpkGsZmWEl3i0JpYZVA5*`ejaF-?F!{}X#&2)?ezx%0%t&PKIvN6i^>{;6~ch1Y4%4O*Rr_;E{o10_{-z`EJ%#vL}6h8Ma9&l;`GS*DL}n% zKDHTNfuH4=>7Se;S>Eu7)qE@g*mx(qL<>mbiUZk^%3)FBUirN0nFg|-TG197CLo2K zzW@a6NtH7?XxI$f_%LoX=Q<4?eY*H|+xa+i|9tKEcA984dQgpiCXEu|iYf+Cx}++c z$mKOAPjcp}Bo15&+2d|UlUG5u*c5hEfFT$nIl$O})l(2W!ya6ltqEFn0WvXNtD&n? z3>+Ph)e3$Y(zywCe4{E<57FQSlC}LvPg)V~h(?6+VF<9D1i&*Y%YPO8jnRi#xJ%4H zB(sf^Y4|LIA91OTyaI>uqeJ%arrb#hk!m3!HW4s&1d(y8c@nRY*Amj2#lz=a_?^$P z(p;}}Ht0Zas8Kqnaggg7Jd#v-Mif7-zTRlFL)(PWKZ_(dziia0)}`fge#0T+un;QM zsBd!PVedc|gU{!Z+3tF4Z|FfgZ3^6K;r3lliz4JM6I%-0Mpjf<@P(n3JlxV)J(g8Z zsdB)+*HzDQvwRm9uv%VIgf%p3H8~2Kq-iXI5hW^dz6#wX5wD}Pc6(WG>9m%$YRT6$V5Zkvd@`YIQ%6J(Q5UU%3m4Xh^h63e^9EhQMrOTGb zEAJVzM)2jPBNJTN`?Y4O@HO+N{6w`rx8yS?YWq2A_T!TW;rG*^OpYeGXnZ{v=}N_? zYAkH}mA!`p0G#X`oQBVW0m28^u;npE*oBP5Nx)0YOdNa$P8z+Wov=m0dB=QnQ4s+F z!<;yB50G8y_|kj;e{9Ox11b;Mak7=56^ab2>?XJA^eKl2xS45C<#oH6J&GdkL1z^9 z`gRH5Ff)ij@I;kOhu67%^_gQeHEU7_H%>Ye0(_aLj^;#c60U=_7lWGQ(`M?W+@%<8dp$X`XijKqHrGXPa$(#2UVF~nfNu2A4nxHyl#89 zmW4~)vAM4aDdLX`u672Rr<_J&*75dOq82qZX?^OL78lUQCA2$tk4!@~W&0vTU@aY7 z=iq2l5#FS)XZ>KAQlI7<@|wHg*BD>SMeEvk-ogxWN!mebLTfQmD^`i!|S z7t=R&A%)bRXY(>~m_35zfH?+@8cN6x-}q%{bQ^H0bTG5#_Wm?!GA$Iimt!9u0X)ND zVTco`?3dGlA73W7>$&w*PDF3lUbOW{!5Oo$bzxKR6&5fU#<0Kl5}6QOOd?pJaOKXx zO^JK!qruF6%{Ul+vIyGz^cb=r6aMdVOWp&3aTYeRJa0X`HTs8e-+Up*Vq_Dooun+Nf( zZu6y+_tsb1a!4@UVptyOSWxgXZ!-j<%xkU2H|gTJiY$RSTC93ag6AXCqgV2XUA|pf zpE>04otjm@F@!szgTMPt9{C;hJx?=%i7&j=e=QQyJ+1MC-&3z`Nr<;-vG8SHrAx)) z#s?KK{ynr7W(D$HuTvm6tW(Ki*#%rkQsq*!!Z^K{tJ;_A0+{tHd_>F^F4~8u=-#fK zV!ob&%fNX$c0)Q&pVB9$S3{ZZ8z70_Wjuh9{>(4xt)p<_*?86Eu~O&Ci$c(nV9TaP z`&C^V2cHItCZtv8!BZL5)-H+OMujUk^o*o~RkYKUqX>NzNOUMEWB_^n3XzSxuL^{v zTE5^~#!1OB@O^keKGaCm?zKfgG_N9Y99h zJiQxxZcpI&v5Jxb?b_N?F;yk~L~}0j9Ff+2RM=ZpX8}j!o!c87%2y;>aigqO`Q~_^ zA((N(xS&2be3JdK0B8PZOrw$()j{+d7nXHVa{9u=R1b$66&{bx(sxZcQs$j$y^++P zCX=}}`k5RrpRb=Ir~mmi_W#Yi!1~X;@Xx&P&%E%@yztMw@Xx&P&%E%@yztMw@Xx&P z&%E%@yztMw@Xx&P&%E%@yzu|h3y;vh4bS}e&_|XZ$6bTIG%dk z0hsvSVZ4yQA9{fmxf;lGGB^-P5g6-Se<9wl?sMv?=hN_Aw*>@gn8T!^*`gvj+&-sf z`_@COrQtn+vtBz%##Q&S(~z0q*HE&Y^St9Fsr^cpbs~Iuk-*3^S@%_}<3w?!5n2iP zs=)j&<CTU(dpcxRQ4=^Ajn07;#hzkZd_9$y)+}>7xcFp48-`u1NFO>MMDo%fq6| zM0FRoU-m%DkxrroBG~8lBXp+<$JuX2HlRw}Y^jRufuKgk?*fX^hX~0@_v6?oGgt|7 z2joQbz9=d3L^<1gx~|8lgiPBG0gN1f+jZ(^z^?k-7vGmdGN`*fUlkt(*Ga0;5o|?u zrh#kAV>yYZwnjuzoA_x`K-;aA?gv=IoeV$=YwsKwe(xn(I`IxI%0Nj*jC%*3l#7<=UiWj>>k z(B7O_hW!xp08VX4CC~w#(+=APXMul1u@7H*R)Ax{WAq2N1E$Ad`EDDlN+3o|2}58( zHVR`;zV1$?>J!ZPc=2*)?A}Lx`qE}ry=LK;k^x{DC9e#9*eIDiEzxonN4k$I zC))`J(K2fa{7p|-n_BCEVy~4bGp9=R-aLJ+*E1rX*b*Ccx}sc~=Kh}L?vJEApyTH( zBqe@x6nw;c;h?Z4q1AlZs|<1ZD9d3S{R$9hsxWU7XxY4iFMm9GG&mi0h=B{iH4rYc z0kW&QopT_s`im)0n}A2P*wC>55k{7y5+i%Kck2eK84_|QaVX5S0M*2{X1*&i-t?!k zE4RC#qtNC0e>tfM3-m8KapVls=CGqOcj+|McG=S>(9% zRhk}mh3Jr~o^c;6S}=;`5k&C^CnEFyk?ISuzyJZTyrm2Iw;9WCv_auT+_6e5RnzfE z&g}&MzZW!?B z&Hph@12T^>nGhX)O#Mc?rJN}Rk4G3l@YBhP*k;Fo6^W?tFR+TR*Q%k$$)7Q)6h8V< zN>j#3=Qa;Apob{J^)7_JCcY72rnD3nTT$&@3F_Ow3iOYpg4gvs0C2P$$nP))NsTKm zEweEKyQ}&o8?u{V@tp1NaQu15yOi-A4EQSKmlEV55Q9@Cg+L}V{0a!^B6&bd z3-fb_-8X|eTHQC5+K_K2F)Q&a!{0%#UJI6=TYOX7R9!1OuexW|7_xd`8E_o&#k+Dn z{}^hZ9|#w}*d{%GTrUm#a&vHPG)gSz}Sx1sasoDUSo|05q3S#~{ObSWLoxpDm0G!QJfUStD% zb8k*0ALCF^xA91+lx&$MH9Q|-a{e3$oeyUaAb(Pq3@&|aka)<2)3YZ1LDyNRR<|AC zRq^XX3R9|{20$wqCN5@z`!PViyQkfDR2X2sYw$PRj&8O zIU{^j@B0-4A=rOtrZH*sM}w?XBSZbUtH5k_tS<6_YBPc7fty9fojN_B4!@_VLsQ}` z<6N&BRbeeWEs&k17x*AI{J`ZM(zY^T!MaETHte0)F$Ue=*XA;wrX(2K5))+ezQ7sq zr4ZYBv-od<&gnH9mdrvm1{p^4V*b`Lj5AORkv;>GfbPEowjjt)0yx=CZ3tQM2d5%t zk;((sp;#5HPa>ldY*lqZ%H1NTeKBMLOS zMg)5N-6ica6;3c!{N7;$UTYf~-JJoF}M^lL6f~yo%jyWD) ztq!c&Q&3Q8LW29plJuQJ5|GV77qdq~q)3`TgHR8C6mZT$L_!SQ(6p^Hf;hY7X9CF? zanUv#0x+>eP-4_jv~qiGD~2DU4z{x#CK|1cRVzR@zHDMa$lJP}=3KlbBI^p5kEOj2 zgaEhq%h$|^MZXIV7}FaS8(&45gkv?eJa~1&GYM>P(cTFhKu?x$a(RCZ2_e&S)Sdkm z;zFp6{|SYU;O}9fpZkVXWG`Jhtsg%IKNY5D0|L&%reYoYN98|h@FIliPj92-3pcrQ zypWwzL|q%!?bu#nz^H01l}W5U(0=8cgF=S!>@0=2<3Zc_gy|yjn3QXSLureX5?$78 zTRefkBR+b44f`Fma134Rj`CPvC_&Ld)5SVKKl$q+cmY+TLuM%RR6h0*-a5-yRW&w% z2K#J-Z2JiJqwo!4F7XDePz0yBgCqpz{oHqP=-YZLlB5+3AYwox-AEu}N1BFO!7anc zg>x95wn{#T^ZeDJb|OGmKg!QU$23iLcS8#v;zLvyD(rT^|% za&#NVgu~@U`Bo{c8yKHt;sF3aVpdJKSlQG`1L}{AhW761Qf;cSOpEueo;Nz_BfR8< zyL>K0qr>?&ThI@vQ+1nB zB8T_)20vSU=7AMTt#|FjPrpMf;p)e?CW9s*4uxu!^(xISJ=>PxlqA(E1zVj&Xoih5 z_!>_8imkK9iNBp?EzxkVJGG1S8*pyOU|L>`qsJkJ`u5VwnH@{*ha&boTFb&}4_KN- zEP;+8GG=x}ESK$l*vDDT?0O&!t7JoL!o1H<@0tw_HJlT95TsCvrw2iQF0o5tMsb)% z(FJjRO`*kFdG%3Hh(2d5NM5sRqHo7Peb)f%6wl%m;eQIG_Q=TGw{H|jq5q+8o@6N4 z)d{7h&yyL5Zaj7W15X^U?Nhv<`kt>^qsloYdHp-)+0R?){E-TMt$h3Zdn?qvYuiJn zYP(8Jq@}E>TDSs^RfD#yIYUN1_QaLCt9!}XHGg&D2{yK}$u@U=DP5;(x%*6&g;(RW zC8JZpdV$OIQnH22{Zh1pTJux%UXa;xb6iHR<8nmsW*fiBM#}QWqyn+-51Rd2q^myw zDvi7__+ZsWxXHEuw~cG#l0~=LWiz%vQ6lT|MpGDAnro%pB^upG3YpX(ovCXh%sri2| z3^-Bj=>|@E1%Dr8tBRD+Eowb_Pm?%w%+otJInI`<b)j|n{dTl>&mp|laP>N;;?2kB%-vKsqEhuo*h0H)tj`pH^kYQTFws_yY(QP!wx>U6W@r+_ zjWOk{;uG3nyt^ELbvM^Nl^N?rlo>mc`9sERK(gjo?AyhNWhOeT0PLHnp6HWrU|=ea z5$q{Vj9L9ubICU1zI~b7S{98iZfKhkswDDp=P2Sroy>DyFznXDK}+JC44bapmRp~! z9<%2$C{Av%-IT2iU!hI3{F7aRSZ-Pia&hK3JsQQ!=a^wKSB@0Je~vjDo{YeMzIskq zzwUL-`MdO2o+<;F@){`g4kH}fn}8$Vj1x&05h3?=?I z!iPnyEtg#|cyZYtXssmH$IUS>X)~rXBb!-|-FNqWW)nB!?bEI)k8jjnW=PvVp)%zcRfC zojR5h)XlD>w2%z=d_@8pEyn~~jaap;{=nv36$;n7SKGL^kLSw{2p({ZA=5%xWIGJ% zDz)y%LRHc)67vn*440omNUu1V6MR0bPPh1>@L|O~?gOm)XOGR@r1IWu44-9$aQM7D zW*-j-W#>u(g4p2KAk0)E?1Lw}VD0exT-rppz)q*kDc+0v&gWPlVM5&(36(@w{9N(x zx#GMrt@Qe`cEE8wN8>`HWd!lqkb7{?#GFDl0bdc3b%ZoL)Wau@y)`nwmGFp({66`9 zx6+1)=lHWhy(XTLt-rp#IvVU~d^ztiH{aP^CU#fl(g~b`Eh@)uFdv{+IBMG!_~TmkmrE|9+5!fkPM>A@<^m0^pdC< z?srU_Ww<{7xPS*>Bq;0sdPijQGa?6gbWiDFRHnT?4iU`BHQndn<)sM&sFqkP-tDf> zr-$^`D`+g2SOqRE;lo*PCQrAD;?enBP4y2ZzHzyQ{W?Mcyb6ubJ!i!kB$r@{ZP{ zHYO?2`%LTZekX6_6AkniPsysC=Xy(~s0f>FkHsi;8m|M@>C# zbCQom4TT}($v2dL$OT)1G;OB>>j`+4d|vNPANyd(zf$=>ilh?|ixrc4>Q>P&_RT|H zGr1CBhZ`YJBLd$@k+aQlL?le2a4e73GEL|{M>=2r%KnSLw^+Lr$6~B1armgR=~5|c zE=ot-3xgku>(*$-9rSJ_csIw@Tprg}*5w2#sS8A$o(!MkiD>m%pcmXCfS38evJH{+JU2wEc!ZLwb zHI+mnXj&7H-W)m34))X1 zZ!bWBv0?XAuQ%_N>NG|K1{aN>I={o(k)qQ8UfarU%spM|Y0%(hdj#s)tg-L>!n&sA z;L#$e8$Ggiob9~BFIluTZVp*8J=9k)i12Jvg{)0N$})skd|c?m$hyH})yC=tJJQxna0(5-KhH&L1Vv&3mw|XGB|YId)@C$9Ag+M>0`+S(Ls5vVoUZ= zMmy}$W;bzE!$V~`NhYd~KStQ_7f0g`MR#GvE{r)!RjU|n7vpp|13$JC}FZ<08H zg3YSU1)Z7@Zdwt?Z=I!GHVr2)V=8i@ZSa+Yi})W{U5Flha_abE-IiAd?U6T@n}_oTe2g`;wU^F z$r)r2OD)r|HX%{fbUr-D9o9Spt=>cngow?B01cW03B(VbmHYN%VA`clN6*olQZq$U z9VhUZ+lSeF*f$Z3Ku4^4h!odokxXa)l2vR_50nw z%`|vOAW^C7-C3Zhy6AwkYz>2!xta6b3X9@N2D~{Dcu;*5GvYrAB05L_vq9K!KzU%} zjZ$Q>g;O-yH-4`YPJE5k#*m6u{9bJpx$VT4kvDa+_18X%>m~dY(442dtYU{E+bN`V zgp3XTwWo742b)06wt|3t0mtOHToy2%XF&-tyW=SY7}}0 zwk;rS11Rc?xY#Ltl{=E=4#7a*k?=sUI;Ig@@XE+MS3N*Qxf>aj@sF%pxdTJ~4y=P? zGZ*Ae%TsclTMS{eG13U#%>Lom-1(?)D%%PSqe68Bj{|yHRawA27Tum-}2+DlVD4-VHmtH&^LUpnMe2y3CXBB$uO>cA(7QDdgaW zNa?_!?9FPs+6&jNtjQ~ECOUADzGHbl@doF_LkLUg!4{q|sUwhLQc)U2Yu5&A@kE;I z`*#50YJS6vyel~>4gP3!E!o~IT|IOfw$AiauwA8`&X(~iOtejPC(Fb+H(TLS^q<{< zm#-f;0up{-^0_abYak!L+=LKoLj%thzJq4u;9L{#rsLw*Zw7nQM|6g2eXv> z*Nt-^n1f-#%Kj|`vTezb6}pBCk2FH<+yjZ7m96Y2!3-RFH^j}&H@E72C8RY|Qy(Go3TJbZoUr*v@kk&v#>u;=|TT(l|D(wrzxBT<~KSu_L>c5htT*O_G zx93{@tE~A8tvz#)*4BzQDY}fB<1L1Ua|>yPDFKvTsR6Zx7M_rVKYb-_i%%CldRfzt zlPua6%2PP;Iqxv<&P_^`IN4HWvaYV14$AI5N^D%#7wg?CGoqvx%lEXCg~q4caS6(f zUCIKeN>?SfbeU@i>gPK9f6rI8Ov&EY>#!b9D7I*%L^)Kgaat#@p*}8DvaFXcRxQq` zG|bWII8VuKIw9XZgEwq4Sk|wWl2T=pr7z8=t?-A-1726iKCFd%T%=t>%{V)4eezQbOqQBz+sS@n^XQ-AX8t5*Ym`G&mg zx$((wsB|NA!tR+_f3P2Z@aZ;LJ<{eLKhwV%A*)C!B)b;t(|PR)%o4A;k-JVc{&gkT zq;PpfIAYP<9@OksjJ5a+YthkeoaU!ZvC8G?C3ug>EH8XkYGB}e<+~y6XH@nl=tfVT z&=TG`oOgFO6g?7QtWkyez%{_V!eNcdnI1|XHo9e=Hi-}AD8%EQdxGel;swwmolTtz zfsHB>MV{-_(%Og?uY?)0ZL+rZ&hC#PyvJZi7C*I06!qfCeRVswSK)hBwI70c%+4Ks z0o0v6eV~PNgO?538*Qpf9B(p@umR{$j55Nv6eoa*GJ+J$`-7`~TV{Kn`UD!zF&*lX z-UOF~nibw^x~=qS%U$$R@ATmbQ_eRR&4zwfbK%d4fqd|xjPZPZ@aM5sXZozUFR_b- zhM?i+?Oi=Vh zqE?E~R*Xo9_ysL_7lDEUz+9yGXu?-#L>q+ z9=Azm(=mOSFFJ<33%DYvulJWc5? z?L+v$gJ8&(B97kHzNVo^Y_y*V*GF>BqDM~A>Y#ABVylPBy5{BW(Q*@(CV;(KZUfYr z9lp0*Fg>yn9AC>>*e@0Co@F9`I7A2KwCgls?`vxzkgwMo>U<31UvR-dGM^_zpPQoo zv#TnG)7vJ?{dM(@r?+WTiIi>F?p{8GHawafo9`y_LU7a2|Ne;^kLILHHB0sfjO5>Z!yLW2x z2bVM&E58a$z>L|`o-You5>Ng$l#2xb4_NLOX=y5Ut$=RUJYT$SY#(Bo6>#z znx&ei#k@8Aoef}bVLq=j@NCB_4M0*AMQ%!*uA$SC79eqYyWxd=S1dCww~%t?r%lGL z689ZT5;(%cm>Z=eZcjs{Ey41MXU*4m^YECVb!QxL8h_E8y` zXSg4DjKcV{pD7hKz==*rp-yl-1};}zJpiu4E=Jd|Rq^)p9{DS_0?8>kt*>O`(aV&i z%l5@DP-rF`LByUn0NPWqV1UE{4Dz$nOM7A(0d=$7c>T3Lm>~O_TR3HP);A-69K@Q) z0*ry5pGyFmvi{N!Z5UP4x9mF8zuZ?C&+95#f!1X{wJa2qaL=@-@23>$2Ey%q(!+q? zEg<2&{Xn1goed@7u=Td6FuHorg?sIsf)T4L*pQyp;gZAU(07~2{FB}?zTL1mb~zhv zTn#>cYOgxGvd2r*)UBCLZr{lDifd>fiZxkgOxZNl|H~Qnvnx^MC3QRse6F7Pn2Yw1 z((Ovo-xnw@6{I1c4bI%A4(L3zw&bDh)`zdKVn zCWT5F&UJMisq1^Nt_d!{+!joy9@U=CYD27eP<&#pM3npmFdw57d~qXaa@IRhhIt5I zMWgt!1G?sHb^tDOK0;yXdxGg;A_C%5hRAke35mj-F%Y@JKQCSY>oVe~gvWt$$nisG z9--G8dbfW^X`t)^JNlV-M|9}i9>b-3QEV7{Uv&9FdAguN&m9;uhPuT$642#r-vGQT zcY#WXteZEvpwg@z!fqP+qXN=ztXQcy3f)QJ-GX-MG`wpK5hkJ~UmH5v92Irt zYE($MsV)FWm}$Un;t9sZYdEyW+D>#~A1}^`P~7_&$zsD|Lv2vm@v;O00}T<1HqDv_ zY0jF#>>d66LllCS13Qm^eSyb!Uvc1nVhSkG%QQL*xHs(3`E`Ly3_wkQgL+5do)FYB zu3&>`Ymp{=7uS9rM39R<&o+fFSnnRO7y;J*q5}X9?Fr)6w%6_4h1(Iq=()3g=m0)D zm-Z@L^XwlwAR?-uevM+Zr0if(B8w@U1P70ADaEL}(&oLUK5SAnWCk8loH_iPE% z=#RYK(0?rvkTFYWNAv+KKibX&ikA`M5IN-5I+SDafnyhFfm=??SRP+2k2jjg8F#AG zv@sZ6XlRFRLvz5{#SwNaTv)%DxtGe5>H`x9umgPaepjZdrW&8i(BiRoz=BcQPb`3g zB6PNvhSmQ!W(zf1{2(=Aazv9FMc>i?zynT}vswKiR{nZgFZ7oiFb5Vo7+G%7KB9bY zr4UJK59AXGVECiG&?UBzg}Vo-8`vZP+NV|{!U>*MY&+1RT_Yn15F`|)i!q0!tir|W z?bgC6T%dh`pSj}H=1QvP-wnWM_QenQRrtU&2$6C=dcwjEI69AG@QpeV_yH4*U4Tbo z#a_k+Ph=%sgAwRXX@m_SEL;&x5M!=`I!+DQGm8cf?!cM!dDwAkrVt9{%+_EJcIjy2(bXTwH0tr_lD->hoZz8LgB0) zENB?3Z6t6d(=j{IDWLoYCvi3`~rUi=Qx4 zl-xZ+H-J>JpuIfwB<&9s@0NKI2t@Byb0u779BhC#pnG8*6>99g3(_2$gfE_lS0MDa z`P#L}ee(Fca%(8!J%m*Q4>@_EK{P-z;6oH<9q5l&TQRVTI6t|Lha2FYDeAn$El}t* zW)6S0T1WHQX8IhA(%D%G$cJ9j|7AwHJFlDlJD1-W(txSSyG=Ywk?;|v<|XcfuHa<~ zwzWuxN3zeT4}^8nze^uoIK!MQcVPav{5X)imLmWmHZBqBbQ_E<~6$EJM z{ccSJMAN!kIBJjx_@krQ)3ApDWVb0+*>QR~Vm|JOesWmxPi9fKG;rxoJ4IGW?Yu_d z`IdW}vv+u^2n(~6C}D8Im=wf+U=b02_krwS|Bmb_ z_@M2oM1eXla1q44hLZvZP~DrMn3?lX2g(&HhSoc9PQ3`nzoFF5RB5w!S+rsq=Jv-= zTB7C$yt(pJ$sE;+_dcOkqzER8 z`G+Zo9eJ9)Thxn5@oDod=@reBX_~01zQUC3)BF56)-2zk1I4nT(fQeoyz9g%lpaY7 zBTmjZ>;Qw`+BE{wiP(=eC9^oJ9a*==Rr6*nTo*R|c{Ffn;{37M{1SgCmaL z@C36c@t8GRvg~rPzOnCp=kKY418ah2xq=VwY3kqFX%W!Eeadj2wXVpbp0)6o-Xndq z>3{_Y^X_5&$$Z(+XLem|0gQ=0gSG24ZK{E9R(R_iCNvqeOkqE&Hn=WTJ!0oCTRXq! zvsg9J3pdQxY{D$c4V)l-yceupm(p%sGzy~42+FR{%C_>uBBRXuoiFi*9qsu0xO!NS zXX7utZzktLlubD^9iXIMK^(<`14@9XJ%4!S!U;Xl4PZA84e>5<_CTr9FRI3{^*d2^ zCb?HXf%10Q{PBA$*(?Vy@JdlT#vZP#nhl9-kvn<1Ew%|*Yr!U|N%-JHDTf;4X zZnltQQo=EbDSY)5oYd`3hc(5?oQ|F=XHn$&K&JL}i1HlJ5L7Q2oQ_;Mm6_{NMnJoJ zOsKCKSTQ4TM7O?>F&n;zDG#cO`ZYuEP-DMT0ZUJv%Sf=+SF8H1-bR0X6+r@j+rHNt z`!7a7+l4%Q4oVr>As^O$D?e40{~p2;2*E`X_Q%{r z{5#G?vQ7{${5zSjYEf~|z3o#EqZ>8ECFA~EB{2cnJ5o&}RH;9*DChY(`|0@$_FvD# z|8;u|{l9!3HfLgI{l83)5&!>x;r~+0)BRH(`=>ni-ne#&FHKjpE1=TG(T zhR4AF&F~n+e;FPdrD1l4kw$ zK=FEC4J!V4)X6!31cFN7M|>{zDKP?B07FPHQGr;mv|%(8Mms4bYA9dMA&}KPlK=n; zn8lb^6EgHe^y88w3NsLMs+T`+ZULUwgrlPby$CTwS$e%L{GL?36rUxjj~(8W2pa%jt%u9;q2Cu1i8RYh=pocU3Wz!uzRlQ>(@oOGJ;7PTgQ8@jc>^kpajV{eE z*Bg(l_HjI(9!YbY&P;nu&MHxW$PJwd0PiJLH)p}ivbk~lxKF_!xmkFgpex&XH{QMa zGd!On>s&x zlR33Ny&f+Z1!dC8c)Xy5cWU1%e}fVNy!_`136LtlK+NBBa*1xULO#LlOcUsX@v$_y z3cs#yC$ddIE!OeS8GS3RI(r@6U*^z+OaQxq3-Qg@|!nn-_#1;xM3|I*LsP2;- z8~w&sLu6K>)H+7c%>|%bx5;a2cG>A7u)+WFR)+XeEV{hUcNmB9AI`JV)ifr?9pmB zRI)oPnS<9akISCk`RiTP-;!UnYEJ-sL9JiU3rek}N4wUCeXh!w-i1f|@8c1!N$}e$ zsDH#%48+sK%TOuQ7GKiW0BXudh?)?MEtt^CY1J#S>iAgRb`e!E5g zz=1Y%E_-Mf%f4T&4Jv@nLO>_jnpG`h7tYTGqPiPoXIJBm}zCatuZA%`me=hqdIsMYEhA4 zqar!&g2=hk{4e`DsCnx*5yF@j#CqS`k0}ib1!Th>cI7?uL~hyUc&0Hj2RaR@Y2u2p zqQa0u{M^(+{GBf)iah)sJW3{SVMVc4iEe&fa&ybbc=~u^66YP4@sbEZtv z!yR^^xg&OwIZ<|jxnOqTYINM#2iQP~HMmC->u{`iRsm3nj9#fZHHMHv+8rWnqgkVZ zQ66wo86q}`j6F0;(?{4}Bp!i$RPWI^1luGru_a>#2R}Evz!)UpBD#0% zt76@PE(tZ^9|w@LY_I7j8QhfT1bXCZGh;cOh9P$x$+(gdN)LP^bKg8IMc?Z-Qhdvs z$==m%w4X2?KiAJ^rn8ni$7S<_eZTdoL9g{`-ptQ6WqnF`()=L5|8wn5pBIQcOt`j5 zqb67%Y_3wQ(mv&6rTBz)vvE$ie}{VRk9|x@I)Qrgy$3E(N=vtOtaUV0)wCT0ZHK&Q zA27Wz+o^2xwHuzAF?14MM35n^Y~aC)!i~%|)k%wSZY}3XHVk16r}GZSu)E3zzVl3D z#0755>}_yuR^Hmx3~QhtrUXO+EC9Ny9T)1E(R)kT2}`hSq@W_r8f~AvVR#HZyo)|f z)MlDQ6_QPF4Y|T=jhjhqlB)sjCr$1rQqzyTe62rRtXpB8afsIN9BWRa{qDd^#>RMe zU*#OV#%(wGNMDv;^X9QhXOfZ$y`0lb*WNxveyiNyW`6IREtY*wcJ^oNl$=J8>6xO+ zNMfaCrgm;bQeD?JVA7v&G+%jGudJus5BlS6L?OgVzw-Yuc8YN+qtoA>&<^zyS26ZR-Ngd zs`+p}ovE3A`qz)QhUDw3KxKF>*24S1U0`OWB z&`hTNq~=HqY@}?;8M=^9i0p!|FvTn{7&mkaVyAmCbo93lIQz_Vy-vEC#MSlv0 z9>eiTg-M@DY86__&?bJlMh^nv7T5axxM$V}#z%U>7|~prKGe#9S@9qh6pEEl2?8a>nMSI~Kes{4qy zgrC#D-A3Z9#Iv&c{>diZPi3XGO)B^tt{aUzFoPI@yubX6ev;-$79m#z>yfU8qhzUG zyv(>n;>ahgGL^bc{`E$hG!s#$+} zS<)f8Xmxs^V?|obkuMve)$W2u0gno3E|yH<|KikCL=PLsA#5@?2$krJmhQb z_1jb-{PBAmQ(MK65>rUQ9ALH2-uyZ#*<`Fb!Z& z;7xy_otOJ>^Q2GSBH#b^6-S1*5ZCwPAXZ55|F2#${NL)O^$#13_;p3`9jd+tvMP+I zci}u5kNj&*e?Swkxd9VVLJZi9nn;BZU2Wt0qI(m!;|g6IJThTQdr4V)sm%aw>fzzR ziT9J__yo+^ik%_@8wU%A?hGkyZ?vHOl;bIVaxKeRX};;M_Pk9|HYY*yA39p)*mO;Q zf`Kcg4JpSf_q?vclf?YYlJ!O$hV7+V6jFjbOV9LvDfnuJV%~nZkxMj3kpTPnhmOYU zz|3g%V=~N|i!}?yam9+`$=X(op`!K;Ieue=45iDVa+;CdGUNuTm(X#KT4^9TKzj8b zrPTXJznrnPt8sMW8|`nv@)elZs1a4LIw@pTveiX#CI1JGb_Cuaiatkj<;SK04l9rS zMOgI}Y69~EM~A-t14nQ2L^~P37TUSd)$O1@umE~6459!vVm6hHz~wn)Bd>nKKqkm^ zi!;8HfTrAIGG*g;;TQiAigVz`%eEqS>9HWKL+s91VAmKtu%iDn`7dmA)8#+%CGdb~ zNC7YKN(qSo+x+I@k9=uK^!dX^->oiZb=>{1(LSxEB|X(|BVm9AB<0LgIIiqJvlQPR zh+kvTczKHFOk2GVdUhs{_qtEOFeUv$(1=~*dNLBxvzu<@%aCTWMoc!_25~YA-c3RV zG-Maf26Rdo(Uvi)G7Mgq9b_U3s^MkKQ}y62>zgypIa6c$!iz#JF8B7Be2d3Wn-Uz` zoIKQnIoHrsQIt~b{fb1h+GB&%g z%b&kZu%6B-i8jnLd^rjQ{xM2Y2?&DdkEeBrF1CbVYCBJEJw=Y!V_p+9t7x%5Kwnb5 z`a6B52J(GN6kO+qkdPp4US~=6@r+K;u)TAonwQF&>wM>r_LqRX`8ha`z%y-gmwxe( zLN+vSgL#Wa z@cIFD(hw=Z;j{^neYZf{V1Bt;j(fD!fmaS-{!b3Fv#VFgMqa7NIml>N<6w$fLNfjZ zFiUeJ0J%M(J_!c2t*eIpaYg?~gAP3hnFKk4wCkTRfy7?OL!{Z?{pfUejWWrx>{| zBftIl(&FA2EjA>a>uRY5NA&QFQFuzKN)cXS8y2*#8WR(Cbkhy}dENaB7|B)r$R@5+ z!nnSl=*=!qN^NoQyMn&CBZz;stHB2Y?zmzR3L^gflea}E$+Dh;jR*z{Qnt&16q^Ig z5?w&>#VExpUV%=~9$)lwB)QAhJs!tOdPf8pJ*q(x1i2jy&z+YI*1tk)L?*{o%_dT6 zOEv@2wM0#WirQa_eD~6o$sZ7Ps!*Iy2GZ9$_Nu=Oc4HdND4#7UQi)bQ)KV^ftxO7V z$!%lYNSidnt4t?qj6XaIOZ-Z9y&H3J2OMs-->)JMXoEqXi`Hhua6htzM9M&VNg5f( z3_w&d3t~iu9a?5dMjpOSl=dn7HF8b3YQv8W2nyk)At$c1C6Ik^8*z+kq9`ZYN-5R3 zjq5O0p=tzOZ6}I@8-5L{bn}A^+Y8bdHM~%r#T^VSY|#7RTDIerm6jb{aR=9jt}x2a zkuQx?80jr&Gc@&>@MPs6FNqP(U)@^7WRuH#gjp?q? zRM!aX2?0o%;kDa4_4VGKAT!`QftW3MG?1$x3~(Hb&|{#Ppl=~Z__^kS0Qes}dioDB z0N@p>w}&BwQ9aIr1Apnn1k>mCbWtAv;|x9tSe`O@g1|ubLw`^`x_#lli=-g({2UL)mo(H%D;(6%Gwat27!NV=Ls}FkM~bglVNd z9>pEmf8&KG!GCyR_cxBfSgep(ERis5nKDxrFje581J=KJyS1Ce`08;tB@);XXgLwB z!4ZC&pVNms&Fc#+*tU~Zzui_Df*$v3d4c^>oi|Jb*^=#74Dcm85%t^9x`047Cdf{h zflUTYMAek!p+skaw}Wv;1QcuJRn-KI zd$E!&LlS1c(Oj{H^2LLt08t2+xbrzXR{~^~HTN3<*Un(~K=wFgq~sK65k6`IbZQUI z_|ABNDuu%NxphTHZnOd!hT-b5$QJ#?>&F30eoZxtZyxfGxdPMGTvdY76V-T@9*LP; z1#}$kd8HA?2G#339q~Muqj6%+7=Z>;;iug?7NP3Mib2%@w0;12UV2Ax!dr!x7&l!^Fgv_4q~lW4>r^eIaO+3Q@0O7Lp}OX{q_UvWUnNB zeVYG~1YrbQv6r^ME4<-=;CX!)+CwsB;u0pz=KqldmkZzY(3K3>& zb_J9TBepW=Pz^8_F+KF&fm9go1IG@u7wz;?eOs?AyKHJ4*UT(r%TF=j;jwdw<0rF8 zlnw%jZ3PDgQC!ov4^WTnbjaL0I70^9ChX9z*PO||Oh)dIR-E{S;5aDI0&{v{23$EP zdRhcjQ>hg*x_OwTf+rO_iAAp7v36Nmcea>s$v{~_S8dyXJo`|?c$VA|B3z}*G0nK` z1iZxamkkdu{I^`oKd(EI6Hw&KP5*(&ZEu)AVdM0sT{^juBuSTJ{0Zh5o-OiN zMU)%Koqc4FmC2>uk>($a1T~b~22Xh9KD3pQl;G)Mx2P%K-_)lChzRz``g-lu0YjAI zNUXjQ_JOQWy#?+I%xEB3p{>T8dJ8K#OV|qm0`PM^RE$dQnyooS+ZWx`sO|&_IdL(W-G?e;m%8GmqI) z-FP%9@Kz@8b@HTZzY-}B>EJExy=k7~A-@}w_mq2K+Y?N+f*T~##SIT%BA2(n6ggK` zDVnknM2gufD^uPeWOH2%_`w}kY|_2#)-J>Dg#i+*6+EO5Bw3kfH8vADbYq0be%Ff4X+`fDEK22R)>1wlESJ334(c`#TVeVDOanksbyKLn|%dw=R z&E=e)m5m0IUPVb?`CQ%te7TR;4)Xn#`?#)=0JkwEH~2?xUZoL*LfQCZW)|CmfDMdc$V_67P$g(o zjP{lAt^orq**0eb?XY8%b(Q;ffo3RIK9GMO@}@9JlC;LLC}+l=w-Ef~&B!dgZ@-G3 z!wKCz`~t+hn+j1076Zy%ri+}KG8;nLLU`9#BCg}{kB#$9H}pRcGT733=v{fDCQ2Bj zvdEf!9)vrLXxoL(!=$m9%fTR8IZ}oJJqYteVQ2WrjnLD`^``i&3K0fM{_b>EMB_ z`}AUJommLKWbpj$NG4c*Q{z^W3XXGM73B-U44&7I2L}nzJM9>NMaVS%@~+r(q&iOw zEmyMz@WS8V{$)!+FIST~>whR@kREBH#gQKhIVZS(n}7HBSs|KB#ttOoY({uG#6J{r zOb&|dKNK?guYt{ZU1@aB$hMa9^PR zwc%EjSo@baFaSV20>FkC;S~7%EU%t{$_%a4s!U912x!)3fFVd6>p%JjQ5x^re7}~FPnhg zHlj3vumvplyPvqc$BvwVfZFvOlWDfkBB})fqE=&@x>k(4i!FUcm^i_;VV@)!(%tJX z(_RSuyAR-#8cj|j&;wk--Hea!y{36D;XQjiFxXebA~B1uZpeO9Ceb56srI<}etkv> zeOR`{YKk@u0tQR=0kQ8H9`%`Tks*`GB0pG%8QVqQIt4O}JqFyH6L8@#ktUnOvtNJ) zsY$C>ub)n4QTJXnIh?36{6yvkg01TG;J>*Xgq5TQuY!48H?1QTRlVx86lQoFhw}X2 z?#;$Jo_r8`Fqtx)I z3VBKC*OB5-etXWZtVFe1h!A8_yY*{*)ptmvAFbaGgbgFu)VOA8x&N*gQvslbI$}JP z!nl00GG#$Z;=F%l*m7&#zAPG|v)RVM;s1Y7r&q~!^hj8159%PdTAyB#w>yGOYK)%EHePYUWU zDM^!c&mJ_@>NH^?URxY59(FaF`+!bgjfe4tD1Bao)ziP{VdHzVXD}$$btY;E33MU&EbxM?lUq=hb z_X4T#g4hKVluL}kOQI!qq6ZOv4J*EDqWjnE{BJqx-!ja<5?&*Xf1{0;H?*Y-b;=Svofbg;;Ftl@6}fK-|P^LYNN z#;ef+?A(CP|hrymIdwBdX@}9&F)}wO#n?beYgyqn$F2zk`)HT2gCM zS0Tm9Dv(Ah17onROck&A@>MCc0~DQhD)^c{ItZ=Ul#E<;~Azm z_cHE6N*Pg1=^TRyEIqBDQX!|Aj$j6$!^egsN>2yklgPu(+-+|H!8N%8AUDw1l)jqS3cej=FuRt32(!_FO2Z8ilJKT2A z!a8x;ZN$gS#2K3Lbzya43-vPJ@6F?FIn9#NFI*{48*69@9o}@7)d*FMZWM`_D^n43 zccNqfY_=%MB!?{O7@%e-#C9p4^$Zt`CJIJ46KuEJf%Tlw@>x^(-2^{&bEm%8;(Zs#dGv>pO%=m=yoECUWbWuLa_fkT1 znLo-=3HKN~xkqY#`DpK{BK2szEDhIGgsJgQLprF$HUwm%98}_&g0fR0n1%&dBy~o{ zszn7Xk^M`UN>vgZzqw+A)*C65r1yHM78Xc>7?&k1t}*~gCnGECCsvkMK>4pB>6}k^ zckx~gLwE}L7-SfS5bb(CSOK$6j)Fx|*t)z_8pT+tEfOWME`UKrZWwZ0jUSyd9WNrD zVjLV>B@r~AQGNHNaS@m7*V5AnM4G>?$0Dsb!*F162QgnjAVah?K1I*NXOpYF2jnno zk8AHBYV!SPJ=CYt+_dH6y#va9Xf6u#9kb9dOwD3o|CY4td|MZd!~hJqo~?@IW-3lX z3O}$6X0oizR(xGm&4}bkjJp1@(yRl889R!SIjFJ*f0D|&R)(sbrf`yqe37z}If}AI z736wlp+!TFx^vbmH^(C=?VxNa!UrE$Yxa|^2b&2JQa*Meo-EH`9$Bzhe}6Kmeym*Y zX01J=jUWr61vaF*%3@|@JLp<^ImU{OLV*_VlEz!0(Y;A*1hg|rS<8YDyzQ!)J`&9R zbdXcAmxIh~qaHZDD*VNAwE2h%a^LWPOT)qm&}0#>trV&NZ#1MBZX{x{x2TEc9X^_( zYx?hXF|~J9e`ETSDxL-e1=82&SbC9Ps@$CLt|E7==K@B!OZUL~$3(oHNd7QB&hB`B zD8>vc!_=AJKrD#18%wW-N0%=v`2BJgs zMF+&H^#{xTV<{8tVK`LdAODwNKh1ogCHSww`9Mo_`X?M`o{zRg|JUGyKEgFxULfBZ zy|h@D?vcS;!*`Zj>Z~+YQ}c9y)v|wt9FV?6v+Z#o?&wKNg7fkkoR~u=`BIv=-<$OE zp<&b%y%KBH{+8K}YIHIWwy@@A1O)nw*x+d7;=|U!<9(-y-V`f;z7Z)Roodz*{YZhP z=js>}i(ZV1yJX6AyIjXYcY0~x-0aZx^F%=(noG*}uHxjv)vdpMDZbTXAkCA;PcQ=DM3<>xN1OcM1M9h!hW zR=k?|sKh%<1>IZYB-ldit@Gf@a~P0#+(>*r$OCkqsV7yt=%qBG>JUYRXZc@ibCimT zt1_8oCzQ>W_7U&U>eE)lD@6O0?crTC%D&mLiuX(`ZOwjd{HwDKHZ;rxGMFj(4a4XT zmCC#cOHVDFfm9H|f~6-k>d1)2B!3hTm8URqYKjpO7*2l9TqL?5-!JJP7PylzWGa{Z z<`N|QFZClXEhUNEI?5()ZSuFL)qJIT4XkF~$|1y%7TfL@8l z4h`4q8C*?iCs-3F0=4V$AI~}KO~c6VPd7e-ple#@fMopcW8kr=WovFC{+bWwSS=Q> z)!(Hz_^8!}Or4BJHB!QRGXNAhM%dJ#eN2N%OM=1<^D_YH6^8ByEDqI_{Kaw^y}r2Q zJ>Fc8H$ZY<1RDaw?19icC;aD6Ep(VPY+P$9yrG?TA8a!7>YjLQ=0gT;ug`=?O-VxE zLp`Io6IFvka~eqVFCu>+!HfZQb0@f8>3CMKZwYg`6A-|{#qdw-pO^%8(2XQW5l7S+ z?=@cGWEx;hd&Fwd|!_M&i)J@kEIxtLT~clO?7t1l4E8@YnZ)eXzn z0o4rNzu>4i&`Nl{cTp-IJSC!AdAdcYc>>B=n_urk>YFCo8q)po8?YIfKvn1~Xm$pX z=Z(1{j8ZTcM!#!B@`44D3Kl8UWe1gi^#^}yNX3!sC5gj_DlGf<80ty5C?IFHHvBkn zC!4ggfp4}W0_0)x{EQik+aT)VuW(#4j~On6fQcZeM2#V(devrcJ_hqloU2Zeq;`SJ z>LGF8xIG0;6cl6h!w|^Wq1I!zl*$Q*IY9mjGe?^JJ1%I_4%1>6im)cskJ98l+-}#G z=GT6A0AbIS87n}AkADP|?MopT<_^4kvj_T@Y**TU(oSv*KjgS(J9Z@d3uJ2RaP*5l zd6w+&mZ5^e(HR88K{6BK!DsNtDGW5cYJz!*@5YIX27@c&%haN4aqbNHMvSbfQmmbW zquS)2>unR-ScpBJPAG=g5Dw9=wS*S7Q3gTSSlYc4?Jva8KX8Hal8b*U=)$-V=r+Y5MCB97APscCn9K=h^rF5NQgZXfhUK=F;>&~b7lq8 z^3JL&Y{xQMV&TzFhTCUCraN;bu}RP-P=t^DPrO4z(Q4CoQbT0%zYjYE+q;OT$BjU0 zKz_Tq5$XTp*ubK{wi+4wG-Bb%4HR+Dj~&U|?U<$jM@J36Gy7(xH#SKjiFg_A;DvabEh(*bTQlB7+O+fTmXKU;^v!rOr>P8VV z=z6%^G<~6rls>E&(HooMhG_K_s05nO=D`b0R6`^BI4wtZz6g_l{Z`?z;rfqhkA=NH z5LG)Qixld&dOy`yWTp4RlY+}*-YCvC(MX{^gmzF!=;Uz}qXF|TQ5XTo^8k!nejR2I z2>YGzjx|(rh)L!viUfBpQKrF6mg)eBEya8_ohfS6_%yt2F3(_vVe6mId59>0m3Y@% z;qc7SQ_pBwQ|Y#pHQZKOujX!3lkXul!`&BQ90=`=!G+c0re9+c0hQ|gtJaWI9;V<}kmR6O;Q05~4Lg4<1p^^w1q3hZ(RD{o z&7QK|MTpnuuh)zdLM{EjZ=mP4S|LV5v&#`}Gd?oykVgSx+h$EJC%Q)m6{+1zZI_Mf z;%^I?UMLF<`-B5mvIL*@GTjlUBdjS2@&)V&r?L)r%3?V;Br>|ml7ntI#snObxU5eF zHil|`9x;K6EjWdRzYj*)r1!^SMx?)XwrYs>?(aQwK-A~&FZEUkZW^75%kZ!I`jxME z6WXW9+mJVl3BHN&mza!x#Gc}%6N~9;hi`m*O7&4;>UM@zbMXqffm9C25;jwD15yXFWuw%hUy0$J62dfWcN9pkG$`&Pan}rSQ%VP!gc)h0@)Yxj zqw*y684-`Y(I1i|cQa+9J&p%CjBzVvqn^>7(?UK{!aVi|BT@&(6b{32DQTlR6b?giT~Y_3 zN(Y3ZKBGcg#RRx)cPvP+D@q5vYqbqMK8yuN@S@4 z%Nn%CT0O2VD7>?o{|5bmy{Hm{dxmw&`MagNK<#-SehFEn?KMUJ*B-Uy%Km#|fE!+G zQs45mm9KtYn$tr+s)w4LQ7n6=$-a%0FO*mV(8LjH#F!L>Yay4$K}fH*1=lc1;1vDd zGk7I8tVGNQVtWFOMWZh+R?IdC#NDYAWwO>PWN$yk6nu$BNxg#o;RL7zELE&-wm zx<6e?Z33@yBIpsipE2!*D)2^&gi98Y1V)4CBU0OO79xKY$gZqt<47g9!wQ1Q9Eyln zYE{a=1`-+K!~KZ2v|)5a67-N3lz&UAQDbn)5uyqwLM5X0fi@2XJ?rgsdxtXP(BO@p zROnmB6avp;=Y3$Sgm&nq`162trHa0Ga)6b>z6qf$!1(aO`OLpoLi(xRUvt z->w~k036cap3K9rA`G)k5c{hER94I5it}j<-aw|db?SGTog#|sg56`a&D}C^K>W#^_Tjqmdl|vU6m6ci;Q=aLk7n! zS2woSYD7a?3g|BqsygS%MM2I4^-CzZ(IBg|-5BR7K}oL3i{)`CJi1+RBomY8QTKg2kz2>X z$|*d%g5JU@e6qx7;}$VnV*2+EIZt$^^|UO2XS(&WOkiW0Nr$5GvT|55xH-%IvebS9 z9P=sg_M+Euz+o0@7zh7~JU`rcsPg5Jwl9tu&@CM?Iiwnf-tualJda#26<&<(MBCw@f(>u z2Q)-VeI=Pph=j>tJvD-ui$EiJhr#frtOXv~FJbz)O!pxEqFYsdW;t)#uMd2?Xk2}l z`9sKcH~O@^7Vf?Pmp-70w}{w6Y;~am{}>dWK7wo2u9xu=Q_Sxl(6x*(-JCBk2%!pzI588_35SN!*l@;EM zjM3Y#Y8M##g%=mojfgQAFlN3;?$=JmvzDG~+!vcGsv5oUTga-f3s{$1 zI}vh{#vRhaZi?1(h0ok9a)do_>GbIp!XJe@Ox1ALV$eZs`L<*;k~nwAJzCeQj`F(m#6( zxjS`ls(I1))m_#wF)SPy<*xVBnYBb_w=-3{Tc+vi>WK<#isouB@=B&z)pEEza!A8NuX&LwA78cAwrr=E?%m zj?Oej{bJLFRu7~XB+_g;QUm#&NPZ_WaJ1oQ%rZ3u2gX_(m9fH=@kK00zHHCQcA!@I z3-!2t&vA?^q=j~vlHwut6Ir(dDZ7_MjEoMhJ)y*@5H(g-U`*28bu}cRH-wyY7ay2x z^txGePt4r#2ICC-epWVtMxbyRv5J0>Lc!y~l~_#^EC&s7M9YVnxAiK^vFFTXKfaWi zpwiXBhu@P7f&!O8N3(~`Mu%ZH7l`qRh2}dObwi-Y8KE+MMXIQQ9UYu56R6ijC{Bnb zG9~yglcZF4YcRcSnd)C48pepSp!f-~9fbZ8RuHWndflXcU|f-#VN9ZRHj}-L1UO`% zLs+oDJdPmX!KG>JEMjOhgCxG=z=~FosIeDBiaKUyMB$Q4lsiZ_v9R`-uZqPC3(jkO z9O3M|(E@k?@>d2ai^QH{x?^KO->Ne3L&cmA*8n$P*=6XUhF1voneJZGK66wbJ$>JP zzgTeR`U8|tK)%@MNPlq#--Z5SbZ{LJ73rRJs_cdPlsBq{>PCB;r3_@A1TCdgW8N`2 z0Q9JQYEfCtX*UwU zf={3Q0qd*#SY@{oAo&uuHdHAWTg2EVq};miR{;xxO$=| zJJb1MRH+P1)}SWG!-J}o z06tHmleZSfN6T4ggTSq{Hd5Xzby#HkMq}yj{ppE)eXx|sCY2;vqARZ24nDSMEjC`w zFg1F8W1mkMc`X(*InIxaT`Jdsw?CHAt4`C%_N2leY9x}xA1@zicK}riAxjWaGdaOr z1{5U-QiCJ|!N|GyhglY5Vph`W7=(forlqUEHpL<$EX@r-G7@$cBCN*7oTh8g+s#OB zBp+$@+Ddohm@HWv?#9M&R0&%PA^4p(^(=vf2f~A=w`0&4%&z&E`gHg$UajM0=y(P< zd_l?!Fy6Ng7+{LHIJ^+XNTkrGU6vtnt99f4LjZOY!k3TZMm=j~OC5pd9+H`c29i}x zsRThUK;K`ncQh8Yc*W;T$?l2Am!(6FNa5EeTZ~@AqE= zC^6min@OY8IXfJe7dw;x442fGGV@~$S;s=3~?3~NEeZvoq?@z$xsNkv$ zKRQ__Gx97;PdC&vPF3_Gc_k?C{dsGw^M1Is>N(os zG!x@UwfS0bK~R&)7-^xpVkz=twS>9kac|KRRO?jBdm^T8;fx7+5&7GWwaSels6v@X zwVagn$3dapLxG!31x`0hg>HRYHHJd;t-D**vkLdxTi!*JfGYDAfSkQz3clR-XErur zvY-G{g!XPX0a{!nWHnr%|K`UNOU(rd1Y|vJRVlVvXc+g|#spK*#9A6A)K)I$6f!NR-Nj61g&k3F94U;+t zB@+c~H`P+CN0pOL(Gg&_Cyyzt@p1eYFmg0gu}B*itO~{a2XJKjk%SS)wt3lIyFqLfU;rVkcG)1^j3cW`3TUM9E;hG>? z%Dy5`;rnre?_$X6itUk!o4Cr`+YIg3+aB;;52Z=Rpmo|*6W{CT4EjkK=dIJ+z!?Y! zk>MoJUcq5urI7gmr%a2DU+Dt^&=sgLwqmtw@}j{X50d9Ki)H*dBu$Zv%k{Z1*j=SE zURwM68bhxlkQ3U% zeTR!BD|)d0b#5AWil|gsu5p*1JQc8w1-imRzTWp#?d!p|2fqc0pORbK415r3)VX!^ zMVQi#I7E0Li;E^Ul+dU7t`4(WnjooWRG*CBJS_-H_Dzg@6nZ9}8jf9z=Bt>koD`fu zB$=3KPW^Kywiu$WF3KH(m{C9{4$MojAy$Z_K6S5{TnnkGsmar`>p#gmju~k0L)~iC z7wS>pfDl?YE4z{M+e96URELotr~0(?)te(?F=O`|K+T7bn~@4QaijNP?IT~G=+2qI zOW+lQ+@7oecj~B+R87^|F~OptdaLK6`QVM3LT~=gdyO&n(S4n?{$ot3vA-WJ6GCv1 zhQUNVGgly)-3>B^p2#~ELX;kPOuQUT99J4NxS;gN>Z-m!4CPC&bTc_AcTSSx?Qt?A z;-Z9AtEDCe7S|Tu4E$BYi~z%o;~P~?T$d=;_ReX@nx`lSb1^|ZUo}1g06O6$G06EG zL2z}80Uyutz5EnnAmJ`9#0g25u0=o}aXq`)>X#Y3v%jYW)^9CSv992L?N+vSZndDc zifoq;ikh_Dhb!^nVm2!y2)oD9G&er&q4n_e#`{vF5kkogyL8J1ghA3ojl-^dtSQ@E z-L#DQu>?AayLyW7pUI@XRF3M)9qCPE5g@o_qrJx{Q<-Pe46}3H@R7$I|mu?V6J0>m0h8fxtZZV z27Ymo!${ulAB#8;5{jHXj9t2e7iYiOkIt$u$LBhxE^?KJzemnj4v|nh)8U~tHA-uv ziOXWnxhaK9ePMr1en9w|#EN$+brxGgXLxg6Jc=&O5i}h*b(m$*V0;$u4O>?ncW0Oj z>6ecvjwuBxjXH}FE@wS@Eu3r4uP~qa`4UtK#$Hs(k%LQbud@sXR;)H&OAShc^=bPb5#J-#=b>!-S!kilspo4AM+m5fJ-CfyfDPUhi6V*4|jlJ)*;(<-rn z{Hq9cO`As~m_<>{48$54D3w@kr{uXCL&ty|MGI8h;7EvE~y|iZQ0%7gKdpW)-__cDlGvcqeA(ebCh31dEh7w3=LxH1C zgTa7@xIl6Hc>(Sz#0BAspr)FYB=@bOG59*|a7cd;qD{yg)ok_#v|Lm89a8$z4v|(U ztgenfi|Qb7+e_-$|CaVvaLq}osEj6?%CcNrj^&}4RW9}~Hu_+I#0xJ>CSq5j@^0iN52)O;t*QWiHC7@5ZD8!BohZoF4VWy#w*Asje5 zmRLR`F;UN5YZkl#{t2q71bU;i2n?jMP+JFnGXJUj?onmSVzb$TqUXJ?wnx7Av|nY5 z(R3J*N1u8UYXA=^L*4i;UC1I$h^6$n952@Rdv;3+elObOus*moa$im$IKgT`IMj;i z0&l%vXE2H;Lk`&BED)2bg$hV;S{*+<3=d``T;AtV0yMU?9n-0uWAJ6k6J;Qk>Q_9O z0^fVJR^qNny9+8lh#8vT2qSd+f%4ZpA**bNDa^NftgS%h1uVuISb%E9Pzn&O{zETnKYfJ_dZ;ws$77@maD7bV^9G7Yx$H zibx6TzdAp7GS)SciRlJ!_|**@mySR!IjCo8c`pQdgV)rsiXuYkLLdbbQORrRaQ2vh zB?wHkwBoTXh73Y1_QwXmhCqT!!e9?Wg0eyWEF$`@P8hq8Gf43u{-v&HN|^8{V1Xy^ z?~~Yrox*b=a$Oc@xDN3Gjug#MaTgQ86Sdv)lH|u37ntNh6k&Nx^{r{#yMvB7ku22= zd}GcJlHr+$yQdd_9Pg1>pimM=gp-yuc~^(QtNAUwn3qfThEcnQD!vUF8oT4u33dPK zfB%w?@3_780yK6WU9X|yQ{hP{7@=|gXc=fByiAsXj-$pPRoZ0Hp^*fXH1H{q}k=u7Divnxr*8lsN#G5$p=lpb~Yh?>w`xc;X0%`WVDd9Rdg(P zn^{?YzLuD2ev-5dAOxL`2C(BoA()@bq;A}bz#x7Ydo#n>*~?hmPqy= zm!_^Cm!?BQMO*E0d2BEpntxoH@DgV>CEy~hUE^DhFD?Bln`&-Xmov1xR=O`#oNw#r zZCQtM*GpYx){|_cd73aUtFaz2rx@8QohetmKfQUmgI+xITs1uep*5p|1`~qjP1=#b zO65Kh;Mi;qyRe?72e(~BZK=1P%O5DQ*%v!hAA=O&H{%BpVB(3%JJw4|xVv)fuDRIx z6>%=|=if4j9<^+p2Jym&$I2cQyC`25%t^sY5#6`*F0*b#zl>3z`N5eM=*DapAPMLr7^PjgZf+TmyA z14nCRt`l&BcDta@DUXg`#qQ;AN-t%4K;{o~b%uIfcG;ECALFu;jCQs+eGdXTv*_fy!J)c>Wkdy_8@IQ3<6nV&VP<8XHZ&F?j1jN!ObK#=&o*U+-jWt7wX%XQ8 zUpYuPDz0kv7hfM@;d{_ALk~ES9PEjX5Z|_90w^h7XP*}FgRy87*BnBh<`=$Op7if* z3j)6YI@54}04C=DydsN)FmZI+$#k9fFqarlJBoQf#j_fxLT}MxmLK?)DYdo@J2@@0 zsw{%3>c${z&j zxmr);nja8x=Vw|9-TzqU`j7r;1wm>%X9r^|cU@Cs8)FB3Cu1Wzy8o^8HI$@oyUqtc za@?lS6DX{!KyEIzQ>36Au1RJSM#o>SL=I#CUJe{aIMQ-$JIta-rz}oe)w#9S_T_kS z#fd&4^b2uZ;))1f)Zxy^Ge*ww74P|?Gl?}mbR{XhaVVv@@gU+=;;b_9yw)NDjF)=9 zP((*&=#cUTMO`?3WwfP`f>j}I8t~IZ(`{wx&F`IHm3~m=IKFa8?8o_SM zGS*{3L91y2p)S96L*!zf4gd9}_^Xi8RzeruDa#@?o2A{v3ss#W^CyER%!IX(v?#hK zb-knc7VcV)%5Lo5lqmc$*(6(k z=cx^7U&9L-11k2tc^zN6LfHBkyJNZSJb^+{ujouabN_=_UvO?FaxfjfmeN5*tUtiZ zeyQ(b53y~ABZiMaT>^W~^iD8`1i{`3Bb{^AQ=l15zA^WO+Ko)KNV6en%nK2qzZYCg zAQxpmyLjjKnUjlEE&-F9Kh3`<)t{l`OloDnuw+_ov*hYD`MYqA>!O-wFK8~hC1qrk zzAvX=G{Lzlqo{g31WZ;JtFh)-C!C8N-OL>{&Ay|?qyb2VJTpsFtlY6y7*7kuDP}qz zKe8ZAo=@sF)eDfyHQzg&-k#3Z(LFDvQ=^Lwk98ceubc$$G=vNVMOjULFHcGE;%-NenL+)u@RapeIurI z1YXQ+x4&sn#kst|rSXoL+7y0cyMC3}i_T46s;vKIB6ZOjU@PuZp{1cRSb~h>YB*^c zUbFxDZv|jw#|jy!p8_xjBLD!!|9CL|y#S0yjVEbqXKsu~Mo;&D)90S9>#fb-J(iE0 zW`B)<6s_>^(-L7X33duIZ#4Mgr>iuh>pirr7_$Igu5oCo{HKUzW<1sks1P!m3|+Du09nVs!f2BDOp1 zAZVr{G%KwoTNrZQHhO+qP}nwlk9%+qOC5%-FWgmG}Mr z?zR4|)m>dR#=ZCK+#926T+ex(2VchFmL}YsF7kS8`!%Q92?8}ip#4;UCPd`BZiY_Jqe zrb&=7+GjnG+`lJec4fQ(bx+LrgyrEO8qKcYtbFWGO;&cTSA^;WA>AViHALnIdSah6~Cb5 zty%B2=d{UdT7XC3jAxwp*nupjM+yDHrP z2?6)(z|iM$5eRP#+3wIr$hfSNiEE-c>tQfx0Aw^QgN8`IA@m~UCVte?@tVll4bK5yG3@_)Dyes_5q8Z8&vKAdLyl(< z(e%hlBY`DAc;lm_Mg@+2VDshn8~i@2DVKqF?? zTiYBkubwjS5#wY@YJwUChTszT-)e!tNiiaPePY<>S7xA5oA&+`oU&lRRr4(GggCGJ z{oSVs`8+<>u30w3&IpLW(&?LqO#qK~D9id2$f7Y>fE*sy?W+Q5^?=X2dvj&z_84_b z*BNgElQPHX&g=nCnb*@(_YTu@W;z-+U!~eLjIY@GGBek+Gxc z_|8aHGDCX;PCQ0NM+z z8QFFxGJSSZdFQb|D*JpSRUT`c+~LHnC+@#0`=l_$0=|rJc6Kd5ibRITI&dgp_v@jo9+i&p1_(l#q-k*x4kfAs$z3)zJ5y#m zk4#{-a6V(w^z`5GdD!%*KHA~tzCgdBUw9%?KB(NBf@=Cv-FU8+ z!5`zel)#03o;5ktZrSq%Pdb-7aFvvZ50mHTtbINYn-PleJB%Uvu3P|kUqSm>;JO%f z6^UUODm;O2HZYPVk8e2m61vfM^8Cq7?+|^Tj>Fl^oYhc2_zxMO!#VkGHVr-i@>%ff zY4wMcHiFWMf2cxJUdD`q%}PUH)s6NS3bR2b-#S014b8zS~%kcnh02HwJM}WW9mf6Ox0R z&9=oo8Y^jp1M6J_?<#OW5YupdwRi*OfAeo)e!9E0yX237q^`J`{yanLF;Kp z95cgQc)-h(ij6VrvBO;`cKQXgus#yP@^qY;2GgC-qAdzq7MhQkYxY1jMAS|A2!nY5 z2+X{M^kISr;+UaCHNj%u77SQ$lKZ|Ht8M_oF^4I(thEX-PN9s~v-_#?9_gW)NK&ww zE)5PsA98D#7;2Ne9ni%CC>yD>X^$8csm2dmX# zk_GKC0zzq&DbWMu2!>@soIlQZK%owni!GNdCED?Bc7fz|lpTc7beKY(6~6uwL&YE9 z7SkKMVh$x#|AtX?(uUYtrc3~Ih;XScxix&}n)XCRi2+I)>LT*Eer^%jx!;JgYtcp& zvPx`8QB}SD{4pgW=b>eR`Iq7H&`5!6*a|{dQEj4zY@l-_%!NDG@2L2`Cm>DdXt|y{ z;VdN3y>SrvzE`N4=k;lMT z{9Z+sJEx9k2;cz_24QF>0|ay-F!J~(J&FZU)liy{}tHJ9-8LM*rmdcW9bpn~}Fo3&&-M-|8goiDbz(io` zfauBCQ_PdOml*Jxk3}mOG4jEh%DEcLy#Su|)Ycj*6;_CfQp*0};95+o$Q^fYV?8Qy zcUBsYBlI*pGnYzUCJ5~*BrtfYbLZKaMZf7W$jZ#+n$nE1p!Ym$5Dj!~XS|*EN_F@R6 zzmGWHc_NsG0)6(v@PIRz-{}Vl05d+r*_prlQ?}42graV)_;)}9oym0bSQ1LhJYf^7 z6V@TNweI<2-31VMe&8pQ<`H~kFy0za=nu{KiwNuy7?(EW8Z(8lC*e?N=Zh_NjVKuo z;XJ7X!UKpNB*)k=6CRA+1ALBmoD*-QT4*l^8stNRkLlur$B##*3hp_=G?b>F^3Jtb z{OtEU*t*g6+<`FZS`$bG^&-Og<|1q)47op=R>E|!;9&t)P@zsjkKINPW6BTU4jEcQ z?&wcPb#O3UApNkI&`4$zh!&_BZA8u2eYfI5BO|t;cu`GZ_Slbf|G40!DsqZJY3S&> zpR(s2Jvx+hqE-NN&k6{NK$$+g1vLzCiiHQFP*Ttz8Bq{0ME01`X#&MB@h zuMiHWVe;)kM?Tvs(zVMQ9U1MQKYadvzw&pGZ@EBfU~*uCAN&OE&XE*sFs1T0*9pAW zadk_DWr=yff+Mg(6$jQ>$maAW`;>=QOjkOyA@{-IS9{mDU2h}*My*<0lZTr|^fdCae&PAzfjjt`gmTR7RI9p@Btnb@j==LNz->7Bc zJvH*b6i*RSh`wN2*py3!Nwy_SD}lSRn8CZBHSP67FQ!8y)j$&nEy0ZV7bf;aZf_U` z4h*OHDj#1U3{d571HhIEI!Q{5Qj&}g9umMyXj-qaUc^dR+f5xGU_*?GJ4F@i8F1}VSNBJw2uBn{P04npaTJvyLS9O4^tzJ>cTx8lUFMZb@iN+HI)K}EPOq5oOM2+hyoNVdeGL99N^AlLxclHQZcQfT= zVnUHurZ9l3xF@dtsHDnM=$f66$1f;q0|%2ms_n#&0>PmT*?khzB@d&iv-di|il){&08;YEJA@utkzD@k$0w(W@Y zba05T1TQRo-%C4xM5aT#P;@}kCX#G`3*x92Ir>AN0xdI|G;N|4;?O@p zMyhh&u{>o0^cVF9XR7S{Bl@KI0-ohn=hl>Ic~QG!BF7XI=spiitR|VW^-qgDdPEBW zG9rgIjm83 z>VZ1})t~UAm5KDLB7K}ez72Py`FDDWku`lsO@Mpo!CoBUg#F2!?1%9JJJ?@op{uD{(s#LT?G!;pi2G46DoGt%$_8O8+l01v@Wxwdy1))eNj zLg9-J<4Om7naM!TUC=hUg=J<$M+h(reewsPgOR4ev_jJy|~3GkxFssUqF zLkm=DRpWG1src~?zb2f&5dbW-^h;_Y#~fEkNP|o#RI7+y=y0e-TqyX9RYuvL1?nlk zz|$P~-B;=3cUJ=80dfo~b~|e7szOyVQ3^GvxbjN4>h~+*bs`_GSb_N{M{vSO5DhZwai&WZNMvIvY_hceu6xbWpVXl7Ho*kO88ov5v_b1( zpCk96#!&^t-E?w(UDgOZY*pUN+@aqxyMMVNU(Gwz0u1;Y$U#cr{23?K%YMWUTyr$9 zKq}^Ibvt|U3TA6~ZYogg5!T?2+ehqhxZjamfq>AeSDs8j)r zq#ksMFYd>x=Ceri`ID<`hjGHUkqiJvimf%E6I>C#`E)m^QSx$CqDY79 zhvy6ArHdL;krpw8jo(S`^YLB;l+8V4)Z`T;?ES~|7O ze$eVy`-gh9v()w*;svz5F^8&ueXF>ZzG5ct6Z*f;Vd*MRae96Vs{?*&$p3faCI@{} zXJdUAdwpX=2WNd7dt+-lCsXtP(*!m(ZWFrS0A(c4`p{pah7`YDk**14l>&LZscu** zn=ShD{>2uZ4yCyDnfLhBW5)AWe5#P>9qM_BO4t#UONg|qY5|T}1Xhqy-EUH_Agmx_ z2X$ChPF2;3&N&I>ud2iGd6^P06?wM5BG}eZXA}Lq7J~M{GNv-J8MyW1H0J2<#<`B5 z4_Dyl4WtCycum3g<3@9bJ21;FGRphUfNXoQw;*jcH=xC}$S*Z|nY~}j>t6${TfX76 zy~il8djI`~5<`P)OyL0l;HduhH}s!G=Knj8`)PwTwl(=b-O#0$wf(w8!>3)}_iq^i z=BEL#wOft>ipDq*?zIz8$;d|Nejw2nk`a{gI?BnO_>U*vzp_g7>#LcY-F={J5*K8h zogE!#i^;FfBxo%0`*m706B;}bAL^6o1N473JbH3aHu5>NJK_?CQ_s2krH;teY-aA~ z<2D%FJ~a_*hm8&K=(`4k2ZQ;Uc}G*1hLBNaKsk-9XuC5)c;V}Ef+%-WP9ld2>(c8T z#^BJPC*AAPmks(;AQ^Ed9Z4h+y#sAMOHF2Q*|~~^ehZBH?L>>C;No{<2oO;uFj0eiZ zsX3!tn-ist`&B{s+#tWS>}VpuS4-^eguu!6t?;(<^@g(?33WJqf5qKYk$;#J(1fWB zEl<(gCSROcP>Pa>>kC_hm~M{>as&;CGb3{9@kEQ$)H-_bQ?EdiZ%)=FLb0d$;tP~3 z(`%sSPZy|G>7@91zCSfosfQuDz{$4z(Gc+rslnhuSSe#jeOeez7;8P+4N*tX$jtH{BWS?W!z~#%m@&b_X9!!CJ!?$+Opez` z5#1(>vjKeEe3u6^aY%D?xWeJZ!z4Eb$htk3@gjLSJmt6yX|LWCjZs5dYkCbL4c3H2 zMF7XVuifVmglbo%fIdU|cWVv`&El1$nsOcf2?()jGjxFH)Oy+J(GA#Ndn!(o)vDbj zZaARa&U=>m{H=Rxq@1<3Rf&qzEY_X&pxb=;?5`p{lvyGuO{dMsXnZ<4d0~sScpyv( zqc4hla$gjVm8N_@QwbL~eUU0%j=3LM7A<GHPu7Je% zafX_p%l99|bH_*TQx^T{(|aYVaB!Gl9lNT>o_d~Az`lnoa=6;iquzJpG=U(QL%BeC z(j^_BJD5FK_O*=t#|48^Zcr;JD|o(^GY+Jm;4jBdoIb2}6 zHYzd;VAOWy7w7f8)|GZj_%{CC(f|;Y3-8?=o6Hk@7Fx3s4n_JRrD&(O(kKf4fkRY; z>YZUAw>9jifuph*#Yx|agPLkr>9;~1qDP&6HoZLYu8;nxSNNmf1^87FHn8FQu&0)f z_qcA|*u9e*8c$DhpY3W#i3Ndi&Fu2BVYCslcK+^YahCNdIQ^;lr1nB2ro1N>VJbvO zY=0h4uZnKy-Al9rC-Qz3^#}x6h8R5YMfN0Dk=7Z*P3GTQdgS(s?4$ur2Z-w9P#!ATD9y#( z`qc$Iko*6|WJ%=VBx*7nYb3HJCG_6rEC!t?%q6G&ES4H(A@sHjceyQ5p(^D=QFlpm ztHKEqV+2Rsh|yhQmns~$G-dwP71T+qfw|J3_4?A2I4tw&Re+Lq^@q$=V*LP8ZbI(3 z;SYdKn$+9nxRx(A^H~BcQ??;@umP`zS6mPxxk}L00!QG7IC*Q%Z;}3>m`m;whCdXr ziBoHV@gNb%MsC^$DwfB0vXKPJU^1^nxPV;VBngb-Mqvw?03SHwkhlR`?(1EMK6V;? z{L$aK&%-+ohaAqk@8f8{sI}?YhTiRnt=Efya&7p(5)YuIsl27BI;E$d(sFo{2YmUr zHIL}gkr88qPdQ`(6DDR?`IDb<&tcukzn>Q6+c&f*eGix}tCSY*s}$mKx!&uWwW<*y zxvSA?arTkE4XFm4qzkKCf{ z%5ZdV0jf-{2~cTsbL!K(?Xx#_1BI*`oi~f$bXKSU+7}*mD?4kFo=*Nl{8KlLDQ~^$~?~ za+et~pyR1^Kn;`NQw6m~$Z7DhKC=VcJk6zgH_~R58((2d=k*w9G+ASjh~(SPX}#~Y zIMqf9W>URw=nH%)3J8;y=Aa*YU{t&B^w~ZODB)D)c~0lsB$eD_Cj0dEq{%Dr(}Z&6 zn1x->+V+NSoA1oy(@9&*i^?+j5Yo+PM|2!97>PWmH;dL#`(D=#k%$M2*T)BmFY$#?VF&{%RYV@n!mP(9M*uDbK!dP8DdKig&Ey^37X z5(|`pD!Q})mRH7U@5*jd#_U0wbiBOfW=}uuzEon)E);SH zzIncTsk*I$-i$f^#L%8L(k~crksIITXmu* z68gf(mLz-Kz**%NpprWmAzMm&d)}K`{wkE z?qw`!ixq@bZ}|NwG>dMVdl&zX8A`8(&Grd#hVn@B`8GmYH$}=SCZMV_${^FXVB9p{ zCs!BM7XS20ovL2Vr{W9(L`xOUfTw!78flc6mr#g`+#HD!JU(UlBA*88Ij}jf(iP-A zEVrrXK9CBG+UeNzU;%i& zX^~V^il&+olpU|YfD<@pQ^AB5sig7@MRZxo@H~Z#z^=4^BTJJ3RhMbls=#GF`HVEWyF-MANBQlU;}r=8O~B0XRocc|3HM&& z0B~`NZoRkXV7u&DwSk2;H3?5+?R!rQb*MjSIyR?o$+X|1RZI8zwMeSLRS2=4Yc~qN z4b zaTR{{tS`vJ&2nm0seRY1J8MPf`XuP)6fy9wcBf(lcohw0{6N1)uZtl-teSM734k$F zIrxm-R7kyaWzyUk2pBNIC(7eal#?@R;#xAF2CVN^$oRyHc?W$EvT#Kk!E#S*QIS+j+|2ietYtg0HB( z)-`66mVkp7s_7?~aNQ@i{Yy*_!3j`tggpr(k=&7tSx+Cz3`N|3DIxxDM;aXRwtqNG zd6)fnm=iZom5dHO)x~idxEv`sSy_*{hl8JVc~A8%GOPZu^Cx=0#s$}^H5%DOUc>J+ zLq{L8{px2zn-hJHZl0NVDTh04?%vUSv*)zFPF&haPwwiVWhyBl@4IiZ=-5jGEes8( zBUP6er>;gshS2I#p7sC$K)CV;@!i?A^pXtV&bzrb&A#h<@y8UT3g)Y{shLBuveH#5 zCGH!TkIT~>Hori-r6=Y?Y53KyMp=E&SikVnhPGn! zjqnx<`$Ltg6SLj6c(v^<=}*40A7R7s?5|i5(J`7pui9!3nd zkw@ybeV@XuOO~ubvsUIWhrhcs?Ci}HqtUnFeQc_`4f95QZyx;_HrdazJgp;D^BCt*TNsqYu-Eotu;uO=K7ChWitD*o z?FoJG_TQ^lhf&d`j!F4DYY%(sNVy7T0}L8iBWWBl-!pd}hxfBsd_KPG3mP}T94i5L zQ?>#w9qh4YpB2kJSUxyq<~Iv$;K7yH%-(n~-)mC8!2EHWrVM*Em*Z_4?XFnHfv#su|R%|N;yZ>HvU+X<$zm>0_ zJv~~iSZ$ve7W%t#v-H9&NSAHnPx+17lpB_&*1hoUHsxLof!5Sy)B2iVFL%Ecga>0k zcCIsXuYTljUAM3d2d;i^$Z&uz;7;M(=ZhvqReJmKGK5Dy@R6`voJae1oqdQlzV+KY zF6J*^-&u}V|FLeYJzO{^Lof69#3S=qhes$YuqC)Ipih6>-2g+_wgE=Ouw^f^P`#Nw8r}oSuOn&{`!8L%69%qPTj^2hGPNGUTnkFFiXT@3b)jnw7?YaHy2n*tU9MDyp-B2|RA8&T9|N9?#njVE@)StS}cy zB3SdoI<$QAtG>eVM&S+)AsKMvg~Lc1Cg3i0LDl81QW%E*sPtYxDt+J3tJ(XuUp?<} z6Uf-et%?0+b%$!YRQ})ig;M$NX=T4#Wy6CPP)6Uci`PcllD;>O7%(PUW<3uAQS zW(t>8YO)m`7b3b9eyVSSxS5C0VO@)eh-^0K5t)qEIDW&ql*amfr}j2}*Ac|3nn4}z zoq_G>6&?utgn{P$^?sc?9Jv|b{!Hu;oI#^ZU`ijLKENA8fOkX&W&U@=(lBjU2SFT&4WMM>kZ-{BGXZXVTI5Sz4&!IT z5(-V=<|?kdOdv>H=5PfH(55ZR6UeTxL7f_VlOZFdWON$fqHcHZfWy8ChZ;r%0L!UA zy%2z5DC-D`&4e`{0hEy1QrsK+KnE)~bFQi2;(#W*zx6Vt2U1AYE$WBam^5?duC=LZ z$6V!zgBEjm9N%CiC6%wccD_yvx49BgMylUY19)a-77n0=mu!_)2Vvoe9@GS=lYSU? z4(W4TMnSAzN$GQfaG@5xgoOf2c#8ZSS_G{VXi!`^Zj~7H|BC5n<@RGS^Y*G8bqn3S zt~T%X_H^(cNvGGh61-T8&=m<8Qm*u$s{-s2j%5|O15qMD24J7Ld|p4f12yP<_*h*L zr2DA}x@?5Qz_i=kIURApH}2rQUvklLK4_C`T4aHR*rUP{XJt+xnuJ(oaO)vMzm*NP z&C4>nzg#gZ%0$ zdBwx$@pSTNQ0)E64jwg?PT~`p&3Ej&u%oF53IVa~Qr610k3#D=voP`4$d0u7v)46( zc9V&1GSH+;yYT!PU9nlIn(bL^FF^&w!F@T-OkY`{a7a|Xb|CwpiyivP4P zRfRoY?}Rn~HfHgAgY@!8+t7R}Kh;0En!&P1mu|ZUuG~OH>!upGiJf9N_%L11bge-! z0PcO#jBK}y*giWd{mSNrh2>#mUEXTkUuEL8GZnL3918K3qi=zF6}@xvQrjt?Y^yKM zctOeLkLv_1_8Hi+L}|e<1~{E2JwysbmV283C}0mq%kG}0-%xvG0Rp0wmZFym+(6<5 zJ)IB8$(fUbNE}=sSjc=|%lxH;o-1hJzM#Dv@xm`#7>f=~P%}pmLg+W12$Z3w7bHPF zqEOs8Zk63u()cIcd~v?1ajJe^JW;~m6E4QnR8=lIJU-Eb+gnnCVfFkW02fOjvyJ+Q zGJ_Ntcc86%5QSOp05h?a?LKg|`^f8_fM2ihYDRf;=Kj7G#%$`T{ol?}nh-}X0;T;g zfC85MM%q2&)nh?vDZOnAS&ymxL*e8tH*=rlBJQCZ*LJq$Pyk*l--nZ>&)_x&Ad?^- z4l!w%6Db<6(BZ!QHFEENjyFak*hYjCc#-bHgIY9kL?!=;)oj#r)aa}xh?=fTEMp=5C1NcJu7DxE7yE9TB{LFNhOE)W^^Ioy5I;oCcVc>e1!`}KkwKb6b6xum-3ZsT z+n|ORBKu3;65arfXXELq*8`h7MS zE$CsGj5mfSVNmFU@k(|wSMG3gd$_)YDR!TxJigA;8fIaT)_aCP>lku_LR%k)Dm{hF6I-~k0C3m8odE5s0F_VR|16US^#n!^=FTX4t%akjjVq=o|^A%7SUoE zmg}A(##3spq7PQXiZU;qm#KU#D$tH2uOc7BLF2fZNx`7<0pkW|s5$Tnd`nMvG~ich8BfTsr$-_N6igEF;hRQPGDZG$~t?B5rS^L|9WJNPcpaDMw<2n0PJ z4oXEcfiwdF4!@ss#HrKzb-a=3kq&F)z&j{`G+!-^Osg8M_O{;=H}{bvM(t6%Sc=%t z1pW{qf>3t%$Yg&+hCSx+q5eKFYl1PImbIQZ0h(f9Nv|tYV@oPXAymh~!>Fvtl_l?D zKkjh$^-0McyqjN?Z{qq(Q2bA-#Giu1DE`F&s-jmz(vP76mSbE zI4c^YBo7kuJ9UvXf=PJdoHXE2Os}gf@IXulW~LZ&cN8PQjG2d-$DlB+mWY&8B*N3+ zuMc4rlXStvh7jxlNBW3!1BW6gUv=v^Eh zO};JOEshENe3gQe{fOcYAQ>$b82}50@-aZVoB??*8d`xwuBj@tvF=#PR6-I;(=+?A*jRf?u1*ieYRDVufK%;*=<1ZsLcw%H)5ey9-h_$g>LI?lexHY7o zP>pqC2aHDn0oXsGnxDe7uF#WThh0BEwO%=LHbQ(*|2~(NSB5*&nWlzJ3>@SUyFkA-Aq5*wnCf4QPt?07e9ZC>A|O`r5P`X^LFMa?}I z)&|4_Y=ZuRL|%kWC`sEc;50{&3J&MC>{_F1%)aWHULl;VIa|W_i8fSJw4bnlj`*r( zUah!?m}+zc(!{1%B~GfXKWP9R#%>A|_8h)cf>fA}h;5Im5axgr^SVRA4cz^A7$LOJ zBuHuQ9l4L9=&TW-sNbnFMap3sDp8yeRzut3ko_!H!qQ{YVgVarMl7%~Xc)y#7Puw4 zu=7D`upT|Nz-72mM)jB7B!gI-J;wCzc>NtdEN0m0>Ztg3?rsJHVeFcI-SGG=pNP%< zK5-g14+dZr!3G!KK$uT#>h>t-;C`WRnDpsSs-|AdJU~m~7_ysAUUSYx zsL|)uEqKn&T#`mRB`8#XY$cg*&#_0D{CNNSt+qN+`#wQe_aA-LhM=05s;A;g@p>13$0 zLodc84@LwfFQ*upb0mu8W$;nKgysB!1Foi=KQu@V+}zE@EE0)?oXWX6U9xlsZ)r=G z-hmc zDCxO9gq52IvXFz?bEc%p1~*0U8m$XQhy1?q$@OJM@&u^D_2Cr&3e-!8Fr@f44{dne zD`FUV>swyL8r)@4Qev_f6^bsjEGd^#Q)t-}8}JRv11PQbf7Pw$-g_0QUA9zw zM)UCkpQdeHtIs_Cb@so}X7)V$Ua~(8)+;2#*YYQb_)ucU02s{{>7p6Ry2cWRMi z#|+&E9QQiL!sGU;EPduq@6M77{wr828mrYf$9t*b?fSZC>E_kIYSA)n+PGDz2mcTs z{DAP_{rh>%D>>`ZY+%oFz>-=Q61>bvff#?M?QeX;Du3y=oVtDO$a}M1DJ7*4hs$4y zpZLsr(ocLQiUd{t_@b&79_iFqLT)w*ytAz3n@saFpS^QYLa6FM#$33!pu zE}Z1y35W{cH06kI-d%~j-4IgGoDp8EKy~z`{N{NTk~)W8bN3D5%Rl5P?`B(BQ}CNW z1=?@M`{k#rruTaQDmT;v>5I!6oNC z!LA$+p1i9nGyypSHC8X_XL4uR%JrfE#?jyX{3E4^dO9}sQq%(t37GN+I6T7IphjqG zDp3kUmDx2Bx;b%zStBUMPFnK=%G-46w{JrR$!P8;v3~T-{F8v`U1mihx-@`!Y#~5Q`Yqp+l)5wq)ZUF`rGx7wMnm_oFQpq|I8fCN~$|>B)r> z)m{~qm6a8h`Ui#Ty_?tP_vRtrU$?y;ueB$qy^?R&_}}**tJL$ZG0mcq^7`}2PQto{ z%wG(AHht7S-qP&K;_k3Ur`YC~;l;4#&5l#qq4IZ)K#Fp4&A`nnN>N4D(>kNhM|=rw z)T4iW7wUy)#TV{z-JPSJ(aonEd$)fYJ_e;CaT3C$UGuO&e#im!?VpyjlsI|mHA_iS zE6H+R|EEXx#ihA>^PkX;(HgV0t-{^YRuk;;7Pn3px|IHgTVh?0SvRCPXy^L7(NZaPMEZ5Xqn;aQ(@HCCRsJZ86Lk{Li3NfM-ZM>7_Skhy@ ztl;(5$o=VEUz2Pe$B(l}Vd=&tYQ)VqH$LHNws;ShP|wM3{$CEk`tVy=L5?+oukepU zK>Onmcx??8vi~>)>@PIE|K$+ixcWR`uMMa-iThsa>iWEbrFockd}+0gS(L0B4E@Uy z(4U0;!FiACz;l7ReJmIC2cLZKxyjbFg4d7ZdkQzEyXL;*b@*^BR|$y@LPw=H?NYfZ z*e#Aq*J32%8yQ9JTD)}%O9#`-^03@Jq$fz>K&Jm5i68hp}{`~ zi;)s6X8s3-(Hf0detl39mCpZ)5&YN$?Qkk6a=eknii
  • +!KA^}^8o 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 Vd?Ew_q6PdT0PGxMsb9C+{{u{v8Pxy) literal 0 HcmV?d00001 diff --git a/platform/win/source-20180817-gerdLTGT/amd64/gerdLTGT.dll b/platform/win/source-20180817-gerdLTGT/amd64/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..eee9b7f5a7259b5ce01ffc91dce3c3661e95ce68 GIT binary patch literal 6656 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 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180817-gerdLTGT/amd64/gerdLTGT.exp b/platform/win/source-20180817-gerdLTGT/amd64/gerdLTGT.exp new file mode 100644 index 0000000000000000000000000000000000000000..084e454c2d95eb6dc55d5f8ec0116c116c4b8e3f GIT binary patch literal 671 zcmYdkV`jLzUNrg#BLf2m0|e-$rX-dmLODPx2#9-t_#RY<4M;lxkzPt_QfazMFjSb~ z2#_HKGzS?tFbFv5r4*$mmz1T##HE0YduZwym>{wsx4_hal)x}d43$n#ElTkTaSzc; z$;n~xPD=4ftV}I(Ni9w;$}A|!FJj;UDhCmIjby2eWj5 zB*=fvU^O3stOOvIWMC8oQVfZ?DP|@ya9dL=3K%pP!~{WFFM#BM02GMo$9yxBi}H)} z(@GRHf;1I;JpH^uhFAzPG6-OE=NF(R2_OdfR)A6ZPciHF7&+tgS8qR5uJ4@5!0;I; zZUDp#&Q>v@#i>QbF?7QFyrz8kY^4)vyo_*i42e z<$8IhI_M_1ZwW@nd#LBQW$yRcH60KnIy!Fu=`%xyiu;uNEIdq@vd?sBXTK|{h?V`G nA->(j_8md!e2Mj3m93&w`G3RB>YngTrqVHVxkTN_;RNCz8u(7Z literal 0 HcmV?d00001 diff --git a/platform/win/source-20180817-gerdLTGT/gerdLG00.klc b/platform/win/source-20180817-gerdLTGT/gerdLG00.klc new file mode 100644 index 0000000..1ea6ff1 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/gerdLG00.klc @@ -0,0 +1,327 @@ +// 2010-2017 Jan Pacner +// etaoin shrdlu! + +// The concept of this keyboard layout +// motto: be as much compatible with ISO dvorak as possible +// 4. level is the same as 3. level +// 2. level of ISO dvorak goes without modifications to the 3. level +// the whole national alphabet is accessible directly from 1. and 2. level +// without any exception +// 3. level has some additional non-alphabet characters (e.g. numbers) +// 3. level is accessible only by pressing both Shifts at once (and +// holding either of them) +// there are 2 variants which differ in placement and/or availability of +// characters ' " < > „ “ en_dash +// in `ltgt`, characters „ “ are not available and ' " < > are at their +// original dvorak places and ! is duplicated for better reachability +// in `writer`, all characters are available, but " < > are in +// the 3. level, thus less reachable + +// ----------- standard ISO dvorak, 1. and 2. level +// ~ ! @ # $ % ^ & * ( ) { } +// ` 1 2 3 4 5 6 7 8 9 0 [ ] +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// space +// space + +// ----------- german dvorak ltgt, 1. and 2. levelll +// ä Ö Ü ß +// ä ö ü ß +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak ltgt, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// nda ! § , 7 8 9 [ ] + | +// en dash +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak writer, 1. and 2. level +// ä Ö Ü ß +// ä ö ü ß +// +// “ nda ' P Y F G C R L ? + | +// en dash +// „ , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak writer, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// " < > § , 7 8 9 [ ] + | +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak (ltgt|writer), 4. level +// the same as 3. level + +// KBD identifier_max_8_bytes_long "Some description to show in keyboard settings and while switching layouts" + KBD gerdLTGT "German Dvorak ltgt (useful for text with lots of <>)" +//KBD gerdLTGT "German Dvorak writer (useful for text with lower/upper UTF-8 double quotes)" + +COPYRIGHT "MIT license" + +COMPANY "github.com/dumblob/ULKL/" + +LOCALENAME "de-DE" + + LOCALEID "00000407" +// LOCALEID "00000000" + +//FIXME 1.1 after unused keys produce the character +VERSION 1.0 + +//ATTRIBUTES + +//MODIFIERS + +SHIFTSTATE + +// shift_state_idx // column_below modifiers +0 // 4 +1 // 5 LSHIFT or RSHIFT pressed +2 // 6 both LSHIFT and RSHIFT pressed simultaneously + +LAYOUT +// an extra @ at the end is a dead key +// -1 denotes the character +// SC denotes a Virtual Scan Code +// Cap ~ CapsInfo (probably whether CapsLock is applicable) + +// topmost row + +//SC VK_ Cap 0 1 2 +29 OEM_3 0 -1 -1 007e // , , TILDE +02 1 0 -1 -1 0021 // , , EXCLAMATION MARK +03 2 0 00e4 00c4 0040 // adiaeresis, Adiaeresis, COMMERCIAL AT +04 3 0 00f6 00d6 0023 // odiaeresis, Odiaeresis, NUMBER SIGN +05 4 0 -1 -1 0024 // , , DOLLAR SIGN +06 5 0 00fc 00dc 0025 // udiaeresis, Udiaeresis, PERCENT SIGN +07 6 0 -1 -1 005e // , , CIRCUMFLEX ACCENT +08 7 0 -1 -1 0026 // , , AMPERSAND +09 8 0 -1 -1 002a // , , ASTERISK +0a 9 0 -1 -1 0028 // , , LEFT PARENTHESIS +0b 0 0 -1 -1 0029 // , , RIGHT PARENTHESIS +0c OEM_4 0 00df 1e9e 007b // ssharp, U1E9E, LEFT CURLY BRACKET (BRACELEFT) +0d OEM_6 0 -1 -1 007d // , , RIGHT CURLY BRACKET (BRACERIGHT) +// FIXME wtf is this key? is it really ? +56 OEM_102 0 -1 -1 -1 // , , +//0e ???? 0 ???? ???? ???? // backspace, backspace, backspace + +// top row + +//0f ???? 0 ???? ???? ???? // tab, tab, tab +// ltgt variant +10 OEM_7 0 0027 0022 -1 // APOSTROPHE, QUOTATION MARK (QUOTEDBL), +11 OEM_COMMA 0 002c 003c 2013 // COMMA, LESS-THAN SIGN, U2013 (EN DASH, pomlcka) +12 OEM_PERIOD 0 002e 003e 0021 // FULL STOP (PERIOD), GREATER-THAN SIGN, EXCLAMATION MARK +// writer variant +//10 OEM_7 0 201e 201c 0022 // U201E LOWER QUOTATION MARK (QUOTEDBL), U201C UPPER QUOTATION MARK (QUOTEDBL), QUOTATION MARK (QUOTEDBL) +//11 OEM_COMMA 0 002c 2013 003c // COMMA, U2013 (EN DASH, pomlcka), LESS-THAN SIGN +//12 OEM_PERIOD 0 002e 0027 003e // FULL STOP (PERIOD), APOSTROPHE, GREATER-THAN SIGN + +13 P 0 p P 00a7 // LATIN SMALL LETTER P, LATIN CAPITAL LETTER P, SECTION SIGN (PARAGRAPH) +14 Y 0 y Y -1 // LATIN SMALL LETTER Y, LATIN CAPITAL LETTER Y, +15 F 0 f F 002c // LATIN SMALL LETTER F, LATIN CAPITAL LETTER F, COMMA +16 G 0 g G 7 // LATIN SMALL LETTER G, LATIN CAPITAL LETTER G, DIGIT SEVEN +17 C 0 c C 8 // LATIN SMALL LETTER C, LATIN CAPITAL LETTER C, DIGIT EIGHT +18 R 0 r R 9 // LATIN SMALL LETTER R, LATIN CAPITAL LETTER R, DIGIT NINE +19 L 0 l L 005b // LATIN SMALL LETTER L, LATIN CAPITAL LETTER L, LEFT SQUARE BRACKET +1a OEM_2 0 002f 003f 005d // SOLIDUS (SLASH), QUESTION MARK, RIGHT SQUARE BRACKET +1b OEM_PLUS 0 003d 002b 002b // EQUALS SIGN, PLUS SIGN, PLUS SIGN +2b OEM_5 0 005c 007c 007c // REVERSE SOLIDUS (BACKSLASH), VERTICAL LINE (BAR), VERTICAL LINE (BAR) + +// home/middle row + +//CapsLk +//3a ???? 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +//3a SGCap 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +1e A 0 a A 0040 // LATIN SMALL LETTER A, LATIN CAPITAL LETTER A, COMMERCIAL AT +1f O 0 o O 00b0 // LATIN SMALL LETTER O, LATIN CAPITAL LETTER O, DEGREE +20 E 0 e E 20ac // LATIN SMALL LETTER E, LATIN CAPITAL LETTER E, EURO SIGN +21 U 0 u U 0060 // LATIN SMALL LETTER U, LATIN CAPITAL LETTER U, GRAVE ACCENT (GRAVE) +22 I 0 i I -1 // LATIN SMALL LETTER I, LATIN CAPITAL LETTER I, +23 D 0 d D 003a // LATIN SMALL LETTER D, LATIN CAPITAL LETTER D, COLON +24 H 0 h H 4 // LATIN SMALL LETTER H, LATIN CAPITAL LETTER H, DIGIT FOUR +25 T 0 t T 5 // LATIN SMALL LETTER T, LATIN CAPITAL LETTER T, DIGIT FIVE +26 N 0 n N 6 // LATIN SMALL LETTER N, LATIN CAPITAL LETTER N, DIGIT SIX +27 S 0 s S 003d // LATIN SMALL LETTER S, LATIN CAPITAL LETTER S, EQUALS SIGN +// pomlcka (= minus = dash) +28 OEM_MINUS 0 002d 005f 005c // HYPHEN-MINUS (FIXME is it the plain minus?), LOW LINE (UNDERSCORE), REVERSE SOLIDUS (BACKSLASH) +//1c ???? 0 ???? ???? ???? // enter/return, enter/return, enter/return + +// bottom row + +//2a ???? 0 ???? ???? ???? // left shift, left shift, left shift +// left bottom key, right from , which doesn't follow the kbd standard +// FIXME wtf is this key? is it really ? +56 OEM_102 0 -1 -1 -1 // , , +2c OEM_1 0 003b 003a -1 // SEMICOLON, COLON, +2d Q 0 q Q -1 // LATIN SMALL LETTER Q, LATIN CAPITAL LETTER Q, +2e J 0 j J -1 // LATIN SMALL LETTER J, LATIN CAPITAL LETTER J, +2f K 0 k K -1 // LATIN SMALL LETTER K, LATIN CAPITAL LETTER K, +30 X 0 x X -1 // LATIN SMALL LETTER X, LATIN CAPITAL LETTER X, +31 B 0 b B 0 // LATIN SMALL LETTER B, LATIN CAPITAL LETTER B, DIGIT ZERO +32 M 0 m M 1 // LATIN SMALL LETTER M, LATIN CAPITAL LETTER M, DIGIT ONE +33 W 0 w W 2 // LATIN SMALL LETTER W, LATIN CAPITAL LETTER W, DIGIT TWO +34 V 0 v V 3 // LATIN SMALL LETTER V, LATIN CAPITAL LETTER V, DIGIT THREE +35 Z 0 z Z 002e // LATIN SMALL LETTER Z, LATIN CAPITAL LETTER Z, FULL STOP (PERIOD) +// numpad dot +53 DECIMAL 0 002e 002e 002e // FULL STOP (PERIOD), FULL STOP (PERIOD), FULL STOP (PERIOD) +//36 ???? 0 ???? ???? ???? // right shift, right shift, right shift + +// bottom-most row + +//?? ???? 0 ???? ???? ???? // left ctrl, left ctrl, left ctrl +//5b ???? 0 ???? ???? ???? // left super (win), left super (win), left super (win) +//?? ???? 0 ???? ???? ???? // left alt (meta), left alt (meta), left alt (meta) +39 SPACE 0 0020 00a0 00a0 // SPACE, NO-BREAK SPACE, NO-BREAK SPACE +//38 ???? 0 ???? ???? ???? // right alt (meta), right alt (meta), right alt (meta) +//5c ???? 0 ???? ???? ???? // right super (win), right super (win), right super (win) +//?? ???? 0 ???? ???? ???? // menu, menu, menu +//5d ???? 0 ???? ???? ???? // menu, menu, menu +//56 ???? 0 ???? ???? ???? // menu, menu, menu +//1d ???? 0 ???? ???? ???? // right ctrl, right ctrl, right ctrl +//46 ???? 0 ???? ???? ???? // scroll lock, scroll lock, scroll lock + +//LIGATURE +// +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// a mod b c + +//KEYNAME +// +//01 Esc +//0e Backspace +//0f Tab +//1c Enter +//1d Ctrl +////2a Shift +//2a "Left Shift" +//36 "Right Shift" +//37 "Num *" +//38 Alt +//39 Space +//3a "Caps Lock" +//3b F1 +//3c F2 +//3d F3 +//3e F4 +//3f F5 +//40 F6 +//41 F7 +//42 F8 +//43 F9 +//44 F10 +//45 Pause +//46 "Scroll Lock" +//47 "Num 7" +//48 "Num 8" +//49 "Num 9" +//4a "Num -" +//4b "Num 4" +//4c "Num 5" +//4d "Num 6" +//4e "Num +" +//4f "Num 1" +//50 "Num 2" +//51 "Num 3" +//52 "Num 0" +//53 "Num Del" +//54 "Sys Req" +//57 F11 +//58 F12 +//7c F13 +//7d F14 +//7e F15 +//7f F16 +//80 F17 +//81 F18 +//82 F19 +//83 F20 +//84 F21 +//85 F22 +//86 F23 +//87 F24 +// +//KEYNAME_EXT +// +//1c "Num Enter" +//1d "Right Ctrl" +//35 "Num /" +//37 "Prnt Scrn" +//38 "Right Alt" +//45 "Num Lock" +//46 Break +//47 Home +//48 Up +//49 "Page Up" +//4b Left +//4d Right +//4f End +//50 Down +//51 "Page Down" +//52 Insert +//53 Delete +//54 <00> +//54 "Sys Req" +//56 Help +//5b "Left Windows" +//5c "Right Windows" +//5d Application + +DESCRIPTIONS + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German Dvorak ltgt (useful for text with lots of <>) +//0409 German Dvorak writer (useful for text with lower/upper UTF-8 double quotes) + +LANGUAGENAMES + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German or related (all locations world-wide) + +ENDKBD + +// vim: set ft=javascript: diff --git a/platform/win/source-20180817-gerdLTGT/gerdLTGT - Kopie.C b/platform/win/source-20180817-gerdLTGT/gerdLTGT - Kopie.C new file mode 100644 index 0000000..9176359 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/gerdLTGT - Kopie.C @@ -0,0 +1,524 @@ +/***************************************************************************\ + ä Ö Ü ß +* Module Name: gerdLTGT.C +* +* keyboard layout +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* History: +* KBDTOOL v3.40 - Created Mon May 29 08:05:02 2017 +\***************************************************************************/ + +#include +#include "kbd.h" +#include "winuser.h" +#include "gerdLTGT.h" + +#if defined(_M_IA64) +//FIXME +//#pragma section(".data",read,write) +#pragma section(".data") +#define ALLOC_SECTION_LDATA __declspec(allocate(".data")) +#else +//FIXME might need system-init of the DLL, not a process-specific init (it's a huge security risk) +//#pragma bss_seg(".data") +#pragma data_seg(".data") +#define ALLOC_SECTION_LDATA +#endif + +/***************************************************************************\ +* ausVK[] - Virtual Scan Code to Virtual Key conversion table +\***************************************************************************/ + +static ALLOC_SECTION_LDATA USHORT ausVK[] = { + T00, T01, T02, T03, T04, T05, T06, T07, + T08, T09, T0A, T0B, T0C, T0D, T0E, T0F, + T10, T11, T12, T13, T14, T15, T16, T17, + // 24 + + T18, T19, T1A, T1B, T1C, + // 5 + + + /* + * Left Ctrl FIXME + */ + T1D, + + T1E, T1F, + T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, + // 12 + + + /* + * Left-hand Shift FIXME + */ + T2A, + + T2B, T2C, T2D, T2E, T2F, + T30, T31, T32, T33, T34, T35, + // 11 + + + /* + * Right-hand Shift key must have KBDEXT bit set. + */ + T36 | KBDEXT, + + T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot + + T38, T39, T3A, T3B, T3C, T3D, T3E, + T3F, T40, T41, T42, T43, T44, + // 13 + + + /* + * NumLock Key: + * KBDEXT - VK_NUMLOCK is an Extended key + * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL) + */ + T45 | KBDEXT | KBDMULTIVK, + + T46 | KBDMULTIVK, + + /* + * Number Pad keys: + * KBDNUMPAD - digits 0-9 and decimal point. + * KBDSPECIAL - require special processing by Windows + */ + T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home) + T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up), + T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp), + T4A, + T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left), + T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear), + T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right), + T4E, + T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End), + T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down), + T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn), + T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins), + T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del), + + T54, T55, T56, T57, T58, T59, T5A, T5B, + T5C, T5D, T5E, T5F, T60, T61, T62, T63, + T64, T65, T66, T67, T68, T69, T6A, T6B, + T6C, T6D, T6E, T6F, T70, T71, T72, T73, + T74, T75, T76, T77, T78, T79, T7A, T7B, + // 40 + + T7C, T7D, T7E + // 3 = 127 + +}; + +static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = { + { 0x10, X10 | KBDEXT }, // Speedracer: Previous Track + { 0x19, X19 | KBDEXT }, // Speedracer: Next Track + { 0x1D, X1D | KBDEXT }, // RControl; Right Ctrl FIXME + { 0x20, X20 | KBDEXT }, // Speedracer: Volume Mute + { 0x21, X21 | KBDEXT }, // Speedracer: Launch App 2 + { 0x22, X22 | KBDEXT }, // Speedracer: Media Play/Pause + { 0x24, X24 | KBDEXT }, // Speedracer: Media Stop + { 0x2E, X2E | KBDEXT }, // Speedracer: Volume Down + { 0x30, X30 | KBDEXT }, // Speedracer: Volume Up + { 0x32, X32 | KBDEXT }, // Speedracer: Browser Home + { 0x35, X35 | KBDEXT }, // Numpad Divide + { 0x37, X37 | KBDEXT }, // Snapshot + { 0x38, X38 | KBDEXT }, // RMenu + { 0x47, X47 | KBDEXT }, // Home + { 0x48, X48 | KBDEXT }, // Up + { 0x49, X49 | KBDEXT }, // Prior + { 0x4B, X4B | KBDEXT }, // Left + { 0x4D, X4D | KBDEXT }, // Right + { 0x4F, X4F | KBDEXT }, // End + { 0x50, X50 | KBDEXT }, // Down + { 0x51, X51 | KBDEXT }, // Next + { 0x52, X52 | KBDEXT }, // Insert + { 0x53, X53 | KBDEXT }, // Delete + { 0x5B, X5B | KBDEXT }, // Left Win + { 0x5C, X5C | KBDEXT }, // Right Win + { 0x5D, X5D | KBDEXT }, // Application + { 0x5F, X5F | KBDEXT }, // Speedracer: Sleep + { 0x65, X65 | KBDEXT }, // Speedracer: Browser Search + { 0x66, X66 | KBDEXT }, // Speedracer: Browser Favorites + { 0x67, X67 | KBDEXT }, // Speedracer: Browser Refresh + { 0x68, X68 | KBDEXT }, // Speedracer: Browser Stop + { 0x69, X69 | KBDEXT }, // Speedracer: Browser Forward + { 0x6A, X6A | KBDEXT }, // Speedracer: Browser Back + { 0x6B, X6B | KBDEXT }, // Speedracer: Launch App 1 + { 0x6C, X6C | KBDEXT }, // Speedracer: Launch Mail + { 0x6D, X6D | KBDEXT }, // Speedracer: Launch Media Selector + { 0x1C, X1C | KBDEXT }, // Numpad Enter + { 0x46, X46 | KBDEXT }, // Break (Ctrl + Pause) + { 0, 0 } +}; + +static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = { + { 0x1D, Y1D }, // Pause + { 0 , 0 } +}; + +/***************************************************************************\ +* aVkToBits[] - map Virtual Keys to Modifier Bits +* +* See kbd.h for a full description. +* +*FIXME wrong original description: +* The keyboard has only three shifter keys: +* SHIFT (L & R) affects alphabnumeric keys, +* CTRL (L & R) is used to generate control characters +* ALT (L & R) used for generating characters by number with numpad +\***************************************************************************/ +static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = { +// { VK_SHIFT , KBDSHIFT }, +// { VK_CONTROL , KBDCTRL }, +// { VK_MENU , KBDALT }, +// { 0 , 0 } + + // FIXME dumblob + // a hack to allow distinguishing left and right shift by propagating it to aModification[] + // make "KBDSHIFT | KBDCTRL" a unique bit combination for left shift + { VK_LSHIFT, KBDSHIFT | KBDCTRL }, + // make "KBDSHIFT | KBDCTRL" a unique bit combination for right shift + { VK_RSHIFT, KBDSHIFT | KBDALT }, + //{ VK_LCONTROL, KBDCTRL }, + //{ VK_RCONTROL, KBDCTRL }, + { 0, 0 } +}; + +/***************************************************************************\ +* aModification[] - map character modifier bits to modification number +* +* See kbd.h for a full description. +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = { + // Demonstration of the relationship (note: this demo is + // a complete nonsense in terms of an internal implementation): + // for( x in aVkToBits ){ + // if( x[0] == 0 && x[1] == 0 ) break + // if( x[1] <= wMaxModBits ){ + // // x[0] is not interesting + // if( aModification[x[1]] != SHFT_INVALID ){ + // shift_to_the_level( x[1] ) + // break + // } + // } + // } + + // PVK_TO_BIT pVkToBit; // Virtual Keys -> Mod bits + &aVkToBits[0], + // WORD wMaxModBits; // max Modification bit combination value + KBDSHIFT | KBDCTRL | KBDALT, + + // BYTE ModNumber[]; // Mod bits -> Modification Number + // mod_bits are an index to this array => order matters ( + // arithmetic progression with step 1 without any omission; + // use SHFT_INVALID as an ignored shift state) + { + // from kbd.h: + // #define KBDSHIFT (1 << 0) + // #define KBDCTRL (1 << 1) + // #define KBDALT (1 << 2) + // #define KBDKANA (1 << 3) + // #define KBDROYA (1 << 4) + // #define KBDLOYA (1 << 5) + // (1 << 6) doesn't exist (not defined anywhere) + // #define KBDGRPSELTAP (1 << 7) + + // FIXME test Ctrl and Alt key bindings (e.g. Ctrl+c, Alt+64, ...) + // shift_state_idx // KBDALT KBDCTRL KBDSHIFT + 0, // 0 0 0 + SHFT_INVALID, // 0 0 1 + SHFT_INVALID, // 0 1 0 + 1, // 0 1 1 (only LSHIFT pressed) + SHFT_INVALID, // 1 0 0 + 1, // 1 0 1 (only RSHIFT pressed) + SHFT_INVALID, // 1 1 0 + 2, // 1 1 1 (both LSHIFT and RSHIFT + // pressed simultaneously) + } +}; + +/***************************************************************************\ +* +* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states +* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states +* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states +* +* Table attributes: Unordered Scan, null-terminated +* +* Search this table for an entry with a matching Virtual Key to find the +* corresponding unshifted and shifted WCHAR characters. +* +* Special values for VirtualKey (column 1) +* 0xff - dead chars for the previous entry +* 0 - terminate the list +* +* Special values for Attributes (column 2) +* CAPLOK bit - CAPS-LOCK affect this key like SHIFT +* +* Special values for wch[*] (column 3 & 4) +* WCH_NONE - No character +* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none) +* WCH_LGTR - Ligature (generates multiple characters) +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VK_TO_WCHARS2 aVkToWch2[] = { +// | | Shift | +// |=========|=========| + {VK_TAB ,0 ,'\t' ,'\t' }, + {VK_ADD ,0 ,'+' ,'+' }, + {VK_DIVIDE ,0 ,'/' ,'/' }, + {VK_MULTIPLY ,0 ,'*' ,'*' }, + {VK_SUBTRACT ,0 ,'-' ,'-' }, + {0 ,0 ,0 ,0 } +}; + +// FIXME all unwanted VK_* keys should be redefined as WCH_NONE +static ALLOC_SECTION_LDATA VK_TO_WCHARS3 aVkToWch3[] = { +// | | Shift | Ctrl | +// |=========|=========|=========| + {VK_OEM_3 ,0 ,WCH_NONE ,WCH_NONE ,'~' }, + {'1' ,0 ,WCH_NONE ,WCH_NONE ,'!' }, + {'2' ,0 ,0x00e4 ,0x00c4 ,'@' }, + {'3' ,0 ,0x00f6 ,0x00d6 ,'#' }, + {'4' ,0 ,WCH_NONE ,WCH_NONE ,'$' }, + {'5' ,0 ,0x00fc ,0x00dc ,'%' }, + {'6' ,0 ,WCH_NONE ,WCH_NONE ,'^' }, + {'7' ,0 ,WCH_NONE ,WCH_NONE ,'&' }, + {'8' ,0 ,WCH_NONE ,WCH_NONE ,'*' }, + {'9' ,0 ,WCH_NONE ,WCH_NONE ,'(' }, + {'0' ,0 ,WCH_NONE ,WCH_NONE ,')' }, + {VK_OEM_4 ,0 ,0x00df ,0x1e9e ,'{' }, + {VK_OEM_6 ,0 ,WCH_NONE ,WCH_NONE ,'}' }, + {VK_OEM_102 ,0 ,WCH_NONE ,WCH_NONE ,WCH_NONE }, + {VK_OEM_7 ,0 ,'\'' ,'\"' ,WCH_NONE }, + {VK_OEM_COMMA ,0 ,',' ,'<' ,WCH_NONE }, + {VK_OEM_PERIOD,0 ,'.' ,'>' ,WCH_NONE }, + {'P' ,0 ,'p' ,'P' ,WCH_NONE }, + {'Y' ,0 ,'y' ,'Y' ,WCH_NONE }, + {'F' ,0 ,'f' ,'F' ,WCH_NONE }, + {'G' ,0 ,'g' ,'G' ,WCH_NONE }, + {'C' ,0 ,'c' ,'C' ,WCH_NONE }, + {'R' ,0 ,'r' ,'R' ,WCH_NONE }, + {'L' ,0 ,'l' ,'L' ,WCH_NONE }, + {VK_OEM_2 ,0 ,'/' ,'?' ,']' }, + {VK_OEM_PLUS ,0 ,'=' ,'+' ,'+' }, + {VK_OEM_5 ,0 ,'\\' ,'|' ,'|' }, + {'A' ,0 ,'a' ,'A' ,WCH_NONE }, + {'O' ,0 ,'o' ,'O' ,WCH_NONE }, + {'E' ,0 ,'e' ,'E' ,WCH_NONE }, + {'U' ,0 ,'u' ,'U' ,WCH_NONE }, + {'I' ,0 ,'i' ,'I' ,WCH_NONE }, + {'D' ,0 ,'d' ,'D' ,WCH_NONE }, + {'H' ,0 ,'h' ,'H' ,WCH_NONE }, + {'T' ,0 ,'t' ,'T' ,WCH_NONE }, + {'N' ,0 ,'n' ,'N' ,WCH_NONE }, + {'S' ,0 ,'s' ,'S' ,WCH_NONE }, + {VK_OEM_MINUS ,0 ,'-' ,'_' ,'\\' }, + {VK_OEM_1 ,0 ,';' ,':' ,WCH_NONE }, + {'Q' ,0 ,'q' ,'Q' ,WCH_NONE }, + {'J' ,0 ,'j' ,'J' ,WCH_NONE }, + {'K' ,0 ,'k' ,'K' ,WCH_NONE }, + {'X' ,0 ,'x' ,'X' ,WCH_NONE }, + {'B' ,0 ,'b' ,'B' ,WCH_NONE }, + {'M' ,0 ,'m' ,'M' ,WCH_NONE }, + {'W' ,0 ,'w' ,'W' ,WCH_NONE }, + {'V' ,0 ,'v' ,'V' ,WCH_NONE }, + {'Z' ,0 ,'z' ,'Z' ,WCH_NONE }, + {VK_DECIMAL ,0 ,'.' ,'.' ,'.' }, + {VK_SPACE ,0 ,' ' ,0x00a0 ,0x00a0 }, + {VK_BACK ,0 ,'\b' ,'\b' ,0x007f }, + {VK_ESCAPE ,0 ,0x001b ,0x001b ,0x001b }, + {VK_RETURN ,0 ,'\r' ,'\r' ,'\n' }, + {VK_CANCEL ,0 ,0x0003 ,0x0003 ,0x0003 }, + {0 ,0 ,0 ,0 ,0 } +}; + +// Put this last so that VkKeyScan interprets number characters +// as coming from the main section of the kbd (aVkToWch2 and +// aVkToWch5) before considering the numpad (aVkToWch1). + +static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = { + { VK_NUMPAD0 , 0 , '0' }, + { VK_NUMPAD1 , 0 , '1' }, + { VK_NUMPAD2 , 0 , '2' }, + { VK_NUMPAD3 , 0 , '3' }, + { VK_NUMPAD4 , 0 , '4' }, + { VK_NUMPAD5 , 0 , '5' }, + { VK_NUMPAD6 , 0 , '6' }, + { VK_NUMPAD7 , 0 , '7' }, + { VK_NUMPAD8 , 0 , '8' }, + { VK_NUMPAD9 , 0 , '9' }, + { 0 , 0 , '\0' } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = { + { (PVK_TO_WCHARS1)aVkToWch3, 3, sizeof(aVkToWch3[0]) }, + { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) }, + { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) }, + { NULL, 0, 0 }, +}; + +/***************************************************************************\ +* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables +* +* Table attributes: Ordered Scan (by scancode), null-terminated +* +* Only the names of Extended, NumPad, Dead and Non-Printable keys are here. +* (Keys producing printable characters are named by that character) +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNames[] = { + 0x01, L"Esc", + 0x0e, L"Backspace", + 0x0f, L"Tab", + 0x1c, L"Enter", + 0x1d, L"Ctrl", + 0x2a, L"Left Shift", + 0x36, L"Right Shift", + 0x37, L"Num *", + 0x38, L"Alt", + 0x39, L"Space", + 0x3a, L"Caps Lock", + 0x3b, L"F1", + 0x3c, L"F2", + 0x3d, L"F3", + 0x3e, L"F4", + 0x3f, L"F5", + 0x40, L"F6", + 0x41, L"F7", + 0x42, L"F8", + 0x43, L"F9", + 0x44, L"F10", + 0x45, L"Pause", + 0x46, L"Scroll Lock", + 0x47, L"Num 7", + 0x48, L"Num 8", + 0x49, L"Num 9", + 0x4a, L"Num -", + 0x4b, L"Num 4", + 0x4c, L"Num 5", + 0x4d, L"Num 6", + 0x4e, L"Num +", + 0x4f, L"Num 1", + 0x50, L"Num 2", + 0x51, L"Num 3", + 0x52, L"Num 0", + 0x53, L"Num Del", + 0x54, L"Sys Req", + 0x57, L"F11", + 0x58, L"F12", + 0x7c, L"F13", + 0x7d, L"F14", + 0x7e, L"F15", + 0x7f, L"F16", + 0x80, L"F17", + 0x81, L"F18", + 0x82, L"F19", + 0x83, L"F20", + 0x84, L"F21", + 0x85, L"F22", + 0x86, L"F23", + 0x87, L"F24", + 0 , NULL +}; + +static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNamesExt[] = { + 0x1c, L"Num Enter", + 0x1d, L"Right Ctrl", + 0x35, L"Num /", + 0x37, L"Prnt Scrn", + 0x38, L"Right Alt", + 0x45, L"Num Lock", + 0x46, L"Break", + 0x47, L"Home", + 0x48, L"Up", + 0x49, L"Page Up", + 0x4b, L"Left", + 0x4d, L"Right", + 0x4f, L"End", + 0x50, L"Down", + 0x51, L"Page Down", + 0x52, L"Insert", + 0x53, L"Delete", + 0x54, L"<00>", + 0x54, L"Sys Req", + 0x56, L"Help", + 0x5b, L"Left Windows", + 0x5c, L"Right Windows", + 0x5d, L"Application", + 0 , NULL +}; + +static ALLOC_SECTION_LDATA KBDTABLES KbdTables = { + /* + * Modifier keys + */ + &CharModifiers, + + /* + * Characters tables + */ + aVkToWcharTable, + + /* + * Diacritics (deadkeys) + */ + NULL, + + /* + * Names of Keys + */ + aKeyNames, + aKeyNamesExt, + NULL, + +// /* +// * Scan codes to Virtual Keys +// */ +// USHORT *KBD_LONG_POINTER pusVSCtoVK; +// BYTE bMaxVSCtoVK; +// PVSC_VK pVSCtoVK_E0; // Scancode has E0 prefix +// PVSC_VK pVSCtoVK_E1; // Scancode has E1 prefix + /* + * Scan codes to Virtual Keys + */ + ausVK, + sizeof(ausVK) / sizeof(ausVK[0]), + aE0VscToVk, + aE1VscToVk, + + /* + * Locale-specific special processing + */ + MAKELONG(0, KBD_VERSION), + + /* + * Ligatures + */ + 0, + 0, + NULL +}; + +PKBDTABLES KbdLayerDescriptor(VOID) +{ + // There doesn't seem to be any easy reliable way to assign VK_ESCAPE to + // the CAPITAL virtual scancode in compile time due to a high diversity + // of keyboard types. + // FIXME supporting only HID keyboards would make it easy to assign + // VK_ESCAPE reliably in compile-time (2017: all widely used compilers + // can detect that the whole expression is static and compute it in + // compile time, but the MSKLC built-in compiler most probably can't) + //int i; + //for( i = 0; i < KbdTables.bMaxVSCtoVK; ++i ){ + // if( KbdTables.pusVSCtoVK[i] == VK_CAPITAL ) + // // CAPITAL (~ CapsLk) -> ESCAPE + // KbdTables.pusVSCtoVK[i] = VK_ESCAPE; + //} + + return &KbdTables; +} + +// vim: set wrap ft=c: diff --git a/platform/win/source-20180817-gerdLTGT/gerdLTGT-purely_generated00.C b/platform/win/source-20180817-gerdLTGT/gerdLTGT-purely_generated00.C new file mode 100644 index 0000000..386c3fb --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/gerdLTGT-purely_generated00.C @@ -0,0 +1,344 @@ +/***************************************************************************\ +* Module Name: gerdLTGT.C +* +* keyboard layout +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* History: +* KBDTOOL v3.40 - Created Wed May 30 21:52:25 2018 +\***************************************************************************/ + +#include +#include "kbd.h" +#include "gerdLTGT.h" + +#if defined(_M_IA64) +#pragma section(".data") +#define ALLOC_SECTION_LDATA __declspec(allocate(".data")) +#else +#pragma data_seg(".data") +#define ALLOC_SECTION_LDATA +#endif + +/***************************************************************************\ +* ausVK[] - Virtual Scan Code to Virtual Key conversion table +\***************************************************************************/ + +static ALLOC_SECTION_LDATA USHORT ausVK[] = { + T00, T01, T02, T03, T04, T05, T06, T07, + T08, T09, T0A, T0B, T0C, T0D, T0E, T0F, + T10, T11, T12, T13, T14, T15, T16, T17, + T18, T19, T1A, T1B, T1C, T1D, T1E, T1F, + T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T2A, T2B, T2C, T2D, T2E, T2F, + T30, T31, T32, T33, T34, T35, + + /* + * Right-hand Shift key must have KBDEXT bit set. + */ + T36 | KBDEXT, + + T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot + + T38, T39, T3A, T3B, T3C, T3D, T3E, + T3F, T40, T41, T42, T43, T44, + + /* + * NumLock Key: + * KBDEXT - VK_NUMLOCK is an Extended key + * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL) + */ + T45 | KBDEXT | KBDMULTIVK, + + T46 | KBDMULTIVK, + + /* + * Number Pad keys: + * KBDNUMPAD - digits 0-9 and decimal point. + * KBDSPECIAL - require special processing by Windows + */ + T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home) + T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up), + T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp), + T4A, + T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left), + T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear), + T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right), + T4E, + T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End), + T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down), + T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn), + T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins), + T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del), + + T54, T55, T56, T57, T58, T59, T5A, T5B, + T5C, T5D, T5E, T5F, T60, T61, T62, T63, + T64, T65, T66, T67, T68, T69, T6A, T6B, + T6C, T6D, T6E, T6F, T70, T71, T72, T73, + T74, T75, T76, T77, T78, T79, T7A, T7B, + T7C, T7D, T7E + +}; + +static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = { + { 0x10, X10 | KBDEXT }, // Speedracer: Previous Track + { 0x19, X19 | KBDEXT }, // Speedracer: Next Track + { 0x1D, X1D | KBDEXT }, // RControl + { 0x20, X20 | KBDEXT }, // Speedracer: Volume Mute + { 0x21, X21 | KBDEXT }, // Speedracer: Launch App 2 + { 0x22, X22 | KBDEXT }, // Speedracer: Media Play/Pause + { 0x24, X24 | KBDEXT }, // Speedracer: Media Stop + { 0x2E, X2E | KBDEXT }, // Speedracer: Volume Down + { 0x30, X30 | KBDEXT }, // Speedracer: Volume Up + { 0x32, X32 | KBDEXT }, // Speedracer: Browser Home + { 0x35, X35 | KBDEXT }, // Numpad Divide + { 0x37, X37 | KBDEXT }, // Snapshot + { 0x38, X38 | KBDEXT }, // RMenu + { 0x47, X47 | KBDEXT }, // Home + { 0x48, X48 | KBDEXT }, // Up + { 0x49, X49 | KBDEXT }, // Prior + { 0x4B, X4B | KBDEXT }, // Left + { 0x4D, X4D | KBDEXT }, // Right + { 0x4F, X4F | KBDEXT }, // End + { 0x50, X50 | KBDEXT }, // Down + { 0x51, X51 | KBDEXT }, // Next + { 0x52, X52 | KBDEXT }, // Insert + { 0x53, X53 | KBDEXT }, // Delete + { 0x5B, X5B | KBDEXT }, // Left Win + { 0x5C, X5C | KBDEXT }, // Right Win + { 0x5D, X5D | KBDEXT }, // Application + { 0x5F, X5F | KBDEXT }, // Speedracer: Sleep + { 0x65, X65 | KBDEXT }, // Speedracer: Browser Search + { 0x66, X66 | KBDEXT }, // Speedracer: Browser Favorites + { 0x67, X67 | KBDEXT }, // Speedracer: Browser Refresh + { 0x68, X68 | KBDEXT }, // Speedracer: Browser Stop + { 0x69, X69 | KBDEXT }, // Speedracer: Browser Forward + { 0x6A, X6A | KBDEXT }, // Speedracer: Browser Back + { 0x6B, X6B | KBDEXT }, // Speedracer: Launch App 1 + { 0x6C, X6C | KBDEXT }, // Speedracer: Launch Mail + { 0x6D, X6D | KBDEXT }, // Speedracer: Launch Media Selector + { 0x1C, X1C | KBDEXT }, // Numpad Enter + { 0x46, X46 | KBDEXT }, // Break (Ctrl + Pause) + { 0, 0 } +}; + +static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = { + { 0x1D, Y1D }, // Pause + { 0 , 0 } +}; + +/***************************************************************************\ +* aVkToBits[] - map Virtual Keys to Modifier Bits +* +* See kbd.h for a full description. +* +* The keyboard has only three shifter keys: +* SHIFT (L & R) affects alphabnumeric keys, +* CTRL (L & R) is used to generate control characters +* ALT (L & R) used for generating characters by number with numpad +\***************************************************************************/ +static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = { + { VK_SHIFT , KBDSHIFT }, + { VK_CONTROL , KBDCTRL }, + { VK_MENU , KBDALT }, + { 0 , 0 } +}; + +/***************************************************************************\ +* aModification[] - map character modifier bits to modification number +* +* See kbd.h for a full description. +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = { + &aVkToBits[0], + 2, + { + // Modification# // Keys Pressed + // ============= // ============= + 0, // + 1, // Shift + 2 // Control + } +}; + +/***************************************************************************\ +* +* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states +* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states +* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states +* +* Table attributes: Unordered Scan, null-terminated +* +* Search this table for an entry with a matching Virtual Key to find the +* corresponding unshifted and shifted WCHAR characters. +* +* Special values for VirtualKey (column 1) +* 0xff - dead chars for the previous entry +* 0 - terminate the list +* +* Special values for Attributes (column 2) +* CAPLOK bit - CAPS-LOCK affect this key like SHIFT +* +* Special values for wch[*] (column 3 & 4) +* WCH_NONE - No character +* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none) +* WCH_LGTR - Ligature (generates multiple characters) +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VK_TO_WCHARS2 aVkToWch2[] = { +// | | Shift | +// |=========|=========| + {VK_TAB ,0 ,'\t' ,'\t' }, + {VK_ADD ,0 ,'+' ,'+' }, + {VK_DIVIDE ,0 ,'/' ,'/' }, + {VK_MULTIPLY ,0 ,'*' ,'*' }, + {VK_SUBTRACT ,0 ,'-' ,'-' }, + {0 ,0 ,0 ,0 } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHARS3 aVkToWch3[] = { +// | | Shift | Ctrl | +// |=========|=========|=========| + {VK_OEM_3 ,0 ,WCH_NONE ,WCH_NONE ,'~' }, + {'1' ,0 ,WCH_NONE ,WCH_NONE ,'!' }, + {'2' ,0 ,0x00e4 ,0x00c4 ,'@' }, + {'3' ,0 ,0x00f6 ,0x00d6 ,'#' }, + {'4' ,0 ,WCH_NONE ,WCH_NONE ,'$' }, + {'5' ,0 ,0x00fc ,0x00dc ,'%' }, + {'6' ,0 ,WCH_NONE ,WCH_NONE ,'^' }, + {'7' ,0 ,WCH_NONE ,WCH_NONE ,'&' }, + {'8' ,0 ,WCH_NONE ,WCH_NONE ,'*' }, + {'9' ,0 ,WCH_NONE ,WCH_NONE ,'(' }, + {'0' ,0 ,WCH_NONE ,WCH_NONE ,')' }, + {VK_OEM_4 ,0 ,0x00df ,0x1e9e ,'{' }, + {VK_OEM_6 ,0 ,WCH_NONE ,WCH_NONE ,'}' }, + {VK_OEM_102 ,0 ,WCH_NONE ,WCH_NONE ,WCH_NONE }, + {VK_OEM_7 ,0 ,'\'' ,'\"' ,WCH_NONE }, + {VK_OEM_COMMA ,0 ,',' ,'<' ,0x2013 }, + {VK_OEM_PERIOD,0 ,'.' ,'>' ,'!' }, + {'P' ,0 ,'p' ,'P' ,0x00a7 }, + {'Y' ,0 ,'y' ,'Y' ,WCH_NONE }, + {'F' ,0 ,'f' ,'F' ,',' }, + {'G' ,0 ,'g' ,'G' ,'7' }, + {'C' ,0 ,'c' ,'C' ,'8' }, + {'R' ,0 ,'r' ,'R' ,'9' }, + {'L' ,0 ,'l' ,'L' ,'[' }, + {VK_OEM_2 ,0 ,'/' ,'?' ,']' }, + {VK_OEM_PLUS ,0 ,'=' ,'+' ,'+' }, + {VK_OEM_5 ,0 ,'\\' ,'|' ,'|' }, + {'A' ,0 ,'a' ,'A' ,'@' }, + {'O' ,0 ,'o' ,'O' ,0x00b0 }, + {'E' ,0 ,'e' ,'E' ,0x20ac }, + {'U' ,0 ,'u' ,'U' ,'`' }, + {'I' ,0 ,'i' ,'I' ,WCH_NONE }, + {'D' ,0 ,'d' ,'D' ,':' }, + {'H' ,0 ,'h' ,'H' ,'4' }, + {'T' ,0 ,'t' ,'T' ,'5' }, + {'N' ,0 ,'n' ,'N' ,'6' }, + {'S' ,0 ,'s' ,'S' ,'=' }, + {VK_OEM_MINUS ,0 ,'-' ,'_' ,'\\' }, + {VK_OEM_1 ,0 ,';' ,':' ,WCH_NONE }, + {'Q' ,0 ,'q' ,'Q' ,WCH_NONE }, + {'J' ,0 ,'j' ,'J' ,WCH_NONE }, + {'K' ,0 ,'k' ,'K' ,WCH_NONE }, + {'X' ,0 ,'x' ,'X' ,WCH_NONE }, + {'B' ,0 ,'b' ,'B' ,'0' }, + {'M' ,0 ,'m' ,'M' ,'1' }, + {'W' ,0 ,'w' ,'W' ,'2' }, + {'V' ,0 ,'v' ,'V' ,'3' }, + {'Z' ,0 ,'z' ,'Z' ,'.' }, + {VK_DECIMAL ,0 ,'.' ,'.' ,'.' }, + {VK_SPACE ,0 ,' ' ,0x00a0 ,0x00a0 }, + {VK_BACK ,0 ,'\b' ,'\b' ,0x007f }, + {VK_ESCAPE ,0 ,0x001b ,0x001b ,0x001b }, + {VK_RETURN ,0 ,'\r' ,'\r' ,'\n' }, + {VK_CANCEL ,0 ,0x0003 ,0x0003 ,0x0003 }, + {0 ,0 ,0 ,0 ,0 } +}; + +// Put this last so that VkKeyScan interprets number characters +// as coming from the main section of the kbd (aVkToWch2 and +// aVkToWch5) before considering the numpad (aVkToWch1). + +static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = { + { VK_NUMPAD0 , 0 , '0' }, + { VK_NUMPAD1 , 0 , '1' }, + { VK_NUMPAD2 , 0 , '2' }, + { VK_NUMPAD3 , 0 , '3' }, + { VK_NUMPAD4 , 0 , '4' }, + { VK_NUMPAD5 , 0 , '5' }, + { VK_NUMPAD6 , 0 , '6' }, + { VK_NUMPAD7 , 0 , '7' }, + { VK_NUMPAD8 , 0 , '8' }, + { VK_NUMPAD9 , 0 , '9' }, + { 0 , 0 , '\0' } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = { + { (PVK_TO_WCHARS1)aVkToWch3, 3, sizeof(aVkToWch3[0]) }, + { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) }, + { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) }, + { NULL, 0, 0 }, +}; + +/***************************************************************************\ +* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables +* +* Table attributes: Ordered Scan (by scancode), null-terminated +* +* Only the names of Extended, NumPad, Dead and Non-Printable keys are here. +* (Keys producing printable characters are named by that character) +\***************************************************************************/ + +static ALLOC_SECTION_LDATA KBDTABLES KbdTables = { + /* + * Modifier keys + */ + &CharModifiers, + + /* + * Characters tables + */ + aVkToWcharTable, + + /* + * Diacritics + */ + NULL, + + /* + * Names of Keys + */ + NULL, + NULL, + NULL, + + /* + * Scan codes to Virtual Keys + */ + ausVK, + sizeof(ausVK) / sizeof(ausVK[0]), + aE0VscToVk, + aE1VscToVk, + + /* + * Locale-specific special processing + */ + MAKELONG(0, KBD_VERSION), + + /* + * Ligatures + */ + 0, + 0, + NULL +}; + +PKBDTABLES KbdLayerDescriptor(VOID) +{ + return &KbdTables; +} diff --git a/platform/win/source-20180817-gerdLTGT/gerdLTGT-purely_generated00.H b/platform/win/source-20180817-gerdLTGT/gerdLTGT-purely_generated00.H new file mode 100644 index 0000000..733b58e --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/gerdLTGT-purely_generated00.H @@ -0,0 +1,103 @@ +/****************************** Module Header ******************************\ +* Module Name: gerdLTGT.H +* +* keyboard layout header +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* Various defines for use by keyboard input code. +* +* History: +* +* created by KBDTOOL v3.40 Wed May 30 21:52:25 2018 +* +\***************************************************************************/ + +/* + * kbd type should be controlled by cl command-line argument + */ +#define KBD_TYPE 4 + +/* +* Include the basis of all keyboard table values +*/ +#include "kbd.h" +/***************************************************************************\ +* The table below defines the virtual keys for various keyboard types where +* the keyboard differ from the US keyboard. +* +* _EQ() : all keyboard types have the same virtual key for this scancode +* _NE() : different virtual keys for this scancode, depending on kbd type +* +* +------+ +----------+----------+----------+----------+----------+----------+ +* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd | +* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 | +\****+-------+_+----------+----------+----------+----------+----------+----------+*/ + +#undef T0C + #define T0C _EQ( OEM_4 ) +#undef T0D + #define T0D _EQ( OEM_6 ) +#undef T10 + #define T10 _EQ( OEM_7 ) +#undef T11 + #define T11 _EQ( OEM_COMMA ) +#undef T12 + #define T12 _EQ( OEM_PERIOD ) +#undef T13 + #define T13 _EQ( 'P' ) +#undef T14 + #define T14 _EQ( 'Y' ) +#undef T15 + #define T15 _EQ( 'F' ) +#undef T16 + #define T16 _EQ( 'G' ) +#undef T17 + #define T17 _EQ( 'C' ) +#undef T18 + #define T18 _EQ( 'R' ) +#undef T19 + #define T19 _EQ( 'L' ) +#undef T1A + #define T1A _EQ( OEM_2 ) +#undef T1B + #define T1B _EQ( OEM_PLUS ) +#undef T1F + #define T1F _EQ( 'O' ) +#undef T20 + #define T20 _EQ( 'E' ) +#undef T21 + #define T21 _EQ( 'U' ) +#undef T22 + #define T22 _EQ( 'I' ) +#undef T23 + #define T23 _EQ( 'D' ) +#undef T24 + #define T24 _EQ( 'H' ) +#undef T25 + #define T25 _EQ( 'T' ) +#undef T26 + #define T26 _EQ( 'N' ) +#undef T27 + #define T27 _EQ( 'S' ) +#undef T28 + #define T28 _EQ( OEM_MINUS ) +#undef T2C + #define T2C _EQ( OEM_1 ) +#undef T2D + #define T2D _EQ( 'Q' ) +#undef T2E + #define T2E _EQ( 'J' ) +#undef T2F + #define T2F _EQ( 'K' ) +#undef T30 + #define T30 _EQ( 'X' ) +#undef T31 + #define T31 _EQ( 'B' ) +#undef T33 + #define T33 _EQ( 'W' ) +#undef T34 + #define T34 _EQ( 'V' ) +#undef T35 + #define T35 _EQ( 'Z' ) + diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.C.bak01 b/platform/win/source-20180817-gerdLTGT/gerdLTGT.C similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.C.bak01 rename to platform/win/source-20180817-gerdLTGT/gerdLTGT.C diff --git a/platform/win/source-20180817-gerdLTGT/gerdLTGT.C.howto b/platform/win/source-20180817-gerdLTGT/gerdLTGT.C.howto new file mode 100644 index 0000000..f895ae9 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/gerdLTGT.C.howto @@ -0,0 +1,12 @@ +lshift 0xa0 +rshift 0xa1 +lctrl 0xa2 +lctrl 0xa3 +lmenu 0xa4 +rmenu 0xa5 + + + +shift 0x10 +ctrl 0x11 +menu 0x12 diff --git a/platform/win/gerd04/gerdLTGT.DEF b/platform/win/source-20180817-gerdLTGT/gerdLTGT.DEF similarity index 100% rename from platform/win/gerd04/gerdLTGT.DEF rename to platform/win/source-20180817-gerdLTGT/gerdLTGT.DEF diff --git a/platform/win/gerd04/gerdLTGT.H b/platform/win/source-20180817-gerdLTGT/gerdLTGT.H similarity index 100% rename from platform/win/gerd04/gerdLTGT.H rename to platform/win/source-20180817-gerdLTGT/gerdLTGT.H diff --git a/platform/win/source-20180817-gerdLTGT/gerdLTGT.RC b/platform/win/source-20180817-gerdLTGT/gerdLTGT.RC new file mode 100644 index 0000000..c758f8f --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/gerdLTGT.RC @@ -0,0 +1,51 @@ +#include "winver.h" +#include "winuser.h" +1 VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L +FILEOS 0x40004L + FILETYPE VFT_DLL + FILESUBTYPE VFT2_DRV_KEYBOARD +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004B0" + BEGIN + VALUE "CompanyName", "shit00\0" + VALUE "FileDescription", "German ULKL keyboard layout (LTGT variant)\0" + VALUE "FileVersion", "shit02\0" + VALUE "InternalName", "shit03\0" + VALUE "ProductName", "shit04\0" + VALUE "Release Information","shit05\0" + VALUE "LegalCopyright", "shit06\0" + VALUE "OriginalFilename", "kbdgr5.dll\0" + VALUE "ProductVersion", "shit08\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0000, 0x04B0 + END +END + +STRINGTABLE DISCARDABLE +LANGUAGE 9, 1 +BEGIN + 1200 "de-DE" +END + + +STRINGTABLE DISCARDABLE +LANGUAGE 9, 1 +BEGIN + 1000 "German Dvorak ltgt (useful for text with lots of <>)" +END + + +STRINGTABLE DISCARDABLE +LANGUAGE 9, 1 +BEGIN + 1100 "German or related (all locations world-wide)" +END diff --git a/platform/win/source-20180817-gerdLTGT/gerdLTGT.RC-purely_generated00 b/platform/win/source-20180817-gerdLTGT/gerdLTGT.RC-purely_generated00 new file mode 100644 index 0000000000000000000000000000000000000000..27f899a187f7d964ce29560b726988ad3e048970 GIT binary patch literal 2528 zcmc(gTWcCo6ovP5q5ol+zNC;gG4Z8P3b7iIPF2(hg+kD1jMPLK&F$a!TjzKjCoz;M zy)ewox$Lv|TKjh1*wk+9!e(}BBO6;}vE941J7%f9w<}g&+bb)v*SDH=tZNNxS(9(m zP8n%8V$`sN{k%-XPWF^+-wt_?dCQFa$u>G$R<$$xY`quG?>-r9o?`jL>LB~dziVHx zd1w#Vxnw7gFO&5$hii$TtHpW0BZPX&&vf+co3-I8kDP+}9Q4UEsVUoOFki z=iscdTY>!vKBzjR71rv`w;s2=S3!3R?}%3nz7>&C+$LC`61y?-H*lS=W92=*OH+tN zUZdyfxmIB8BOYXbtu09Q;gP^vo{7Obw`*J20Bn!s%7EFJ^?i236T@K&pDXfjNVZ+L zGY912Ez(1{&G{anGl6}===%%!g2p_C;GZg%muQ#Y7TBAj_hyYH#^1{IYlk!<4tMOP z%zl7#hV+CtvOO>@k-X$TV=jNE{8y|!I0;pbxI|zb!+D6r0GSah38P2mw@CaRhrUC( z%wZ3#W9n0WRdq$Kz9Ls)#Vjd{#3toGfa9*1DPocs{Ksr3vz3tY3`zZf#q#` z%AXWV1BXZ+9OA!-3Rit6>_%{w)nXhw=v2iFTr8ta<@oq-XU5+`kYIh{{HqFCz)D#; zA#YZj>WJalpm!+$rsVCIh$#1pac!+Nt5+zVp&B#`wfH=q#cbpwxI0ISW@n8|@ZHeo z_tSa4d-Y+HZnzcgg!z8aLzDW|5^pKxAyKCcWv5f8F)e53agPFWwWXh$DwF>kGQo-(jUjZb@q% z)xSjMeU~Bo^IccB#fsQP{4e=_v`=)T|INGfBqDj<{ti*6^BFgGx5XaWH{((L&#C_` U7sc+LwUnI^k=31}81Lr!6Hcr?$N&HU literal 0 HcmV?d00001 diff --git a/platform/win/source-20180817-gerdLTGT/gerdLTGT.klc b/platform/win/source-20180817-gerdLTGT/gerdLTGT.klc new file mode 100644 index 0000000..54cb1ce --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/gerdLTGT.klc @@ -0,0 +1,327 @@ +// 2010-2017 Jan Pacner +// etaoin shrdlu! + +// The concept of this keyboard layout +// motto: be as much compatible with ISO dvorak as possible +// 4. level is the same as 3. level +// 2. level of ISO dvorak goes without modifications to the 3. level +// the whole national alphabet is accessible directly from 1. and 2. level +// without any exception +// 3. level has some additional non-alphabet characters (e.g. numbers) +// 3. level is accessible only by pressing both Shifts at once (and +// holding either of them) +// there are 2 variants which differ in placement and/or availability of +// characters ' " < > „ “ en_dash +// in `ltgt`, characters „ “ are not available and ' " < > are at their +// original dvorak places and ! is duplicated for better reachability +// in `writer`, all characters are available, but " < > are in +// the 3. level, thus less reachable + +// ----------- standard ISO dvorak, 1. and 2. level +// ~ ! @ # $ % ^ & * ( ) { } +// ` 1 2 3 4 5 6 7 8 9 0 [ ] +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// space +// space + +// ----------- german dvorak ltgt, 1. and 2. levelll +// ä Ö Ü ß +// ä ö ü ß +// +// " < > P Y F G C R L ? + | +// ' , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak ltgt, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// nda ! § , 7 8 9 [ ] + | +// en dash +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak writer, 1. and 2. level +// ä Ö Ü ß +// ä ö ü ß +// +// “ nda ' P Y F G C R L ? + | +// en dash +// „ , . p y f g c r l / = \ +// +// A O E U I D H T N S _ +// a o e u i d h t n s - +// +// : Q J K X B M W V Z +// ; q j k x b m w v z +// +// NBSP +// space + +// ----------- german dvorak writer, 3. level +// ~ ! @ # $ % ^ & * ( ) { } +// +// " < > § , 7 8 9 [ ] + | +// +// @ ° € ` : 4 5 6 = \ +// +// 0 1 2 3 . +// +// NBSP + +// ----------- german dvorak (ltgt|writer), 4. level +// the same as 3. level + +// KBD identifier_max_8_bytes_long "Some description to show in keyboard settings and while switching layouts" +KBD gerdLTGT "German Dvorak ltgt (useful for text with lots of <>)" +//KBD gerdLTGT "German Dvorak writer (useful for text with lower/upper UTF-8 double quotes)" + +COPYRIGHT "MIT license" + +COMPANY "github.com/dumblob/ULKL/" + +LOCALENAME "de-DE" + +// LOCALEID "00000000" +LOCALEID "00000407" + +//FIXME 1.1 after unused keys produce the character +VERSION 1.0 + +//ATTRIBUTES + +//MODIFIERS + +SHIFTSTATE + +// shift_state_idx // column_below modifiers +0 // 4 +1 // 5 LSHIFT or RSHIFT pressed +2 // 6 both LSHIFT and RSHIFT pressed simultaneously + +LAYOUT +// an extra @ at the end is a dead key +// -1 denotes the character +// SC denotes a Virtual Scan Code +// Cap ~ CapsInfo (probably whether CapsLock is applicable) + +// topmost row + +//SC VK_ Cap 0 1 2 +29 OEM_3 0 -1 -1 007e // , , TILDE +02 1 0 -1 -1 0021 // , , EXCLAMATION MARK +03 2 0 00e4 00c4 0040 // adiaeresis, Adiaeresis, COMMERCIAL AT +04 3 0 00f6 00d6 0023 // odiaeresis, Odiaeresis, NUMBER SIGN +05 4 0 -1 -1 0024 // , , DOLLAR SIGN +06 5 0 00fc 00dc 0025 // udiaeresis, Udiaeresis, PERCENT SIGN +07 6 0 -1 -1 005e // , , CIRCUMFLEX ACCENT +08 7 0 -1 -1 0026 // , , AMPERSAND +09 8 0 -1 -1 002a // , , ASTERISK +0a 9 0 -1 -1 0028 // , , LEFT PARENTHESIS +0b 0 0 -1 -1 0029 // , , RIGHT PARENTHESIS +0c OEM_4 0 00df 1e9e 007b // ssharp, U1E9E, LEFT CURLY BRACKET (BRACELEFT) +0d OEM_6 0 -1 -1 007d // , , RIGHT CURLY BRACKET (BRACERIGHT) +// FIXME wtf is this key? is it really ? +56 OEM_102 0 -1 -1 -1 // , , +//0e ???? 0 ???? ???? ???? // backspace, backspace, backspace + +// top row + +//0f ???? 0 ???? ???? ???? // tab, tab, tab +// ltgt variant +10 OEM_7 0 0027 0022 -1 // APOSTROPHE, QUOTATION MARK (QUOTEDBL), +11 OEM_COMMA 0 002c 003c 2013 // COMMA, LESS-THAN SIGN, U2013 (EN DASH, pomlcka) +12 OEM_PERIOD 0 002e 003e 0021 // FULL STOP (PERIOD), GREATER-THAN SIGN, EXCLAMATION MARK +// writer variant +//10 OEM_7 0 201e 201c 0022 // U201E LOWER QUOTATION MARK (QUOTEDBL), U201C UPPER QUOTATION MARK (QUOTEDBL), QUOTATION MARK (QUOTEDBL) +//11 OEM_COMMA 0 002c 2013 003c // COMMA, U2013 (EN DASH, pomlcka), LESS-THAN SIGN +//12 OEM_PERIOD 0 002e 0027 003e // FULL STOP (PERIOD), APOSTROPHE, GREATER-THAN SIGN + +13 P 0 p P 00a7 // LATIN SMALL LETTER P, LATIN CAPITAL LETTER P, SECTION SIGN (PARAGRAPH) +14 Y 0 y Y -1 // LATIN SMALL LETTER Y, LATIN CAPITAL LETTER Y, +15 F 0 f F 002c // LATIN SMALL LETTER F, LATIN CAPITAL LETTER F, COMMA +16 G 0 g G 7 // LATIN SMALL LETTER G, LATIN CAPITAL LETTER G, DIGIT SEVEN +17 C 0 c C 8 // LATIN SMALL LETTER C, LATIN CAPITAL LETTER C, DIGIT EIGHT +18 R 0 r R 9 // LATIN SMALL LETTER R, LATIN CAPITAL LETTER R, DIGIT NINE +19 L 0 l L 005b // LATIN SMALL LETTER L, LATIN CAPITAL LETTER L, LEFT SQUARE BRACKET +1a OEM_2 0 002f 003f 005d // SOLIDUS (SLASH), QUESTION MARK, RIGHT SQUARE BRACKET +1b OEM_PLUS 0 003d 002b 002b // EQUALS SIGN, PLUS SIGN, PLUS SIGN +2b OEM_5 0 005c 007c 007c // REVERSE SOLIDUS (BACKSLASH), VERTICAL LINE (BAR), VERTICAL LINE (BAR) + +// home/middle row + +//CapsLk +//3a ???? 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +//3a SGCap 0 001b 001b 001b // ESCAPE, ESCAPE, ESCAPE +1e A 0 a A 0040 // LATIN SMALL LETTER A, LATIN CAPITAL LETTER A, COMMERCIAL AT +1f O 0 o O 00b0 // LATIN SMALL LETTER O, LATIN CAPITAL LETTER O, DEGREE +20 E 0 e E 20ac // LATIN SMALL LETTER E, LATIN CAPITAL LETTER E, EURO SIGN +21 U 0 u U 0060 // LATIN SMALL LETTER U, LATIN CAPITAL LETTER U, GRAVE ACCENT (GRAVE) +22 I 0 i I -1 // LATIN SMALL LETTER I, LATIN CAPITAL LETTER I, +23 D 0 d D 003a // LATIN SMALL LETTER D, LATIN CAPITAL LETTER D, COLON +24 H 0 h H 4 // LATIN SMALL LETTER H, LATIN CAPITAL LETTER H, DIGIT FOUR +25 T 0 t T 5 // LATIN SMALL LETTER T, LATIN CAPITAL LETTER T, DIGIT FIVE +26 N 0 n N 6 // LATIN SMALL LETTER N, LATIN CAPITAL LETTER N, DIGIT SIX +27 S 0 s S 003d // LATIN SMALL LETTER S, LATIN CAPITAL LETTER S, EQUALS SIGN +// pomlcka (= minus = dash) +28 OEM_MINUS 0 002d 005f 005c // HYPHEN-MINUS (FIXME is it the plain minus?), LOW LINE (UNDERSCORE), REVERSE SOLIDUS (BACKSLASH) +//1c ???? 0 ???? ???? ???? // enter/return, enter/return, enter/return + +// bottom row + +//2a ???? 0 ???? ???? ???? // left shift, left shift, left shift +// left bottom key, right from , which doesn't follow the kbd standard +// FIXME wtf is this key? is it really ? +//56 OEM_102 0 -1 -1 -1 // , , +2c OEM_1 0 003b 003a -1 // SEMICOLON, COLON, +2d Q 0 q Q -1 // LATIN SMALL LETTER Q, LATIN CAPITAL LETTER Q, +2e J 0 j J -1 // LATIN SMALL LETTER J, LATIN CAPITAL LETTER J, +2f K 0 k K -1 // LATIN SMALL LETTER K, LATIN CAPITAL LETTER K, +30 X 0 x X -1 // LATIN SMALL LETTER X, LATIN CAPITAL LETTER X, +31 B 0 b B 0 // LATIN SMALL LETTER B, LATIN CAPITAL LETTER B, DIGIT ZERO +32 M 0 m M 1 // LATIN SMALL LETTER M, LATIN CAPITAL LETTER M, DIGIT ONE +33 W 0 w W 2 // LATIN SMALL LETTER W, LATIN CAPITAL LETTER W, DIGIT TWO +34 V 0 v V 3 // LATIN SMALL LETTER V, LATIN CAPITAL LETTER V, DIGIT THREE +35 Z 0 z Z 002e // LATIN SMALL LETTER Z, LATIN CAPITAL LETTER Z, FULL STOP (PERIOD) +// numpad dot +53 DECIMAL 0 002e 002e 002e // FULL STOP (PERIOD), FULL STOP (PERIOD), FULL STOP (PERIOD) +//36 ???? 0 ???? ???? ???? // right shift, right shift, right shift + +// bottom-most row + +//?? ???? 0 ???? ???? ???? // left ctrl, left ctrl, left ctrl +//5b ???? 0 ???? ???? ???? // left super (win), left super (win), left super (win) +//?? ???? 0 ???? ???? ???? // left alt (meta), left alt (meta), left alt (meta) +39 SPACE 0 0020 00a0 00a0 // SPACE, NO-BREAK SPACE, NO-BREAK SPACE +//38 ???? 0 ???? ???? ???? // right alt (meta), right alt (meta), right alt (meta) +//5c ???? 0 ???? ???? ???? // right super (win), right super (win), right super (win) +//?? ???? 0 ???? ???? ???? // menu, menu, menu +//5d ???? 0 ???? ???? ???? // menu, menu, menu +//56 ???? 0 ???? ???? ???? // menu, menu, menu +//1d ???? 0 ???? ???? ???? // right ctrl, right ctrl, right ctrl +//46 ???? 0 ???? ???? ???? // scroll lock, scroll lock, scroll lock + +//LIGATURE +// +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// LigatureRow( a: string, mod: byte = SHIFTSTATE[?], tuple ) +//// a mod b c + +//KEYNAME +// +//01 Esc +//0e Backspace +//0f Tab +//1c Enter +//1d Ctrl +////2a Shift +//2a "Left Shift" +//36 "Right Shift" +//37 "Num *" +//38 Alt +//39 Space +//3a "Caps Lock" +//3b F1 +//3c F2 +//3d F3 +//3e F4 +//3f F5 +//40 F6 +//41 F7 +//42 F8 +//43 F9 +//44 F10 +//45 Pause +//46 "Scroll Lock" +//47 "Num 7" +//48 "Num 8" +//49 "Num 9" +//4a "Num -" +//4b "Num 4" +//4c "Num 5" +//4d "Num 6" +//4e "Num +" +//4f "Num 1" +//50 "Num 2" +//51 "Num 3" +//52 "Num 0" +//53 "Num Del" +//54 "Sys Req" +//57 F11 +//58 F12 +//7c F13 +//7d F14 +//7e F15 +//7f F16 +//80 F17 +//81 F18 +//82 F19 +//83 F20 +//84 F21 +//85 F22 +//86 F23 +//87 F24 +// +//KEYNAME_EXT +// +//1c "Num Enter" +//1d "Right Ctrl" +//35 "Num /" +//37 "Prnt Scrn" +//38 "Right Alt" +//45 "Num Lock" +//46 Break +//47 Home +//48 Up +//49 "Page Up" +//4b Left +//4d Right +//4f End +//50 Down +//51 "Page Down" +//52 Insert +//53 Delete +//54 <00> +//54 "Sys Req" +//56 Help +//5b "Left Windows" +//5c "Right Windows" +//5d Application + +DESCRIPTIONS + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German Dvorak ltgt (useful for text with lots of <>) +//0409 German Dvorak writer (useful for text with lower/upper UTF-8 double quotes) + +LANGUAGENAMES + +// Don't ask me why the parser doesn't strip double quotes here ( +// even though they're stripped for the KBD command/section above). +0409 German or related (all locations world-wide) + +ENDKBD + +// vim: set ft=javascript: diff --git a/platform/win/source-20180817-gerdLTGT/i386/gerdLTGT.dll b/platform/win/source-20180817-gerdLTGT/i386/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..a0dfadda7b32c3753d0ccbb1dd9cf85534e38221 GIT binary patch literal 6144 zcmeI0UvSjb7016fi8bh=>4;V>v>S|y8e$;7-%4x5hyj8uB#;FIhC)b|WX&cUH$k8x zg5sYC9_WlS^?~VNrLAq#N^ROY7L~R<;*1YWUrLqf_+VSwZl|;}oie4LbAP++LTR08 zJJWH-`?!Vu?=bm%!xi?v{e!r?E)$pD>C%pzOwfWzF|ML#bSAF*Nt28z3?fTbT z^6mQ6P-Z+nmd_35`$ppZeWRnfiTLJpJim1`o*9j|cXr1|as%n6>C>-hC=NZVCjH*J z^p*Qc@2;1&?CYVt>!nAE+*ahc=ju%VkoEmnl65VXlCD}OUb*(6QlC?*s=w0JM#UMW zT3A!#S8*zDNcSW~P~=kzOm zQIFx+ztZ1-**jq)ivq6u34|R`I>a0a_%lQx&`{0TdD@v zp}xsp)QsstGmHEL~&J!Ri-%Bsug+)m<)KeYN9ZKTh+{ zu);Y?!J|}IszLlph5OZycd4)%zaWkllFH&~D!j$2?$ri7?jFC+lj_CRJMq0fUKKi7 zc_&<~G`^_98a!$ZT&4_usY1I3@Jfs3@+f?r_;+Fk)4#ETzk7``=qZ{_o6vM0R@;ol`mxpkmP%u#Em&v}>kMI;j9G^FzX-l)2(U=O?+cEOpj9nOLa;O#ID@dMRD{6J@KP#u1tGtg%I z0HPzEfOo^=5L@dQyayhE*j!WaUN{Nc;30_3bO53|JrA+D_Cai0u`{J&Zxq zLoYNvB%$e{6`CHJi!^=U%W9x(m#JFV3r}CCx()CI1U^mTd&lrQD|`T-ySCWI&B}Bo z+7IyhTa=Y6Qt7Vt>UB}8`KrAyQ=a5K%)9$W=`AP?rt<^I)Y4SbKsKx8n+KA8JJR{~ z^muBYdZA1Wc!0y^|$rkKI zTb2?1Pl!^t5?QhH_5CE0ds7uCg2#e!s@g z9{rj;IigN9=OSiHGtV#|tR(i0Fk6!LeqU2Lb{xHAy<}Z{GwRpcO+U+*zrFJUdE&(6 z33_Brob%(G+_q-Z^%CM!P-IJy^NZxn@$Jo?^L(^gLQJz*Vl>}2CWelui-^@b&~Y4FrisvHnIc=1%Qk08A2v=YZ)276HeM-zM@8P`Db<@yrM$^i%G>!` z%3Dk<5~HomXsa^X ziiFMj@E6lk*%P{{>BHLQH6=eN$!Rgaa&L6AM>2jll>ITzO3Jl1N7*kb{UOCHn;CDB zpKTZ^%JVL!)K6PwdaZ*X^0UgCkMsXO4OIC*2jhg>I)va%*?plb)!fB6*QmF1XgjoX zcmF^2b5Z=hME$gy;@^~fS58h=|4zB0n2YL9U84SS`WL8Q(7<_I(SDRNa-C1Ll+C}- zr+WS@u0CHPZ+mGi-o26E#q5J_?v0)7;f-)5d&*8u>5ZB{{JnfSS&g$FuMcAlPZhMc zlr~dvjAuK=PMbkS%Mb_Bj6BNz%F%J5?_+05^aSjjX6l=CIp5yzBfagQQR3c8Sc?1O zem73|uWY_u+>YJ(@huwKUbA_}n7?!aio3SO?GZm>oSSlzTWyj^F--jqc5aTAJf~6| zIs2%|5vAicB;7!$h9rZ37{THjhf%Xr1SWqG4m6|K+o5S=8WjFzof zVYz=4lY7yUnS za^A6)<1HszPPd$CIonbb#DW>Y%%CA?41%CFXb+M>D(DRcf^0Am>`-10#1HqwS zGMEaE1jmBo!HM8x@P2SQI1`)=YQk7JBb*sFgpFYkwubFtGE9ZN;Xs%TC&HcKzVP|* zKzJye45z{);j!>|cp^L*z8{_r&xB{gnnWxyBQZ14kZ4QxwLy2r+ NkNxTSarz%=;2*wB$7=up literal 0 HcmV?d00001 diff --git a/platform/win/source-20180817-gerdLTGT/i386/gerdLTGT.exp b/platform/win/source-20180817-gerdLTGT/i386/gerdLTGT.exp new file mode 100644 index 0000000000000000000000000000000000000000..3f979e2122a9938dbef239ce2303217e00547812 GIT binary patch literal 672 zcmZuu%}T>S5T3MZJ$PsjN~t0_6k0*jYC%db7A=T2R?+rkK+|MffGx~Kaa%6o_# z#DF#!6NoZCipiSi?esor6c30Lp7T4(5MNVF&J3@^0zHLf@XrSk|1H%L_{b6<(EhG% z#!a=pQCG~96R0*#Rlj7s!d!z}j%Rb2LOUHCgE`Dm!DP&1f~7H!3zij`e2d7aznJj6 zAv;1OK}z5PR-w3}g+FB%4rE~_5yLlhHU-Tv)8DoXZo78Nle2pZvbtHT;$)zhkRT3+ zBkKIXuaXGrHZIM6yW^kQe4+jH{Ce5Dz6E$kJ&%C(lGbn;ceSluUBgC?J=@W`)>&9o zNbqu6@N#!A=PIfy=XM(PQdl@nt8Cb(j$)aa{uK;|RR8Z=r#hnGUe)wdytQTA`3i44 p9V&z76)3)o<`yX39d7#d`bxT%$5?{Z(1S$GmsX01=zi2>egL?Fc4Pnm literal 0 HcmV?d00001 diff --git a/platform/win/source-20180817-gerdLTGT/i386/gerdLTGT.lib b/platform/win/source-20180817-gerdLTGT/i386/gerdLTGT.lib new file mode 100644 index 0000000000000000000000000000000000000000..dafec1462f87306306832a0432f9764af80d7935 GIT binary patch literal 1766 zcmcIlPfrs;6#wlmqHKsZqDRS+kbsv;mtCZWm?AaWbSb1PCl5pER%ilgv#bZh!7t$V z@aT;T7fxI~K*9$g;cMV~+Zj7(i><*)cILg`yxn=f_h)u$sTS9FU)wL7n+6hB1T}qq}l4@%fImL&!B%KREVUgmAf4h#$D-=BVXMEo8Q zPZ~xxYHWYnncnEAzzPXpl_J*yGHwWGTdB8v^jl z#_uAGPw^xNe;s%wHC{}FG~adO*gEAw>c#b4tzOKuUXD}u*va1Y5~W++NvoH6g>t=o zQ;J-ONdL9 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180817-gerdLTGT/ia64/gerdLTGT.dll b/platform/win/source-20180817-gerdLTGT/ia64/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..02dee5eade9d5576fa5bf2096b56a79a5ce75048 GIT binary patch literal 7168 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 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (10).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (10).sh new file mode 100644 index 0000000..a142239 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (10).sh @@ -0,0 +1,253 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=X64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + printf 'INFO Compiling %s...\n' "$outdir" + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + #"$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + "$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + printf '\nHOWK00\n\n' + + # FIXME WINVER and WIN32_IE higher than at rc.exe + #"$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 -DWINVER=x5 -D_WIN32_IE=x5 -MD -c -Zp8 -Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Z7 -Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + # FIXME -Gz (x86 only) + # FIXME -Gm + "$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0500 -D_WIN32_IE=0x0500 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox -Fo"$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + printf '\nHOWK11\n\n' + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + # FIXME -noentry will probably disable main(); we need main() though + # -section:init,d might have deleted it :( + #"$p\\link.exe" -nologo -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:0x04,0x01 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + # FIXME -merge:.rdata=.data + "$p\\link.exe" "-machine:$machine" -nologo -SECTION:INIT,d -noentry -OPT:REF -OPT:ICF -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-def:${kbdname}.def" "-out:$outdir\\${kbdname}.dll" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" + + printf '\nHOWK22\n\n' + + if [ -n "$(ls -1 "$TEMP_WIN\\my_layout."* 2>/dev/null)" ]; then + rm "$TEMP_WIN\\my_layout."* + fi +done + +# vim: set wrap: diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (11).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (11).sh new file mode 100644 index 0000000..cff44bf --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (11).sh @@ -0,0 +1,249 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=IA64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + printf '\nINFO Compiling %s...\n' "$outdir" + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + #"$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + "$msklc\\bin\\i386\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than at rc.exe + #"$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 -DWINVER=x5 -D_WIN32_IE=x5 -MD -c -Zp8 -Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Z7 -Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + # FIXME -Gz (x86 only) + # FIXME -Gm + "$p\\cl.exe" "-I$msklc\\inc" -nologo -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0500 -D_WIN32_IE=0x0500 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox -Fo"$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + # FIXME -noentry will probably disable main(); we need main() though + # -section:init,d might have deleted it :( + #"$p\\link.exe" -nologo -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:0x04,0x01 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + # FIXME -merge:.rdata=.data + # FIXME -SECTION:INIT,d + # LINK : warning LNK4039: section 'INIT' specified with /SECTION option does not exist + "$p\\link.exe" "-LIBPATH:$msklc\\lib\\$libdir" "-MACHINE:$machine" -nologo -noentry -OPT:REF -OPT:ICF -dll "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-DEF:${kbdname}.def" "-OUT:$outdir\\${kbdname}.dll" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" + + if [ -n "$(ls -1 "$TEMP_WIN\\my_layout."* 2>/dev/null)" ]; then + rm "$TEMP_WIN\\my_layout."* + fi +done + +# vim: set wrap: diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (12).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (12).sh new file mode 100644 index 0000000..84a4efe --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (12).sh @@ -0,0 +1,255 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 +readonly TMPDIR_WIN="$(cmd.exe /c "echo %TEMP%")" + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken automatically into account as it should + readonly t="$(mktemp -p "$TMPDIR_WIN" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR_WIN" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | + sed -r 's|^[^=]+=[^0-9]*([0-9]+).*|\1|')))" -ne 0 \ + -o "$c" -le 0 ]; then + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + +# FIXME +# INFO Waiting 10s... Keine Instanzen verf▒gbar. +# 9s... Keine Instanzen verf▒gbar. +# 8s... Keine Instanzen verf▒gbar. + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME avoid collision with the default MSKLC compile directory +readonly dockbd="$USERPROFILE\\documents\\$kbdname" +if [ -e "$dockbd" ]; then + mv "$dockbd" "${dockbd}-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry (for VBS)? +# FIXME open it with a different DLL directory than \Userprofile\Documents +"$msklc/MSKLC.exe" "$layoutpath\\${kbdname}.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN_PREFIX="$(cmd.exe /c "echo %TEMP%")\\my_layout" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # FIXME + # 32bit on 64bit systems +# if [ "$idx" -eq 0 ]; then +# idx=$((idx +1)) +# defwow64=-DBUILD_WOW6432 +# outdir=wow64 +# else + outdir=i386 +# fi + ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=amd64 + fi + #outdir=amd64 + ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=IA64 + subsys_native_ver=5.02 + outdir=ia64 + ;; + esac + + printf '\nINFO Compiling DLL for %s...\n' "$outdir" + + # make traps local + ( + trap "rm -f '${TEMP_WIN_PREFIX}.res' '${TEMP_WIN_PREFIX}.obj'" \ + INT HUP TERM EXIT RETURN + + "$msklc\\bin\\i386\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "${TEMP_WIN_PREFIX}.res" "${kbdname}.rc" + + # FIXME -Gz (x86 only) + "$p\\cl.exe" -nologo -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox "-I$msklc\\inc" -Fo"${TEMP_WIN_PREFIX}.obj" "${kbdname}.c" + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + "$p\\link.exe" "-LIBPATH:$msklc\\lib\\$libdir" "-MACHINE:$machine" -nologo -noentry -OPT:REF -OPT:ICF -dll "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-DEF:${kbdname}.def" "-OUT:$outdir\\${kbdname}.dll" "${TEMP_WIN_PREFIX}.res" "${TEMP_WIN_PREFIX}.obj" + ) +done + +# vim: set wrap: diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (2).cmd b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (2).cmd new file mode 100644 index 0000000..8e9bab9 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (2).cmd @@ -0,0 +1,258 @@ +@rem http://steve-jansen.github.io/guides/windows-batch-scripting/index.html + +@rem disable the default echoing of every executed command +@echo off + +rem adds setlocal, chdir, ... (nonexistent before cca Win2000) +setlocal enableextensions +rem make all variables local solely to this batch +setlocal +rem treat string !abc! as a variable and expand it each time it's +rem accessed (unlike %abc% which gets expanded only once while parsing +rem a block in parenthesis) +setlocal enabledelayedexpansion + +rem FIXME c:\users\jpa\desktop\win\gerdltgt\make_pkg.cmd + +rem https://stackoverflow.com/a/26079981 +rem prevent interpretation for the first time +goto :endtrim +rem :trim ... +:trim + setlocal + if "%~1"=="" set emsg=%%1 != "" + if not "%emsg%"=="" ( + echo ERR failed assert in %0 %emsg% >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set x=%* + for /f "tokens=1*" %%a in ("!x!") do endlocal & set %~1=%%b + exit /b +:endtrim + +rem double quotes are not allowed in paths => we can safely remove them +set ccline=%CMDCMDLINE:"=% +set cspec=%COMSPEC:"=% +call :trim ccline %ccline% + +set msklc=C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4 + +rem argument 0 (full path with file name of this script) +set layoutpath=%~dp0 +rem remove trailing backslash (otherwise the "basename" trick doesn't work) +set layoutpath=%layoutpath:~0,-1% +rem basename +for %%_ in ("%layoutpath%") do set kbdname=%%~n_ + +if not exist "%msklc%" ( + echo ERR Dir "%msklc%" not found. Is MSKLC installed? >&2 + rem wait for user input + rem (can't use %CMDCMDLINE%, because it doesn't work when double clicked) + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + rem /b exits the batch, not the cmd.exe process + exit /b 1 +) + +for %%f in ( + "%layoutpath%\%kbdname%.c" + "%layoutpath%\%kbdname%.def" + "%layoutpath%\%kbdname%.h" + "%layoutpath%\%kbdname%.klc" + "%layoutpath%\%kbdname%.rc") do ( + if not exist %%f ( + echo ERR %%f >&2 + echo ERR ^^^^^^File not found (the file name without >&2 + echo ERR extension must be the same as its parent directory^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 + ) +) + +rem switch all processing of octets to UTF-8 (useful e.g. for "for /f ...") +rem note: wrongly looking characters on stdout are just a font issue +rem note: switching to non-ANSI codepage draws find, more, ... unusable +rem chcp 65001 + +set productname= +for /f "usebackq tokens=1,2*" %%a in ("%layoutpath%\%kbdname%.klc") do ( + if "%%a"=="KBD" ( + if "%%b"=="%kbdname%" ( + set productname=%%~c + goto :endfor00 + ) + ) +) +:endfor00 +if "%productname%"=="" ( + echo ERR Could not parse keyboard description from "%kbdname%.klc" >&2 + echo ERR Try converting it to ANSI 850 or UTF-16 or UTF-8 ( >&2 + echo ERR disregarding whether with BOM or not^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 +) + +rem is_installed +goto :endis_installed +:is_installed + setlocal + if "%~1"=="" set emsg=%%1 != "" + if "%~2"=="" set emsg=%%2 != "" + if "%~3"=="" set emsg=%%3 != "" + if not "%~4"=="" set emsg=number_of_arguments = 3 + if not "%emsg%"=="" ( + echo ERR failed assert in %0 (%emsg%^) >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set found=0 + set guid32= + + rem list all installed apps: wmic product get name + for /f "tokens=1" %%a in ( + 'wmic product where name^="%~3" get IdentifyingNumber 2^> NUL') do ( + if "!found!" equ "1" ( + set guid32=%%a + goto :endfor01 + ) + if "%%a"=="IdentifyingNumber" ( + rem at least one such app is installed + set found=1 + ) + ) + :endfor01 + + rem can't use %errorlevel% because it gets inconveniently overwritten + endlocal & set "%~1=%found%" & set "%~2=%guid32%" + exit /b +:endis_installed + +echo INFO Checking if installed: "%productname%" + +call :is_installed found guid32 "%productname%" +echo FIXME DEBUGguid32=%guid32% +if /i "%found%" neq "0" ( + rem the kbd uninstaller sometimes leaves shareddlls entries in registry + rem the kbd uninstaller leaves some dll files even if SharedDlls is 0 + +rem CreateObject^( "Shell.Application" ^).ShellExecute ^ +rem "wmic", "product where IdentifyingNumber=""%guid32%"" call uninstall", "", "runas", 1 :^ + echo on error resume next :^ +CreateObject^( "Wscript.Shell" ^).Run ^ + "wmic product where IdentifyingNumber=""%guid32%"" call uninstall", 1, true :^ +const hklm = ^&H80000002 :^ +set reg = GetObject^( ^ + "winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv" ^) :^ +set fs = createobject^( "Scripting.FileSystemObject" ^) :^ +for each s in array^( ^ + "C:\Windows\System32\%kbdname%.dll", ^ + "C:\Windows\SysWOW64\%kbdname%.dll" ^) :^ + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s :^ + fs.DeleteFile s, true :^ +next :^ +fs.DeleteFile "%temp%\marker.txt", true > "%temp%\elevated.vbs" + + rem FIXME how will this work if the current account will not + rem have admin rights? will there be any issues with password? + rem https://stackoverflow.com/a/23825726 + echo on error resume next :^ +set fs = createObject^( "Scripting.FileSystemObject" ^) :^ +fs.createTextFile^( "%temp%\marker.txt" ^) :^ +createObject^( "Shell.Application" ^).ShellExecute ^ + "cscript", "%temp%\elevated.vbs", "", "runas", 1 :^ +x = 600 :^ +do while fs.fileExists^( "%temp%\marker.txt" ^) :^ + if x ^< 0 then : exit do : end if :^ + wscript.sleep 100 :^ + x = x -1 :^ +loop > "%temp%\elevate.vbs" + + echo INFO Uninstalling "%productname%" + + "%temp%\elevate.vbs" + rem del /f /q "%temp%\elevate.vbs" > NUL + rem del /f /q "%temp%\elevated.vbs" > NUL + + rem we can't read stdout nor any return values from elevated processes through pipe + rem (we could read a file, but checking again is the safest possible method) + call :is_installed found _ "%productname%" + if /i "%found%" neq "0" ( + echo ERR Can't uninstall the kbd layout. >&2 + echo ERR Please do it manually and re-run this script. >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) +) +:endif00 + +if exist "%userprofile%\documents\%kbdname%" ( + rem removes all files recursively (does leave all directories in place) + del /f /s /q "%userprofile%\documents\%kbdname%" > NUL + rem removes all empty directories recursively + rmdir /s /q "%userprofile%\documents\%kbdname%" > NUL +) + +echo INFO >&2 +echo INFO Instructions for the "Keyboard Layout Creator": >&2 +echo INFO 1. click "Project" in menu -^> "Build DLL and Setup Package" >&2 +echo INFO 2. click "No" to disable viewing of "KeyboardVerify.log" >&2 +echo INFO 3. click "No" to disable opening of the Installer package directory >&2 +echo INFO 4. close the window of the "Keyboard Layout Creator" >&2 +echo INFO >&2 + +rem MSKLC will correctly generate all the install and setup files +rem "pipe to more" trick to wait for closing +"%msklc%\MSKLC.exe" "%layoutpath%\%kbdname%.klc" | more + +if exist "%userprofile%\Documents\KeyboardVerify.log" ( + del /f /q "%userprofile%\Documents\KeyboardVerify.log" > NUL +) +rem FIXME +pause +exit /b 1 + +rem recompile just the DLLs (the rest is prepared from MSKLC) +rem x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +for %%p in ( + "%msklc%\bin\i386" + "%msklc%\bin\i386" + "%msklc%\bin\i386\amd64" + "%msklc%\bin\i386\ia64") do ( + if %%p=="%msklc%\bin\i368" ( + echo howk11 + rem the second iteration is the same compiler, but a wow64 binary + if "!outdir!"=="i386" ( + set defwow64=-DBUILD_WOW6432 + set outdir=wow64 + ) else ( + set outdir=i386 + ) + ) + if %%p=="%msklc%\bin\i368\amd64" ( + echo howk 1100 + set outdir=amd64 + ) + if %%p=="%msklc%\bin\i368\ia64" set outdir=ia64 + + echo INFO Compiling layout "!outdir!\%kbdname%.dll" >&2 + + echo howk22 + + rem FIXME call this once for all architectures? + rem %%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "%%p\rc.exe" -r "-i%msklc%\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 "%layoutpath%\%kbdname%.rc" + + rem %%p\cl.exe -nologo -I%msklc%\inc -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 %defwow64% /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs %TEMP%/my_layout.obj "%layoutpath%\%kbdname%.c" + + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text +) + +echo INFO Success! Find the kbd layout in: >&2 +echo INFO %userprofile%\Documents\%kbdname% >&2 +rem FIXME the condition is wrong - bad variables? +if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + +rem vim: set wrap: diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (2).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (2).sh new file mode 100644 index 0000000..f9a3200 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (2).sh @@ -0,0 +1,184 @@ +#!/bin/sh + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver without the last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + readonly f="$TMP/elevate.vbs" + readonly f2="$TMP/wmic.cmd" + readonly f2_win='%TMP%\wmic.cmd' + # VBS needs double quotes quoted by putting them twice + readonly f2_vbs='%TMP%\wmic.cmd' + readonly f2log="${f2}.log" + readonly f2log_win="${f2_win}.log" + #readonly p="$(printf %s "$productname_quoted" | sed -r 's|"|""|g')" + + #printf '%s\n%s\n%s\n%s\n%s\n' "$f" "$f2" "$f2log" "$productname_quoted" "$p" + + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2_vbs"'","","","runas",1' > "$f" + printf %s "wmic product where name=$productname_quoted call uninstall > $f2log_win" > "$f2" + + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME cscript wscript + #wscript "$f" + #rm -f "$f" "$f2" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$f2log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$f2log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + + # FIXME wmic does not remove it + for f in "C:/Windows/System32/$kbdname" "C:/Windows/SysWOW64/$kbdname"; do + # FIXME + #[ -e "$f" ] && rm -f "$f" + [ -e "$f" ] && printf 'DEBUG rm -f %s\n' "$f" || true + done + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + # FIXME change "-l 409" to the language in klc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 409"$(grep -E '^LOCALEID' "$layoutpath/${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" /fo "${TEMP}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP/my_layout."* +} diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (3).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (3).sh new file mode 100644 index 0000000..15aafa8 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (3).sh @@ -0,0 +1,198 @@ +#!/bin/sh + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver without the last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || return 1 + readonly t="$(mktemp run_elevated.XXXXXX "$TMP/elevate.vbs")" + #trap 'rm -f "$t"' int term hup +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + readonly f="$TMP/elevate.vbs" + readonly f2="$TMP/wmic.cmd" + readonly f2_win='%TMP%\wmic.cmd' + # VBS needs double quotes quoted by putting them twice + readonly f2_vbs='%TMP%\wmic.cmd' + readonly f2log="${f2}.log" + readonly f2log_win="${f2_win}.log" + #readonly p="$(printf %s "$productname_quoted" | sed -r 's|"|""|g')" + + #printf '%s\n%s\n%s\n%s\n%s\n' "$f" "$f2" "$f2log" "$productname_quoted" "$p" + + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2_vbs"'","","","runas",1' > "$f" + printf %s "wmic product where name=$productname_quoted call uninstall > $f2log_win" > "$f2" + + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME cscript wscript + #cscript "$f" + #rm -f "$f" "$f2" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$f2log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$f2log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + + # FIXME wmic does not remove it + # FIXME needs elevation + for f in "C:/Windows/System32/$kbdname" "C:/Windows/SysWOW64/$kbdname"; do + # FIXME + #[ -e "$f" ] && rm "$f" + [ -e "$f" ] && printf 'DEBUG rm -f %s\n' "$f" || true + done + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP/my_layout."* +} diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (4).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (4).sh new file mode 100644 index 0000000..c9f3ef9 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (4).sh @@ -0,0 +1,208 @@ +#!/bin/sh + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver without the last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + readonly t="$(mktemp run_elevated.XXXXXXXXXXXXXXXX).vbs" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + cscript "$t" +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps only sometimes accept forward slashes + readonly a="$(printf %s "$TMP/app.cmd" | sed -r 's|/|\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + # FIXME + printf '%s\n' "DEBUG run_elevated $a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME wmic does not remove it +cat > "$a" </dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP/my_layout."* +} diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (5).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (5).sh new file mode 100644 index 0000000..cf98187 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (5).sh @@ -0,0 +1,222 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + readonly t="$(mktemp run_elevated.XXXXXXXXXXXXXXXX).vbs" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + cscript "$t" +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\|g').cmd" + readonly a_log="${a}.log" + + # make traps local + ( + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + # FIXME + printf '%s\n' "DEBUG run_elevated $a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +# sntnh +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" +readonly TEMP_WIN="$(printf %s "$TEMP" | sed -r 's|/|\|g')" +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP_WIN}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP_WIN}\\my_layout.res" "${TEMP_WIN}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP_WIN/my_layout."* +} diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (6).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (6).sh new file mode 100644 index 0000000..cf98187 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (6).sh @@ -0,0 +1,222 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath/${kbdname}.c" \ + "$layoutpath/${kbdname}.def" \ + "$layoutpath/${kbdname}.h" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' "$layoutpath/${kbdname}.klc" | grep -E '^[[:blank:]]*LOCALEID' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + readonly t="$(mktemp run_elevated.XXXXXXXXXXXXXXXX).vbs" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + cscript "$t" +) + +# list all installed apps: wmic product get name +if [ -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\|g').cmd" + readonly a_log="${a}.log" + + # make traps local + ( + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + # FIXME + printf '%s\n' "DEBUG run_elevated $a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? does it collide with some default MSKLC-stuff? +# sntnh +if [ -e "${USERPROFILE}/documents/$kbdname" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$userprofile/Documents/KeyboardVerify.log" ]; then + # FIXME + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ +fi + +cd "$layoutpath" +readonly TEMP_WIN="$(printf %s "$TEMP" | sed -r 's|/|\|g')" +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc/bin/i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i386/amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc/bin/i386/ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP_WIN}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP_WIN}\\my_layout.res" "${TEMP_WIN}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP_WIN/my_layout."* +} diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (7).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (7).sh new file mode 100644 index 0000000..51cba02 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (7).sh @@ -0,0 +1,225 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(tr '[:upper:]' '[:lower:]' < "$layoutpath\\${kbdname}.klc" | grep -E '^[[:blank:]]*localeid' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*(.+)|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +readonly TEMP_WIN="$(printf %s "$TEMP" | sed -r 's|/|\\|g')" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + +#FIXME +#Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0 +#Copyright (C) Microsoft Corporation. All rights reserved. +#fatal error RC1107: invalid usage; use RC /? for Help + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -i "${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + + # FIXME WINVER and WIN32_IE higher than for rc.exe + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP_WIN}\\my_layout.obj" "${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:${msklc}\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "${TEMP_WIN}\\my_layout.res" "${TEMP_WIN}\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + rm "$TEMP_WIN/my_layout."* +done diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (8).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (8).sh new file mode 100644 index 0000000..efa2a7f --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (8).sh @@ -0,0 +1,236 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + # FIXME $outdir not used + # FIXME arguments with slash rewrite to minus + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + "$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + printf '\nHOWK00\n\n' + + # FIXME WINVER and WIN32_IE higher than at rc.exe + "$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + printf '\nHOWK11\n\n' + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + "$p\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + + printf '\nHOWK22\n\n' + + rm "$TEMP_WIN\\my_layout."* +done diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (9).sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (9).sh new file mode 100644 index 0000000..a45afd3 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie (9).sh @@ -0,0 +1,252 @@ +#!/bin/sh + +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken into account + readonly t="$(mktemp -p "$TMPDIR" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX)" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + #cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a' '$a_log'" INT HUP TERM EXIT RETURN + printf %s "wmic product where name=$productname_quoted call uninstall > $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ]; then + rm -f "$a_log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # FIXME wmic does not remove it + cat > "$a" <&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME why moving this? does it collide with some default MSKLC-stuff? +# (maybe it's created by MSKLC when building DLLs and shouldn't stay from last time there) +if [ -e "$USERPROFILE\\documents\\$kbdname" ]; then + mv "$USERPROFILE\\documents\\$kbdname" "$USERPROFILE\\documents\\$kbdname-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry? +#"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN="$(cmd.exe /c "echo %TEMP%")" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + outdir=amd64 ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=X64 + subsys_native_ver=5.02 + outdir=ia64 ;; + esac + + printf 'INFO Compiling %s...\n' "$outdir" + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + #"${p}\\rc.exe" -i "${msklc}\\inc\\" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" /fo "${TEMP_WIN}\\my_layout.res" "${kbdname}.rc" + #"$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 -DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + "$p\\rc.exe" -i "$msklc\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -fo "$TEMP_WIN\\my_layout.res" "${kbdname}.rc" + + printf '\nHOWK00\n\n' + + # FIXME WINVER and WIN32_IE higher than at rc.exe + #"$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 -DWINVER=x5 -D_WIN32_IE=x5 -MD -c -Zp8 -Gy -W3 -WX -Gz -Gm- -EHs-c- -GR- -GF -Z7 -Oxs "$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + # FIXME -Gz (x86 only) + # FIXME -Gm + "$p\\cl.exe" -nologo "-I$msklc\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=0x0500 $defwow64 -DWINVER=0x0500 -D_WIN32_IE=0x0500 -MD -c -Zp8 -Gy -W3 -WX -EHs-c- -GR- -GF -Z7 -Ox -Fo"$TEMP_WIN\\my_layout.obj" "${kbdname}.c" + + printf '\nHOWK11\n\n' + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + # FIXME add -IGNORE:439,478 + # FIXME what is -osversion:4. + # FIXME -noentry will probably disable main(); we need main() though + # -section:init,d might have deleted it :( + #"$p\\link.exe" -nologo -SECTION:INIT,d -OPT:REF -OPT:ICF -noentry -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:0x04,0x01 /opt:nowin98 "-version:$my_ver" /release "-def:${kbdname}.def" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" -merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text + # FIXME -SECTION:INIT,d -noentry + # FIXME -merge:.rdata=.data + "$p\\link.exe" "-machine:$machine" -nologo -OPT:REF -OPT:ICF -dll "-libpath:$msklc\\lib\\$libdir" "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-def:${kbdname}.def" "-out:$outdir\\${kbdname}.dll" "$TEMP_WIN\\my_layout.res" "$TEMP_WIN\\my_layout.obj" + + printf '\nHOWK22\n\n' + + [ -n "$(ls -1 "$TEMP_WIN\\my_layout."*)" ] && rm "$TEMP_WIN\\my_layout."* +done + +# vim: set wrap: diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie.sh b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie.sh new file mode 100644 index 0000000..2b8ba5c --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg - Kopie.sh @@ -0,0 +1,157 @@ +#!/bin/sh + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(dirname "$0")" +readonly kbdname="$(basename "$(dirname "$0")")" + +[ -x "$msklc" ] || { + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +} +for f in \ + "$layoutpath/${kbdname}.C" \ + "$layoutpath/${kbdname}.DEF" \ + "$layoutpath/${kbdname}.H" \ + "$layoutpath/${kbdname}.klc" \ + "$layoutpath/${kbdname}.RC"; do + [ -r "$f" ] || { + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + } +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath/${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +[ -z "$productname_quoted" ] && { + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +} + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# list all installed apps: wmic product get name +[ -n "$(wmic product where name="$productname_quoted")" ] && { + readonly f="$TMP/elevate.vbs" + readonly f2="$TMP/wmic.cmd" + readonly f2_win='%TMP%\wmic.cmd' + # VBS needs double quotes quoted by putting them twice + readonly f2_vbs='%TMP%\wmic.cmd' + readonly f2log="${f2}.log" + readonly f2log_win="${f2_win}.log" + #readonly p="$(printf %s "$productname_quoted" | sed -r 's|"|""|g')" + + #printf '%s\n%s\n%s\n%s\n%s\n' "$f" "$f2" "$f2log" "$productname_quoted" "$p" + + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2_vbs"'","","","runas",1' > "$f" + printf %s "wmic product where name=$productname_quoted call uninstall > $f2log_win" > "$f2" + + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME cscript wscript + #wscript "$f" + #rm -f "$f" "$f2" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%d... ' "$c"; do + [ "$(($(grep -E ReturnValue "$f2log" 2>/dev/null | sed -r 's|^[^=]+=||')))" -ne 0 \ + -o "$c" -le 0 ] && { + rm -f "$f2log" + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + } + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break + c=$((c-1)) + done + echo + + # FIXME wmic does not remove it + for f in "C:/Windows/System32/$kbdname" "C:/Windows/SysWOW64/$kbdname"; do + # FIXME + #[ -e "$f" ] && rm -f "$f" + [ -e "$f" ] && printf 'DEBUG rm -f %s\n' "$f" + done + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +} + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +printf '%s\n' "WARN Please do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. click "Project" in menu -> "Build DLL and Setup Package" +INFO 2. click "No" to disable viewing of "KeyboardVerify.log" +INFO 3. click "No" to disable opening of the Installer package directory +INFO 4. close the window of the "Keyboard Layout Creator" +END + +# FIXME why removing this? +[ -e "${USERPROFILE}/documents/$kbdname" ] && \ + printf 'DEBUG would remove %s\n' "${USERPROFILE}/documents/$kbdname" >&2 + #rm -r "${USERPROFILE}\\documents\\$kbdname" + +exit 1 + +"$msklc/MSKLC.exe" "%layoutpath%\%kbdname%.klc" + +[ -e "$userprofile/Documents/KeyboardVerify.log" ] && \ + printf 'DEBUG would remove %s\n' "$userprofile/Documents/KeyboardVerify.log" >&2 + #rm "$userprofile/Documents/KeyboardVerify.log" ] && \ + +# x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +idx=0 +for p in \ + "$msklc/bin/i386" \ + "$msklc/bin/i386" \ + "$msklc/bin/i386/amd64" \ + "$msklc/bin/i386/ia64"; do { + case "$p" in + "$msklc/bin/i368") + # 32bit for 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + outdir=i386 + fi ;; + "$msklc/bin/i368/amd64") outdir=amd64 ;; + "$msklc/bin/i368/ia64") outdir=ia64 ;; + esac + + # FIXME $outdir not used + + #%%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "${p}\\rc.exe" -r "-i${msklc}\\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 "${layoutpath}\\${kbdname}.rc" + + "${p}\\cl.exe" -nologo "-I${msklc}\\inc" -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 $defwow64 /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs "${TEMP}\\my_layout.obj" "${layoutpath}\\${kbdname}.c" + + #%%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + "${p}\\link.exe" -nologo abc00 abc11 -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release "-def:${kbdname}.def" "${TEMP}\\my_layout.res" "${TEMP}\\my_layout.obj-merge:.edata=.data" -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text +} diff --git a/platform/win/source-20180817-gerdLTGT/make_pkg.cmd b/platform/win/source-20180817-gerdLTGT/make_pkg.cmd new file mode 100644 index 0000000..8e9bab9 --- /dev/null +++ b/platform/win/source-20180817-gerdLTGT/make_pkg.cmd @@ -0,0 +1,258 @@ +@rem http://steve-jansen.github.io/guides/windows-batch-scripting/index.html + +@rem disable the default echoing of every executed command +@echo off + +rem adds setlocal, chdir, ... (nonexistent before cca Win2000) +setlocal enableextensions +rem make all variables local solely to this batch +setlocal +rem treat string !abc! as a variable and expand it each time it's +rem accessed (unlike %abc% which gets expanded only once while parsing +rem a block in parenthesis) +setlocal enabledelayedexpansion + +rem FIXME c:\users\jpa\desktop\win\gerdltgt\make_pkg.cmd + +rem https://stackoverflow.com/a/26079981 +rem prevent interpretation for the first time +goto :endtrim +rem :trim ... +:trim + setlocal + if "%~1"=="" set emsg=%%1 != "" + if not "%emsg%"=="" ( + echo ERR failed assert in %0 %emsg% >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set x=%* + for /f "tokens=1*" %%a in ("!x!") do endlocal & set %~1=%%b + exit /b +:endtrim + +rem double quotes are not allowed in paths => we can safely remove them +set ccline=%CMDCMDLINE:"=% +set cspec=%COMSPEC:"=% +call :trim ccline %ccline% + +set msklc=C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4 + +rem argument 0 (full path with file name of this script) +set layoutpath=%~dp0 +rem remove trailing backslash (otherwise the "basename" trick doesn't work) +set layoutpath=%layoutpath:~0,-1% +rem basename +for %%_ in ("%layoutpath%") do set kbdname=%%~n_ + +if not exist "%msklc%" ( + echo ERR Dir "%msklc%" not found. Is MSKLC installed? >&2 + rem wait for user input + rem (can't use %CMDCMDLINE%, because it doesn't work when double clicked) + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + rem /b exits the batch, not the cmd.exe process + exit /b 1 +) + +for %%f in ( + "%layoutpath%\%kbdname%.c" + "%layoutpath%\%kbdname%.def" + "%layoutpath%\%kbdname%.h" + "%layoutpath%\%kbdname%.klc" + "%layoutpath%\%kbdname%.rc") do ( + if not exist %%f ( + echo ERR %%f >&2 + echo ERR ^^^^^^File not found (the file name without >&2 + echo ERR extension must be the same as its parent directory^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 + ) +) + +rem switch all processing of octets to UTF-8 (useful e.g. for "for /f ...") +rem note: wrongly looking characters on stdout are just a font issue +rem note: switching to non-ANSI codepage draws find, more, ... unusable +rem chcp 65001 + +set productname= +for /f "usebackq tokens=1,2*" %%a in ("%layoutpath%\%kbdname%.klc") do ( + if "%%a"=="KBD" ( + if "%%b"=="%kbdname%" ( + set productname=%%~c + goto :endfor00 + ) + ) +) +:endfor00 +if "%productname%"=="" ( + echo ERR Could not parse keyboard description from "%kbdname%.klc" >&2 + echo ERR Try converting it to ANSI 850 or UTF-16 or UTF-8 ( >&2 + echo ERR disregarding whether with BOM or not^). >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit /b 1 +) + +rem is_installed +goto :endis_installed +:is_installed + setlocal + if "%~1"=="" set emsg=%%1 != "" + if "%~2"=="" set emsg=%%2 != "" + if "%~3"=="" set emsg=%%3 != "" + if not "%~4"=="" set emsg=number_of_arguments = 3 + if not "%emsg%"=="" ( + echo ERR failed assert in %0 (%emsg%^) >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) + + set found=0 + set guid32= + + rem list all installed apps: wmic product get name + for /f "tokens=1" %%a in ( + 'wmic product where name^="%~3" get IdentifyingNumber 2^> NUL') do ( + if "!found!" equ "1" ( + set guid32=%%a + goto :endfor01 + ) + if "%%a"=="IdentifyingNumber" ( + rem at least one such app is installed + set found=1 + ) + ) + :endfor01 + + rem can't use %errorlevel% because it gets inconveniently overwritten + endlocal & set "%~1=%found%" & set "%~2=%guid32%" + exit /b +:endis_installed + +echo INFO Checking if installed: "%productname%" + +call :is_installed found guid32 "%productname%" +echo FIXME DEBUGguid32=%guid32% +if /i "%found%" neq "0" ( + rem the kbd uninstaller sometimes leaves shareddlls entries in registry + rem the kbd uninstaller leaves some dll files even if SharedDlls is 0 + +rem CreateObject^( "Shell.Application" ^).ShellExecute ^ +rem "wmic", "product where IdentifyingNumber=""%guid32%"" call uninstall", "", "runas", 1 :^ + echo on error resume next :^ +CreateObject^( "Wscript.Shell" ^).Run ^ + "wmic product where IdentifyingNumber=""%guid32%"" call uninstall", 1, true :^ +const hklm = ^&H80000002 :^ +set reg = GetObject^( ^ + "winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv" ^) :^ +set fs = createobject^( "Scripting.FileSystemObject" ^) :^ +for each s in array^( ^ + "C:\Windows\System32\%kbdname%.dll", ^ + "C:\Windows\SysWOW64\%kbdname%.dll" ^) :^ + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s :^ + fs.DeleteFile s, true :^ +next :^ +fs.DeleteFile "%temp%\marker.txt", true > "%temp%\elevated.vbs" + + rem FIXME how will this work if the current account will not + rem have admin rights? will there be any issues with password? + rem https://stackoverflow.com/a/23825726 + echo on error resume next :^ +set fs = createObject^( "Scripting.FileSystemObject" ^) :^ +fs.createTextFile^( "%temp%\marker.txt" ^) :^ +createObject^( "Shell.Application" ^).ShellExecute ^ + "cscript", "%temp%\elevated.vbs", "", "runas", 1 :^ +x = 600 :^ +do while fs.fileExists^( "%temp%\marker.txt" ^) :^ + if x ^< 0 then : exit do : end if :^ + wscript.sleep 100 :^ + x = x -1 :^ +loop > "%temp%\elevate.vbs" + + echo INFO Uninstalling "%productname%" + + "%temp%\elevate.vbs" + rem del /f /q "%temp%\elevate.vbs" > NUL + rem del /f /q "%temp%\elevated.vbs" > NUL + + rem we can't read stdout nor any return values from elevated processes through pipe + rem (we could read a file, but checking again is the safest possible method) + call :is_installed found _ "%productname%" + if /i "%found%" neq "0" ( + echo ERR Can't uninstall the kbd layout. >&2 + echo ERR Please do it manually and re-run this script. >&2 + if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + exit 1 + ) +) +:endif00 + +if exist "%userprofile%\documents\%kbdname%" ( + rem removes all files recursively (does leave all directories in place) + del /f /s /q "%userprofile%\documents\%kbdname%" > NUL + rem removes all empty directories recursively + rmdir /s /q "%userprofile%\documents\%kbdname%" > NUL +) + +echo INFO >&2 +echo INFO Instructions for the "Keyboard Layout Creator": >&2 +echo INFO 1. click "Project" in menu -^> "Build DLL and Setup Package" >&2 +echo INFO 2. click "No" to disable viewing of "KeyboardVerify.log" >&2 +echo INFO 3. click "No" to disable opening of the Installer package directory >&2 +echo INFO 4. close the window of the "Keyboard Layout Creator" >&2 +echo INFO >&2 + +rem MSKLC will correctly generate all the install and setup files +rem "pipe to more" trick to wait for closing +"%msklc%\MSKLC.exe" "%layoutpath%\%kbdname%.klc" | more + +if exist "%userprofile%\Documents\KeyboardVerify.log" ( + del /f /q "%userprofile%\Documents\KeyboardVerify.log" > NUL +) +rem FIXME +pause +exit /b 1 + +rem recompile just the DLLs (the rest is prepared from MSKLC) +rem x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) +for %%p in ( + "%msklc%\bin\i386" + "%msklc%\bin\i386" + "%msklc%\bin\i386\amd64" + "%msklc%\bin\i386\ia64") do ( + if %%p=="%msklc%\bin\i368" ( + echo howk11 + rem the second iteration is the same compiler, but a wow64 binary + if "!outdir!"=="i386" ( + set defwow64=-DBUILD_WOW6432 + set outdir=wow64 + ) else ( + set outdir=i386 + ) + ) + if %%p=="%msklc%\bin\i368\amd64" ( + echo howk 1100 + set outdir=amd64 + ) + if %%p=="%msklc%\bin\i368\ia64" set outdir=ia64 + + echo INFO Compiling layout "!outdir!\%kbdname%.dll" >&2 + + echo howk22 + + rem FIXME call this once for all architectures? + rem %%p\rc.exe -r -i%msklc%\inc -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 -Fo%TEMP%/my_layout.res %layoutpath%\%kbdname%.rc + "%%p\rc.exe" -r "-i%msklc%\inc" -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST= -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=x5 /DWINVER=x4 -D_WIN32_IE=x4 -DWIN32_LEAN_AND_MEAN=1 -DDEVL=1 -DFPO=1 -DNDEBUG -l 49 "%layoutpath%\%kbdname%.rc" + + rem %%p\cl.exe -nologo -I%msklc%\inc -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DWIN32_LEAN_AND_MEAN -DRoster -DSTD_CALL -D_WIN32_WINNT=x5 %defwow64% /DWINVER=x5 -D_WIN32_IE=x5 /MD /c /Zp8 /Gy /W3 /WX /Gz /Gm- /EHs-c- /GR- /GF -Z7 /Oxs %TEMP%/my_layout.obj "%layoutpath%\%kbdname%.c" + + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text -out %kbdname%_arch00.dll + rem %%p\link.exe -nologo %s %s -SECTION:INIT,d -OPT:REF -OPT:ICF -IGNORE:439,478 -noentry -dll -libpath:%s -subsystem:native,5. -merge:.rdata=.text -PDBPATH:NONE -STACK:x4,x1 /opt:nowin98 -osversion:4. -version:4. /release -def:%kbdname%.def %TEMP%/my_layout.res %TEMP%/my_layout.obj-merge:.edata=.data -merge:.rdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text +) + +echo INFO Success! Find the kbd layout in: >&2 +echo INFO %userprofile%\Documents\%kbdname% >&2 +rem FIXME the condition is wrong - bad variables? +if not "%ccline%"=="%cspec%" set /p _=(Press ENTER to exit^) + +rem vim: set wrap: diff --git a/platform/win/20220624-gerdLTGT/make_pkg.sh.bak00 b/platform/win/source-20180817-gerdLTGT/make_pkg.sh similarity index 100% rename from platform/win/20220624-gerdLTGT/make_pkg.sh.bak00 rename to platform/win/source-20180817-gerdLTGT/make_pkg.sh diff --git a/platform/win/20220624-gerdLTGT/map_esc_to_caps_lock.reg.bak00 b/platform/win/source-20180817-gerdLTGT/map_esc_to_caps_lock.reg similarity index 100% rename from platform/win/20220624-gerdLTGT/map_esc_to_caps_lock.reg.bak00 rename to platform/win/source-20180817-gerdLTGT/map_esc_to_caps_lock.reg diff --git a/platform/win/source-20180817-gerdLTGT/wow64/gerdLTGT.dll b/platform/win/source-20180817-gerdLTGT/wow64/gerdLTGT.dll new file mode 100644 index 0000000000000000000000000000000000000000..461fd22d092c30dc8bbb9a92267728491336b288 GIT binary patch literal 6656 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 literal 0 HcmV?d00001 diff --git a/platform/win/source-20180817-gerdLTGT/wow64/gerdLTGT.lib b/platform/win/source-20180817-gerdLTGT/wow64/gerdLTGT.lib new file mode 100644 index 0000000000000000000000000000000000000000..dafec1462f87306306832a0432f9764af80d7935 GIT binary patch literal 1766 zcmcIlPfrs;6#wlmqHKsZqDRS+kbsv;mtCZWm?AaWbSb1PCl5pER%ilgv#bZh!7t$V z@aT;T7fxI~K*9$g;cMV~+Zj7(i><*)cILg`yxn=f_h)u$sTS9FU)wL7n+6hB1T}qq}l4@%fImL&!B%KREVUgmAf4h#$D-=BVXMEo8Q zPZ~xxYHWYnncnEAzzPXpl_J*yGHwWGTdB8v^jl z#_uAGPw^xNe;s%wHC{}FG~adO*gEAw>c#b4tzOKuUXD}u*va1Y5~W++NvoH6g>t=o zQ;J-ONdL9 literal 0 HcmV?d00001 diff --git a/platform/win/gerd02/gerd-ltgt.klc b/platform/win/source-20181111-gerd02/gerd-ltgt.klc similarity index 100% rename from platform/win/gerd02/gerd-ltgt.klc rename to platform/win/source-20181111-gerd02/gerd-ltgt.klc diff --git a/platform/win/gerd02/gerdLTGT.C b/platform/win/source-20181111-gerd02/gerdLTGT.C similarity index 100% rename from platform/win/gerd02/gerdLTGT.C rename to platform/win/source-20181111-gerd02/gerdLTGT.C diff --git a/platform/win/gerd05/gerdLTGT.DEF b/platform/win/source-20181111-gerd02/gerdLTGT.DEF similarity index 100% rename from platform/win/gerd05/gerdLTGT.DEF rename to platform/win/source-20181111-gerd02/gerdLTGT.DEF diff --git a/platform/win/gerd05/gerdLTGT.H b/platform/win/source-20181111-gerd02/gerdLTGT.H similarity index 100% rename from platform/win/gerd05/gerdLTGT.H rename to platform/win/source-20181111-gerd02/gerdLTGT.H diff --git a/platform/win/gerd02/gerdLTGT.RC b/platform/win/source-20181111-gerd02/gerdLTGT.RC similarity index 100% rename from platform/win/gerd02/gerdLTGT.RC rename to platform/win/source-20181111-gerd02/gerdLTGT.RC diff --git a/platform/win/gerd03/Dvorak keyboard layout ... makes ctrl-c open downloads window in Firefox.html b/platform/win/source-20181111-gerd03/Dvorak keyboard layout ... makes ctrl-c open downloads window in Firefox.html similarity index 100% rename from platform/win/gerd03/Dvorak keyboard layout ... makes ctrl-c open downloads window in Firefox.html rename to platform/win/source-20181111-gerd03/Dvorak keyboard layout ... makes ctrl-c open downloads window in Firefox.html diff --git a/platform/win/gerd04/gerdLTGT.C b/platform/win/source-20181111-gerd04/gerdLTGT.C similarity index 100% rename from platform/win/gerd04/gerdLTGT.C rename to platform/win/source-20181111-gerd04/gerdLTGT.C diff --git a/platform/win/source-20181111-gerd04/gerdLTGT.DEF b/platform/win/source-20181111-gerd04/gerdLTGT.DEF new file mode 100644 index 0000000..c79f1c5 --- /dev/null +++ b/platform/win/source-20181111-gerd04/gerdLTGT.DEF @@ -0,0 +1,4 @@ +LIBRARY gerdLTGT + + EXPORTS + KbdLayerDescriptor @1 diff --git a/platform/win/source-20181111-gerd04/gerdLTGT.H b/platform/win/source-20181111-gerd04/gerdLTGT.H new file mode 100644 index 0000000..3d4e2b2 --- /dev/null +++ b/platform/win/source-20181111-gerd04/gerdLTGT.H @@ -0,0 +1,103 @@ +/****************************** Module Header ******************************\ +* Module Name: gerdLTGT.H +* +* keyboard layout header +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* Various defines for use by keyboard input code. +* +* History: +* +* created by KBDTOOL v3.40 Mon May 29 08:05:02 2017 +* +\***************************************************************************/ + +/* + * kbd type should be controlled by cl command-line argument + */ +#define KBD_TYPE 4 + +/* +* Include the basis of all keyboard table values +*/ +#include "kbd.h" +/***************************************************************************\ +* The table below defines the virtual keys for various keyboard types where +* the keyboard differ from the US keyboard. +* +* _EQ() : all keyboard types have the same virtual key for this scancode +* _NE() : different virtual keys for this scancode, depending on kbd type +* +* +------+ +----------+----------+----------+----------+----------+----------+ +* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd | +* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 | +\****+-------+_+----------+----------+----------+----------+----------+----------+*/ + +#undef T0C + #define T0C _EQ( OEM_4 ) +#undef T0D + #define T0D _EQ( OEM_6 ) +#undef T10 + #define T10 _EQ( OEM_7 ) +#undef T11 + #define T11 _EQ( OEM_COMMA ) +#undef T12 + #define T12 _EQ( OEM_PERIOD ) +#undef T13 + #define T13 _EQ( 'P' ) +#undef T14 + #define T14 _EQ( 'Y' ) +#undef T15 + #define T15 _EQ( 'F' ) +#undef T16 + #define T16 _EQ( 'G' ) +#undef T17 + #define T17 _EQ( 'C' ) +#undef T18 + #define T18 _EQ( 'R' ) +#undef T19 + #define T19 _EQ( 'L' ) +#undef T1A + #define T1A _EQ( OEM_2 ) +#undef T1B + #define T1B _EQ( OEM_PLUS ) +#undef T1F + #define T1F _EQ( 'O' ) +#undef T20 + #define T20 _EQ( 'E' ) +#undef T21 + #define T21 _EQ( 'U' ) +#undef T22 + #define T22 _EQ( 'I' ) +#undef T23 + #define T23 _EQ( 'D' ) +#undef T24 + #define T24 _EQ( 'H' ) +#undef T25 + #define T25 _EQ( 'T' ) +#undef T26 + #define T26 _EQ( 'N' ) +#undef T27 + #define T27 _EQ( 'S' ) +#undef T28 + #define T28 _EQ( OEM_MINUS ) +#undef T2C + #define T2C _EQ( OEM_1 ) +#undef T2D + #define T2D _EQ( 'Q' ) +#undef T2E + #define T2E _EQ( 'J' ) +#undef T2F + #define T2F _EQ( 'K' ) +#undef T30 + #define T30 _EQ( 'X' ) +#undef T31 + #define T31 _EQ( 'B' ) +#undef T33 + #define T33 _EQ( 'W' ) +#undef T34 + #define T34 _EQ( 'V' ) +#undef T35 + #define T35 _EQ( 'Z' ) + diff --git a/platform/win/gerd05/gerdLTGT.RC-mod00 b/platform/win/source-20181111-gerd04/gerdLTGT.RC-mod00 similarity index 100% rename from platform/win/gerd05/gerdLTGT.RC-mod00 rename to platform/win/source-20181111-gerd04/gerdLTGT.RC-mod00 diff --git a/platform/win/gerd04/gerdLTGT.klc b/platform/win/source-20181111-gerd04/gerdLTGT.klc similarity index 100% rename from platform/win/gerd04/gerdLTGT.klc rename to platform/win/source-20181111-gerd04/gerdLTGT.klc diff --git a/platform/win/gerd04/win_registry_uninstall.vbs b/platform/win/source-20181111-gerd04/win_registry_uninstall.vbs similarity index 100% rename from platform/win/gerd04/win_registry_uninstall.vbs rename to platform/win/source-20181111-gerd04/win_registry_uninstall.vbs diff --git a/platform/win/gerd05/gerdLTGT.C b/platform/win/source-20181111-gerd05/gerdLTGT.C similarity index 100% rename from platform/win/gerd05/gerdLTGT.C rename to platform/win/source-20181111-gerd05/gerdLTGT.C diff --git a/platform/win/source-20181111-gerd05/gerdLTGT.DEF b/platform/win/source-20181111-gerd05/gerdLTGT.DEF new file mode 100644 index 0000000..c79f1c5 --- /dev/null +++ b/platform/win/source-20181111-gerd05/gerdLTGT.DEF @@ -0,0 +1,4 @@ +LIBRARY gerdLTGT + + EXPORTS + KbdLayerDescriptor @1 diff --git a/platform/win/source-20181111-gerd05/gerdLTGT.H b/platform/win/source-20181111-gerd05/gerdLTGT.H new file mode 100644 index 0000000..3d4e2b2 --- /dev/null +++ b/platform/win/source-20181111-gerd05/gerdLTGT.H @@ -0,0 +1,103 @@ +/****************************** Module Header ******************************\ +* Module Name: gerdLTGT.H +* +* keyboard layout header +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* Various defines for use by keyboard input code. +* +* History: +* +* created by KBDTOOL v3.40 Mon May 29 08:05:02 2017 +* +\***************************************************************************/ + +/* + * kbd type should be controlled by cl command-line argument + */ +#define KBD_TYPE 4 + +/* +* Include the basis of all keyboard table values +*/ +#include "kbd.h" +/***************************************************************************\ +* The table below defines the virtual keys for various keyboard types where +* the keyboard differ from the US keyboard. +* +* _EQ() : all keyboard types have the same virtual key for this scancode +* _NE() : different virtual keys for this scancode, depending on kbd type +* +* +------+ +----------+----------+----------+----------+----------+----------+ +* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd | +* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 | +\****+-------+_+----------+----------+----------+----------+----------+----------+*/ + +#undef T0C + #define T0C _EQ( OEM_4 ) +#undef T0D + #define T0D _EQ( OEM_6 ) +#undef T10 + #define T10 _EQ( OEM_7 ) +#undef T11 + #define T11 _EQ( OEM_COMMA ) +#undef T12 + #define T12 _EQ( OEM_PERIOD ) +#undef T13 + #define T13 _EQ( 'P' ) +#undef T14 + #define T14 _EQ( 'Y' ) +#undef T15 + #define T15 _EQ( 'F' ) +#undef T16 + #define T16 _EQ( 'G' ) +#undef T17 + #define T17 _EQ( 'C' ) +#undef T18 + #define T18 _EQ( 'R' ) +#undef T19 + #define T19 _EQ( 'L' ) +#undef T1A + #define T1A _EQ( OEM_2 ) +#undef T1B + #define T1B _EQ( OEM_PLUS ) +#undef T1F + #define T1F _EQ( 'O' ) +#undef T20 + #define T20 _EQ( 'E' ) +#undef T21 + #define T21 _EQ( 'U' ) +#undef T22 + #define T22 _EQ( 'I' ) +#undef T23 + #define T23 _EQ( 'D' ) +#undef T24 + #define T24 _EQ( 'H' ) +#undef T25 + #define T25 _EQ( 'T' ) +#undef T26 + #define T26 _EQ( 'N' ) +#undef T27 + #define T27 _EQ( 'S' ) +#undef T28 + #define T28 _EQ( OEM_MINUS ) +#undef T2C + #define T2C _EQ( OEM_1 ) +#undef T2D + #define T2D _EQ( 'Q' ) +#undef T2E + #define T2E _EQ( 'J' ) +#undef T2F + #define T2F _EQ( 'K' ) +#undef T30 + #define T30 _EQ( 'X' ) +#undef T31 + #define T31 _EQ( 'B' ) +#undef T33 + #define T33 _EQ( 'W' ) +#undef T34 + #define T34 _EQ( 'V' ) +#undef T35 + #define T35 _EQ( 'Z' ) + diff --git a/platform/win/source-20181111-gerd05/gerdLTGT.RC-mod00 b/platform/win/source-20181111-gerd05/gerdLTGT.RC-mod00 new file mode 100644 index 0000000..3e611bb --- /dev/null +++ b/platform/win/source-20181111-gerd05/gerdLTGT.RC-mod00 @@ -0,0 +1,50 @@ +#include "winver.h" + 1 VERSIONINFO + FILEVERSION 1,0,3,40 + PRODUCTVERSION 1,0,3,40 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE VFT_DLL + FILESUBTYPE VFT2_DRV_KEYBOARD +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004B0" + BEGIN + VALUE "CompanyName", "Please contribute on https:\0" + VALUE "FileDescription", "German Dvorak ltgt (useful for text with Keyboard Layout\0" + VALUE "FileVersion", "1, 0, 3, 40\0" + VALUE "InternalName", "gerdltgt (3.40)\0" + VALUE "ProductName","Created by MSKLC 1.4\0" + VALUE "Release Information","Created by MSKLC 1.4\0" + VALUE "LegalCopyright", "MIT license\0" + VALUE "OriginalFilename","gerdltgt\0" + VALUE "ProductVersion", "1, 0, 3, 40\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0000, 0x04B0 + END +END + +STRINGTABLE DISCARDABLE +LANGUAGE 9, 1 +BEGIN + 1200 "de-DE" +END + + +STRINGTABLE DISCARDABLE +LANGUAGE 9, 1 +BEGIN + 1000 "German Dvorak ltgt (useful for text with lots of <>)" +END + + +STRINGTABLE DISCARDABLE +LANGUAGE 9, 1 +BEGIN + 1100 "German or related (all locations world-wide)" +END diff --git a/platform/win/gerd05/gerdLTGT.klc b/platform/win/source-20181111-gerd05/gerdLTGT.klc similarity index 100% rename from platform/win/gerd05/gerdLTGT.klc rename to platform/win/source-20181111-gerd05/gerdLTGT.klc diff --git a/platform/win/gerd05/win_registry_uninstall.vbs b/platform/win/source-20181111-gerd05/win_registry_uninstall.vbs similarity index 100% rename from platform/win/gerd05/win_registry_uninstall.vbs rename to platform/win/source-20181111-gerd05/win_registry_uninstall.vbs diff --git a/platform/win/20220624-gerdLTGT/Registry_ HKEY_LOCAL_MACHINE_SYSTEM_CurrentControlSet_Control_Keyboard Layout.pdf b/platform/win/source-20220624-gerdLTGT/Registry_ HKEY_LOCAL_MACHINE_SYSTEM_CurrentControlSet_Control_Keyboard Layout.pdf similarity index 100% rename from platform/win/20220624-gerdLTGT/Registry_ HKEY_LOCAL_MACHINE_SYSTEM_CurrentControlSet_Control_Keyboard Layout.pdf rename to platform/win/source-20220624-gerdLTGT/Registry_ HKEY_LOCAL_MACHINE_SYSTEM_CurrentControlSet_Control_Keyboard Layout.pdf diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.C b/platform/win/source-20220624-gerdLTGT/gerdLTGT.C similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.C rename to platform/win/source-20220624-gerdLTGT/gerdLTGT.C diff --git a/platform/win/source-20220624-gerdLTGT/gerdLTGT.C.bak00 b/platform/win/source-20220624-gerdLTGT/gerdLTGT.C.bak00 new file mode 100644 index 0000000..386c3fb --- /dev/null +++ b/platform/win/source-20220624-gerdLTGT/gerdLTGT.C.bak00 @@ -0,0 +1,344 @@ +/***************************************************************************\ +* Module Name: gerdLTGT.C +* +* keyboard layout +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* History: +* KBDTOOL v3.40 - Created Wed May 30 21:52:25 2018 +\***************************************************************************/ + +#include +#include "kbd.h" +#include "gerdLTGT.h" + +#if defined(_M_IA64) +#pragma section(".data") +#define ALLOC_SECTION_LDATA __declspec(allocate(".data")) +#else +#pragma data_seg(".data") +#define ALLOC_SECTION_LDATA +#endif + +/***************************************************************************\ +* ausVK[] - Virtual Scan Code to Virtual Key conversion table +\***************************************************************************/ + +static ALLOC_SECTION_LDATA USHORT ausVK[] = { + T00, T01, T02, T03, T04, T05, T06, T07, + T08, T09, T0A, T0B, T0C, T0D, T0E, T0F, + T10, T11, T12, T13, T14, T15, T16, T17, + T18, T19, T1A, T1B, T1C, T1D, T1E, T1F, + T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T2A, T2B, T2C, T2D, T2E, T2F, + T30, T31, T32, T33, T34, T35, + + /* + * Right-hand Shift key must have KBDEXT bit set. + */ + T36 | KBDEXT, + + T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot + + T38, T39, T3A, T3B, T3C, T3D, T3E, + T3F, T40, T41, T42, T43, T44, + + /* + * NumLock Key: + * KBDEXT - VK_NUMLOCK is an Extended key + * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL) + */ + T45 | KBDEXT | KBDMULTIVK, + + T46 | KBDMULTIVK, + + /* + * Number Pad keys: + * KBDNUMPAD - digits 0-9 and decimal point. + * KBDSPECIAL - require special processing by Windows + */ + T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home) + T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up), + T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp), + T4A, + T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left), + T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear), + T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right), + T4E, + T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End), + T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down), + T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn), + T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins), + T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del), + + T54, T55, T56, T57, T58, T59, T5A, T5B, + T5C, T5D, T5E, T5F, T60, T61, T62, T63, + T64, T65, T66, T67, T68, T69, T6A, T6B, + T6C, T6D, T6E, T6F, T70, T71, T72, T73, + T74, T75, T76, T77, T78, T79, T7A, T7B, + T7C, T7D, T7E + +}; + +static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = { + { 0x10, X10 | KBDEXT }, // Speedracer: Previous Track + { 0x19, X19 | KBDEXT }, // Speedracer: Next Track + { 0x1D, X1D | KBDEXT }, // RControl + { 0x20, X20 | KBDEXT }, // Speedracer: Volume Mute + { 0x21, X21 | KBDEXT }, // Speedracer: Launch App 2 + { 0x22, X22 | KBDEXT }, // Speedracer: Media Play/Pause + { 0x24, X24 | KBDEXT }, // Speedracer: Media Stop + { 0x2E, X2E | KBDEXT }, // Speedracer: Volume Down + { 0x30, X30 | KBDEXT }, // Speedracer: Volume Up + { 0x32, X32 | KBDEXT }, // Speedracer: Browser Home + { 0x35, X35 | KBDEXT }, // Numpad Divide + { 0x37, X37 | KBDEXT }, // Snapshot + { 0x38, X38 | KBDEXT }, // RMenu + { 0x47, X47 | KBDEXT }, // Home + { 0x48, X48 | KBDEXT }, // Up + { 0x49, X49 | KBDEXT }, // Prior + { 0x4B, X4B | KBDEXT }, // Left + { 0x4D, X4D | KBDEXT }, // Right + { 0x4F, X4F | KBDEXT }, // End + { 0x50, X50 | KBDEXT }, // Down + { 0x51, X51 | KBDEXT }, // Next + { 0x52, X52 | KBDEXT }, // Insert + { 0x53, X53 | KBDEXT }, // Delete + { 0x5B, X5B | KBDEXT }, // Left Win + { 0x5C, X5C | KBDEXT }, // Right Win + { 0x5D, X5D | KBDEXT }, // Application + { 0x5F, X5F | KBDEXT }, // Speedracer: Sleep + { 0x65, X65 | KBDEXT }, // Speedracer: Browser Search + { 0x66, X66 | KBDEXT }, // Speedracer: Browser Favorites + { 0x67, X67 | KBDEXT }, // Speedracer: Browser Refresh + { 0x68, X68 | KBDEXT }, // Speedracer: Browser Stop + { 0x69, X69 | KBDEXT }, // Speedracer: Browser Forward + { 0x6A, X6A | KBDEXT }, // Speedracer: Browser Back + { 0x6B, X6B | KBDEXT }, // Speedracer: Launch App 1 + { 0x6C, X6C | KBDEXT }, // Speedracer: Launch Mail + { 0x6D, X6D | KBDEXT }, // Speedracer: Launch Media Selector + { 0x1C, X1C | KBDEXT }, // Numpad Enter + { 0x46, X46 | KBDEXT }, // Break (Ctrl + Pause) + { 0, 0 } +}; + +static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = { + { 0x1D, Y1D }, // Pause + { 0 , 0 } +}; + +/***************************************************************************\ +* aVkToBits[] - map Virtual Keys to Modifier Bits +* +* See kbd.h for a full description. +* +* The keyboard has only three shifter keys: +* SHIFT (L & R) affects alphabnumeric keys, +* CTRL (L & R) is used to generate control characters +* ALT (L & R) used for generating characters by number with numpad +\***************************************************************************/ +static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = { + { VK_SHIFT , KBDSHIFT }, + { VK_CONTROL , KBDCTRL }, + { VK_MENU , KBDALT }, + { 0 , 0 } +}; + +/***************************************************************************\ +* aModification[] - map character modifier bits to modification number +* +* See kbd.h for a full description. +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = { + &aVkToBits[0], + 2, + { + // Modification# // Keys Pressed + // ============= // ============= + 0, // + 1, // Shift + 2 // Control + } +}; + +/***************************************************************************\ +* +* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states +* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states +* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states +* +* Table attributes: Unordered Scan, null-terminated +* +* Search this table for an entry with a matching Virtual Key to find the +* corresponding unshifted and shifted WCHAR characters. +* +* Special values for VirtualKey (column 1) +* 0xff - dead chars for the previous entry +* 0 - terminate the list +* +* Special values for Attributes (column 2) +* CAPLOK bit - CAPS-LOCK affect this key like SHIFT +* +* Special values for wch[*] (column 3 & 4) +* WCH_NONE - No character +* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none) +* WCH_LGTR - Ligature (generates multiple characters) +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VK_TO_WCHARS2 aVkToWch2[] = { +// | | Shift | +// |=========|=========| + {VK_TAB ,0 ,'\t' ,'\t' }, + {VK_ADD ,0 ,'+' ,'+' }, + {VK_DIVIDE ,0 ,'/' ,'/' }, + {VK_MULTIPLY ,0 ,'*' ,'*' }, + {VK_SUBTRACT ,0 ,'-' ,'-' }, + {0 ,0 ,0 ,0 } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHARS3 aVkToWch3[] = { +// | | Shift | Ctrl | +// |=========|=========|=========| + {VK_OEM_3 ,0 ,WCH_NONE ,WCH_NONE ,'~' }, + {'1' ,0 ,WCH_NONE ,WCH_NONE ,'!' }, + {'2' ,0 ,0x00e4 ,0x00c4 ,'@' }, + {'3' ,0 ,0x00f6 ,0x00d6 ,'#' }, + {'4' ,0 ,WCH_NONE ,WCH_NONE ,'$' }, + {'5' ,0 ,0x00fc ,0x00dc ,'%' }, + {'6' ,0 ,WCH_NONE ,WCH_NONE ,'^' }, + {'7' ,0 ,WCH_NONE ,WCH_NONE ,'&' }, + {'8' ,0 ,WCH_NONE ,WCH_NONE ,'*' }, + {'9' ,0 ,WCH_NONE ,WCH_NONE ,'(' }, + {'0' ,0 ,WCH_NONE ,WCH_NONE ,')' }, + {VK_OEM_4 ,0 ,0x00df ,0x1e9e ,'{' }, + {VK_OEM_6 ,0 ,WCH_NONE ,WCH_NONE ,'}' }, + {VK_OEM_102 ,0 ,WCH_NONE ,WCH_NONE ,WCH_NONE }, + {VK_OEM_7 ,0 ,'\'' ,'\"' ,WCH_NONE }, + {VK_OEM_COMMA ,0 ,',' ,'<' ,0x2013 }, + {VK_OEM_PERIOD,0 ,'.' ,'>' ,'!' }, + {'P' ,0 ,'p' ,'P' ,0x00a7 }, + {'Y' ,0 ,'y' ,'Y' ,WCH_NONE }, + {'F' ,0 ,'f' ,'F' ,',' }, + {'G' ,0 ,'g' ,'G' ,'7' }, + {'C' ,0 ,'c' ,'C' ,'8' }, + {'R' ,0 ,'r' ,'R' ,'9' }, + {'L' ,0 ,'l' ,'L' ,'[' }, + {VK_OEM_2 ,0 ,'/' ,'?' ,']' }, + {VK_OEM_PLUS ,0 ,'=' ,'+' ,'+' }, + {VK_OEM_5 ,0 ,'\\' ,'|' ,'|' }, + {'A' ,0 ,'a' ,'A' ,'@' }, + {'O' ,0 ,'o' ,'O' ,0x00b0 }, + {'E' ,0 ,'e' ,'E' ,0x20ac }, + {'U' ,0 ,'u' ,'U' ,'`' }, + {'I' ,0 ,'i' ,'I' ,WCH_NONE }, + {'D' ,0 ,'d' ,'D' ,':' }, + {'H' ,0 ,'h' ,'H' ,'4' }, + {'T' ,0 ,'t' ,'T' ,'5' }, + {'N' ,0 ,'n' ,'N' ,'6' }, + {'S' ,0 ,'s' ,'S' ,'=' }, + {VK_OEM_MINUS ,0 ,'-' ,'_' ,'\\' }, + {VK_OEM_1 ,0 ,';' ,':' ,WCH_NONE }, + {'Q' ,0 ,'q' ,'Q' ,WCH_NONE }, + {'J' ,0 ,'j' ,'J' ,WCH_NONE }, + {'K' ,0 ,'k' ,'K' ,WCH_NONE }, + {'X' ,0 ,'x' ,'X' ,WCH_NONE }, + {'B' ,0 ,'b' ,'B' ,'0' }, + {'M' ,0 ,'m' ,'M' ,'1' }, + {'W' ,0 ,'w' ,'W' ,'2' }, + {'V' ,0 ,'v' ,'V' ,'3' }, + {'Z' ,0 ,'z' ,'Z' ,'.' }, + {VK_DECIMAL ,0 ,'.' ,'.' ,'.' }, + {VK_SPACE ,0 ,' ' ,0x00a0 ,0x00a0 }, + {VK_BACK ,0 ,'\b' ,'\b' ,0x007f }, + {VK_ESCAPE ,0 ,0x001b ,0x001b ,0x001b }, + {VK_RETURN ,0 ,'\r' ,'\r' ,'\n' }, + {VK_CANCEL ,0 ,0x0003 ,0x0003 ,0x0003 }, + {0 ,0 ,0 ,0 ,0 } +}; + +// Put this last so that VkKeyScan interprets number characters +// as coming from the main section of the kbd (aVkToWch2 and +// aVkToWch5) before considering the numpad (aVkToWch1). + +static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = { + { VK_NUMPAD0 , 0 , '0' }, + { VK_NUMPAD1 , 0 , '1' }, + { VK_NUMPAD2 , 0 , '2' }, + { VK_NUMPAD3 , 0 , '3' }, + { VK_NUMPAD4 , 0 , '4' }, + { VK_NUMPAD5 , 0 , '5' }, + { VK_NUMPAD6 , 0 , '6' }, + { VK_NUMPAD7 , 0 , '7' }, + { VK_NUMPAD8 , 0 , '8' }, + { VK_NUMPAD9 , 0 , '9' }, + { 0 , 0 , '\0' } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = { + { (PVK_TO_WCHARS1)aVkToWch3, 3, sizeof(aVkToWch3[0]) }, + { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) }, + { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) }, + { NULL, 0, 0 }, +}; + +/***************************************************************************\ +* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables +* +* Table attributes: Ordered Scan (by scancode), null-terminated +* +* Only the names of Extended, NumPad, Dead and Non-Printable keys are here. +* (Keys producing printable characters are named by that character) +\***************************************************************************/ + +static ALLOC_SECTION_LDATA KBDTABLES KbdTables = { + /* + * Modifier keys + */ + &CharModifiers, + + /* + * Characters tables + */ + aVkToWcharTable, + + /* + * Diacritics + */ + NULL, + + /* + * Names of Keys + */ + NULL, + NULL, + NULL, + + /* + * Scan codes to Virtual Keys + */ + ausVK, + sizeof(ausVK) / sizeof(ausVK[0]), + aE0VscToVk, + aE1VscToVk, + + /* + * Locale-specific special processing + */ + MAKELONG(0, KBD_VERSION), + + /* + * Ligatures + */ + 0, + 0, + NULL +}; + +PKBDTABLES KbdLayerDescriptor(VOID) +{ + return &KbdTables; +} diff --git a/platform/win/source-20220624-gerdLTGT/gerdLTGT.C.bak01 b/platform/win/source-20220624-gerdLTGT/gerdLTGT.C.bak01 new file mode 100644 index 0000000..80014e8 --- /dev/null +++ b/platform/win/source-20220624-gerdLTGT/gerdLTGT.C.bak01 @@ -0,0 +1,533 @@ +// FIXME use virtual keys (e.g. OEM_ or rather undefined ones) instead of Shifts +// disdvantage: might not work with some of the "shift levels" +// FIXME has E1 other possibilities than E0 ? +// FIXME test when a shift level falls down (when the last pressed key +// gets unpressed? or already when just one of the keys gets unpressed?) +// FIXME per keyboard layout option "SHIFTLOCK" + +/***************************************************************************\ + ä Ö Ü ß +* Module Name: gerdLTGT.C +* +* keyboard layout +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* History: +* KBDTOOL v3.40 - Created Mon May 29 08:05:02 2017 +\***************************************************************************/ + +#include +#include "kbd.h" +#include "winuser.h" +#include "gerdLTGT.h" + +#if defined(_M_IA64) +//FIXME +//#pragma section(".data",read,write) +#pragma section(".data") +#define ALLOC_SECTION_LDATA __declspec(allocate(".data")) +#else +//FIXME might need system-init of the DLL, not a process-specific init (it's a huge security risk) +//#pragma bss_seg(".data") +#pragma data_seg(".data") +#define ALLOC_SECTION_LDATA +#endif + +/***************************************************************************\ +* ausVK[] - Virtual Scan Code to Virtual Key conversion table +\***************************************************************************/ + +static ALLOC_SECTION_LDATA USHORT ausVK[] = { + T00, T01, T02, T03, T04, T05, T06, T07, + T08, T09, T0A, T0B, T0C, T0D, T0E, T0F, + T10, T11, T12, T13, T14, T15, T16, T17, + // 24 + + T18, T19, T1A, T1B, T1C, + // 5 + + + /* + * Left Ctrl FIXME + */ + T1D, + + T1E, T1F, + T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, + // 12 + + + /* + * Left-hand Shift FIXME + */ + T2A, + + T2B, T2C, T2D, T2E, T2F, + T30, T31, T32, T33, T34, T35, + // 11 + + + /* + * Right-hand Shift key must have KBDEXT bit set. + */ + // FIXME try it without KBDEXT (https://stackoverflow.com/a/15967904 ) + T36 | KBDEXT, + + T37 | KBDMULTIVK, // numpad_* + Shift/Alt -> SnapShot + + T38, T39, T3A, T3B, T3C, T3D, T3E, + T3F, T40, T41, T42, T43, T44, + // 13 + + + /* + * NumLock Key: + * KBDEXT - VK_NUMLOCK is an Extended key + * KBDMULTIVK - VK_NUMLOCK or VK_PAUSE (without or with CTRL) + */ + T45 | KBDEXT | KBDMULTIVK, + + T46 | KBDMULTIVK, + + /* + * Number Pad keys: + * KBDNUMPAD - digits 0-9 and decimal point. + * KBDSPECIAL - require special processing by Windows + */ + T47 | KBDNUMPAD | KBDSPECIAL, // Numpad 7 (Home) + T48 | KBDNUMPAD | KBDSPECIAL, // Numpad 8 (Up), + T49 | KBDNUMPAD | KBDSPECIAL, // Numpad 9 (PgUp), + T4A, + T4B | KBDNUMPAD | KBDSPECIAL, // Numpad 4 (Left), + T4C | KBDNUMPAD | KBDSPECIAL, // Numpad 5 (Clear), + T4D | KBDNUMPAD | KBDSPECIAL, // Numpad 6 (Right), + T4E, + T4F | KBDNUMPAD | KBDSPECIAL, // Numpad 1 (End), + T50 | KBDNUMPAD | KBDSPECIAL, // Numpad 2 (Down), + T51 | KBDNUMPAD | KBDSPECIAL, // Numpad 3 (PgDn), + T52 | KBDNUMPAD | KBDSPECIAL, // Numpad 0 (Ins), + T53 | KBDNUMPAD | KBDSPECIAL, // Numpad . (Del), + + T54, T55, T56, T57, T58, T59, T5A, T5B, + T5C, T5D, T5E, T5F, T60, T61, T62, T63, + T64, T65, T66, T67, T68, T69, T6A, T6B, + T6C, T6D, T6E, T6F, T70, T71, T72, T73, + T74, T75, T76, T77, T78, T79, T7A, T7B, + // 40 + + T7C, T7D, T7E + // 3 = 127 + +}; + +static ALLOC_SECTION_LDATA VSC_VK aE0VscToVk[] = { + { 0x10, X10 | KBDEXT }, // Speedracer: Previous Track + { 0x19, X19 | KBDEXT }, // Speedracer: Next Track + { 0x1D, X1D | KBDEXT }, // RControl; Right Ctrl FIXME + { 0x20, X20 | KBDEXT }, // Speedracer: Volume Mute + { 0x21, X21 | KBDEXT }, // Speedracer: Launch App 2 + { 0x22, X22 | KBDEXT }, // Speedracer: Media Play/Pause + { 0x24, X24 | KBDEXT }, // Speedracer: Media Stop + { 0x2E, X2E | KBDEXT }, // Speedracer: Volume Down + { 0x30, X30 | KBDEXT }, // Speedracer: Volume Up + { 0x32, X32 | KBDEXT }, // Speedracer: Browser Home + { 0x35, X35 | KBDEXT }, // Numpad Divide + { 0x37, X37 | KBDEXT }, // Snapshot + { 0x38, X38 | KBDEXT }, // RMenu + { 0x47, X47 | KBDEXT }, // Home + { 0x48, X48 | KBDEXT }, // Up + { 0x49, X49 | KBDEXT }, // Prior + { 0x4B, X4B | KBDEXT }, // Left + { 0x4D, X4D | KBDEXT }, // Right + { 0x4F, X4F | KBDEXT }, // End + { 0x50, X50 | KBDEXT }, // Down + { 0x51, X51 | KBDEXT }, // Next + { 0x52, X52 | KBDEXT }, // Insert + { 0x53, X53 | KBDEXT }, // Delete + { 0x5B, X5B | KBDEXT }, // Left Win + { 0x5C, X5C | KBDEXT }, // Right Win + { 0x5D, X5D | KBDEXT }, // Application + { 0x5F, X5F | KBDEXT }, // Speedracer: Sleep + { 0x65, X65 | KBDEXT }, // Speedracer: Browser Search + { 0x66, X66 | KBDEXT }, // Speedracer: Browser Favorites + { 0x67, X67 | KBDEXT }, // Speedracer: Browser Refresh + { 0x68, X68 | KBDEXT }, // Speedracer: Browser Stop + { 0x69, X69 | KBDEXT }, // Speedracer: Browser Forward + { 0x6A, X6A | KBDEXT }, // Speedracer: Browser Back + { 0x6B, X6B | KBDEXT }, // Speedracer: Launch App 1 + { 0x6C, X6C | KBDEXT }, // Speedracer: Launch Mail + { 0x6D, X6D | KBDEXT }, // Speedracer: Launch Media Selector + { 0x1C, X1C | KBDEXT }, // Numpad Enter + { 0x46, X46 | KBDEXT }, // Break (Ctrl + Pause) + { 0, 0 } +}; + +static ALLOC_SECTION_LDATA VSC_VK aE1VscToVk[] = { + { 0x1D, Y1D }, // Pause + { 0 , 0 } +}; + +/***************************************************************************\ +* aVkToBits[] - map Virtual Keys to Modifier Bits +* +* See kbd.h for a full description. +* +*FIXME wrong original description: +* The keyboard has only three shifter keys: +* SHIFT (L & R) affects alphabnumeric keys, +* CTRL (L & R) is used to generate control characters +* ALT (L & R) used for generating characters by number with numpad +\***************************************************************************/ +static ALLOC_SECTION_LDATA VK_TO_BIT aVkToBits[] = { +// { VK_SHIFT , KBDSHIFT }, +// { VK_CONTROL , KBDCTRL }, +// { VK_MENU , KBDALT }, +// { 0 , 0 } + + // FIXME dumblob + // a hack to allow distinguishing left and right shift by propagating it to aModification[] + // make "KBDSHIFT | KBDCTRL" a unique bit combination for left shift + { VK_LSHIFT, KBDSHIFT | KBDCTRL }, + // make "KBDSHIFT | KBDCTRL" a unique bit combination for right shift + { VK_RSHIFT, KBDSHIFT | KBDALT }, + //{ VK_LCONTROL, KBDCTRL }, + //{ VK_RCONTROL, KBDCTRL }, + { 0, 0 } +}; + +/***************************************************************************\ +* aModification[] - map character modifier bits to modification number +* +* See kbd.h for a full description. +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA MODIFIERS CharModifiers = { + // Demonstration of the relationship (note: this demo is + // a complete nonsense in terms of an internal implementation): + // for( x in aVkToBits ){ + // if( x[0] == 0 && x[1] == 0 ) break + // if( x[1] <= wMaxModBits ){ + // // x[0] is not interesting + // if( aModification[x[1]] != SHFT_INVALID ){ + // shift_to_the_level( aModification[x[1]] ) + // break + // } + // } + // } + + // PVK_TO_BIT pVkToBit; // Virtual Keys -> Mod bits + &aVkToBits[0], + // WORD wMaxModBits; // max Modification bit combination value + KBDSHIFT | KBDCTRL | KBDALT, + + // BYTE ModNumber[]; // Mod bits -> Modification Number + // mod_bits are an index to this array => order matters ( + // arithmetic progression with step 1 without any omission; + // use SHFT_INVALID as an ignored shift state) + { + // from kbd.h: + // #define KBDSHIFT (1 << 0) + // #define KBDCTRL (1 << 1) + // #define KBDALT (1 << 2) + // #define KBDKANA (1 << 3) + // #define KBDROYA (1 << 4) + // #define KBDLOYA (1 << 5) + // (1 << 6) doesn't exist (not defined anywhere) + // #define KBDGRPSELTAP (1 << 7) + + // FIXME test Ctrl and Alt key bindings (e.g. Ctrl+c, Alt+64, ...) + // shift_state_idx // KBDALT KBDCTRL KBDSHIFT + 0, // 0 0 0 + SHFT_INVALID, // 0 0 1 + SHFT_INVALID, // 0 1 0 + 1, // 0 1 1 (only LSHIFT pressed) + SHFT_INVALID, // 1 0 0 + 1, // 1 0 1 (only RSHIFT pressed) + SHFT_INVALID, // 1 1 0 + 2, // 1 1 1 (both LSHIFT and RSHIFT + // pressed simultaneously) + } +}; + +/***************************************************************************\ +* +* aVkToWch2[] - Virtual Key to WCHAR translation for 2 shift states +* aVkToWch3[] - Virtual Key to WCHAR translation for 3 shift states +* aVkToWch4[] - Virtual Key to WCHAR translation for 4 shift states +* +* Table attributes: Unordered Scan, null-terminated +* +* Search this table for an entry with a matching Virtual Key to find the +* corresponding unshifted and shifted WCHAR characters. +* +* Special values for VirtualKey (column 1) +* 0xff - dead chars for the previous entry +* 0 - terminate the list +* +* Special values for Attributes (column 2) +* CAPLOK bit - CAPS-LOCK affect this key like SHIFT +* +* Special values for wch[*] (column 3 & 4) +* WCH_NONE - No character +* WCH_DEAD - Dead Key (diaresis) or invalid (US keyboard has none) +* WCH_LGTR - Ligature (generates multiple characters) +* +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VK_TO_WCHARS2 aVkToWch2[] = { +// | | Shift | +// |=========|=========| + {VK_TAB ,0 ,'\t' ,'\t' }, + {VK_ADD ,0 ,'+' ,'+' }, + {VK_DIVIDE ,0 ,'/' ,'/' }, + {VK_MULTIPLY ,0 ,'*' ,'*' }, + {VK_SUBTRACT ,0 ,'-' ,'-' }, + {0 ,0 ,0 ,0 } +}; + +// FIXME all unwanted VK_* keys should be redefined as WCH_NONE +static ALLOC_SECTION_LDATA VK_TO_WCHARS3 aVkToWch3[] = { +// | | Shift | Ctrl | +// |=========|=========|=========| + {VK_OEM_3 ,0 ,WCH_NONE ,WCH_NONE ,'~' }, + {'1' ,0 ,WCH_NONE ,WCH_NONE ,'!' }, + {'2' ,0 ,0x00e4 ,0x00c4 ,'@' }, + {'3' ,0 ,0x00f6 ,0x00d6 ,'#' }, + {'4' ,0 ,WCH_NONE ,WCH_NONE ,'$' }, + {'5' ,0 ,0x00fc ,0x00dc ,'%' }, + {'6' ,0 ,WCH_NONE ,WCH_NONE ,'^' }, + {'7' ,0 ,WCH_NONE ,WCH_NONE ,'&' }, + {'8' ,0 ,WCH_NONE ,WCH_NONE ,'*' }, + {'9' ,0 ,WCH_NONE ,WCH_NONE ,'(' }, + {'0' ,0 ,WCH_NONE ,WCH_NONE ,')' }, + {VK_OEM_4 ,0 ,0x00df ,0x1e9e ,'{' }, + {VK_OEM_6 ,0 ,WCH_NONE ,WCH_NONE ,'}' }, + {VK_OEM_102 ,0 ,WCH_NONE ,WCH_NONE ,WCH_NONE }, + {VK_OEM_7 ,0 ,'\'' ,'\"' ,WCH_NONE }, + {VK_OEM_COMMA ,0 ,',' ,'<' ,WCH_NONE }, + {VK_OEM_PERIOD,0 ,'.' ,'>' ,WCH_NONE }, + {'P' ,0 ,'p' ,'P' ,WCH_NONE }, + {'Y' ,0 ,'y' ,'Y' ,WCH_NONE }, + {'F' ,0 ,'f' ,'F' ,WCH_NONE }, + {'G' ,0 ,'g' ,'G' ,WCH_NONE }, + {'C' ,0 ,'c' ,'C' ,WCH_NONE }, + {'R' ,0 ,'r' ,'R' ,WCH_NONE }, + {'L' ,0 ,'l' ,'L' ,WCH_NONE }, + {VK_OEM_2 ,0 ,'/' ,'?' ,']' }, + {VK_OEM_PLUS ,0 ,'=' ,'+' ,'+' }, + {VK_OEM_5 ,0 ,'\\' ,'|' ,'|' }, + {'A' ,0 ,'a' ,'A' ,WCH_NONE }, + {'O' ,0 ,'o' ,'O' ,WCH_NONE }, + {'E' ,0 ,'e' ,'E' ,WCH_NONE }, + {'U' ,0 ,'u' ,'U' ,WCH_NONE }, + {'I' ,0 ,'i' ,'I' ,WCH_NONE }, + {'D' ,0 ,'d' ,'D' ,WCH_NONE }, + {'H' ,0 ,'h' ,'H' ,WCH_NONE }, + {'T' ,0 ,'t' ,'T' ,WCH_NONE }, + {'N' ,0 ,'n' ,'N' ,WCH_NONE }, + {'S' ,0 ,'s' ,'S' ,WCH_NONE }, + {VK_OEM_MINUS ,0 ,'-' ,'_' ,'\\' }, + {VK_OEM_1 ,0 ,';' ,':' ,WCH_NONE }, + {'Q' ,0 ,'q' ,'Q' ,WCH_NONE }, + {'J' ,0 ,'j' ,'J' ,WCH_NONE }, + {'K' ,0 ,'k' ,'K' ,WCH_NONE }, + {'X' ,0 ,'x' ,'X' ,WCH_NONE }, + {'B' ,0 ,'b' ,'B' ,WCH_NONE }, + {'M' ,0 ,'m' ,'M' ,WCH_NONE }, + {'W' ,0 ,'w' ,'W' ,WCH_NONE }, + {'V' ,0 ,'v' ,'V' ,WCH_NONE }, + {'Z' ,0 ,'z' ,'Z' ,WCH_NONE }, + {VK_DECIMAL ,0 ,'.' ,'.' ,'.' }, + {VK_SPACE ,0 ,' ' ,0x00a0 ,0x00a0 }, + {VK_BACK ,0 ,'\b' ,'\b' ,0x007f }, + {VK_ESCAPE ,0 ,0x001b ,0x001b ,0x001b }, + {VK_RETURN ,0 ,'\r' ,'\r' ,'\n' }, + {VK_CANCEL ,0 ,0x0003 ,0x0003 ,0x0003 }, + {0 ,0 ,0 ,0 ,0 } +}; + +// Put this last so that VkKeyScan interprets number characters +// as coming from the main section of the kbd (aVkToWch2 and +// aVkToWch5) before considering the numpad (aVkToWch1). + +static ALLOC_SECTION_LDATA VK_TO_WCHARS1 aVkToWch1[] = { + { VK_NUMPAD0 , 0 , '0' }, + { VK_NUMPAD1 , 0 , '1' }, + { VK_NUMPAD2 , 0 , '2' }, + { VK_NUMPAD3 , 0 , '3' }, + { VK_NUMPAD4 , 0 , '4' }, + { VK_NUMPAD5 , 0 , '5' }, + { VK_NUMPAD6 , 0 , '6' }, + { VK_NUMPAD7 , 0 , '7' }, + { VK_NUMPAD8 , 0 , '8' }, + { VK_NUMPAD9 , 0 , '9' }, + { 0 , 0 , '\0' } +}; + +static ALLOC_SECTION_LDATA VK_TO_WCHAR_TABLE aVkToWcharTable[] = { + { (PVK_TO_WCHARS1)aVkToWch3, 3, sizeof(aVkToWch3[0]) }, + { (PVK_TO_WCHARS1)aVkToWch2, 2, sizeof(aVkToWch2[0]) }, + { (PVK_TO_WCHARS1)aVkToWch1, 1, sizeof(aVkToWch1[0]) }, + { NULL, 0, 0 }, +}; + +/***************************************************************************\ +* aKeyNames[], aKeyNamesExt[] - Virtual Scancode to Key Name tables +* +* Table attributes: Ordered Scan (by scancode), null-terminated +* +* Only the names of Extended, NumPad, Dead and Non-Printable keys are here. +* (Keys producing printable characters are named by that character) +\***************************************************************************/ + +static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNames[] = { + 0x01, L"Esc", + 0x0e, L"Backspace", + 0x0f, L"Tab", + 0x1c, L"Enter", + 0x1d, L"Ctrl", + 0x2a, L"Left Shift", + 0x36, L"Right Shift", + 0x37, L"Num *", + 0x38, L"Alt", + 0x39, L"Space", + 0x3a, L"Caps Lock", + 0x3b, L"F1", + 0x3c, L"F2", + 0x3d, L"F3", + 0x3e, L"F4", + 0x3f, L"F5", + 0x40, L"F6", + 0x41, L"F7", + 0x42, L"F8", + 0x43, L"F9", + 0x44, L"F10", + 0x45, L"Pause", + 0x46, L"Scroll Lock", + 0x47, L"Num 7", + 0x48, L"Num 8", + 0x49, L"Num 9", + 0x4a, L"Num -", + 0x4b, L"Num 4", + 0x4c, L"Num 5", + 0x4d, L"Num 6", + 0x4e, L"Num +", + 0x4f, L"Num 1", + 0x50, L"Num 2", + 0x51, L"Num 3", + 0x52, L"Num 0", + 0x53, L"Num Del", + 0x54, L"Sys Req", + 0x57, L"F11", + 0x58, L"F12", + 0x7c, L"F13", + 0x7d, L"F14", + 0x7e, L"F15", + 0x7f, L"F16", + 0x80, L"F17", + 0x81, L"F18", + 0x82, L"F19", + 0x83, L"F20", + 0x84, L"F21", + 0x85, L"F22", + 0x86, L"F23", + 0x87, L"F24", + 0 , NULL +}; + +static ALLOC_SECTION_LDATA VSC_LPWSTR aKeyNamesExt[] = { + 0x1c, L"Num Enter", + 0x1d, L"Right Ctrl", + 0x35, L"Num /", + 0x37, L"Prnt Scrn", + 0x38, L"Right Alt", + 0x45, L"Num Lock", + 0x46, L"Break", + 0x47, L"Home", + 0x48, L"Up", + 0x49, L"Page Up", + 0x4b, L"Left", + 0x4d, L"Right", + 0x4f, L"End", + 0x50, L"Down", + 0x51, L"Page Down", + 0x52, L"Insert", + 0x53, L"Delete", + 0x54, L"<00>", + 0x54, L"Sys Req", + 0x56, L"Help", + 0x5b, L"Left Windows", + 0x5c, L"Right Windows", + 0x5d, L"Application", + 0 , NULL +}; + +static ALLOC_SECTION_LDATA KBDTABLES KbdTables = { + /* + * Modifier keys + */ + &CharModifiers, + + /* + * Characters tables + */ + aVkToWcharTable, + + /* + * Diacritics (deadkeys) + */ + NULL, + + /* + * Names of Keys + */ + aKeyNames, + aKeyNamesExt, + NULL, + +// /* +// * Scan codes to Virtual Keys +// */ +// USHORT *KBD_LONG_POINTER pusVSCtoVK; +// BYTE bMaxVSCtoVK; +// PVSC_VK pVSCtoVK_E0; // Scancode has E0 prefix +// PVSC_VK pVSCtoVK_E1; // Scancode has E1 prefix + /* + * Scan codes to Virtual Keys + */ + ausVK, + sizeof(ausVK) / sizeof(ausVK[0]), + // both LSHIFT and RSHIFT usually ignored (see xlate.c in win2ksrc.rar) + aE0VscToVk, + aE1VscToVk, + + /* + * Locale-specific special processing + */ + MAKELONG(0, KBD_VERSION), + + /* + * Ligatures + */ + 0, + 0, + NULL +}; + +PKBDTABLES KbdLayerDescriptor(VOID) +{ + // There doesn't seem to be any easy reliable way to assign VK_ESCAPE to + // the CAPITAL virtual scancode in compile time due to a high diversity + // of keyboard types. + // FIXME supporting only HID keyboards would make it easy to assign + // VK_ESCAPE reliably in compile-time (2017: all widely used compilers + // can detect that the whole expression is static and compute it in + // compile time, but the MSKLC built-in compiler most probably can't) + //int i; + //for( i = 0; i < KbdTables.bMaxVSCtoVK; ++i ){ + // if( KbdTables.pusVSCtoVK[i] == VK_CAPITAL ) + // // CAPITAL (~ CapsLk) -> ESCAPE + // KbdTables.pusVSCtoVK[i] = VK_ESCAPE; + //} + + return &KbdTables; +} + +// vim: set wrap ft=c: diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.C.howto b/platform/win/source-20220624-gerdLTGT/gerdLTGT.C.howto similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.C.howto rename to platform/win/source-20220624-gerdLTGT/gerdLTGT.C.howto diff --git a/platform/win/source-20220624-gerdLTGT/gerdLTGT.DEF b/platform/win/source-20220624-gerdLTGT/gerdLTGT.DEF new file mode 100644 index 0000000..c79f1c5 --- /dev/null +++ b/platform/win/source-20220624-gerdLTGT/gerdLTGT.DEF @@ -0,0 +1,4 @@ +LIBRARY gerdLTGT + + EXPORTS + KbdLayerDescriptor @1 diff --git a/platform/win/source-20220624-gerdLTGT/gerdLTGT.H b/platform/win/source-20220624-gerdLTGT/gerdLTGT.H new file mode 100644 index 0000000..3d4e2b2 --- /dev/null +++ b/platform/win/source-20220624-gerdLTGT/gerdLTGT.H @@ -0,0 +1,103 @@ +/****************************** Module Header ******************************\ +* Module Name: gerdLTGT.H +* +* keyboard layout header +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* Various defines for use by keyboard input code. +* +* History: +* +* created by KBDTOOL v3.40 Mon May 29 08:05:02 2017 +* +\***************************************************************************/ + +/* + * kbd type should be controlled by cl command-line argument + */ +#define KBD_TYPE 4 + +/* +* Include the basis of all keyboard table values +*/ +#include "kbd.h" +/***************************************************************************\ +* The table below defines the virtual keys for various keyboard types where +* the keyboard differ from the US keyboard. +* +* _EQ() : all keyboard types have the same virtual key for this scancode +* _NE() : different virtual keys for this scancode, depending on kbd type +* +* +------+ +----------+----------+----------+----------+----------+----------+ +* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd | +* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 | +\****+-------+_+----------+----------+----------+----------+----------+----------+*/ + +#undef T0C + #define T0C _EQ( OEM_4 ) +#undef T0D + #define T0D _EQ( OEM_6 ) +#undef T10 + #define T10 _EQ( OEM_7 ) +#undef T11 + #define T11 _EQ( OEM_COMMA ) +#undef T12 + #define T12 _EQ( OEM_PERIOD ) +#undef T13 + #define T13 _EQ( 'P' ) +#undef T14 + #define T14 _EQ( 'Y' ) +#undef T15 + #define T15 _EQ( 'F' ) +#undef T16 + #define T16 _EQ( 'G' ) +#undef T17 + #define T17 _EQ( 'C' ) +#undef T18 + #define T18 _EQ( 'R' ) +#undef T19 + #define T19 _EQ( 'L' ) +#undef T1A + #define T1A _EQ( OEM_2 ) +#undef T1B + #define T1B _EQ( OEM_PLUS ) +#undef T1F + #define T1F _EQ( 'O' ) +#undef T20 + #define T20 _EQ( 'E' ) +#undef T21 + #define T21 _EQ( 'U' ) +#undef T22 + #define T22 _EQ( 'I' ) +#undef T23 + #define T23 _EQ( 'D' ) +#undef T24 + #define T24 _EQ( 'H' ) +#undef T25 + #define T25 _EQ( 'T' ) +#undef T26 + #define T26 _EQ( 'N' ) +#undef T27 + #define T27 _EQ( 'S' ) +#undef T28 + #define T28 _EQ( OEM_MINUS ) +#undef T2C + #define T2C _EQ( OEM_1 ) +#undef T2D + #define T2D _EQ( 'Q' ) +#undef T2E + #define T2E _EQ( 'J' ) +#undef T2F + #define T2F _EQ( 'K' ) +#undef T30 + #define T30 _EQ( 'X' ) +#undef T31 + #define T31 _EQ( 'B' ) +#undef T33 + #define T33 _EQ( 'W' ) +#undef T34 + #define T34 _EQ( 'V' ) +#undef T35 + #define T35 _EQ( 'Z' ) + diff --git a/platform/win/source-20220624-gerdLTGT/gerdLTGT.H.bak00 b/platform/win/source-20220624-gerdLTGT/gerdLTGT.H.bak00 new file mode 100644 index 0000000..733b58e --- /dev/null +++ b/platform/win/source-20220624-gerdLTGT/gerdLTGT.H.bak00 @@ -0,0 +1,103 @@ +/****************************** Module Header ******************************\ +* Module Name: gerdLTGT.H +* +* keyboard layout header +* +* Copyright (c) 1985-2001, Microsoft Corporation +* +* Various defines for use by keyboard input code. +* +* History: +* +* created by KBDTOOL v3.40 Wed May 30 21:52:25 2018 +* +\***************************************************************************/ + +/* + * kbd type should be controlled by cl command-line argument + */ +#define KBD_TYPE 4 + +/* +* Include the basis of all keyboard table values +*/ +#include "kbd.h" +/***************************************************************************\ +* The table below defines the virtual keys for various keyboard types where +* the keyboard differ from the US keyboard. +* +* _EQ() : all keyboard types have the same virtual key for this scancode +* _NE() : different virtual keys for this scancode, depending on kbd type +* +* +------+ +----------+----------+----------+----------+----------+----------+ +* | Scan | | kbd | kbd | kbd | kbd | kbd | kbd | +* | code | | type 1 | type 2 | type 3 | type 4 | type 5 | type 6 | +\****+-------+_+----------+----------+----------+----------+----------+----------+*/ + +#undef T0C + #define T0C _EQ( OEM_4 ) +#undef T0D + #define T0D _EQ( OEM_6 ) +#undef T10 + #define T10 _EQ( OEM_7 ) +#undef T11 + #define T11 _EQ( OEM_COMMA ) +#undef T12 + #define T12 _EQ( OEM_PERIOD ) +#undef T13 + #define T13 _EQ( 'P' ) +#undef T14 + #define T14 _EQ( 'Y' ) +#undef T15 + #define T15 _EQ( 'F' ) +#undef T16 + #define T16 _EQ( 'G' ) +#undef T17 + #define T17 _EQ( 'C' ) +#undef T18 + #define T18 _EQ( 'R' ) +#undef T19 + #define T19 _EQ( 'L' ) +#undef T1A + #define T1A _EQ( OEM_2 ) +#undef T1B + #define T1B _EQ( OEM_PLUS ) +#undef T1F + #define T1F _EQ( 'O' ) +#undef T20 + #define T20 _EQ( 'E' ) +#undef T21 + #define T21 _EQ( 'U' ) +#undef T22 + #define T22 _EQ( 'I' ) +#undef T23 + #define T23 _EQ( 'D' ) +#undef T24 + #define T24 _EQ( 'H' ) +#undef T25 + #define T25 _EQ( 'T' ) +#undef T26 + #define T26 _EQ( 'N' ) +#undef T27 + #define T27 _EQ( 'S' ) +#undef T28 + #define T28 _EQ( OEM_MINUS ) +#undef T2C + #define T2C _EQ( OEM_1 ) +#undef T2D + #define T2D _EQ( 'Q' ) +#undef T2E + #define T2E _EQ( 'J' ) +#undef T2F + #define T2F _EQ( 'K' ) +#undef T30 + #define T30 _EQ( 'X' ) +#undef T31 + #define T31 _EQ( 'B' ) +#undef T33 + #define T33 _EQ( 'W' ) +#undef T34 + #define T34 _EQ( 'V' ) +#undef T35 + #define T35 _EQ( 'Z' ) + diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.RC b/platform/win/source-20220624-gerdLTGT/gerdLTGT.RC similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.RC rename to platform/win/source-20220624-gerdLTGT/gerdLTGT.RC diff --git a/platform/win/source-20220624-gerdLTGT/gerdLTGT.RC.bak00 b/platform/win/source-20220624-gerdLTGT/gerdLTGT.RC.bak00 new file mode 100644 index 0000000000000000000000000000000000000000..27f899a187f7d964ce29560b726988ad3e048970 GIT binary patch literal 2528 zcmc(gTWcCo6ovP5q5ol+zNC;gG4Z8P3b7iIPF2(hg+kD1jMPLK&F$a!TjzKjCoz;M zy)ewox$Lv|TKjh1*wk+9!e(}BBO6;}vE941J7%f9w<}g&+bb)v*SDH=tZNNxS(9(m zP8n%8V$`sN{k%-XPWF^+-wt_?dCQFa$u>G$R<$$xY`quG?>-r9o?`jL>LB~dziVHx zd1w#Vxnw7gFO&5$hii$TtHpW0BZPX&&vf+co3-I8kDP+}9Q4UEsVUoOFki z=iscdTY>!vKBzjR71rv`w;s2=S3!3R?}%3nz7>&C+$LC`61y?-H*lS=W92=*OH+tN zUZdyfxmIB8BOYXbtu09Q;gP^vo{7Obw`*J20Bn!s%7EFJ^?i236T@K&pDXfjNVZ+L zGY912Ez(1{&G{anGl6}===%%!g2p_C;GZg%muQ#Y7TBAj_hyYH#^1{IYlk!<4tMOP z%zl7#hV+CtvOO>@k-X$TV=jNE{8y|!I0;pbxI|zb!+D6r0GSah38P2mw@CaRhrUC( z%wZ3#W9n0WRdq$Kz9Ls)#Vjd{#3toGfa9*1DPocs{Ksr3vz3tY3`zZf#q#` z%AXWV1BXZ+9OA!-3Rit6>_%{w)nXhw=v2iFTr8ta<@oq-XU5+`kYIh{{HqFCz)D#; zA#YZj>WJalpm!+$rsVCIh$#1pac!+Nt5+zVp&B#`wfH=q#cbpwxI0ISW@n8|@ZHeo z_tSa4d-Y+HZnzcgg!z8aLzDW|5^pKxAyKCcWv5f8F)e53agPFWwWXh$DwF>kGQo-(jUjZb@q% z)xSjMeU~Bo^IccB#fsQP{4e=_v`=)T|INGfBqDj<{ti*6^BFgGx5XaWH{((L&#C_` U7sc+LwUnI^k=31}81Lr!6Hcr?$N&HU literal 0 HcmV?d00001 diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.klc b/platform/win/source-20220624-gerdLTGT/gerdLTGT.klc similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.klc rename to platform/win/source-20220624-gerdLTGT/gerdLTGT.klc diff --git a/platform/win/20220624-gerdLTGT/gerdLTGT.klc.bak00 b/platform/win/source-20220624-gerdLTGT/gerdLTGT.klc.bak00 similarity index 100% rename from platform/win/20220624-gerdLTGT/gerdLTGT.klc.bak00 rename to platform/win/source-20220624-gerdLTGT/gerdLTGT.klc.bak00 diff --git a/platform/win/source-20220624-gerdLTGT/make_pkg.sh b/platform/win/source-20220624-gerdLTGT/make_pkg.sh new file mode 100644 index 0000000..a8ea958 --- /dev/null +++ b/platform/win/source-20220624-gerdLTGT/make_pkg.sh @@ -0,0 +1,274 @@ +#!/bin/sh +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - +# FIXME generate new *.c *.h *.rc *.def +# /c/Program\ Files\ \(x86\)/Microsoft\ Keyboard\ Layout\ Creator\ 1.4/bin/i386/kbdutool.exe -v -w -a -n -s gerdLTGT.klc +# FIXME uninstall +# msiexec /x c:\Windows\Installer\ba87.msi DISABLEROLLBACK="1" /l*v! c:\mylog00.txt +# FIXME the layout not installed for all users +# installation property (global variable) ALLUSERS +# FIXME installed for each system32, syswow64 +# SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs +# FIXME unregister a DLL +# Regsvr32.exe /u msutb.dll +# FIXME layouts in registry +# HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\00000401 +# FIXME temporary "bad" solution +#reg query 'hklm\software\policies\microsoft\windows\installer' //v DisableRollback; echo $? +cat <<\END +REGEDIT4 + +[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer] +"DisableRollback"=- +END + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 +readonly TMPDIR_WIN="$(cmd.exe /c "echo %TEMP%")" + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken automatically into account as it should + readonly t="$(mktemp -p "$TMPDIR_WIN" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR_WIN" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # kbd layout uninstallation doesn't complete successfully if the DLL files + # are present + cat > "$a" < $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | + sed -r 's|^[^=]+=[^0-9]*([0-9]+).*|\1|')))" -ne 0 \ + -o "$c" -le 0 ]; then + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + +# FIXME +# INFO Waiting 10s... Keine Instanzen verf▒gbar. +# 9s... Keine Instanzen verf▒gbar. +# 8s... Keine Instanzen verf▒gbar. + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME avoid collision with the default MSKLC compile directory +readonly dockbd="$USERPROFILE\\documents\\$kbdname" +if [ -e "$dockbd" ]; then + mv "$dockbd" "${dockbd}-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry (for VBS)? +# FIXME open it with a different DLL directory than \Userprofile\Documents +#"$msklc/MSKLC.exe" "$layoutpath\\${kbdname}.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN_PREFIX="$(cmd.exe /c "echo %TEMP%")\\my_layout" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + defwow64= + outdir=i386 + fi + ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + defwow64= + outdir=amd64 + ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=IA64 + subsys_native_ver=5.02 + defwow64= + outdir=ia64 + ;; + esac + + printf '\nINFO Compiling DLL for %s...\n' "$outdir" + + # make traps local + ( + trap "rm -f '${TEMP_WIN_PREFIX}.res' '${TEMP_WIN_PREFIX}.obj'" \ + INT HUP TERM EXIT RETURN + # FIXME -DSTD_CALL + "$msklc\\bin\\i386\\rc.exe" -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST=0 -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 $defwow64 -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DRoster -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -i "$msklc\\inc" -fo "${TEMP_WIN_PREFIX}.res" "${kbdname}.rc" + + # FIXME -Gz (x86 only) + # -DSTD_CALL + # FIXME -EHs-c- + "$p\\cl.exe" -nologo -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST=0 -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 $defwow64 -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DRoster -DDEVL=1 -DFPO=1 -DNDEBUG -MD -c -Zp8 -Gy -W3 -WX -EHsc -GR- -GF -Z7 -Ox "-I$msklc\\inc" -Fo"${TEMP_WIN_PREFIX}.obj" "${kbdname}.c" + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + "$p\\link.exe" "-LIBPATH:$msklc\\lib\\$libdir" "-MACHINE:$machine" -nologo -noentry -OPT:REF -OPT:ICF -dll "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-DEF:${kbdname}.def" "-OUT:$outdir\\${kbdname}.dll" "${TEMP_WIN_PREFIX}.res" "${TEMP_WIN_PREFIX}.obj" + ) +done + +# FIXME debug +#cp "$layoutpath\\wow64\\${kbdname}.dll" 'C:\Users\JPa\Documents\gerdLTGT-2018-05-29-105034+02\wow64\' + +# vim: set wrap: diff --git a/platform/win/source-20220624-gerdLTGT/make_pkg.sh.bak00 b/platform/win/source-20220624-gerdLTGT/make_pkg.sh.bak00 new file mode 100644 index 0000000..a8ea958 --- /dev/null +++ b/platform/win/source-20220624-gerdLTGT/make_pkg.sh.bak00 @@ -0,0 +1,274 @@ +#!/bin/sh +# FIXME ULKL gerd +# Ctrl + s writes `=` in Excel instead of saving the file +# Shift + Del doesn't work in Windows (file) Explorer +# Ctrl + f doesn't work in nvim and in Chromium it triggers the built-in search instead of the "page down cVim function" +# Ctrl + Backspace sometimes doesn't delete word backwards (e.g. in notepad) +# Ctrl + at sign sometimes doesn't work (e.g. in nvim; but in notepad it works) +# is this because in gerdLTGT.klc is the third level in many cases disabled and if not, it doesn't produce the desired VK_xxx key? +# some apps seem to handle combinations themself and some rely on the resulting "character"/"abbreviation" provided by the operating system +# FIXME test +# Windows remote desktop - all 3 combinations (outside only, inside only, outside inside) +# Virtualbox - || - +# FIXME generate new *.c *.h *.rc *.def +# /c/Program\ Files\ \(x86\)/Microsoft\ Keyboard\ Layout\ Creator\ 1.4/bin/i386/kbdutool.exe -v -w -a -n -s gerdLTGT.klc +# FIXME uninstall +# msiexec /x c:\Windows\Installer\ba87.msi DISABLEROLLBACK="1" /l*v! c:\mylog00.txt +# FIXME the layout not installed for all users +# installation property (global variable) ALLUSERS +# FIXME installed for each system32, syswow64 +# SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDLLs +# FIXME unregister a DLL +# Regsvr32.exe /u msutb.dll +# FIXME layouts in registry +# HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layouts\00000401 +# FIXME temporary "bad" solution +#reg query 'hklm\software\policies\microsoft\windows\installer' //v DisableRollback; echo $? +cat <<\END +REGEDIT4 + +[HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer] +"DisableRollback"=- +END + +set -e + +readonly msklc='C:\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4' +readonly layoutpath="$(cd "$(dirname "$0")"; pwd)" +readonly kbdname="$(basename "$layoutpath")" +# Semver with the second part serving also the purpose of the missing last part +readonly my_ver=0.9 +readonly TMPDIR_WIN="$(cmd.exe /c "echo %TEMP%")" + +if [ ! -x "$msklc" ]; then + printf 'ERR %s\n' "$msklc" >&2 + printf 'ERR ^^^Could not open the MSKLC dir. Is MSKLC 1.4 installed?\n' "$msklc" >&2 + exit 1 +fi + +printf 'INFO Checking for files availability...\n' + +for f in \ + "$layoutpath\\${kbdname}.c" \ + "$layoutpath\\${kbdname}.def" \ + "$layoutpath\\${kbdname}.h" \ + "$layoutpath\\${kbdname}.klc" \ + "$layoutpath\\${kbdname}.rc"; do + if [ ! -r "$f" ]; then + printf 'ERR %s\n' "$f" >&2 + printf 'ERR ^^^Could not read the file. Make sure the filename without\n' >&2 + printf 'ERR extension matches the name of its parent directory).\n' >&2 + exit 1 + fi +done + +readonly productname_quoted="$( \ + grep -E '^[[:blank:]]*KBD' "$layoutpath\\${kbdname}.klc" | \ + sed -r 's|^[[:blank:]]*KBD[[:blank:]]+[^[:blank:]]+[[:blank:]]+||')" +if [ -z "$productname_quoted" ]; then + printf 'ERR Could not parse keyboard description from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi +readonly localeid="$(grep -E '^[[:blank:]]*LOCALEID' "$layoutpath\\${kbdname}.klc" | tr '[:upper:]' '[:lower:]' | sed -r 's|^[[:blank:]]*localeid[[:blank:]]+"0*([0-9]+).*|\1|')" +if [ -z "$localeid" ]; then + printf 'ERR Could not parse keyboard localeid from %s\n' "${kbdname}.klc" >&2 + exit 1 +fi + +# (\\CREED\ROOT\CIMV2:Win32_Product.IdentifyingNumber="{ACBB506E-BC38-45FA-BC22-6A6E2E1D9E81}",Name="German Dvorak ltgt (useful for text with lots of <>)",Version="1.0.3.40")->Uninstall() wird ausgeführt +# Methode wurde ausgeführt. +# Ausgabeparameter: +# instance of __PARAMETERS +# { +# ReturnValue = 1603; +# }; + +# run_elevated +run_elevated()( + [ $# -eq 1 ] || { + printf 'ERR run_elevated: one and only one param allowed\n' >&2 + exit 1 + } + [ -r "$1" ] || { + printf 'ERR run_elevated: executable not readable\n' >&2 + exit 1 + } + [ -n "$(printf %s "$1" | grep -E '/')" ] && { + printf 'ERR run_elevated: forward slash in path not allowed\n' >&2 + exit 1 + } + # VBS needs double quotes quoted by putting them twice + readonly x="$(printf %s "$1" | sed -r 's|"|""|g')" + # FIXME $TMPDIR not taken automatically into account as it should + readonly t="$(mktemp -p "$TMPDIR_WIN" --suffix .vbs run_elevated.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + trap "rm -f '$t'" INT HUP TERM EXIT + # printf %s 'CreateObject("Shell.Application").ShellExecute "'"$f2"'","","'"$TMP"'","runas",1' > "$f" + printf %s 'CreateObject("Shell.Application").ShellExecute "'"$x"'","","","runas",1' > "$t" + # cscript/wscript + # FIXME + printf '%s\n' "cscript $t" + cscript "$t" +) + +printf 'INFO Searching for conflicting keyboard layouts...\n' + +# list all installed apps: wmic product get name +# FIXME ! +if [ ! -n "$(wmic product where name="$productname_quoted")" ]; then + # win apps usually do not accept forward slashes + readonly a="$(mktemp -p "$TMPDIR_WIN" --suffix .cmd cmd_app.XXXXXXXXXXXXXXXX | sed -r 's|/|\\|g')" + readonly a_log="${a}.log" + + # make traps local + ( + trap "rm -f '$a'" INT HUP TERM EXIT RETURN + # kbd layout uninstallation doesn't complete successfully if the DLL files + # are present + cat > "$a" < $a_log" > "$a" + printf 'INFO Uninstalling conflicting keyboard layouts.\n' + # FIXME https://msdn.microsoft.com/en-us/library/xsy6k3ys(VS.85).aspx + run_elevated "$a" + + # due to deferred DB-operations etc. + printf 'INFO Waiting ' + c=10 + while printf '%ds... ' "$c"; do + if [ "$(($(grep -E ReturnValue "$a_log" 2>/dev/null | + sed -r 's|^[^=]+=[^0-9]*([0-9]+).*|\1|')))" -ne 0 \ + -o "$c" -le 0 ]; then + printf '\n%s\n' "ERR Couldn't uninstall the kbd layout \"$kbdname\"." >&2 + exit 1 + fi + +# FIXME +# INFO Waiting 10s... Keine Instanzen verf▒gbar. +# 9s... Keine Instanzen verf▒gbar. +# 8s... Keine Instanzen verf▒gbar. + # this takes time => no need for sleep 1 + [ -z "$(wmic product where name="$productname_quoted")" ] && break || true + c=$((c-1)) + done + printf '\n' + ) + + # FIXME unregister the DLL + # what about DLLs in use? restart needed (logout won't help as kbd layouts are also for the login page)? +cat >/dev/null <<\END +on error resume next +CreateObject( "Wscript.Shell" ).Run "wmic product where IdentifyingNumber="""{11D34ED0-8C85-4C7C-BCB8-59884CAC02FC}""" call uninstall", 1, true + +const hklm = &H80000002 +set reg = GetObject( "winmgmts:{impersonationLevel=impersonate}StdRegProv" ) +set fs = createobject( "Scripting.FileSystemObject" ) +for each s in array( "C:\Windows\System32\gerdLTGT.dll", "C:\Windows\SysWOW64\gerdLTGT.dll" ) + reg.DeleteValue hklm, "SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls\", s + fs.DeleteFile s, true + next +fs.DeleteFile "C:\Users\JPa\AppData\Local\Temp\marker.txt", true +END +fi + +# FIXME automatically in VBS (periodically check for MSKLC to appear and then try to click it)? +# FIXME can we lock the window to just a certain process for input? +printf '%s\n' "WARN Do not touch any input device (mouse, keyboard, ...)" >&2 +cat >&2 <<\END +INFO 1. wait for "Keyboard Layout Creator" window to appear +INFO 2. click "Project" in menu -> "Build DLL and Setup Package" +INFO 3. click "No" to disable viewing of "KeyboardVerify.log" +INFO 4. click "No" to disable opening of the Installer package directory +INFO 5. close the window of the "Keyboard Layout Creator" +END + +# FIXME avoid collision with the default MSKLC compile directory +readonly dockbd="$USERPROFILE\\documents\\$kbdname" +if [ -e "$dockbd" ]; then + mv "$dockbd" "${dockbd}-$(date +%F-%H%M%S%:::z)" +fi + +# FIXME open it with some other geometry (for VBS)? +# FIXME open it with a different DLL directory than \Userprofile\Documents +#"$msklc/MSKLC.exe" "$layoutpath\\${kbdname}.klc" + +printf '%s\n' "WARN You can freely use input devices (mouse, keyboard, ...) again" >&2 + +if [ -e "$USERPROFILE\\Documents\\KeyboardVerify.log" ]; then + rm "$USERPROFILE\\Documents\\KeyboardVerify.log" +fi + +cd "$layoutpath" +# can't use $TEMP as it's a virtual mountpoint (win apps see /tmp as C:\tmp) +readonly TEMP_WIN_PREFIX="$(cmd.exe /c "echo %TEMP%")\\my_layout" +idx=0 +for p in \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386" \ + "$msklc\\bin\\i386\\amd64" \ + "$msklc\\bin\\i386\\ia64"; do + # x86, wow64 (32bit on 64bit system), x86_64, ia64 (x86_64 Itanium) + case "$p" in + "$msklc\\bin\\i386") + libdir=i386 + machine=X86 + # https://docs.microsoft.com/de-de/cpp/build/reference/linker-options + subsys_native_ver=4.00 + # 32bit on 64bit systems + if [ "$idx" -eq 0 ]; then + idx=$((idx +1)) + defwow64=-DBUILD_WOW6432 + outdir=wow64 + else + defwow64= + outdir=i386 + fi + ;; + "$msklc\\bin\\i386\\amd64") + libdir=amd64 + machine=X64 + subsys_native_ver=5.02 + defwow64= + outdir=amd64 + ;; + "$msklc\\bin\\i386\\ia64") + libdir=ia64 + machine=IA64 + subsys_native_ver=5.02 + defwow64= + outdir=ia64 + ;; + esac + + printf '\nINFO Compiling DLL for %s...\n' "$outdir" + + # make traps local + ( + trap "rm -f '${TEMP_WIN_PREFIX}.res' '${TEMP_WIN_PREFIX}.obj'" \ + INT HUP TERM EXIT RETURN + # FIXME -DSTD_CALL + "$msklc\\bin\\i386\\rc.exe" -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST=0 -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 $defwow64 -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DRoster -DDEVL=1 -DFPO=1 -DNDEBUG -l "$localeid" -i "$msklc\\inc" -fo "${TEMP_WIN_PREFIX}.res" "${kbdname}.rc" + + # FIXME -Gz (x86 only) + # -DSTD_CALL + # FIXME -EHs-c- + "$p\\cl.exe" -nologo -DCONDITION_HANDLING=1 -DNT_UP=1 -DNT_INST=0 -DWIN32=1 -D_NT1X_=1 -DWINNT=1 -D_WIN32_WINNT=0x0500 -DWINVER=0x0400 -D_WIN32_IE=0x0400 -DWIN32_LEAN_AND_MEAN=1 $defwow64 -DNOGDICAPMASKS -DNOWINMESSAGES -DNOWINSTYLES -DNOSYSMETRICS -DNOMENUS -DNOICONS -DNOSYSCOMMANDS -DNORASTEROPS -DNOSHOWWINDOW -DOEMRESOURCE -DNOATOM -DNOCLIPBOARD -DNOCOLOR -DNOCTLMGR -DNODRAWTEXT -DNOGDI -DNOKERNEL -DNONLS -DNOMB -DNOMEMMGR -DNOMETAFILE -DNOMINMAX -DNOMSG -DNOOPENFILE -DNOSCROLL -DNOSERVICE -DNOSOUND -DNOTEXTMETRIC -DNOWINOFFSETS -DNOWH -DNOCOMM -DNOKANJI -DNOHELP -DNOPROFILER -DNODEFERWINDOWPOS -DNOMCX -DRoster -DDEVL=1 -DFPO=1 -DNDEBUG -MD -c -Zp8 -Gy -W3 -WX -EHsc -GR- -GF -Z7 -Ox "-I$msklc\\inc" -Fo"${TEMP_WIN_PREFIX}.obj" "${kbdname}.c" + + [ -e "$outdir" ] && rm -r "$outdir" + mkdir "$outdir" + + "$p\\link.exe" "-LIBPATH:$msklc\\lib\\$libdir" "-MACHINE:$machine" -nologo -noentry -OPT:REF -OPT:ICF -dll "-subsystem:native,$subsys_native_ver" -merge:.rdata=.text -PDBPATH:NONE -STACK:4096,1024 -opt:nowin98 "-version:$my_ver" -release -merge:.edata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text-merge:.edata=.data -merge:.srdata=.data -merge:.text=.data -merge:.bss=.data -section:.data,re -MERGE:_PAGE=PAGE -MERGE:_TEXT=.text "-DEF:${kbdname}.def" "-OUT:$outdir\\${kbdname}.dll" "${TEMP_WIN_PREFIX}.res" "${TEMP_WIN_PREFIX}.obj" + ) +done + +# FIXME debug +#cp "$layoutpath\\wow64\\${kbdname}.dll" 'C:\Users\JPa\Documents\gerdLTGT-2018-05-29-105034+02\wow64\' + +# vim: set wrap: diff --git a/platform/win/source-20220624-gerdLTGT/map_esc_to_caps_lock.reg b/platform/win/source-20220624-gerdLTGT/map_esc_to_caps_lock.reg new file mode 100644 index 0000000000000000000000000000000000000000..e3dbb29c105398c05eefda75701fdf4d250a86cf GIT binary patch literal 384 zcmb7=O>4qH6h+Tk=zkE`rTBrHf(r=+MWdjlB3eSLp$$kPQL+B{wkJVdxshS!&Hb2n zAM^J+BOzr?#*rOWCd7Qn?bwrZl6g^0M47nCn|iLAh*NQ!C+e;TD&=0#W8j-P5ktlV zbgdDgHBjp_Qe86DG3C{JC<-{(HMe(aQc(6T@-sHNV!6UoBwpC1DY5f?%6{lvJIm19 xNqo@tUQSc<^-4DN%=E;%Lh+Uw9lpgsJeTu7-gP#)?QdN9mMOPA^)p}m*gtwZIfDQI literal 0 HcmV?d00001 diff --git a/platform/win/source-20220624-gerdLTGT/map_esc_to_caps_lock.reg.bak00 b/platform/win/source-20220624-gerdLTGT/map_esc_to_caps_lock.reg.bak00 new file mode 100644 index 0000000000000000000000000000000000000000..e3dbb29c105398c05eefda75701fdf4d250a86cf GIT binary patch literal 384 zcmb7=O>4qH6h+Tk=zkE`rTBrHf(r=+MWdjlB3eSLp$$kPQL+B{wkJVdxshS!&Hb2n zAM^J+BOzr?#*rOWCd7Qn?bwrZl6g^0M47nCn|iLAh*NQ!C+e;TD&=0#W8j-P5ktlV zbgdDgHBjp_Qe86DG3C{JC<-{(HMe(aQc(6T@-sHNV!6UoBwpC1DY5f?%6{lvJIm19 xNqo@tUQSc<^-4DN%=E;%Lh+Uw9lpgsJeTu7-gP#)?QdN9mMOPA^)p}m*gtwZIfDQI literal 0 HcmV?d00001