keyboard.pp 37 KB

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