x_keymap = cluster is load, getc, gets rep = null mapsub = 85 qb = sequence[bool] slmin = 192 slmap = qb$[true, % 0301 q true, % 0302 a true, % 0303 z false, % 0304 false, % 0305 2 true, % 0306 w true, % 0307 s true, % 0310 x false, % 0311 < false, % 0312 false, % 0313 3 true, % 0314 e true, % 0315 d true, % 0316 c false, % 0317 false, % 0320 4 true, % 0321 r true, % 0322 f true, % 0323 v false, % 0324 space false, % 0325 false, % 0326 5 true, % 0327 t true, % 0330 g true, % 0331 b false, % 0332 false, % 0333 6 true, % 0334 y true, % 0335 h true, % 0336 n false, % 0337 false, % 0340 7 true, % 0341 u true, % 0342 j true, % 0343 m false, % 0344 false, % 0345 8 true, % 0346 i true, % 0347 k false, % 0350 , false, % 0351 false, % 0352 9 true, % 0353 o true, % 0354 l false, % 0355 . false, % 0356 false, % 0357 0 true % 0360 p ] qs = sequence[string] % plain,S,M,M-S,C,C-S,C-M,C-M-S charmap = qs$[ "\330\330\330\330\330\330\330\330", % 0126 F1/Hold Screen "\324\324\324\324\324\324\324\324", % 0127 F2/Print Screen "\325\325\325\325\325\325\325\325", % 0130 F3/Set-Up "\326\326\326\326\326\326\326\326", % 0131 F4 "\327\327\327\327\327\327\327\327", % 0132 F5/Break "", % 0133 "", % 0134 "", % 0135 "", % 0136 "", % 0137 "", % 0140 "", % 0141 "", % 0142 "", % 0143 "\341\341\341\341\341\341\341\341", % 0144 F6 "\342\342\342\342\342\342\342\342", % 0145 F7 "\343\343\343\343\343\343\343\343", % 0146 F8 "\344\344\344\344\344\344\344\344", % 0147 F9 "\345\345\345\345\345\345\345\345", % 0150 F10 "", % 0151 "", % 0152 "", % 0153 "", % 0154 "", % 0155 "", % 0156 "", % 0157 "", % 0160 "\033\033\033\033\033\033\033\033", % 0161 F11/ESC "\b\b\210\210\b\b\210\210", % 0162 F12/BS "\n\n\212\212\n\n\212\212", % 0163 F13/LF "", % 0164 F14 "", % 0165 "", % 0166 "", % 0167 "", % 0170 "", % 0171 "", % 0172 "", % 0173 "", % 0174 Help/F15 "", % 0175 Do/F16 "", % 0176 "", % 0177 "\346\346\346\346\346\346\346\346", % 0200 F17 "\347\347\347\347\347\347\347\347", % 0201 F18 "\350\350\350\350\350\350\350\350", % 0202 F19 "\351\351\351\351\351\351\351\351", % 0203 F20/Hyph "", % 0204 "", % 0205 "", % 0206 "", % 0207 "", % 0210 "", % 0211 "\261\261\261\261\261\261\261\261", % 0212 Find "\262\262\262\262\262\262\262\262", % 0213 Insert "\263\263\263\263\263\263\263\263", % 0214 Remove "\264\264\264\264\264\264\264\264", % 0215 Select "\265\265\265\265\265\265\265\265", % 0216 Prev Screen "\266\266\266\266\266\266\266\266", % 0217 Next Screen "", % 0220 "", % 0221 "\360\360\360\360\360\360\360\360", % 0222 R0 "", % 0223 "\356\356\356\356\356\356\356\356", % 0224 R. "\315\315\315\315\315\315\315\315", % 0225 Enter "\361\361\361\361\361\361\361\361", % 0226 R1 "\362\362\362\362\362\362\362\362", % 0227 R2 "\363\363\363\363\363\363\363\363", % 0230 R3 "\364\364\364\364\364\364\364\364", % 0231 R4 "\365\365\365\365\365\365\365\365", % 0232 R5 "\366\366\366\366\366\366\366\366", % 0233 R6 "\354\354\354\354\354\354\354\354", % 0234 R, "\367\367\367\367\367\367\367\367", % 0235 R7 "\370\370\370\370\370\370\370\370", % 0236 R8 "\371\371\371\371\371\371\371\371", % 0237 R9 "\355\355\355\355\355\355\355\355", % 0240 R- "\320\320\320\320\320\320\320\320", % 0241 PF1 "\321\321\321\321\321\321\321\321", % 0242 PF2 "\322\322\322\322\322\322\322\322", % 0243 PF3 "\323\323\323\323\323\323\323\323", % 0244 PF4 "", % 0245 "", % 0246 "\304\304\304\304\304\304\304\304", % 0247 leftarrow "\303\303\303\303\303\303\303\303", % 0250 rightarrow "\302\302\302\302\302\302\302\302", % 0251 downarrow "\301\301\301\301\301\301\301\301", % 0252 uparrow "", % 0253 "", % 0254 "", % 0255 "", % 0256 Shift "", % 0257 Ctrl "", % 0260 Lock "", % 0261 Compose Character "", % 0262 "", % 0263 "", % 0264 "", % 0265 "", % 0266 "", % 0267 "", % 0270 "", % 0271 "", % 0272 "", % 0273 "\177\177\377\377\177\177\377\377", % 0274 back "\r\r\215\215\r\r\215\215", % 0275 Return "\t\t\211\211\t\t\211\211", % 0276 Tab "`~\340\376", % 0277 ` "1!\261\2411!", % 0300 1 "qQ\361\321\021\021\221\221", % 0301 q "aA\341\301\001\001\201\201", % 0302 a "zZ\372\332\032\032\232\232", % 0303 z "", % 0304 "2@\262\3002\000\262\200", % 0305 2 "wW\367\327\027\027\227\227", % 0306 w "sS\363\323\023\023\223\223", % 0307 s "xX\370\330\030\030\230\230", % 0310 x "<>\274\276", % 0311 < "", % 0312 "3#\263\2433#", % 0313 3 "eE\345\305\005\005\205\205", % 0314 e "dD\344\304\004\004\204\204", % 0315 d "cC\343\303\003\003\203\203", % 0316 c "", % 0317 "4$\264\2444$", % 0320 4 "rR\362\322\022\022\222\222", % 0321 r "fF\346\306\006\006\206\206", % 0322 f "vV\366\326\026\026\226\226", % 0323 v " \240\240\000\000\200\200", % 0324 space "", % 0325 "5%\265\2455%", % 0326 5 "tT\364\324\024\024\224\224", % 0327 t "gG\347\307\007\007\207\207", % 0330 g "bB\342\302\002\002\202\202", % 0331 b "", % 0332 "6^\266\3366\036\266\236", % 0333 6 "yY\371\331\031\031\231\231", % 0334 y "hH\350\310\010\010\210\210", % 0335 h "nN\356\316\016\016\216\216", % 0336 n "", % 0337 "7&\267\2467&", % 0340 7 "uU\365\325\025\025\225\225", % 0341 u "jJ\352\312\012\012\212\212", % 0342 j "mM\355\315\015\015\215\215", % 0343 m "", % 0344 "8*\270\2528*", % 0345 8 "iI\351\311\011\011\211\211", % 0346 i "kK\353\313\013\013\213\213", % 0347 k ",<\254\274", % 0350 , "", % 0351 "9(\271\2509(", % 0352 9 "oO\357\317\017\017\217\217", % 0353 o "lL\354\314\014\014\214\214", % 0354 l ".>\256\276", % 0355 . "", % 0356 "0)\260\2510(", % 0357 0 "pP\360\320\020\020\220\220", % 0360 p "", % 0361 ";:\273\272", % 0362 ; "/?\257\277\037\037\237\237", % 0363 / "", % 0364 "=+\275\253", % 0365 = "]}\335\375\035\035\235\235", % 0366 ] "\\|\334\374\034\034\234\234", % 0367 \ "", % 0370 "-_\255\337-\037\255\237", % 0371 - "[{\333\373\033\033\233\233", % 0372 [ "'\"\247\242" % 0373 ' ] multilist = array[multi] multi = record[key: int, mask: int, value: string] own havemap: bool := false own keymap: _bytevec own multis: multilist load = proc (fs: string) if string$empty(fs) then fs := ".Xkeymap" end begin fn: file_name := file_name$parse(fs) if string$empty(fn.dir) then fn := file_name$create(_environ("HOME"), fn.name, fn.suffix, fn.other) end c: _chan := _chan$open(fn, "read", 0) if _chan$getc(c, false) ~= '\372' then _chan$close(c) return end keymap := _bytevec$create(c.length - 1) _chan$getb(c, keymap) _chan$close(c) havemap := _bytevec$size(keymap) >= 4096 multis := multilist$new() i: int := 4097 while true do multilist$addh(multis, multi${key: char$c2i(keymap[i]), mask: char$c2i(keymap[i + 1]), value: string$substr(_cvt[_bytevec, string]( keymap), i + 3, char$c2i(keymap[i + 2]))}) i := i + 3 + char$c2i(keymap[i + 2]) end end except others: end end load getc = proc (key, mask: int) returns (char) signals (none, multi(string)) if havemap then mask := mask / 2**11 c: char := keymap[(key * 16) + mask + 1] if c < '\375' then return(c) end if c = '\376' then for m: multi in multilist$elements(multis) do if key = m.key cand (mask = m.mask cor m.mask = 255) then if string$size(m.value) = 1 then return(m.value[1]) end if string$empty(m.value) then signal none end signal multi(m.value) end end end signal none end except when bounds: signal none end key := key - mapsub keymode: int := mask / 2**12 + 1 if (mask / 2**11) // 4 = 1 cand slmap[key + (mapsub - slmin)] then keymode := keymode + 1 end except when bounds: end return(charmap[key][keymode]) except when bounds: signal none end end getc gets = proc (key, mask: int) returns (string) signals (none) if havemap then mask := mask / 2**11 c: char := keymap[(key * 16) + mask + 1] if c < '\375' then return(string$c2s(c)) end if c = '\376' then for m: multi in multilist$elements(multis) do if key = m.key cand (mask = m.mask cor m.mask = 255) then if string$empty(m.value) then signal none end return(m.value) end end end signal none end except when bounds: signal none end key := key - mapsub keymode: int := mask / 2**12 + 1 if (mask / 2**11) // 4 = 1 cand slmap[key + (mapsub - slmin)] then keymode := keymode + 1 end except when bounds: end return(string$c2s(charmap[key][keymode])) except when bounds: signal none end end gets end x_keymap