fpusrscr.pas 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Integrated Development Environment
  4. Copyright (c) 1998 by Berczi Gabor
  5. User screen support routines
  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 FPUsrScr;
  14. interface
  15. uses
  16. {$ifdef win32}
  17. windows,
  18. {$endif win32}
  19. video,Objects;
  20. type
  21. PScreen = ^TScreen;
  22. TScreen = object(TObject)
  23. function GetWidth: integer; virtual;
  24. function GetHeight: integer; virtual;
  25. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  26. procedure GetCursorPos(var P: TPoint); virtual;
  27. { copy the initial video screen in the ide screen }
  28. procedure Capture; virtual;
  29. { move up or down if supported by OS }
  30. function Scroll(i : integer) : integer; virtual;
  31. { saves the current IDE screen }
  32. procedure SaveIDEScreen; virtual;
  33. { saves the current console screen }
  34. procedure SaveConsoleScreen; virtual;
  35. { restores the saved console screen }
  36. procedure SwitchToConsoleScreen; virtual;
  37. { restores the saved IDE screen }
  38. procedure SwitchBackToIDEScreen; virtual;
  39. end;
  40. {$ifdef DOS}
  41. TDOSVideoInfo = record
  42. Mode : word;
  43. ScreenSize: word;
  44. Page : byte;
  45. Rows,Cols : integer;
  46. CurPos : TPoint;
  47. CurShapeT : integer;
  48. CurShapeB : integer;
  49. StateSize : word;
  50. StateBuf : pointer;
  51. end;
  52. PDOSScreen = ^TDOSScreen;
  53. TDOSScreen = object(TScreen)
  54. constructor Init;
  55. destructor Done; virtual;
  56. public
  57. function GetWidth: integer; virtual;
  58. function GetHeight: integer; virtual;
  59. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  60. procedure GetCursorPos(var P: TPoint); virtual;
  61. procedure Capture; virtual;
  62. procedure SaveIDEScreen; virtual;
  63. procedure SaveConsoleScreen; virtual;
  64. procedure SwitchToConsoleScreen; virtual;
  65. procedure SwitchBackToIDEScreen; virtual;
  66. private
  67. ConsoleVideoInfo : TDOSVideoInfo;
  68. VBufferSize : longint;
  69. VIDEBufferSize : longint;
  70. VBuffer : PByteArray;
  71. VIDEBuffer : PByteArray;
  72. IDEVideoInfo : TDOSVideoInfo;
  73. ctrl_c_state : boolean;
  74. function GetLineStartOfs(Line: integer): word;
  75. procedure GetBuffer(Size: word);
  76. procedure FreeBuffer;
  77. procedure GetVideoMode(var MI: TDOSVideoInfo);
  78. procedure SetVideoMode(MI: TDOSVideoInfo);
  79. end;
  80. {$endif}
  81. {$ifdef Unix}
  82. PLinuxScreen = ^TLinuxScreen;
  83. TLinuxScreen = object(TScreen)
  84. constructor Init;
  85. destructor Done; virtual;
  86. public
  87. function GetWidth: integer; virtual;
  88. function GetHeight: integer; virtual;
  89. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  90. procedure GetCursorPos(var P: TPoint); virtual;
  91. procedure Capture; virtual;
  92. procedure SaveIDEScreen; virtual;
  93. procedure SaveConsoleScreen; virtual;
  94. procedure SwitchToConsoleScreen; virtual;
  95. procedure SwitchBackToIDEScreen; virtual;
  96. private
  97. IDE_screen: pvideobuf;
  98. IDE_size : longint;
  99. end;
  100. {$endif}
  101. {$ifdef win32}
  102. PWin32Screen = ^TWin32Screen;
  103. TWin32Screen = object(TScreen)
  104. constructor Init;
  105. destructor Done; virtual;
  106. public
  107. function GetWidth: integer; virtual;
  108. function GetHeight: integer; virtual;
  109. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  110. procedure GetCursorPos(var P: TPoint); virtual;
  111. function Scroll(i : integer) : integer; virtual;
  112. procedure Capture; virtual;
  113. procedure SaveIDEScreen; virtual;
  114. procedure SaveConsoleScreen; virtual;
  115. procedure SwitchToConsoleScreen; virtual;
  116. procedure SwitchBackToIDEScreen; virtual;
  117. private
  118. DosScreenBufferHandle,
  119. IDEScreenBufferHandle,
  120. StartScreenBufferHandle,
  121. DummyScreenBufferHandle,
  122. NewScreenBufferHandle : THandle;
  123. IDEActive : boolean;
  124. ConsoleMode,IdeMode : Dword;
  125. procedure BufferCopy(src,dest : THandle);
  126. end;
  127. {$endif}
  128. procedure InitUserScreen;
  129. procedure DoneUserScreen;
  130. const UserScreen : PScreen = nil;
  131. implementation
  132. uses
  133. Dos
  134. (* {$ifdef TP}
  135. {$ifdef DPMI}
  136. ,WinAPI
  137. {$endif}
  138. {$endif}*)
  139. {$ifdef FPC}
  140. {$ifdef GO32V2}
  141. ,Dpmiexcp, Go32
  142. {$endif}
  143. {$endif}
  144. {$ifdef fvision}
  145. ,Drivers
  146. {$endif}
  147. {$ifdef VESA}
  148. ,VESA
  149. {$endif}
  150. ;
  151. function TScreen.GetWidth: integer;
  152. begin
  153. Getwidth:=0;
  154. Abstract;
  155. end;
  156. function TScreen.GetHeight: integer;
  157. begin
  158. Getheight:=0;
  159. Abstract;
  160. end;
  161. procedure TScreen.GetLine(Line: integer; var Text, Attr: string);
  162. begin
  163. Abstract;
  164. end;
  165. procedure TScreen.GetCursorPos(var P: TPoint);
  166. begin
  167. Abstract;
  168. end;
  169. procedure TScreen.Capture;
  170. begin
  171. Abstract;
  172. end;
  173. procedure TScreen.SwitchToConsoleScreen;
  174. begin
  175. Abstract;
  176. end;
  177. procedure TScreen.SwitchBackToIDEScreen;
  178. begin
  179. Abstract;
  180. end;
  181. procedure TScreen.SaveIDEScreen;
  182. begin
  183. Abstract;
  184. end;
  185. function TScreen.Scroll(i : integer) : integer;
  186. begin
  187. Scroll:=0;
  188. end;
  189. procedure TScreen.SaveConsoleScreen;
  190. begin
  191. Abstract;
  192. end;
  193. {****************************************************************************
  194. TDOSScreen
  195. ****************************************************************************}
  196. {$ifdef DOS}
  197. constructor TDOSScreen.Init;
  198. begin
  199. inherited Init;
  200. Capture;
  201. { get the current ctrl-C state }
  202. Ctrl_c_state:=djgpp_set_ctrl_c(false);
  203. djgpp_set_ctrl_c(Ctrl_c_state);
  204. end;
  205. destructor TDOSScreen.Done;
  206. begin
  207. FreeBuffer;
  208. if assigned(VIDEBuffer) then
  209. FreeMem(VIDEBuffer,VIDEBufferSize);
  210. inherited Done;
  211. end;
  212. function TDOSScreen.GetWidth: integer;
  213. begin
  214. GetWidth:=ConsoleVideoInfo.Cols;
  215. end;
  216. function TDOSScreen.GetHeight: integer;
  217. begin
  218. GetHeight:=ConsoleVideoInfo.Rows;
  219. end;
  220. procedure TDOSScreen.GetLine(Line: integer; var Text, Attr: string);
  221. var X: integer;
  222. W: word;
  223. begin
  224. Text:=''; Attr:='';
  225. if Line<GetHeight then
  226. begin
  227. W:=GetLineStartOfs(Line);
  228. for X:=0 to GetWidth-1 do
  229. begin
  230. {Text:=Text+chr(VBuffer^[W+X*2]);
  231. Attr:=Attr+chr(VBuffer^[W+X*2+1]);}
  232. System.Insert(chr(VBuffer^[W+X*2]),Text,Length(Text)+1);
  233. System.Insert(chr(VBuffer^[W+X*2+1]),Attr,Length(Attr)+1);
  234. end;
  235. end;
  236. end;
  237. procedure TDOSScreen.GetCursorPos(var P: TPoint);
  238. begin
  239. P:=ConsoleVideoInfo.CurPos;
  240. end;
  241. procedure TDOSScreen.Capture;
  242. begin
  243. SaveConsoleScreen;
  244. end;
  245. procedure TDosScreen.SaveIDEScreen;
  246. var
  247. VSeg,SOfs: word;
  248. begin
  249. GetVideoMode(IDEVideoInfo);
  250. { First keep a copy of IDE screen }
  251. if ConsoleVideoInfo.Mode=7 then
  252. VSeg:=SegB000
  253. else
  254. VSeg:=SegB800;
  255. SOfs:=MemW[Seg0040:$4e];
  256. if not assigned(VIDEBuffer) or (VIDEBufferSize<>IDEVideoInfo.ScreenSize) then
  257. begin
  258. if assigned(VIDEBuffer) then
  259. FreeMem(VIDEBuffer,VIDEBufferSize);
  260. GetMem(VIDEBuffer,IDEVideoInfo.ScreenSize);
  261. VIDEBufferSize:=IDEVideoInfo.ScreenSize;
  262. end;
  263. {$ifdef FPC}
  264. DosmemGet(VSeg,SOfs,VIDEBuffer^,IDEVideoInfo.ScreenSize);
  265. {$else}
  266. Move(ptr(VSeg,SOfs)^,VIDEBuffer^,IDEVideoInfo.ScreenSize);
  267. {$endif}
  268. end;
  269. procedure TDosScreen.SaveConsoleScreen;
  270. var
  271. VSeg,SOfs: word;
  272. begin
  273. GetVideoMode(ConsoleVideoInfo);
  274. GetBuffer(ConsoleVideoInfo.ScreenSize);
  275. if ConsoleVideoInfo.Mode=7 then
  276. VSeg:=SegB000
  277. else
  278. VSeg:=SegB800;
  279. SOfs:=MemW[Seg0040:$4e];
  280. {$ifdef FPC}
  281. DosmemGet(VSeg,SOfs,VBuffer^,ConsoleVideoInfo.ScreenSize);
  282. {$else}
  283. Move(ptr(VSeg,SOfs)^,VBuffer^,ConsoleVideoInfo.ScreenSize);
  284. {$endif}
  285. end;
  286. procedure TDOSScreen.SwitchToConsoleScreen;
  287. var
  288. VSeg,SOfs: word;
  289. begin
  290. SetVideoMode(ConsoleVideoInfo);
  291. if ConsoleVideoInfo.Mode=7 then
  292. VSeg:=SegB000
  293. else
  294. VSeg:=SegB800;
  295. SOfs:=MemW[Seg0040:$4e];
  296. {$ifdef FPC}
  297. DosmemPut(VSeg,SOfs,VBuffer^,ConsoleVideoInfo.ScreenSize);
  298. djgpp_set_ctrl_c(Ctrl_c_state);
  299. {$else}
  300. Move(VBuffer^,ptr(VSeg,SOfs)^,ConsoleVideoInfo.ScreenSize);
  301. {$endif}
  302. end;
  303. procedure TDOSScreen.SwitchBackToIDEScreen;
  304. var
  305. VSeg,SOfs: word;
  306. begin
  307. SetVideoMode(IDEVideoInfo);
  308. if ConsoleVideoInfo.Mode=7 then
  309. VSeg:=SegB000
  310. else
  311. VSeg:=SegB800;
  312. SOfs:=MemW[Seg0040:$4e];
  313. if assigned(VIDEBuffer) then
  314. {$ifdef FPC}
  315. DosmemPut(VSeg,SOfs,VIDEBuffer^,IDEVideoInfo.ScreenSize);
  316. Ctrl_c_state := djgpp_set_ctrl_c(false);
  317. {$else}
  318. Move(VIDEBuffer^,ptr(VSeg,SOfs)^,IDEVideoInfo.ScreenSize);
  319. {$endif}
  320. end;
  321. function TDOSScreen.GetLineStartOfs(Line: integer): word;
  322. begin
  323. GetLineStartOfs:=(ConsoleVideoInfo.Cols*Line)*2;
  324. end;
  325. procedure TDOSScreen.GetBuffer(Size: word);
  326. begin
  327. if (VBuffer<>nil) and (VBufferSize=Size) then Exit;
  328. if VBuffer<>nil then FreeBuffer;
  329. VBufferSize:=Size;
  330. GetMem(VBuffer,VBufferSize);
  331. end;
  332. procedure TDOSScreen.FreeBuffer;
  333. begin
  334. if (VBuffer<>nil) and (VBufferSize>0) then FreeMem(VBuffer,VBufferSize);
  335. VBuffer:=nil;
  336. end;
  337. procedure TDOSScreen.GetVideoMode(var MI: TDOSVideoInfo);
  338. var
  339. r: registers;
  340. {$ifdef TP}
  341. P: pointer;
  342. Sel: longint;
  343. (* {$I realintr.inc} *)
  344. {$endif}
  345. begin
  346. if (MI.StateSize>0) and (MI.StateBuf<>nil) then
  347. begin FreeMem(MI.StateBuf,MI.StateSize); MI.StateBuf:=nil; end;
  348. MI.ScreenSize:=MemW[Seg0040:$4c];
  349. r.ah:=$0f;
  350. intr($10,r);
  351. MI.Mode:=r.al;
  352. MI.Page:=r.bh;
  353. MI.Cols:=r.ah;
  354. {$ifdef VESA}
  355. VESAGetMode(MI.Mode);
  356. {$endif}
  357. MI.Rows:=MI.ScreenSize div (MI.Cols*2);
  358. if MI.Rows=51 then MI.Rows:=50;
  359. r.ah:=$03;
  360. r.bh:=MI.Page;
  361. intr($10,r);
  362. with MI do
  363. begin
  364. CurPos.X:=r.dl; CurPos.Y:=r.dh;
  365. CurShapeT:=r.ch; CurShapeB:=r.cl;
  366. end;
  367. (*
  368. {$ifdef TP}
  369. { check VGA functions }
  370. MI.StateSize:=0;
  371. r.ah:=$1c; r.al:=0; r.cx:=7; intr($10,r);
  372. if (r.al=$1c) and ((r.flags and fCarry)=0) and (r.bx>0) then
  373. begin
  374. MI.StateSize:=r.bx;
  375. GetMem(MI.StateBuf,MI.StateSize); FillChar(MI.StateBuf^,MI.StateSize,0);
  376. P:=MI.StateBuf;
  377. {$ifdef DPMI}
  378. Sel:=GlobalDosAlloc(MI.StateSize);
  379. P:=Ptr(Sel shr 16,0);
  380. {$endif}
  381. r.ah:=$1c; r.al:=1; r.cx:=7;
  382. r.es:=PtrRec(P).Seg; r.bx:=PtrRec(P).Ofs;
  383. {$ifdef DPMI}realintr($10,r);{$else}intr($10,r);{$endif}
  384. {$ifdef DPMI}
  385. Move(Ptr(Sel and $ffff,0)^,MI.StateBuf^,MI.StateSize);
  386. GlobalDosFree(Sel and $ffff);
  387. {$endif}
  388. end;
  389. {$endif}
  390. *)
  391. end;
  392. procedure TDOSScreen.SetVideoMode(MI: TDOSVideoInfo);
  393. var r: registers;
  394. CM: TDOSVideoInfo;
  395. {$ifdef TP}
  396. P: pointer;
  397. Sel: longint;
  398. {$I realintr.inc}
  399. {$endif}
  400. begin
  401. FillChar(CM,sizeof(CM),0);
  402. GetVideoMode(CM);
  403. if (CM.Mode<>MI.Mode) or (CM.Cols<>MI.Cols) or (CM.Rows<>MI.Rows) then
  404. begin
  405. {$ifdef VESA}
  406. if MI.Mode>=$100 then
  407. VESASetMode(MI.Mode)
  408. else
  409. {$endif}
  410. begin
  411. r.ah:=$00; r.al:=MI.Mode; intr($10,r);
  412. end;
  413. if (MI.Mode=3) and (MI.Cols=80) and (MI.Rows=50) then
  414. begin
  415. r.ax:=$1112; r.bx:=$0;
  416. intr($10,r);
  417. end;
  418. end;
  419. r.ah:=$05; r.al:=MI.Page; intr($10,r);
  420. r.ah:=$02; r.bh:=MI.Page; r.dl:=MI.CurPos.X; r.dh:=MI.CurPos.Y; intr($10,r);
  421. r.ah:=$01; r.ch:=MI.CurShapeT; r.cl:=MI.CurShapeB; intr($10,r);
  422. (*
  423. {$ifdef TP}
  424. if (MI.StateSize>0) and (MI.StateBuf<>nil) then
  425. begin
  426. P:=MI.StateBuf;
  427. {$ifdef DPMI}
  428. Sel:=GlobalDosAlloc(MI.StateSize);
  429. Move(MI.StateBuf^,ptr(Sel and $ffff,0)^,MI.StateSize);
  430. P:=Ptr(Sel shr 16,0);
  431. {$endif}
  432. r.ah:=$1c; r.al:=2; r.cx:=7;
  433. r.es:=PtrRec(P).Seg; r.bx:=PtrRec(P).Ofs;
  434. {$ifdef DPMI}realintr($10,r);{$else}intr($10,r);{$endif}
  435. {$ifdef DPMI}
  436. GlobalDosFree(Sel and $ffff);
  437. {$endif}
  438. end;
  439. {$endif}
  440. *)
  441. end;
  442. {$endif}
  443. {****************************************************************************
  444. TLinuxScreen
  445. ****************************************************************************}
  446. {$ifdef Unix}
  447. constructor TLinuxScreen.Init;
  448. begin
  449. inherited Init;
  450. IDE_screen := nil;
  451. end;
  452. destructor TLinuxScreen.Done;
  453. begin
  454. inherited Done;
  455. end;
  456. function TLinuxScreen.GetWidth: integer;
  457. begin
  458. GetWidth:=ScreenWidth;
  459. end;
  460. function TLinuxScreen.GetHeight: integer;
  461. begin
  462. GetHeight:=ScreenHeight;
  463. end;
  464. procedure TLinuxScreen.GetLine(Line: integer; var Text, Attr: string);
  465. begin
  466. Text:='';
  467. Attr:='';
  468. end;
  469. procedure TLinuxScreen.GetCursorPos(var P: TPoint);
  470. begin
  471. P.X:=0;
  472. P.Y:=0;
  473. end;
  474. procedure TLinuxScreen.Capture;
  475. begin
  476. end;
  477. procedure TLinuxScreen.SaveIDEScreen;
  478. begin
  479. if assigned(IDE_screen) then
  480. dispose(IDE_screen);
  481. getmem(IDE_screen,videobufsize);
  482. Ide_size:=videobufsize;
  483. move(videobuf^,IDE_screen^,videobufsize);
  484. end;
  485. procedure TLinuxScreen.SaveConsoleScreen;
  486. begin
  487. end;
  488. procedure TLinuxScreen.SwitchToConsoleScreen;
  489. begin
  490. end;
  491. procedure TLinuxScreen.SwitchBackToIDEScreen;
  492. begin
  493. if IDE_screen = nil then
  494. exit;
  495. move(IDE_screen^,videobuf^,videobufsize);
  496. freemem(IDE_screen,Ide_size);
  497. IDE_screen := nil;
  498. end;
  499. {$endif}
  500. {****************************************************************************
  501. TWin32Screen
  502. ****************************************************************************}
  503. {$ifdef win32}
  504. procedure UpdateFileHandles;
  505. begin
  506. {StdInputHandle:=longint(GetStdHandle(STD_INPUT_HANDLE));}
  507. StdOutputHandle:=longint(GetStdHandle(STD_OUTPUT_HANDLE));
  508. {StdErrorHandle:=longint(GetStdHandle(STD_ERROR_HANDLE));}
  509. TextRec(Output).Handle:=StdOutputHandle;
  510. TextRec(StdOut).Handle:=StdOutputHandle;
  511. {TextRec(StdErr).Handle:=StdErrorHandle;}
  512. end;
  513. constructor TWin32Screen.Init;
  514. var
  515. SecurityAttr : Security_attributes;
  516. BigWin : Coord;
  517. res : longbool;
  518. Error : dword;
  519. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  520. begin
  521. inherited Init;
  522. {if GetConsoleOutputCP<>437 then
  523. res:=SetConsoleOutputCP(437);}
  524. SecurityAttr.nLength:=SizeOf(Security_attributes);
  525. SecurityAttr.lpSecurityDescriptor:=nil;
  526. SecurityAttr.bInheritHandle:=true;
  527. NewScreenBufferHandle:=CreateConsoleScreenBuffer(
  528. GENERIC_READ or GENERIC_WRITE,
  529. FILE_SHARE_READ or FILE_SHARE_WRITE,SecurityAttr,
  530. CONSOLE_TEXTMODE_BUFFER,nil);
  531. DummyScreenBufferHandle:=CreateConsoleScreenBuffer(
  532. GENERIC_READ or GENERIC_WRITE,
  533. FILE_SHARE_READ or FILE_SHARE_WRITE,SecurityAttr,
  534. CONSOLE_TEXTMODE_BUFFER,nil);
  535. StartScreenBufferHandle:=GetStdHandle(STD_OUTPUT_HANDLE);
  536. GetConsoleMode(GetStdHandle(Std_Input_Handle), @ConsoleMode);
  537. IdeMode:=ConsoleMode;
  538. {$ifdef debug}
  539. {define win32bigwin}
  540. {$endif debug}
  541. {$ifdef win32bigwin}
  542. GetConsoleScreenBufferInfo(StartScreenBufferHandle,
  543. @ConsoleScreenBufferInfo);
  544. BigWin.X:=ConsoleScreenBufferInfo.dwSize.X;
  545. BigWin.Y:=200;
  546. { Try to allow to store more info }
  547. res:=SetConsoleScreenBufferSize(NewScreenBufferHandle,BigWin);
  548. if not res then
  549. error:=GetLastError;
  550. res:=SetConsoleScreenBufferSize(StartScreenBufferHandle,BigWin);
  551. if not res then
  552. error:=GetLastError;
  553. {$endif win32bigwin}
  554. { make sure that both Screen Handle have the sme buffer }
  555. GetConsoleScreenBufferInfo(StartScreenBufferHandle,
  556. @ConsoleScreenBufferInfo);
  557. res:=SetConsoleScreenBufferSize(NewScreenBufferHandle,
  558. ConsoleScreenBufferInfo.dwSize);
  559. if not res then
  560. error:=GetLastError;
  561. IDEScreenBufferHandle:=NewScreenBufferHandle;
  562. DosScreenBufferHandle:=StartScreenBufferHandle;
  563. Capture;
  564. {$ifdef fvision}
  565. if TextModeGFV then
  566. {$endif fvision}
  567. SwitchBackToIDEScreen;
  568. end;
  569. destructor TWin32Screen.Done;
  570. begin
  571. { copy the Dos buffer content into the original ScreenBuffer
  572. which remains the startup std_output_handle PM }
  573. {if StartScreenBufferHandle=IDEScreenBufferHandle then}
  574. BufferCopy(DosScreenBufferHandle,IDEScreenBufferHandle);
  575. SetConsoleActiveScreenBuffer(StartScreenBufferHandle);
  576. SetStdHandle(Std_Output_Handle,StartScreenBufferHandle);
  577. UpdateFileHandles;
  578. CloseHandle(NewScreenBufferHandle);
  579. CloseHandle(DummyScreenBufferHandle);
  580. inherited Done;
  581. end;
  582. function TWin32Screen.GetWidth: integer;
  583. var
  584. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  585. begin
  586. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  587. @ConsoleScreenBufferInfo);
  588. GetWidth:=ConsoleScreenBufferInfo.dwSize.X;
  589. end;
  590. function TWin32Screen.GetHeight: integer;
  591. var
  592. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  593. begin
  594. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  595. @ConsoleScreenBufferInfo);
  596. GetHeight:=ConsoleScreenBufferInfo.dwSize.Y;
  597. end;
  598. function TWin32Screen.Scroll(i : integer) : integer;
  599. var
  600. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  601. ConsoleWindow : Small_rect;
  602. begin
  603. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  604. @ConsoleScreenBufferInfo);
  605. if (ConsoleScreenBufferInfo.srWindow.Top + i < 0) then
  606. i:= -ConsoleScreenBufferInfo.srWindow.Top;
  607. if (ConsoleScreenBufferInfo.srWindow.Bottom + i > ConsoleScreenBufferInfo.dwSize.Y) then
  608. i:= ConsoleScreenBufferInfo.dwSize.Y - ConsoleScreenBufferInfo.srWindow.Bottom;
  609. if i<>0 then
  610. begin
  611. ConsoleWindow.Left:=ConsoleScreenBufferInfo.srWindow.Left;
  612. ConsoleWindow.Right:=ConsoleScreenBufferInfo.srWindow.Right;
  613. ConsoleWindow.Top:=ConsoleScreenBufferInfo.srWindow.Top+i;
  614. ConsoleWindow.Bottom:=ConsoleScreenBufferInfo.srWindow.Bottom+i;
  615. SetConsoleWindowInfo(DosScreenBufferHandle,true,ConsoleWindow);
  616. Scroll:=i;
  617. end
  618. else
  619. Scroll:=0;
  620. end;
  621. procedure TWin32Screen.GetLine(Line: integer; var Text, Attr: string);
  622. type
  623. CharInfoArray = Array [0..255] of Char_Info;
  624. var
  625. LineBuf : ^CharInfoArray;
  626. BufSize,BufCoord : Coord;
  627. i,LineSize : longint;
  628. WriteRegion : SMALL_RECT;
  629. begin
  630. GetMem(LineBuf,SizeOf(CharInfoArray));
  631. LineSize:=ScreenWidth;
  632. If LineSize>256 then
  633. LineSize:=256;
  634. BufSize.X:=LineSize;
  635. BufSize.Y:=1;
  636. BufCoord.X:=0;
  637. BufCoord.Y:=0;
  638. with WriteRegion do
  639. begin
  640. Top :=Line;
  641. Left :=0;
  642. Bottom := Line+1;
  643. Right := LineSize-1;
  644. end;
  645. ReadConsoleOutput(DosScreenBufferHandle, PChar_info(LineBuf),
  646. BufSize, BufCoord, @WriteRegion);
  647. for i:=1 to LineSize do
  648. begin
  649. Text[i]:=LineBuf^[i-1].AsciiChar;
  650. Attr[i]:=char(byte(LineBuf^[i-1].Attributes));
  651. end;
  652. FreeMem(LineBuf,SizeOf(CharInfoArray));
  653. Text[0]:=char(byte(LineSize));
  654. Attr[0]:=char(byte(LineSize));
  655. end;
  656. procedure TWin32Screen.GetCursorPos(var P: TPoint);
  657. var
  658. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  659. begin
  660. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  661. @ConsoleScreenBufferInfo);
  662. P.X:=ConsoleScreenBufferInfo.dwCursorPosition.X;
  663. P.Y:=ConsoleScreenBufferInfo.dwCursorPosition.Y;
  664. end;
  665. procedure TWin32Screen.BufferCopy(Src, Dest : THandle);
  666. type
  667. CharInfoArray = Array [0..256*255-1] of Char_Info;
  668. var
  669. LineBuf : ^CharInfoArray;
  670. BufSize,BufCoord : Coord;
  671. Error, LineSize,
  672. Part, OnePartY: longint;
  673. res : boolean;
  674. WriteRegion : SMALL_RECT;
  675. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  676. DestConsoleScreenBufferInfo : Console_screen_buffer_info;
  677. begin
  678. GetConsoleScreenBufferInfo(Src,
  679. @ConsoleScreenBufferInfo);
  680. GetConsoleScreenBufferInfo(Dest,
  681. @DestConsoleScreenBufferInfo);
  682. GetMem(LineBuf,SizeOf(CharInfoArray));
  683. FillChar(LineBuf^,SizeOf(CharInfoArray),#0);
  684. LineSize:=ConsoleScreenBufferInfo.dwSize.X;
  685. If LineSize>256 then
  686. LineSize:=256;
  687. BufSize.X:=LineSize;
  688. BufSize.Y:=ConsoleScreenBufferInfo.dwSize.Y;
  689. BufCoord.X:=0;
  690. BufCoord.Y:=0;
  691. with WriteRegion do
  692. begin
  693. Top :=0;
  694. Left :=0;
  695. Bottom := ConsoleScreenBufferInfo.dwSize.Y-1;
  696. Right := LineSize-1;
  697. end;
  698. if BufSize.X*BufSize.Y*Sizeof(CHAR_INFO) >= $8000 then
  699. begin
  700. OnePartY := ($8000 -1) div (BufSize.X * SizeOf(Char_Info) );
  701. BufSize.Y:=OnePartY;
  702. Part:=0;
  703. while ((Part+1)*OnePartY < ConsoleScreenBufferInfo.dwSize.Y) do
  704. begin
  705. WriteRegion.Top := Part*OnePartY;
  706. WriteRegion.Bottom := (Part+1)*OnePartY-1;
  707. res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
  708. BufSize, BufCoord, @WriteRegion);
  709. if not res then
  710. Error:=GetLastError;
  711. res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
  712. BufSize, BufCoord, @WriteRegion);
  713. if not res then
  714. Error:=GetLastError;
  715. Inc(Part);
  716. end;
  717. BufSize.Y:=ConsoleScreenBufferInfo.dwSize.Y - Part*OnePartY;
  718. WriteRegion.Top := Part*OnePartY;
  719. WriteRegion.Bottom := ConsoleScreenBufferInfo.dwSize.Y-1;
  720. res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
  721. BufSize, BufCoord, @WriteRegion);
  722. if not res then
  723. Error:=GetLastError;
  724. res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
  725. BufSize, BufCoord, @WriteRegion);
  726. if not res then
  727. Error:=GetLastError;
  728. end
  729. else
  730. begin
  731. res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
  732. BufSize, BufCoord, @WriteRegion);
  733. if not res then
  734. Error:=GetLastError;
  735. res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
  736. BufSize, BufCoord, @WriteRegion);
  737. if not res then
  738. Error:=GetLastError;
  739. end;
  740. FreeMem(LineBuf,SizeOf(CharInfoArray));
  741. SetConsoleCursorPosition(Dest, ConsoleScreenBufferInfo.dwCursorPosition);
  742. end;
  743. procedure TWin32Screen.Capture;
  744. begin
  745. {if StartScreenBufferHandle=IdeScreenBufferHandle then
  746. BufferCopy(IDEScreenBufferHandle,DosScreenBufferHandle)
  747. else
  748. BufferCopy(DosScreenBufferHandle,IDEScreenBufferHandle);}
  749. SaveConsoleScreen;
  750. end;
  751. { dummy for win32 as the Buffer screen
  752. do hold all the info }
  753. procedure TWin32Screen.SaveIDEScreen;
  754. begin
  755. {$ifdef fvision}
  756. if TextModeGFV then
  757. {$endif fvision}
  758. begin
  759. GetConsoleMode(GetStdHandle(Std_Input_Handle), @IdeMode);
  760. { set the dummy buffer as active already now PM }
  761. SetStdHandle(Std_Output_Handle,DummyScreenBufferHandle);
  762. UpdateFileHandles;
  763. end;
  764. end;
  765. { dummy for win32 as the Buffer screen
  766. do hold all the info }
  767. procedure TWin32Screen.SaveConsoleScreen;
  768. begin
  769. {$ifdef fvision}
  770. if TextModeGFV then
  771. {$endif fvision}
  772. begin
  773. GetConsoleMode(GetStdHandle(Std_Input_Handle), @ConsoleMode);
  774. { set the dummy buffer as active already now PM }
  775. SetStdHandle(Std_Output_Handle,DummyScreenBufferHandle);
  776. UpdateFileHandles;
  777. end;
  778. end;
  779. procedure TWin32Screen.SwitchToConsoleScreen;
  780. begin
  781. {$ifdef fvision}
  782. if TextModeGFV then
  783. {$endif fvision}
  784. begin
  785. SetConsoleActiveScreenBuffer(DosScreenBufferHandle);
  786. SetStdHandle(Std_Output_Handle,DosScreenBufferHandle);
  787. SetConsoleMode(GetStdHandle(Std_Input_Handle), ConsoleMode);
  788. UpdateFileHandles;
  789. end;
  790. IDEActive:=false;
  791. end;
  792. procedure TWin32Screen.SwitchBackToIDEScreen;
  793. var
  794. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  795. WindowPos : Small_rect;
  796. res : boolean;
  797. error : longint;
  798. begin
  799. {$ifdef fvision}
  800. if TextModeGFV then
  801. {$endif fvision}
  802. begin
  803. SetStdHandle(Std_Output_Handle,IDEScreenBufferHandle);
  804. UpdateFileHandles;
  805. GetConsoleScreenBufferInfo(IDEScreenBufferHandle,
  806. @ConsoleScreenBufferInfo);
  807. SetConsoleActiveScreenBuffer(IDEScreenBufferHandle);
  808. IdeMode:=(IdeMode or ENABLE_MOUSE_INPUT) and not ENABLE_PROCESSED_INPUT;
  809. SetConsoleMode(GetStdHandle(Std_Input_Handle), IdeMode);
  810. WindowPos.left:=0;
  811. WindowPos.right:=ConsoleScreenBufferInfo.srWindow.right
  812. -ConsoleScreenBufferInfo.srWindow.left;
  813. WindowPos.top:=0;
  814. WindowPos.bottom:=ConsoleScreenBufferInfo.srWindow.bottom
  815. -ConsoleScreenBufferInfo.srWindow.top;
  816. with ConsoleScreenBufferInfo.dwMaximumWindowSize do
  817. begin
  818. if WindowPos.Right<X-1 then
  819. WindowPos.right:=X-1;
  820. if WindowPos.Bottom<Y-1 then
  821. WindowPos.Bottom:=Y-1;
  822. end;
  823. res:=SetConsoleWindowInfo(IDEScreenBufferHandle,true,WindowPos);
  824. if not res then
  825. error:=GetLastError;
  826. end;
  827. IDEActive:=true;
  828. end;
  829. {$endif}
  830. {****************************************************************************
  831. Initialize
  832. ****************************************************************************}
  833. procedure InitUserScreen;
  834. begin
  835. {$ifdef DOS}
  836. UserScreen:=New(PDOSScreen, Init);
  837. {$else}
  838. {$ifdef Unix}
  839. UserScreen:=New(PLinuxScreen, Init);
  840. {$else}
  841. {$ifdef Win32}
  842. UserScreen:=New(PWin32Screen, Init);
  843. {$else}
  844. UserScreen:=New(PScreen, Init);
  845. {$endif Win32}
  846. {$endif Unix}
  847. {$endif Dos}
  848. end;
  849. procedure DoneUserScreen;
  850. begin
  851. if UserScreen<>nil then
  852. begin
  853. UserScreen^.SwitchToConsoleScreen;
  854. Dispose(UserScreen, Done);
  855. UserScreen:=nil;
  856. end;
  857. end;
  858. end.
  859. {
  860. $Log$
  861. Revision 1.10 2002-06-06 06:46:28 pierre
  862. * No videobuffer switch necessary for fvision win32 graphic version
  863. Revision 1.9 2002/04/25 13:34:17 pierre
  864. * fix the disappearing desktop for win32
  865. Revision 1.8 2002/01/22 16:29:52 pierre
  866. * try to fix win32 problem with Dos program ouptut in command shell
  867. Warning, to debug under win32 with GDB you must use "set new-console on"
  868. Revision 1.7 2001/11/08 17:06:22 pierre
  869. * impose the correct size for win32 console window
  870. Revision 1.6 2001/11/08 16:38:25 pierre
  871. * fix win32 scrolling
  872. + always go back to 0,0 position in IDE mode
  873. Revision 1.5 2001/11/08 16:07:41 pierre
  874. * overcome buffer win32 problem due to a bug in ReadConsoleOutput
  875. Revision 1.4 2001/10/24 14:17:27 pierre
  876. * try to fix the Win2000 mouse problem
  877. Revision 1.3 2001/09/09 20:44:53 carl
  878. * bugfix of console sharing mode (on NT this would bug all
  879. std_input access).
  880. Revision 1.2 2001/08/12 00:04:50 pierre
  881. * some speed improvements for string operations
  882. Revision 1.1 2001/08/04 11:30:24 peter
  883. * ide works now with both compiler versions
  884. Revision 1.1.2.10 2001/06/14 09:15:16 pierre
  885. TScreen methods reorganized:
  886. SwitchTo method renamed SwitchToConsoleScreen
  887. SwitchBack method renamed SwitchBackToIDEScreen
  888. + method Scroll added
  889. + SaveIDEScreen and SaveConsoleScreen methods added
  890. Revision 1.1.2.9 2001/04/04 08:52:01 pierre
  891. * allow inheritance for win32 DosScreenBufferHandle
  892. Revision 1.1.2.8 2001/03/16 17:45:54 pierre
  893. * free VIDEBuffer of TDosScreen
  894. Revision 1.1.2.7 2000/11/30 13:04:01 pierre
  895. * fix for bug 1205
  896. Revision 1.1.2.6 2000/11/29 00:54:45 pierre
  897. + preserve window number and save special windows
  898. Revision 1.1.2.5 2000/11/22 12:47:21 pierre
  899. * fix the screen saving at start for win32
  900. Revision 1.1.2.4 2000/11/14 09:23:56 marco
  901. * Second batch
  902. Revision 1.1.2.3 2000/10/10 21:24:56 pierre
  903. * avoid writing past IDE_screen buffer length
  904. Revision 1.1.2.2 2000/08/21 12:10:19 jonas
  905. * fixed errors in my previous commit, it now works properly
  906. Revision 1.1.2.1 2000/08/21 10:51:13 jonas
  907. * IDE screen saving/restoring implemented for Linux
  908. Revision 1.1 2000/07/13 09:48:36 michael
  909. + Initial import
  910. Revision 1.13 2000/06/16 15:00:20 pierre
  911. * accord to new WriteConsoleOuput declarations
  912. Revision 1.12 2000/04/25 08:42:33 pierre
  913. * New Gabor changes : see fixes.txt
  914. Revision 1.11 2000/04/18 11:42:37 pierre
  915. lot of Gabor changes : see fixes.txt
  916. Revision 1.10 2000/03/13 20:30:37 pierre
  917. + stores IDE screen before Switching for DOS
  918. Revision 1.9 2000/02/04 23:17:25 pierre
  919. * Keep the entry ScreenBuffer at exit
  920. Revision 1.8 1999/12/01 16:17:18 pierre
  921. * Restore std_output_handle correctly at exit for GDB
  922. Revision 1.7 1999/11/10 17:12:00 pierre
  923. * Win32 screen problems solved
  924. Revision 1.6 1999/09/22 13:02:00 pierre
  925. + Twin32Screen added
  926. Revision 1.5 1999/08/16 18:25:24 peter
  927. * Adjusting the selection when the editor didn't contain any line.
  928. * Reserved word recognition redesigned, but this didn't affect the overall
  929. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  930. The syntax scanner loop is a bit slow but the main problem is the
  931. recognition of special symbols. Switching off symbol processing boosts
  932. the performance up to ca. 200%...
  933. * The editor didn't allow copying (for ex to clipboard) of a single character
  934. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  935. * Compiler Messages window (actually the whole desktop) did not act on any
  936. keypress when compilation failed and thus the window remained visible
  937. + Message windows are now closed upon pressing Esc
  938. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  939. only when neccessary
  940. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  941. + LineSelect (Ctrl+K+L) implemented
  942. * The IDE had problems closing help windows before saving the desktop
  943. Revision 1.4 1999/06/28 19:32:25 peter
  944. * fixes from gabor
  945. Revision 1.3 1999/02/02 16:41:42 peter
  946. + automatic .pas/.pp adding by opening of file
  947. * better debuggerscreen changes
  948. Revision 1.2 1999/01/04 11:49:51 peter
  949. * 'Use tab characters' now works correctly
  950. + Syntax highlight now acts on File|Save As...
  951. + Added a new class to syntax highlight: 'hex numbers'.
  952. * There was something very wrong with the palette managment. Now fixed.
  953. + Added output directory (-FE<xxx>) support to 'Directories' dialog...
  954. * Fixed some possible bugs in Running/Compiling, and the compilation/run
  955. process revised
  956. Revision 1.1 1998/12/28 15:47:53 peter
  957. + Added user screen support, display & window
  958. + Implemented Editor,Mouse Options dialog
  959. + Added location of .INI and .CFG file
  960. + Option (INI) file managment implemented (see bottom of Options Menu)
  961. + Switches updated
  962. + Run program
  963. Revision 1.0 1998/12/24 09:55:49 gabor
  964. Original implementation
  965. }