keyboard.inc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858
  1. {
  2. System independent keyboard interface for linux
  3. $Id$
  4. }
  5. uses
  6. Linux;
  7. var
  8. OldIO : TermIos;
  9. {$ifdef logging}
  10. f : text;
  11. {$endif logging}
  12. Procedure SetRawMode(b:boolean);
  13. Var
  14. Tio : Termios;
  15. Begin
  16. TCGetAttr(1,Tio);
  17. if b then
  18. begin
  19. OldIO:=Tio;
  20. Tio.c_iflag:=Tio.c_iflag and (not (IGNBRK or BRKINT or PARMRK or ISTRIP or
  21. INLCR or IGNCR or ICRNL or IXON));
  22. Tio.c_lflag:=Tio.c_lflag and (not (ECHO or ECHONL or ICANON or ISIG or IEXTEN));
  23. end
  24. else
  25. Tio := OldIO;
  26. TCSetAttr(1,TCSANOW,Tio);
  27. End;
  28. type
  29. chgentry=packed record
  30. tab,
  31. idx,
  32. oldtab,
  33. oldidx : byte;
  34. oldval,
  35. newval : word;
  36. end;
  37. kbentry=packed record
  38. kb_table,
  39. kb_index : byte;
  40. kb_value : word;
  41. end;
  42. const
  43. kbdchanges=10;
  44. kbdchange:array[1..kbdchanges] of chgentry=(
  45. (tab:8; idx:$3b; oldtab:0; oldidx:$3b; oldval:0; newval:0),
  46. (tab:8; idx:$3c; oldtab:0; oldidx:$3c; oldval:0; newval:0),
  47. (tab:8; idx:$3d; oldtab:0; oldidx:$3d; oldval:0; newval:0),
  48. (tab:8; idx:$3e; oldtab:0; oldidx:$3e; oldval:0; newval:0),
  49. (tab:8; idx:$3f; oldtab:0; oldidx:$3f; oldval:0; newval:0),
  50. (tab:8; idx:$40; oldtab:0; oldidx:$40; oldval:0; newval:0),
  51. (tab:8; idx:$41; oldtab:0; oldidx:$41; oldval:0; newval:0),
  52. (tab:8; idx:$42; oldtab:0; oldidx:$42; oldval:0; newval:0),
  53. (tab:8; idx:$43; oldtab:0; oldidx:$43; oldval:0; newval:0),
  54. (tab:8; idx:$44; oldtab:0; oldidx:$44; oldval:0; newval:0)
  55. );
  56. KDGKBENT=$4B46;
  57. KDSKBENT=$4B47;
  58. procedure PatchKeyboard;
  59. var
  60. e : ^chgentry;
  61. entry : kbentry;
  62. i : longint;
  63. begin
  64. for i:=1to kbdchanges do
  65. begin
  66. e:=@kbdchange[i];
  67. entry.kb_table:=e^.tab;
  68. entry.kb_index:=e^.idx;
  69. Ioctl(stdinputhandle,KDGKBENT,@entry);
  70. e^.oldval:=entry.kb_value;
  71. entry.kb_table:=e^.oldtab;
  72. entry.kb_index:=e^.oldidx;
  73. ioctl(stdinputhandle,KDGKBENT,@entry);
  74. e^.newval:=entry.kb_value;
  75. end;
  76. for i:=1to kbdchanges do
  77. begin
  78. e:=@kbdchange[i];
  79. entry.kb_table:=e^.tab;
  80. entry.kb_index:=e^.idx;
  81. entry.kb_value:=e^.newval;
  82. Ioctl(stdinputhandle,KDSKBENT,@entry);
  83. end;
  84. end;
  85. procedure UnpatchKeyboard;
  86. var
  87. e : ^chgentry;
  88. entry : kbentry;
  89. i : longint;
  90. begin
  91. for i:=1to kbdchanges do
  92. begin
  93. e:=@kbdchange[i];
  94. entry.kb_table:=e^.tab;
  95. entry.kb_index:=e^.idx;
  96. entry.kb_value:=e^.oldval;
  97. Ioctl(stdinputhandle,KDSKBENT,@entry);
  98. end;
  99. end;
  100. { Buffered Input routines }
  101. const
  102. InSize=256;
  103. var
  104. InBuf : array[0..InSize-1] of char;
  105. InCnt,
  106. InHead,
  107. InTail : longint;
  108. function ttyRecvChar:char;
  109. var
  110. Readed,i : longint;
  111. begin
  112. {Buffer Empty? Yes, Input from StdIn}
  113. if (InHead=InTail) then
  114. begin
  115. {Calc Amount of Chars to Read}
  116. i:=InSize-InHead;
  117. if InTail>InHead then
  118. i:=InTail-InHead;
  119. {Read}
  120. Readed:=fdRead(StdInputHandle,InBuf[InHead],i);
  121. {Increase Counters}
  122. inc(InCnt,Readed);
  123. inc(InHead,Readed);
  124. {Wrap if End has Reached}
  125. if InHead>=InSize then
  126. InHead:=0;
  127. end;
  128. {Check Buffer}
  129. if (InCnt=0) then
  130. ttyRecvChar:=#0
  131. else
  132. begin
  133. ttyRecvChar:=InBuf[InTail];
  134. dec(InCnt);
  135. inc(InTail);
  136. if InTail>=InSize then
  137. InTail:=0;
  138. end;
  139. end;
  140. Const
  141. KeyBufferSize = 20;
  142. var
  143. KeyBuffer : Array[0..KeyBufferSize-1] of Char;
  144. KeyPut,
  145. KeySend : longint;
  146. Procedure PushKey(Ch:char);
  147. Var
  148. Tmp : Longint;
  149. Begin
  150. Tmp:=KeyPut;
  151. Inc(KeyPut);
  152. If KeyPut>=KeyBufferSize Then
  153. KeyPut:=0;
  154. If KeyPut<>KeySend Then
  155. KeyBuffer[Tmp]:=Ch
  156. Else
  157. KeyPut:=Tmp;
  158. End;
  159. Function PopKey:char;
  160. Begin
  161. If KeyPut<>KeySend Then
  162. Begin
  163. PopKey:=KeyBuffer[KeySend];
  164. Inc(KeySend);
  165. If KeySend>=KeyBufferSize Then
  166. KeySend:=0;
  167. End
  168. Else
  169. PopKey:=#0;
  170. End;
  171. Procedure PushExt(b:byte);
  172. begin
  173. PushKey(#0);
  174. PushKey(chr(b));
  175. end;
  176. const
  177. AltKeyStr : string[38]='qwertyuiopasdfghjklzxcvbnm1234567890-=';
  178. AltCodeStr : string[38]=#016#017#018#019#020#021#022#023#024#025#030#031#032#033#034#035#036#037#038+
  179. #044#045#046#047#048#049#050#120#121#122#123#124#125#126#127#128#129#130#131;
  180. Function FAltKey(ch:char):byte;
  181. var
  182. Idx : longint;
  183. Begin
  184. Idx:=Pos(ch,AltKeyStr);
  185. if Idx>0 then
  186. FAltKey:=byte(AltCodeStr[Idx])
  187. else
  188. FAltKey:=0;
  189. End;
  190. { This one doesn't care about keypresses already processed by readkey }
  191. { and waiting in the KeyBuffer, only about waiting keypresses at the }
  192. { TTYLevel (including ones that are waiting in the TTYRecvChar buffer) }
  193. function sysKeyPressed: boolean;
  194. var
  195. fdsin : fdSet;
  196. begin
  197. if (InCnt>0) then
  198. sysKeyPressed:=true
  199. else
  200. begin
  201. FD_Zero(fdsin);
  202. fd_Set(StdInputHandle,fdsin);
  203. sysKeypressed:=(Select(StdInputHandle+1,@fdsin,nil,nil,0)>0);
  204. end;
  205. end;
  206. Function KeyPressed:Boolean;
  207. Begin
  208. Keypressed := (KeySend<>KeyPut) or sysKeyPressed;
  209. End;
  210. {$ifdef DEBUG}
  211. Function RawReadKey:char;
  212. Var
  213. ch : char;
  214. OldState,
  215. State : longint;
  216. is_delay : boolean;
  217. fdsin : fdSet;
  218. Begin
  219. {Check Buffer first}
  220. if KeySend<>KeyPut then
  221. begin
  222. RawReadKey:=PopKey;
  223. exit;
  224. end;
  225. {Wait for Key}
  226. if not sysKeyPressed then
  227. begin
  228. FD_Zero (fdsin);
  229. FD_Set (StdInputHandle,fdsin);
  230. Select (StdInputHandle+1,@fdsin,nil,nil,nil);
  231. end;
  232. RawReadKey:=ttyRecvChar;
  233. end;
  234. {$endif DEBUG}
  235. Function ReadKey:char;
  236. Var
  237. ch : char;
  238. OldState,
  239. State : longint;
  240. is_delay : boolean;
  241. fdsin : fdSet;
  242. Begin
  243. {Check Buffer first}
  244. if KeySend<>KeyPut then
  245. begin
  246. ReadKey:=PopKey;
  247. exit;
  248. end;
  249. {Wait for Key}
  250. if not sysKeyPressed then
  251. begin
  252. FD_Zero (fdsin);
  253. FD_Set (StdInputHandle,fdsin);
  254. Select (StdInputHandle+1,@fdsin,nil,nil,nil);
  255. end;
  256. ch:=ttyRecvChar;
  257. {Esc Found ?}
  258. If (ch=#27) then
  259. begin
  260. FD_Zero(fdsin);
  261. fd_Set(StdInputHandle,fdsin);
  262. State:=1;
  263. {$ifdef logging}
  264. write(f,'Esc');
  265. {$endif logging}
  266. if InCnt=0 then
  267. Select(StdInputHandle+1,@fdsin,nil,nil,10);
  268. while (State<>0) and (sysKeyPressed) do
  269. begin
  270. ch:=ttyRecvChar;
  271. {$ifdef logging}
  272. if ord(ch)>31 then
  273. write(f,ch)
  274. else
  275. write(f,'#',ord(ch):2);
  276. {$endif logging}
  277. OldState:=State;
  278. State:=0;
  279. case OldState of
  280. 1 : begin {Esc}
  281. case ch of
  282. 'a'..'z',
  283. '0'..'9',
  284. '-','=' : PushExt(FAltKey(ch));
  285. #10 : PushKey(#10);
  286. #13 : PushKey(#10);
  287. #127 : PushKey(#8);
  288. '[' : State:=2;
  289. 'O' : State:=6;
  290. else
  291. begin
  292. PushKey(#27);
  293. PushKey(ch);
  294. end;
  295. end;
  296. end;
  297. 2 : begin {Esc[}
  298. case ch of
  299. '[' : State:=3;
  300. 'A' : PushExt(72);
  301. 'B' : PushExt(80);
  302. 'C' : PushExt(77);
  303. 'D' : PushExt(75);
  304. 'G' : PushKey('5');
  305. 'H' : PushExt(71);
  306. 'K' : PushExt(79);
  307. '1' : State:=4;
  308. '2' : State:=5;
  309. '3' : State:=12;{PushExt(83)}
  310. '4' : PushExt(79);
  311. '5' : PushExt(73);
  312. '6' : PushExt(81);
  313. '?' : State:=7;
  314. else
  315. begin
  316. PushKey(#27);
  317. PushKey('[');
  318. PushKey(ch);
  319. end;
  320. end;
  321. if ch in ['3'..'6'] then
  322. State:=255;
  323. end;
  324. 3 : begin {Esc[[}
  325. case ch of
  326. 'A' : PushExt(59);
  327. 'B' : PushExt(60);
  328. 'C' : PushExt(61);
  329. 'D' : PushExt(62);
  330. 'E' : PushExt(63);
  331. else
  332. begin
  333. PushKey(#27);
  334. PushKey('[');
  335. PushKey('[');
  336. PushKey(ch);
  337. end;
  338. end;
  339. end;
  340. 4 : begin {Esc[1}
  341. case ch of
  342. '~' : PushExt(71);
  343. '7' : PushExt(64);
  344. '8' : PushExt(65);
  345. '9' : PushExt(66);
  346. else
  347. begin
  348. PushKey(#27);
  349. PushKey('[');
  350. PushKey('1');
  351. PushKey(ch);
  352. end;
  353. end;
  354. if (Ch<>'~') then
  355. State:=255;
  356. end;
  357. 5 : begin {Esc[2}
  358. case ch of
  359. '~' : PushExt(82);
  360. '0' : pushExt(67);
  361. '1' : PushExt(68);
  362. '3' : PushExt($85){F11, but ShiftF1 also !!};
  363. '4' : PushExt($86){F12, but Shift F2 also !!};
  364. '5' : PushExt($56){ShiftF3};
  365. '6' : PushExt($57){ShiftF4};
  366. '8' : PushExt($58){ShiftF5};
  367. '9' : PushExt($59){ShiftF6};
  368. else
  369. begin
  370. PushKey(#27);
  371. PushKey('[');
  372. PushKey('2');
  373. PushKey(ch);
  374. end;
  375. end;
  376. if (Ch<>'~') then
  377. State:=255;
  378. end;
  379. 12 : begin {Esc[3}
  380. case ch of
  381. '~' : PushExt(83);
  382. '1' : PushExt($5A){ShiftF7};
  383. '2' : PushExt($5B){ShiftF8};
  384. '3' : PushExt($5C){ShiftF9};
  385. '4' : PushExt($5D){ShiftF10};
  386. else
  387. begin
  388. PushKey(#27);
  389. PushKey('[');
  390. PushKey('3');
  391. PushKey(ch);
  392. end;
  393. end;
  394. if (Ch<>'~') then
  395. State:=255;
  396. end;
  397. 6 : begin {EscO Function keys in vt100 mode PM }
  398. case ch of
  399. 'P' : {F1}PushExt(59);
  400. 'Q' : {F2}PushExt(60);
  401. 'R' : {F3}PushExt(61);
  402. 'S' : {F4}PushExt(62);
  403. 't' : {F5}PushExt(63);
  404. 'u' : {F6}PushExt(64);
  405. 'v' : {F7}PushExt(65);
  406. 'l' : {F8}PushExt(66);
  407. 'w' : {F9}PushExt(67);
  408. 'x' : {F10}PushExt(68);
  409. 'D' : {keyLeft}PushExt($4B);
  410. 'C' : {keyRight}PushExt($4D);
  411. 'A' : {keyUp}PushExt($48);
  412. 'B' : {keyDown}PushExt($50);
  413. else
  414. begin
  415. PushKey(#27);
  416. PushKey('O');
  417. PushKey(ch);
  418. end;
  419. end;
  420. end;
  421. 7 : begin {Esc[? keys in vt100 mode PM }
  422. case ch of
  423. '0' : State:=11;
  424. '1' : State:=8;
  425. '7' : State:=9;
  426. else
  427. begin
  428. PushKey(#27);
  429. PushKey('[');
  430. PushKey('?');
  431. PushKey(ch);
  432. end;
  433. end;
  434. end;
  435. 8 : begin {Esc[?1 keys in vt100 mode PM }
  436. case ch of
  437. 'l' : {local mode};
  438. 'h' : {transmit mode};
  439. ';' : { 'Esc[1;0c seems to be sent by M$ telnet app
  440. for no hangup purposes }
  441. state:=10;
  442. else
  443. begin
  444. PushKey(#27);
  445. PushKey('[');
  446. PushKey('?');
  447. PushKey('1');
  448. PushKey(ch);
  449. end;
  450. end;
  451. end;
  452. 9 : begin {Esc[?7 keys in vt100 mode PM }
  453. case ch of
  454. 'l' : {exit_am_mode};
  455. 'h' : {enter_am_mode};
  456. else
  457. begin
  458. PushKey(#27);
  459. PushKey('[');
  460. PushKey('?');
  461. PushKey('7');
  462. PushKey(ch);
  463. end;
  464. end;
  465. end;
  466. 10 : begin {Esc[?1; keys in vt100 mode PM }
  467. case ch of
  468. '0' : state:=11;
  469. else
  470. begin
  471. PushKey(#27);
  472. PushKey('[');
  473. PushKey('?');
  474. PushKey('1');
  475. PushKey(';');
  476. PushKey(ch);
  477. end;
  478. end;
  479. end;
  480. 11 : begin {Esc[?1;0 keys in vt100 mode PM }
  481. case ch of
  482. 'c' : ;
  483. else
  484. begin
  485. PushKey(#27);
  486. PushKey('[');
  487. PushKey('?');
  488. PushKey('1');
  489. PushKey(';');
  490. PushKey('0');
  491. PushKey(ch);
  492. end;
  493. end;
  494. end;
  495. 255 : { just forget this trailing char };
  496. end;
  497. if (State<>0) and (InCnt=0) then
  498. Select(StdInputHandle+1,@fdsin,nil,nil,10);
  499. end;
  500. if State=1 then
  501. PushKey(ch);
  502. if ch='$' then
  503. begin { '$<XX>' means a delay of XX millisecs }
  504. is_delay :=false;
  505. Select(StdInputHandle+1,@fdsin,nil,nil,10);
  506. if (sysKeyPressed) then
  507. begin
  508. ch:=ttyRecvChar;
  509. is_delay:=(ch='<');
  510. if not is_delay then
  511. begin
  512. PushKey('$');
  513. PushKey(ch);
  514. end
  515. else
  516. begin
  517. {$ifdef logging}
  518. write(f,'$<');
  519. {$endif logging}
  520. Select(StdInputHandle+1,@fdsin,nil,nil,10);
  521. while (sysKeyPressed) and (ch<>'>') do
  522. begin
  523. { Should we really repect this delay ?? }
  524. ch:=ttyRecvChar;
  525. {$ifdef logging}
  526. write(f,ch);
  527. {$endif logging}
  528. Select(StdInputHandle+1,@fdsin,nil,nil,10);
  529. end;
  530. end;
  531. end
  532. else
  533. PushKey('$');
  534. end;
  535. {$ifdef logging}
  536. writeln(f);
  537. {$endif logging}
  538. end
  539. else
  540. Begin
  541. case ch of
  542. #127 : PushKey(#8);
  543. else
  544. PushKey(ch);
  545. end;
  546. End;
  547. ReadKey:=PopKey;
  548. End;
  549. function ShiftState:byte;
  550. var
  551. arg,shift : longint;
  552. begin
  553. arg:=6;
  554. shift:=0;
  555. {$Ifndef BSD}
  556. if IOCtl(StdInputHandle,TIOCLINUX,@arg) then
  557. begin
  558. if (arg and (2 or 8))<>0 then
  559. inc(shift,8);
  560. if (arg and 4)<>0 then
  561. inc(shift,4);
  562. if (arg and 1)<>0 then
  563. inc(shift,3);
  564. end;
  565. {$endif}
  566. ShiftState:=shift;
  567. end;
  568. { Exported functions }
  569. procedure InitKeyboard;
  570. begin
  571. SetRawMode(true);
  572. patchkeyboard;
  573. {$ifdef logging}
  574. assign(f,'keyboard.log');
  575. rewrite(f);
  576. {$endif logging}
  577. end;
  578. procedure DoneKeyboard;
  579. begin
  580. unpatchkeyboard;
  581. SetRawMode(false);
  582. {$ifdef logging}
  583. close(f);
  584. {$endif logging}
  585. end;
  586. function GetKeyEvent: TKeyEvent;
  587. function EvalScan(b:byte):byte;
  588. const
  589. DScan:array[0..31] of byte = (
  590. $39, $02, $28, $04, $05, $06, $08, $28,
  591. $0A, $0B, $09, $0D, $33, $0C, $34, $35,
  592. $0B, $02, $03, $04, $05, $06, $07, $08,
  593. $09, $0A, $27, $27, $33, $0D, $34, $35);
  594. LScan:array[0..31] of byte = (
  595. $29, $1E, $30, $2E, $20, $12, $21, $22,
  596. $23, $17, $24, $25, $26, $32, $31, $18,
  597. $19, $10, $13, $1F, $14, $16, $2F, $11,
  598. $2D, $15, $2C, $1A, $2B, $1B, $29, $0C);
  599. begin
  600. if (b and $E0)=$20 { digits / leters } then
  601. EvalScan:=DScan[b and $1F]
  602. else
  603. case b of
  604. $08:EvalScan:=$0E; { backspace }
  605. $09:EvalScan:=$0F; { TAB }
  606. $0D:EvalScan:=$1C; { CR }
  607. $1B:EvalScan:=$01; { esc }
  608. $40:EvalScan:=$03; { @ }
  609. $5E:EvalScan:=$07; { ^ }
  610. $60:EvalScan:=$29; { ` }
  611. else
  612. EvalScan:=LScan[b and $1F];
  613. end;
  614. end;
  615. function EvalScanZ(b:byte):byte;
  616. begin
  617. EvalScanZ:=b;
  618. if b in [$3B..$44] { F1..F10 -> Alt-F1..Alt-F10} then
  619. EvalScanZ:=b+$2D;
  620. end;
  621. const
  622. CtrlArrow : array [71..81] of byte =
  623. ($77,$8d,$84,$8e,$73,$8f,$74,$90,$75,$91,$76);
  624. var
  625. MyScan,
  626. SState : byte;
  627. MyChar : char;
  628. begin {main}
  629. if PendingKeyEvent<>0 then
  630. begin
  631. GetKeyEvent:=PendingKeyEvent;
  632. PendingKeyEvent:=0;
  633. exit;
  634. end;
  635. MyChar:=Readkey;
  636. MyScan:=ord(MyChar);
  637. SState:=ShiftState;
  638. case MyChar of
  639. #26 : begin { ^Z - replace Alt for Linux OS }
  640. MyChar:=ReadKey;
  641. MyScan:=ord(MyChar);
  642. if MyScan=0 then
  643. MyScan:=EvalScanZ(ord(ReadKey))
  644. else
  645. begin
  646. MyScan:=EvalScan(ord(MyChar));
  647. if MyScan in [$02..$0D] then
  648. inc(MyScan,$76);
  649. MyChar:=chr(0);
  650. end;
  651. end;
  652. #0 : begin
  653. MyScan:=ord(ReadKey);
  654. { Handle Ctrl-<x> }
  655. if (SState and 4)<>0 then
  656. begin
  657. case MyScan of
  658. 71..81 : { cArrow }
  659. MyScan:=CtrlArrow[MyScan];
  660. $3b..$44 : { cF1-cF10 }
  661. MyScan:=MyScan+$23;
  662. end;
  663. end;
  664. { Handle Alt-<x> }
  665. if (SState and 8)<>0 then
  666. begin
  667. case MyScan of
  668. $3b..$44 : { aF1-aF10 }
  669. MyScan:=MyScan+$2d;
  670. end;
  671. end;
  672. end;
  673. else begin
  674. MyScan:=EvalScan(ord(MyChar));
  675. end;
  676. end;
  677. GetKeyEvent:=$3000000 or ord(MyChar) or (MyScan shl 8) or (SState shl 16);
  678. end;
  679. function PollKeyEvent: TKeyEvent;
  680. begin
  681. if PendingKeyEvent<>0 then
  682. exit(PendingKeyEvent);
  683. if keypressed then
  684. begin
  685. { just get the key and place it in the pendingkeyevent }
  686. PendingKeyEvent:=GetKeyEvent;
  687. PollKeyEvent:=PendingKeyEvent;
  688. end
  689. else
  690. PollKeyEvent:=0;
  691. end;
  692. function PollShiftStateEvent: TKeyEvent;
  693. begin
  694. PollShiftStateEvent:=ShiftState shl 16;
  695. end;
  696. { Function key translation }
  697. type
  698. TTranslationEntry = packed record
  699. Min, Max: Byte;
  700. Offset: Word;
  701. end;
  702. const
  703. TranslationTableEntries = 12;
  704. TranslationTable: array [1..TranslationTableEntries] of TTranslationEntry =
  705. ((Min: $3B; Max: $44; Offset: kbdF1), { function keys F1-F10 }
  706. (Min: $54; Max: $5D; Offset: kbdF1), { Shift fn keys F1-F10 }
  707. (Min: $5E; Max: $67; Offset: kbdF1), { Ctrl fn keys F1-F10 }
  708. (Min: $68; Max: $71; Offset: kbdF1), { Alt fn keys F1-F10 }
  709. (Min: $85; Max: $86; Offset: kbdF11), { function keys F11-F12 }
  710. (Min: $87; Max: $88; Offset: kbdF11), { Shift+function keys F11-F12 }
  711. (Min: $89; Max: $8A; Offset: kbdF11), { Ctrl+function keys F11-F12 }
  712. (Min: $8B; Max: $8C; Offset: kbdF11), { Alt+function keys F11-F12 }
  713. (Min: 71; Max: 73; Offset: kbdHome), { Keypad keys kbdHome-kbdPgUp }
  714. (Min: 75; Max: 77; Offset: kbdLeft), { Keypad keys kbdLeft-kbdRight }
  715. (Min: 79; Max: 81; Offset: kbdEnd), { Keypad keys kbdEnd-kbdPgDn }
  716. (Min: $52; Max: $53; Offset: kbdInsert));
  717. function TranslateKeyEvent(KeyEvent: TKeyEvent): TKeyEvent;
  718. var
  719. I: Integer;
  720. ScanCode: Byte;
  721. begin
  722. if KeyEvent and $03000000 = $03000000 then
  723. begin
  724. if KeyEvent and $000000FF <> 0 then
  725. begin
  726. TranslateKeyEvent := KeyEvent and $00FFFFFF;
  727. exit;
  728. end
  729. else
  730. begin
  731. { This is a function key }
  732. ScanCode := (KeyEvent and $0000FF00) shr 8;
  733. for I := 1 to TranslationTableEntries do
  734. begin
  735. if (TranslationTable[I].Min <= ScanCode) and (ScanCode <= TranslationTable[I].Max) then
  736. begin
  737. TranslateKeyEvent := $02000000 + (KeyEvent and $00FF0000) +
  738. (ScanCode - TranslationTable[I].Min) + TranslationTable[I].Offset;
  739. exit;
  740. end;
  741. end;
  742. end;
  743. end;
  744. TranslateKeyEvent := KeyEvent;
  745. end;
  746. function TranslateKeyEventUniCode(KeyEvent: TKeyEvent): TKeyEvent;
  747. begin
  748. TranslateKeyEventUniCode := KeyEvent;
  749. ErrorHandler(errKbdNotImplemented, nil);
  750. end;
  751. {
  752. $Log$
  753. Revision 1.2 2000-10-26 23:08:48 peter
  754. * merged freebsd from fixes
  755. Revision 1.1.2.1 2000/10/25 12:23:20 marco
  756. * Linux dir split up
  757. Revision 1.1.2.4 2000/10/19 07:41:35 pierre
  758. + added testkeyb for linux for get Escape sequences easily
  759. Revision 1.1.2.3 2000/10/19 07:29:01 pierre
  760. * enhance special keys support both in linux and vt100 mode
  761. Revision 1.1.2.2 2000/10/11 16:19:44 pierre
  762. * add support of function keys for vt100
  763. Revision 1.1.2.1 2000/09/25 13:18:37 jonas
  764. * added missing restoring of part of the termios info (even though those
  765. fields weren't changed, leaving them uninitialized when restoring
  766. won't do much good :)
  767. Revision 1.1 2000/07/13 06:29:39 michael
  768. + Initial import
  769. Revision 1.2 2000/06/30 09:00:33 jonas
  770. * compiles again with -dnomouse
  771. Revision 1.1 2000/01/06 01:20:31 peter
  772. * moved out of packages/ back to topdir
  773. Revision 1.1 1999/11/24 23:36:38 peter
  774. * moved to packages dir
  775. Revision 1.5 1999/02/16 10:44:53 peter
  776. * alt-f<x> support
  777. Revision 1.4 1998/12/15 10:30:34 peter
  778. + ctrl arrows support
  779. * better backspace
  780. Revision 1.3 1998/12/12 19:13:02 peter
  781. * keyboard updates
  782. * make test target, make all only makes units
  783. Revision 1.1 1998/12/04 12:48:30 peter
  784. * moved some dirs
  785. Revision 1.3 1998/10/29 12:49:48 peter
  786. * more fixes
  787. Revision 1.1 1998/10/26 11:31:47 peter
  788. + inital include files
  789. }