Browse Source

* slightly optimized event handling (merged)

peter 24 years ago
parent
commit
db8c675d94
3 changed files with 96 additions and 109 deletions
  1. 33 35
      rtl/win32/keyboard.pp
  2. 23 25
      rtl/win32/mouse.pp
  3. 40 49
      rtl/win32/winevent.pp

+ 33 - 35
rtl/win32/keyboard.pp

@@ -110,18 +110,12 @@ end;
 { The event-Handler thread from the unit event will call us if a key-event
 { The event-Handler thread from the unit event will call us if a key-event
   is available }
   is available }
 
 
-procedure HandleKeyboard;
+procedure HandleKeyboard(var ir:INPUT_RECORD);
 var
 var
-   ir     : INPUT_RECORD;
-   dwRead : DWord;
    i      : longint;
    i      : longint;
    c      : word;
    c      : word;
    addThis: boolean;
    addThis: boolean;
 begin
 begin
-   dwRead:=1;
-   ReadConsoleInput(TextRec(Input).Handle,ir,1,dwRead);
-   if (dwRead=1) and (ir.EventType=KEY_EVENT) then
-     begin
          with ir.KeyEvent do
          with ir.KeyEvent do
            begin
            begin
               { key up events are ignored (except alt) }
               { key up events are ignored (except alt) }
@@ -156,36 +150,37 @@ begin
                    lastShiftState := transShiftState (dwControlKeyState);  {save it for PollShiftStateEvent}
                    lastShiftState := transShiftState (dwControlKeyState);  {save it for PollShiftStateEvent}
                    SetEvent (newKeyEvent);             {event that a new key is available}
                    SetEvent (newKeyEvent);             {event that a new key is available}
                    LeaveCriticalSection (lockVar);
                    LeaveCriticalSection (lockVar);
-                end else
+                end
+              else
                 begin
                 begin
                   lastShiftState := transShiftState (dwControlKeyState);   {save it for PollShiftStateEvent}
                   lastShiftState := transShiftState (dwControlKeyState);   {save it for PollShiftStateEvent}
                   {for alt-number we have to look for alt-key release}
                   {for alt-number we have to look for alt-key release}
                   if altNumActive then
                   if altNumActive then
-                    if (wVirtualKeyCode = $12) then    {alt-released}
-                    begin
-                      if altNumBuffer <> '' then       {numbers with alt pressed?}
+                   begin
+                     if (wVirtualKeyCode = $12) then    {alt-released}
                       begin
                       begin
-                        Val (altNumBuffer, c, i);
-                        if (i = 0) and (c <= 255) then {valid number?}
-                        begin                          {add to queue}
-                          fillchar (ir, sizeof (ir), 0);
-                          bKeyDown := true;
-                          AsciiChar := char (c);
+                        if altNumBuffer <> '' then       {numbers with alt pressed?}
+                         begin
+                           Val (altNumBuffer, c, i);
+                           if (i = 0) and (c <= 255) then {valid number?}
+                            begin                          {add to queue}
+                              fillchar (ir, sizeof (ir), 0);
+                              bKeyDown := true;
+                              AsciiChar := char (c);
                                                        {and add to queue}
                                                        {and add to queue}
-                          EnterCriticalSection (lockVar);
-                          keyboardeventqueue[nextfreekeyevent]:=
-                            ir.KeyEvent;
-                          incqueueindex(nextfreekeyevent);
-                          SetEvent (newKeyEvent);      {event that a new key is available}
-                          LeaveCriticalSection (lockVar);
-                        end;
+                              EnterCriticalSection (lockVar);
+                              keyboardeventqueue[nextfreekeyevent]:=ir.KeyEvent;
+                              incqueueindex(nextfreekeyevent);
+                              SetEvent (newKeyEvent);      {event that a new key is available}
+                              LeaveCriticalSection (lockVar);
+                            end;
+                         end;
+                        altNumActive   := false;         {clear alt-buffer}
+                        altNumBuffer   := '';
                       end;
                       end;
-                      altNumActive   := false;         {clear alt-buffer}
-                      altNumBuffer   := '';
-                    end;
+                   end;
                 end;
                 end;
            end;
            end;
-     end;
 end;
 end;
 
 
 procedure InitKeyboard;
 procedure InitKeyboard;
@@ -194,16 +189,16 @@ begin
      exit;
      exit;
    KeyBoardLayout:=GetKeyboardLayout(0);
    KeyBoardLayout:=GetKeyboardLayout(0);
    lastShiftState := 0;
    lastShiftState := 0;
-   FlushConsoleInputBuffer(TextRec(Input).Handle);
+   FlushConsoleInputBuffer(StdInputHandle);
    newKeyEvent := CreateEvent (nil,        // address of security attributes
    newKeyEvent := CreateEvent (nil,        // address of security attributes
                                true,       // flag for manual-reset event
                                true,       // flag for manual-reset event
                                false,      // flag for initial state
                                false,      // flag for initial state
                                nil);       // address of event-object name
                                nil);       // address of event-object name
    if newKeyEvent = INVALID_HANDLE_VALUE then
    if newKeyEvent = INVALID_HANDLE_VALUE then
-   begin
-     // what to do here ????
-     RunError (217);
-   end;
+    begin
+      // what to do here ????
+      RunError (217);
+    end;
    InitializeCriticalSection (lockVar);
    InitializeCriticalSection (lockVar);
    altNumActive := false;
    altNumActive := false;
    altNumBuffer := '';
    altNumBuffer := '';
@@ -220,7 +215,7 @@ begin
      exit;
      exit;
    SetKeyboardEventHandler(nil);     {hangs???}
    SetKeyboardEventHandler(nil);     {hangs???}
    DeleteCriticalSection (lockVar);
    DeleteCriticalSection (lockVar);
-   FlushConsoleInputBuffer(TextRec(Input).Handle);
+   FlushConsoleInputBuffer(StdInputHandle);
    closeHandle (newKeyEvent);
    closeHandle (newKeyEvent);
    KeyboardActive:=false;
    KeyboardActive:=false;
 end;
 end;
@@ -791,7 +786,10 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2001-01-13 11:03:59  peter
+  Revision 1.2  2001-01-14 22:20:00  peter
+    * slightly optimized event handling (merged)
+
+  Revision 1.1  2001/01/13 11:03:59  peter
     * API 2 RTL commit
     * API 2 RTL commit
 
 
 }
 }

+ 23 - 25
rtl/win32/mouse.pp

@@ -32,18 +32,14 @@ var
 Const
 Const
   MouseEventActive : Boolean = false;
   MouseEventActive : Boolean = false;
 
 
-procedure MouseEventHandler;
+procedure MouseEventHandler(var ir:INPUT_RECORD);
 
 
   var
   var
-     ir : INPUT_RECORD;
      dwRead : DWord;
      dwRead : DWord;
      i: longint;
      i: longint;
      e : TMouseEvent;
      e : TMouseEvent;
 
 
   begin
   begin
-     ReadConsoleInput(TextRec(Input).Handle,ir,1,dwRead);
-     if (dwRead=1) and (ir.EventType=_MOUSE_EVENT) then
-       begin
           EnterCriticalSection(ChangeMouseEvents);
           EnterCriticalSection(ChangeMouseEvents);
           e.x:=ir.MouseEvent.dwMousePosition.x;
           e.x:=ir.MouseEvent.dwMousePosition.x;
           e.y:=ir.MouseEvent.dwMousePosition.y;
           e.y:=ir.MouseEvent.dwMousePosition.y;
@@ -71,7 +67,6 @@ procedure MouseEventHandler;
                // inc(PendingMouseEvents);
                // inc(PendingMouseEvents);
             end;
             end;
           LeaveCriticalSection(ChangeMouseEvents);
           LeaveCriticalSection(ChangeMouseEvents);
-       end;
   end;
   end;
 
 
 procedure InitMouse;
 procedure InitMouse;
@@ -83,9 +78,9 @@ begin
   if MouseEventActive then
   if MouseEventActive then
     exit;
     exit;
   // enable mouse events
   // enable mouse events
-  GetConsoleMode(TextRec(Input).Handle,@mode);
+  GetConsoleMode(StdInputHandle,@mode);
   mode:=mode or ENABLE_MOUSE_INPUT;
   mode:=mode or ENABLE_MOUSE_INPUT;
-  SetConsoleMode(TextRec(Input).Handle,mode);
+  SetConsoleMode(StdInputHandle,mode);
 
 
   PendingMouseHead:=@PendingMouseEvent;
   PendingMouseHead:=@PendingMouseEvent;
   PendingMouseTail:=@PendingMouseEvent;
   PendingMouseTail:=@PendingMouseEvent;
@@ -106,9 +101,9 @@ begin
     exit;
     exit;
   HideMouse;
   HideMouse;
   // disable mouse events
   // disable mouse events
-  GetConsoleMode(TextRec(Input).Handle,@mode);
+  GetConsoleMode(StdInputHandle,@mode);
   mode:=mode and (not ENABLE_MOUSE_INPUT);
   mode:=mode and (not ENABLE_MOUSE_INPUT);
-  SetConsoleMode(TextRec(Input).Handle,mode);
+  SetConsoleMode(StdInputHandle,mode);
 
 
   SetMouseEventHandler(nil);
   SetMouseEventHandler(nil);
   DeleteCriticalSection(ChangeMouseEvents);
   DeleteCriticalSection(ChangeMouseEvents);
@@ -193,6 +188,20 @@ begin
 end;
 end;
 
 
 
 
+function PollMouseEvent(var MouseEvent: TMouseEvent):boolean;
+begin
+  EnterCriticalSection(ChangeMouseEvents);
+  if PendingMouseEvents>0 then
+   begin
+     MouseEvent:=PendingMouseHead^;
+     PollMouseEvent:=true;
+   end
+  else
+   PollMouseEvent:=false;
+  LeaveCriticalSection(ChangeMouseEvents);
+end;
+
+
 procedure PutMouseEvent(const MouseEvent: TMouseEvent);
 procedure PutMouseEvent(const MouseEvent: TMouseEvent);
 begin
 begin
   if PendingMouseEvents<MouseEventBufSize then
   if PendingMouseEvents<MouseEventBufSize then
@@ -207,24 +216,13 @@ begin
    end;
    end;
 end;
 end;
 
 
-
-function PollMouseEvent(var MouseEvent: TMouseEvent):boolean;
-begin
-  EnterCriticalSection(ChangeMouseEvents);
-  if PendingMouseEvents>0 then
-   begin
-     MouseEvent:=PendingMouseHead^;
-     PollMouseEvent:=true;
-   end
-  else
-   PollMouseEvent:=false;
-  LeaveCriticalSection(ChangeMouseEvents);
-end;
-
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2001-01-13 11:03:59  peter
+  Revision 1.2  2001-01-14 22:20:00  peter
+    * slightly optimized event handling (merged)
+
+  Revision 1.1  2001/01/13 11:03:59  peter
     * API 2 RTL commit
     * API 2 RTL commit
 
 
 }
 }

+ 40 - 49
rtl/win32/winevent.pp

@@ -22,8 +22,11 @@ interface
    because win32 uses only one message queue for mouse and key events
    because win32 uses only one message queue for mouse and key events
 }
 }
 
 
+    uses
+       Windows;
+
     type
     type
-       TEventProcedure = Procedure;
+       TEventProcedure = Procedure(var ir:INPUT_RECORD);
 
 
     { these procedures must be used to set the event handlers }
     { these procedures must be used to set the event handlers }
     { these doesn't do something, they signal only the        }
     { these doesn't do something, they signal only the        }
@@ -47,24 +50,20 @@ interface
 
 
   implementation
   implementation
 
 
-    uses
-       windows, dos;
-
     const
     const
        { these procedures are called if an event occurs }
        { these procedures are called if an event occurs }
-       MouseEventHandler : procedure = nil;
-       KeyboardEventHandler : procedure = nil;
-       FocusEventHandler : procedure = nil;
-       MenuEventHandler : procedure = nil;
-       ResizeEventHandler : procedure = nil;
-       UnknownEventHandler  : procedure = nil;
+       MouseEventHandler : TEventProcedure = nil;
+       KeyboardEventHandler : TEventProcedure = nil;
+       FocusEventHandler : TEventProcedure = nil;
+       MenuEventHandler : TEventProcedure = nil;
+       ResizeEventHandler : TEventProcedure = nil;
+       UnknownEventHandler  : TEventProcedure = nil;
 
 
        { if this counter is zero, the event handler thread is killed }
        { if this counter is zero, the event handler thread is killed }
        InstalledHandlers : Byte = 0;
        InstalledHandlers : Byte = 0;
 
 
     var
     var
        HandlerChanging : TCriticalSection;
        HandlerChanging : TCriticalSection;
-       OldExitProc : Pointer;
        EventThreadHandle : Handle;
        EventThreadHandle : Handle;
        EventThreadID : DWord;
        EventThreadID : DWord;
 
 
@@ -106,25 +105,18 @@ interface
          GetUnknownEventHandler:=UnknownEventHandler;
          GetUnknownEventHandler:=UnknownEventHandler;
       end;
       end;
 
 
-    { removes an event from the event queue }
-    { necessary, if no handler is installed }
-    Procedure DestroyOneEvent;
-      var
-         ir : TInputRecord;
-         dwRead : DWord;
-      begin
-         ReadConsoleInput(TextRec(Input).Handle,ir,1,dwRead);
-      end;
 
 
     Function EventHandleThread(p : pointer) : DWord;StdCall;
     Function EventHandleThread(p : pointer) : DWord;StdCall;
+      const
+        irsize = 10;
       var
       var
-         ir : TInputRecord;
-         dwRead : DWord;
+         ir : array[0..irsize-1] of TInputRecord;
+         i,dwRead : DWord;
       begin
       begin
          while not(ExitEventHandleThread) do
          while not(ExitEventHandleThread) do
            begin
            begin
               { wait for an event }
               { wait for an event }
-              WaitForSingleObject(TextRec(Input).Handle,INFINITE);
+              WaitForSingleObject(StdInputHandle,INFINITE);
               { guard this code, else it is doomed to crash, if the
               { guard this code, else it is doomed to crash, if the
                 thread is switched between the assigned test and
                 thread is switched between the assigned test and
                 the call and the handler is removed
                 the call and the handler is removed
@@ -133,61 +125,56 @@ interface
                 begin
                 begin
                    EnterCriticalSection(HandlerChanging);
                    EnterCriticalSection(HandlerChanging);
                    { read, but don't remove the event }
                    { read, but don't remove the event }
-                   if (PeekConsoleInput(TextRec(Input).Handle,ir,1,dwRead)) and
-                     (dwRead>0) then
-                     { call the handler }
-                     case ir.EventType of
+                   if ReadConsoleInput(StdInputHandle,ir[0],irsize,dwRead) then
+                    begin
+                      i:=0;
+                      while (i<dwRead) do
+                       begin
+                       { call the handler }
+                       case ir[i].EventType of
                         KEY_EVENT:
                         KEY_EVENT:
                           begin
                           begin
                              if assigned(KeyboardEventHandler) then
                              if assigned(KeyboardEventHandler) then
-                               KeyboardEventHandler
-                             else
-                               DestroyOneEvent;
+                               KeyboardEventHandler(ir[i]);
                           end;
                           end;
 
 
                         _MOUSE_EVENT:
                         _MOUSE_EVENT:
                           begin
                           begin
                              if assigned(MouseEventHandler) then
                              if assigned(MouseEventHandler) then
-                               MouseEventHandler
-                             else
-                               DestroyOneEvent;
+                               MouseEventHandler(ir[i]);
                           end;
                           end;
 
 
                         WINDOW_BUFFER_SIZE_EVENT:
                         WINDOW_BUFFER_SIZE_EVENT:
                           begin
                           begin
                              if assigned(ResizeEventHandler) then
                              if assigned(ResizeEventHandler) then
-                               ResizeEventHandler
-                             else
-                               DestroyOneEvent;
+                               ResizeEventHandler(ir[i]);
                           end;
                           end;
 
 
                         MENU_EVENT:
                         MENU_EVENT:
                           begin
                           begin
                              if assigned(MenuEventHandler) then
                              if assigned(MenuEventHandler) then
-                               MenuEventHandler
-                             else
-                               DestroyOneEvent;
+                               MenuEventHandler(ir[i]);
                           end;
                           end;
 
 
                         FOCUS_EVENT:
                         FOCUS_EVENT:
                           begin
                           begin
                              if assigned(FocusEventHandler) then
                              if assigned(FocusEventHandler) then
-                               FocusEventHandler
-                             else
-                               DestroyOneEvent;
+                               FocusEventHandler(ir[i]);
                           end;
                           end;
 
 
                         else
                         else
                           begin
                           begin
                              if assigned(UnknownEventHandler) then
                              if assigned(UnknownEventHandler) then
-                               UnknownEventHandler
-                             else
-                               DestroyOneEvent;
+                               UnknownEventHandler(ir[i]);
                           end;
                           end;
-                     end;
+                       end;
+                       inc(i);
+                      end;
+                    end;
                    LeaveCriticalSection(HandlerChanging);
                    LeaveCriticalSection(HandlerChanging);
                 end;
                 end;
            end;
            end;
+        EventHandleThread:=0;
       end;
       end;
 
 
     Procedure NewEventHandlerInstalled(p,oldp : TEventProcedure);
     Procedure NewEventHandlerInstalled(p,oldp : TEventProcedure);
@@ -213,12 +200,12 @@ interface
            begin
            begin
               ExitEventHandleThread:=true;
               ExitEventHandleThread:=true;
               { create a dummy event and sent it to the thread, so
               { create a dummy event and sent it to the thread, so
-                we can leave WatiForSingleObject }
+                we can leave WaitForSingleObject }
               ir.EventType:=KEY_EVENT;
               ir.EventType:=KEY_EVENT;
               { mouse event can be disabled by mouse.inc code
               { mouse event can be disabled by mouse.inc code
                 in DoneMouse
                 in DoneMouse
                 so use a key event instead PM }
                 so use a key event instead PM }
-              WriteConsoleInput(TextRec(Input).Handle,ir,1,written);
+              WriteConsoleInput(StdInputHandle,ir,1,written);
               { wait, til the thread is ready }
               { wait, til the thread is ready }
               WaitForSingleObject(EventThreadHandle,INFINITE);
               WaitForSingleObject(EventThreadHandle,INFINITE);
               CloseHandle(EventThreadHandle);
               CloseHandle(EventThreadHandle);
@@ -312,11 +299,15 @@ finalization
   SetUnknownEventHandler(nil);
   SetUnknownEventHandler(nil);
   { delete the critical section object }
   { delete the critical section object }
   DeleteCriticalSection(HandlerChanging);
   DeleteCriticalSection(HandlerChanging);
+
 end.
 end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2001-01-13 11:03:59  peter
+  Revision 1.2  2001-01-14 22:20:00  peter
+    * slightly optimized event handling (merged)
+
+  Revision 1.1  2001/01/13 11:03:59  peter
     * API 2 RTL commit
     * API 2 RTL commit
 
 
 }
 }