keyboard.inc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. {
  2. $Id$
  3. System independent keyboard interface for windows
  4. Copyright (c) 1999 by Florian Klaempfl
  5. Member of the Free Pascal development team
  6. This library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Library General Public
  8. License as published by the Free Software Foundation; either
  9. version 2 of the License, or (at your option) any later version.
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. Library General Public License for more details.
  14. You should have received a copy of the GNU Library General Public
  15. License along with this library; if not, write to the Free
  16. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************}
  18. { WARNING: Keyboard-Drivers (i.e. german) will only work under WinNT.
  19. 95 and 98 do not support keyboard-drivers other than us for win32
  20. console-apps. So we always get the keys in us-keyboard layout
  21. from Win9x.
  22. }
  23. uses
  24. {$ifndef DEBUG}
  25. Windows,
  26. {$endif DEBUG}
  27. Dos,
  28. Event;
  29. const MaxQueueSize = 120;
  30. FrenchKeyboard = $040C040C;
  31. KeyboardActive : boolean =false;
  32. var
  33. keyboardeventqueue : array[0..maxqueuesize] of TKeyEventRecord;
  34. nextkeyevent,nextfreekeyevent : longint;
  35. newKeyEvent : THandle; {sinaled if key is available}
  36. lockVar : TCriticalSection; {for queue access}
  37. lastShiftState : byte; {set by handler for PollShiftStateEvent}
  38. altNumActive : boolean; {for alt+0..9}
  39. altNumBuffer : string [3];
  40. { used for keyboard specific stuff }
  41. KeyBoardLayout : HKL;
  42. procedure incqueueindex(var l : longint);
  43. begin
  44. inc(l);
  45. { wrap around? }
  46. if l>maxqueuesize then
  47. l:=0;
  48. end;
  49. function keyEventsInQueue : boolean;
  50. begin
  51. keyEventsInQueue := (nextkeyevent <> nextfreekeyevent);
  52. end;
  53. { gets or peeks the next key from the queue, does not wait for new keys }
  54. function getKeyEventFromQueue (VAR t : TKeyEventRecord; Peek : boolean) : boolean;
  55. begin
  56. EnterCriticalSection (lockVar);
  57. if keyEventsInQueue then
  58. begin
  59. t := keyboardeventqueue[nextkeyevent];
  60. if not peek then incqueueindex (nextkeyevent);
  61. getKeyEventFromQueue := true;
  62. if not keyEventsInQueue then ResetEvent (newKeyEvent);
  63. end else
  64. begin
  65. getKeyEventFromQueue := false;
  66. ResetEvent (newKeyEvent);
  67. end;
  68. LeaveCriticalSection (lockVar);
  69. end;
  70. { gets the next key from the queue, does wait for new keys }
  71. function getKeyEventFromQueueWait (VAR t : TKeyEventRecord) : boolean;
  72. begin
  73. WaitForSingleObject (newKeyEvent, INFINITE);
  74. getKeyEventFromQueueWait := getKeyEventFromQueue (t, false);
  75. end;
  76. { translate win32 shift-state to keyboard shift state }
  77. function transShiftState (ControlKeyState : dword) : byte;
  78. var b : byte;
  79. begin
  80. b := 0;
  81. if ControlKeyState and SHIFT_PRESSED <> 0 then { win32 makes no difference between left and right shift }
  82. b := b or kbShift;
  83. if (ControlKeyState and LEFT_CTRL_PRESSED <> 0) or
  84. (ControlKeyState and RIGHT_CTRL_PRESSED <> 0) then
  85. b := b or kbCtrl;
  86. if (ControlKeyState and LEFT_ALT_PRESSED <> 0) or
  87. (ControlKeyState and RIGHT_ALT_PRESSED <> 0) then
  88. b := b or kbAlt;
  89. transShiftState := b;
  90. end;
  91. { The event-Handler thread from the unit event will call us if a key-event
  92. is available }
  93. procedure HandleKeyboard;
  94. var
  95. ir : INPUT_RECORD;
  96. dwRead : DWord;
  97. i : longint;
  98. c : word;
  99. addThis: boolean;
  100. begin
  101. dwRead:=1;
  102. ReadConsoleInput(TextRec(Input).Handle,ir,1,dwRead);
  103. if (dwRead=1) and (ir.EventType=KEY_EVENT) then
  104. begin
  105. with ir.KeyEvent do
  106. begin
  107. { key up events are ignored (except alt) }
  108. if bKeyDown then
  109. begin
  110. EnterCriticalSection (lockVar);
  111. for i:=1 to wRepeatCount do
  112. begin
  113. addThis := true;
  114. if (dwControlKeyState and LEFT_ALT_PRESSED <> 0) or
  115. (dwControlKeyState and RIGHT_ALT_PRESSED <> 0) then {alt pressed}
  116. if (wVirtualKeyCode >= $60) and (wVirtualKeyCode <= $69) then {0..9 on NumBlock}
  117. begin
  118. if length (altNumBuffer) = 3 then
  119. delete (altNumBuffer,1,1);
  120. altNumBuffer := altNumBuffer + char (wVirtualKeyCode-48);
  121. altNumActive := true;
  122. addThis := false;
  123. end else
  124. begin
  125. altNumActive := false;
  126. altNumBuffer := '';
  127. end;
  128. if addThis then
  129. begin
  130. keyboardeventqueue[nextfreekeyevent]:=
  131. ir.KeyEvent;
  132. incqueueindex(nextfreekeyevent);
  133. end;
  134. end;
  135. lastShiftState := transShiftState (dwControlKeyState); {save it for PollShiftStateEvent}
  136. SetEvent (newKeyEvent); {event that a new key is available}
  137. LeaveCriticalSection (lockVar);
  138. end else
  139. begin
  140. lastShiftState := transShiftState (dwControlKeyState); {save it for PollShiftStateEvent}
  141. {for alt-number we have to look for alt-key release}
  142. if altNumActive then
  143. if (wVirtualKeyCode = $12) then {alt-released}
  144. begin
  145. if altNumBuffer <> '' then {numbers with alt pressed?}
  146. begin
  147. Val (altNumBuffer, c, i);
  148. if (i = 0) and (c <= 255) then {valid number?}
  149. begin {add to queue}
  150. fillchar (ir, sizeof (ir), 0);
  151. bKeyDown := true;
  152. AsciiChar := char (c);
  153. {and add to queue}
  154. EnterCriticalSection (lockVar);
  155. keyboardeventqueue[nextfreekeyevent]:=
  156. ir.KeyEvent;
  157. incqueueindex(nextfreekeyevent);
  158. SetEvent (newKeyEvent); {event that a new key is available}
  159. LeaveCriticalSection (lockVar);
  160. end;
  161. end;
  162. altNumActive := false; {clear alt-buffer}
  163. altNumBuffer := '';
  164. end;
  165. end;
  166. end;
  167. end;
  168. end;
  169. procedure InitKeyboard;
  170. begin
  171. if KeyboardActive then
  172. exit;
  173. KeyBoardLayout:=GetKeyboardLayout(0);
  174. lastShiftState := 0;
  175. FlushConsoleInputBuffer(TextRec(Input).Handle);
  176. newKeyEvent := CreateEvent (nil, // address of security attributes
  177. true, // flag for manual-reset event
  178. false, // flag for initial state
  179. nil); // address of event-object name
  180. if newKeyEvent = INVALID_HANDLE_VALUE then
  181. begin
  182. // what to do here ????
  183. RunError (217);
  184. end;
  185. InitializeCriticalSection (lockVar);
  186. altNumActive := false;
  187. altNumBuffer := '';
  188. nextkeyevent:=0;
  189. nextfreekeyevent:=0;
  190. SetKeyboardEventHandler (@HandleKeyboard);
  191. KeyboardActive:=true;
  192. end;
  193. procedure DoneKeyboard;
  194. begin
  195. if not KeyboardActive then
  196. exit;
  197. SetKeyboardEventHandler(nil); {hangs???}
  198. DeleteCriticalSection (lockVar);
  199. FlushConsoleInputBuffer(TextRec(Input).Handle);
  200. closeHandle (newKeyEvent);
  201. KeyboardActive:=false;
  202. end;
  203. {$define USEKEYCODES}
  204. {Translatetable Win32 -> Dos for Special Keys = Function Key, Cursor Keys
  205. and Keys other than numbers on numblock (to make fv happy) }
  206. {combinations under dos: Shift+Ctrl: same as Ctrl
  207. Shift+Alt : same as alt
  208. Ctrl+Alt : nothing (here we get it like alt)}
  209. {$ifdef USEKEYCODES}
  210. { use positive values for ScanCode we want to set
  211. 0 for key where we should leave the scancode
  212. -1 for OEM specifc keys
  213. -2 for unassigned
  214. -3 for Kanji systems ???
  215. }
  216. const
  217. Unassigned = -2;
  218. Kanji = -3;
  219. OEM_specific = -1;
  220. KeyToQwertyScan : array [0..255] of integer =
  221. (
  222. { 00 } 0,
  223. { 01 VK_LBUTTON } 0,
  224. { 02 VK_RBUTTON } 0,
  225. { 03 VK_CANCEL } 0,
  226. { 04 VK_MBUTTON } 0,
  227. { 05 unassigned } -2,
  228. { 06 unassigned } -2,
  229. { 07 unassigned } -2,
  230. { 08 VK_BACK } $E,
  231. { 09 VK_TAB } $F,
  232. { 0A unassigned } -2,
  233. { 0B unassigned } -2,
  234. { 0C VK_CLEAR ?? } 0,
  235. { 0D VK_RETURN } 0,
  236. { 0E unassigned } -2,
  237. { 0F unassigned } -2,
  238. { 10 VK_SHIFT } 0,
  239. { 11 VK_CONTROL } 0,
  240. { 12 VK_MENU (Alt key) } 0,
  241. { 13 VK_PAUSE } 0,
  242. { 14 VK_CAPITAL (Caps Lock) } 0,
  243. { 15 Reserved for Kanji systems} -3,
  244. { 16 Reserved for Kanji systems} -3,
  245. { 17 Reserved for Kanji systems} -3,
  246. { 18 Reserved for Kanji systems} -3,
  247. { 19 Reserved for Kanji systems} -3,
  248. { 1A unassigned } -2,
  249. { 1B VK_ESCAPE } $1,
  250. { 1C Reserved for Kanji systems} -3,
  251. { 1D Reserved for Kanji systems} -3,
  252. { 1E Reserved for Kanji systems} -3,
  253. { 1F Reserved for Kanji systems} -3,
  254. { 20 VK_SPACE} 0,
  255. { 21 VK_PRIOR (PgUp) } 0,
  256. { 22 VK_NEXT (PgDown) } 0,
  257. { 23 VK_END } 0,
  258. { 24 VK_HOME } 0,
  259. { 25 VK_LEFT } 0,
  260. { 26 VK_UP } 0,
  261. { 27 VK_RIGHT } 0,
  262. { 28 VK_DOWN } 0,
  263. { 29 VK_SELECT ??? } 0,
  264. { 2A OEM specific !! } -1,
  265. { 2B VK_EXECUTE } 0,
  266. { 2C VK_SNAPSHOT } 0,
  267. { 2D VK_INSERT } 0,
  268. { 2E VK_DELETE } 0,
  269. { 2F VK_HELP } 0,
  270. { 30 VK_0 '0' } 11,
  271. { 31 VK_1 '1' } 2,
  272. { 32 VK_2 '2' } 3,
  273. { 33 VK_3 '3' } 4,
  274. { 34 VK_4 '4' } 5,
  275. { 35 VK_5 '5' } 6,
  276. { 36 VK_6 '6' } 7,
  277. { 37 VK_7 '7' } 8,
  278. { 38 VK_8 '8' } 9,
  279. { 39 VK_9 '9' } 10,
  280. { 3A unassigned } -2,
  281. { 3B unassigned } -2,
  282. { 3C unassigned } -2,
  283. { 3D unassigned } -2,
  284. { 3E unassigned } -2,
  285. { 3F unassigned } -2,
  286. { 40 unassigned } -2,
  287. { 41 VK_A 'A' } $1E,
  288. { 42 VK_B 'B' } $30,
  289. { 43 VK_C 'C' } $2E,
  290. { 44 VK_D 'D' } $20,
  291. { 45 VK_E 'E' } $12,
  292. { 46 VK_F 'F' } $21,
  293. { 47 VK_G 'G' } $22,
  294. { 48 VK_H 'H' } $23,
  295. { 49 VK_I 'I' } $17,
  296. { 4A VK_J 'J' } $24,
  297. { 4B VK_K 'K' } $25,
  298. { 4C VK_L 'L' } $26,
  299. { 4D VK_M 'M' } $32,
  300. { 4E VK_N 'N' } $31,
  301. { 4F VK_O 'O' } $18,
  302. { 50 VK_P 'P' } $19,
  303. { 51 VK_Q 'Q' } $10,
  304. { 52 VK_R 'R' } $13,
  305. { 53 VK_S 'S' } $1F,
  306. { 54 VK_T 'T' } $14,
  307. { 55 VK_U 'U' } $16,
  308. { 56 VK_V 'V' } $2F,
  309. { 57 VK_W 'W' } $11,
  310. { 58 VK_X 'X' } $2D,
  311. { 59 VK_Y 'Y' } $15,
  312. { 5A VK_Z 'Z' } $2C,
  313. { 5B unassigned } -2,
  314. { 5C unassigned } -2,
  315. { 5D unassigned } -2,
  316. { 5E unassigned } -2,
  317. { 5F unassigned } -2,
  318. { 60 VK_NUMPAD0 NumKeyPad '0' } 11,
  319. { 61 VK_NUMPAD1 NumKeyPad '1' } 2,
  320. { 62 VK_NUMPAD2 NumKeyPad '2' } 3,
  321. { 63 VK_NUMPAD3 NumKeyPad '3' } 4,
  322. { 64 VK_NUMPAD4 NumKeyPad '4' } 5,
  323. { 65 VK_NUMPAD5 NumKeyPad '5' } 6,
  324. { 66 VK_NUMPAD6 NumKeyPad '6' } 7,
  325. { 67 VK_NUMPAD7 NumKeyPad '7' } 8,
  326. { 68 VK_NUMPAD8 NumKeyPad '8' } 9,
  327. { 69 VK_NUMPAD9 NumKeyPad '9' } 10,
  328. { 6A VK_MULTIPLY } 0,
  329. { 6B VK_ADD } 0,
  330. { 6C VK_SEPARATOR } 0,
  331. { 6D VK_SUBSTRACT } 0,
  332. { 6E VK_DECIMAL } 0,
  333. { 6F VK_DIVIDE } 0,
  334. { 70 VK_F1 'F1' } $3B,
  335. { 71 VK_F2 'F2' } $3C,
  336. { 72 VK_F3 'F3' } $3D,
  337. { 73 VK_F4 'F4' } $3E,
  338. { 74 VK_F5 'F5' } $3F,
  339. { 75 VK_F6 'F6' } $40,
  340. { 76 VK_F7 'F7' } $41,
  341. { 77 VK_F8 'F8' } $42,
  342. { 78 VK_F9 'F9' } $43,
  343. { 79 VK_F10 'F10' } $44,
  344. { 7A VK_F11 'F11' } $57,
  345. { 7B VK_F12 'F12' } $58,
  346. { 7C VK_F13 } 0,
  347. { 7D VK_F14 } 0,
  348. { 7E VK_F15 } 0,
  349. { 7F VK_F16 } 0,
  350. { 80 VK_F17 } 0,
  351. { 81 VK_F18 } 0,
  352. { 82 VK_F19 } 0,
  353. { 83 VK_F20 } 0,
  354. { 84 VK_F21 } 0,
  355. { 85 VK_F22 } 0,
  356. { 86 VK_F23 } 0,
  357. { 87 VK_F24 } 0,
  358. { 88 unassigned } -2,
  359. { 89 VK_NUMLOCK } 0,
  360. { 8A VK_SCROLL } 0,
  361. { 8B unassigned } -2,
  362. { 8C unassigned } -2,
  363. { 8D unassigned } -2,
  364. { 8E unassigned } -2,
  365. { 8F unassigned } -2,
  366. { 90 unassigned } -2,
  367. { 91 unassigned } -2,
  368. { 92 unassigned } -2,
  369. { 93 unassigned } -2,
  370. { 94 unassigned } -2,
  371. { 95 unassigned } -2,
  372. { 96 unassigned } -2,
  373. { 97 unassigned } -2,
  374. { 98 unassigned } -2,
  375. { 99 unassigned } -2,
  376. { 9A unassigned } -2,
  377. { 9B unassigned } -2,
  378. { 9C unassigned } -2,
  379. { 9D unassigned } -2,
  380. { 9E unassigned } -2,
  381. { 9F unassigned } -2,
  382. { A0 unassigned } -2,
  383. { A1 unassigned } -2,
  384. { A2 unassigned } -2,
  385. { A3 unassigned } -2,
  386. { A4 unassigned } -2,
  387. { A5 unassigned } -2,
  388. { A6 unassigned } -2,
  389. { A7 unassigned } -2,
  390. { A8 unassigned } -2,
  391. { A9 unassigned } -2,
  392. { AA unassigned } -2,
  393. { AB unassigned } -2,
  394. { AC unassigned } -2,
  395. { AD unassigned } -2,
  396. { AE unassigned } -2,
  397. { AF unassigned } -2,
  398. { B0 unassigned } -2,
  399. { B1 unassigned } -2,
  400. { B2 unassigned } -2,
  401. { B3 unassigned } -2,
  402. { B4 unassigned } -2,
  403. { B5 unassigned } -2,
  404. { B6 unassigned } -2,
  405. { B7 unassigned } -2,
  406. { B8 unassigned } -2,
  407. { B9 unassigned } -2,
  408. { BA OEM specific } 0,
  409. { BB OEM specific } 0,
  410. { BC OEM specific } 0,
  411. { BD OEM specific } 0,
  412. { BE OEM specific } 0,
  413. { BF OEM specific } 0,
  414. { C0 OEM specific } 0,
  415. { C1 unassigned } -2,
  416. { C2 unassigned } -2,
  417. { C3 unassigned } -2,
  418. { C4 unassigned } -2,
  419. { C5 unassigned } -2,
  420. { C6 unassigned } -2,
  421. { C7 unassigned } -2,
  422. { C8 unassigned } -2,
  423. { C9 unassigned } -2,
  424. { CA unassigned } -2,
  425. { CB unassigned } -2,
  426. { CC unassigned } -2,
  427. { CD unassigned } -2,
  428. { CE unassigned } -2,
  429. { CF unassigned } -2,
  430. { D0 unassigned } -2,
  431. { D1 unassigned } -2,
  432. { D2 unassigned } -2,
  433. { D3 unassigned } -2,
  434. { D4 unassigned } -2,
  435. { D5 unassigned } -2,
  436. { D6 unassigned } -2,
  437. { D7 unassigned } -2,
  438. { D8 unassigned } -2,
  439. { D9 unassigned } -2,
  440. { DA unassigned } -2,
  441. { DB OEM specific } 0,
  442. { DC OEM specific } 0,
  443. { DD OEM specific } 0,
  444. { DE OEM specific } 0,
  445. { DF OEM specific } 0,
  446. { E0 OEM specific } 0,
  447. { E1 OEM specific } 0,
  448. { E2 OEM specific } 0,
  449. { E3 OEM specific } 0,
  450. { E4 OEM specific } 0,
  451. { E5 unassigned } -2,
  452. { E6 OEM specific } 0,
  453. { E7 unassigned } -2,
  454. { E8 unassigned } -2,
  455. { E9 OEM specific } 0,
  456. { EA OEM specific } 0,
  457. { EB OEM specific } 0,
  458. { EC OEM specific } 0,
  459. { ED OEM specific } 0,
  460. { EE OEM specific } 0,
  461. { EF OEM specific } 0,
  462. { F0 OEM specific } 0,
  463. { F1 OEM specific } 0,
  464. { F2 OEM specific } 0,
  465. { F3 OEM specific } 0,
  466. { F4 OEM specific } 0,
  467. { F5 OEM specific } 0,
  468. { F6 unassigned } -2,
  469. { F7 unassigned } -2,
  470. { F8 unassigned } -2,
  471. { F9 unassigned } -2,
  472. { FA unassigned } -2,
  473. { FB unassigned } -2,
  474. { FC unassigned } -2,
  475. { FD unassigned } -2,
  476. { FE unassigned } -2,
  477. { FF unassigned } -2
  478. );
  479. {$endif USEKEYCODES}
  480. type TTEntryT = packed record
  481. n,s,c,a : byte; {normal,shift, ctrl, alt, normal only for f11,f12}
  482. end;
  483. CONST
  484. DosTT : ARRAY [$3B..$58] OF TTEntryT =
  485. ((n : $3B; s : $54; c : $5E; a: $68), {3B F1}
  486. (n : $3C; s : $55; c : $5F; a: $69), {3C F2}
  487. (n : $3D; s : $56; c : $60; a: $6A), {3D F3}
  488. (n : $3E; s : $57; c : $61; a: $6B), {3E F4}
  489. (n : $3F; s : $58; c : $62; a: $6C), {3F F5}
  490. (n : $40; s : $59; c : $63; a: $6D), {40 F6}
  491. (n : $41; s : $5A; c : $64; a: $6E), {41 F7}
  492. (n : $42; s : $5B; c : $65; a: $6F), {42 F8}
  493. (n : $43; s : $5C; c : $66; a: $70), {43 F9}
  494. (n : $44; s : $5D; c : $67; a: $71), {44 F10}
  495. (n : $45; s : $00; c : $00; a: $00), {45 ???}
  496. (n : $46; s : $00; c : $00; a: $00), {46 ???}
  497. (n : $47; s : $47; c : $77; a: $97), {47 Home}
  498. (n : $48; s : $00; c : $8D; a: $98), {48 Up}
  499. (n : $49; s : $49; c : $84; a: $99), {49 PgUp}
  500. (n : $4A; s : $00; c : $8E; a: $4A), {4A -}
  501. (n : $4B; s : $4B; c : $73; a: $9B), {4B Left}
  502. (n : $4C; s : $00; c : $00; a: $00), {4C ???}
  503. (n : $4D; s : $4D; c : $74; a: $9D), {4D Right}
  504. (n : $4E; s : $00; c : $90; a: $4E), {4E +}
  505. (n : $4F; s : $4F; c : $75; a: $9F), {4F End}
  506. (n : $50; s : $50; c : $91; a: $A0), {50 Down}
  507. (n : $51; s : $51; c : $76; a: $A1), {51 PgDown}
  508. (n : $52; s : $52; c : $92; a: $A2), {52 Insert}
  509. (n : $53; s : $53; c : $93; a: $A3), {53 Del}
  510. (n : $54; s : $00; c : $00; a: $00), {54 ???}
  511. (n : $55; s : $00; c : $00; a: $00), {55 ???}
  512. (n : $56; s : $00; c : $00; a: $00), {56 ???}
  513. (n : $85; s : $87; c : $89; a: $8B), {57 F11}
  514. (n : $86; s : $88; c : $8A; a: $8C)); {58 F12}
  515. DosTT09 : ARRAY [$02..$0F] OF TTEntryT =
  516. ((n : $00; s : $00; c : $00; a: $78), {02 1 }
  517. (n : $00; s : $00; c : $00; a: $79), {03 2 }
  518. (n : $00; s : $00; c : $00; a: $7A), {04 3 }
  519. (n : $00; s : $00; c : $00; a: $7B), {05 4 }
  520. (n : $00; s : $00; c : $00; a: $7C), {06 5 }
  521. (n : $00; s : $00; c : $00; a: $7D), {07 6 }
  522. (n : $00; s : $00; c : $00; a: $7E), {08 7 }
  523. (n : $00; s : $00; c : $00; a: $7F), {09 8 }
  524. (n : $00; s : $00; c : $00; a: $80), {0A 9 }
  525. (n : $00; s : $00; c : $00; a: $81), {0B 0 }
  526. (n : $00; s : $00; c : $00; a: $82), {0C ß }
  527. (n : $00; s : $00; c : $00; a: $00), {0D}
  528. (n : $00; s : $09; c : $00; a: $00), {0E Backspace}
  529. (n : $00; s : $0F; c : $94; a: $00)); {0F Tab }
  530. function translateKey (t : TKeyEventRecord) : TKeyEvent;
  531. var key : TKeyEvent;
  532. ss : byte;
  533. {$ifdef USEKEYCODES}
  534. ScanCode : byte;
  535. {$endif USEKEYCODES}
  536. b : byte;
  537. begin
  538. Key := 0;
  539. if t.bKeyDown then
  540. begin
  541. { ascii-char is <> 0 if not a specal key }
  542. { we return it here otherwise we have to translate more later }
  543. if t.AsciiChar <> #0 then
  544. begin
  545. {drivers needs scancode, we return it here as under dos and linux
  546. with $03000000 = the lowest two bytes is the physical representation}
  547. {$ifdef USEKEYCODES}
  548. Scancode:=KeyToQwertyScan[t.wVirtualKeyCode AND $00FF];
  549. If ScanCode>0 then
  550. t.wVirtualScanCode:=ScanCode;
  551. Key := byte (t.AsciiChar) + (t.wVirtualScanCode shl 8) + $03000000;
  552. ss := transShiftState (t.dwControlKeyState);
  553. key := key or (ss shl 16);
  554. if (ss and kbAlt <> 0) and (t.dwControlKeyState and RIGHT_ALT_PRESSED = 0) then
  555. key := key and $FFFFFF00;
  556. {$else not USEKEYCODES}
  557. Key := byte (t.AsciiChar) + ((t.wVirtualScanCode AND $00FF) shl 8) + $03000000;
  558. {$endif not USEKEYCODES}
  559. end else
  560. begin
  561. {$ifdef USEKEYCODES}
  562. Scancode:=KeyToQwertyScan[t.wVirtualKeyCode AND $00FF];
  563. If ScanCode>0 then
  564. t.wVirtualScanCode:=ScanCode;
  565. {$endif not USEKEYCODES}
  566. translateKey := 0;
  567. { ignore shift,ctrl,alt,numlock,capslock alone }
  568. case t.wVirtualKeyCode of
  569. $0010, {shift}
  570. $0011, {ctrl}
  571. $0012, {alt}
  572. $0014, {capslock}
  573. $0090, {numlock}
  574. $0091, {scrollock}
  575. { This should be handled !! }
  576. { these last two are OEM specific
  577. this is not good !!! }
  578. $00DC, {^ : next key i.e. a is modified }
  579. { Strange on my keyboard this corresponds to double point over i or u PM }
  580. $00DD: exit; {´ and ` : next key i.e. e is modified }
  581. end;
  582. key := $03000000 + (t.wVirtualScanCode shl 8); { make lower 8 bit=0 like under dos }
  583. end;
  584. { Handling of ~ key as AltGr 2 }
  585. { This is also French keyboard specific !! }
  586. { but without this I can not get a ~ !! PM }
  587. if (t.wVirtualKeyCode=$32) and
  588. (KeyBoardLayout = FrenchKeyboard) and
  589. (t.dwControlKeyState and RIGHT_ALT_PRESSED <> 0) then
  590. key:=(key and $ffffff00) or ord('~');
  591. { ok, now add Shift-State }
  592. ss := transShiftState (t.dwControlKeyState);
  593. key := key or (ss shl 16);
  594. { Reset Ascii-Char if Alt+Key, fv needs that, may be we
  595. need it for other special keys too
  596. 18 Sept 1999 AD: not for right Alt i.e. for AltGr+ß = \ on german keyboard }
  597. if ((ss and kbAlt <> 0) and (t.dwControlKeyState and RIGHT_ALT_PRESSED = 0)) or
  598. (*
  599. { yes, we need it for cursor keys, 25=left, 26=up, 27=right,28=down}
  600. {aggg, this will not work because esc is also virtualKeyCode 27!!}
  601. {if (t.wVirtualKeyCode >= 25) and (t.wVirtualKeyCode <= 28) then}
  602. no VK_ESCAPE is $1B !!
  603. there was a mistake :
  604. VK_LEFT is $25 not 25 !! *)
  605. { not $2E VK_DELETE because its only the Keypad point !! PM }
  606. (t.wVirtualKeyCode in [$21..$28,$2C,$2D,$2F]) then
  607. { if t.wVirtualScanCode in [$47..$49,$4b,$4d,$4f,$50..$53] then}
  608. key := key and $FFFFFF00;
  609. {and translate to dos-scancodes to make fv happy, we will convert this
  610. back in translateKeyEvent}
  611. if (t.dwControlKeyState and RIGHT_ALT_PRESSED) = 0 then {not for alt-gr}
  612. if (t.wVirtualScanCode >= low (DosTT)) and
  613. (t.wVirtualScanCode <= high (dosTT)) then
  614. begin
  615. b := 0;
  616. if (ss and kbAlt) <> 0 then
  617. b := DosTT[t.wVirtualScanCode].a
  618. else
  619. if (ss and kbCtrl) <> 0 then
  620. b := DosTT[t.wVirtualScanCode].c
  621. else
  622. if (ss and kbShift) <> 0 then
  623. b := DosTT[t.wVirtualScanCode].s
  624. else
  625. b := DosTT[t.wVirtualScanCode].n;
  626. if b <> 0 then
  627. key := (key and $FFFF00FF) or (longint (b) shl 8);
  628. end;
  629. {Alt-0 to Alt-9}
  630. if (t.dwControlKeyState and RIGHT_ALT_PRESSED) = 0 then {not for alt-gr}
  631. if (t.wVirtualScanCode >= low (DosTT09)) and
  632. (t.wVirtualScanCode <= high (dosTT09)) then
  633. begin
  634. b := 0;
  635. if (ss and kbAlt) <> 0 then
  636. b := DosTT09[t.wVirtualScanCode].a
  637. else
  638. if (ss and kbCtrl) <> 0 then
  639. b := DosTT09[t.wVirtualScanCode].c
  640. else
  641. if (ss and kbShift) <> 0 then
  642. b := DosTT09[t.wVirtualScanCode].s
  643. else
  644. b := DosTT09[t.wVirtualScanCode].n;
  645. if b <> 0 then
  646. key := (key and $FFFF0000) or (longint (b) shl 8);
  647. end;
  648. TranslateKey := key;
  649. end;
  650. translateKey := Key;
  651. end;
  652. function GetKeyEvent: TKeyEvent;
  653. var t : TKeyEventRecord;
  654. key : TKeyEvent;
  655. begin
  656. if PendingKeyEvent<>0 then
  657. begin
  658. GetKeyEvent:=PendingKeyEvent;
  659. PendingKeyEvent:=0;
  660. exit;
  661. end;
  662. key := 0;
  663. repeat
  664. if getKeyEventFromQueueWait (t) then
  665. key := translateKey (t);
  666. until key <> 0;
  667. {$ifdef DEBUG}
  668. last_ir.KeyEvent:=t;
  669. {$endif DEBUG}
  670. GetKeyEvent := key;
  671. end;
  672. function PollKeyEvent: TKeyEvent;
  673. var t : TKeyEventRecord;
  674. k : TKeyEvent;
  675. begin
  676. if PendingKeyEvent<>0 then
  677. exit(PendingKeyEvent);
  678. PollKeyEvent := 0;
  679. if getKeyEventFromQueue (t, true) then
  680. begin
  681. { we get an enty for shift, ctrl, alt... }
  682. k := translateKey (t);
  683. while (k = 0) do
  684. begin
  685. getKeyEventFromQueue (t, false); {remove it}
  686. if not getKeyEventFromQueue (t, true) then exit;
  687. k := translateKey (t)
  688. end;
  689. PollKeyEvent := k;
  690. end;
  691. end;
  692. function TranslateKeyEvent(KeyEvent: TKeyEvent): TKeyEvent;
  693. begin
  694. if KeyEvent and $03000000 = $03000000 then
  695. begin
  696. if KeyEvent and $000000FF <> 0 then
  697. begin
  698. TranslateKeyEvent := KeyEvent and $00FFFFFF;
  699. exit;
  700. end;
  701. {translate function-keys and other specials, ascii-codes are already ok}
  702. case (KeyEvent AND $0000FF00) shr 8 of
  703. {F1..F10}
  704. $3B..$44 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF1 + ((KeyEvent AND $0000FF00) SHR 8) - $3B + $02000000;
  705. {F11,F12}
  706. $85..$86 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF11 + ((KeyEvent AND $0000FF00) SHR 8) - $85 + $02000000;
  707. {Shift F1..F10}
  708. $54..$5D : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF1 + ((KeyEvent AND $0000FF00) SHR 8) - $54 + $02000000;
  709. {Shift F11,F12}
  710. $87..$88 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF11 + ((KeyEvent AND $0000FF00) SHR 8) - $87 + $02000000;
  711. {Alt F1..F10}
  712. $68..$71 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF1 + ((KeyEvent AND $0000FF00) SHR 8) - $68 + $02000000;
  713. {Alt F11,F12}
  714. $8B..$8C : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF11 + ((KeyEvent AND $0000FF00) SHR 8) - $8B + $02000000;
  715. {Ctrl F1..F10}
  716. $5E..$67 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF1 + ((KeyEvent AND $0000FF00) SHR 8) - $5E + $02000000;
  717. {Ctrl F11,F12}
  718. $89..$8A : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdF11 + ((KeyEvent AND $0000FF00) SHR 8) - $89 + $02000000;
  719. {normal,ctrl,alt}
  720. $47,$77,$97 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdHome + $02000000;
  721. $48,$8D,$98 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdUp + $02000000;
  722. $49,$84,$99 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdPgUp + $02000000;
  723. $4b,$73,$9B : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdLeft + $02000000;
  724. $4d,$74,$9D : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdRight + $02000000;
  725. $4f,$75,$9F : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdEnd + $02000000;
  726. $50,$91,$A0 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdDown + $02000000;
  727. $51,$76,$A1 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdPgDn + $02000000;
  728. $52,$92,$A2 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdInsert + $02000000;
  729. $53,$93,$A3 : TranslateKeyEvent := (KeyEvent AND $FCFF0000) + kbdDelete + $02000000;
  730. else
  731. TranslateKeyEvent := KeyEvent;
  732. end;
  733. end else
  734. TranslateKeyEvent := KeyEvent;
  735. end;
  736. function TranslateKeyEventUniCode(KeyEvent: TKeyEvent): TKeyEvent;
  737. begin
  738. exit (KeyEvent); {???}
  739. end;
  740. function PollShiftStateEvent: TKeyEvent;
  741. var t : TKeyEvent;
  742. begin
  743. {may be better to save the last state and return that if no key is in buffer???}
  744. t := lastShiftState;
  745. PollShiftStateEvent := t shl 16;
  746. end;
  747. {
  748. $Log$
  749. Revision 1.2 2000-07-13 11:32:27 michael
  750. + removed logs
  751. }