mouse.pp 5.1 KB

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