winclip.pas 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1999 by Pierre Muller
  4. Connection with Windows Clipboard
  5. based on Ralph Brown Interrupt List
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$i globdir.inc}
  13. unit WinClip;
  14. interface
  15. {$ifdef WinClipSupported}
  16. function WinClipboardSupported : boolean;
  17. function OpenWinClipboard : boolean;
  18. function EmptyWinClipboard : boolean;
  19. function GetTextWinClipboardSize : longint;
  20. function GetTextWinClipBoardData(var p : PAnsiChar;var l : longint) : boolean;
  21. function SetTextWinClipBoardData(p : PAnsiChar;l : longint) : boolean;
  22. {$endif WinClipSupported}
  23. implementation
  24. {$ifdef WinClipSupported}
  25. {$ifdef DOS}
  26. uses
  27. pmode,
  28. {$ifdef go32v2}
  29. {go32 sorry Gabor, but its still not compiling without that ! }
  30. {now it works. btw. you don't have to sorry - just to tell me... ;)) Gabor }
  31. {$endif go32v2}
  32. dos;
  33. {$endif DOS}
  34. {$ifdef linux}
  35. uses
  36. baseUnix,keyboard,fvclip;
  37. {$endif linux}
  38. {$ifdef Windows}
  39. uses
  40. strings,windows;
  41. {$endif Windows}
  42. {$ifdef HASAMIGA}
  43. uses
  44. clipboard,cliputils;
  45. {$endif}
  46. {$ifdef os2}
  47. uses
  48. DosCalls, OS2Def;
  49. {$endif os2}
  50. {$ifdef DOS}
  51. function WinClipboardSupported : boolean;
  52. var
  53. r : registers;
  54. begin
  55. r.ax:=$1700;
  56. RealIntr($2F,r);
  57. WinClipboardSupported:=(r.ax<>$1700);
  58. end;
  59. function OpenWinClipboard : boolean;
  60. var
  61. r : Registers;
  62. begin
  63. r.ax:=$1701;
  64. RealIntr($2F,r);
  65. OpenWinClipboard:=(r.ax<>0);
  66. end;
  67. function EmptyWinClipboard : boolean;
  68. var
  69. r : Registers;
  70. begin
  71. r.ax:=$1702;
  72. RealIntr($2F,r);
  73. EmptyWinClipboard:=(r.ax<>0);
  74. end;
  75. function CloseWinClipboard : boolean;
  76. var
  77. r : Registers;
  78. begin
  79. r.ax:=$1708;
  80. RealIntr($2F,r);
  81. CloseWinClipboard:=(r.ax<>0);
  82. end;
  83. function InternGetDataSize : longint;
  84. var
  85. r : Registers;
  86. begin
  87. r.ax:=$1704;
  88. r.dx:=7 {OEM Text rather then 1 : Text };
  89. RealIntr($2F,r);
  90. InternGetDataSize:=(r.dx shl 16) + r.ax;
  91. end;
  92. {$endif DOS}
  93. {$ifdef linux}
  94. function WinClipboardSupported : boolean;
  95. begin
  96. WinClipboardSupported:=true;
  97. end;
  98. function OpenWinClipboard : boolean;
  99. begin
  100. OpenWinClipboard:=true;
  101. end;
  102. function EmptyWinClipboard : boolean;
  103. begin
  104. EmptyWinClipboard:=true;
  105. end;
  106. function CloseWinClipboard : boolean;
  107. begin
  108. CloseWinClipboard:=true;
  109. end;
  110. function InternGetDataSize : longint;
  111. begin
  112. InternGetDataSize:=1; {there has to be something in order for menu to be active}
  113. end;
  114. function GetTextLinuxClipBoardData(var p : PAnsiChar;var l : longint) : boolean;
  115. begin
  116. GetTextLinuxClipBoardData:=false;
  117. GetGlobalClipboardData;
  118. end;
  119. {$endif linux}
  120. {$ifdef Windows}
  121. function WinClipboardSupported : boolean;
  122. begin
  123. WinClipboardSupported:=true;
  124. end;
  125. function OpenWinClipboard : boolean;
  126. begin
  127. OpenWinClipboard:=OpenClipboard(0);
  128. end;
  129. function EmptyWinClipboard : boolean;
  130. begin
  131. EmptyWinClipboard:=EmptyClipboard;
  132. end;
  133. function CloseWinClipboard : boolean;
  134. begin
  135. CloseWinClipboard:=CloseClipboard;
  136. end;
  137. function InternGetDataSize : longint;
  138. var HC : Handle;
  139. begin
  140. HC:=GetClipBoardData(CF_OEMTEXT);
  141. if HC<>0 then
  142. begin
  143. InternGetDataSize:=strlen(PAnsiChar(GlobalLock(HC)))+1;
  144. GlobalUnlock(HC);
  145. end
  146. else
  147. InternGetDataSize:=0;
  148. end;
  149. {$endif Windows}
  150. {$ifdef HASAMIGA}
  151. function WinClipboardSupported: Boolean;
  152. begin
  153. WinClipboardSupported := True;
  154. end;
  155. function OpenWinClipboard: boolean;
  156. begin
  157. OpenWinClipboard := True;
  158. end;
  159. function EmptyWinClipboard: boolean;
  160. begin
  161. EmptyWinClipboard := GetTextFromClip(PRIMARY_CLIP) = '';
  162. end;
  163. function CloseWinClipboard : boolean;
  164. begin
  165. CloseWinClipboard:= True;
  166. end;
  167. function InternGetDataSize: LongInt;
  168. var
  169. Text: string;
  170. begin
  171. Text := GetTextFromClip(PRIMARY_CLIP);
  172. InternGetDataSize := Length(Text);
  173. end;
  174. {$endif HASAMIGA}
  175. {$ifdef os2}
  176. const
  177. CF_TEXT = 1;
  178. CF_BITMAP = 2;
  179. CF_DSPTEXT = 3;
  180. CF_DSPBITMAP = 4;
  181. CF_METAFILE = 5;
  182. CF_DSPMETAFILE = 6;
  183. CF_PALETTE = 9;
  184. CFI_OWNERFREE = $0001;
  185. CFI_OWNERDISPLAY = $0002;
  186. CFI_POINTER = $0400;
  187. CFI_HANDLE = $0200;
  188. var
  189. OS2ClipboardSupported: boolean = false;
  190. PMWHandle: cardinal;
  191. MsgQueueHandle: cardinal;
  192. PIB: PProcessInfoBlock;
  193. type
  194. (* TWinSetClipbrdOwner = function (hab, hwnd: cardinal): longbool; cdecl;*)
  195. TWinSetClipbrdData = function (hab, ulData, fmt, rgfFmtInfo: cardinal): longbool; cdecl;
  196. TWinQueryClipbrdData = function (hab, fmt: cardinal): cardinal; cdecl;
  197. TWinQueryClipbrdFmtInfo = function (hab, fmt: cardinal; var prgfFmtInfo: cardinal): longbool; cdecl;
  198. { function WinSetClipbrdViewer(hab,hwndNewClipViewer : cardinal) : longbool; cdecl;}
  199. { function WinEnumClipbrdFmts(hab,fmt : cardinal) : cardinal; cdecl;}
  200. TWinEmptyClipbrd = function (hab: cardinal): longbool; cdecl;
  201. TWinOpenClipbrd = function (hab: cardinal): longbool; cdecl;
  202. TWinCloseClipbrd = function (hab: cardinal): longbool; cdecl;
  203. (* TWinQueryClipbrdOwner = function (hab: cardinal): cardinal; cdecl;*)
  204. { function WinQueryClipbrdViewer(hab : cardinal) : cardinal; cdecl;}
  205. TWinInitialize = function (flOptions: cardinal): cardinal; cdecl;
  206. TWinTerminate = function (hab: cardinal): longbool; cdecl;
  207. TWinCreateMsgQueue = function (hab: cardinal; cmsg: longint): cardinal; cdecl;
  208. TWinDestroyMsgQueue = function (hmq: cardinal): longbool; cdecl;
  209. var
  210. (* WinSetClipbrdOwner: TWinSetClipbrdOwner;*)
  211. ClWinSetClipbrdData: TWinSetClipbrdData;
  212. ClWinQueryClipbrdData: TWinQueryClipbrdData;
  213. ClWinQueryClipbrdFmtInfo: TWinQueryClipbrdFmtInfo;
  214. { function WinSetClipbrdViewer(hab,hwndNewClipViewer : cardinal) : longbool; cdecl;}
  215. { function WinEnumClipbrdFmts(hab,fmt : cardinal) : cardinal; cdecl;}
  216. ClWinEmptyClipbrd: TWinEmptyClipbrd;
  217. ClWinOpenClipbrd: TWinOpenClipbrd;
  218. ClWinCloseClipbrd: TWinCloseClipbrd;
  219. (* WinQueryClipbrdOwner: TWinQueryClipbrdOwner;*)
  220. { function WinQueryClipbrdViewer(hab : cardinal) : cardinal; cdecl;}
  221. ClWinInitialize: TWinInitialize;
  222. ClWinTerminate: TWinTerminate;
  223. ClWinCreateMsgQueue: TWinCreateMsgQueue;
  224. ClWinDestroyMsgQueue: TWinDestroyMsgQueue;
  225. OrigSessType: cardinal;
  226. function WinClipboardSupported : boolean;
  227. begin
  228. WinClipboardSupported:=OS2ClipboardSupported;
  229. end;
  230. function OpenWinClipboard : boolean;
  231. var
  232. SessType: cardinal;
  233. begin
  234. OpenWinClipboard := false;
  235. if not (OS2ClipboardSupported) then
  236. Exit;
  237. SessType := PIB^.tType;
  238. PIB^.tType := 3;
  239. OpenWinClipboard := ClWinOpenClipbrd (PMWHandle);
  240. PIB^.tType := SessType;
  241. end;
  242. function EmptyWinClipboard : boolean;
  243. var
  244. SessType: cardinal;
  245. begin
  246. EmptyWinClipboard := false;
  247. if not (OS2ClipboardSupported) then
  248. Exit;
  249. SessType := PIB^.tType;
  250. PIB^.tType := 3;
  251. EmptyWinClipboard := ClWinEmptyClipbrd (PMWHandle);
  252. PIB^.tType := SessType;
  253. end;
  254. function CloseWinClipboard : boolean;
  255. var
  256. SessType: cardinal;
  257. begin
  258. CloseWinClipboard := false;
  259. if not (OS2ClipboardSupported) then
  260. Exit;
  261. SessType := PIB^.tType;
  262. PIB^.tType := 3;
  263. CloseWinClipboard := ClWinCloseClipbrd (PMWHandle);
  264. PIB^.tType := SessType;
  265. end;
  266. function InternGetDataSize : longint;
  267. var
  268. P: PAnsiChar;
  269. SessType: cardinal;
  270. begin
  271. InternGetDataSize := 0;
  272. if not (OS2ClipboardSupported) then
  273. Exit;
  274. SessType := PIB^.tType;
  275. PIB^.tType := 3;
  276. P := PAnsiChar (ClWinQueryClipbrdData (PMWHandle, CF_TEXT));
  277. PIB^.tType := SessType;
  278. if P <> nil then
  279. InternGetDataSize := StrLen (PAnsiChar (P)) + 1;
  280. end;
  281. procedure InitClipboard;
  282. var
  283. RC: cardinal;
  284. ProcOK: boolean;
  285. TIB: PThreadInfoBlock;
  286. PMWModHandle: THandle;
  287. Err: string;
  288. ErrL: cardinal;
  289. begin
  290. if OS2ClipboardSupported then
  291. Exit;
  292. DosGetInfoBlocks (TIB, PIB);
  293. OrigSessType := PIB^.tType;
  294. PIB^.tType := 3;
  295. { RC := DosQueryModuleHandle ('PMWIN', PMWModHandle);}
  296. RC := DosLoadModule (Err, ErrL, 'PMWIN', PMWModHandle);
  297. if RC <> 0 then
  298. begin
  299. PIB^.tType := OrigSessType;
  300. Exit;
  301. end;
  302. ProcOK := (DosQueryProcAddr (PMWModHandle, 707, nil, pointer (ClWinCloseClipbrd)) = 0)
  303. and
  304. (DosQueryProcAddr (PMWModHandle, 716, nil, pointer (ClWinCreateMsgQueue)) = 0) and
  305. (DosQueryProcAddr (PMWModHandle, 726, nil, pointer (ClWinDestroyMsgQueue)) = 0) and
  306. (DosQueryProcAddr (PMWModHandle, 733, nil, pointer (ClWinEmptyClipbrd)) = 0) and
  307. (DosQueryProcAddr (PMWModHandle, 763, nil, pointer (ClWinInitialize)) = 0) and
  308. (DosQueryProcAddr (PMWModHandle, 793, nil, pointer (ClWinOpenClipbrd)) = 0) and
  309. (DosQueryProcAddr (PMWModHandle, 806, nil, pointer (ClWinQueryClipbrdData)) = 0) and
  310. (DosQueryProcAddr (PMWModHandle, 807, nil, pointer (ClWinQueryClipbrdFmtInfo)) = 0) and
  311. (DosQueryProcAddr (PMWModHandle, 854, nil, pointer (ClWinSetClipbrdData)) = 0) and
  312. (DosQueryProcAddr (PMWModHandle, 888, nil, pointer (ClWinTerminate)) = 0);
  313. if ProcOK then
  314. begin
  315. PMWHandle := ClWinInitialize (0);
  316. if PMWHandle <> 0 then
  317. begin
  318. MsgQueueHandle := ClWinCreateMsgQueue (PMWHandle, 0);
  319. ProcOK := MsgQueueHandle <> 0;
  320. end
  321. else
  322. ProcOK := false;
  323. end;
  324. PIB^.tType := OrigSessType;
  325. if ProcOK then
  326. OS2ClipboardSupported := true;
  327. end;
  328. procedure DoneClipboard;
  329. var
  330. SessType: cardinal;
  331. begin
  332. if not (OS2ClipboardSupported) then
  333. Exit;
  334. OS2ClipboardSupported := false;
  335. SessType := PIB^.tType;
  336. PIB^.tType := 3;
  337. if MsgQueueHandle <> 0 then
  338. begin
  339. ClWinDestroyMsgQueue (MsgQueueHandle);
  340. MsgQueueHandle := 0;
  341. end;
  342. if PMWHandle <> 0 then
  343. begin
  344. ClWinTerminate (PMWHandle);
  345. PMWHandle := 0;
  346. end;
  347. PIB^.tType := SessType;
  348. end;
  349. {$endif os2}
  350. function GetTextWinClipboardSize : longint;
  351. begin
  352. OpenWinClipboard;
  353. GetTextWinClipboardSize:=InternGetDataSize;
  354. CloseWinClipboard;
  355. end;
  356. function GetTextWinClipBoardData(var p : PAnsiChar;var l : longint) : boolean;
  357. var
  358. {$ifdef DOS}
  359. r : Registers;
  360. M : MemPtr;
  361. pp: PAnsiChar;
  362. {$endif DOS}
  363. {$ifdef linux}
  364. rez : boolean; {one variable needed to satisfy compiler}
  365. {$endif linux}
  366. {$ifdef Windows}
  367. h : HGlobal;
  368. pp : PAnsiChar;
  369. {$endif Windows}
  370. {$ifdef HASAMIGA}
  371. Text: AnsiString;
  372. pp: PAnsiChar;
  373. {$endif HASAMIGA}
  374. {$IFDEF OS2}
  375. PP: PAnsiChar;
  376. SessType: cardinal;
  377. {$ENDIF OS2}
  378. begin
  379. p:=nil;
  380. GetTextWinClipBoardData:=False;
  381. if not OpenWinClipBoard then
  382. exit;
  383. {$ifdef DOS}
  384. l:=InternGetDataSize;
  385. if (l=0) or (l>65520) then
  386. begin
  387. l:=0;
  388. CloseWinClipBoard;
  389. exit;
  390. end;
  391. GetMem(p,l+1);
  392. GetDosMem(M,l);
  393. r.ax:=$1705;
  394. r.dx:=7{ OEM Text rather then 1 : Text };
  395. r.es:=M.DosSeg;
  396. r.bx:=M.DosOfs;
  397. RealIntr($2F,r);
  398. GetTextWinClipBoardData:=(r.ax<>0);
  399. {$endif DOS}
  400. {$ifdef linux}
  401. rez:=GetTextLinuxClipBoardData(p,l);
  402. GetTextWinClipBoardData:=rez;
  403. {$endif linux}
  404. {$ifdef Windows}
  405. h:=GetClipboardData(CF_OEMTEXT);
  406. if h<>0 then
  407. begin
  408. pp:=PAnsiChar(GlobalLock(h));
  409. l:=strlen(pp)+1;
  410. getmem(p,l);
  411. move(pp^,p^,l);
  412. GlobalUnlock(h);
  413. end;
  414. GetTextWinClipBoardData:=h<>0;
  415. {$endif Windows}
  416. {$ifdef HASAMIGA}
  417. Text := GetTextFromClip(0) + #0;
  418. PP := @Text[1];
  419. l := Length(Text);
  420. GetMem(p,l);
  421. Move(pp^,p^,l);
  422. GetTextWinClipBoardData := True;
  423. {$endif HASAMIGA}
  424. {$IFDEF OS2}
  425. GetTextWinClipboardData := false;
  426. L := 0;
  427. if not (OS2ClipboardSupported) then
  428. Exit;
  429. SessType := PIB^.tType;
  430. PIB^.tType := 3;
  431. PP := PAnsiChar (ClWinQueryClipbrdData (PMWHandle, CF_TEXT));
  432. PIB^.tType := SessType;
  433. if PP <> nil then
  434. begin
  435. L := StrLen (PAnsiChar (PP)) + 1;
  436. GetMem (P, L);
  437. if P <> nil then
  438. begin
  439. Move (PP^, P^, L);
  440. GetTextWinClipBoardData := true;
  441. end;
  442. end;
  443. {$ENDIF OS2}
  444. CloseWinClipBoard;
  445. {$ifdef DOS}
  446. M.MoveDataFrom(l,P^);
  447. FreeDosMem(M);
  448. pp:=p+l;
  449. pp^:=#0; { make null terminated }
  450. {$endif DOS}
  451. end;
  452. function SetTextWinClipBoardData(p : PAnsiChar;l : longint) : boolean;
  453. var
  454. {$ifdef DOS}
  455. r : Registers;
  456. M : MemPtr;
  457. pp: PAnsiChar;
  458. op: PAnsiChar;
  459. {$endif DOS}
  460. {$ifdef linux}
  461. st : AnsiString;
  462. {$endif linux}
  463. {$ifdef Windows}
  464. h : HGlobal;
  465. pp : PAnsiChar;
  466. res : boolean;
  467. {$endif Windows}
  468. {$ifdef HASAMIGA}
  469. pp: PAnsiChar;
  470. Test: AnsiString;
  471. {$endif HASAMIGA}
  472. {$IFDEF OS2}
  473. RC: cardinal;
  474. PShared: pointer;
  475. SessType: cardinal;
  476. {$ENDIF OS2}
  477. begin
  478. SetTextWinClipBoardData:=False;
  479. if (l=0) or (l>65520) then
  480. exit;
  481. if not OpenWinClipBoard then
  482. exit;
  483. EmptyWinClipBoard;
  484. {$ifdef DOS}
  485. GetMem(pp,l+1);
  486. Move(p^,pp^,l);
  487. op:=pp+l;
  488. op^:=#0; { make sure that string is null terminated }
  489. GetDosMem(M,l+1);
  490. M.MoveDataTo(PP^,l+1);
  491. FreeMem(pp);
  492. r.ax:=$1703;
  493. r.dx:=7{ OEM Text rather then 1 : Text };
  494. r.es:=M.DosSeg;
  495. r.bx:=M.DosOfs;
  496. r.si:=l shr 16;
  497. r.cx:=l and $ffff;
  498. RealIntr($2F,r);
  499. SetTextWinClipBoardData:=(r.ax<>0);
  500. (*
  501. r.ax:=$1703;
  502. r.dx:=1{ Empty Text };
  503. r.es:=M.DosSeg;
  504. r.bx:=M.DosOfs;
  505. r.si:=0;
  506. r.cx:=0;
  507. RealIntr($2F,r);
  508. *)
  509. FreeDosMem(M);
  510. {$endif DOS}
  511. {$ifdef linux}
  512. SetTextWinClipBoardData:=SetGlobalClipboardData(p,l);
  513. {$endif linux}
  514. {$ifdef Windows}
  515. h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1);
  516. pp:=PAnsiChar(GlobalLock(h));
  517. move(p^,pp^,l+1);
  518. GlobalUnlock(h);
  519. res:=(SetClipboardData(CF_OEMTEXT,h)=h);
  520. h:=GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE,l+1);
  521. pp:=PAnsiChar(GlobalLock(h));
  522. OemToCharBuffA(p,pp,l+1);
  523. SetClipboardData(CF_TEXT,h);
  524. GlobalUnlock(h);
  525. SetTextWinClipBoardData:=res;
  526. {$endif Windows}
  527. {$ifdef HASAMIGA}
  528. PutTextToClip(0, AnsiString(p));
  529. {$endif HASAMIGA}
  530. {$IFDEF OS2}
  531. SetTextWinClipboardData := false;
  532. if not (OS2ClipboardSupported) then
  533. Exit;
  534. RC := DosAllocSharedMem (PShared, nil, Succ (L),
  535. PAG_WRITE or PAG_COMMIT or OBJ_GIVEABLE);
  536. if RC = 0 then
  537. begin
  538. Move (P^, PShared^, Succ (L));
  539. SessType := PIB^.tType;
  540. PIB^.tType := 3;
  541. SetTextWinClipboardData := ClWinSetClipbrdData (PMWHandle,
  542. cardinal (PShared), CF_TEXT, CFI_POINTER);
  543. PIB^.tType := SessType;
  544. end;
  545. {$ENDIF OS2}
  546. CloseWinClipBoard;
  547. end;
  548. {$ifdef os2}
  549. initialization
  550. InitClipboard;
  551. finalization
  552. DoneClipboard;
  553. {$endif os2}
  554. {$endif WinClipSupported}
  555. end.