kbd.inc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. {
  2. Free Pascal port of the OpenPTC C++ library.
  3. Copyright (C) 2001-2003 Nikolay Nikolov ([email protected])
  4. Original C++ version by Glenn Fiedler ([email protected])
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. This library 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. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. }
  17. Constructor TWin32Keyboard.Create(window : HWND; thread : DWord; multithreaded : Boolean);
  18. Begin
  19. m_monitor := Nil;
  20. m_event := Nil;
  21. Inherited Create(window, thread);
  22. m_monitor := TWin32Monitor.Create;
  23. m_event := TWin32Event.Create;
  24. { defaults }
  25. m_key := False;
  26. m_head := 0;
  27. m_tail := 0;
  28. { setup defaults }
  29. m_alt := False;
  30. m_shift := False;
  31. m_control := False;
  32. { enable buffering }
  33. m_enabled := True;
  34. { setup data }
  35. m_multithreaded := multithreaded;
  36. End;
  37. Destructor TWin32Keyboard.Destroy;
  38. Begin
  39. m_event.Free;
  40. m_monitor.Free;
  41. Inherited Destroy;
  42. End;
  43. Function TWin32Keyboard.internal_PeekKey(window : TWin32Window; k : TPTCKey) : Boolean;
  44. Begin
  45. { check enabled flag }
  46. If Not m_enabled Then
  47. Begin
  48. Result := False;
  49. Exit;
  50. End;
  51. { enter monitor if multithreaded }
  52. If m_multithreaded Then
  53. m_monitor.enter;
  54. { update window }
  55. window.update;
  56. { is a key ready? }
  57. Result := ready;
  58. If Result = True Then
  59. k.ASSign(m_buffer[m_tail]);
  60. { leave monitor if multithreaded }
  61. If m_multithreaded Then
  62. m_monitor.leave;
  63. End;
  64. Procedure TWin32Keyboard.internal_ReadKey(window : TWin32Window; k : TPTCKey);
  65. Var
  66. read : TPTCKey;
  67. Begin
  68. read := Nil;
  69. Try
  70. { check enabled flag }
  71. If Not m_enabled Then
  72. Begin
  73. read := TPTCKey.Create;
  74. Exit;
  75. End;
  76. { check if multithreaded }
  77. If m_multithreaded Then
  78. Begin
  79. { check if ready }
  80. If Not ready Then
  81. Begin
  82. { wait for key event }
  83. m_event.wait;
  84. { reset event }
  85. m_event.reset;
  86. End;
  87. { enter monitor }
  88. m_monitor.enter;
  89. { remove key }
  90. read := remove;
  91. { leave monitor }
  92. m_monitor.leave;
  93. End
  94. Else
  95. Begin
  96. { update until ready }
  97. While Not ready Do
  98. { update window }
  99. window.update;
  100. { remove key }
  101. read := remove;
  102. End;
  103. Finally
  104. If Assigned(read) Then
  105. k.ASSign(read);
  106. read.Free;
  107. End;
  108. End;
  109. Procedure TWin32Keyboard.enable;
  110. Begin
  111. { enable buffering }
  112. m_enabled := True;
  113. End;
  114. Procedure TWin32Keyboard.disable;
  115. Begin
  116. { disable buffering }
  117. m_enabled := False;
  118. End;
  119. Function TWin32Keyboard.WndProc(hWnd : HWND; message : DWord; wParam : WPARAM; lParam : LPARAM) : LRESULT;
  120. Var
  121. i : Integer;
  122. scancode : Integer;
  123. KeyStateArray : Array[0..255] Of Byte;
  124. AsciiBuf : Word;
  125. press : Boolean;
  126. uni : Integer;
  127. tmp : Integer;
  128. Begin
  129. WndProc := 0;
  130. { check enabled flag }
  131. If Not m_enabled Then
  132. Exit;
  133. { process key message }
  134. If (message = WM_KEYDOWN) Or (message = WM_KEYUP) {Or ((message = WM_SYSKEYDOWN) And ((lParam And (1 Shl 29)) <> 0))} Then
  135. Begin
  136. If message = WM_KEYUP Then
  137. press := False
  138. Else
  139. press := True;
  140. { update modifiers }
  141. If wParam = VK_MENU Then
  142. { alt }
  143. m_alt := press
  144. Else
  145. If wParam = VK_SHIFT Then
  146. { shift }
  147. m_shift := press
  148. Else
  149. If wParam = VK_CONTROL Then
  150. { control }
  151. m_control := press;
  152. { enter monitor if multithreaded }
  153. If m_multithreaded Then
  154. m_monitor.enter;
  155. uni := -1;
  156. If GetKeyboardState(@KeyStateArray) Then
  157. Begin
  158. scancode := (lParam Shr 16) And $FF;
  159. {todo: ToUnicode (Windows NT)}
  160. tmp := ToAscii(wParam, scancode, @KeyStateArray, @AsciiBuf, 0);
  161. If (tmp = 1) Or (tmp = 2) Then
  162. Begin
  163. If tmp = 2 Then
  164. Begin
  165. // Writeln('[', AsciiBuf, ']'); {???? todo: dead keys ????}
  166. End
  167. Else
  168. Begin
  169. // Write(Chr(AsciiBuf));
  170. {todo: codepage -> unicode}
  171. If AsciiBuf <= 126 Then
  172. uni := AsciiBuf;
  173. End;
  174. End;
  175. End;
  176. { handle key repeat count }
  177. For i := 1 To lParam And $FFFF Do
  178. { create and insert key object }
  179. insert(TPTCKey.Create(wParam, uni, m_alt, m_shift, m_control, press));
  180. { check multithreaded flag }
  181. If m_multithreaded Then
  182. Begin
  183. { set event }
  184. m_event._set;
  185. { leave monitor }
  186. m_monitor.leave;
  187. End;
  188. End;
  189. (* Else
  190. If message = WM_KEYUP Then
  191. { update modifiers }
  192. If wParam = VK_MENU Then
  193. { alt up }
  194. m_alt := False
  195. Else
  196. If wParam = VK_SHIFT Then
  197. { shift up }
  198. m_shift := False
  199. Else
  200. If wParam = VK_CONTROL Then
  201. { control up }
  202. m_control := False;*)
  203. End;
  204. Procedure TWin32Keyboard.insert(_key : TPTCKey);
  205. Begin
  206. { check for overflow }
  207. If (m_head <> (m_tail - 1)) And
  208. ((m_tail <> 0) Or (m_head <> High(m_buffer))) Then
  209. Begin
  210. { insert key at head }
  211. m_buffer[m_head] := _key;
  212. { increase head }
  213. Inc(m_head);
  214. { wrap head from end to start }
  215. If m_head > High(m_buffer) Then
  216. m_head := Low(m_buffer);
  217. End;
  218. End;
  219. Function TWin32Keyboard.remove : TPTCKey;
  220. Begin
  221. { return key data from tail }
  222. remove := m_buffer[m_tail];
  223. { increase tail }
  224. Inc(m_tail);
  225. { wrap tail from end to start }
  226. If m_tail > High(m_buffer) Then
  227. m_tail := Low(m_buffer);
  228. End;
  229. Function TWin32Keyboard.ready : Boolean;
  230. Begin
  231. ready := m_head <> m_tail;
  232. End;