2
0
Эх сурвалжийг харах

+ Use CtrlBreakHandler infrastructure to allow processing of Ctrl-C in ReadKey (OS/2 implementation)

git-svn-id: trunk@8693 -
Tomas Hajny 18 жил өмнө
parent
commit
58ff2fb482
2 өөрчлөгдсөн 93 нэмэгдсэн , 44 устгасан
  1. 35 1
      rtl/inc/crt.inc
  2. 58 43
      rtl/os2/crt.pas

+ 35 - 1
rtl/inc/crt.inc

@@ -15,6 +15,10 @@
 
  **********************************************************************}
 
+var
+  ScanCode: byte;
+  SpecialKey: boolean;
+
 procedure GotoXY (X: byte; Y: byte);
 begin
  GotoXY32 (X, Y);
@@ -381,6 +385,31 @@ end;
 {$ENDIF HAS_NOSOUND}
 
 
+var
+  PrevCtrlBreakHandler: TCtrlBreakHandler;
+
+
+function CrtCtrlBreakHandler (CtrlBreak: boolean): boolean;
+begin
+(* Earlier registered handlers (e.g. FreeVision) have priority. *)
+  if Assigned (PrevCtrlBreakHandler) then
+    if PrevCtrlBreakHandler (CtrlBreak) then
+      begin
+        CrtCtrlBreakHandler := true;
+        Exit;
+      end;
+(* If Ctrl-Break was pressed, either ignore it or allow default processing. *)
+  if CtrlBreak then
+    CrtCtrlBreakHandler := not (CheckBreak)
+  else (* Ctrl-C pressed *)
+    begin
+      if not (SpecialKey) and (ScanCode = 0) then
+        ScanCode := 3;
+      CrtCtrlBreakHandler := true;
+    end;
+end;
+
+
 procedure CrtInit;
 (* Common part of unit initialization. *)
 begin
@@ -396,9 +425,14 @@ begin
   WindMax := WindMax or $FF00
  else
   WindMax := WindMax or (WindMaxY shl 8);
- ExtKeyCode := #0;
+ ScanCode := 0;
+ SpecialKey := false;
  AssignCrt (Input);
  Reset (Input);
  AssignCrt (Output);
  Rewrite (Output);
+ PrevCtrlBreakHandler := SysSetCtrlBreakHandler (@CrtCtrlBreakHandler);
+ if PrevCtrlBreakHandler = TCtrlBreakHandler (pointer (-1)) then
+   PrevCtrlBreakHandler := nil;
+ CheckBreak := true;
 end;

+ 58 - 43
rtl/os2/crt.pas

@@ -131,49 +131,6 @@ external 'DOSCALLS' index 286;
 
 
 
-threadvar
-  ExtKeyCode: char;
-
-
-
-function KeyPressed: boolean;
-{Checks if a key is pressed.}
-var
- AKeyRec: TKbdKeyinfo;
-begin
- if ExtKeyCode <> #0 then
-  KeyPressed := true
- else
-  KeyPressed := (KbdPeek (AKeyRec, 0) = 0)
-                                         and ((AKeyRec.fbStatus and $40) <> 0);
-end;
-
-
-function ReadKey: char;
-{Reads the next character from the keyboard.}
-var
- AKeyRec: TKbdKeyInfo;
- C, S: char;
-begin
- if ExtKeyCode <> #0 then
-  begin
-   ReadKey := ExtKeyCode;
-   ExtKeyCode := #0
-  end
- else
-  begin
-   KbdCharIn (AKeyRec, 0, 0);
-   C := AKeyRec.CharCode;
-   S := AKeyRec.ScanCode;
-   if (C = #224) and (S <> #0) then
-    C := #0;
-   if C = #0 then
-    ExtKeyCode := S;
-   ReadKey := C;
-  end;
-end;
-
-
 procedure GetScreenCursor (var X, Y: dword);inline;
 (* Return current cursor postion - 0-based. *)
 var
@@ -329,6 +286,64 @@ end;
 {$I crt.inc}
 
 
+function KeyPressed: boolean;
+{Checks if a key is pressed.}
+var
+ AKeyRec: TKbdKeyinfo;
+begin
+ if SpecialKey or (ScanCode <> 0) then
+  KeyPressed := true
+ else
+  KeyPressed := (KbdPeek (AKeyRec, 0) = 0)
+                                         and ((AKeyRec.fbStatus and $40) <> 0);
+end;
+
+
+function ReadKey: char;
+{Reads the next character from the keyboard.}
+var
+ AKeyRec: TKbdKeyInfo;
+ C, S: char;
+begin
+ if SpecialKey then
+  begin
+   SpecialKey := false;
+   ReadKey := char (ScanCode);
+   ScanCode := 0;
+  end
+ else
+  if ScanCode <> 0 then
+   begin
+    ReadKey := char (ScanCode);
+    ScanCode := 0;
+   end
+  else
+   begin
+    while ((KbdCharIn (AKeyRec, 1, 0) <> 0)
+                    or (AKeyRec.fbStatus and $41 <> $40)) and (ScanCode = 0) do
+     DosSleep (5);
+    if ScanCode = 0 then
+     begin
+      C := AKeyRec.CharCode;
+      S := AKeyRec.ScanCode;
+      if (C = #224) and (S <> #0) then
+       C := #0;
+      if C = #0 then
+       begin
+        SpecialKey := true;
+        ScanCode := byte (S);
+       end;
+      ReadKey := C;
+     end
+    else
+     begin
+      ReadKey := char (ScanCode);
+      ScanCode := 0;
+     end;
+   end;
+end;
+
+
 {Initialization.}
 
 var