fpusrscr.pas 30 KB

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