mouse.pp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. Mouse 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 Mouse;
  14. interface
  15. const
  16. MouseEventBufSize = 255;
  17. {$i mouseh.inc}
  18. implementation
  19. uses
  20. windows,dos,Winevent;
  21. var
  22. ChangeMouseEvents : TCriticalSection;
  23. Const
  24. MouseEventActive : Boolean = false;
  25. procedure MouseEventHandler(var ir:INPUT_RECORD);
  26. var
  27. dwRead : DWord;
  28. i: longint;
  29. e : TMouseEvent;
  30. begin
  31. EnterCriticalSection(ChangeMouseEvents);
  32. e.x:=ir.MouseEvent.dwMousePosition.x;
  33. e.y:=ir.MouseEvent.dwMousePosition.y;
  34. e.buttons:=0;
  35. e.action:=0;
  36. if (ir.MouseEvent.dwButtonState and FROM_LEFT_1ST_BUTTON_PRESSED<>0) then
  37. e.buttons:=e.buttons or MouseLeftButton;
  38. if (ir.MouseEvent.dwButtonState and FROM_LEFT_2ND_BUTTON_PRESSED<>0) then
  39. e.buttons:=e.buttons or MouseMiddleButton;
  40. if (ir.MouseEvent.dwButtonState and RIGHTMOST_BUTTON_PRESSED<>0) then
  41. e.buttons:=e.buttons or MouseRightButton;
  42. { can we compress the events? }
  43. if (PendingMouseEvents>0) and
  44. (e.buttons=PendingMouseTail^.buttons) and
  45. (e.action=PendingMouseTail^.action) then
  46. begin
  47. PendingMouseTail^.x:=e.x;
  48. PendingMouseTail^.y:=e.y;
  49. end
  50. else
  51. begin
  52. PutMouseEvent(e);
  53. // this should be done in PutMouseEvent, now it is PM
  54. // inc(PendingMouseEvents);
  55. end;
  56. LeaveCriticalSection(ChangeMouseEvents);
  57. end;
  58. procedure InitMouse;
  59. var
  60. mode : dword;
  61. begin
  62. if MouseEventActive then
  63. exit;
  64. // enable mouse events
  65. GetConsoleMode(StdInputHandle,@mode);
  66. mode:=mode or ENABLE_MOUSE_INPUT;
  67. SetConsoleMode(StdInputHandle,mode);
  68. PendingMouseHead:=@PendingMouseEvent;
  69. PendingMouseTail:=@PendingMouseEvent;
  70. PendingMouseEvents:=0;
  71. FillChar(LastMouseEvent,sizeof(TMouseEvent),0);
  72. InitializeCriticalSection(ChangeMouseEvents);
  73. SetMouseEventHandler(@MouseEventHandler);
  74. ShowMouse;
  75. MouseEventActive:=true;
  76. end;
  77. procedure DoneMouse;
  78. var
  79. mode : dword;
  80. begin
  81. if not MouseEventActive then
  82. exit;
  83. HideMouse;
  84. // disable mouse events
  85. GetConsoleMode(StdInputHandle,@mode);
  86. mode:=mode and (not ENABLE_MOUSE_INPUT);
  87. SetConsoleMode(StdInputHandle,mode);
  88. SetMouseEventHandler(nil);
  89. DeleteCriticalSection(ChangeMouseEvents);
  90. MouseEventActive:=false;
  91. end;
  92. function DetectMouse:byte;
  93. var
  94. num : dword;
  95. begin
  96. GetNumberOfConsoleMouseButtons(@num);
  97. DetectMouse:=num;
  98. end;
  99. procedure ShowMouse;
  100. begin
  101. end;
  102. procedure HideMouse;
  103. begin
  104. end;
  105. function GetMouseX:word;
  106. begin
  107. GetMouseX:=0;
  108. end;
  109. function GetMouseY:word;
  110. begin
  111. GetMouseY:=0;
  112. end;
  113. function GetMouseButtons:word;
  114. begin
  115. GetMouseButtons:=0;
  116. end;
  117. procedure SetMouseXY(x,y:word);
  118. begin
  119. end;
  120. procedure GetMouseEvent(var MouseEvent: TMouseEvent);
  121. var
  122. b : byte;
  123. begin
  124. repeat
  125. EnterCriticalSection(ChangeMouseEvents);
  126. b:=PendingMouseEvents;
  127. LeaveCriticalSection(ChangeMouseEvents);
  128. if b>0 then
  129. break
  130. else
  131. sleep(50);
  132. until false;
  133. EnterCriticalSection(ChangeMouseEvents);
  134. MouseEvent:=PendingMouseHead^;
  135. inc(PendingMouseHead);
  136. if longint(PendingMouseHead)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
  137. PendingMouseHead:=@PendingMouseEvent;
  138. dec(PendingMouseEvents);
  139. if (LastMouseEvent.x<>MouseEvent.x) or (LastMouseEvent.y<>MouseEvent.y) then
  140. MouseEvent.Action:=MouseActionMove;
  141. if (LastMouseEvent.Buttons<>MouseEvent.Buttons) then
  142. begin
  143. if (LastMouseEvent.Buttons=0) then
  144. MouseEvent.Action:=MouseActionDown
  145. else
  146. MouseEvent.Action:=MouseActionUp;
  147. end;
  148. LastMouseEvent:=MouseEvent;
  149. LeaveCriticalSection(ChangeMouseEvents);
  150. end;
  151. function PollMouseEvent(var MouseEvent: TMouseEvent):boolean;
  152. begin
  153. EnterCriticalSection(ChangeMouseEvents);
  154. if PendingMouseEvents>0 then
  155. begin
  156. MouseEvent:=PendingMouseHead^;
  157. PollMouseEvent:=true;
  158. end
  159. else
  160. PollMouseEvent:=false;
  161. LeaveCriticalSection(ChangeMouseEvents);
  162. end;
  163. procedure PutMouseEvent(const MouseEvent: TMouseEvent);
  164. begin
  165. if PendingMouseEvents<MouseEventBufSize then
  166. begin
  167. PendingMouseTail^:=MouseEvent;
  168. inc(PendingMouseTail);
  169. if longint(PendingMouseTail)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
  170. PendingMouseTail:=@PendingMouseEvent;
  171. { why isn't this done here ?
  172. so the win32 version do this by hand:}
  173. inc(PendingMouseEvents);
  174. end;
  175. end;
  176. end.
  177. {
  178. $Log$
  179. Revision 1.2 2001-01-14 22:20:00 peter
  180. * slightly optimized event handling (merged)
  181. Revision 1.1 2001/01/13 11:03:59 peter
  182. * API 2 RTL commit
  183. }