Browse Source

+ Huge video unit rework for Amiga/MorphOS
* removed tons of Win32 unit leftovers, and other cleanups
* cursor handling fixes, additions (like changing cursor shapes)
* added initial support for sysmsgs

git-svn-id: trunk@11982 -

Károly Balogh 17 years ago
parent
commit
423aca9d63
1 changed files with 81 additions and 200 deletions
  1. 81 200
      rtl/morphos/video.pp

+ 81 - 200
rtl/morphos/video.pp

@@ -22,9 +22,16 @@ uses
 
 
 {$i videoh.inc}
 {$i videoh.inc}
 
 
+
+{ Amiga specific calls, to help interaction between Keyboard, Mouse and
+  Video units, and Free Vision }
+procedure GotCloseWindow;
+function HasCloseWindow: boolean;
+
 var
 var
    videoWindow   : pWindow; 
    videoWindow   : pWindow; 
 
 
+
 implementation
 implementation
 
 
 uses
 uses
@@ -45,57 +52,36 @@ var
    videoPens     : array[0..15] of longint;
    videoPens     : array[0..15] of longint;
 
 
    oldCursorX, oldCursorY: longint;
    oldCursorX, oldCursorY: longint;
-   visibleCursor: boolean;
-   oldvisibleCursor: boolean;
+   cursorType: word;
+   oldcursorType: word;
+
+   gotCloseWindowMsg: boolean;
 
 
 procedure SysInitVideo;
 procedure SysInitVideo;
 var counter: longint;
 var counter: longint;
 begin
 begin
-//   writeln('sysinitvideo');
    InitGraphicsLibrary;
    InitGraphicsLibrary;
    InitIntuitionLibrary;
    InitIntuitionLibrary;
-{
-  ScreenColor:=true;
-  GetConsoleScreenBufferInfo(TextRec(Output).Handle, OrigConsoleInfo);
-  GetConsoleCursorInfo(TextRec(Output).Handle, OrigConsoleCursorInfo);
-  OrigCP := GetConsoleCP;
-  ConsoleInfo:=OrigConsoleInfo;
-  ConsoleCursorInfo:=OrigConsoleCursorInfo;
-  {
-    About the ConsoleCursorInfo record: There are 3 possible
-    structures in it that can be regarded as the 'screen':
-    - dwsize   : contains the cols & row in current screen buffer.
-    - srwindow : Coordinates (relative to buffer) of upper left
-                 & lower right corners of visible console.
-    - dmMaximumWindowSize : Maximal size of Screen buffer.
-    The first implementation of video used srWindow. After some
-    bug-reports, this was switched to dwMaximumWindowSize.
-  }
-  with ConsoleInfo.dwMaximumWindowSize do
-    begin
-    ScreenWidth:=X;
-    ScreenHeight:=Y;
-    end;
-  { TDrawBuffer only has FVMaxWidth elements
-    larger values lead to crashes }
-  if ScreenWidth> FVMaxWidth then
-    ScreenWidth:=FVMaxWidth;
-  CursorX:=ConsoleInfo.dwCursorPosition.x;
-  CursorY:=ConsoleInfo.dwCursorPosition.y;
-  if not ConsoleCursorInfo.bvisible then
-    CursorLines:=0
-  else
-    CursorLines:=ConsoleCursorInfo.dwSize;
-}
+
+   // fill videobuf and oldvideobuf with different bytes, to allow proper first draw
+   FillDword(VideoBuf^,VideoBufSize Div 4,$1234D3AD);
+   FillDword(OldVideoBuf^,VideoBufSize Div 4,$4321BEEF);
+
    videoWindow:=OpenWindowTags(Nil, [
    videoWindow:=OpenWindowTags(Nil, [
       WA_Left,50,
       WA_Left,50,
       WA_Top,50,
       WA_Top,50,
       WA_InnerWidth,80*8,
       WA_InnerWidth,80*8,
       WA_InnerHeight,25*16,
       WA_InnerHeight,25*16,
+      WA_MaxWidth,32768,
+      WA_MaxHeight,32768,
 //      WA_IDCMP,IDCMP_MOUSEBUTTONS Or IDCMP_RAWKEYS,
 //      WA_IDCMP,IDCMP_MOUSEBUTTONS Or IDCMP_RAWKEYS,
-      WA_IDCMP,IDCMP_VANILLAKEY Or IDCMP_RAWKEY,
+      WA_IDCMP,IDCMP_VANILLAKEY Or IDCMP_RAWKEY Or
+               IDCMP_CLOSEWINDOW,
       WA_Title,DWord(PChar('Free Pascal Video Output')),
       WA_Title,DWord(PChar('Free Pascal Video Output')),
-      WA_Flags,(WFLG_GIMMEZEROZERO Or WFLG_SMART_REFRESH Or WFLG_NOCAREREFRESH Or WFLG_ACTIVATE Or WFLG_DRAGBAR Or WFLG_DEPTHGADGET)
+      WA_Flags,(WFLG_GIMMEZEROZERO Or WFLG_SMART_REFRESH Or WFLG_NOCAREREFRESH Or 
+                WFLG_ACTIVATE Or WFLG_DRAGBAR Or WFLG_DEPTHGADGET Or
+//                WFLG_SIZEGADGET Or WFLG_SIZEBBOTTOM Or
+                WFLG_CLOSEGADGET)
    ]);
    ]);
 
 
    ScreenWidth := 80;
    ScreenWidth := 80;
@@ -115,8 +101,10 @@ begin
    CursorY:=0;
    CursorY:=0;
    oldCursorX:=0;
    oldCursorX:=0;
    oldCursorY:=0;
    oldCursorY:=0;
-   visibleCursor:=true;
-   oldvisibleCursor:=true;
+   cursorType:=crHidden;
+   oldcursorType:=crHidden;
+
+   gotCloseWindowMsg:=false;
 end;
 end;
 
 
 
 
@@ -125,101 +113,18 @@ var counter: longint;
 begin
 begin
    if videoWindow<>nil then CloseWindow(videoWindow);
    if videoWindow<>nil then CloseWindow(videoWindow);
    for counter:=0 to 15 do ReleasePen(videoColorMap,videoPens[counter]);
    for counter:=0 to 15 do ReleasePen(videoColorMap,videoPens[counter]);
- 
-{
-  SetConsoleScreenBufferSize (TextRec (Output).Handle, OrigConsoleInfo.dwSize);
-  SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, OrigConsoleInfo.srWindow);
-  SetConsoleCursorInfo(TextRec(Output).Handle, OrigConsoleCursorInfo);
-  SetConsoleCP(OrigCP);
-}
 end;
 end;
 
 
 
 
 
 
-function SysVideoModeSelector (const VideoMode: TVideoMode): boolean;
+function SysSetVideoMode (Const Mode : TVideoMode) : Boolean;
 
 
-{
-var MI: Console_Screen_Buffer_Info;
-    C: Coord;
-    SR: Small_Rect;
-}
-begin
-{
-  if not (GetConsoleScreenBufferInfo (TextRec (Output).Handle, MI)) then
-    SysVideoModeSelector := false
-  else
-    begin
-      with MI do
-        begin
-          C.X := VideoMode.Col;
-          C.Y := VideoMode.Row;
-        end;
-      with SR do
-        begin
-          Top := 0;
-          Left := 0;
-          { First, we need to make sure we reach the minimum window size
-            to always fit in the new buffer after changing buffer size. }
-          Right := MI.srWindow.Right - MI.srWindow.Left;
-          if VideoMode.Col <= Right then
-            Right := Pred (VideoMode.Col);
-          Bottom := MI.srWindow.Bottom - MI.srWindow.Top;
-          if VideoMode.Row <= Bottom then
-            Bottom := Pred (VideoMode.Row);
-        end;
-      if SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, SR) then
-        if SetConsoleScreenBufferSize (TextRec (Output).Handle, C) then
-          begin
-            with SR do
-              begin
-                { Now, we can resize the window to the final size. }
-                Right := Pred (VideoMode.Col);
-                Bottom := Pred (VideoMode.Row);
-              end;
-            if SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, SR) then
-              begin
-                SysVideoModeSelector := true;
-                SetCursorType (LastCursorType);
-                ClearScreen;
-              end
-            else
-              begin
-                SysVideoModeSelector := false;
-                SetConsoleScreenBufferSize (TextRec (Output).Handle, MI.dwSize);
-                SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, MI.srWindow);
-                SetCursorType (LastCursorType);
-              end
-          end
-        else
-          begin
-            SysVideoModeSelector := false;
-            SetConsoleWindowInfo (cardinal (TextRec (Output).Handle), true, MI.srWindow);
-            SetCursorType (LastCursorType);
-          end
-      else
-        SysVideoModeSelector := false;
-    end;
-}
-end;
-
-Const
-  SysVideoModeCount = 6;
-  SysVMD : Array[0..SysVideoModeCount-1] of TVideoMode = (
-   (Col: 40; Row: 25; Color: True),
-   (Col: 80; Row: 25; Color: True),
-   (Col: 80; Row: 30; Color: True),
-   (Col: 80; Row: 43; Color: True),
-   (Col: 80; Row: 50; Color: True),
-   (Col: 80; Row: 25; Color: True) // Reserved for TargetEntry
-  );
-
-
-Function SysSetVideoMode (Const Mode : TVideoMode) : Boolean;
-
-Var
+var
   I : Integer;
   I : Integer;
 
 
 begin
 begin
+
+{
   I:=SysVideoModeCount-1;
   I:=SysVideoModeCount-1;
   SysSetVideoMode:=False;
   SysSetVideoMode:=False;
   While (I>=0) and Not SysSetVideoMode do
   While (I>=0) and Not SysSetVideoMode do
@@ -238,21 +143,9 @@ begin
       ScreenColor:=SysVMD[I].Color;
       ScreenColor:=SysVMD[I].Color;
       end else SysSetVideoMode := false;
       end else SysSetVideoMode := false;
     end;
     end;
+}
 end;
 end;
 
 
-Function SysGetVideoModeData (Index : Word; Var Data : TVideoMode) : boolean;
-
-begin
-  SysGetVideoModeData:=(Index<=high(SysVMD));
-  If SysGetVideoModeData then
-    Data:=SysVMD[Index];
-end;
-
-Function SysGetVideoModeCount : Word;
-
-begin
-  SysGetVideoModeCount:=SysVideoModeCount;
-end;
 
 
 procedure SysClearScreen;
 procedure SysClearScreen;
 begin
 begin
@@ -260,7 +153,7 @@ begin
 end;
 end;
 
 
 
 
-procedure DrawChar(x,y: longint; bitmap: pBitmap; drawCursor: boolean);
+procedure DrawChar(x,y: longint; crType: word);
 var tmpCharData: word;
 var tmpCharData: word;
     tmpChar    : byte;
     tmpChar    : byte;
     tmpFGColor : byte;
     tmpFGColor : byte;
@@ -273,17 +166,24 @@ begin
   tmpChar    :=tmpCharData and $0ff;
   tmpChar    :=tmpCharData and $0ff;
   tmpFGColor :=(tmpCharData shr 8) and %00001111;
   tmpFGColor :=(tmpCharData shr 8) and %00001111;
   tmpBGColor :=(tmpCharData shr 12) and %00000111;
   tmpBGColor :=(tmpCharData shr 12) and %00000111;
-  
+
   sX:=x*8;
   sX:=x*8;
   sY:=y*16;
   sY:=y*16;
-  
-  SetAPen(videoWindow^.Rport,videoPens[tmpFGColor]);
-  SetBPen(videoWindow^.RPort,videoPens[tmpBGColor]);
+
+  if crType <> crBlock then begin
+    SetABPenDrMd(videoWindow^.RPort,videoPens[tmpFGColor],videoPens[tmpBGColor],JAM2);
+  end else begin
+    { in case of block cursor, swap fg/bg colors 
+      and BltTemplate() below will take care of everything }
+    SetABPenDrMd(videoWindow^.RPort,videoPens[tmpBGColor],videoPens[tmpFGColor],JAM2);
+  end;
+
   BltTemplate(@vgafont[tmpChar,0],0,1,videoWindow^.RPort,sX,sY,8,16);
   BltTemplate(@vgafont[tmpChar,0],0,1,videoWindow^.RPort,sX,sY,8,16);
-  
-  if drawCursor then begin
-     gfxMove(videoWindow^.RPort,sX,sY+14); Draw(videoWindow^.RPort,sX+7,sY+14);
-     gfxMove(videoWindow^.RPort,sX,sY+15); Draw(videoWindow^.RPort,sX+7,sY+15);
+
+  if crType = crUnderLine then begin
+    { draw two lines at the bottom of the char, in case of underline cursor }
+    gfxMove(videoWindow^.RPort,sX,sY+14); Draw(videoWindow^.RPort,sX+7,sY+14);
+    gfxMove(videoWindow^.RPort,sX,sY+15); Draw(videoWindow^.RPort,sX+7,sY+15);
   end;
   end;
 end;
 end;
 
 
@@ -292,11 +192,12 @@ procedure SysUpdateScreen(force: boolean);
 var
 var
    BufCounter  : Longint;
    BufCounter  : Longint;
    smallforce  : boolean;
    smallforce  : boolean;
-
+   cursormoved : boolean;
    counter, counterX, counterY: longint;
    counter, counterX, counterY: longint;
-var
-   tmpBitmap   : tBitmap;
 begin
 begin
+  smallforce:=false;
+  cursormoved:=false;
+
   if force then
   if force then
     smallforce:=true
     smallforce:=true
   else begin
   else begin
@@ -312,21 +213,23 @@ begin
     for counterY:=0 to ScreenHeight-1 do begin
     for counterY:=0 to ScreenHeight-1 do begin
       for counterX:=0 to ScreenWidth-1 do begin
       for counterX:=0 to ScreenWidth-1 do begin
         if VideoBuf^[BufCounter]<>OldVideoBuf^[BufCounter] then
         if VideoBuf^[BufCounter]<>OldVideoBuf^[BufCounter] then
-          DrawChar(counterX,counterY,@tmpBitmap,false);
+          DrawChar(counterX,counterY,crHidden);
         Inc(BufCounter);
         Inc(BufCounter);
       end;
       end;
     end;
     end;
     move(VideoBuf^,OldVideoBuf^,VideoBufSize);
     move(VideoBuf^,OldVideoBuf^,VideoBufSize);
   end;
   end;
 
 
-  if (oldvisibleCursor<>visibleCursor) or (CursorX<>oldCursorX) or (CursorY<>oldCursorY) then begin
-    writeln('kurzor:',cursorx,' ',cursory);
-    DrawChar(oldCursorY,oldCursorX,@tmpBitmap,false);
-    DrawChar(CursorY,CursorX,@tmpBitmap,visibleCursor);
+  if (cursorType<>oldcursorType) or 
+     (CursorX<>oldCursorX) or (CursorY<>oldCursorY) or
+     smallforce then begin
+    DrawChar(oldCursorY,oldCursorX,crHidden);
+    DrawChar(CursorY,CursorX,cursorType);
     oldCursorX:=CursorX;
     oldCursorX:=CursorX;
     oldCursorY:=CursorY;
     oldCursorY:=CursorY;
-    oldVisibleCursor:=visibleCursor;
+    oldcursorType:=cursorType;
   end;
   end;
+
 end;
 end;
 
 
 
 
@@ -344,54 +247,33 @@ end;
 
 
 function SysGetCursorType: Word;
 function SysGetCursorType: Word;
 begin
 begin
-  if not visibleCursor then SysGetCursorType:=crHidden 
-                       else SysGetCursorType:=crUnderline;
- 
-{
-   GetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
-   if not ConsoleCursorInfo.bvisible then
-     SysGetCursorType:=crHidden
-   else
-     case ConsoleCursorInfo.dwSize of
-        1..30:
-          SysGetCursorType:=crUnderline;
-        31..70:
-          SysGetCursorType:=crHalfBlock;
-        71..100:
-          SysGetCursorType:=crBlock;
-     end;
-}
+  SysGetCursorType:=cursorType;
 end;
 end;
 
 
 
 
 procedure SysSetCursorType(NewType: Word);
 procedure SysSetCursorType(NewType: Word);
 begin
 begin
-  if newType=crHidden then visibleCursor:=false
-                      else visibleCursor:=true;
+  cursorType:=newType;
+  { FIXME: halfBlock cursors are not supported for now 
+           by the rendering code }
+  if cursorType = crHalfBlock then cursorType:=crBlock;
+
   SysUpdateScreen(false);
   SysUpdateScreen(false);
-{
-   GetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
-   if newType=crHidden then
-     ConsoleCursorInfo.bvisible:=false
-   else
-     begin
-        ConsoleCursorInfo.bvisible:=true;
-        case NewType of
-           crUnderline:
-             ConsoleCursorInfo.dwSize:=10;
-
-           crHalfBlock:
-             ConsoleCursorInfo.dwSize:=50;
-
-           crBlock:
-             ConsoleCursorInfo.dwSize:=99;
-        end
-     end;
-   SetConsoleCursorInfo(TextRec(Output).Handle,ConsoleCursorInfo);
-}
 end;
 end;
 
 
 
 
+// Amiga specific calls
+procedure GotCloseWindow;
+begin
+  gotCloseWindowMsg:=true;
+end;
+
+function HasCloseWindow: boolean;
+begin
+  HasCloseWindow:=gotCloseWindowMsg;
+  gotCloseWindowMsg:=false;
+end;
+
 
 
 const
 const
   SysVideoDriver : TVideoDriver = (
   SysVideoDriver : TVideoDriver = (
@@ -400,13 +282,12 @@ const
     UpdateScreen : @SysUpdateScreen;
     UpdateScreen : @SysUpdateScreen;
     ClearScreen : @SysClearScreen;
     ClearScreen : @SysClearScreen;
     SetVideoMode : @SysSetVideoMode;
     SetVideoMode : @SysSetVideoMode;
-    GetVideoModeCount : @SysGetVideoModeCount;
-    GetVideoModeData : @SysGetVideoModeData;
+    GetVideoModeCount : nil;
+    GetVideoModeData : nil;
     SetCursorPos : @SysSetCursorPos;
     SetCursorPos : @SysSetCursorPos;
     GetCursorType : @SysGetCursorType;
     GetCursorType : @SysGetCursorType;
     SetCursorType : @SysSetCursorType;
     SetCursorType : @SysSetCursorType;
     GetCapabilities : @SysGetCapabilities
     GetCapabilities : @SysGetCapabilities
-
   );
   );