Browse Source

Merge branch source:main into main

Curtis Hamilton 1 week ago
parent
commit
3a3a3934a3

+ 1 - 1
compiler/msg/errorheu.msg

@@ -3496,7 +3496,7 @@ wpo_cant_create_feedback_file=12019_E_Cannot create specified whole program opti
 #
 option_logo=11023_[
 Free Pascal Compiler version $FPCFULLVERSION [$FPCDATE] for $FPCCPU
-Copyright (c) 1993-2025 by Florian Klaempfl and others
+Copyright (c) 1993-2026 by Florian Klaempfl and others
 ]
 
 #

+ 1 - 1
packages/aspell/fpmake.pp

@@ -24,7 +24,7 @@ begin
     P.Author := 'header:Aleš Katona, library: Kevin Atkinson';
     P.License := 'header: LGPL with modification, library: LGPL 2.0 or 2.1';
     P.HomepageURL := 'www.freepascal.org';
-    P.OSes := [beos,haiku,freebsd,darwin,iphonesim,ios,netbsd,openbsd,linux,win32,aix,dragonfly];
+    P.OSes := [beos,haiku,freebsd,darwin,iphonesim,ios,netbsd,openbsd,linux,win32,win64,aix,dragonfly];
     P.Email := '';
     P.Description := 'The New Aspell, spelling library';
     P.NeedLibC:= true;

+ 63 - 18
packages/fv/examples/demoedit.pas

@@ -1,16 +1,42 @@
+{ This example is part of FPC Free Vision package.
+
+  Program demonstrates Editor use in your Free Vision Application
+  and manual clipboard manipulations.
+
+  To have clipboard functionally all you have to do is to add Editor
+  (TFileEditor) to Clipboard. By default Free Vision will try to use your OS
+  clipboard as long there is one and as long it is supported by Free Vision.
+  Otherwise it will fall back to local clipboard. Use of local clipboard can
+  be triggered manually if desired. As well OS clipboard can be used directly
+  via FVClip unit.
+
+  Note. On Unix/Linux systems Free Vision uses OSC 52 clipboard and bracketed
+  paste. It is assumed that OSC 52 clipboard is available. While real
+  availability depends on particular terminal in use and particular
+  configuration of it.
+}
 program DemoEditor;
 {$mode fpc}
 
+{ Have FV_UNICODE defined to compile and run with Free Vision Unicode version,
+  otherwise single byte code page ShortString Free Vision version will be used }
+{$define FV_UNICODE}
+
 uses
   {$ifdef UNIX}cwstring,{$endif}Objects,fvconsts,
-  //Drivers, Views, Menus, StdDlg, App, Editors,Msgbox{$ifdef unix},fvclip { OSC 52 support unit } {$endif},FVCommon;
-  uDrivers, uViews, uMenus, uStdDlg, uApp, uEditors,uMsgbox{$ifdef unix},ufvclip { OSC 52 support unit } {$endif},uFVCommon;
+{$ifdef FV_UNICODE}
+  uDrivers, uViews, uMenus, uStdDlg, uApp, uEditors,uMsgbox,ufvclip,uFVCommon;
+{$else}
+  Drivers, Views, Menus, StdDlg, App, Editors,Msgbox,fvclip,FVCommon;
+{$endif}
 
 
 const
   cmShowClip   = 102;
   cmCopyWin    = 240;
   cmPasteWin   = 241;
+  cmLocalClip  = 242;
+  cmOSClip     = 243;
 
 type
   PEditorApp = ^TEditorApp;
@@ -46,24 +72,21 @@ procedure TMyEditWindow.HandleEvent(var Event: TEvent);
 procedure ClipCopyWin;
 var p : pointer;
 begin
-{$ifdef unix}
   if Editor^.SelStart<>Editor^.SelEnd then { Text selected? }
-  begin
-    {This is where the magic happens. Parameters are PAnsiChar and Length of data to be copied to global clipboard}
-    SetGlobalClipboardData( @Editor^.Buffer^[Editor^.BufPtr(Editor^.SelStart)], Editor^.SelEnd - Editor^.SelStart);
-  end;
-{$else}
-  MessageBox('Not implemented for this platform!', nil, mfInformation + mfOkButton);
-{$endif}
+    { This is where the magic happens. Parameters are PAnsiChar and Length of data to be copied to OS clipboard }
+    SetTextWinClipboardData( @Editor^.Buffer^[Editor^.BufPtr(Editor^.SelStart)], Editor^.SelEnd - Editor^.SelStart);
 end;
 
 procedure ClipPasteWin;
+var P : PAnsiChar; Len: Longint;
 begin
-{$ifdef unix}
-  GetGlobalClipboardData; {Request data from global Clipboard. That's it}
-{$else}
-  MessageBox('Not implemented for this platform!', nil, mfInformation + mfOkButton);
-{$endif}
+  { Get OS clipboard data }
+  if GetTextWinClipboardData (P, Len) then
+    if assigned(P) then
+    begin
+      Editor^.InsertText (P, Len, False);  { On success insert into Editor window }
+      FreeMem(P);  { Our responsibility to free memory }
+    end;
 end;
 
 begin
@@ -73,6 +96,13 @@ begin
       case Event.Command of
         cmCopyWin   : ClipCopyWin;
         cmPasteWin  : ClipPasteWin;
+        {  Information. cmPasteText is triggered by Bracketed paste and
+           OSC 52 paste. It is necessary handle cmPasteText event only for
+           your own Views that are not descendants of TInputLine or TEditro.
+           cmPasteText is not part of legacy Turbo Vision v2.0.
+           Here Event.Id holds length of data in Event.InfoPtr PAnsiChar.
+        cmPasteText : Editor^.InsertText(Event.InfoPtr,Event.Id,false);
+        }
       else
         Exit;
       end;
@@ -89,14 +119,16 @@ var
 begin
   inherited Init;
   DisableCommands([cmSave, cmSaveAs, cmCut, cmCopy, cmPaste,
-    {cmCopyWin, cmPasteWin,}
     cmClear, cmUndo, cmFind, cmReplace, cmSearchAgain]);
+  if not WinClipboardSupported then
+    DisableCommands([cmCopyWin, cmPasteWin, cmOSClip]);
   EditorDialog := @StdEditorDialog;
   ClipWindow := OpenEditor('', False);
   if ClipWindow <> nil then
   begin
+    { Add Editor to Clipboard and by that clipboard functionality is enabled }
     Clipboard := ClipWindow^.Editor;
-    Clipboard^.CanUndo := False;
+    Clipboard^.CanUndo := False;  { No Undo for clipboard }
   end;
 end;
 
@@ -137,6 +169,16 @@ begin
         cmNew: FileNew;
         cmChangeDir : ChangeDir;
         cmShowClip  : ShowClip;
+        cmLocalClip :
+          begin
+            SetGlobalClipboard( False );
+            MessageBox('Set to use local clipboard!', nil, mfInformation + mfOkButton);
+          end;
+        cmOSClip    :
+          begin
+            SetGlobalClipboard( True );
+            MessageBox('Set to use OS clipboard!', nil, mfInformation + mfOkButton);
+          end;
       else
         Exit;
       end;
@@ -161,9 +203,12 @@ begin
       NewLine(
       NewItem('~S~hwo clipboard', '', kbNoKey, cmShowClip, hcNoContext,
       NewLine(
+      NewItem('Use ~l~ocal clipboard', '', kbNoKey, cmLocalClip, hcNoContext,
+      NewItem('Use ~O~S clipboard', '', kbNoKey, cmOSClip, hcNoContext,
+      NewLine(
       NewItem('Cop~y~ to Windows', '', kbNoKey, cmCopyWin, hcNoContext,
       NewItem('Paste from ~W~indows', '', kbNoKey, cmPasteWin, hcNoContext,
-      nil))))))),
+      nil)))))))))),
     NewSubMenu('~S~earch', hcNoContext, NewMenu(
       NewItem('~F~ind...', '', kbNoKey, cmFind, hcNoContext,
       NewItem('~R~eplace...', '', kbNoKey, cmReplace, hcNoContext,

+ 16 - 10
packages/fv/fpmake.pp

@@ -50,7 +50,6 @@ begin
           AddUnit('dialogs');
           AddUnit('msgbox');
           AddUnit('fvconsts');
-          AddUnit('fvclip',AllUnixOSes);
         end;
     T.ResourceStrings := True;
     T:=P.Targets.AddUnit('uapp.pas',P.OSes-[msdos,win16]);
@@ -66,7 +65,6 @@ begin
           AddUnit('udialogs');
           AddUnit('umsgbox');
           AddUnit('fvconsts');
-          AddUnit('ufvclip',AllUnixOSes);
         end;
     T.ResourceStrings := True;
     T:=P.Targets.AddUnit('asciitab.pas');
@@ -176,6 +174,7 @@ begin
           AddUnit('validate');
           AddUnit('app');
           AddUnit('histlist');
+          AddUnit('editors');
         end;
     T.ResourceStrings := True;
     T:=P.Targets.AddUnit('udialogs.pas',P.OSes-[msdos,win16]);
@@ -190,6 +189,7 @@ begin
           AddUnit('uvalidate');
           AddUnit('uapp');
           AddUnit('uhistlist');
+          AddUnit('ueditors');
         end;
     T.ResourceStrings := True;
     T:=P.Targets.AddUnit('drivers.pas');
@@ -200,6 +200,7 @@ begin
           AddUnit('sysmsg');
           AddUnit('fvcommon');
           AddUnit('fvconsts');
+          AddUnit('fvclip');
         end;
     T:=P.Targets.AddUnit('udrivers.pas',P.OSes-[msdos,win16]);
       with T.Dependencies do
@@ -209,6 +210,7 @@ begin
           AddUnit('sysmsg');
           AddUnit('ufvcommon');
           AddUnit('fvconsts');
+          AddUnit('ufvclip');
         end;
     T:=P.Targets.AddUnit('editors.pas');
       with T.Dependencies do
@@ -223,6 +225,7 @@ begin
           AddUnit('app');
           AddUnit('stddlg');
           AddUnit('msgbox');
+          AddUnit('fvclip');
         end;
     T.ResourceStrings := True;
     T:=P.Targets.AddUnit('ueditors.pas',P.OSes-[msdos,win16]);
@@ -238,27 +241,24 @@ begin
           AddUnit('uapp');
           AddUnit('ustddlg');
           AddUnit('umsgbox');
+          AddUnit('ufvclip');
         end;
     T.ResourceStrings := True;
-    T:=P.Targets.AddUnit('fvclip.pas',AllUnixOSes);
+    T:=P.Targets.AddUnit('fvclip.pas');
       with T.Dependencies do
         begin
           AddInclude('fvclip.inc');
           AddInclude('platform.inc');
-          AddUnit('drivers');
+          AddUnit('sysmsg');
           AddUnit('fvconsts');
-          AddUnit('app');
-          AddUnit('fvcommon');
         end;
-    T:=P.Targets.AddUnit('ufvclip.pas',AllUnixOSes);
+    T:=P.Targets.AddUnit('ufvclip.pas',P.OSes-[msdos,win16]);
       with T.Dependencies do
         begin
           AddInclude('fvclip.inc');
           AddInclude('platform.inc');
-          AddUnit('udrivers');
+          AddUnit('sysmsg');
           AddUnit('fvconsts');
-          AddUnit('uapp');
-          AddUnit('ufvcommon');
         end;
     T:=P.Targets.AddUnit('fvcommon.pas');
       with T.Dependencies do
@@ -399,6 +399,7 @@ begin
           AddUnit('udrivers');
           AddUnit('uviews');
         end;
+    T:=P.Targets.AddUnit('pmode.pas',[go32v2]);
     T:=P.Targets.AddUnit('statuses.pas');
       with T.Dependencies do
         begin
@@ -553,6 +554,11 @@ begin
         end;
     P.ExamplePath.Add('examples');
     P.ExamplePath.Add('src');
+    P.Targets.AddExampleProgram('examples/keytest.pas');
+    P.Targets.AddExampleProgram('examples/demoedit.pas');
+    P.Targets.AddExampleProgram('examples/colorselonly.pp');
+    P.Targets.AddExampleProgram('examples/filedlg.pas');
+    P.Targets.AddExampleProgram('examples/testuapp.pas',P.OSes-[msdos,win16]);
     P.Targets.AddExampleProgram('examples/testapp.pas');
     P.Targets.AddExampleProgram('src/platform.inc');
     // 'examples/Makefile

+ 3 - 0
packages/fv/namespaced/FreeVision.Pmode.pas

@@ -0,0 +1,3 @@
+unit FreeVision.Pmode;
+{$DEFINE FPC_DOTTEDUNITS}
+{$i pmode.pas}

+ 1 - 0
packages/fv/namespaces.lst

@@ -47,3 +47,4 @@ src/gadgets.pas=namespaced/FreeVision.Gadgets.pas
 src/ugadgets.pas=namespaced/FreeVision.Ugadgets.pas
 src/fvclip.pas=namespaced/FreeVision.Fvclip.pas
 src/ufvclip.pas=namespaced/FreeVision.Ufvclip.pas
+src/pmode.pas=namespaced/FreeVision.Pmode.pas

+ 2 - 18
packages/fv/src/app.inc

@@ -403,21 +403,9 @@ CONST
 {<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>}
 
 {$IFDEF FPC_DOTTEDUNITS}
-uses    System.Console.Mouse
-{$ifdef FV_UNICODE}
-  {$ifdef unix},FreeVision.Ufvclip{$endif}
-{$else FV_UNICODE}
-  {$ifdef unix},FreeVision.Fvclip{$endif}
-{$endif FV_UNICODE}
-  ;
+uses    System.Console.Mouse;
 {$ELSE FPC_DOTTEDUNITS}
-uses    Mouse
-{$ifdef FV_UNICODE}
-  {$ifdef unix},ufvclip{$endif}
-{$else FV_UNICODE}
-  {$ifdef unix},fvclip{$endif}
-{$endif FV_UNICODE}
-  ;
+uses    Mouse;
 {$ENDIF FPC_DOTTEDUNITS}
 
 resourcestring  sVideoFailed='Video initialization failed.';
@@ -1136,7 +1124,6 @@ BEGIN
 {$endif FV_UNICODE}
    InitHistory;                                               { Start history up }
    Inherited Init;                                            { Call ancestor }
-   {$ifdef unix}InitClip(@Self);{$endif}
    InitMsgBox;
    { init mouse and cursor }
    {$IFDEF FPC_DOTTEDUNITS}System.Console.{$ENDIF}Video.SetCursorType(crHidden);
@@ -1160,7 +1147,6 @@ BEGIN
    {$IFDEF FPC_DOTTEDUNITS}FreeVision.{$ENDIF}drivers.donevideo;
 {$endif FV_UNICODE}
 {   DoneMemory;}                                       { Close memory }
-   {$ifdef unix}DoneClip;{$endif}
    donekeyboard;
 {   DoneResource;}
 END;
@@ -1196,7 +1182,6 @@ var s:string;
 {$endif}
 
 BEGIN                                                 { Compatibility only }
-  {$ifdef unix}DoneClip;{$endif}
   DoneSysError;
   DoneEvents;
 {$ifdef FV_UNICODE}
@@ -1232,7 +1217,6 @@ BEGIN                                                 { Compatibility only }
   InitScreen;
   InitEvents;
   InitSysError;
-  {$ifdef unix}InitClip(@Self);{$endif}
   if (PrevHeight<>ScreenHeight) or (PrevWidth<>ScreenWidth) then
     { acknowledge new screen dimensions }
     { prevents to draw out of boundaries of new video buffer }

+ 33 - 17
packages/fv/src/dialogs.inc

@@ -1082,15 +1082,15 @@ resourcestring  slCancel='Cancel';
 
 {$IFDEF FPC_DOTTEDUNITS}
 {$ifdef FV_UNICODE}
-USES FreeVision.Uapp,FreeVision.Uhistlist,FreeVision.Ufvclip;                            { Standard GFV unit }
+USES FreeVision.Uapp,FreeVision.Uhistlist,FreeVision.Ueditors;  { Standard FV unit }
 {$else FV_UNICODE}
-USES FreeVision.App,FreeVision.Histlist,FreeVision.Fvclip;                               { Standard GFV unit }
+USES FreeVision.App,FreeVision.Histlist,FreeVision.Editors;     { Standard FV unit }
 {$endif FV_UNICODE}
 {$ELSE FPC_DOTTEDUNITS}
 {$ifdef FV_UNICODE}
-USES UApp,UHistList,UFVClip;                            { Standard GFV unit }
+USES UApp,UHistList,UEditors;                         { Standard FV unit }
 {$else FV_UNICODE}
-USES App,HistList,FVClip;                               { Standard GFV unit }
+USES App,HistList,Editors;                            { Standard FV unit }
 {$endif FV_UNICODE}
 {$ENDIF FPC_DOTTEDUNITS}
 
@@ -1892,14 +1892,32 @@ Len, I: Integer;
 BEGIN
    Inherited HandleEvent(Event);                      { Call ancestor }
    If (State AND sfSelected <> 0) Then Begin          { View is selected }
+     If Event.What=evKeyDown Then Begin
+       Case Event.KeyCode Of
+         kbCtrlIns:; // COPY command
+         kbShiftDel:; // CUT command
+         kbShiftIns: Begin
+             Event.What:=evCommand;
+             Event.Command:=cmPaste;                  { Translate to Paste command }
+           End;
+       End;
+     End;
      Case Event.What Of
        evNothing: Exit;                               { Speed up exit }
        evCommand: Begin                               { Command event }
-         If (Event.Command=cmPasteText) then begin    { Bracketed paste or osc52 }
-           PasteText(Event.InfoPtr,Event.Id);
-           ClearEvent(Event);
-         end;
-       end;
+         Case (Event.Command) Of
+           cmPasteText: Begin                         { Bracketed paste or OSC 52 }
+               PasteText(Event.InfoPtr,Event.Id);
+               ClearEvent(Event);
+             End;
+           cmPaste: Begin                             { Paste from Clipboard }
+               If assigned(Clipboard) Then
+                 If Clipboard^.GetSelectedText(Event.InfoPtr,Event.Id) Then
+                   PasteText(Event.InfoPtr,Event.Id);
+               ClearEvent(Event);
+             End;
+         End;
+       End;
        evMouseDown: Begin                             { Mouse down event }
          Delta := MouseDelta;                         { Calc scroll value }
          If CanScroll(Delta) Then Begin               { Can scroll }
@@ -1943,24 +1961,22 @@ BEGIN
              begin
                if (Data <> Sw_PString_Empty) and (SelStart < SelEnd) then
                begin
-                 // Copy selected text to OSC 52 clipboard
+                 // Copy selected text to clipboard
                  SelectedTextAnsi := AnsiString(Copy(Data Sw_PString_DeRef, SelStart + 1, SelEnd - SelStart));
                  if Length(SelectedTextAnsi) > 0 then
-                 begin
-                   SetGlobalClipboardData(PAnsiChar(SelectedTextAnsi), Length(SelectedTextAnsi));
-                 end;
+                   if assigned(Clipboard) then
+                     Clipboard^.InsertText(Pointer(SelectedTextAnsi), Length(SelectedTextAnsi), True);
                end;
              end;
            kbShiftDel: // CUT command
              begin
                if (Data <> Sw_PString_Empty) and (SelStart < SelEnd) then
                begin
-                 // Copy selected text to OSC 52 clipboard
+                 // Copy selected text to clipboard
                  SelectedTextAnsi := AnsiString(Copy(Data Sw_PString_DeRef, SelStart + 1, SelEnd - SelStart));
                  if Length(SelectedTextAnsi) > 0 then
-                 begin
-                     SetGlobalClipboardData(PAnsiChar(SelectedTextAnsi), Length(SelectedTextAnsi));
-                 end;
+                   if assigned(Clipboard) then
+                     Clipboard^.InsertText(Pointer(SelectedTextAnsi), Length(SelectedTextAnsi), True);
                  DeleteSelect; // Then delete the selection
                  CheckValid(True); // Validate after deletion
                end;

+ 16 - 3
packages/fv/src/drivers.inc

@@ -84,13 +84,13 @@ USES
 
    {$IFDEF OS_OS2}                                    { OS2 CODE }
      {$IFDEF PPC_Virtual}                             { VIRTUAL PASCAL UNITS }
-       OS2Api.os2def, OS2Base, OS2PMAPI,                     { Standard units }
+       os2def, OS2Base, OS2PMAPI,                     { Standard units }
      {$ENDIF}
      {$IFDEF PPC_Speed}                               { SPEED PASCAL UNITS }
        BseDos, Os2Def,                                { Standard units }
      {$ENDIF}
      {$IFDEF PPC_FPC}                                 { FPC UNITS }
-       OS2Api.doscalls, Os2Def,                              { Standard units }
+       OS2Api.doscalls, OS2Api.Os2Def,                { Standard units }
      {$ENDIF}
    {$ENDIF}
 
@@ -106,7 +106,7 @@ USES
    {$ENDIF}
 
    {$IFDEF OS_AMIGA}
-      dos, Amiga.Core.Amigados,
+      TP.DOS, Amiga.Core.Amigados,
    {$ENDIF}
 
    System.Console.Video,
@@ -114,8 +114,10 @@ USES
 {$ifdef FV_UNICODE}
    FreeVision.UfvCommon,
    System.Unicode.Graphemebreakproperty,
+   FreeVision.Ufvclip,
 {$else FV_UNICODE}
    FreeVision.Fvcommon,
+   FreeVision.Fvclip,
 {$endif FV_UNICODE}
    System.Objects;                                 { GFV standard units }
 {$ELSE FPC_DOTTEDUNITS}
@@ -165,8 +167,10 @@ USES
 {$ifdef FV_UNICODE}
    UFVCommon,
    GraphemeBreakProperty,
+   ufvclip,
 {$else FV_UNICODE}
    FVCommon,
+   fvclip,
 {$endif FV_UNICODE}
    Objects;                                 { GFV standard units }
 {$ENDIF FPC_DOTTEDUNITS}
@@ -1523,6 +1527,13 @@ begin
           Event.Id:=SysEvent.x;
           Event.InfoWord:=SysEvent.y;
         end;
+      SysPaste :
+        begin
+          Event.What:=evCommand;
+          Event.Command:=cmPasteText;
+          Event.Id:=SysEvent.Len;
+          Event.InfoPtr:=SysEvent.P;
+        end;
       else
         Event.What:=evNothing;
       end;
@@ -1558,6 +1569,7 @@ BEGIN
      MouseEvents := True;                             { Set initialized flag }
     end;
   InitSystemMsg;
+  InitClip;
 END;
 
 {---------------------------------------------------------------------------}
@@ -1565,6 +1577,7 @@ END;
 {---------------------------------------------------------------------------}
 PROCEDURE DoneEvents;
 BEGIN
+  DoneClip;
   DoneSystemMsg;
   {$IFDEF FPC_DOTTEDUNITS}System.Console.{$ENDIF}Mouse.DoneMouse;
   MouseEvents:=false;

+ 144 - 26
packages/fv/src/editors.inc

@@ -225,6 +225,7 @@ type
     function   InsertChar (AChar : Sw_Char) : Boolean;
     procedure  ScrollTo (X, Y : Sw_Integer);
     function   Search (const FindStr : String; Opts : Word) : Boolean;
+    function   GetSelectedText (var Text : Pointer; var Length : Sw_Word) : Boolean;
     function   SetBufSize (NewSize : Sw_Word) : Boolean; virtual;
     procedure  SetCmdState (Command : Word; Enable : Boolean);
     procedure  SetSelect (NewStart, NewEnd : Sw_Word; CurStart : Boolean);
@@ -290,6 +291,7 @@ type
     procedure  Scroll_Up;
     procedure  Select_Word;
     procedure  SetBufLen (Length : Sw_Word);
+    function   SetTextWinClip : Boolean; { Copy to OS clipboard. }
     procedure  Set_Place_Marker (Element : Byte);
     procedure  Set_Right_Margin;
     procedure  Set_Tabs;
@@ -365,6 +367,15 @@ function RightMarginDialog : PDialog;
 function TabStopDialog : PDialog;
 function StdEditorDialog(Dialog: SmallInt; Info: Pointer): Word;
 
+{ If true then use OS clipboard otherwise use local clipboard (Editor.Clipboard). }
+{ At unit initalization its value is set to value of WinClipboardSupported. }
+function GlobalClipboard : boolean; inline;
+
+{ Set to false to use local clipboard.
+  If set to True then GlobalClipboard value will be value of WinClipboardSupported. }
+procedure SetGlobalClipboard( AGlobalClipboard : boolean);
+
+
 const
   WordChars    : set of AnsiChar = ['!'..#255];
 
@@ -488,7 +499,8 @@ implementation
 uses
   TP.DOS,
 {$ifdef FV_UNICODE}
-  System.Console.Video, System.Unicode.Graphemebreakproperty, FreeVision.Uapp, FreeVision.Ustddlg, FreeVision.Umsgbox, FreeVision.Ufvclip;
+  System.Console.Video, System.Unicode.Graphemebreakproperty, FreeVision.Uapp,
+  FreeVision.Ustddlg, FreeVision.Umsgbox, FreeVision.Ufvclip;
 {$else FV_UNICODE}
   FreeVision.App, FreeVision.Stddlg, FreeVision.Msgbox, FreeVision.Fvclip;
 {$ENDIF}
@@ -695,6 +707,19 @@ CONST
   { CENTER - Stop. } { Added @FormatKeys for new ^O? keys. }
 
 
+var DefaultGlobalClipboard : boolean;
+
+function GlobalClipboard : boolean;
+begin
+  GlobalClipboard:=DefaultGlobalClipboard;
+end;
+
+procedure SetGlobalClipboard( AGlobalClipboard : boolean);
+begin
+  DefaultGlobalClipboard:=AGlobalClipboard and WinClipboardSupported;
+end;
+
+
 {****************************************************************************
                                  Dialogs
 ****************************************************************************}
@@ -1726,30 +1751,7 @@ end; {Check_For_Word_Wrap}
 
 
 function TEditor.ClipCopy : Boolean;
-var
-  SelectedTextAnsi: AnsiString;
-  Len: Sw_Word;
 begin
-  if HasSelection then
-  begin
-    Len := SelEnd - SelStart;
-    SetLength(SelectedTextAnsi, Len);
-    if Len > 0 then
-    begin
-      if SelEnd <= CurPtr then
-        Move(Buffer^[SelStart], SelectedTextAnsi[1], Len)
-      else if SelStart >= CurPtr then
-        Move(Buffer^[SelStart + GapLen], SelectedTextAnsi[1], Len)
-      else
-      begin
-        Move(Buffer^[SelStart], SelectedTextAnsi[1], CurPtr - SelStart);
-        Move(Buffer^[CurPtr + GapLen], SelectedTextAnsi[1 + (CurPtr - SelStart)], SelEnd - CurPtr);
-      end;
-      if Length(SelectedTextAnsi) > 0 then
-        SetGlobalClipboardData(PAnsiChar(SelectedTextAnsi), Length(SelectedTextAnsi));
-    end;
-  end;
-
   ClipCopy := False;
   if Assigned(Clipboard) and (Clipboard <> @Self) then
    begin
@@ -2774,6 +2776,10 @@ begin
              (Event.Command <> cmBackSpace) and
              (Event.Command <> cmTabKey)    and
              (Event.Command <> cmSelectAll) and
+{$ifdef unix}
+             { this is due to fact that OSC 52 paste is delayed and performed later via cmPasteText or never }
+             ((Event.Command <> cmPaste) or ((Event.Command = cmPaste) and (not GlobalClipboard) )) and
+{$endif}
               Modified then
             Remove_EOL_Spaces (SelectMode);
           Unlock;
@@ -2950,14 +2956,111 @@ begin
 end; { TEditor.InsertChar }
 
 
-function TEditor.InsertFrom (Editor : PEditor) : Boolean;
+function TEditor.SetTextWinClip : Boolean;
+var
+  SelectedTextAnsi: AnsiString;
+  Len: Sw_Word;
+var InsertToClipboard : boolean;
 begin
+  SetTextWinClip:=false;
+  InsertToClipboard:=IsClipboard;
+  if HasSelection then
+  begin
+    Len := SelEnd - SelStart;
+    SetLength(SelectedTextAnsi, Len);
+    if Len > 0 then
+    begin
+      if SelEnd <= CurPtr then
+      begin
+        Move(Buffer^[SelStart], SelectedTextAnsi[1], Len)
+      end
+      else if SelStart >= CurPtr then
+        Move(Buffer^[SelStart + GapLen], SelectedTextAnsi[1], Len);
+      if Length(SelectedTextAnsi) > 0 then
+        SetTextWinClip:=SetTextWinClipBoardData(PAnsiChar(SelectedTextAnsi), Length(SelectedTextAnsi));
+    end;
+  end;
+end; { TEditor.SetTextWinClip }
+
+
+function TEditor.InsertFrom (Editor : PEditor) : Boolean;
+var InsertToClipboard : boolean;
+    InsertFromClipboard : boolean;
+    Len  : longint;
+    P : PAnsiChar;
+begin
+  InsertToClipboard:=IsClipboard;
+  InsertFromClipboard:=(Editor = Clipboard);
+  { Look if Clipboard then might be need to interact with OS clipboard. }
+  if InsertToClipboard or InsertFromClipboard then
+    if GlobalClipboard and not (InsertToClipboard and InsertFromClipboard) then
+      if InsertToClipboard then
+      begin
+        { Insert to OS clipboard (Copy or Cut) }
+        if not Editor^.SetTextWinClip then
+        begin
+           { Fail to set OS clipboard, not much to do about. }
+        end;
+      end else
+      begin
+        { Insert from OS clipboard (Paste) }
+        P:=nil; Len:=0;
+        if GetTextWinClipBoardData (P , Len ) then
+        begin
+          if assigned(P) then
+          begin
+            { Insert OS clipboard text in local Clipboard }
+            InsertFrom := Editor^.InsertBuffer (PEditBuffer(P),0,Len, Editor^.CanUndo, InsertToClipboard);
+            { Insert OS clipboard text in itself }
+            InsertFrom := InsertBuffer (PEditBuffer(P),0,Len, CanUndo, InsertToClipboard);
+            FreeMem(p);
+          end;
+          exit;
+        end;
+      end;
+
   InsertFrom := InsertBuffer (Editor^.Buffer,
     Editor^.BufPtr (Editor^.SelStart),
-    Editor^.SelEnd - Editor^.SelStart, CanUndo, IsClipboard);
+    Editor^.SelEnd - Editor^.SelStart, CanUndo, InsertToClipboard);
 end; { TEditor.InsertFrom }
 
 
+function TEditor.GetSelectedText (var Text : Pointer; var Length : Sw_Word) : Boolean;
+{ Return reference to TEditor's selected text. True if there are any text }
+{ selected. If Editor is Clipboard then return OS clipboard content if    }
+{ available and configured to do so.                                      }
+var GetFromClipboard : boolean;
+   Offset : Longword;
+   Len  : longint;
+   P : PAnsiChar;
+begin
+  GetSelectedText:=False;
+  Text:=nil;Length:=0;
+  GetFromClipboard:=IsClipboard;
+  { Look if Clipboard then might be need to interact with OS clipboard. }
+  if GetFromClipboard then
+    if GlobalClipboard then                            { Use OS clipboard }
+    begin
+      P:=nil; Len:=0;
+      if GetTextWinClipBoardData (P , Len ) then       { Get OS clipboard data }
+        if assigned(P) then
+        begin
+          InsertBuffer (PEditBuffer(P),0,Len, False, True);{ Insert and select }
+          FreeMem(p);
+        end else
+          Exit; {no data}
+    end;
+
+  if SelStart<>SelEnd then
+  begin
+    Offset:=BufPtr (SelStart);
+    Text:=@Buffer^[Offset];
+    Length:=SelEnd-SelStart;
+    GetSelectedText:=True;
+  end;
+end; { TEditor.GetSelectedText }
+
+
 procedure TEditor.Insert_Line (Select_Mode : Byte);
 { This procedure inserts a newline at the current cursor position }
 { if a ^N is pressed.  Unlike cmNewLine, the cursor will return   }
@@ -2973,7 +3076,20 @@ end; { TEditor.Insert_Line }
 function TEditor.InsertText (Text       : Pointer;
                              Length     : Sw_Word;
                              SelectText : Boolean) : Boolean;
+var InsertToClipboard : boolean;
 begin
+  InsertToClipboard:=IsClipboard;
+  { Look if Clipboard then might be need to interact with OS clipboard. }
+  if InsertToClipboard and SelectText then
+    if GlobalClipboard then
+    begin
+      { Insert to clipboard (Copy or Cut) }
+      if not SetTextWinClipBoardData(PAnsiChar(Text), Length) then
+        begin
+           { Fail to set OS clipboard, not much to do about. }
+        end;
+    end;
+
   if assigned(Text) and not Search_Replace then
     Update_Place_Markers (Length, 0, Self.SelStart, Self.SelEnd);
   InsertText := InsertBuffer (PEditBuffer (Text),
@@ -4662,4 +4778,6 @@ begin
 end; { RegisterEditors }
 
 
+begin
+  DefaultGlobalClipboard:=WinClipboardSupported;
 end. { Unit NewEdit }

+ 728 - 68
packages/fv/src/fvclip.inc

@@ -1,9 +1,13 @@
 {
    This unit is part of the Free Vision package
+   Copyright (c) 1999 by Pierre Muller
 
-   Copyright 2024 by Margers
+   General OS clipboard support unit.
 
-   Bracketed paste and OSC 52 clipboard support (Unix only).
+   Connection with Windows Clipboard based on Ralph Brown Interrupt List
+
+   Copyright (c) 2024 by Margers
+   Bracketed paste and OSC 52 clipboard support.
 
    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.
@@ -32,58 +36,96 @@ unit fvclip;
 
 interface
 
-{$IFDEF FPC_DOTTEDUNITS}
-{$ifdef FV_UNICODE}
-uses System.Objects, FreeVision.Uapp;
-{$else FV_UNICODE}
-uses System.Objects, FreeVision.App;
-{$endif FV_UNICODE}
-{$ELSE}
-{$ifdef FV_UNICODE}
-uses objects,uapp;
-{$else FV_UNICODE}
-uses objects,app;
-{$endif FV_UNICODE}
-{$ENDIF}
-
-{Should be called after InitKeyboard}
-procedure InitClip(AProgram :PProgram);
-procedure DoneClip;
+{$undef WinClipSupported}
+{$undef DOS}
+{ ----------- define DOS for DOS targets ---------- }
+{$ifdef GO32V2}{$define DOS}{$endif}
 
-{Request clipboard content}
-{Actual clipboard content will be returned via event system, if terminal supports OSC 52}
-procedure GetGlobalClipboardData;
+function WinClipboardSupported : boolean;
+function OpenWinClipboard : boolean;
+function EmptyWinClipboard : boolean;
+function CloseWinClipboard : boolean;
+function GetTextWinClipboardSize : longint;
+function GetTextWinClipboardData(var p : PAnsiChar;var l : longint) : boolean;
+function SetTextWinClipboardData(p : PAnsiChar;l : longint) : boolean;
 
-{ Set clipboard content, if terminal supports OSC 52. Return true always }
-function SetGlobalClipboardData(P: PAnsiChar; ASize: longint): boolean;
+{Should be called after InitKeyboard }
+procedure InitClip;
+procedure DoneClip;
 
 implementation
 
 {$IFDEF FPC_DOTTEDUNITS}
-uses
+{$ifdef DOS}
+  uses
+    FreeVision.Pmode,
+{$ifdef go32v2}
+    {go32   sorry Gabor, but its still not compiling without that ! }
+    {now it works. btw. you don't have to sorry - just to tell me... ;)) Gabor }
+{$endif go32v2}
+    TP.DOS;
+{$endif DOS}
+
 {$ifdef unix}
-  UnixApi.Base, System.Console.Keyboard,
+  uses
+    UnixApi.Base,UnixApi.TermIO,System.Console.Keyboard,FreeVision.Sysmsg;
 {$endif}
-{$ifdef FV_UNICODE}
-  FreeVision.UDrivers, FreeVision.Ufvcommon,
-{$else FV_UNICODE}
-  FreeVision.Drivers, FreeVision.Fvcommon,
-{$endif FV_UNICODE}
-  FreeVision.Fvconsts;
-{$ELSE}
-uses
+
+{$ifdef Windows}
+  uses
+    System.Strings,WinApi.Windows;
+{$endif Windows}
+
+{$ifdef HASAMIGA}
+  uses
+    {$ifdef AMIGA68K} Amiga.Core.Clipboard,{$endif}
+    {$ifdef AMIGAOS4} AmigaApi.Clipboard,{$endif}
+    {$ifdef AROS} AROSApi.Clipboard,{$endif}
+    {$ifdef MorphOS} MorphApi.Clipboard,{$endif}
+    AmigaApi.Cliputils;
+{$endif}
+
+{$ifdef os2}
+  uses
+    OS2Api.DosCalls, OS2Api.OS2Def;
+{$endif os2}
+
+{$ELSE  not FPC_DOTTEDUNITS}
+{$ifdef DOS}
+  uses
+    pmode,
+{$ifdef go32v2}
+    {go32   sorry Gabor, but its still not compiling without that ! }
+    {now it works. btw. you don't have to sorry - just to tell me... ;)) Gabor }
+{$endif go32v2}
+    dos;
+{$endif DOS}
+
 {$ifdef unix}
-  baseUnix,keyboard,
+  uses
+    baseUnix,termio,keyboard,sysmsg;
 {$endif}
-{$ifdef FV_UNICODE}
-  udrivers, UFVCommon,
-{$else FV_UNICODE}
-  drivers, FVCommon,
-{$endif FV_UNICODE}
-  fvconsts;
-{$ENDIF}
-var cProgram : PProgram;
-  PText : PAnsiChar;
+
+{$ifdef Windows}
+  uses
+    strings,windows;
+{$endif Windows}
+
+{$ifdef HASAMIGA}
+  uses
+    clipboard,cliputils;
+{$endif}
+
+{$ifdef os2}
+  uses
+    DosCalls, OS2Def;
+{$endif os2}
+
+{$ENDIF  FPC_DOTTEDUNITS}
+
+
+{$ifdef UNIX}
+var PText : PAnsiChar;
 
 {Could not use unit base64 because of Sysutils and reasons }
 {Speed or reusability here is not a concern                }
@@ -92,7 +134,7 @@ const
     'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
 Alphabet = ['a'..'z','A'..'Z','0'..'9','+','/','=']; // all 65 chars that are in the base64 encoding alphabet
 
-{ Memory have to be preallocated;  source p, destination d }
+{ Memory has to be preallocated;  source p, destination d }
 procedure encodeBase64(p:PAnsiChar;len:longint; d:PAnsiChar; var outlen: longint);
 var
   i, rem : longint;
@@ -136,7 +178,7 @@ begin
   end;
 end;
 
-{ Memory have to be preallocated;  source p, destination d }
+{ Memory has to be preallocated;  source p, destination d }
 procedure decodeBase64(p:PAnsiChar; len: longint; d:PAnsiChar; var outlen: longint);
 var
   i,rlen : longint;
@@ -185,30 +227,37 @@ begin
      outlen:=rlen; {length for output}
 end;
 
-{$ifdef unix}
-procedure PutInEventQue (var zt: AnsiString;l:sw_integer);
-var Event:TEvent;
+
+procedure PutInEventQue (var zt: AnsiString;l:Longint);
+var SysEvent:TSystemEvent;
+    PrevPText : PAnsiChar;
+    NewPText : PAnsiChar;
 begin
-  if Assigned(PText) then
-    FreeMem(PText);
-  GetMem(PText,l+1);
-  Move(zt[1],PText^,l+1);
-  Event.What:=evCommand;
-  Event.Command:=cmPasteText;
-  Event.Id:=l; {length of pasted text}
-  Event.InfoPtr:=pointer(PText);
-  cProgram^.PutEvent(Event);
+  GetMem(NewPText,l+1);
+  Move(zt[1],NewPText^,l+1);
+  { Create paste event }
+  SysEvent.Typ:=SysPaste;
+  SysEvent.P:=PAnsiChar(NewPText);
+  SysEvent.Len:=l;
+  PutSystemEvent(SysEvent);
+  { Discard previous pasted data }
+  { This is not Thread safe, but expectation is that FV is running in single thread }
+  PrevPText:=PText;
+  PText:=NewPText;
+  if Assigned(PrevPText) then
+    FreeMem(PrevPText);
 end;
 
-procedure LinuxClipBoardData;
+
+procedure OSC_52_ClipboardData;
 var zt,rt  : AnsiString;
   escSeq : ShortString;
   inEsc,inRead : boolean;
-  k : sw_integer;
+  k : Longint;
   ch : AnsiChar;
   timewait,finalparsec : TimeSpec;
   ree:longint;
-  countemptines : sw_integer;
+  countemptines : Longint;
   rlen : longint;
 begin
   countemptines:=0;
@@ -267,14 +316,15 @@ begin
   PutInEventQue(rt,rlen);
 end;
 
+
 procedure BracketedPaste;
 var zt  : AnsiString;
-  k : sw_integer;
+  k : Longint;
   ch : AnsiChar;
   timewait,finalparsec : TimeSpec;
   ree:longint;
-  countemptines : sw_integer;
-  len : sw_integer;
+  countemptines : Longint;
+  len : Longint;
 begin
   countemptines:=0;
   zt:='';
@@ -313,15 +363,14 @@ begin
 end;
 {$endif}
 
-procedure InitClip(AProgram :PProgram);
+procedure InitClip;
 begin
 {$ifdef unix}
   if Assigned(PText) then
     FreeMem(PText);
   PText:=nil;
-  cProgram:=AProgram;
   AddSpecialSequence(#27'[200~',@BracketedPaste);
-  AddSpecialSequence(#27']52;c',@LinuxClipBoardData);
+  AddSpecialSequence(#27']52;c',@OSC_52_ClipboardData);
   write(#27'[?2004h');
 {$endif}
 end;
@@ -339,7 +388,6 @@ end;
 {function GetGlobalClipboardData(var P: PAnsiChar;var ASize: longint): boolean;}
 procedure GetGlobalClipboardData;
 begin
-  {GetGlobalClipboardData:=false;}
 {$ifdef unix}
   write(#27']52;c;?'#7); { OSC 52  Get Clipboard Content }
 {$endif}
@@ -363,4 +411,616 @@ begin
 {$endif}
 end;
 
+
+{$ifdef DOS}
+{$define WinClipSupported}
+function WinClipboardSupported : boolean;
+var
+  r : registers;
+begin
+  r.ax:=$1700;
+  RealIntr($2F,r);
+  WinClipboardSupported:=(r.ax<>$1700);
+end;
+
+function OpenWinClipboard : boolean;
+var
+  r : Registers;
+begin
+  r.ax:=$1701;
+  RealIntr($2F,r);
+  OpenWinClipboard:=(r.ax<>0);
+end;
+
+function EmptyWinClipboard : boolean;
+var
+  r : Registers;
+begin
+  r.ax:=$1702;
+  RealIntr($2F,r);
+  EmptyWinClipboard:=(r.ax<>0);
+end;
+
+function CloseWinClipboard : boolean;
+var
+  r : Registers;
+begin
+  r.ax:=$1708;
+  RealIntr($2F,r);
+  CloseWinClipboard:=(r.ax<>0);
+end;
+
+function InternGetDataSize : longint;
+var
+  r : Registers;
+begin
+  r.ax:=$1704;
+  r.dx:=7 {OEM Text rather then 1 : Text };
+  RealIntr($2F,r);
+  InternGetDataSize:=(r.dx shl 16) + r.ax;
+end;
+{$endif DOS}
+
+{$ifdef UNIX}
+{$define WinClipSupported}
+function WinClipboardSupported : boolean;
+var term, typ : string;
+    thistty : shortstring;
+begin
+  WinClipboardSupported:=false;
+{$if not defined(LINUX) and not defined(BSD)}
+  Exit; { Report as not supported when in realty it has not been tested. }
+{$endif}
+{$ifndef LINUX}
+  thistty:=ttyname(stdinputhandle);
+  if (copy(thistty,1,8)<>'/dev/tty') then
+    WinClipboardSupported:=true; { probably we are good }
+{$endif}
+{$ifdef LINUX}
+  typ:=fpgetenv('XDG_SESSION_TYPE');
+  if length(typ)>0 then
+    if lowercase(typ)='tty' then
+      Exit; { in console mode OSC 52 is not supported }
+  term:=fpgetenv('TERM');
+  if length(term)>0 then
+    if lowercase(term)<>'linux' then
+      WinClipboardSupported:=true; { probably we are good }
+{$endif}
+end;
+
+function OpenWinClipboard : boolean;
+begin
+  OpenWinClipboard:=true;
+end;
+
+function EmptyWinClipboard : boolean;
+begin
+  EmptyWinClipboard:=true;
+end;
+
+function CloseWinClipboard : boolean;
+begin
+  CloseWinClipboard:=true;
+end;
+
+function GetTextWinClipboardSize : longint;
+begin
+  GetTextWinClipboardSize:=1;  {there has to be something in order for menu to be active}
+end;
+
+function GetTextWinClipBoardData(var P : PAnsiChar;var L : longint) : boolean;
+begin
+  GetTextWinClipBoardData:=true;
+  P:=nil;L:=0;              { Have no immediate response }
+  GetGlobalClipboardData;   { Request now, get clipboard data later }
+end;
+
+function SetTextWinClipBoardData(P : PAnsiChar; L : longint) : boolean;
+begin
+  SetTextWinClipBoardData:= SetGlobalClipboardData(P,L);
+end;
+{$endif}
+
+{$ifdef Windows}
+{$define WinClipSupported}
+function WinClipboardSupported : boolean;
+begin
+  WinClipboardSupported:=true;
+end;
+
+function OpenWinClipboard : boolean;
+begin
+  OpenWinClipboard:=OpenClipboard(0);
+end;
+
+function EmptyWinClipboard : boolean;
+begin
+  EmptyWinClipboard:=EmptyClipboard;
+end;
+
+function CloseWinClipboard : boolean;
+begin
+  CloseWinClipboard:=CloseClipboard;
+end;
+
+function InternGetDataSize : longint;
+var HC : Handle;
+begin
+  HC:=GetClipBoardData(CF_OEMTEXT);
+  if HC<>0 then
+    begin
+      InternGetDataSize:=strlen(PAnsiChar(GlobalLock(HC)))+1;
+      GlobalUnlock(HC);
+    end
+  else
+    InternGetDataSize:=0;
+end;
+{$endif Windows}
+
+{$ifdef HASAMIGA}
+{$define WinClipSupported}
+function WinClipboardSupported: Boolean;
+begin
+  WinClipboardSupported := True;
+end;
+
+function OpenWinClipboard: boolean;
+begin
+  OpenWinClipboard := True;
+end;
+
+function EmptyWinClipboard: boolean;
+begin
+  EmptyWinClipboard := GetTextFromClip(PRIMARY_CLIP) = '';
+end;
+
+function CloseWinClipboard : boolean;
+begin
+  CloseWinClipboard:= True;
+end;
+
+function InternGetDataSize: LongInt;
+var
+  Text: string;
+begin
+  Text := GetTextFromClip(PRIMARY_CLIP);
+  InternGetDataSize := Length(Text);
+end;
+{$endif HASAMIGA}
+
+{$ifdef os2}
+{$define WinClipSupported}
+const
+  CF_TEXT = 1;
+  CF_BITMAP = 2;
+  CF_DSPTEXT = 3;
+  CF_DSPBITMAP = 4;
+  CF_METAFILE = 5;
+  CF_DSPMETAFILE = 6;
+  CF_PALETTE = 9;
+
+  CFI_OWNERFREE = $0001;
+  CFI_OWNERDISPLAY = $0002;
+  CFI_POINTER = $0400;
+  CFI_HANDLE = $0200;
+
+var
+  OS2ClipboardSupported: boolean = false;
+  PMWHandle: cardinal;
+  MsgQueueHandle: cardinal;
+  PIB: PProcessInfoBlock;
+
+type
+(*  TWinSetClipbrdOwner = function (hab, hwnd: cardinal): longbool; cdecl;*)
+  TWinSetClipbrdData = function (hab, ulData, fmt, rgfFmtInfo: cardinal): longbool;  cdecl;
+  TWinQueryClipbrdData = function (hab, fmt: cardinal): cardinal; cdecl;
+  TWinQueryClipbrdFmtInfo = function (hab, fmt: cardinal; var prgfFmtInfo: cardinal): longbool; cdecl;
+{    function WinSetClipbrdViewer(hab,hwndNewClipViewer : cardinal) : longbool;  cdecl;}
+{    function WinEnumClipbrdFmts(hab,fmt : cardinal) : cardinal; cdecl;}
+  TWinEmptyClipbrd = function (hab: cardinal): longbool; cdecl;
+  TWinOpenClipbrd = function (hab: cardinal): longbool; cdecl;
+  TWinCloseClipbrd = function (hab: cardinal): longbool; cdecl;
+(*  TWinQueryClipbrdOwner = function (hab: cardinal): cardinal; cdecl;*)
+{    function WinQueryClipbrdViewer(hab : cardinal) : cardinal; cdecl;}
+  TWinInitialize = function (flOptions: cardinal): cardinal; cdecl;
+  TWinTerminate = function (hab: cardinal): longbool; cdecl;
+  TWinCreateMsgQueue = function (hab: cardinal; cmsg: longint): cardinal; cdecl;
+  TWinDestroyMsgQueue = function (hmq: cardinal): longbool; cdecl;
+
+var
+(*  WinSetClipbrdOwner: TWinSetClipbrdOwner;*)
+  ClWinSetClipbrdData: TWinSetClipbrdData;
+  ClWinQueryClipbrdData: TWinQueryClipbrdData;
+  ClWinQueryClipbrdFmtInfo: TWinQueryClipbrdFmtInfo;
+{    function WinSetClipbrdViewer(hab,hwndNewClipViewer : cardinal) : longbool;  cdecl;}
+{    function WinEnumClipbrdFmts(hab,fmt : cardinal) : cardinal; cdecl;}
+  ClWinEmptyClipbrd: TWinEmptyClipbrd;
+  ClWinOpenClipbrd: TWinOpenClipbrd;
+  ClWinCloseClipbrd: TWinCloseClipbrd;
+(*  WinQueryClipbrdOwner: TWinQueryClipbrdOwner;*)
+{    function WinQueryClipbrdViewer(hab : cardinal) : cardinal; cdecl;}
+  ClWinInitialize: TWinInitialize;
+  ClWinTerminate: TWinTerminate;
+  ClWinCreateMsgQueue: TWinCreateMsgQueue;
+  ClWinDestroyMsgQueue: TWinDestroyMsgQueue;
+
+  OrigSessType: cardinal;
+
+
+function WinClipboardSupported : boolean;
+begin
+  WinClipboardSupported:=OS2ClipboardSupported;
+end;
+
+function OpenWinClipboard : boolean;
+var
+  SessType: cardinal;
+begin
+  OpenWinClipboard := false;
+  if not (OS2ClipboardSupported) then
+   Exit;
+  SessType := PIB^.tType;
+  PIB^.tType := 3;
+  OpenWinClipboard := ClWinOpenClipbrd (PMWHandle);
+  PIB^.tType := SessType;
+end;
+
+function EmptyWinClipboard : boolean;
+var
+  SessType: cardinal;
+begin
+  EmptyWinClipboard := false;
+  if not (OS2ClipboardSupported) then
+   Exit;
+  SessType := PIB^.tType;
+  PIB^.tType := 3;
+  EmptyWinClipboard := ClWinEmptyClipbrd (PMWHandle);
+  PIB^.tType := SessType;
+end;
+
+function CloseWinClipboard : boolean;
+var
+  SessType: cardinal;
+begin
+  CloseWinClipboard := false;
+  if not (OS2ClipboardSupported) then
+   Exit;
+  SessType := PIB^.tType;
+  PIB^.tType := 3;
+  CloseWinClipboard := ClWinCloseClipbrd (PMWHandle);
+  PIB^.tType := SessType;
+end;
+
+function InternGetDataSize : longint;
+var
+  P: PAnsiChar;
+  SessType: cardinal;
+begin
+  InternGetDataSize := 0;
+  if not (OS2ClipboardSupported) then
+   Exit;
+  SessType := PIB^.tType;
+  PIB^.tType := 3;
+  P := PAnsiChar (ClWinQueryClipbrdData (PMWHandle, CF_TEXT));
+  PIB^.tType := SessType;
+
+  if P <> nil then
+   InternGetDataSize := StrLen (PAnsiChar (P)) + 1;
+end;
+
+procedure InitClipboard;
+var
+  RC: cardinal;
+  ProcOK: boolean;
+  TIB: PThreadInfoBlock;
+  PMWModHandle: THandle;
+  Err: string;
+  ErrL: cardinal;
+begin
+  if OS2ClipboardSupported then
+   Exit;
+  DosGetInfoBlocks (TIB, PIB);
+  OrigSessType := PIB^.tType;
+  PIB^.tType := 3;
+
+{  RC := DosQueryModuleHandle ('PMWIN', PMWModHandle);}
+  RC := DosLoadModule (Err, ErrL, 'PMWIN', PMWModHandle);
+  if RC <> 0 then
+   begin
+    PIB^.tType := OrigSessType;
+    Exit;
+   end;
+
+  ProcOK := (DosQueryProcAddr (PMWModHandle, 707, nil, pointer (ClWinCloseClipbrd)) = 0)
+     and
+   (DosQueryProcAddr (PMWModHandle, 716, nil, pointer (ClWinCreateMsgQueue)) = 0) and
+   (DosQueryProcAddr (PMWModHandle, 726, nil, pointer (ClWinDestroyMsgQueue)) = 0) and
+   (DosQueryProcAddr (PMWModHandle, 733, nil, pointer (ClWinEmptyClipbrd)) = 0) and
+   (DosQueryProcAddr (PMWModHandle, 763, nil, pointer (ClWinInitialize)) = 0) and
+   (DosQueryProcAddr (PMWModHandle, 793, nil, pointer (ClWinOpenClipbrd)) = 0) and
+   (DosQueryProcAddr (PMWModHandle, 806, nil, pointer (ClWinQueryClipbrdData)) = 0) and
+   (DosQueryProcAddr (PMWModHandle, 807, nil, pointer (ClWinQueryClipbrdFmtInfo)) = 0) and
+   (DosQueryProcAddr (PMWModHandle, 854, nil, pointer (ClWinSetClipbrdData)) = 0) and
+   (DosQueryProcAddr (PMWModHandle, 888, nil, pointer (ClWinTerminate)) = 0);
+
+  if ProcOK then
+   begin
+    PMWHandle := ClWinInitialize (0);
+    if PMWHandle <> 0 then
+     begin
+      MsgQueueHandle := ClWinCreateMsgQueue (PMWHandle, 0);
+      ProcOK := MsgQueueHandle <> 0;
+     end
+    else
+     ProcOK := false;
+   end;
+
+  PIB^.tType := OrigSessType;
+
+  if ProcOK then
+   OS2ClipboardSupported := true;
+end;
+
+procedure DoneClipboard;
+var
+  SessType: cardinal;
+begin
+  if not (OS2ClipboardSupported) then
+   Exit;
+  OS2ClipboardSupported := false;
+  SessType := PIB^.tType;
+  PIB^.tType := 3;
+  if MsgQueueHandle <> 0 then
+   begin
+    ClWinDestroyMsgQueue (MsgQueueHandle);
+    MsgQueueHandle := 0;
+   end;
+  if PMWHandle <> 0 then
+   begin
+    ClWinTerminate (PMWHandle);
+    PMWHandle := 0;
+   end;
+  PIB^.tType := SessType;
+end;
+{$endif os2}
+
+{$ifndef UNIX} { Unix have defined all functions, lets go for every other system }
+{$ifdef WinClipSupported}
+function GetTextWinClipboardSize : longint;
+begin
+  OpenWinClipboard;
+  GetTextWinClipboardSize:=InternGetDataSize;
+  CloseWinClipboard;
+end;
+
+function GetTextWinClipBoardData(var p : PAnsiChar;var l : longint) : boolean;
+var
+{$ifdef DOS}
+  r : Registers;
+  M : MemPtr;
+  pp: PAnsiChar;
+{$endif DOS}
+{$ifdef Windows}
+  h : HGlobal;
+  pp : PAnsiChar;
+{$endif Windows}
+{$ifdef HASAMIGA}
+  Text: AnsiString;
+  pp: PAnsiChar;
+{$endif HASAMIGA}
+{$IFDEF OS2}
+  PP: PAnsiChar;
+  SessType: cardinal;
+{$ENDIF OS2}
+begin
+  p:=nil;
+  GetTextWinClipBoardData:=False;
+  if not OpenWinClipBoard then
+    exit;
+{$ifdef DOS}
+  l:=InternGetDataSize;
+  if (l=0) or (l>65520) then
+    begin
+      l:=0;
+      CloseWinClipBoard;
+      exit;
+    end;
+  GetMem(p,l+1);
+  GetDosMem(M,l);
+  r.ax:=$1705;
+  r.dx:=7{ OEM Text rather then 1 : Text };
+  r.es:=M.DosSeg;
+  r.bx:=M.DosOfs;
+  RealIntr($2F,r);
+  GetTextWinClipBoardData:=(r.ax<>0);
+{$endif DOS}
+{$ifdef Windows}
+  h:=GetClipboardData(CF_OEMTEXT);
+  if h<>0 then
+    begin
+      pp:=PAnsiChar(GlobalLock(h));
+      l:=strlen(pp)+1;
+      getmem(p,l);
+      move(pp^,p^,l);
+      GlobalUnlock(h);
+    end;
+  GetTextWinClipBoardData:=h<>0;
+{$endif Windows}
+{$ifdef HASAMIGA}
+  Text := GetTextFromClip(0) + #0;
+  PP := @Text[1];
+  l := Length(Text);
+  GetMem(p,l);
+  Move(pp^,p^,l);
+  GetTextWinClipBoardData := True;
+{$endif HASAMIGA}
+{$IFDEF OS2}
+  GetTextWinClipboardData := false;
+  L := 0;
+  if not (OS2ClipboardSupported) then
+   Exit;
+  SessType := PIB^.tType;
+  PIB^.tType := 3;
+  PP := PAnsiChar (ClWinQueryClipbrdData (PMWHandle, CF_TEXT));
+  PIB^.tType := SessType;
+
+  if PP <> nil then
+   begin
+    L := StrLen (PAnsiChar (PP)) + 1;
+    GetMem (P, L);
+    if P <> nil then
+     begin
+      Move (PP^, P^, L);
+      GetTextWinClipBoardData := true;
+     end;
+   end;
+{$ENDIF OS2}
+  CloseWinClipBoard;
+{$ifdef DOS}
+  M.MoveDataFrom(l,P^);
+  FreeDosMem(M);
+  pp:=p+l;
+  pp^:=#0; { make null terminated }
+{$endif DOS}
+end;
+
+function SetTextWinClipBoardData(p : PAnsiChar;l : longint) : boolean;
+var
+{$ifdef DOS}
+  r : Registers;
+  M : MemPtr;
+  pp: PAnsiChar;
+  op: PAnsiChar;
+{$endif DOS}
+{$ifdef Windows}
+  h : HGlobal;
+  pp : PAnsiChar;
+  res : boolean;
+{$endif Windows}
+{$ifdef HASAMIGA}
+  pp: PAnsiChar;
+  Test: AnsiString;
+{$endif HASAMIGA}
+{$IFDEF OS2}
+  RC: cardinal;
+  PShared: pointer;
+  SessType: cardinal;
+{$ENDIF OS2}
+begin
+  SetTextWinClipBoardData:=False;
+  if (l=0) or (l>65520) then
+    exit;
+  if not OpenWinClipBoard then
+    exit;
+  EmptyWinClipBoard;
+{$ifdef DOS}
+  GetMem(pp,l+1);
+  Move(p^,pp^,l);
+  op:=pp+l;
+  op^:=#0; { make sure that string is null terminated }
+  GetDosMem(M,l+1);
+  M.MoveDataTo(PP^,l+1);
+  FreeMem(pp);
+  r.ax:=$1703;
+  r.dx:=7{ OEM Text rather then 1 : Text };
+  r.es:=M.DosSeg;
+  r.bx:=M.DosOfs;
+  r.si:=l shr 16;
+  r.cx:=l and $ffff;
+  RealIntr($2F,r);
+  SetTextWinClipBoardData:=(r.ax<>0);
+  (*
+  r.ax:=$1703;
+  r.dx:=1{ Empty  Text };
+  r.es:=M.DosSeg;
+  r.bx:=M.DosOfs;
+  r.si:=0;
+  r.cx:=0;
+  RealIntr($2F,r);
+  *)
+  FreeDosMem(M);
+{$endif DOS}
+{$ifdef Windows}
+  h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1);
+  pp:=PAnsiChar(GlobalLock(h));
+  move(p^,pp^,l+1);
+  GlobalUnlock(h);
+  res:=(SetClipboardData(CF_OEMTEXT,h)=h);
+  h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1);
+  pp:=PAnsiChar(GlobalLock(h));
+  OemToCharBuffA(p,pp,l+1);
+  SetClipboardData(CF_TEXT,h);
+  GlobalUnlock(h);
+  SetTextWinClipBoardData:=res;
+{$endif Windows}
+{$ifdef HASAMIGA}
+  PutTextToClip(0, AnsiString(p));
+{$endif HASAMIGA}
+{$IFDEF OS2}
+  SetTextWinClipboardData := false;
+  if not (OS2ClipboardSupported) then
+   Exit;
+  RC := DosAllocSharedMem (PShared, nil, Succ (L),
+                                      PAG_WRITE or PAG_COMMIT or OBJ_GIVEABLE);
+  if RC = 0 then
+   begin
+    Move (P^, PShared^, Succ (L));
+
+    SessType := PIB^.tType;
+    PIB^.tType := 3;
+    SetTextWinClipboardData := ClWinSetClipbrdData (PMWHandle,
+                                     cardinal (PShared), CF_TEXT, CFI_POINTER);
+    PIB^.tType := SessType;
+   end;
+{$ENDIF OS2}
+  CloseWinClipBoard;
+end;
+
+{$else WinClipSupported}
+{ Implementation for not supported OS clipboard. }
+
+function WinClipboardSupported : boolean;
+begin
+  WinClipboardSupported:=false;
+end;
+
+function OpenWinClipboard : boolean;
+begin
+  OpenWinClipboard:=false;
+end;
+
+function EmptyWinClipboard : boolean;
+begin
+  EmptyWinClipboard:=false;
+end;
+
+function CloseWinClipboard : boolean;
+begin
+  CloseWinClipboard:=false;
+end;
+
+function GetTextWinClipboardSize : longint;
+begin
+  GetTextWinClipboardSize:=0;
+end;
+
+function GetTextWinClipBoardData(var P : PAnsiChar;var L : longint) : boolean;
+begin
+  GetTextWinClipBoardData:=false;
+end;
+
+function SetTextWinClipBoardData(P : PAnsiChar; L : longint) : boolean;
+begin
+  SetTextWinClipBoardData:=false;
+end;
+{$endif}
+{$endif UNIX}
+
+{$ifdef os2}
+initialization
+ InitClipboard;
+
+finalization
+ DoneClipboard;
+{$endif os2}
 end.

+ 4 - 4
packages/fv/src/platform.inc

@@ -70,7 +70,7 @@
     OS_XXXX         The operating system used (XXXX may be one of:
                        DOS, OS2, Linux, Windows, Go32)
     PPC_XXXX        The compiler used: BP, FPK, Virtual, Speed
-    BIT_XX          The number of bits of the target platform: 16 or 32
+    BIT_XX          The number of bits of the target platform: 16, 32 or 64
     PROC_XXXX       The mode of the target processor (Real or Protected)
                     This shouldn't be used, except for i386 specific parts.
     ASM_XXXX        This is the assembler type: BP, ISO-ANSI, FPK
@@ -215,7 +215,8 @@ FOR FPC THESE ARE THE TRANSLATIONS
 {$IFDEF LINUX}
   {$UNDEF OS_DOS}
   {$DEFINE OS_LINUX}
-  {$DEFINE OS_UNIX}{$ENDIF}
+  {$DEFINE OS_UNIX}
+{$ENDIF}
 
 {$IFDEF FreeBSD}
   {$UNDEF OS_DOS}
@@ -387,8 +388,7 @@ FOR FPC THESE ARE THE TRANSLATIONS
   {$DEFINE PPC_DELPHI3}
   {$DEFINE PPC_DELPHI4}
   {$DEFINE PPC_DELPHI5}
-  {$UNDEF BP_VMTLink
-  }
+  {$UNDEF BP_VMTLink}
 {$ENDIF}
 
 {---------------------------------------------------------------------------}

+ 288 - 0
packages/fv/src/pmode.pas

@@ -0,0 +1,288 @@
+{
+   This file is part of the Free Sockets Interface
+   Copyright (c) 1999 by Berczi Gabor
+
+   Support routines for DPMI programs
+
+   See the file COPYING.FPC, included in this distribution,
+   for details about the copyright.
+
+   This library 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.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+   MA 02110-1301, USA.
+
+ **********************************************************************}
+
+{$IFNDEF FPC_DOTTEDUNITS}
+unit PMode;
+{$ENDIF FPC_DOTTEDUNITS}
+{$mode objfpc}
+{$H-}
+
+interface
+{$IFDEF FPC_DOTTEDUNITS}
+uses TP.DOS;
+{$ELSE}
+uses Dos;
+{$ENDIF FPC_DOTTEDUNITS}
+
+type
+    MemPtr = object
+      Ofs,Seg: word;
+      Size   : word;
+      Sel    : word;
+      function  DosPtr: pointer;
+      function  DataPtr: pointer;
+      function  DosSeg: word;
+      function  DosOfs: word;
+      procedure MoveDataTo(var Src; DSize: word);
+      procedure MoveDataFrom(DSize: word; var Dest);
+      procedure Clear;
+    private
+      function DataSeg: word;
+      function DataOfs: word;
+    end;
+
+    PtrRec = packed record
+      Ofs,Seg: word;
+    end;
+
+    registers32 = packed record     { DPMI call structure }
+      EDI     : LongInt;
+      ESI     : LongInt;
+      EBP     : LongInt;
+      Reserved: LongInt;
+      EBX     : LongInt;
+      EDX     : LongInt;
+      ECX     : LongInt;
+      EAX     : LongInt;
+      Flags   : Word;
+      ES      : Word;
+      DS      : Word;
+      FS      : Word;
+      GS      : Word;
+      IP      : Word;
+      CS      : Word;
+      SP      : Word;
+      SS      : Word;
+    end;
+
+    pregisters = ^registers;
+
+function  GetDosMem(var M: MemPtr; Size: word): boolean;
+procedure FreeDosMem(var M: MemPtr);
+procedure realintr(IntNo: byte; var r: registers);
+{procedure realintr32(IntNo: byte; var r: registers32);}
+procedure realcall(Proc: pointer; var r: registers);
+function  MoveDosToPM(DosPtr: pointer; PMPtr: pointer; Size: word): boolean;
+function  MovePMToDos(PMPtr: pointer; DosPtr: pointer; Size: word): boolean;
+procedure realGetIntVec(IntNo: byte; var P: pointer);
+function  allocrmcallback(PMAddr: pointer; RealRegs: pregisters): pointer;
+procedure freermcallback(RealCallAddr: pointer);
+
+function MakePtr(ASeg,AOfs: word): pointer;
+
+implementation
+
+{$ifdef GO32V2}
+
+{ --------------------- GO32 --------------------- }
+{$IFDEF FPC_DOTTEDUNITS}
+uses DOSApi.GO32;
+{$ELSE}
+uses go32;
+{$ENDIF FPC_DOTTEDUNITS}
+
+function  GetDosMem(var M: MemPtr; Size: word): boolean;
+var L: longint;
+begin
+  M.Size:=Size;
+  L:=global_dos_alloc(Size);
+  M.Seg:=(L shr 16); M.Ofs:=0;
+  M.Sel:=(L and $ffff);
+  GetDosMem:=M.Seg<>0;
+end;
+
+procedure FreeDosMem(var M: MemPtr);
+begin
+  if M.Size=0 then Exit;
+  if M.Sel<>0 then
+  if global_dos_free(M.Sel)=false then
+    writeln('!!!Failed to deallocate Dos block!!!');
+  FillChar(M,SizeOf(M),0);
+end;
+
+procedure realintr(IntNo: byte; var r: registers);
+var rr: trealregs;
+begin
+  rr.realeax:=r.ax;
+  rr.realebx:=r.bx;
+  rr.realecx:=r.cx;
+  rr.realedx:=r.dx;
+  rr.realesi:=r.si;
+  rr.realedi:=r.di;
+  rr.reales:=r.es;
+  rr.realds:=r.ds;
+  go32.realintr(IntNo,rr);
+  r.ax:=rr.realeax and $ffff;
+  r.bx:=rr.realebx and $ffff;
+  r.cx:=rr.realecx and $ffff;
+  r.dx:=rr.realedx and $ffff;
+  r.si:=rr.realesi and $ffff;
+  r.di:=rr.realedi and $ffff;
+  r.es:=rr.reales and $ffff;
+  r.ds:=rr.realds and $ffff;
+end;
+
+function dorealcall(var regs : trealregs) : boolean;
+begin
+  regs.realsp:=0;
+  regs.realss:=0;
+  asm
+    movw  $0x0,%bx
+    xorl  %ecx,%ecx
+    movl  regs,%edi
+    { es is always equal ds }
+    movl  $0x301,%eax
+    int   $0x31
+    setnc %al
+    movb  %al,__RESULT
+  end;
+end;
+
+
+procedure realcall(Proc: pointer; var r: registers);
+var rr: trealregs;
+begin
+  rr.realeax:=r.ax;
+  rr.realebx:=r.bx;
+  rr.realecx:=r.cx;
+  rr.realedx:=r.dx;
+  rr.realesi:=r.si;
+  rr.realedi:=r.di;
+  rr.reales:=r.es;
+  rr.realds:=r.ds;
+  rr.flags:=r.flags;
+  rr.CS:=PtrRec(Proc).Seg;
+  rr.IP:=PtrRec(Proc).Ofs;
+
+  rr.realss:=0; rr.realsp:=0;
+
+  dorealcall(rr);
+
+  r.ax:=rr.realeax and $ffff;
+  r.bx:=rr.realebx and $ffff;
+  r.cx:=rr.realecx and $ffff;
+  r.dx:=rr.realedx and $ffff;
+  r.si:=rr.realesi and $ffff;
+  r.di:=rr.realedi and $ffff;
+  r.es:=rr.reales and $ffff;
+  r.ds:=rr.realds and $ffff;
+  r.flags:=rr.Flags and $ffff;
+end;
+
+function MoveDosToPM(DosPtr: pointer; PMPtr: pointer; Size: word): boolean;
+begin
+  dosmemget(PtrRec(DosPtr).Seg,PtrRec(DosPtr).Ofs,PMPtr^,Size);
+  MoveDosToPM:=true;
+end;
+
+function MovePMToDos(PMPtr, DosPtr: pointer; Size: word): boolean;
+begin
+  dosmemput(PtrRec(DosPtr).Seg,PtrRec(DosPtr).Ofs,PMPtr^,Size);
+  MovePMToDos:=true;
+end;
+
+procedure realGetIntVec(IntNo: byte; var P: pointer);
+var si: tseginfo;
+begin
+  get_rm_interrupt(IntNo,si);
+  PtrRec(P).Seg:=si.segment; PtrRec(P).Ofs:=longint(si.offset);
+end;
+
+procedure MemPtr.MoveDataTo(var Src; DSize: word);
+begin
+  dpmi_dosmemput(DosSeg,DosOfs,Src,DSize);
+end;
+
+procedure MemPtr.MoveDataFrom(DSize: word; var Dest);
+begin
+  dpmi_dosmemget(DosSeg,DosOfs,Dest,DSize);
+end;
+
+procedure MemPtr.Clear;
+begin
+  dpmi_dosmemfillchar(DosSeg,DosOfs,Size,#0);
+end;
+
+
+function  allocrmcallback(PMAddr: pointer; RealRegs: pregisters): pointer;
+var s: tseginfo;
+    P: pointer;
+begin
+  if get_rm_callback(PMAddr,RealRegs^,s) then
+    P:=MakePtr(s.segment,longint(s.offset))
+  else
+    P:=nil;
+  allocrmcallback:=P;
+end;
+
+procedure freermcallback(RealCallAddr: pointer);
+var s: tseginfo;
+begin
+  s.segment:=PtrRec(RealCallAddr).seg;
+  s.offset:=pointer(longint(PtrRec(RealCallAddr).ofs));
+  free_rm_callback(s);
+end;
+
+{$endif GO32V2}
+
+{ ---------------------- COMMON ---------------------- }
+
+function MemPtr.DosPtr: pointer;
+begin
+  DosPtr:=MakePtr(Seg,Ofs);
+end;
+
+function MemPtr.DataPtr: pointer;
+begin
+  DataPtr:=MakePtr(DataSeg,DataOfs);
+end;
+
+function MemPtr.DataSeg: word;
+begin
+  DataSeg:=Sel;
+end;
+
+function MemPtr.DataOfs: word;
+begin
+  DataOfs:=0;
+end;
+
+function MemPtr.DosSeg: word;
+begin
+  DosSeg:=Seg;
+end;
+
+function MemPtr.DosOfs: word;
+begin
+  DosOfs:=Ofs;
+end;
+
+function MakePtr(ASeg, AOfs: word): pointer;
+var P: pointer;
+begin
+  with PtrRec(P) do
+  begin
+    Seg:=ASeg; Ofs:=AOfs;
+  end;
+  MakePtr:=P;
+end;
+
+END.

+ 4 - 1
packages/fv/src/sysmsg.pas

@@ -33,12 +33,15 @@ type
     SysSetFocus,
     SysReleaseFocus,
     SysClose,
-    SysResize );
+    SysResize,
+    SysPaste  { OSC 52 or Bracketed paste }
+    );
 
   TSystemEvent = Record
     case typ : TSystemMessage of
       SysClose : ( CloseTyp : Longint);
       SysResize : (X,Y : Longint);
+      SysPaste : (P :PAnsiChar; Len : Longint);
     end;
 
   PSystemEvent = ^TSystemEvent;

+ 4 - 6
packages/ide/fpide.pas

@@ -178,10 +178,10 @@ uses
   fpcatch,
 {$endif HasSignal}
 {$ifdef WinClipSupported}
-  WinClip,
+  FvClip,
 {$endif WinClipSupported}
 {$ifdef Unix}
-  fpKeys,FVClip,
+  fpKeys,
 {$endif Unix}
   FpDpAnsi,WConsts,
   Video,Mouse,Keyboard,
@@ -1508,7 +1508,6 @@ begin
     UserScreen^.SaveIDEScreen;
   DoneSysError;
   DoneEvents;
-  {$ifdef unix}DoneClip;{$endif}
   { DoneKeyboard should be called last to
     restore the keyboard correctly PM }
 {$ifndef go32v2}
@@ -1516,7 +1515,7 @@ begin
 {$endif ndef go32v2}
   DoneKeyboard;
   If UseMouse then
-    DoneMouse
+    { DoneMouse  called by DoneEvents }
   else
     ButtonCount:=0;
 {  DoneDosMem;}
@@ -1534,12 +1533,11 @@ begin
 {  InitDosMem;}
   InitKeyboard;
   If UseMouse then
-    InitMouse
+    { InitMouse  called by InitEvents }
   else
     ButtonCount:=0;
   oldH:=ScreenHeight;
   oldW:=ScreenWidth;
-  {$ifdef unix}InitClip(@Self);{$endif}
 {$ifndef go32v2}
   initvideo;
 {$endif ndef go32v2}

+ 2 - 2
packages/ide/weditor.pas

@@ -849,7 +849,7 @@ implementation
 uses
   Strings,Video,MsgBox,App,Validate,
 {$ifdef WinClipSupported}
-  WinClip,
+  FvClip,
 {$endif WinClipSupported}
 {$ifdef TEST_REGEXP}
   {$ifdef USE_OLD_REGEXP}
@@ -6509,7 +6509,7 @@ begin
         OK:=false
       else
         OK:=GetTextWinClipBoardData(p,l);
-      if OK then
+      if OK and assigned(p) then
         begin
           PasteText(p,l);
           { we must free the allocated memory }

+ 15 - 3
packages/ide/winclip.pas

@@ -43,7 +43,7 @@ implementation
 
 {$ifdef linux}
   uses
-    baseUnix,base64,keyboard,Objects,fvclip;
+    baseUnix,keyboard,fvclip;
 {$endif linux}
 
 {$ifdef Windows}
@@ -415,6 +415,7 @@ var
 {$ifdef DOS}
   r : Registers;
   M : MemPtr;
+  pp: PAnsiChar;
 {$endif DOS}
 {$ifdef linux}
   rez : boolean; {one variable needed to satisfy compiler}
@@ -444,7 +445,7 @@ begin
       CloseWinClipBoard;
       exit;
     end;
-  GetMem(p,l);
+  GetMem(p,l+1);
   GetDosMem(M,l);
   r.ax:=$1705;
   r.dx:=7{ OEM Text rather then 1 : Text };
@@ -502,6 +503,8 @@ begin
 {$ifdef DOS}
   M.MoveDataFrom(l,P^);
   FreeDosMem(M);
+  pp:=p+l;
+  pp^:=#0; { make null terminated }
 {$endif DOS}
 end;
 
@@ -510,6 +513,8 @@ var
 {$ifdef DOS}
   r : Registers;
   M : MemPtr;
+  pp: PAnsiChar;
+  op: PAnsiChar;
 {$endif DOS}
 {$ifdef linux}
   st : AnsiString;
@@ -536,8 +541,13 @@ begin
     exit;
   EmptyWinClipBoard;
 {$ifdef DOS}
+  GetMem(pp,l+1);
+  Move(p^,pp^,l);
+  op:=pp+l;
+  op^:=#0; { make sure that string is null terminated }
   GetDosMem(M,l+1);
-  M.MoveDataTo(P^,l+1);
+  M.MoveDataTo(PP^,l+1);
+  FreeMem(pp);
   r.ax:=$1703;
   r.dx:=7{ OEM Text rather then 1 : Text };
   r.es:=M.DosSeg;
@@ -546,6 +556,7 @@ begin
   r.cx:=l and $ffff;
   RealIntr($2F,r);
   SetTextWinClipBoardData:=(r.ax<>0);
+  (*
   r.ax:=$1703;
   r.dx:=1{ Empty  Text };
   r.es:=M.DosSeg;
@@ -553,6 +564,7 @@ begin
   r.si:=0;
   r.cx:=0;
   RealIntr($2F,r);
+  *)
   FreeDosMem(M);
 {$endif DOS}
 {$ifdef linux}

+ 1 - 1
packages/ide/wviews.pas

@@ -303,7 +303,7 @@ implementation
 uses Mouse,
 {     Resource,}
 {$ifdef WinClipSupported}
-     WinClip,
+     FvClip,
 {$endif WinClipSupported}
      FpConst,
      FVConsts,