fpusrscr.pas 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  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 : THandle;
  120. IDEActive : boolean;
  121. ConsoleMode,IdeMode : Dword;
  122. procedure BufferCopy(src,dest : THandle);
  123. end;
  124. {$endif}
  125. procedure InitUserScreen;
  126. procedure DoneUserScreen;
  127. const UserScreen : PScreen = nil;
  128. implementation
  129. uses
  130. Dos
  131. (* {$ifdef TP}
  132. {$ifdef DPMI}
  133. ,WinAPI
  134. {$endif}
  135. {$endif}*)
  136. {$ifdef FPC}
  137. {$ifdef GO32V2}
  138. ,Dpmiexcp, Go32
  139. {$endif}
  140. {$endif}
  141. {$ifdef VESA}
  142. ,VESA
  143. {$endif}
  144. ;
  145. function TScreen.GetWidth: integer;
  146. begin
  147. Getwidth:=0;
  148. Abstract;
  149. end;
  150. function TScreen.GetHeight: integer;
  151. begin
  152. Getheight:=0;
  153. Abstract;
  154. end;
  155. procedure TScreen.GetLine(Line: integer; var Text, Attr: string);
  156. begin
  157. Abstract;
  158. end;
  159. procedure TScreen.GetCursorPos(var P: TPoint);
  160. begin
  161. Abstract;
  162. end;
  163. procedure TScreen.Capture;
  164. begin
  165. Abstract;
  166. end;
  167. procedure TScreen.SwitchToConsoleScreen;
  168. begin
  169. Abstract;
  170. end;
  171. procedure TScreen.SwitchBackToIDEScreen;
  172. begin
  173. Abstract;
  174. end;
  175. procedure TScreen.SaveIDEScreen;
  176. begin
  177. Abstract;
  178. end;
  179. function TScreen.Scroll(i : integer) : integer;
  180. begin
  181. Scroll:=0;
  182. end;
  183. procedure TScreen.SaveConsoleScreen;
  184. begin
  185. Abstract;
  186. end;
  187. {****************************************************************************
  188. TDOSScreen
  189. ****************************************************************************}
  190. {$ifdef DOS}
  191. constructor TDOSScreen.Init;
  192. begin
  193. inherited Init;
  194. Capture;
  195. { get the current ctrl-C state }
  196. Ctrl_c_state:=djgpp_set_ctrl_c(false);
  197. djgpp_set_ctrl_c(Ctrl_c_state);
  198. end;
  199. destructor TDOSScreen.Done;
  200. begin
  201. FreeBuffer;
  202. if assigned(VIDEBuffer) then
  203. FreeMem(VIDEBuffer,VIDEBufferSize);
  204. inherited Done;
  205. end;
  206. function TDOSScreen.GetWidth: integer;
  207. begin
  208. GetWidth:=ConsoleVideoInfo.Cols;
  209. end;
  210. function TDOSScreen.GetHeight: integer;
  211. begin
  212. GetHeight:=ConsoleVideoInfo.Rows;
  213. end;
  214. procedure TDOSScreen.GetLine(Line: integer; var Text, Attr: string);
  215. var X: integer;
  216. W: word;
  217. begin
  218. Text:=''; Attr:='';
  219. if Line<GetHeight then
  220. begin
  221. W:=GetLineStartOfs(Line);
  222. for X:=0 to GetWidth-1 do
  223. begin
  224. {Text:=Text+chr(VBuffer^[W+X*2]);
  225. Attr:=Attr+chr(VBuffer^[W+X*2+1]);}
  226. System.Insert(chr(VBuffer^[W+X*2]),Text,Length(Text)+1);
  227. System.Insert(chr(VBuffer^[W+X*2+1]),Attr,Length(Attr)+1);
  228. end;
  229. end;
  230. end;
  231. procedure TDOSScreen.GetCursorPos(var P: TPoint);
  232. begin
  233. P:=ConsoleVideoInfo.CurPos;
  234. end;
  235. procedure TDOSScreen.Capture;
  236. begin
  237. SaveConsoleScreen;
  238. end;
  239. procedure TDosScreen.SaveIDEScreen;
  240. var
  241. VSeg,SOfs: word;
  242. begin
  243. GetVideoMode(IDEVideoInfo);
  244. { First keep a copy of IDE screen }
  245. if ConsoleVideoInfo.Mode=7 then
  246. VSeg:=SegB000
  247. else
  248. VSeg:=SegB800;
  249. SOfs:=MemW[Seg0040:$4e];
  250. if not assigned(VIDEBuffer) or (VIDEBufferSize<>IDEVideoInfo.ScreenSize) then
  251. begin
  252. if assigned(VIDEBuffer) then
  253. FreeMem(VIDEBuffer,VIDEBufferSize);
  254. GetMem(VIDEBuffer,IDEVideoInfo.ScreenSize);
  255. VIDEBufferSize:=IDEVideoInfo.ScreenSize;
  256. end;
  257. {$ifdef FPC}
  258. DosmemGet(VSeg,SOfs,VIDEBuffer^,IDEVideoInfo.ScreenSize);
  259. {$else}
  260. Move(ptr(VSeg,SOfs)^,VIDEBuffer^,IDEVideoInfo.ScreenSize);
  261. {$endif}
  262. end;
  263. procedure TDosScreen.SaveConsoleScreen;
  264. var
  265. VSeg,SOfs: word;
  266. begin
  267. GetVideoMode(ConsoleVideoInfo);
  268. GetBuffer(ConsoleVideoInfo.ScreenSize);
  269. if ConsoleVideoInfo.Mode=7 then
  270. VSeg:=SegB000
  271. else
  272. VSeg:=SegB800;
  273. SOfs:=MemW[Seg0040:$4e];
  274. {$ifdef FPC}
  275. DosmemGet(VSeg,SOfs,VBuffer^,ConsoleVideoInfo.ScreenSize);
  276. {$else}
  277. Move(ptr(VSeg,SOfs)^,VBuffer^,ConsoleVideoInfo.ScreenSize);
  278. {$endif}
  279. end;
  280. procedure TDOSScreen.SwitchToConsoleScreen;
  281. var
  282. VSeg,SOfs: word;
  283. begin
  284. SetVideoMode(ConsoleVideoInfo);
  285. if ConsoleVideoInfo.Mode=7 then
  286. VSeg:=SegB000
  287. else
  288. VSeg:=SegB800;
  289. SOfs:=MemW[Seg0040:$4e];
  290. {$ifdef FPC}
  291. DosmemPut(VSeg,SOfs,VBuffer^,ConsoleVideoInfo.ScreenSize);
  292. djgpp_set_ctrl_c(Ctrl_c_state);
  293. {$else}
  294. Move(VBuffer^,ptr(VSeg,SOfs)^,ConsoleVideoInfo.ScreenSize);
  295. {$endif}
  296. end;
  297. procedure TDOSScreen.SwitchBackToIDEScreen;
  298. var
  299. VSeg,SOfs: word;
  300. begin
  301. SetVideoMode(IDEVideoInfo);
  302. if ConsoleVideoInfo.Mode=7 then
  303. VSeg:=SegB000
  304. else
  305. VSeg:=SegB800;
  306. SOfs:=MemW[Seg0040:$4e];
  307. if assigned(VIDEBuffer) then
  308. {$ifdef FPC}
  309. DosmemPut(VSeg,SOfs,VIDEBuffer^,IDEVideoInfo.ScreenSize);
  310. Ctrl_c_state := djgpp_set_ctrl_c(false);
  311. {$else}
  312. Move(VIDEBuffer^,ptr(VSeg,SOfs)^,IDEVideoInfo.ScreenSize);
  313. {$endif}
  314. end;
  315. function TDOSScreen.GetLineStartOfs(Line: integer): word;
  316. begin
  317. GetLineStartOfs:=(ConsoleVideoInfo.Cols*Line)*2;
  318. end;
  319. procedure TDOSScreen.GetBuffer(Size: word);
  320. begin
  321. if (VBuffer<>nil) and (VBufferSize=Size) then Exit;
  322. if VBuffer<>nil then FreeBuffer;
  323. VBufferSize:=Size;
  324. GetMem(VBuffer,VBufferSize);
  325. end;
  326. procedure TDOSScreen.FreeBuffer;
  327. begin
  328. if (VBuffer<>nil) and (VBufferSize>0) then FreeMem(VBuffer,VBufferSize);
  329. VBuffer:=nil;
  330. end;
  331. procedure TDOSScreen.GetVideoMode(var MI: TDOSVideoInfo);
  332. var
  333. r: registers;
  334. {$ifdef TP}
  335. P: pointer;
  336. Sel: longint;
  337. (* {$I realintr.inc} *)
  338. {$endif}
  339. begin
  340. if (MI.StateSize>0) and (MI.StateBuf<>nil) then
  341. begin FreeMem(MI.StateBuf,MI.StateSize); MI.StateBuf:=nil; end;
  342. MI.ScreenSize:=MemW[Seg0040:$4c];
  343. r.ah:=$0f;
  344. intr($10,r);
  345. MI.Mode:=r.al;
  346. MI.Page:=r.bh;
  347. MI.Cols:=r.ah;
  348. {$ifdef VESA}
  349. VESAGetMode(MI.Mode);
  350. {$endif}
  351. MI.Rows:=MI.ScreenSize div (MI.Cols*2);
  352. if MI.Rows=51 then MI.Rows:=50;
  353. r.ah:=$03;
  354. r.bh:=MI.Page;
  355. intr($10,r);
  356. with MI do
  357. begin
  358. CurPos.X:=r.dl; CurPos.Y:=r.dh;
  359. CurShapeT:=r.ch; CurShapeB:=r.cl;
  360. end;
  361. (*
  362. {$ifdef TP}
  363. { check VGA functions }
  364. MI.StateSize:=0;
  365. r.ah:=$1c; r.al:=0; r.cx:=7; intr($10,r);
  366. if (r.al=$1c) and ((r.flags and fCarry)=0) and (r.bx>0) then
  367. begin
  368. MI.StateSize:=r.bx;
  369. GetMem(MI.StateBuf,MI.StateSize); FillChar(MI.StateBuf^,MI.StateSize,0);
  370. P:=MI.StateBuf;
  371. {$ifdef DPMI}
  372. Sel:=GlobalDosAlloc(MI.StateSize);
  373. P:=Ptr(Sel shr 16,0);
  374. {$endif}
  375. r.ah:=$1c; r.al:=1; r.cx:=7;
  376. r.es:=PtrRec(P).Seg; r.bx:=PtrRec(P).Ofs;
  377. {$ifdef DPMI}realintr($10,r);{$else}intr($10,r);{$endif}
  378. {$ifdef DPMI}
  379. Move(Ptr(Sel and $ffff,0)^,MI.StateBuf^,MI.StateSize);
  380. GlobalDosFree(Sel and $ffff);
  381. {$endif}
  382. end;
  383. {$endif}
  384. *)
  385. end;
  386. procedure TDOSScreen.SetVideoMode(MI: TDOSVideoInfo);
  387. var r: registers;
  388. CM: TDOSVideoInfo;
  389. {$ifdef TP}
  390. P: pointer;
  391. Sel: longint;
  392. {$I realintr.inc}
  393. {$endif}
  394. begin
  395. FillChar(CM,sizeof(CM),0);
  396. GetVideoMode(CM);
  397. if (CM.Mode<>MI.Mode) or (CM.Cols<>MI.Cols) or (CM.Rows<>MI.Rows) then
  398. begin
  399. {$ifdef VESA}
  400. if MI.Mode>=$100 then
  401. VESASetMode(MI.Mode)
  402. else
  403. {$endif}
  404. begin
  405. r.ah:=$00; r.al:=MI.Mode; intr($10,r);
  406. end;
  407. if (MI.Mode=3) and (MI.Cols=80) and (MI.Rows=50) then
  408. begin
  409. r.ax:=$1112; r.bx:=$0;
  410. intr($10,r);
  411. end;
  412. end;
  413. r.ah:=$05; r.al:=MI.Page; intr($10,r);
  414. r.ah:=$02; r.bh:=MI.Page; r.dl:=MI.CurPos.X; r.dh:=MI.CurPos.Y; intr($10,r);
  415. r.ah:=$01; r.ch:=MI.CurShapeT; r.cl:=MI.CurShapeB; intr($10,r);
  416. (*
  417. {$ifdef TP}
  418. if (MI.StateSize>0) and (MI.StateBuf<>nil) then
  419. begin
  420. P:=MI.StateBuf;
  421. {$ifdef DPMI}
  422. Sel:=GlobalDosAlloc(MI.StateSize);
  423. Move(MI.StateBuf^,ptr(Sel and $ffff,0)^,MI.StateSize);
  424. P:=Ptr(Sel shr 16,0);
  425. {$endif}
  426. r.ah:=$1c; r.al:=2; r.cx:=7;
  427. r.es:=PtrRec(P).Seg; r.bx:=PtrRec(P).Ofs;
  428. {$ifdef DPMI}realintr($10,r);{$else}intr($10,r);{$endif}
  429. {$ifdef DPMI}
  430. GlobalDosFree(Sel and $ffff);
  431. {$endif}
  432. end;
  433. {$endif}
  434. *)
  435. end;
  436. {$endif}
  437. {****************************************************************************
  438. TLinuxScreen
  439. ****************************************************************************}
  440. {$ifdef Unix}
  441. constructor TLinuxScreen.Init;
  442. begin
  443. inherited Init;
  444. IDE_screen := nil;
  445. end;
  446. destructor TLinuxScreen.Done;
  447. begin
  448. inherited Done;
  449. end;
  450. function TLinuxScreen.GetWidth: integer;
  451. begin
  452. GetWidth:=ScreenWidth;
  453. end;
  454. function TLinuxScreen.GetHeight: integer;
  455. begin
  456. GetHeight:=ScreenHeight;
  457. end;
  458. procedure TLinuxScreen.GetLine(Line: integer; var Text, Attr: string);
  459. begin
  460. Text:='';
  461. Attr:='';
  462. end;
  463. procedure TLinuxScreen.GetCursorPos(var P: TPoint);
  464. begin
  465. P.X:=0;
  466. P.Y:=0;
  467. end;
  468. procedure TLinuxScreen.Capture;
  469. begin
  470. end;
  471. procedure TLinuxScreen.SaveIDEScreen;
  472. begin
  473. if assigned(IDE_screen) then
  474. dispose(IDE_screen);
  475. getmem(IDE_screen,videobufsize);
  476. Ide_size:=videobufsize;
  477. move(videobuf^,IDE_screen^,videobufsize);
  478. end;
  479. procedure TLinuxScreen.SaveConsoleScreen;
  480. begin
  481. end;
  482. procedure TLinuxScreen.SwitchToConsoleScreen;
  483. begin
  484. end;
  485. procedure TLinuxScreen.SwitchBackToIDEScreen;
  486. begin
  487. if IDE_screen = nil then
  488. exit;
  489. move(IDE_screen^,videobuf^,videobufsize);
  490. freemem(IDE_screen,Ide_size);
  491. IDE_screen := nil;
  492. end;
  493. {$endif}
  494. {****************************************************************************
  495. TWin32Screen
  496. ****************************************************************************}
  497. {$ifdef win32}
  498. constructor TWin32Screen.Init;
  499. var
  500. SecurityAttr : Security_attributes;
  501. BigWin : Coord;
  502. res : longbool;
  503. Error : dword;
  504. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  505. begin
  506. inherited Init;
  507. {if GetConsoleOutputCP<>437 then
  508. res:=SetConsoleOutputCP(437);}
  509. SecurityAttr.nLength:=SizeOf(Security_attributes);
  510. SecurityAttr.lpSecurityDescriptor:=nil;
  511. SecurityAttr.bInheritHandle:=true;
  512. DosScreenBufferHandle:=CreateConsoleScreenBuffer(
  513. GENERIC_READ or GENERIC_WRITE,
  514. 0,SecurityAttr,
  515. CONSOLE_TEXTMODE_BUFFER,nil);
  516. IDEScreenBufferHandle:=GetStdHandle(STD_OUTPUT_HANDLE);
  517. GetConsoleMode(GetStdHandle(Std_Input_Handle), @ConsoleMode);
  518. IdeMode:=ConsoleMode;
  519. {$ifdef debug}
  520. {define win32bigwin}
  521. {$endif debug}
  522. {$ifdef win32bigwin}
  523. GetConsoleScreenBufferInfo(IDEScreenBufferHandle,
  524. @ConsoleScreenBufferInfo);
  525. BigWin.X:=ConsoleScreenBufferInfo.dwSize.X;
  526. BigWin.Y:=200;
  527. { Try to allow to store more info }
  528. res:=SetConsoleScreenBufferSize(DosScreenBufferHandle,BigWin);
  529. if not res then
  530. error:=GetLastError;
  531. res:=SetConsoleScreenBufferSize(IDEScreenBufferHandle,BigWin);
  532. if not res then
  533. error:=GetLastError;
  534. {$endif win32bigwin}
  535. Capture;
  536. SwitchBackToIDEScreen;
  537. end;
  538. destructor TWin32Screen.Done;
  539. begin
  540. { copy the Dos buffer content into the original ScreenBuffer
  541. which remains the startup std_output_handle PM }
  542. BufferCopy(DosScreenBufferHandle,IDEScreenBufferHandle);
  543. SetConsoleActiveScreenBuffer(IDEScreenBufferHandle);
  544. SetStdHandle(Std_Output_Handle,IDEScreenBufferHandle);
  545. CloseHandle(DosScreenBufferHandle);
  546. inherited Done;
  547. end;
  548. function TWin32Screen.GetWidth: integer;
  549. var
  550. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  551. begin
  552. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  553. @ConsoleScreenBufferInfo);
  554. GetWidth:=ConsoleScreenBufferInfo.dwSize.X;
  555. end;
  556. function TWin32Screen.GetHeight: integer;
  557. var
  558. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  559. begin
  560. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  561. @ConsoleScreenBufferInfo);
  562. GetHeight:=ConsoleScreenBufferInfo.dwSize.Y;
  563. end;
  564. function TWin32Screen.Scroll(i : integer) : integer;
  565. var
  566. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  567. ConsoleWindow : Small_rect;
  568. begin
  569. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  570. @ConsoleScreenBufferInfo);
  571. if (ConsoleScreenBufferInfo.srWindow.Top + i >= 0) then
  572. i:= -ConsoleScreenBufferInfo.srWindow.Top;
  573. if (ConsoleScreenBufferInfo.srWindow.Bottom + i <= ConsoleScreenBufferInfo.dwSize.Y) then
  574. i:= ConsoleScreenBufferInfo.dwSize.Y - ConsoleScreenBufferInfo.srWindow.Bottom;
  575. if i<>0 then
  576. begin
  577. ConsoleWindow.Left:=ConsoleScreenBufferInfo.srWindow.Left;
  578. ConsoleWindow.Right:=ConsoleScreenBufferInfo.srWindow.Right;
  579. ConsoleWindow.Top:=ConsoleScreenBufferInfo.srWindow.Top+i;
  580. ConsoleWindow.Bottom:=ConsoleScreenBufferInfo.srWindow.Bottom+i;
  581. SetConsoleWindowInfo(DosScreenBufferHandle,true,ConsoleWindow);
  582. Scroll:=i;
  583. end
  584. else
  585. Scroll:=0;
  586. end;
  587. procedure TWin32Screen.GetLine(Line: integer; var Text, Attr: string);
  588. type
  589. CharInfoArray = Array [0..255] of Char_Info;
  590. var
  591. LineBuf : ^CharInfoArray;
  592. BufSize,BufCoord : Coord;
  593. i,LineSize : longint;
  594. WriteRegion : SMALL_RECT;
  595. begin
  596. GetMem(LineBuf,SizeOf(CharInfoArray));
  597. LineSize:=ScreenWidth;
  598. If LineSize>256 then
  599. LineSize:=256;
  600. BufSize.X:=LineSize;
  601. BufSize.Y:=1;
  602. BufCoord.X:=0;
  603. BufCoord.Y:=0;
  604. with WriteRegion do
  605. begin
  606. Top :=Line;
  607. Left :=0;
  608. Bottom := Line+1;
  609. Right := LineSize-1;
  610. end;
  611. ReadConsoleOutput(DosScreenBufferHandle, PChar_info(LineBuf),
  612. BufSize, BufCoord, @WriteRegion);
  613. for i:=1 to LineSize do
  614. begin
  615. Text[i]:=LineBuf^[i-1].AsciiChar;
  616. Attr[i]:=char(byte(LineBuf^[i-1].Attributes));
  617. end;
  618. FreeMem(LineBuf,SizeOf(CharInfoArray));
  619. Text[0]:=char(byte(LineSize));
  620. Attr[0]:=char(byte(LineSize));
  621. end;
  622. procedure TWin32Screen.GetCursorPos(var P: TPoint);
  623. var
  624. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  625. begin
  626. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  627. @ConsoleScreenBufferInfo);
  628. P.X:=ConsoleScreenBufferInfo.dwCursorPosition.X;
  629. P.Y:=ConsoleScreenBufferInfo.dwCursorPosition.Y;
  630. end;
  631. procedure TWin32Screen.BufferCopy(Src, Dest : THandle);
  632. type
  633. CharInfoArray = Array [0..256*255-1] of Char_Info;
  634. var
  635. LineBuf : ^CharInfoArray;
  636. BufSize,BufCoord : Coord;
  637. LineSize : longint;
  638. WriteRegion : SMALL_RECT;
  639. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  640. begin
  641. GetConsoleScreenBufferInfo(Src,
  642. @ConsoleScreenBufferInfo);
  643. GetMem(LineBuf,SizeOf(CharInfoArray));
  644. LineSize:=ConsoleScreenBufferInfo.dwSize.X;
  645. If LineSize>256 then
  646. LineSize:=256;
  647. BufSize.X:=LineSize;
  648. BufSize.Y:=ConsoleScreenBufferInfo.dwSize.Y;
  649. BufCoord.X:=0;
  650. BufCoord.Y:=0;
  651. with WriteRegion do
  652. begin
  653. Top :=0;
  654. Left :=0;
  655. Bottom := ConsoleScreenBufferInfo.dwSize.Y-1;
  656. Right := LineSize-1;
  657. end;
  658. ReadConsoleOutput(Src, PChar_info(LineBuf),
  659. BufSize, BufCoord, @WriteRegion);
  660. WriteConsoleOutput(Dest, PChar_info(LineBuf),
  661. BufSize, BufCoord, @WriteRegion);
  662. FreeMem(LineBuf,SizeOf(CharInfoArray));
  663. SetConsoleCursorPosition(Dest, ConsoleScreenBufferInfo.dwCursorPosition);
  664. end;
  665. procedure TWin32Screen.Capture;
  666. begin
  667. BufferCopy(IDEScreenBufferHandle,DosScreenBufferHandle);
  668. end;
  669. { dummy for win32 as the Buffer screen
  670. do hold all the info }
  671. procedure TWin32Screen.SaveIDEScreen;
  672. begin
  673. GetConsoleMode(GetStdHandle(Std_Input_Handle), @IdeMode);
  674. end;
  675. { dummy for win32 as the Buffer screen
  676. do hold all the info }
  677. procedure TWin32Screen.SaveConsoleScreen;
  678. begin
  679. GetConsoleMode(GetStdHandle(Std_Input_Handle), @ConsoleMode);
  680. end;
  681. procedure TWin32Screen.SwitchToConsoleScreen;
  682. begin
  683. SetConsoleActiveScreenBuffer(DosScreenBufferHandle);
  684. SetStdHandle(Std_Output_Handle,DosScreenBufferHandle);
  685. IDEActive:=false;
  686. SetConsoleMode(GetStdHandle(Std_Input_Handle), ConsoleMode);
  687. end;
  688. procedure TWin32Screen.SwitchBackToIDEScreen;
  689. begin
  690. SetConsoleActiveScreenBuffer(IDEScreenBufferHandle);
  691. SetStdHandle(Std_Output_Handle,IDEScreenBufferHandle);
  692. IdeMode:=IdeMode and not ENABLE_PROCESSED_INPUT;
  693. SetConsoleMode(GetStdHandle(Std_Input_Handle), IdeMode);
  694. IDEActive:=true;
  695. end;
  696. {$endif}
  697. {****************************************************************************
  698. Initialize
  699. ****************************************************************************}
  700. procedure InitUserScreen;
  701. begin
  702. {$ifdef DOS}
  703. UserScreen:=New(PDOSScreen, Init);
  704. {$else}
  705. {$ifdef Unix}
  706. UserScreen:=New(PLinuxScreen, Init);
  707. {$else}
  708. {$ifdef Win32}
  709. UserScreen:=New(PWin32Screen, Init);
  710. {$else}
  711. UserScreen:=New(PScreen, Init);
  712. {$endif Win32}
  713. {$endif Unix}
  714. {$endif Dos}
  715. end;
  716. procedure DoneUserScreen;
  717. begin
  718. if UserScreen<>nil then
  719. begin
  720. UserScreen^.SwitchToConsoleScreen;
  721. Dispose(UserScreen, Done);
  722. UserScreen:=nil;
  723. end;
  724. end;
  725. end.
  726. {
  727. $Log$
  728. Revision 1.2 2001-08-12 00:04:50 pierre
  729. * some speed improvements for string operations
  730. Revision 1.1 2001/08/04 11:30:24 peter
  731. * ide works now with both compiler versions
  732. Revision 1.1.2.10 2001/06/14 09:15:16 pierre
  733. TScreen methods reorganized:
  734. SwitchTo method renamed SwitchToConsoleScreen
  735. SwitchBack method renamed SwitchBackToIDEScreen
  736. + method Scroll added
  737. + SaveIDEScreen and SaveConsoleScreen methods added
  738. Revision 1.1.2.9 2001/04/04 08:52:01 pierre
  739. * allow inheritance for win32 DosScreenBufferHandle
  740. Revision 1.1.2.8 2001/03/16 17:45:54 pierre
  741. * free VIDEBuffer of TDosScreen
  742. Revision 1.1.2.7 2000/11/30 13:04:01 pierre
  743. * fix for bug 1205
  744. Revision 1.1.2.6 2000/11/29 00:54:45 pierre
  745. + preserve window number and save special windows
  746. Revision 1.1.2.5 2000/11/22 12:47:21 pierre
  747. * fix the screen saving at start for win32
  748. Revision 1.1.2.4 2000/11/14 09:23:56 marco
  749. * Second batch
  750. Revision 1.1.2.3 2000/10/10 21:24:56 pierre
  751. * avoid writing past IDE_screen buffer length
  752. Revision 1.1.2.2 2000/08/21 12:10:19 jonas
  753. * fixed errors in my previous commit, it now works properly
  754. Revision 1.1.2.1 2000/08/21 10:51:13 jonas
  755. * IDE screen saving/restoring implemented for Linux
  756. Revision 1.1 2000/07/13 09:48:36 michael
  757. + Initial import
  758. Revision 1.13 2000/06/16 15:00:20 pierre
  759. * accord to new WriteConsoleOuput declarations
  760. Revision 1.12 2000/04/25 08:42:33 pierre
  761. * New Gabor changes : see fixes.txt
  762. Revision 1.11 2000/04/18 11:42:37 pierre
  763. lot of Gabor changes : see fixes.txt
  764. Revision 1.10 2000/03/13 20:30:37 pierre
  765. + stores IDE screen before Switching for DOS
  766. Revision 1.9 2000/02/04 23:17:25 pierre
  767. * Keep the entry ScreenBuffer at exit
  768. Revision 1.8 1999/12/01 16:17:18 pierre
  769. * Restore std_output_handle correctly at exit for GDB
  770. Revision 1.7 1999/11/10 17:12:00 pierre
  771. * Win32 screen problems solved
  772. Revision 1.6 1999/09/22 13:02:00 pierre
  773. + Twin32Screen added
  774. Revision 1.5 1999/08/16 18:25:24 peter
  775. * Adjusting the selection when the editor didn't contain any line.
  776. * Reserved word recognition redesigned, but this didn't affect the overall
  777. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  778. The syntax scanner loop is a bit slow but the main problem is the
  779. recognition of special symbols. Switching off symbol processing boosts
  780. the performance up to ca. 200%...
  781. * The editor didn't allow copying (for ex to clipboard) of a single character
  782. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  783. * Compiler Messages window (actually the whole desktop) did not act on any
  784. keypress when compilation failed and thus the window remained visible
  785. + Message windows are now closed upon pressing Esc
  786. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  787. only when neccessary
  788. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  789. + LineSelect (Ctrl+K+L) implemented
  790. * The IDE had problems closing help windows before saving the desktop
  791. Revision 1.4 1999/06/28 19:32:25 peter
  792. * fixes from gabor
  793. Revision 1.3 1999/02/02 16:41:42 peter
  794. + automatic .pas/.pp adding by opening of file
  795. * better debuggerscreen changes
  796. Revision 1.2 1999/01/04 11:49:51 peter
  797. * 'Use tab characters' now works correctly
  798. + Syntax highlight now acts on File|Save As...
  799. + Added a new class to syntax highlight: 'hex numbers'.
  800. * There was something very wrong with the palette managment. Now fixed.
  801. + Added output directory (-FE<xxx>) support to 'Directories' dialog...
  802. * Fixed some possible bugs in Running/Compiling, and the compilation/run
  803. process revised
  804. Revision 1.1 1998/12/28 15:47:53 peter
  805. + Added user screen support, display & window
  806. + Implemented Editor,Mouse Options dialog
  807. + Added location of .INI and .CFG file
  808. + Option (INI) file managment implemented (see bottom of Options Menu)
  809. + Switches updated
  810. + Run program
  811. Revision 1.0 1998/12/24 09:55:49 gabor
  812. Original implementation
  813. }