fpusrscr.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  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. FILE_SHARE_READ or FILE_SHARE_WRITE,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. { make sure that both Screen Handle have the sme buffer }
  536. GetConsoleScreenBufferInfo(IDEScreenBufferHandle,
  537. @ConsoleScreenBufferInfo);
  538. res:=SetConsoleScreenBufferSize(DosScreenBufferHandle,
  539. ConsoleScreenBufferInfo.dwSize);
  540. if not res then
  541. error:=GetLastError;
  542. Capture;
  543. SwitchBackToIDEScreen;
  544. end;
  545. destructor TWin32Screen.Done;
  546. begin
  547. { copy the Dos buffer content into the original ScreenBuffer
  548. which remains the startup std_output_handle PM }
  549. BufferCopy(DosScreenBufferHandle,IDEScreenBufferHandle);
  550. SetConsoleActiveScreenBuffer(IDEScreenBufferHandle);
  551. SetStdHandle(Std_Output_Handle,IDEScreenBufferHandle);
  552. CloseHandle(DosScreenBufferHandle);
  553. inherited Done;
  554. end;
  555. function TWin32Screen.GetWidth: integer;
  556. var
  557. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  558. begin
  559. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  560. @ConsoleScreenBufferInfo);
  561. GetWidth:=ConsoleScreenBufferInfo.dwSize.X;
  562. end;
  563. function TWin32Screen.GetHeight: integer;
  564. var
  565. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  566. begin
  567. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  568. @ConsoleScreenBufferInfo);
  569. GetHeight:=ConsoleScreenBufferInfo.dwSize.Y;
  570. end;
  571. function TWin32Screen.Scroll(i : integer) : integer;
  572. var
  573. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  574. ConsoleWindow : Small_rect;
  575. begin
  576. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  577. @ConsoleScreenBufferInfo);
  578. if (ConsoleScreenBufferInfo.srWindow.Top + i < 0) then
  579. i:= -ConsoleScreenBufferInfo.srWindow.Top;
  580. if (ConsoleScreenBufferInfo.srWindow.Bottom + i > ConsoleScreenBufferInfo.dwSize.Y) then
  581. i:= ConsoleScreenBufferInfo.dwSize.Y - ConsoleScreenBufferInfo.srWindow.Bottom;
  582. if i<>0 then
  583. begin
  584. ConsoleWindow.Left:=ConsoleScreenBufferInfo.srWindow.Left;
  585. ConsoleWindow.Right:=ConsoleScreenBufferInfo.srWindow.Right;
  586. ConsoleWindow.Top:=ConsoleScreenBufferInfo.srWindow.Top+i;
  587. ConsoleWindow.Bottom:=ConsoleScreenBufferInfo.srWindow.Bottom+i;
  588. SetConsoleWindowInfo(DosScreenBufferHandle,true,ConsoleWindow);
  589. Scroll:=i;
  590. end
  591. else
  592. Scroll:=0;
  593. end;
  594. procedure TWin32Screen.GetLine(Line: integer; var Text, Attr: string);
  595. type
  596. CharInfoArray = Array [0..255] of Char_Info;
  597. var
  598. LineBuf : ^CharInfoArray;
  599. BufSize,BufCoord : Coord;
  600. i,LineSize : longint;
  601. WriteRegion : SMALL_RECT;
  602. begin
  603. GetMem(LineBuf,SizeOf(CharInfoArray));
  604. LineSize:=ScreenWidth;
  605. If LineSize>256 then
  606. LineSize:=256;
  607. BufSize.X:=LineSize;
  608. BufSize.Y:=1;
  609. BufCoord.X:=0;
  610. BufCoord.Y:=0;
  611. with WriteRegion do
  612. begin
  613. Top :=Line;
  614. Left :=0;
  615. Bottom := Line+1;
  616. Right := LineSize-1;
  617. end;
  618. ReadConsoleOutput(DosScreenBufferHandle, PChar_info(LineBuf),
  619. BufSize, BufCoord, @WriteRegion);
  620. for i:=1 to LineSize do
  621. begin
  622. Text[i]:=LineBuf^[i-1].AsciiChar;
  623. Attr[i]:=char(byte(LineBuf^[i-1].Attributes));
  624. end;
  625. FreeMem(LineBuf,SizeOf(CharInfoArray));
  626. Text[0]:=char(byte(LineSize));
  627. Attr[0]:=char(byte(LineSize));
  628. end;
  629. procedure TWin32Screen.GetCursorPos(var P: TPoint);
  630. var
  631. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  632. begin
  633. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  634. @ConsoleScreenBufferInfo);
  635. P.X:=ConsoleScreenBufferInfo.dwCursorPosition.X;
  636. P.Y:=ConsoleScreenBufferInfo.dwCursorPosition.Y;
  637. end;
  638. procedure TWin32Screen.BufferCopy(Src, Dest : THandle);
  639. type
  640. CharInfoArray = Array [0..256*255-1] of Char_Info;
  641. var
  642. LineBuf : ^CharInfoArray;
  643. BufSize,BufCoord : Coord;
  644. Error, LineSize,
  645. Part, OnePartY: longint;
  646. res : boolean;
  647. WriteRegion : SMALL_RECT;
  648. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  649. DestConsoleScreenBufferInfo : Console_screen_buffer_info;
  650. begin
  651. GetConsoleScreenBufferInfo(Src,
  652. @ConsoleScreenBufferInfo);
  653. GetConsoleScreenBufferInfo(Dest,
  654. @DestConsoleScreenBufferInfo);
  655. GetMem(LineBuf,SizeOf(CharInfoArray));
  656. FillChar(LineBuf^,SizeOf(CharInfoArray),#0);
  657. LineSize:=ConsoleScreenBufferInfo.dwSize.X;
  658. If LineSize>256 then
  659. LineSize:=256;
  660. BufSize.X:=LineSize;
  661. BufSize.Y:=ConsoleScreenBufferInfo.dwSize.Y;
  662. BufCoord.X:=0;
  663. BufCoord.Y:=0;
  664. with WriteRegion do
  665. begin
  666. Top :=0;
  667. Left :=0;
  668. Bottom := ConsoleScreenBufferInfo.dwSize.Y-1;
  669. Right := LineSize-1;
  670. end;
  671. if BufSize.X*BufSize.Y*Sizeof(CHAR_INFO) >= $8000 then
  672. begin
  673. OnePartY := ($8000 -1) div (BufSize.X * SizeOf(Char_Info) );
  674. BufSize.Y:=OnePartY;
  675. Part:=0;
  676. while ((Part+1)*OnePartY < ConsoleScreenBufferInfo.dwSize.Y) do
  677. begin
  678. WriteRegion.Top := Part*OnePartY;
  679. WriteRegion.Bottom := (Part+1)*OnePartY-1;
  680. res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
  681. BufSize, BufCoord, @WriteRegion);
  682. if not res then
  683. Error:=GetLastError;
  684. res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
  685. BufSize, BufCoord, @WriteRegion);
  686. if not res then
  687. Error:=GetLastError;
  688. Inc(Part);
  689. end;
  690. BufSize.Y:=ConsoleScreenBufferInfo.dwSize.Y - Part*OnePartY;
  691. WriteRegion.Top := Part*OnePartY;
  692. WriteRegion.Bottom := ConsoleScreenBufferInfo.dwSize.Y-1;
  693. res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
  694. BufSize, BufCoord, @WriteRegion);
  695. if not res then
  696. Error:=GetLastError;
  697. res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
  698. BufSize, BufCoord, @WriteRegion);
  699. if not res then
  700. Error:=GetLastError;
  701. end
  702. else
  703. begin
  704. res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
  705. BufSize, BufCoord, @WriteRegion);
  706. if not res then
  707. Error:=GetLastError;
  708. res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
  709. BufSize, BufCoord, @WriteRegion);
  710. if not res then
  711. Error:=GetLastError;
  712. end;
  713. FreeMem(LineBuf,SizeOf(CharInfoArray));
  714. SetConsoleCursorPosition(Dest, ConsoleScreenBufferInfo.dwCursorPosition);
  715. end;
  716. procedure TWin32Screen.Capture;
  717. begin
  718. BufferCopy(IDEScreenBufferHandle,DosScreenBufferHandle);
  719. end;
  720. { dummy for win32 as the Buffer screen
  721. do hold all the info }
  722. procedure TWin32Screen.SaveIDEScreen;
  723. begin
  724. GetConsoleMode(GetStdHandle(Std_Input_Handle), @IdeMode);
  725. end;
  726. { dummy for win32 as the Buffer screen
  727. do hold all the info }
  728. procedure TWin32Screen.SaveConsoleScreen;
  729. begin
  730. GetConsoleMode(GetStdHandle(Std_Input_Handle), @ConsoleMode);
  731. end;
  732. procedure TWin32Screen.SwitchToConsoleScreen;
  733. begin
  734. SetConsoleActiveScreenBuffer(DosScreenBufferHandle);
  735. SetStdHandle(Std_Output_Handle,DosScreenBufferHandle);
  736. IDEActive:=false;
  737. SetConsoleMode(GetStdHandle(Std_Input_Handle), ConsoleMode);
  738. end;
  739. procedure TWin32Screen.SwitchBackToIDEScreen;
  740. var
  741. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  742. WindowPos : Small_rect;
  743. res : boolean;
  744. error : longint;
  745. begin
  746. GetConsoleScreenBufferInfo(IDEScreenBufferHandle,
  747. @ConsoleScreenBufferInfo);
  748. SetConsoleActiveScreenBuffer(IDEScreenBufferHandle);
  749. SetStdHandle(Std_Output_Handle,IDEScreenBufferHandle);
  750. IdeMode:=(IdeMode or ENABLE_MOUSE_INPUT) and not ENABLE_PROCESSED_INPUT;
  751. SetConsoleMode(GetStdHandle(Std_Input_Handle), IdeMode);
  752. WindowPos.left:=0;
  753. WindowPos.right:=ConsoleScreenBufferInfo.srWindow.right
  754. -ConsoleScreenBufferInfo.srWindow.left;
  755. WindowPos.top:=0;
  756. WindowPos.bottom:=ConsoleScreenBufferInfo.srWindow.bottom
  757. -ConsoleScreenBufferInfo.srWindow.top;
  758. with ConsoleScreenBufferInfo.dwMaximumWindowSize do
  759. begin
  760. if WindowPos.Right<X-1 then
  761. WindowPos.right:=X-1;
  762. if WindowPos.Bottom<Y-1 then
  763. WindowPos.Bottom:=Y-1;
  764. end;
  765. res:=SetConsoleWindowInfo(IDEScreenBufferHandle,true,WindowPos);
  766. if not res then
  767. error:=GetLastError;
  768. IDEActive:=true;
  769. end;
  770. {$endif}
  771. {****************************************************************************
  772. Initialize
  773. ****************************************************************************}
  774. procedure InitUserScreen;
  775. begin
  776. {$ifdef DOS}
  777. UserScreen:=New(PDOSScreen, Init);
  778. {$else}
  779. {$ifdef Unix}
  780. UserScreen:=New(PLinuxScreen, Init);
  781. {$else}
  782. {$ifdef Win32}
  783. UserScreen:=New(PWin32Screen, Init);
  784. {$else}
  785. UserScreen:=New(PScreen, Init);
  786. {$endif Win32}
  787. {$endif Unix}
  788. {$endif Dos}
  789. end;
  790. procedure DoneUserScreen;
  791. begin
  792. if UserScreen<>nil then
  793. begin
  794. UserScreen^.SwitchToConsoleScreen;
  795. Dispose(UserScreen, Done);
  796. UserScreen:=nil;
  797. end;
  798. end;
  799. end.
  800. {
  801. $Log$
  802. Revision 1.7 2001-11-08 17:06:22 pierre
  803. * impose the correct size for win32 console window
  804. Revision 1.6 2001/11/08 16:38:25 pierre
  805. * fix win32 scrolling
  806. + always go back to 0,0 position in IDE mode
  807. Revision 1.5 2001/11/08 16:07:41 pierre
  808. * overcome buffer win32 problem due to a bug in ReadConsoleOutput
  809. Revision 1.4 2001/10/24 14:17:27 pierre
  810. * try to fix the Win2000 mouse problem
  811. Revision 1.3 2001/09/09 20:44:53 carl
  812. * bugfix of console sharing mode (on NT this would bug all
  813. std_input access).
  814. Revision 1.2 2001/08/12 00:04:50 pierre
  815. * some speed improvements for string operations
  816. Revision 1.1 2001/08/04 11:30:24 peter
  817. * ide works now with both compiler versions
  818. Revision 1.1.2.10 2001/06/14 09:15:16 pierre
  819. TScreen methods reorganized:
  820. SwitchTo method renamed SwitchToConsoleScreen
  821. SwitchBack method renamed SwitchBackToIDEScreen
  822. + method Scroll added
  823. + SaveIDEScreen and SaveConsoleScreen methods added
  824. Revision 1.1.2.9 2001/04/04 08:52:01 pierre
  825. * allow inheritance for win32 DosScreenBufferHandle
  826. Revision 1.1.2.8 2001/03/16 17:45:54 pierre
  827. * free VIDEBuffer of TDosScreen
  828. Revision 1.1.2.7 2000/11/30 13:04:01 pierre
  829. * fix for bug 1205
  830. Revision 1.1.2.6 2000/11/29 00:54:45 pierre
  831. + preserve window number and save special windows
  832. Revision 1.1.2.5 2000/11/22 12:47:21 pierre
  833. * fix the screen saving at start for win32
  834. Revision 1.1.2.4 2000/11/14 09:23:56 marco
  835. * Second batch
  836. Revision 1.1.2.3 2000/10/10 21:24:56 pierre
  837. * avoid writing past IDE_screen buffer length
  838. Revision 1.1.2.2 2000/08/21 12:10:19 jonas
  839. * fixed errors in my previous commit, it now works properly
  840. Revision 1.1.2.1 2000/08/21 10:51:13 jonas
  841. * IDE screen saving/restoring implemented for Linux
  842. Revision 1.1 2000/07/13 09:48:36 michael
  843. + Initial import
  844. Revision 1.13 2000/06/16 15:00:20 pierre
  845. * accord to new WriteConsoleOuput declarations
  846. Revision 1.12 2000/04/25 08:42:33 pierre
  847. * New Gabor changes : see fixes.txt
  848. Revision 1.11 2000/04/18 11:42:37 pierre
  849. lot of Gabor changes : see fixes.txt
  850. Revision 1.10 2000/03/13 20:30:37 pierre
  851. + stores IDE screen before Switching for DOS
  852. Revision 1.9 2000/02/04 23:17:25 pierre
  853. * Keep the entry ScreenBuffer at exit
  854. Revision 1.8 1999/12/01 16:17:18 pierre
  855. * Restore std_output_handle correctly at exit for GDB
  856. Revision 1.7 1999/11/10 17:12:00 pierre
  857. * Win32 screen problems solved
  858. Revision 1.6 1999/09/22 13:02:00 pierre
  859. + Twin32Screen added
  860. Revision 1.5 1999/08/16 18:25:24 peter
  861. * Adjusting the selection when the editor didn't contain any line.
  862. * Reserved word recognition redesigned, but this didn't affect the overall
  863. syntax highlight speed remarkably (at least not on my Amd-K6/350).
  864. The syntax scanner loop is a bit slow but the main problem is the
  865. recognition of special symbols. Switching off symbol processing boosts
  866. the performance up to ca. 200%...
  867. * The editor didn't allow copying (for ex to clipboard) of a single character
  868. * 'File|Save as' caused permanently run-time error 3. Not any more now...
  869. * Compiler Messages window (actually the whole desktop) did not act on any
  870. keypress when compilation failed and thus the window remained visible
  871. + Message windows are now closed upon pressing Esc
  872. + At 'Run' the IDE checks whether any sources are modified, and recompiles
  873. only when neccessary
  874. + BlockRead and BlockWrite (Ctrl+K+R/W) implemented in TCodeEditor
  875. + LineSelect (Ctrl+K+L) implemented
  876. * The IDE had problems closing help windows before saving the desktop
  877. Revision 1.4 1999/06/28 19:32:25 peter
  878. * fixes from gabor
  879. Revision 1.3 1999/02/02 16:41:42 peter
  880. + automatic .pas/.pp adding by opening of file
  881. * better debuggerscreen changes
  882. Revision 1.2 1999/01/04 11:49:51 peter
  883. * 'Use tab characters' now works correctly
  884. + Syntax highlight now acts on File|Save As...
  885. + Added a new class to syntax highlight: 'hex numbers'.
  886. * There was something very wrong with the palette managment. Now fixed.
  887. + Added output directory (-FE<xxx>) support to 'Directories' dialog...
  888. * Fixed some possible bugs in Running/Compiling, and the compilation/run
  889. process revised
  890. Revision 1.1 1998/12/28 15:47:53 peter
  891. + Added user screen support, display & window
  892. + Implemented Editor,Mouse Options dialog
  893. + Added location of .INI and .CFG file
  894. + Option (INI) file managment implemented (see bottom of Options Menu)
  895. + Switches updated
  896. + Run program
  897. Revision 1.0 1998/12/24 09:55:49 gabor
  898. Original implementation
  899. }