fpusrscr.pas 24 KB

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