fpusrscr.pas 29 KB

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