Browse Source

* safer handling of video buffer changes, free original screen buffer at termination and initialized screen parameters at start to allow proper working of TProgram based FV programs

git-svn-id: trunk@15129 -
Tomas Hajny 15 years ago
parent
commit
e0c8c39d74
1 changed files with 33 additions and 12 deletions
  1. 33 12
      rtl/os2/video.pp

+ 33 - 12
rtl/os2/video.pp

@@ -82,7 +82,9 @@ Var
 
 
 procedure SysInitVideo;
 procedure SysInitVideo;
 
 
-var MI: TVioModeInfo;
+var
+  MI: TVioModeInfo;
+  NewBuf: PVideoBuf;
 
 
 begin
 begin
   MI.cb := SizeOf (MI);
   MI.cb := SizeOf (MI);
@@ -96,9 +98,9 @@ begin
   VioGetCurPos (CursorY, CursorX, 0);
   VioGetCurPos (CursorY, CursorX, 0);
   SetCursorType (LastCursorType);
   SetCursorType (LastCursorType);
 { Get the address of the videobuffer.}
 { Get the address of the videobuffer.}
-  if VioGetBuf (SysVideoBuf, PWord (@VideoBufSize)^, 0) = 0 then
+  if VioGetBuf (NewBuf, PWord (@VideoBufSize)^, 0) = 0 then
     begin
     begin
-    SysVideoBuf := SelToFlat (cardinal (SysVideoBuf));
+    SysVideoBuf := SelToFlat (PtrUInt (NewBuf));
     SetHighBitBlink (true);
     SetHighBitBlink (true);
     end
     end
   else
   else
@@ -215,7 +217,7 @@ begin
     if (VioGetBuf (PScr, PWord (@ScrSize)^, 0) = 0) and
     if (VioGetBuf (PScr, PWord (@ScrSize)^, 0) = 0) and
        (ScrSize = OrigScreenSize) then
        (ScrSize = OrigScreenSize) then
       begin
       begin
-      PScr := SelToFlat (cardinal (PScr));
+      PScr := SelToFlat (PtrUInt (PScr));
       Move (OrigScreen^, PScr^, OrigScreenSize);
       Move (OrigScreen^, PScr^, OrigScreenSize);
       VioShowBuf (0, ScrSize, 0);
       VioShowBuf (0, ScrSize, 0);
       end;
       end;
@@ -232,7 +234,9 @@ end;
 
 
 function SysVideoModeSelector (const VideoMode: TVideoMode): boolean;
 function SysVideoModeSelector (const VideoMode: TVideoMode): boolean;
 
 
-var OldMI, MI: TVioModeInfo;
+var
+  OldMI, MI: TVioModeInfo;
+  NewBuf: PVideoBuf;
 
 
 begin
 begin
   OldMI.cb := SizeOf (OldMI);
   OldMI.cb := SizeOf (OldMI);
@@ -252,9 +256,9 @@ begin
       Row := VideoMode.Row;
       Row := VideoMode.Row;
       end;
       end;
     if VioSetMode (MI, 0) = 0 then
     if VioSetMode (MI, 0) = 0 then
-      if VioGetBuf (SysVideoBuf, PWord (@VideoBufSize)^, 0) = 0 then
+      if VioGetBuf (NewBuf, PWord (@VideoBufSize)^, 0) = 0 then
         begin
         begin
-        SysVideoBuf := SelToFlat (cardinal (SysVideoBuf));
+        SysVideoBuf := SelToFlat (PtrUInt (NewBuf));
         SysVideoModeSelector := true;
         SysVideoModeSelector := true;
         SetHighBitBlink (true);
         SetHighBitBlink (true);
         CheckCellHeight;
         CheckCellHeight;
@@ -265,8 +269,8 @@ begin
         begin
         begin
         SysVideoModeSelector := false;
         SysVideoModeSelector := false;
         VioSetMode (OldMI, 0);
         VioSetMode (OldMI, 0);
-        VioGetBuf (SysVideoBuf, PWord (@VideoBufSize)^, 0);
-        SysVideoBuf := SelToFlat (cardinal (SysVideoBuf));
+        if (VioGetBuf (NewBuf, PWord (@VideoBufSize)^, 0) = 0) then
+          SysVideoBuf := SelToFlat (PtrUInt (NewBuf));
         SetHighBitBlink (true);
         SetHighBitBlink (true);
         CheckCellHeight;
         CheckCellHeight;
         SetCursorType (LastCursorType);
         SetCursorType (LastCursorType);
@@ -275,8 +279,8 @@ begin
     else
     else
       begin
       begin
       SysVideoModeSelector := false;
       SysVideoModeSelector := false;
-      VioGetBuf (SysVideoBuf, PWord (@VideoBufSize)^, 0);
-      SysVideoBuf := SelToFlat (cardinal (SysVideoBuf));
+      if VioGetBuf (NewBuf, PWord (@VideoBufSize)^, 0) = 0 then
+        SysVideoBuf := SelToFlat (PtrUInt (NewBuf));
       SetHighBitBlink (true);
       SetHighBitBlink (true);
       SetCursorType (LastCursorType);
       SetCursorType (LastCursorType);
       end;
       end;
@@ -406,6 +410,7 @@ begin
     CLen := VideoBufSize;
     CLen := VideoBufSize;
     end;
     end;
   // .MVC. Move video buffer to system video buffer.
   // .MVC. Move video buffer to system video buffer.
+{$HINT Change so that only relevant parts calculated above are moved}
   Move(VideoBuf^,SysVideoBuf^,VideoBufSize);
   Move(VideoBuf^,SysVideoBuf^,VideoBufSize);
   if Force then
   if Force then
     begin
     begin
@@ -444,6 +449,12 @@ begin
 {Remember original video mode, cursor type and high bit behaviour setting}
 {Remember original video mode, cursor type and high bit behaviour setting}
   OrigVioMode.cb := SizeOf (OrigVioMode);
   OrigVioMode.cb := SizeOf (OrigVioMode);
   VioGetMode (OrigVioMode, 0);
   VioGetMode (OrigVioMode, 0);
+  with OrigVioMode do
+    begin
+    ScreenWidth := Col;
+    ScreenHeight := Row;
+    ScreenColor := Color >= Colors_16;
+    end;
   VioGetCurType (OrigCurType, 0);
   VioGetCurType (OrigCurType, 0);
   VioGetCurPos (OrigCurRow, OrigCurCol, 0);
   VioGetCurPos (OrigCurRow, OrigCurCol, 0);
   with OrigHighBit do
   with OrigHighBit do
@@ -463,7 +474,7 @@ begin
   {Get the address of the original videobuffer and size.}
   {Get the address of the original videobuffer and size.}
   if VioGetBuf (PScr, PWord (@OrigScreenSize)^, 0) = 0 then
   if VioGetBuf (PScr, PWord (@OrigScreenSize)^, 0) = 0 then
     begin
     begin
-    PScr := SelToFlat (cardinal (PScr));
+    PScr := SelToFlat (PtrUInt (PScr));
     GetMem (OrigScreen, OrigScreenSize);
     GetMem (OrigScreen, OrigScreenSize);
     Move (PScr^, OrigScreen^, OrigScreenSize);
     Move (PScr^, OrigScreen^, OrigScreenSize);
     end;
     end;
@@ -471,6 +482,16 @@ end;
 
 
 
 
 initialization
 initialization
+begin
   SetVideoDriver(SysVideoDriver);
   SetVideoDriver(SysVideoDriver);
   TargetEntry;
   TargetEntry;
+end;
+
+finalization
+  if (OrigScreenSize <> 0) and (OrigScreen <> nil) then
+    begin
+      FreeMem (OrigScreen, OrigScreenSize);
+      OrigScreen := nil;
+      OrigScreenSize := 0;
+    end;
 end.
 end.