Browse Source

* fix to lastmouseevent update

marco 20 years ago
parent
commit
1910cee059
1 changed files with 254 additions and 250 deletions
  1. 254 250
      rtl/win32/mouse.pp

+ 254 - 250
rtl/win32/mouse.pp

@@ -1,251 +1,255 @@
-{
-    $Id$
-    This file is part of the Free Pascal run time library.
-    Copyright (c) 1999-2000 by Florian Klaempfl
-    member of the Free Pascal development team
-
-    Mouse unit for linux
-
-    See the file COPYING.FPC, included in this distribution,
-    for details about the copyright.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- **********************************************************************}
-unit Mouse;
-interface
-
-{$i mouseh.inc}
-
-implementation
-
-uses
-   windows,dos,Winevent;
-
-{$i mouse.inc}
-
-var
-   ChangeMouseEvents : TCriticalSection;
-   LastHandlerMouseEvent : TMouseEvent;
-
-procedure MouseEventHandler(var ir:INPUT_RECORD);
-
-  var
-     e : TMouseEvent;
-
-  begin
-          EnterCriticalSection(ChangeMouseEvents);
-          e.x:=ir.Event.MouseEvent.dwMousePosition.x;
-          e.y:=ir.Event.MouseEvent.dwMousePosition.y;
-          e.buttons:=0;
-          e.action:=0;
-          if (ir.Event.MouseEvent.dwButtonState and FROM_LEFT_1ST_BUTTON_PRESSED<>0) then
-            e.buttons:=e.buttons or MouseLeftButton;
-          if (ir.Event.MouseEvent.dwButtonState and FROM_LEFT_2ND_BUTTON_PRESSED<>0) then
-            e.buttons:=e.buttons or MouseMiddleButton;
-          if (ir.Event.MouseEvent.dwButtonState and RIGHTMOST_BUTTON_PRESSED<>0) then
-            e.buttons:=e.buttons or MouseRightButton;
-
-          if (Lasthandlermouseevent.x<>e.x) or (LasthandlerMouseEvent.y<>e.y) then
-            e.Action:=MouseActionMove;
-          if (LastHandlerMouseEvent.Buttons<>e.Buttons) then
-           begin
-            if (LasthandlerMouseEvent.Buttons and e.buttons<>LasthandlerMouseEvent.Buttons) then
-              e.Action:=MouseActionUp
-            else
-              e.Action:=MouseActionDown;
-           end;
-
-
-//
-//  The mouse event compression here was flawed and could lead
-//  to "zero" mouse actions if the new (x,y) was the same as the
-//  previous one. (bug 2312)
-//
-
-           { can we compress the events? }
-         if (PendingMouseEvents>0) and
-            (e.buttons=PendingMouseTail^.buttons) and
-            (e.action=PendingMouseTail^.action) then
-            begin
-               PendingMouseTail^.x:=e.x;
-               PendingMouseTail^.y:=e.y;
-            end
-          else
-            begin
-
-               if e.action<>0 then
-                 begin
-                   LastHandlermouseEvent:=e;
-                   PutMouseEvent(e);
-                 end;
-               // this should be done in PutMouseEvent, now it is PM
-               // inc(PendingMouseEvents);
-            end;
-          LeaveCriticalSection(ChangeMouseEvents);
-  end;
-
-procedure SysInitMouse;
-
-var
-   mode : dword;
-
-begin
-  // enable mouse events
-  GetConsoleMode(StdInputHandle,@mode);
-  mode:=mode or ENABLE_MOUSE_INPUT;
-  SetConsoleMode(StdInputHandle,mode);
-
-  PendingMouseHead:=@PendingMouseEvent;
-  PendingMouseTail:=@PendingMouseEvent;
-  PendingMouseEvents:=0;
-  FillChar(LastMouseEvent,sizeof(TMouseEvent),0);
-  InitializeCriticalSection(ChangeMouseEvents);
-  SetMouseEventHandler(@MouseEventHandler);
-  ShowMouse;
-end;
-
-
-procedure SysDoneMouse;
-var
-   mode : dword;
-begin
-  HideMouse;
-  // disable mouse events
-  GetConsoleMode(StdInputHandle,@mode);
-  mode:=mode and (not ENABLE_MOUSE_INPUT);
-  SetConsoleMode(StdInputHandle,mode);
-
-  SetMouseEventHandler(nil);
-  DeleteCriticalSection(ChangeMouseEvents);
-end;
-
-
-function SysDetectMouse:byte;
-var
-  num : dword;
-begin
-  GetNumberOfConsoleMouseButtons(@num);
-  SysDetectMouse:=num;
-end;
-
-
-procedure SysGetMouseEvent(var MouseEvent: TMouseEvent);
-
-var
-   b : byte;
-
-begin
-  repeat
-    EnterCriticalSection(ChangeMouseEvents);
-    b:=PendingMouseEvents;
-    LeaveCriticalSection(ChangeMouseEvents);
-    if b>0 then
-      break
-    else
-      sleep(50);
-  until false;
-  EnterCriticalSection(ChangeMouseEvents);
-  MouseEvent:=PendingMouseHead^;
-  inc(PendingMouseHead);
-  if longint(PendingMouseHead)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
-   PendingMouseHead:=@PendingMouseEvent;
-  dec(PendingMouseEvents);
-  if (LastMouseEvent.x<>MouseEvent.x) or (LastMouseEvent.y<>MouseEvent.y) then
-   MouseEvent.Action:=MouseActionMove;
-  if (LastMouseEvent.Buttons<>MouseEvent.Buttons) then
-   begin
-     if (LastMouseEvent.Buttons and MouseEvent.buttons<>LastMouseEvent.Buttons) then
-       MouseEvent.Action:=MouseActionUp
-     else
-       MouseEvent.Action:=MouseActionDown;
-   end;
-  if MouseEvent.action=0 then MousEevent.action:=MouseActionMove; // can sometimes happen due to compression of events.
-  LastMouseEvent:=MouseEvent;
-  LeaveCriticalSection(ChangeMouseEvents);
-end;
-
-
-function SysPollMouseEvent(var MouseEvent: TMouseEvent):boolean;
-begin
-  EnterCriticalSection(ChangeMouseEvents);
-  if PendingMouseEvents>0 then
-   begin
-     MouseEvent:=PendingMouseHead^;
-     SysPollMouseEvent:=true;
-   end
-  else
-   SysPollMouseEvent:=false;
-  LeaveCriticalSection(ChangeMouseEvents);
-end;
-
-
-procedure SysPutMouseEvent(const MouseEvent: TMouseEvent);
-begin
-  if PendingMouseEvents<MouseEventBufSize then
-   begin
-     PendingMouseTail^:=MouseEvent;
-     inc(PendingMouseTail);
-     if longint(PendingMouseTail)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
-      PendingMouseTail:=@PendingMouseEvent;
-      { why isn't this done here ?
-        so the win32 version do this by hand:}
-       inc(PendingMouseEvents);
-   end;
-end;
-
-
-function SysGetMouseX:word;
-begin
-  EnterCriticalSection(ChangeMouseEvents);
-  SysGetMouseX:=LastMouseEvent.x;
-  LeaveCriticalSection(ChangeMouseEvents);
-end;
-
-
-function SysGetMouseY:word;
-begin
-  EnterCriticalSection(ChangeMouseEvents);
-  SysGetMouseY:=LastMouseEvent.y;
-  LeaveCriticalSection(ChangeMouseEvents);
-end;
-
-
-function SysGetMouseButtons:word;
-begin
-  EnterCriticalSection(ChangeMouseEvents);
-  SysGetMouseButtons:=LastMouseEvent.Buttons;
-  LeaveCriticalSection(ChangeMouseEvents);
-end;
-
-Const
-  SysMouseDriver : TMouseDriver = (
-    UseDefaultQueue : False;
-    InitDriver      : @SysInitMouse;
-    DoneDriver      : @SysDoneMouse;
-    DetectMouse     : @SysDetectMouse;
-    ShowMouse       : Nil;
-    HideMouse       : Nil;
-    GetMouseX       : @SysGetMouseX;
-    GetMouseY       : @SysGetMouseY;
-    GetMouseButtons : @SysGetMouseButtons;
-    SetMouseXY      : Nil;
-    GetMouseEvent   : @SysGetMouseEvent;
-    PollMouseEvent  : @SysPollMouseEvent;
-    PutMouseEvent   : @SysPutMouseEvent;
-  );
-
-Begin
-  SetMouseDriver(SysMouseDriver);
-end.
-{
+{
+    $Id$
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Florian Klaempfl
+    member of the Free Pascal development team
+
+    Mouse unit for linux
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+unit Mouse;
+interface
+
+{$i mouseh.inc}
+
+implementation
+
+uses
+   windows,dos,Winevent;
+
+{$i mouse.inc}
+
+var
+   ChangeMouseEvents : TCriticalSection;
+   LastHandlerMouseEvent : TMouseEvent;
+
+procedure MouseEventHandler(var ir:INPUT_RECORD);
+
+  var
+     e : TMouseEvent;
+
+  begin
+          EnterCriticalSection(ChangeMouseEvents);
+          e.x:=ir.Event.MouseEvent.dwMousePosition.x;
+          e.y:=ir.Event.MouseEvent.dwMousePosition.y;
+          e.buttons:=0;
+          e.action:=0;
+          if (ir.Event.MouseEvent.dwButtonState and FROM_LEFT_1ST_BUTTON_PRESSED<>0) then
+            e.buttons:=e.buttons or MouseLeftButton;
+          if (ir.Event.MouseEvent.dwButtonState and FROM_LEFT_2ND_BUTTON_PRESSED<>0) then
+            e.buttons:=e.buttons or MouseMiddleButton;
+          if (ir.Event.MouseEvent.dwButtonState and RIGHTMOST_BUTTON_PRESSED<>0) then
+            e.buttons:=e.buttons or MouseRightButton;
+
+          if (Lasthandlermouseevent.x<>e.x) or (LasthandlerMouseEvent.y<>e.y) then
+            e.Action:=MouseActionMove;
+          if (LastHandlerMouseEvent.Buttons<>e.Buttons) then
+           begin
+            if (LasthandlerMouseEvent.Buttons and e.buttons<>LasthandlerMouseEvent.Buttons) then
+              e.Action:=MouseActionUp
+            else
+              e.Action:=MouseActionDown;
+           end;
+
+
+//
+//  The mouse event compression here was flawed and could lead
+//  to "zero" mouse actions if the new (x,y) was the same as the
+//  previous one. (bug 2312)
+//
+
+           { can we compress the events? }
+         if (PendingMouseEvents>0) and
+            (e.buttons=PendingMouseTail^.buttons) and
+            (e.action=PendingMouseTail^.action) then
+            begin
+               PendingMouseTail^.x:=e.x;
+               PendingMouseTail^.y:=e.y;
+            end
+          else
+            begin
+
+               if e.action<>0 then
+                 begin
+                   LastHandlermouseEvent:=e;
+                   PutMouseEvent(e);
+                 end;
+               // this should be done in PutMouseEvent, now it is PM
+               // inc(PendingMouseEvents);
+            end;
+          LastMouseEvent:=e;
+          LeaveCriticalSection(ChangeMouseEvents);
+  end;
+
+procedure SysInitMouse;
+
+var
+   mode : dword;
+
+begin
+  // enable mouse events
+  GetConsoleMode(StdInputHandle,@mode);
+  mode:=mode or ENABLE_MOUSE_INPUT;
+  SetConsoleMode(StdInputHandle,mode);
+
+  PendingMouseHead:=@PendingMouseEvent;
+  PendingMouseTail:=@PendingMouseEvent;
+  PendingMouseEvents:=0;
+  FillChar(LastMouseEvent,sizeof(TMouseEvent),0);
+  InitializeCriticalSection(ChangeMouseEvents);
+  SetMouseEventHandler(@MouseEventHandler);
+  ShowMouse;
+end;
+
+
+procedure SysDoneMouse;
+var
+   mode : dword;
+begin
+  HideMouse;
+  // disable mouse events
+  GetConsoleMode(StdInputHandle,@mode);
+  mode:=mode and (not ENABLE_MOUSE_INPUT);
+  SetConsoleMode(StdInputHandle,mode);
+
+  SetMouseEventHandler(nil);
+  DeleteCriticalSection(ChangeMouseEvents);
+end;
+
+
+function SysDetectMouse:byte;
+var
+  num : dword;
+begin
+  GetNumberOfConsoleMouseButtons(@num);
+  SysDetectMouse:=num;
+end;
+
+
+procedure SysGetMouseEvent(var MouseEvent: TMouseEvent);
+
+var
+   b : byte;
+
+begin
+  repeat
+    EnterCriticalSection(ChangeMouseEvents);
+    b:=PendingMouseEvents;
+    LeaveCriticalSection(ChangeMouseEvents);
+    if b>0 then
+      break
+    else
+      sleep(50);
+  until false;
+  EnterCriticalSection(ChangeMouseEvents);
+  MouseEvent:=PendingMouseHead^;
+  inc(PendingMouseHead);
+  if longint(PendingMouseHead)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
+   PendingMouseHead:=@PendingMouseEvent;
+  dec(PendingMouseEvents);
+  if (LastMouseEvent.x<>MouseEvent.x) or (LastMouseEvent.y<>MouseEvent.y) then
+   MouseEvent.Action:=MouseActionMove;
+  if (LastMouseEvent.Buttons<>MouseEvent.Buttons) then
+   begin
+     if (LastMouseEvent.Buttons and MouseEvent.buttons<>LastMouseEvent.Buttons) then
+       MouseEvent.Action:=MouseActionUp
+     else
+       MouseEvent.Action:=MouseActionDown;
+   end;
+  if MouseEvent.action=0 then MousEevent.action:=MouseActionMove; // can sometimes happen due to compression of events.
+  LastMouseEvent:=MouseEvent;
+  LeaveCriticalSection(ChangeMouseEvents);
+end;
+
+
+function SysPollMouseEvent(var MouseEvent: TMouseEvent):boolean;
+begin
+  EnterCriticalSection(ChangeMouseEvents);
+  if PendingMouseEvents>0 then
+   begin
+     MouseEvent:=PendingMouseHead^;
+     SysPollMouseEvent:=true;
+   end
+  else
+   SysPollMouseEvent:=false;
+  LeaveCriticalSection(ChangeMouseEvents);
+end;
+
+
+procedure SysPutMouseEvent(const MouseEvent: TMouseEvent);
+begin
+  if PendingMouseEvents<MouseEventBufSize then
+   begin
+     PendingMouseTail^:=MouseEvent;
+     inc(PendingMouseTail);
+     if longint(PendingMouseTail)=longint(@PendingMouseEvent)+sizeof(PendingMouseEvent) then
+      PendingMouseTail:=@PendingMouseEvent;
+      { why isn't this done here ?
+        so the win32 version do this by hand:}
+       inc(PendingMouseEvents);
+   end;
+end;
+
+
+function SysGetMouseX:word;
+begin
+  EnterCriticalSection(ChangeMouseEvents);
+  SysGetMouseX:=LastMouseEvent.x;
+  LeaveCriticalSection(ChangeMouseEvents);
+end;
+
+
+function SysGetMouseY:word;
+begin
+  EnterCriticalSection(ChangeMouseEvents);
+  SysGetMouseY:=LastMouseEvent.y;
+  LeaveCriticalSection(ChangeMouseEvents);
+end;
+
+
+function SysGetMouseButtons:word;
+begin
+  EnterCriticalSection(ChangeMouseEvents);
+  SysGetMouseButtons:=LastMouseEvent.Buttons;
+  LeaveCriticalSection(ChangeMouseEvents);
+end;
+
+Const
+  SysMouseDriver : TMouseDriver = (
+    UseDefaultQueue : False;
+    InitDriver      : @SysInitMouse;
+    DoneDriver      : @SysDoneMouse;
+    DetectMouse     : @SysDetectMouse;
+    ShowMouse       : Nil;
+    HideMouse       : Nil;
+    GetMouseX       : @SysGetMouseX;
+    GetMouseY       : @SysGetMouseY;
+    GetMouseButtons : @SysGetMouseButtons;
+    SetMouseXY      : Nil;
+    GetMouseEvent   : @SysGetMouseEvent;
+    PollMouseEvent  : @SysPollMouseEvent;
+    PutMouseEvent   : @SysPutMouseEvent;
+  );
+
+Begin
+  SetMouseDriver(SysMouseDriver);
+end.
+{
   $Log$
   $Log$
-  Revision 1.10  2005-02-14 17:13:32  peter
-    * truncate log
-
-  Revision 1.9  2005/01/12 10:25:48  armin
-  * Patch for bug 3548 from Peter
-
-}
+  Revision 1.11  2005-03-31 14:43:03  marco
+   * fix to lastmouseevent update
+
+  Revision 1.10  2005/02/14 17:13:32  peter
+    * truncate log
+
+  Revision 1.9  2005/01/12 10:25:48  armin
+  * Patch for bug 3548 from Peter
+
+}