keyboard.pp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2006 by Karoly Balogh
  4. Keyboard unit for MorphOS and Amiga
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit Keyboard;
  12. interface
  13. {$ifdef DEBUG}
  14. //uses
  15. // windows;
  16. //var
  17. // last_ir : Input_Record;
  18. {$endif DEBUG}
  19. {$i keybrdh.inc}
  20. implementation
  21. { WARNING: Keyboard-Drivers (i.e. german) will only work under WinNT.
  22. 95 and 98 do not support keyboard-drivers other than us for win32
  23. console-apps. So we always get the keys in us-keyboard layout
  24. from Win9x.
  25. }
  26. //uses
  27. {ifndef DEBUG}
  28. // Windows,
  29. {endif DEBUG}
  30. // Dos,
  31. // WinEvent;
  32. uses
  33. video,
  34. exec,intuition, inputevent;
  35. {$i keyboard.inc}
  36. var
  37. lastShiftState : byte; {set by handler for PollShiftStateEvent}
  38. {*
  39. const MaxQueueSize = 120;
  40. FrenchKeyboard = $040C040C;
  41. var
  42. keyboardeventqueue : array[0..maxqueuesize] of TKeyEventRecord;
  43. nextkeyevent,nextfreekeyevent : longint;
  44. newKeyEvent : THandle; {sinaled if key is available}
  45. lockVar : TCriticalSection; {for queue access}
  46. lastShiftState : byte; {set by handler for PollShiftStateEvent}
  47. altNumActive : boolean; {for alt+0..9}
  48. altNumBuffer : string [3];
  49. { used for keyboard specific stuff }
  50. KeyBoardLayout : HKL;
  51. Inited : Boolean;
  52. HasAltGr : Boolean = false;
  53. procedure incqueueindex(var l : longint);
  54. begin
  55. inc(l);
  56. { wrap around? }
  57. if l>maxqueuesize then
  58. l:=0;
  59. end;
  60. function keyEventsInQueue : boolean;
  61. begin
  62. keyEventsInQueue := (nextkeyevent <> nextfreekeyevent);
  63. end;
  64. function rightistruealt(dw:cardinal):boolean; // inline ?
  65. // used to wrap checks for right alt/altgr.
  66. begin
  67. rightistruealt:=true;
  68. if hasaltgr then
  69. rightistruealt:=(dw and RIGHT_ALT_PRESSED)=0;
  70. end;
  71. { gets or peeks the next key from the queue, does not wait for new keys }
  72. function getKeyEventFromQueue (VAR t : TKeyEventRecord; Peek : boolean) : boolean;
  73. begin
  74. if not Inited then
  75. begin
  76. getKeyEventFromQueue := false;
  77. exit;
  78. end;
  79. EnterCriticalSection (lockVar);
  80. if keyEventsInQueue then
  81. begin
  82. t := keyboardeventqueue[nextkeyevent];
  83. if not peek then incqueueindex (nextkeyevent);
  84. getKeyEventFromQueue := true;
  85. if not keyEventsInQueue then ResetEvent (newKeyEvent);
  86. end else
  87. begin
  88. getKeyEventFromQueue := false;
  89. ResetEvent (newKeyEvent);
  90. end;
  91. LeaveCriticalSection (lockVar);
  92. end;
  93. { gets the next key from the queue, does wait for new keys }
  94. function getKeyEventFromQueueWait (VAR t : TKeyEventRecord) : boolean;
  95. begin
  96. if not Inited then
  97. begin
  98. getKeyEventFromQueueWait := false;
  99. exit;
  100. end;
  101. WaitForSingleObject (newKeyEvent, dword(INFINITE));
  102. getKeyEventFromQueueWait := getKeyEventFromQueue (t, false);
  103. end;
  104. { translate win32 shift-state to keyboard shift state }
  105. function transShiftState (ControlKeyState : dword) : byte;
  106. var b : byte;
  107. begin
  108. b := 0;
  109. if ControlKeyState and SHIFT_PRESSED <> 0 then { win32 makes no difference between left and right shift }
  110. b := b or kbShift;
  111. if (ControlKeyState and LEFT_CTRL_PRESSED <> 0) or
  112. (ControlKeyState and RIGHT_CTRL_PRESSED <> 0) then
  113. b := b or kbCtrl;
  114. if (ControlKeyState and LEFT_ALT_PRESSED <> 0) or
  115. (ControlKeyState and RIGHT_ALT_PRESSED <> 0) then
  116. b := b or kbAlt;
  117. transShiftState := b;
  118. end;
  119. { The event-Handler thread from the unit event will call us if a key-event
  120. is available }
  121. procedure HandleKeyboard(var ir:INPUT_RECORD);
  122. var
  123. i : longint;
  124. c : word;
  125. altc : char;
  126. addThis: boolean;
  127. begin
  128. with ir.Event.KeyEvent do
  129. begin
  130. { key up events are ignored (except alt) }
  131. if bKeyDown then
  132. begin
  133. EnterCriticalSection (lockVar);
  134. for i:=1 to wRepeatCount do
  135. begin
  136. addThis := true;
  137. if (dwControlKeyState and LEFT_ALT_PRESSED <> 0) or
  138. (dwControlKeyState and RIGHT_ALT_PRESSED <> 0) then {alt pressed}
  139. if ((wVirtualKeyCode >= $60) and (wVirtualKeyCode <= $69)) or
  140. ((dwControlKeyState and ENHANCED_KEY = 0) and
  141. (wVirtualKeyCode in [$C{VK_CLEAR generated by keypad 5},
  142. $21 {VK_PRIOR (PgUp) 9},
  143. $22 {VK_NEXT (PgDown) 3},
  144. $23 {VK_END 1},
  145. $24 {VK_HOME 7},
  146. $25 {VK_LEFT 4},
  147. $26 {VK_UP 8},
  148. $27 {VK_RIGHT 6},
  149. $28 {VK_DOWN 2},
  150. $2D {VK_INSERT 0}])) then {0..9 on NumBlock}
  151. begin
  152. if length (altNumBuffer) = 3 then
  153. delete (altNumBuffer,1,1);
  154. case wVirtualKeyCode of
  155. $60..$69 : altc:=char (wVirtualKeyCode-48);
  156. $c : altc:='5';
  157. $21 : altc:='9';
  158. $22 : altc:='3';
  159. $23 : altc:='1';
  160. $24 : altc:='7';
  161. $25 : altc:='4';
  162. $26 : altc:='8';
  163. $27 : altc:='6';
  164. $28 : altc:='2';
  165. $2D : altc:='0';
  166. end;
  167. altNumBuffer := altNumBuffer + altc;
  168. altNumActive := true;
  169. addThis := false;
  170. end else
  171. begin
  172. altNumActive := false;
  173. altNumBuffer := '';
  174. end;
  175. if addThis then
  176. begin
  177. keyboardeventqueue[nextfreekeyevent]:=
  178. ir.Event.KeyEvent;
  179. incqueueindex(nextfreekeyevent);
  180. end;
  181. end;
  182. lastShiftState := transShiftState (dwControlKeyState); {save it for PollShiftStateEvent}
  183. SetEvent (newKeyEvent); {event that a new key is available}
  184. LeaveCriticalSection (lockVar);
  185. end
  186. else
  187. begin
  188. lastShiftState := transShiftState (dwControlKeyState); {save it for PollShiftStateEvent}
  189. {for alt-number we have to look for alt-key release}
  190. if altNumActive then
  191. begin
  192. if (wVirtualKeyCode = $12) then {alt-released}
  193. begin
  194. if altNumBuffer <> '' then {numbers with alt pressed?}
  195. begin
  196. Val (altNumBuffer, c, i);
  197. if (i = 0) and (c <= 255) then {valid number?}
  198. begin {add to queue}
  199. fillchar (ir, sizeof (ir), 0);
  200. bKeyDown := true;
  201. AsciiChar := char (c);
  202. {and add to queue}
  203. EnterCriticalSection (lockVar);
  204. keyboardeventqueue[nextfreekeyevent]:=ir.Event.KeyEvent;
  205. incqueueindex(nextfreekeyevent);
  206. SetEvent (newKeyEvent); {event that a new key is available}
  207. LeaveCriticalSection (lockVar);
  208. end;
  209. end;
  210. altNumActive := false; {clear alt-buffer}
  211. altNumBuffer := '';
  212. end;
  213. end;
  214. end;
  215. end;
  216. end;
  217. *}
  218. {*
  219. procedure CheckAltGr;
  220. var ahkl : HKL;
  221. i : integer;
  222. begin
  223. HasAltGr:=false;
  224. ahkl:=GetKeyboardLayout(0);
  225. i:=$20;
  226. while i<$100 do
  227. begin
  228. // <MSDN>
  229. // For keyboard layouts that use the right-hand ALT key as ashift key
  230. // (for example, the French keyboard layout), the shift state is
  231. // represented by the value 6, because the right-hand ALT key is
  232. // converted internally into CTRL+ALT.
  233. // </MSDN>
  234. if (HIBYTE(VkKeyScanEx(chr(i),ahkl))=6) then
  235. begin
  236. HasAltGr:=true;
  237. break;
  238. end;
  239. inc(i);
  240. end;
  241. end;
  242. *}
  243. procedure SysInitKeyboard;
  244. begin
  245. // writeln('sysinitkeyboard');
  246. lastShiftState:=0;
  247. {*
  248. KeyBoardLayout:=GetKeyboardLayout(0);
  249. lastShiftState := 0;
  250. FlushConsoleInputBuffer(StdInputHandle);
  251. newKeyEvent := CreateEvent (nil, // address of security attributes
  252. true, // flag for manual-reset event
  253. false, // flag for initial state
  254. nil); // address of event-object name
  255. if newKeyEvent = INVALID_HANDLE_VALUE then
  256. begin
  257. // what to do here ????
  258. RunError (217);
  259. end;
  260. InitializeCriticalSection (lockVar);
  261. altNumActive := false;
  262. altNumBuffer := '';
  263. nextkeyevent:=0;
  264. nextfreekeyevent:=0;
  265. checkaltgr;
  266. SetKeyboardEventHandler (@HandleKeyboard);
  267. Inited:=true;
  268. *}
  269. end;
  270. procedure SysDoneKeyboard;
  271. begin
  272. {*
  273. SetKeyboardEventHandler(nil); {hangs???}
  274. DeleteCriticalSection (lockVar);
  275. FlushConsoleInputBuffer(StdInputHandle);
  276. closeHandle (newKeyEvent);
  277. Inited:=false;
  278. *}
  279. end;
  280. {$define USEKEYCODES}
  281. {Translatetable Win32 -> Dos for Special Keys = Function Key, Cursor Keys
  282. and Keys other than numbers on numblock (to make fv happy) }
  283. {combinations under dos: Shift+Ctrl: same as Ctrl
  284. Shift+Alt : same as alt
  285. {* Ctrl+Alt : nothing (here we get it like alt)}
  286. {ifdef USEKEYCODES}
  287. { use positive values for ScanCode we want to set
  288. 0 for key where we should leave the scancode
  289. -1 for OEM specifc keys
  290. -2 for unassigned
  291. -3 for Kanji systems ???
  292. }
  293. const
  294. Unassigned = -2;
  295. Kanji = -3;
  296. OEM_specific = -1;
  297. KeyToQwertyScan : array [0..255] of integer =
  298. (
  299. { 00 } 0,
  300. { 01 VK_LBUTTON } 0,
  301. { 02 VK_RBUTTON } 0,
  302. { 03 VK_CANCEL } 0,
  303. { 04 VK_MBUTTON } 0,
  304. { 05 unassigned } -2,
  305. { 06 unassigned } -2,
  306. { 07 unassigned } -2,
  307. { 08 VK_BACK } $E,
  308. { 09 VK_TAB } $F,
  309. { 0A unassigned } -2,
  310. { 0B unassigned } -2,
  311. { 0C VK_CLEAR ?? } 0,
  312. { 0D VK_RETURN } 0,
  313. { 0E unassigned } -2,
  314. { 0F unassigned } -2,
  315. { 10 VK_SHIFT } 0,
  316. { 11 VK_CONTROL } 0,
  317. { 12 VK_MENU (Alt key) } 0,
  318. { 13 VK_PAUSE } 0,
  319. { 14 VK_CAPITAL (Caps Lock) } 0,
  320. { 15 Reserved for Kanji systems} -3,
  321. { 16 Reserved for Kanji systems} -3,
  322. { 17 Reserved for Kanji systems} -3,
  323. { 18 Reserved for Kanji systems} -3,
  324. { 19 Reserved for Kanji systems} -3,
  325. { 1A unassigned } -2,
  326. { 1B VK_ESCAPE } $1,
  327. { 1C Reserved for Kanji systems} -3,
  328. { 1D Reserved for Kanji systems} -3,
  329. { 1E Reserved for Kanji systems} -3,
  330. { 1F Reserved for Kanji systems} -3,
  331. { 20 VK_SPACE} 0,
  332. { 21 VK_PRIOR (PgUp) } 0,
  333. { 22 VK_NEXT (PgDown) } 0,
  334. { 23 VK_END } 0,
  335. { 24 VK_HOME } 0,
  336. { 25 VK_LEFT } 0,
  337. { 26 VK_UP } 0,
  338. { 27 VK_RIGHT } 0,
  339. { 28 VK_DOWN } 0,
  340. { 29 VK_SELECT ??? } 0,
  341. { 2A OEM specific !! } -1,
  342. { 2B VK_EXECUTE } 0,
  343. { 2C VK_SNAPSHOT } 0,
  344. { 2D VK_INSERT } 0,
  345. { 2E VK_DELETE } 0,
  346. { 2F VK_HELP } 0,
  347. { 30 VK_0 '0' } 11,
  348. { 31 VK_1 '1' } 2,
  349. { 32 VK_2 '2' } 3,
  350. { 33 VK_3 '3' } 4,
  351. { 34 VK_4 '4' } 5,
  352. { 35 VK_5 '5' } 6,
  353. { 36 VK_6 '6' } 7,
  354. { 37 VK_7 '7' } 8,
  355. { 38 VK_8 '8' } 9,
  356. { 39 VK_9 '9' } 10,
  357. { 3A unassigned } -2,
  358. { 3B unassigned } -2,
  359. { 3C unassigned } -2,
  360. { 3D unassigned } -2,
  361. { 3E unassigned } -2,
  362. { 3F unassigned } -2,
  363. { 40 unassigned } -2,
  364. { 41 VK_A 'A' } $1E,
  365. { 42 VK_B 'B' } $30,
  366. { 43 VK_C 'C' } $2E,
  367. { 44 VK_D 'D' } $20,
  368. { 45 VK_E 'E' } $12,
  369. { 46 VK_F 'F' } $21,
  370. { 47 VK_G 'G' } $22,
  371. { 48 VK_H 'H' } $23,
  372. { 49 VK_I 'I' } $17,
  373. { 4A VK_J 'J' } $24,
  374. { 4B VK_K 'K' } $25,
  375. { 4C VK_L 'L' } $26,
  376. { 4D VK_M 'M' } $32,
  377. { 4E VK_N 'N' } $31,
  378. { 4F VK_O 'O' } $18,
  379. { 50 VK_P 'P' } $19,
  380. { 51 VK_Q 'Q' } $10,
  381. { 52 VK_R 'R' } $13,
  382. { 53 VK_S 'S' } $1F,
  383. { 54 VK_T 'T' } $14,
  384. { 55 VK_U 'U' } $16,
  385. { 56 VK_V 'V' } $2F,
  386. { 57 VK_W 'W' } $11,
  387. { 58 VK_X 'X' } $2D,
  388. { 59 VK_Y 'Y' } $15,
  389. { 5A VK_Z 'Z' } $2C,
  390. { 5B unassigned } -2,
  391. { 5C unassigned } -2,
  392. { 5D unassigned } -2,
  393. { 5E unassigned } -2,
  394. { 5F unassigned } -2,
  395. { 60 VK_NUMPAD0 NumKeyPad '0' } 11,
  396. { 61 VK_NUMPAD1 NumKeyPad '1' } 2,
  397. { 62 VK_NUMPAD2 NumKeyPad '2' } 3,
  398. { 63 VK_NUMPAD3 NumKeyPad '3' } 4,
  399. { 64 VK_NUMPAD4 NumKeyPad '4' } 5,
  400. { 65 VK_NUMPAD5 NumKeyPad '5' } 6,
  401. { 66 VK_NUMPAD6 NumKeyPad '6' } 7,
  402. { 67 VK_NUMPAD7 NumKeyPad '7' } 8,
  403. { 68 VK_NUMPAD8 NumKeyPad '8' } 9,
  404. { 69 VK_NUMPAD9 NumKeyPad '9' } 10,
  405. { 6A VK_MULTIPLY } 0,
  406. { 6B VK_ADD } 0,
  407. { 6C VK_SEPARATOR } 0,
  408. { 6D VK_SUBSTRACT } 0,
  409. { 6E VK_DECIMAL } 0,
  410. { 6F VK_DIVIDE } 0,
  411. { 70 VK_F1 'F1' } $3B,
  412. { 71 VK_F2 'F2' } $3C,
  413. { 72 VK_F3 'F3' } $3D,
  414. { 73 VK_F4 'F4' } $3E,
  415. { 74 VK_F5 'F5' } $3F,
  416. { 75 VK_F6 'F6' } $40,
  417. { 76 VK_F7 'F7' } $41,
  418. { 77 VK_F8 'F8' } $42,
  419. { 78 VK_F9 'F9' } $43,
  420. { 79 VK_F10 'F10' } $44,
  421. { 7A VK_F11 'F11' } $57,
  422. { 7B VK_F12 'F12' } $58,
  423. { 7C VK_F13 } 0,
  424. { 7D VK_F14 } 0,
  425. { 7E VK_F15 } 0,
  426. { 7F VK_F16 } 0,
  427. { 80 VK_F17 } 0,
  428. { 81 VK_F18 } 0,
  429. { 82 VK_F19 } 0,
  430. { 83 VK_F20 } 0,
  431. { 84 VK_F21 } 0,
  432. { 85 VK_F22 } 0,
  433. { 86 VK_F23 } 0,
  434. { 87 VK_F24 } 0,
  435. { 88 unassigned } -2,
  436. { 89 VK_NUMLOCK } 0,
  437. { 8A VK_SCROLL } 0,
  438. { 8B unassigned } -2,
  439. { 8C unassigned } -2,
  440. { 8D unassigned } -2,
  441. { 8E unassigned } -2,
  442. { 8F unassigned } -2,
  443. { 90 unassigned } -2,
  444. { 91 unassigned } -2,
  445. { 92 unassigned } -2,
  446. { 93 unassigned } -2,
  447. { 94 unassigned } -2,
  448. { 95 unassigned } -2,
  449. { 96 unassigned } -2,
  450. { 97 unassigned } -2,
  451. { 98 unassigned } -2,
  452. { 99 unassigned } -2,
  453. { 9A unassigned } -2,
  454. { 9B unassigned } -2,
  455. { 9C unassigned } -2,
  456. { 9D unassigned } -2,
  457. { 9E unassigned } -2,
  458. { 9F unassigned } -2,
  459. { A0 unassigned } -2,
  460. { A1 unassigned } -2,
  461. { A2 unassigned } -2,
  462. { A3 unassigned } -2,
  463. { A4 unassigned } -2,
  464. { A5 unassigned } -2,
  465. { A6 unassigned } -2,
  466. { A7 unassigned } -2,
  467. { A8 unassigned } -2,
  468. { A9 unassigned } -2,
  469. { AA unassigned } -2,
  470. { AB unassigned } -2,
  471. { AC unassigned } -2,
  472. { AD unassigned } -2,
  473. { AE unassigned } -2,
  474. { AF unassigned } -2,
  475. { B0 unassigned } -2,
  476. { B1 unassigned } -2,
  477. { B2 unassigned } -2,
  478. { B3 unassigned } -2,
  479. { B4 unassigned } -2,
  480. { B5 unassigned } -2,
  481. { B6 unassigned } -2,
  482. { B7 unassigned } -2,
  483. { B8 unassigned } -2,
  484. { B9 unassigned } -2,
  485. { BA OEM specific } 0,
  486. { BB OEM specific } 0,
  487. { BC OEM specific } 0,
  488. { BD OEM specific } 0,
  489. { BE OEM specific } 0,
  490. { BF OEM specific } 0,
  491. { C0 OEM specific } 0,
  492. { C1 unassigned } -2,
  493. { C2 unassigned } -2,
  494. { C3 unassigned } -2,
  495. { C4 unassigned } -2,
  496. { C5 unassigned } -2,
  497. { C6 unassigned } -2,
  498. { C7 unassigned } -2,
  499. { C8 unassigned } -2,
  500. { C9 unassigned } -2,
  501. { CA unassigned } -2,
  502. { CB unassigned } -2,
  503. { CC unassigned } -2,
  504. { CD unassigned } -2,
  505. { CE unassigned } -2,
  506. { CF unassigned } -2,
  507. { D0 unassigned } -2,
  508. { D1 unassigned } -2,
  509. { D2 unassigned } -2,
  510. { D3 unassigned } -2,
  511. { D4 unassigned } -2,
  512. { D5 unassigned } -2,
  513. { D6 unassigned } -2,
  514. { D7 unassigned } -2,
  515. { D8 unassigned } -2,
  516. { D9 unassigned } -2,
  517. { DA unassigned } -2,
  518. { DB OEM specific } 0,
  519. { DC OEM specific } 0,
  520. { DD OEM specific } 0,
  521. { DE OEM specific } 0,
  522. { DF OEM specific } 0,
  523. { E0 OEM specific } 0,
  524. { E1 OEM specific } 0,
  525. { E2 OEM specific } 0,
  526. { E3 OEM specific } 0,
  527. { E4 OEM specific } 0,
  528. { E5 unassigned } -2,
  529. { E6 OEM specific } 0,
  530. { E7 unassigned } -2,
  531. { E8 unassigned } -2,
  532. { E9 OEM specific } 0,
  533. { EA OEM specific } 0,
  534. { EB OEM specific } 0,
  535. { EC OEM specific } 0,
  536. { ED OEM specific } 0,
  537. { EE OEM specific } 0,
  538. { EF OEM specific } 0,
  539. { F0 OEM specific } 0,
  540. { F1 OEM specific } 0,
  541. { F2 OEM specific } 0,
  542. { F3 OEM specific } 0,
  543. { F4 OEM specific } 0,
  544. { F5 OEM specific } 0,
  545. { F6 unassigned } -2,
  546. { F7 unassigned } -2,
  547. { F8 unassigned } -2,
  548. { F9 unassigned } -2,
  549. { FA unassigned } -2,
  550. { FB unassigned } -2,
  551. { FC unassigned } -2,
  552. { FD unassigned } -2,
  553. { FE unassigned } -2,
  554. { FF unassigned } -2
  555. );
  556. {$endif USEKEYCODES}
  557. type TTEntryT = packed record
  558. n,s,c,a : byte; {normal,shift, ctrl, alt, normal only for f11,f12}
  559. end;
  560. *}
  561. {*
  562. CONST
  563. DosTT : ARRAY [$3B..$58] OF TTEntryT =
  564. ((n : $3B; s : $54; c : $5E; a: $68), {3B F1}
  565. (n : $3C; s : $55; c : $5F; a: $69), {3C F2}
  566. (n : $3D; s : $56; c : $60; a: $6A), {3D F3}
  567. (n : $3E; s : $57; c : $61; a: $6B), {3E F4}
  568. (n : $3F; s : $58; c : $62; a: $6C), {3F F5}
  569. (n : $40; s : $59; c : $63; a: $6D), {40 F6}
  570. (n : $41; s : $5A; c : $64; a: $6E), {41 F7}
  571. (n : $42; s : $5B; c : $65; a: $6F), {42 F8}
  572. (n : $43; s : $5C; c : $66; a: $70), {43 F9}
  573. (n : $44; s : $5D; c : $67; a: $71), {44 F10}
  574. (n : $45; s : $00; c : $00; a: $00), {45 ???}
  575. (n : $46; s : $00; c : $00; a: $00), {46 ???}
  576. (n : $47; s : $47; c : $77; a: $97), {47 Home}
  577. (n : $48; s : $00; c : $8D; a: $98), {48 Up}
  578. (n : $49; s : $49; c : $84; a: $99), {49 PgUp}
  579. (n : $4A; s : $00; c : $8E; a: $4A), {4A -}
  580. (n : $4B; s : $4B; c : $73; a: $9B), {4B Left}
  581. (n : $4C; s : $00; c : $00; a: $00), {4C ???}
  582. (n : $4D; s : $4D; c : $74; a: $9D), {4D Right}
  583. (n : $4E; s : $00; c : $90; a: $4E), {4E +}
  584. (n : $4F; s : $4F; c : $75; a: $9F), {4F End}
  585. (n : $50; s : $50; c : $91; a: $A0), {50 Down}
  586. (n : $51; s : $51; c : $76; a: $A1), {51 PgDown}
  587. (n : $52; s : $52; c : $92; a: $A2), {52 Insert}
  588. (n : $53; s : $53; c : $93; a: $A3), {53 Del}
  589. (n : $54; s : $00; c : $00; a: $00), {54 ???}
  590. (n : $55; s : $00; c : $00; a: $00), {55 ???}
  591. (n : $56; s : $00; c : $00; a: $00), {56 ???}
  592. (n : $85; s : $87; c : $89; a: $8B), {57 F11}
  593. (n : $86; s : $88; c : $8A; a: $8C)); {58 F12}
  594. DosTT09 : ARRAY [$02..$0F] OF TTEntryT =
  595. ((n : $00; s : $00; c : $00; a: $78), {02 1 }
  596. (n : $00; s : $00; c : $00; a: $79), {03 2 }
  597. (n : $00; s : $00; c : $00; a: $7A), {04 3 }
  598. (n : $00; s : $00; c : $00; a: $7B), {05 4 }
  599. (n : $00; s : $00; c : $00; a: $7C), {06 5 }
  600. (n : $00; s : $00; c : $00; a: $7D), {07 6 }
  601. (n : $00; s : $00; c : $00; a: $7E), {08 7 }
  602. (n : $00; s : $00; c : $00; a: $7F), {09 8 }
  603. (n : $00; s : $00; c : $00; a: $80), {0A 9 }
  604. (n : $00; s : $00; c : $00; a: $81), {0B 0 }
  605. (n : $00; s : $00; c : $00; a: $82), {0C ß }
  606. (n : $00; s : $00; c : $00; a: $00), {0D}
  607. (n : $00; s : $09; c : $00; a: $00), {0E Backspace}
  608. (n : $00; s : $0F; c : $94; a: $00)); {0F Tab }
  609. *}
  610. {*
  611. function TranslateKey (t : TKeyEventRecord) : TKeyEvent;
  612. var key : TKeyEvent;
  613. ss : byte;
  614. {$ifdef USEKEYCODES}
  615. ScanCode : byte;
  616. {$endif USEKEYCODES}
  617. b : byte;
  618. begin
  619. Key := 0;
  620. if t.bKeyDown then
  621. begin
  622. { ascii-char is <> 0 if not a specal key }
  623. { we return it here otherwise we have to translate more later }
  624. if t.AsciiChar <> #0 then
  625. begin
  626. if (t.dwControlKeyState and ENHANCED_KEY <> 0) and
  627. (t.wVirtualKeyCode = $DF) then
  628. begin
  629. t.dwControlKeyState:=t.dwControlKeyState and not ENHANCED_KEY;
  630. t.wVirtualKeyCode:=VK_DIVIDE;
  631. t.AsciiChar:='/';
  632. end;
  633. {drivers needs scancode, we return it here as under dos and linux
  634. with $03000000 = the lowest two bytes is the physical representation}
  635. {$ifdef USEKEYCODES}
  636. Scancode:=KeyToQwertyScan[t.wVirtualKeyCode AND $00FF];
  637. If ScanCode>0 then
  638. t.wVirtualScanCode:=ScanCode;
  639. Key := byte (t.AsciiChar) + (t.wVirtualScanCode shl 8) + $03000000;
  640. ss := transShiftState (t.dwControlKeyState);
  641. key := key or (ss shl 16);
  642. if (ss and kbAlt <> 0) and rightistruealt(t.dwControlKeyState) then
  643. key := key and $FFFFFF00;
  644. {$else not USEKEYCODES}
  645. Key := byte (t.AsciiChar) + ((t.wVirtualScanCode AND $00FF) shl 8) + $03000000;
  646. {$endif not USEKEYCODES}
  647. end else
  648. begin
  649. {$ifdef USEKEYCODES}
  650. Scancode:=KeyToQwertyScan[t.wVirtualKeyCode AND $00FF];
  651. If ScanCode>0 then
  652. t.wVirtualScanCode:=ScanCode;
  653. {$endif not USEKEYCODES}
  654. translateKey := 0;
  655. { ignore shift,ctrl,alt,numlock,capslock alone }
  656. case t.wVirtualKeyCode of
  657. $0010, {shift}
  658. $0011, {ctrl}
  659. $0012, {alt}
  660. $0014, {capslock}
  661. $0090, {numlock}
  662. $0091, {scrollock}
  663. { This should be handled !! }
  664. { these last two are OEM specific
  665. this is not good !!! }
  666. $00DC, {^ : next key i.e. a is modified }
  667. { Strange on my keyboard this corresponds to double point over i or u PM }
  668. $00DD: exit; {´ and ` : next key i.e. e is modified }
  669. end;
  670. key := $03000000 + (t.wVirtualScanCode shl 8); { make lower 8 bit=0 like under dos }
  671. end;
  672. { Handling of ~ key as AltGr 2 }
  673. { This is also French keyboard specific !! }
  674. { but without this I can not get a ~ !! PM }
  675. { MvdV: not rightruealtised, since it already has frenchkbd guard}
  676. if (t.wVirtualKeyCode=$32) and
  677. (KeyBoardLayout = FrenchKeyboard) and
  678. (t.dwControlKeyState and RIGHT_ALT_PRESSED <> 0) then
  679. key:=(key and $ffffff00) or ord('~');
  680. { ok, now add Shift-State }
  681. ss := transShiftState (t.dwControlKeyState);
  682. key := key or (ss shl 16);
  683. { Reset Ascii-Char if Alt+Key, fv needs that, may be we
  684. need it for other special keys too
  685. 18 Sept 1999 AD: not for right Alt i.e. for AltGr+ß = \ on german keyboard }
  686. if ((ss and kbAlt <> 0) and rightistruealt(t.dwControlKeyState)) or
  687. (*
  688. { yes, we need it for cursor keys, 25=left, 26=up, 27=right,28=down}
  689. {aggg, this will not work because esc is also virtualKeyCode 27!!}
  690. {if (t.wVirtualKeyCode >= 25) and (t.wVirtualKeyCode <= 28) then}
  691. no VK_ESCAPE is $1B !!
  692. there was a mistake :
  693. VK_LEFT is $25 not 25 !! *)
  694. { not $2E VK_DELETE because its only the Keypad point !! PM }
  695. (t.wVirtualKeyCode in [$21..$28,$2C,$2D,$2F]) then
  696. { if t.wVirtualScanCode in [$47..$49,$4b,$4d,$4f,$50..$53] then}
  697. key := key and $FFFFFF00;
  698. {and translate to dos-scancodes to make fv happy, we will convert this
  699. back in translateKeyEvent}
  700. if rightistruealt(t.dwControlKeyState) then {not for alt-gr}
  701. if (t.wVirtualScanCode >= low (DosTT)) and
  702. (t.wVirtualScanCode <= high (dosTT)) then
  703. begin
  704. b := 0;
  705. if (ss and kbAlt) <> 0 then
  706. b := DosTT[t.wVirtualScanCode].a
  707. else
  708. if (ss and kbCtrl) <> 0 then
  709. b := DosTT[t.wVirtualScanCode].c
  710. else
  711. if (ss and kbShift) <> 0 then
  712. b := DosTT[t.wVirtualScanCode].s
  713. else
  714. b := DosTT[t.wVirtualScanCode].n;
  715. if b <> 0 then
  716. key := (key and $FFFF00FF) or (longint (b) shl 8);
  717. end;
  718. {Alt-0 to Alt-9}
  719. if rightistruealt(t.dwControlKeyState) then {not for alt-gr}
  720. if (t.wVirtualScanCode >= low (DosTT09)) and
  721. (t.wVirtualScanCode <= high (dosTT09)) then
  722. begin
  723. b := 0;
  724. if (ss and kbAlt) <> 0 then
  725. b := DosTT09[t.wVirtualScanCode].a
  726. else
  727. if (ss and kbCtrl) <> 0 then
  728. b := DosTT09[t.wVirtualScanCode].c
  729. else
  730. if (ss and kbShift) <> 0 then
  731. b := DosTT09[t.wVirtualScanCode].s
  732. else
  733. b := DosTT09[t.wVirtualScanCode].n;
  734. if b <> 0 then
  735. key := (key and $FFFF0000) or (longint (b) shl 8);
  736. end;
  737. TranslateKey := key;
  738. end;
  739. translateKey := Key;
  740. end;
  741. *}
  742. //#define IsMsgPortEmpty(x) (((x)->mp_MsgList.lh_TailPred) == (struct Node *)(&(x)->mp_MsgList))
  743. function IsMsgPortEmpty(port: PMsgPort): boolean; inline;
  744. begin
  745. IsMsgPortEmpty:=(port^.mp_MsgList.lh_TailPred = @(port^.mp_MsgList));
  746. end;
  747. var
  748. KeyQueue: TKeyEvent;
  749. type
  750. rawCodeEntry = record
  751. rc,n,s,c,a : word; { raw code, normal, shift, ctrl, alt }
  752. end;
  753. const
  754. RCTABLE_MAXIDX = 16;
  755. rawCodeTable : array[0..RCTABLE_MAXIDX] of rawCodeEntry =
  756. ((rc: 71; n: $5200; s: $0500; c: $0400; a: $A200; ), // Insert
  757. (rc: 72; n: $4900; s: $4900; c: $8400; a: $9900; ), // PgUP // shift?
  758. (rc: 73; n: $5100; s: $5100; c: $7600; a: $A100; ), // PgDOWN // shift?
  759. (rc: 76; n: $4800; s: $4800; c: $8D00; a: $9800; ), // UP // shift?
  760. (rc: 77; n: $5000; s: $5000; c: $9100; a: $A000; ), // DOWN // shift?
  761. (rc: 78; n: $4D00; s: $4D00; c: $7400; a: $9D00; ), // RIGHT // shift?
  762. (rc: 79; n: $4B00; s: $4B00; c: $7300; a: $9B00; ), // LEFT // shift?
  763. (rc: 80; n: $3B00; s: $5400; c: $5E00; a: $6800; ), // F1
  764. (rc: 81; n: $3C00; s: $5500; c: $5F00; a: $6900; ), // F2
  765. (rc: 82; n: $3D00; s: $5600; c: $6000; a: $6A00; ), // F3
  766. (rc: 83; n: $3E00; s: $5700; c: $6100; a: $6B00; ), // F4
  767. (rc: 84; n: $3F00; s: $5800; c: $6200; a: $6C00; ), // F5
  768. (rc: 85; n: $4000; s: $5900; c: $6300; a: $6D00; ), // F6
  769. (rc: 86; n: $4100; s: $5A00; c: $6400; a: $6E00; ), // F7
  770. (rc: 87; n: $4200; s: $5B00; c: $6500; a: $6F00; ), // F8
  771. (rc: 88; n: $4300; s: $5C00; c: $6600; a: $7000; ), // F9
  772. (rc: 89; n: $4400; s: $5D00; c: $6700; a: $7100; ) // F10
  773. );
  774. function rcTableIdx(rc: longint): longint;
  775. var counter: longint;
  776. begin
  777. rcTableIdx := -1;
  778. counter := 0;
  779. while (rawCodeTable[counter].rc <> rc) and (counter <= RCTABLE_MAXIDX) do inc(counter);
  780. if (counter <= RCTABLE_MAXIDX) then rcTableIdx:=counter;
  781. end;
  782. function hasShift(iMsg: PIntuiMessage) : boolean; inline;
  783. begin
  784. hasShift:=false;
  785. if ((iMsg^.qualifier and IEQUALIFIER_LSHIFT) > 0) or
  786. ((iMsg^.qualifier and IEQUALIFIER_RSHIFT) > 0) then hasShift:=true;
  787. end;
  788. function hasCtrl(iMsg: PIntuiMessage) : boolean; inline;
  789. begin
  790. hasCtrl:=false;
  791. if ((iMsg^.qualifier and IEQUALIFIER_CONTROL) > 0) then hasCtrl:=true;
  792. end;
  793. function hasAlt(iMsg: PIntuiMessage) : boolean; inline;
  794. begin
  795. hasAlt:=false;
  796. if ((iMsg^.qualifier and IEQUALIFIER_LALT) > 0) or
  797. ((iMsg^.qualifier and IEQUALIFIER_RALT) > 0) then hasAlt:=true;
  798. end;
  799. function rcTableCode(iMsg: PIntuiMessage; Idx: longint): longint;
  800. begin
  801. if (Idx < 0) or (Idx > RCTABLE_MAXIDX) then begin
  802. rcTableCode:=-1;
  803. exit;
  804. end;
  805. if hasShift(iMsg) then rcTableCode:=rawCodeTable[Idx].s else
  806. if hasCtrl(iMsg) then rcTableCode:=rawCodeTable[Idx].c else
  807. if hasAlt(iMsg) then rcTableCode:=rawCodeTable[Idx].a else
  808. rcTableCode:=rawCodeTable[Idx].n;
  809. end;
  810. procedure setShiftState(iMsg: PIntuiMessage);
  811. begin
  812. lastShiftState:=0;
  813. if ((iMsg^.qualifier and IEQUALIFIER_LSHIFT) > 0) then lastShiftState := lastShiftState or $01;
  814. if ((iMsg^.qualifier and IEQUALIFIER_RSHIFT) > 0) then lastShiftState := lastShiftState or $02;
  815. if hasCtrl(iMsg) then lastShiftState := lastShiftState or $04;
  816. if hasAlt(iMsg) then lastShiftState := lastShiftState or $08;
  817. if ((iMsg^.qualifier and IEQUALIFIER_NUMERICPAD) > 0) then lastShiftState := lastShiftState or $20;
  818. if ((iMsg^.qualifier and IEQUALIFIER_CAPSLOCK) > 0) then lastShiftState := lastShiftState or $40;
  819. end;
  820. function SysPollKeyEvent: TKeyEvent;
  821. //var t : TKeyEventRecord;
  822. // k : TKeyEvent;
  823. var
  824. iMsg : PIntuiMessage;
  825. KeyCode: longint;
  826. tmpFCode: word;
  827. tmpIdx : longint;
  828. begin
  829. KeyCode:=0;
  830. SysPollKeyEvent:=0;
  831. if KeyQueue<>0 then begin
  832. SysPollKeyEvent:=KeyQueue;
  833. exit;
  834. end;
  835. if videoWindow<>nil then begin
  836. if IsMsgPortEmpty(videoWindow^.UserPort) then exit;
  837. end;
  838. PMessage(iMsg):=GetMsg(videoWindow^.UserPort);
  839. if (iMsg<>nil) then begin
  840. // set Shift state qualifiers. do this for all messages we get.
  841. setShiftState(iMsg);
  842. case (iMsg^.iClass) of
  843. IDCMP_CLOSEWINDOW: begin
  844. GotCloseWindow;
  845. end;
  846. IDCMP_CHANGEWINDOW: begin
  847. GotResizeWindow;
  848. end;
  849. IDCMP_VANILLAKEY: begin
  850. writeln('vanilla keycode: ',iMsg^.code);
  851. KeyCode:=iMsg^.code;
  852. case (iMsg^.code) of
  853. 09: KeyCode:=$0F09; // Tab
  854. 13: KeyCode:=$1C0D; // Enter
  855. 27: KeyCode:=$011B; // ESC
  856. 127: KeyCode:=$5300; // Del
  857. 164: KeyCode:=$1200; // Alt-E //XXX: conflicts with Alt-Z(?)
  858. 174: KeyCode:=$1300; // Alt-R
  859. 176: KeyCode:=$1100; // Alt-W
  860. 215: KeyCode:=$2D00; // Alt-X
  861. 229: KeyCode:=$1000; // Alt-Q
  862. 254: KeyCode:=$1400; // Alt-T
  863. end;
  864. end;
  865. IDCMP_RAWKEY: begin
  866. writeln('raw keycode: ',iMsg^.code);
  867. case (iMsg^.code) of
  868. 35: KeyCode:=$2100; // Alt-F
  869. 112: KeyCode:=$4700; // HOME
  870. 113: KeyCode:=$4F00; // END
  871. else
  872. KeyCode:=rcTableCode(iMsg,rcTableIdx(iMsg^.code));
  873. end;
  874. end;
  875. else begin
  876. KeyCode:=-1;
  877. end;
  878. end;
  879. ReplyMsg(PMessage(iMsg));
  880. end;
  881. // end;
  882. // XXX: huh :)
  883. if KeyCode>=0 then begin
  884. SysPollKeyEvent:=KeyCode or (kbPhys shl 24);
  885. end else begin
  886. SysPollKeyEvent:=0;
  887. end;
  888. KeyQueue:=SysPollKeyEvent;
  889. {*
  890. SysPollKeyEvent := 0;
  891. if getKeyEventFromQueue (t, true) then
  892. begin
  893. { we get an enty for shift, ctrl, alt... }
  894. k := translateKey (t);
  895. while (k = 0) do
  896. begin
  897. getKeyEventFromQueue (t, false); {remove it}
  898. if not getKeyEventFromQueue (t, true) then exit;
  899. k := translateKey (t)
  900. end;
  901. SysPollKeyEvent := k;
  902. end;
  903. *}
  904. end;
  905. function SysGetKeyEvent: TKeyEvent;
  906. //var t : TKeyEventRecord;
  907. // key : TKeyEvent;
  908. var
  909. iMsg : PIntuiMessage;
  910. res : TKeyEvent;
  911. begin
  912. {*
  913. key := 0;
  914. repeat
  915. if getKeyEventFromQueueWait (t) then
  916. key := translateKey (t);
  917. until key <> 0;
  918. {$ifdef DEBUG}
  919. last_ir.Event.KeyEvent:=t;
  920. {$endif DEBUG}
  921. SysGetKeyEvent := key;
  922. *}
  923. // writeln('keyboard/SysGetKeyEvent');
  924. if videoWindow<>nil then begin
  925. if KeyQueue <> 0 then begin
  926. SysGetKeyEvent := KeyQueue;
  927. KeyQueue:=0;
  928. exit;
  929. end;
  930. repeat
  931. WaitPort(videoWindow^.UserPort);
  932. res:=SysPollKeyEvent;
  933. until res<>0;
  934. end;
  935. SysGetKeyEvent:=res;
  936. {*
  937. if videoWindow<>nil then begin
  938. WaitPort(videoWindow^.UserPort);
  939. PMessage(iMsg):=GetMsg(videoWindow^.UserPort);
  940. if (iMsg<>nil) then begin
  941. writeln('got msg!');
  942. ReplyMsg(PMessage(iMsg));
  943. end;
  944. end;
  945. *}
  946. end;
  947. function SysTranslateKeyEvent(KeyEvent: TKeyEvent): TKeyEvent;
  948. begin
  949. {*
  950. if KeyEvent and $03000000 = $03000000 then
  951. begin
  952. if KeyEvent and $000000FF <> 0 then
  953. begin
  954. SysTranslateKeyEvent := KeyEvent and $00FFFFFF;
  955. exit;
  956. end;
  957. {translate function-keys and other specials, ascii-codes are already ok}
  958. case (KeyEvent AND $0000FF00) shr 8 of
  959. {F1..F10}
  960. $3B..$44 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF1 + ((KeyEvent AND $0000FF00) SHR 8) - $3B + $02000000;
  961. {F11,F12}
  962. $85..$86 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF11 + ((KeyEvent AND $0000FF00) SHR 8) - $85 + $02000000;
  963. {Shift F1..F10}
  964. $54..$5D : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF1 + ((KeyEvent AND $0000FF00) SHR 8) - $54 + $02000000;
  965. {Shift F11,F12}
  966. $87..$88 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF11 + ((KeyEvent AND $0000FF00) SHR 8) - $87 + $02000000;
  967. {Alt F1..F10}
  968. $68..$71 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF1 + ((KeyEvent AND $0000FF00) SHR 8) - $68 + $02000000;
  969. {Alt F11,F12}
  970. $8B..$8C : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF11 + ((KeyEvent AND $0000FF00) SHR 8) - $8B + $02000000;
  971. {Ctrl F1..F10}
  972. $5E..$67 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF1 + ((KeyEvent AND $0000FF00) SHR 8) - $5E + $02000000;
  973. {Ctrl F11,F12}
  974. $89..$8A : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF11 + ((KeyEvent AND $0000FF00) SHR 8) - $89 + $02000000;
  975. {normal,ctrl,alt}
  976. $47,$77,$97 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdHome + $02000000;
  977. $48,$8D,$98 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdUp + $02000000;
  978. $49,$84,$99 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdPgUp + $02000000;
  979. $4b,$73,$9B : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdLeft + $02000000;
  980. $4d,$74,$9D : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdRight + $02000000;
  981. $4f,$75,$9F : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdEnd + $02000000;
  982. $50,$91,$A0 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdDown + $02000000;
  983. $51,$76,$A1 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdPgDn + $02000000;
  984. $52,$92,$A2 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdInsert + $02000000;
  985. $53,$93,$A3 : SysTranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdDelete + $02000000;
  986. else
  987. SysTranslateKeyEvent := KeyEvent;
  988. end;
  989. end else
  990. SysTranslateKeyEvent := KeyEvent;
  991. *}
  992. end;
  993. function SysGetShiftState: Byte;
  994. begin
  995. //writeln('SysgetShiftState:',hexstr(lastShiftState,2));
  996. SysGetShiftState:= lastShiftState;
  997. end;
  998. Const
  999. SysKeyboardDriver : TKeyboardDriver = (
  1000. InitDriver : @SysInitKeyBoard;
  1001. DoneDriver : @SysDoneKeyBoard;
  1002. GetKeyevent : @SysGetKeyEvent;
  1003. PollKeyEvent : @SysPollKeyEvent;
  1004. GetShiftState : @SysGetShiftState;
  1005. // TranslateKeyEvent : @SysTranslateKeyEvent;
  1006. TranslateKeyEvent : Nil;
  1007. TranslateKeyEventUnicode : Nil;
  1008. );
  1009. begin
  1010. SetKeyBoardDriver(SysKeyBoardDriver);
  1011. end.