ソースを参照

Merge branch source:main into main

Curtis Hamilton 2 週間 前
コミット
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_[
 option_logo=11023_[
 Free Pascal Compiler version $FPCFULLVERSION [$FPCDATE] for $FPCCPU
 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.Author := 'header:Aleš Katona, library: Kevin Atkinson';
     P.License := 'header: LGPL with modification, library: LGPL 2.0 or 2.1';
     P.License := 'header: LGPL with modification, library: LGPL 2.0 or 2.1';
     P.HomepageURL := 'www.freepascal.org';
     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.Email := '';
     P.Description := 'The New Aspell, spelling library';
     P.Description := 'The New Aspell, spelling library';
     P.NeedLibC:= true;
     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;
 program DemoEditor;
 {$mode fpc}
 {$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
 uses
   {$ifdef UNIX}cwstring,{$endif}Objects,fvconsts,
   {$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
 const
   cmShowClip   = 102;
   cmShowClip   = 102;
   cmCopyWin    = 240;
   cmCopyWin    = 240;
   cmPasteWin   = 241;
   cmPasteWin   = 241;
+  cmLocalClip  = 242;
+  cmOSClip     = 243;
 
 
 type
 type
   PEditorApp = ^TEditorApp;
   PEditorApp = ^TEditorApp;
@@ -46,24 +72,21 @@ procedure TMyEditWindow.HandleEvent(var Event: TEvent);
 procedure ClipCopyWin;
 procedure ClipCopyWin;
 var p : pointer;
 var p : pointer;
 begin
 begin
-{$ifdef unix}
   if Editor^.SelStart<>Editor^.SelEnd then { Text selected? }
   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;
 end;
 
 
 procedure ClipPasteWin;
 procedure ClipPasteWin;
+var P : PAnsiChar; Len: Longint;
 begin
 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;
 end;
 
 
 begin
 begin
@@ -73,6 +96,13 @@ begin
       case Event.Command of
       case Event.Command of
         cmCopyWin   : ClipCopyWin;
         cmCopyWin   : ClipCopyWin;
         cmPasteWin  : ClipPasteWin;
         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
       else
         Exit;
         Exit;
       end;
       end;
@@ -89,14 +119,16 @@ var
 begin
 begin
   inherited Init;
   inherited Init;
   DisableCommands([cmSave, cmSaveAs, cmCut, cmCopy, cmPaste,
   DisableCommands([cmSave, cmSaveAs, cmCut, cmCopy, cmPaste,
-    {cmCopyWin, cmPasteWin,}
     cmClear, cmUndo, cmFind, cmReplace, cmSearchAgain]);
     cmClear, cmUndo, cmFind, cmReplace, cmSearchAgain]);
+  if not WinClipboardSupported then
+    DisableCommands([cmCopyWin, cmPasteWin, cmOSClip]);
   EditorDialog := @StdEditorDialog;
   EditorDialog := @StdEditorDialog;
   ClipWindow := OpenEditor('', False);
   ClipWindow := OpenEditor('', False);
   if ClipWindow <> nil then
   if ClipWindow <> nil then
   begin
   begin
+    { Add Editor to Clipboard and by that clipboard functionality is enabled }
     Clipboard := ClipWindow^.Editor;
     Clipboard := ClipWindow^.Editor;
-    Clipboard^.CanUndo := False;
+    Clipboard^.CanUndo := False;  { No Undo for clipboard }
   end;
   end;
 end;
 end;
 
 
@@ -137,6 +169,16 @@ begin
         cmNew: FileNew;
         cmNew: FileNew;
         cmChangeDir : ChangeDir;
         cmChangeDir : ChangeDir;
         cmShowClip  : ShowClip;
         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
       else
         Exit;
         Exit;
       end;
       end;
@@ -161,9 +203,12 @@ begin
       NewLine(
       NewLine(
       NewItem('~S~hwo clipboard', '', kbNoKey, cmShowClip, hcNoContext,
       NewItem('~S~hwo clipboard', '', kbNoKey, cmShowClip, hcNoContext,
       NewLine(
       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('Cop~y~ to Windows', '', kbNoKey, cmCopyWin, hcNoContext,
       NewItem('Paste from ~W~indows', '', kbNoKey, cmPasteWin, hcNoContext,
       NewItem('Paste from ~W~indows', '', kbNoKey, cmPasteWin, hcNoContext,
-      nil))))))),
+      nil)))))))))),
     NewSubMenu('~S~earch', hcNoContext, NewMenu(
     NewSubMenu('~S~earch', hcNoContext, NewMenu(
       NewItem('~F~ind...', '', kbNoKey, cmFind, hcNoContext,
       NewItem('~F~ind...', '', kbNoKey, cmFind, hcNoContext,
       NewItem('~R~eplace...', '', kbNoKey, cmReplace, hcNoContext,
       NewItem('~R~eplace...', '', kbNoKey, cmReplace, hcNoContext,

+ 16 - 10
packages/fv/fpmake.pp

@@ -50,7 +50,6 @@ begin
           AddUnit('dialogs');
           AddUnit('dialogs');
           AddUnit('msgbox');
           AddUnit('msgbox');
           AddUnit('fvconsts');
           AddUnit('fvconsts');
-          AddUnit('fvclip',AllUnixOSes);
         end;
         end;
     T.ResourceStrings := True;
     T.ResourceStrings := True;
     T:=P.Targets.AddUnit('uapp.pas',P.OSes-[msdos,win16]);
     T:=P.Targets.AddUnit('uapp.pas',P.OSes-[msdos,win16]);
@@ -66,7 +65,6 @@ begin
           AddUnit('udialogs');
           AddUnit('udialogs');
           AddUnit('umsgbox');
           AddUnit('umsgbox');
           AddUnit('fvconsts');
           AddUnit('fvconsts');
-          AddUnit('ufvclip',AllUnixOSes);
         end;
         end;
     T.ResourceStrings := True;
     T.ResourceStrings := True;
     T:=P.Targets.AddUnit('asciitab.pas');
     T:=P.Targets.AddUnit('asciitab.pas');
@@ -176,6 +174,7 @@ begin
           AddUnit('validate');
           AddUnit('validate');
           AddUnit('app');
           AddUnit('app');
           AddUnit('histlist');
           AddUnit('histlist');
+          AddUnit('editors');
         end;
         end;
     T.ResourceStrings := True;
     T.ResourceStrings := True;
     T:=P.Targets.AddUnit('udialogs.pas',P.OSes-[msdos,win16]);
     T:=P.Targets.AddUnit('udialogs.pas',P.OSes-[msdos,win16]);
@@ -190,6 +189,7 @@ begin
           AddUnit('uvalidate');
           AddUnit('uvalidate');
           AddUnit('uapp');
           AddUnit('uapp');
           AddUnit('uhistlist');
           AddUnit('uhistlist');
+          AddUnit('ueditors');
         end;
         end;
     T.ResourceStrings := True;
     T.ResourceStrings := True;
     T:=P.Targets.AddUnit('drivers.pas');
     T:=P.Targets.AddUnit('drivers.pas');
@@ -200,6 +200,7 @@ begin
           AddUnit('sysmsg');
           AddUnit('sysmsg');
           AddUnit('fvcommon');
           AddUnit('fvcommon');
           AddUnit('fvconsts');
           AddUnit('fvconsts');
+          AddUnit('fvclip');
         end;
         end;
     T:=P.Targets.AddUnit('udrivers.pas',P.OSes-[msdos,win16]);
     T:=P.Targets.AddUnit('udrivers.pas',P.OSes-[msdos,win16]);
       with T.Dependencies do
       with T.Dependencies do
@@ -209,6 +210,7 @@ begin
           AddUnit('sysmsg');
           AddUnit('sysmsg');
           AddUnit('ufvcommon');
           AddUnit('ufvcommon');
           AddUnit('fvconsts');
           AddUnit('fvconsts');
+          AddUnit('ufvclip');
         end;
         end;
     T:=P.Targets.AddUnit('editors.pas');
     T:=P.Targets.AddUnit('editors.pas');
       with T.Dependencies do
       with T.Dependencies do
@@ -223,6 +225,7 @@ begin
           AddUnit('app');
           AddUnit('app');
           AddUnit('stddlg');
           AddUnit('stddlg');
           AddUnit('msgbox');
           AddUnit('msgbox');
+          AddUnit('fvclip');
         end;
         end;
     T.ResourceStrings := True;
     T.ResourceStrings := True;
     T:=P.Targets.AddUnit('ueditors.pas',P.OSes-[msdos,win16]);
     T:=P.Targets.AddUnit('ueditors.pas',P.OSes-[msdos,win16]);
@@ -238,27 +241,24 @@ begin
           AddUnit('uapp');
           AddUnit('uapp');
           AddUnit('ustddlg');
           AddUnit('ustddlg');
           AddUnit('umsgbox');
           AddUnit('umsgbox');
+          AddUnit('ufvclip');
         end;
         end;
     T.ResourceStrings := True;
     T.ResourceStrings := True;
-    T:=P.Targets.AddUnit('fvclip.pas',AllUnixOSes);
+    T:=P.Targets.AddUnit('fvclip.pas');
       with T.Dependencies do
       with T.Dependencies do
         begin
         begin
           AddInclude('fvclip.inc');
           AddInclude('fvclip.inc');
           AddInclude('platform.inc');
           AddInclude('platform.inc');
-          AddUnit('drivers');
+          AddUnit('sysmsg');
           AddUnit('fvconsts');
           AddUnit('fvconsts');
-          AddUnit('app');
-          AddUnit('fvcommon');
         end;
         end;
-    T:=P.Targets.AddUnit('ufvclip.pas',AllUnixOSes);
+    T:=P.Targets.AddUnit('ufvclip.pas',P.OSes-[msdos,win16]);
       with T.Dependencies do
       with T.Dependencies do
         begin
         begin
           AddInclude('fvclip.inc');
           AddInclude('fvclip.inc');
           AddInclude('platform.inc');
           AddInclude('platform.inc');
-          AddUnit('udrivers');
+          AddUnit('sysmsg');
           AddUnit('fvconsts');
           AddUnit('fvconsts');
-          AddUnit('uapp');
-          AddUnit('ufvcommon');
         end;
         end;
     T:=P.Targets.AddUnit('fvcommon.pas');
     T:=P.Targets.AddUnit('fvcommon.pas');
       with T.Dependencies do
       with T.Dependencies do
@@ -399,6 +399,7 @@ begin
           AddUnit('udrivers');
           AddUnit('udrivers');
           AddUnit('uviews');
           AddUnit('uviews');
         end;
         end;
+    T:=P.Targets.AddUnit('pmode.pas',[go32v2]);
     T:=P.Targets.AddUnit('statuses.pas');
     T:=P.Targets.AddUnit('statuses.pas');
       with T.Dependencies do
       with T.Dependencies do
         begin
         begin
@@ -553,6 +554,11 @@ begin
         end;
         end;
     P.ExamplePath.Add('examples');
     P.ExamplePath.Add('examples');
     P.ExamplePath.Add('src');
     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('examples/testapp.pas');
     P.Targets.AddExampleProgram('src/platform.inc');
     P.Targets.AddExampleProgram('src/platform.inc');
     // 'examples/Makefile
     // '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/ugadgets.pas=namespaced/FreeVision.Ugadgets.pas
 src/fvclip.pas=namespaced/FreeVision.Fvclip.pas
 src/fvclip.pas=namespaced/FreeVision.Fvclip.pas
 src/ufvclip.pas=namespaced/FreeVision.Ufvclip.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}
 {$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}
 {$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}
 {$ENDIF FPC_DOTTEDUNITS}
 
 
 resourcestring  sVideoFailed='Video initialization failed.';
 resourcestring  sVideoFailed='Video initialization failed.';
@@ -1136,7 +1124,6 @@ BEGIN
 {$endif FV_UNICODE}
 {$endif FV_UNICODE}
    InitHistory;                                               { Start history up }
    InitHistory;                                               { Start history up }
    Inherited Init;                                            { Call ancestor }
    Inherited Init;                                            { Call ancestor }
-   {$ifdef unix}InitClip(@Self);{$endif}
    InitMsgBox;
    InitMsgBox;
    { init mouse and cursor }
    { init mouse and cursor }
    {$IFDEF FPC_DOTTEDUNITS}System.Console.{$ENDIF}Video.SetCursorType(crHidden);
    {$IFDEF FPC_DOTTEDUNITS}System.Console.{$ENDIF}Video.SetCursorType(crHidden);
@@ -1160,7 +1147,6 @@ BEGIN
    {$IFDEF FPC_DOTTEDUNITS}FreeVision.{$ENDIF}drivers.donevideo;
    {$IFDEF FPC_DOTTEDUNITS}FreeVision.{$ENDIF}drivers.donevideo;
 {$endif FV_UNICODE}
 {$endif FV_UNICODE}
 {   DoneMemory;}                                       { Close memory }
 {   DoneMemory;}                                       { Close memory }
-   {$ifdef unix}DoneClip;{$endif}
    donekeyboard;
    donekeyboard;
 {   DoneResource;}
 {   DoneResource;}
 END;
 END;
@@ -1196,7 +1182,6 @@ var s:string;
 {$endif}
 {$endif}
 
 
 BEGIN                                                 { Compatibility only }
 BEGIN                                                 { Compatibility only }
-  {$ifdef unix}DoneClip;{$endif}
   DoneSysError;
   DoneSysError;
   DoneEvents;
   DoneEvents;
 {$ifdef FV_UNICODE}
 {$ifdef FV_UNICODE}
@@ -1232,7 +1217,6 @@ BEGIN                                                 { Compatibility only }
   InitScreen;
   InitScreen;
   InitEvents;
   InitEvents;
   InitSysError;
   InitSysError;
-  {$ifdef unix}InitClip(@Self);{$endif}
   if (PrevHeight<>ScreenHeight) or (PrevWidth<>ScreenWidth) then
   if (PrevHeight<>ScreenHeight) or (PrevWidth<>ScreenWidth) then
     { acknowledge new screen dimensions }
     { acknowledge new screen dimensions }
     { prevents to draw out of boundaries of new video buffer }
     { 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 FPC_DOTTEDUNITS}
 {$ifdef FV_UNICODE}
 {$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}
 {$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}
 {$endif FV_UNICODE}
 {$ELSE FPC_DOTTEDUNITS}
 {$ELSE FPC_DOTTEDUNITS}
 {$ifdef FV_UNICODE}
 {$ifdef FV_UNICODE}
-USES UApp,UHistList,UFVClip;                            { Standard GFV unit }
+USES UApp,UHistList,UEditors;                         { Standard FV unit }
 {$else FV_UNICODE}
 {$else FV_UNICODE}
-USES App,HistList,FVClip;                               { Standard GFV unit }
+USES App,HistList,Editors;                            { Standard FV unit }
 {$endif FV_UNICODE}
 {$endif FV_UNICODE}
 {$ENDIF FPC_DOTTEDUNITS}
 {$ENDIF FPC_DOTTEDUNITS}
 
 
@@ -1892,14 +1892,32 @@ Len, I: Integer;
 BEGIN
 BEGIN
    Inherited HandleEvent(Event);                      { Call ancestor }
    Inherited HandleEvent(Event);                      { Call ancestor }
    If (State AND sfSelected <> 0) Then Begin          { View is selected }
    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
      Case Event.What Of
        evNothing: Exit;                               { Speed up exit }
        evNothing: Exit;                               { Speed up exit }
        evCommand: Begin                               { Command event }
        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 }
        evMouseDown: Begin                             { Mouse down event }
          Delta := MouseDelta;                         { Calc scroll value }
          Delta := MouseDelta;                         { Calc scroll value }
          If CanScroll(Delta) Then Begin               { Can scroll }
          If CanScroll(Delta) Then Begin               { Can scroll }
@@ -1943,24 +1961,22 @@ BEGIN
              begin
              begin
                if (Data <> Sw_PString_Empty) and (SelStart < SelEnd) then
                if (Data <> Sw_PString_Empty) and (SelStart < SelEnd) then
                begin
                begin
-                 // Copy selected text to OSC 52 clipboard
+                 // Copy selected text to clipboard
                  SelectedTextAnsi := AnsiString(Copy(Data Sw_PString_DeRef, SelStart + 1, SelEnd - SelStart));
                  SelectedTextAnsi := AnsiString(Copy(Data Sw_PString_DeRef, SelStart + 1, SelEnd - SelStart));
                  if Length(SelectedTextAnsi) > 0 then
                  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;
              end;
              end;
            kbShiftDel: // CUT command
            kbShiftDel: // CUT command
              begin
              begin
                if (Data <> Sw_PString_Empty) and (SelStart < SelEnd) then
                if (Data <> Sw_PString_Empty) and (SelStart < SelEnd) then
                begin
                begin
-                 // Copy selected text to OSC 52 clipboard
+                 // Copy selected text to clipboard
                  SelectedTextAnsi := AnsiString(Copy(Data Sw_PString_DeRef, SelStart + 1, SelEnd - SelStart));
                  SelectedTextAnsi := AnsiString(Copy(Data Sw_PString_DeRef, SelStart + 1, SelEnd - SelStart));
                  if Length(SelectedTextAnsi) > 0 then
                  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
                  DeleteSelect; // Then delete the selection
                  CheckValid(True); // Validate after deletion
                  CheckValid(True); // Validate after deletion
                end;
                end;

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

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

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

@@ -225,6 +225,7 @@ type
     function   InsertChar (AChar : Sw_Char) : Boolean;
     function   InsertChar (AChar : Sw_Char) : Boolean;
     procedure  ScrollTo (X, Y : Sw_Integer);
     procedure  ScrollTo (X, Y : Sw_Integer);
     function   Search (const FindStr : String; Opts : Word) : Boolean;
     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;
     function   SetBufSize (NewSize : Sw_Word) : Boolean; virtual;
     procedure  SetCmdState (Command : Word; Enable : Boolean);
     procedure  SetCmdState (Command : Word; Enable : Boolean);
     procedure  SetSelect (NewStart, NewEnd : Sw_Word; CurStart : Boolean);
     procedure  SetSelect (NewStart, NewEnd : Sw_Word; CurStart : Boolean);
@@ -290,6 +291,7 @@ type
     procedure  Scroll_Up;
     procedure  Scroll_Up;
     procedure  Select_Word;
     procedure  Select_Word;
     procedure  SetBufLen (Length : Sw_Word);
     procedure  SetBufLen (Length : Sw_Word);
+    function   SetTextWinClip : Boolean; { Copy to OS clipboard. }
     procedure  Set_Place_Marker (Element : Byte);
     procedure  Set_Place_Marker (Element : Byte);
     procedure  Set_Right_Margin;
     procedure  Set_Right_Margin;
     procedure  Set_Tabs;
     procedure  Set_Tabs;
@@ -365,6 +367,15 @@ function RightMarginDialog : PDialog;
 function TabStopDialog : PDialog;
 function TabStopDialog : PDialog;
 function StdEditorDialog(Dialog: SmallInt; Info: Pointer): Word;
 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
 const
   WordChars    : set of AnsiChar = ['!'..#255];
   WordChars    : set of AnsiChar = ['!'..#255];
 
 
@@ -488,7 +499,8 @@ implementation
 uses
 uses
   TP.DOS,
   TP.DOS,
 {$ifdef FV_UNICODE}
 {$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}
 {$else FV_UNICODE}
   FreeVision.App, FreeVision.Stddlg, FreeVision.Msgbox, FreeVision.Fvclip;
   FreeVision.App, FreeVision.Stddlg, FreeVision.Msgbox, FreeVision.Fvclip;
 {$ENDIF}
 {$ENDIF}
@@ -695,6 +707,19 @@ CONST
   { CENTER - Stop. } { Added @FormatKeys for new ^O? keys. }
   { 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
                                  Dialogs
 ****************************************************************************}
 ****************************************************************************}
@@ -1726,30 +1751,7 @@ end; {Check_For_Word_Wrap}
 
 
 
 
 function TEditor.ClipCopy : Boolean;
 function TEditor.ClipCopy : Boolean;
-var
-  SelectedTextAnsi: AnsiString;
-  Len: Sw_Word;
 begin
 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;
   ClipCopy := False;
   if Assigned(Clipboard) and (Clipboard <> @Self) then
   if Assigned(Clipboard) and (Clipboard <> @Self) then
    begin
    begin
@@ -2774,6 +2776,10 @@ begin
              (Event.Command <> cmBackSpace) and
              (Event.Command <> cmBackSpace) and
              (Event.Command <> cmTabKey)    and
              (Event.Command <> cmTabKey)    and
              (Event.Command <> cmSelectAll) 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
               Modified then
             Remove_EOL_Spaces (SelectMode);
             Remove_EOL_Spaces (SelectMode);
           Unlock;
           Unlock;
@@ -2950,14 +2956,111 @@ begin
 end; { TEditor.InsertChar }
 end; { TEditor.InsertChar }
 
 
 
 
-function TEditor.InsertFrom (Editor : PEditor) : Boolean;
+function TEditor.SetTextWinClip : Boolean;
+var
+  SelectedTextAnsi: AnsiString;
+  Len: Sw_Word;
+var InsertToClipboard : boolean;
 begin
 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,
   InsertFrom := InsertBuffer (Editor^.Buffer,
     Editor^.BufPtr (Editor^.SelStart),
     Editor^.BufPtr (Editor^.SelStart),
-    Editor^.SelEnd - Editor^.SelStart, CanUndo, IsClipboard);
+    Editor^.SelEnd - Editor^.SelStart, CanUndo, InsertToClipboard);
 end; { TEditor.InsertFrom }
 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);
 procedure TEditor.Insert_Line (Select_Mode : Byte);
 { This procedure inserts a newline at the current cursor position }
 { This procedure inserts a newline at the current cursor position }
 { if a ^N is pressed.  Unlike cmNewLine, the cursor will return   }
 { if a ^N is pressed.  Unlike cmNewLine, the cursor will return   }
@@ -2973,7 +3076,20 @@ end; { TEditor.Insert_Line }
 function TEditor.InsertText (Text       : Pointer;
 function TEditor.InsertText (Text       : Pointer;
                              Length     : Sw_Word;
                              Length     : Sw_Word;
                              SelectText : Boolean) : Boolean;
                              SelectText : Boolean) : Boolean;
+var InsertToClipboard : boolean;
 begin
 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
   if assigned(Text) and not Search_Replace then
     Update_Place_Markers (Length, 0, Self.SelStart, Self.SelEnd);
     Update_Place_Markers (Length, 0, Self.SelStart, Self.SelEnd);
   InsertText := InsertBuffer (PEditBuffer (Text),
   InsertText := InsertBuffer (PEditBuffer (Text),
@@ -4662,4 +4778,6 @@ begin
 end; { RegisterEditors }
 end; { RegisterEditors }
 
 
 
 
+begin
+  DefaultGlobalClipboard:=WinClipboardSupported;
 end. { Unit NewEdit }
 end. { Unit NewEdit }

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

@@ -1,9 +1,13 @@
 {
 {
    This unit is part of the Free Vision package
    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,
    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.
    for details about the copyright.
@@ -32,58 +36,96 @@ unit fvclip;
 
 
 interface
 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
 implementation
 
 
 {$IFDEF FPC_DOTTEDUNITS}
 {$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}
 {$ifdef unix}
-  UnixApi.Base, System.Console.Keyboard,
+  uses
+    UnixApi.Base,UnixApi.TermIO,System.Console.Keyboard,FreeVision.Sysmsg;
 {$endif}
 {$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}
 {$ifdef unix}
-  baseUnix,keyboard,
+  uses
+    baseUnix,termio,keyboard,sysmsg;
 {$endif}
 {$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 }
 {Could not use unit base64 because of Sysutils and reasons }
 {Speed or reusability here is not a concern                }
 {Speed or reusability here is not a concern                }
@@ -92,7 +134,7 @@ const
     'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
     'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
 Alphabet = ['a'..'z','A'..'Z','0'..'9','+','/','=']; // all 65 chars that are in the base64 encoding alphabet
 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);
 procedure encodeBase64(p:PAnsiChar;len:longint; d:PAnsiChar; var outlen: longint);
 var
 var
   i, rem : longint;
   i, rem : longint;
@@ -136,7 +178,7 @@ begin
   end;
   end;
 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);
 procedure decodeBase64(p:PAnsiChar; len: longint; d:PAnsiChar; var outlen: longint);
 var
 var
   i,rlen : longint;
   i,rlen : longint;
@@ -185,30 +227,37 @@ begin
      outlen:=rlen; {length for output}
      outlen:=rlen; {length for output}
 end;
 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
 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;
 end;
 
 
-procedure LinuxClipBoardData;
+
+procedure OSC_52_ClipboardData;
 var zt,rt  : AnsiString;
 var zt,rt  : AnsiString;
   escSeq : ShortString;
   escSeq : ShortString;
   inEsc,inRead : boolean;
   inEsc,inRead : boolean;
-  k : sw_integer;
+  k : Longint;
   ch : AnsiChar;
   ch : AnsiChar;
   timewait,finalparsec : TimeSpec;
   timewait,finalparsec : TimeSpec;
   ree:longint;
   ree:longint;
-  countemptines : sw_integer;
+  countemptines : Longint;
   rlen : longint;
   rlen : longint;
 begin
 begin
   countemptines:=0;
   countemptines:=0;
@@ -267,14 +316,15 @@ begin
   PutInEventQue(rt,rlen);
   PutInEventQue(rt,rlen);
 end;
 end;
 
 
+
 procedure BracketedPaste;
 procedure BracketedPaste;
 var zt  : AnsiString;
 var zt  : AnsiString;
-  k : sw_integer;
+  k : Longint;
   ch : AnsiChar;
   ch : AnsiChar;
   timewait,finalparsec : TimeSpec;
   timewait,finalparsec : TimeSpec;
   ree:longint;
   ree:longint;
-  countemptines : sw_integer;
-  len : sw_integer;
+  countemptines : Longint;
+  len : Longint;
 begin
 begin
   countemptines:=0;
   countemptines:=0;
   zt:='';
   zt:='';
@@ -313,15 +363,14 @@ begin
 end;
 end;
 {$endif}
 {$endif}
 
 
-procedure InitClip(AProgram :PProgram);
+procedure InitClip;
 begin
 begin
 {$ifdef unix}
 {$ifdef unix}
   if Assigned(PText) then
   if Assigned(PText) then
     FreeMem(PText);
     FreeMem(PText);
   PText:=nil;
   PText:=nil;
-  cProgram:=AProgram;
   AddSpecialSequence(#27'[200~',@BracketedPaste);
   AddSpecialSequence(#27'[200~',@BracketedPaste);
-  AddSpecialSequence(#27']52;c',@LinuxClipBoardData);
+  AddSpecialSequence(#27']52;c',@OSC_52_ClipboardData);
   write(#27'[?2004h');
   write(#27'[?2004h');
 {$endif}
 {$endif}
 end;
 end;
@@ -339,7 +388,6 @@ end;
 {function GetGlobalClipboardData(var P: PAnsiChar;var ASize: longint): boolean;}
 {function GetGlobalClipboardData(var P: PAnsiChar;var ASize: longint): boolean;}
 procedure GetGlobalClipboardData;
 procedure GetGlobalClipboardData;
 begin
 begin
-  {GetGlobalClipboardData:=false;}
 {$ifdef unix}
 {$ifdef unix}
   write(#27']52;c;?'#7); { OSC 52  Get Clipboard Content }
   write(#27']52;c;?'#7); { OSC 52  Get Clipboard Content }
 {$endif}
 {$endif}
@@ -363,4 +411,616 @@ begin
 {$endif}
 {$endif}
 end;
 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.
 end.

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

@@ -70,7 +70,7 @@
     OS_XXXX         The operating system used (XXXX may be one of:
     OS_XXXX         The operating system used (XXXX may be one of:
                        DOS, OS2, Linux, Windows, Go32)
                        DOS, OS2, Linux, Windows, Go32)
     PPC_XXXX        The compiler used: BP, FPK, Virtual, Speed
     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)
     PROC_XXXX       The mode of the target processor (Real or Protected)
                     This shouldn't be used, except for i386 specific parts.
                     This shouldn't be used, except for i386 specific parts.
     ASM_XXXX        This is the assembler type: BP, ISO-ANSI, FPK
     ASM_XXXX        This is the assembler type: BP, ISO-ANSI, FPK
@@ -215,7 +215,8 @@ FOR FPC THESE ARE THE TRANSLATIONS
 {$IFDEF LINUX}
 {$IFDEF LINUX}
   {$UNDEF OS_DOS}
   {$UNDEF OS_DOS}
   {$DEFINE OS_LINUX}
   {$DEFINE OS_LINUX}
-  {$DEFINE OS_UNIX}{$ENDIF}
+  {$DEFINE OS_UNIX}
+{$ENDIF}
 
 
 {$IFDEF FreeBSD}
 {$IFDEF FreeBSD}
   {$UNDEF OS_DOS}
   {$UNDEF OS_DOS}
@@ -387,8 +388,7 @@ FOR FPC THESE ARE THE TRANSLATIONS
   {$DEFINE PPC_DELPHI3}
   {$DEFINE PPC_DELPHI3}
   {$DEFINE PPC_DELPHI4}
   {$DEFINE PPC_DELPHI4}
   {$DEFINE PPC_DELPHI5}
   {$DEFINE PPC_DELPHI5}
-  {$UNDEF BP_VMTLink
-  }
+  {$UNDEF BP_VMTLink}
 {$ENDIF}
 {$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,
     SysSetFocus,
     SysReleaseFocus,
     SysReleaseFocus,
     SysClose,
     SysClose,
-    SysResize );
+    SysResize,
+    SysPaste  { OSC 52 or Bracketed paste }
+    );
 
 
   TSystemEvent = Record
   TSystemEvent = Record
     case typ : TSystemMessage of
     case typ : TSystemMessage of
       SysClose : ( CloseTyp : Longint);
       SysClose : ( CloseTyp : Longint);
       SysResize : (X,Y : Longint);
       SysResize : (X,Y : Longint);
+      SysPaste : (P :PAnsiChar; Len : Longint);
     end;
     end;
 
 
   PSystemEvent = ^TSystemEvent;
   PSystemEvent = ^TSystemEvent;

+ 4 - 6
packages/ide/fpide.pas

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

+ 2 - 2
packages/ide/weditor.pas

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

+ 15 - 3
packages/ide/winclip.pas

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

+ 1 - 1
packages/ide/wviews.pas

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