mouse.pp 5.1 KB

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