keyboard.pp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. Keyboard unit for linux
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit Keyboard;
  14. interface
  15. {$i keybrdh.inc}
  16. implementation
  17. uses
  18. KbdCalls, DosCalls;
  19. {$i keyboard.inc}
  20. const
  21. DefaultKeyboard = 0;
  22. Handle: word = DefaultKeyboard;
  23. procedure InitKeyboard;
  24. var
  25. K: TKbdInfo;
  26. begin
  27. if KbdGetFocus (IO_Wait, DefaultKeyboard) = No_Error then
  28. begin
  29. if KbdOpen (Handle) <> No_Error then Handle := DefaultKeyboard;
  30. KbdFlushBuffer (Handle);
  31. KbdFreeFocus (DefaultKeyboard);
  32. KbdGetFocus (IO_Wait, Handle);
  33. K.cb := 10;
  34. KbdGetStatus (K, Handle);
  35. K.fsMask := $14;
  36. KbdSetStatus (K, Handle);
  37. end;
  38. end;
  39. procedure DoneKeyboard;
  40. begin
  41. KbdFreeFocus (Handle);
  42. if KbdGetFocus (IO_Wait, DefaultKeyboard) = No_Error then
  43. begin
  44. KbdClose (Handle);
  45. Handle := DefaultKeyboard;
  46. KbdFreeFocus (DefaultKeyboard);
  47. end;
  48. end;
  49. function GetKeyEvent: TKeyEvent;
  50. var
  51. K: TKbdKeyInfo;
  52. begin
  53. if PendingKeyEvent <> 0 then
  54. begin
  55. GetKeyEvent := PendingKeyEvent;
  56. PendingKeyEvent := 0;
  57. end else
  58. begin
  59. KbdGetFocus (IO_Wait, Handle);
  60. while (KbdCharIn (K, IO_Wait, Handle) <> No_Error)
  61. or (K.fbStatus and $40 = 0) do DosSleep (5);
  62. with K do
  63. begin
  64. if (byte (chChar) = $E0) and (fbStatus and 2 <> 0) then chChar := #0;
  65. GetKeyEvent := cardinal ($0300 or fsState and $F) shl 16 or
  66. cardinal (byte (chScan)) shl 8 or byte (chChar);
  67. end;
  68. end;
  69. end;
  70. function PollKeyEvent: TKeyEvent;
  71. var
  72. K: TKbdKeyInfo;
  73. begin
  74. if PendingKeyEvent = 0 then
  75. begin
  76. KbdGetFocus (IO_NoWait, Handle);
  77. if (KbdCharIn (K, IO_NoWait, Handle) <> No_Error) or
  78. (K.fbStatus and $40 = 0) then FillChar (K, SizeOf (K), 0) else
  79. with K do
  80. begin
  81. if (byte (chChar) = $E0) and (fbStatus and 2 <> 0) then chChar := #0;
  82. PendingKeyEvent := cardinal ($0300 or fsState and $F) shl 16 or
  83. cardinal (byte (chScan)) shl 8 or byte (chChar);
  84. end;
  85. end;
  86. PollKeyEvent := PendingKeyEvent;
  87. if PendingKeyEvent and $FFFF = 0 then PendingKeyEvent := 0;
  88. end;
  89. function PollShiftStateEvent: TKeyEvent;
  90. var
  91. K: TKbdInfo;
  92. begin
  93. KbdGetFocus (IO_NoWait, Handle);
  94. KbdGetStatus (K, Handle);
  95. PollShiftStateEvent := cardinal (K.fsState and $F) shl 16;
  96. end;
  97. type
  98. TTranslationEntry = packed record
  99. Min, Max: byte;
  100. Offset: word;
  101. end;
  102. const
  103. TranslationTableEntries = 12;
  104. TranslationTable: array [1..TranslationTableEntries] of TTranslationEntry =
  105. ((Min: $3B; Max: $44; Offset: kbdF1), { function keys F1-F10 }
  106. (Min: $54; Max: $5D; Offset: kbdF1), { Shift fn keys F1-F10 }
  107. (Min: $5E; Max: $67; Offset: kbdF1), { Ctrl fn keys F1-F10 }
  108. (Min: $68; Max: $71; Offset: kbdF1), { Alt fn keys F1-F10 }
  109. (Min: $85; Max: $86; Offset: kbdF11), { function keys F11-F12 }
  110. (Min: $87; Max: $88; Offset: kbdF11), { Shift+function keys F11-F12 }
  111. (Min: $89; Max: $8A; Offset: kbdF11), { Ctrl+function keys F11-F12 }
  112. (Min: $8B; Max: $8C; Offset: kbdF11), { Alt+function keys F11-F12 }
  113. (Min: 71; Max: 73; Offset: kbdHome), { Keypad keys kbdHome-kbdPgUp }
  114. (Min: 75; Max: 77; Offset: kbdLeft), { Keypad keys kbdLeft-kbdRight }
  115. (Min: 79; Max: 81; Offset: kbdEnd), { Keypad keys kbdEnd-kbdPgDn }
  116. (Min: $52; Max: $53; Offset: kbdInsert));
  117. function TranslateKeyEvent (KeyEvent: TKeyEvent): TKeyEvent;
  118. var
  119. I: integer;
  120. ScanCode: byte;
  121. begin
  122. if KeyEvent and $03000000 = $03000000 then
  123. begin
  124. if (KeyEvent and $000000FF <> 0) and (KeyEvent and $000000FF <> $E0) then
  125. TranslateKeyEvent := KeyEvent and $00FFFFFF else
  126. begin
  127. { This is a function key }
  128. ScanCode := (KeyEvent and $0000FF00) shr 8;
  129. I := 1;
  130. while (I <= TranslationTableEntries) and
  131. ((TranslationTable [I].Min > ScanCode) or
  132. (ScanCode > TranslationTable [I].Max)) do Inc (I);
  133. if I > TranslationTableEntries then TranslateKeyEvent := KeyEvent else
  134. TranslateKeyEvent := $02000000 + (KeyEvent and $00FF0000) +
  135. (ScanCode - TranslationTable[I].Min) + TranslationTable[I].Offset;
  136. end;
  137. end else TranslateKeyEvent := KeyEvent;
  138. end;
  139. function TranslateKeyEventUniCode (KeyEvent: TKeyEvent): TKeyEvent;
  140. begin
  141. TranslateKeyEventUniCode := KeyEvent;
  142. ErrorHandler (errKbdNotImplemented, nil);
  143. end;
  144. end.
  145. {
  146. $Log$
  147. Revision 1.1 2001-01-13 11:03:58 peter
  148. * API 2 RTL commit
  149. }