fpusrscr.pas 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486
  1. {
  2. This file is part of the Free Pascal Integrated Development Environment
  3. Copyright (c) 1998 by Berczi Gabor
  4. User screen support routines
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$i globdir.inc}
  12. unit FPUsrScr;
  13. interface
  14. uses
  15. {$ifdef Windows}
  16. windows,
  17. {$endif Windows}
  18. {$ifdef Unix}
  19. baseunix,
  20. termio,
  21. {$endif}
  22. video,Objects;
  23. type
  24. PScreen = ^TScreen;
  25. TScreen = object(TObject)
  26. function GetWidth: integer; virtual;
  27. function GetHeight: integer; virtual;
  28. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  29. procedure GetCursorPos(var P: TPoint); virtual;
  30. { remember the initial video screen }
  31. procedure Capture; virtual;
  32. { restore the initial video mode }
  33. procedure Restore; virtual;
  34. { move up or down if supported by OS }
  35. function Scroll(i : integer) : integer; virtual;
  36. { is moving supported by OS }
  37. function CanScroll : boolean; virtual;
  38. { saves the current IDE screen }
  39. procedure SaveIDEScreen; virtual;
  40. { saves the current console screen }
  41. procedure SaveConsoleScreen; virtual;
  42. { restores the saved console screen }
  43. procedure SwitchToConsoleScreen; virtual;
  44. { restores the saved IDE screen }
  45. procedure SwitchBackToIDEScreen; virtual;
  46. end;
  47. {$IFDEF netwlibc}
  48. PNWLScreen = ^TNWLScreen;
  49. TNWLScreen = object(TScreen)
  50. function GetWidth: integer; virtual;
  51. function GetHeight: integer; virtual;
  52. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  53. procedure GetCursorPos(var P: TPoint); virtual;
  54. { remember the initial video screen }
  55. procedure Capture; virtual;
  56. { restore the initial video mode }
  57. procedure Restore; virtual;
  58. { saves the current IDE screen }
  59. procedure SaveIDEScreen; virtual;
  60. { saves the current console screen }
  61. procedure SaveConsoleScreen; virtual;
  62. { restores the saved console screen }
  63. procedure SwitchToConsoleScreen; virtual;
  64. { restores the saved IDE screen }
  65. procedure SwitchBackToIDEScreen; virtual;
  66. end;
  67. {$ENDIF}
  68. {$IFDEF OS2}
  69. POS2Screen = ^TOS2Screen;
  70. TOS2Screen = object(TScreen)
  71. constructor Init;
  72. destructor Done; virtual;
  73. public
  74. function GetWidth: integer; virtual;
  75. function GetHeight: integer; virtual;
  76. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  77. procedure GetCursorPos(var P: TPoint); virtual;
  78. { remember the initial video screen }
  79. procedure Capture; virtual;
  80. { restore the initial video mode }
  81. procedure Restore; virtual;
  82. { move up or down if supported by OS }
  83. function Scroll(i : integer) : integer; virtual;
  84. { saves the current IDE screen }
  85. procedure SaveIDEScreen; virtual;
  86. { saves the current console screen }
  87. procedure SaveConsoleScreen; virtual;
  88. { restores the saved console screen }
  89. procedure SwitchToConsoleScreen; virtual;
  90. { restores the saved IDE screen }
  91. procedure SwitchBackToIDEScreen; virtual;
  92. end;
  93. {$ENDIF}
  94. {$ifdef DOS}
  95. TDOSVideoInfo = record
  96. Mode : word;
  97. ScreenSize: word;
  98. Page : byte;
  99. Rows,Cols : integer;
  100. CurPos : TPoint;
  101. CurShapeT : integer;
  102. CurShapeB : integer;
  103. StateSize : word;
  104. StateBuf : pointer;
  105. end;
  106. PDOSScreen = ^TDOSScreen;
  107. TDOSScreen = object(TScreen)
  108. constructor Init;
  109. destructor Done; virtual;
  110. public
  111. function GetWidth: integer; virtual;
  112. function GetHeight: integer; virtual;
  113. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  114. procedure GetCursorPos(var P: TPoint); virtual;
  115. procedure Capture; virtual;
  116. procedure Restore; virtual;
  117. procedure SaveIDEScreen; virtual;
  118. procedure SaveConsoleScreen; virtual;
  119. procedure SwitchToConsoleScreen; virtual;
  120. procedure SwitchBackToIDEScreen; virtual;
  121. procedure FreeGraphBuffer;
  122. private
  123. LastTextConsoleVideoInfo,
  124. ConsoleVideoInfo : TDOSVideoInfo;
  125. VBufferSize : longint;
  126. VIDEBufferSize : longint;
  127. VBuffer : PByteArray;
  128. VIDEBuffer : PByteArray;
  129. IDEVideoInfo : TDOSVideoInfo;
  130. ctrl_c_state : boolean;
  131. {$ifdef USE_GRAPH_SWITCH}
  132. GraphImageSize : longint;
  133. GraphDriverName,
  134. GraphModeName : string;
  135. GraphXres,GraphYres : longint;
  136. GraphBuffer : pointer;
  137. ConsoleGraphDriver, ConsoleGraphMode : word;
  138. {$endif USE_GRAPH_SWITCH}
  139. function GetLineStartOfs(Line: integer): word;
  140. procedure GetBuffer(Size: word);
  141. procedure FreeBuffer;
  142. procedure GetVideoMode(var MI: TDOSVideoInfo);
  143. procedure SetVideoMode(MI: TDOSVideoInfo);
  144. end;
  145. {$endif}
  146. {$ifdef Unix}
  147. TConsoleType = (ttyNetwork,ttyLinux,ttyFreeBSD,ttyNetBSD);
  148. PLinuxScreen = ^TLinuxScreen;
  149. TLinuxScreen = object(TScreen)
  150. constructor Init;
  151. destructor Done; virtual;
  152. public
  153. function GetWidth: integer; virtual;
  154. function GetHeight: integer; virtual;
  155. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  156. procedure GetCursorPos(var P: TPoint); virtual;
  157. procedure Capture; virtual;
  158. procedure Restore; virtual;
  159. procedure SaveIDEScreen; virtual;
  160. procedure SaveConsoleScreen; virtual;
  161. procedure SwitchToConsoleScreen; virtual;
  162. procedure SwitchBackToIDEScreen; virtual;
  163. private
  164. IdeScreen: PByteArray;
  165. IdeSize : longint;
  166. IsXterm : boolean;
  167. Console : TConsoleType;
  168. TTyfd : longint;
  169. ConsVideoBuf : PByteArray;
  170. ConsHeight, ConsWidth,
  171. ConsCursorX, ConsCursorY : byte;
  172. ConsVideoBufSize : longint;
  173. ConsTio : termios;
  174. ConsTioValid : boolean;
  175. end;
  176. {$endif}
  177. {$ifdef Windows}
  178. PWindowsScreen = ^TWindowsScreen;
  179. TWindowsScreen = object(TScreen)
  180. constructor Init;
  181. destructor Done; virtual;
  182. public
  183. function GetWidth: integer; virtual;
  184. function GetHeight: integer; virtual;
  185. procedure GetLine(Line: integer; var Text, Attr: string); virtual;
  186. procedure GetCursorPos(var P: TPoint); virtual;
  187. function CanScroll : boolean; virtual;
  188. function Scroll(i : integer) : integer; virtual;
  189. procedure Capture; virtual;
  190. procedure Restore; virtual;
  191. procedure SaveIDEScreen; virtual;
  192. procedure SaveConsoleScreen; virtual;
  193. procedure SwitchToConsoleScreen; virtual;
  194. procedure SwitchBackToIDEScreen; virtual;
  195. private
  196. DosScreenBufferHandle,
  197. IDEScreenBufferHandle,
  198. StartScreenBufferHandle,
  199. DummyScreenBufferHandle,
  200. NewScreenBufferHandle : THandle;
  201. IDEActive : boolean;
  202. ConsoleMode,IdeMode : Dword;
  203. IdeScreenMode : TVideoMode;
  204. procedure BufferCopy(src,dest : THandle);
  205. {$ifdef debug}
  206. procedure Complain(St : string);
  207. Procedure SetConsoleMode(FH : Handle;Mode : DWord);
  208. {$endif debug}
  209. end;
  210. {$endif}
  211. procedure InitUserScreen;
  212. procedure DoneUserScreen;
  213. const UserScreen : PScreen = nil;
  214. implementation
  215. uses
  216. Dos,WUtils
  217. {$ifdef GO32V2}
  218. ,Dpmiexcp, Go32
  219. {$endif}
  220. ,Drivers,App
  221. {$ifdef USE_GRAPH_SWITCH}
  222. ,Graph,VESA
  223. {$else not USE_GRAPH_SWITCH}
  224. {$ifdef VESA}
  225. ,VESA
  226. {$endif VESA}
  227. {$endif not USE_GRAPH_SWITCH}
  228. ;
  229. function TScreen.GetWidth: integer;
  230. begin
  231. Getwidth:=0;
  232. Abstract;
  233. end;
  234. function TScreen.GetHeight: integer;
  235. begin
  236. Getheight:=0;
  237. Abstract;
  238. end;
  239. procedure TScreen.GetLine(Line: integer; var Text, Attr: string);
  240. begin
  241. Abstract;
  242. end;
  243. procedure TScreen.GetCursorPos(var P: TPoint);
  244. begin
  245. Abstract;
  246. end;
  247. procedure TScreen.Capture;
  248. begin
  249. Abstract;
  250. end;
  251. procedure TScreen.Restore;
  252. begin
  253. Abstract;
  254. end;
  255. procedure TScreen.SwitchToConsoleScreen;
  256. begin
  257. Abstract;
  258. end;
  259. procedure TScreen.SwitchBackToIDEScreen;
  260. begin
  261. Abstract;
  262. end;
  263. procedure TScreen.SaveIDEScreen;
  264. begin
  265. Abstract;
  266. end;
  267. function TScreen.Scroll(i : integer) : integer;
  268. begin
  269. Scroll:=0;
  270. end;
  271. function TScreen.CanScroll : boolean;
  272. begin
  273. CanScroll:=false;
  274. end;
  275. procedure TScreen.SaveConsoleScreen;
  276. begin
  277. Abstract;
  278. end;
  279. {****************************************************************************
  280. TDOSScreen
  281. ****************************************************************************}
  282. {$ifdef DOS}
  283. constructor TDOSScreen.Init;
  284. begin
  285. inherited Init;
  286. FillChar(LastTextConsoleVideoInfo,Sizeof(TDOSVideoInfo),#0);
  287. Capture;
  288. { get the current ctrl-C state }
  289. Ctrl_c_state:=djgpp_set_ctrl_c(false);
  290. djgpp_set_ctrl_c(Ctrl_c_state);
  291. end;
  292. destructor TDOSScreen.Done;
  293. begin
  294. FreeBuffer;
  295. if assigned(VIDEBuffer) then
  296. FreeMem(VIDEBuffer,VIDEBufferSize);
  297. inherited Done;
  298. end;
  299. function TDOSScreen.GetWidth: integer;
  300. begin
  301. GetWidth:=ConsoleVideoInfo.Cols;
  302. end;
  303. function TDOSScreen.GetHeight: integer;
  304. begin
  305. GetHeight:=ConsoleVideoInfo.Rows;
  306. end;
  307. procedure TDOSScreen.GetLine(Line: integer; var Text, Attr: string);
  308. var
  309. X: integer;
  310. W: word;
  311. begin
  312. Text:=''; Attr:='';
  313. if (Line<GetHeight) and
  314. {$ifdef USE_GRAPH_SWITCH}
  315. not assigned(GraphBuffer) and
  316. {$endif USE_GRAPH_SWITCH}
  317. assigned(VBuffer) then
  318. begin
  319. W:=GetLineStartOfs(Line);
  320. for X:=0 to GetWidth-1 do
  321. begin
  322. {Text:=Text+chr(VBuffer^[W+X*2]);
  323. Attr:=Attr+chr(VBuffer^[W+X*2+1]);}
  324. System.Insert(chr(VBuffer^[W+X*2]),Text,Length(Text)+1);
  325. System.Insert(chr(VBuffer^[W+X*2+1]),Attr,Length(Attr)+1);
  326. end;
  327. {$ifdef USE_GRAPH_SWITCH}
  328. end
  329. else if assigned(GraphBuffer) then
  330. begin
  331. if (Line=0) then
  332. Text:='Console in graph mode, use Alt+F5'
  333. else if (Line=1) then
  334. Text:='Graph driver: '+GraphDriverName
  335. else if (Line=2) then
  336. Text:='Graph mode: '+GraphModeName+' ('+
  337. IntToStr(GraphXres+1)+'x'+IntToStr(GraphYres+1)+')';
  338. Attr:=CharStr(chr($0F),Length(Text));
  339. end;
  340. {$else not USE_GRAPH_SWITCH}
  341. end;
  342. {$endif USE_GRAPH_SWITCH}
  343. end;
  344. procedure TDOSScreen.GetCursorPos(var P: TPoint);
  345. begin
  346. P:=ConsoleVideoInfo.CurPos;
  347. end;
  348. procedure TDOSScreen.Capture;
  349. begin
  350. SaveConsoleScreen;
  351. end;
  352. procedure TDOSScreen.FreeGraphBuffer;
  353. begin
  354. { We don't want to restore the last user screen if
  355. it was a grpahic screen, for example if we
  356. leave in the middle of the debugging of a
  357. graphic program, so we first
  358. dispose the graphic buffer, thus
  359. SwitchToConsoleScreen will restore the
  360. last used text mode }
  361. if LastTextConsoleVideoInfo.Mode<>0 then
  362. begin
  363. ConsoleVideoInfo:=LastTextConsoleVideoInfo;
  364. {$ifdef USE_GRAPH_SWITCH}
  365. if assigned(GraphBuffer) then
  366. begin
  367. FreeMem(GraphBuffer,GraphImageSize);
  368. GraphBuffer:=nil;
  369. GraphImageSize:=0;
  370. end;
  371. {$endif USE_GRAPH_SWITCH}
  372. end;
  373. end;
  374. procedure TDosScreen.Restore;
  375. begin
  376. FreeGraphBuffer;
  377. SwitchToConsoleScreen;
  378. end;
  379. procedure TDosScreen.SaveIDEScreen;
  380. var
  381. VSeg,SOfs: word;
  382. begin
  383. GetVideoMode(IDEVideoInfo);
  384. { First keep a copy of IDE screen }
  385. if ConsoleVideoInfo.Mode=7 then
  386. VSeg:=SegB000
  387. else
  388. VSeg:=SegB800;
  389. SOfs:=MemW[Seg0040:$4e];
  390. if not assigned(VIDEBuffer) or (VIDEBufferSize<>IDEVideoInfo.ScreenSize) then
  391. begin
  392. if assigned(VIDEBuffer) then
  393. FreeMem(VIDEBuffer,VIDEBufferSize);
  394. GetMem(VIDEBuffer,IDEVideoInfo.ScreenSize);
  395. VIDEBufferSize:=IDEVideoInfo.ScreenSize;
  396. end;
  397. DosmemGet(VSeg,SOfs,VIDEBuffer^,IDEVideoInfo.ScreenSize);
  398. end;
  399. procedure TDosScreen.SaveConsoleScreen;
  400. var
  401. VSeg,SOfs: word;
  402. {$ifdef USE_GRAPH_SWITCH}
  403. saved : boolean;
  404. GraphDriver,GraphMode : integer;
  405. {$endif USE_GRAPH_SWITCH}
  406. begin
  407. GetVideoMode(ConsoleVideoInfo);
  408. {$ifdef USE_GRAPH_SWITCH}
  409. saved:=false;
  410. if assigned(GraphBuffer) then
  411. begin
  412. FreeMem(GraphBuffer,GraphImageSize);
  413. GraphBuffer:=nil;
  414. GraphImageSize:=0;
  415. end;
  416. if (ConsoleVideoInfo.Mode>= $100) or
  417. (ConsoleVideoInfo.Mode=$13) or
  418. (ConsoleVideoInfo.Mode=$12) or
  419. (ConsoleVideoInfo.Mode=$10) or
  420. (ConsoleVideoInfo.Mode=$E) then
  421. begin
  422. if VesaSetMode(ConsoleVideoInfo.Mode or $8000) then
  423. begin
  424. Graph.DontClearGraphMemory:=true;
  425. if ConsoleVideoInfo.Mode>=$100 then
  426. begin
  427. GraphDriver:=Graph.Vesa;
  428. GraphMode:=ConsoleVideoInfo.Mode and $fff;
  429. end
  430. else
  431. begin
  432. GraphDriver:=Graph.VGA;
  433. case ConsoleVideoInfo.Mode of
  434. $E : GraphMode:=VGALo;
  435. $10 : GraphMode:=VGAMed;
  436. $12 : GraphMode:=VGAHi;
  437. $13 : begin
  438. GraphDriver:=Graph.LowRes;
  439. GraphMode:=0;
  440. end;
  441. end;
  442. end;
  443. Graph.InitGraph(GraphDriver,GraphMode,'');
  444. if graphresult=grOk then
  445. begin
  446. ConsoleGraphDriver:=GraphDriver;
  447. GraphDriverName:=GetDriverName;
  448. GraphModeName:=GetModeName(GraphMode);
  449. ConsoleGraphMode:=GraphMode;
  450. Graph.DontClearGraphMemory:=false;
  451. GraphXres:=Graph.GetmaxX;
  452. GraphYres:=Graph.GetmaxY;
  453. GraphImageSize:=ImageSize(0,0,GraphXres,GraphYres);
  454. GetMem(GraphBuffer,GraphImageSize);
  455. FillChar(GraphBuffer^,GraphImageSize,#0);
  456. GetImage(0,0,GraphXres,GraphYres,GraphBuffer^);
  457. ConsoleVideoInfo.Rows:=GraphYres div 8;
  458. ConsoleVideoInfo.Cols:=GraphXres div 8;
  459. {FreeBuffer;}
  460. saved:=true;
  461. end
  462. {$ifdef DEBUG}
  463. else
  464. Writeln(stderr,'Error in InitGraph ',Graphdriver, ' ',Graphmode)
  465. {$endif DEBUG}
  466. ;
  467. end;
  468. end;
  469. { mode < $100 so use standard Save code }
  470. if not saved then
  471. {$endif USE_GRAPH_SWITCH}
  472. begin
  473. LastTextConsoleVideoInfo:=ConsoleVideoInfo;
  474. GetBuffer(ConsoleVideoInfo.ScreenSize);
  475. if ConsoleVideoInfo.Mode=7 then
  476. VSeg:=SegB000
  477. else
  478. VSeg:=SegB800;
  479. SOfs:=MemW[Seg0040:$4e];
  480. DosmemGet(VSeg,SOfs,VBuffer^,ConsoleVideoInfo.ScreenSize);
  481. end;
  482. end;
  483. procedure TDOSScreen.SwitchToConsoleScreen;
  484. var
  485. VSeg,SOfs: word;
  486. {$ifdef USE_GRAPH_SWITCH}
  487. restored : boolean;
  488. GraphDriver,GraphMode : integer;
  489. {$endif USE_GRAPH_SWITCH}
  490. begin
  491. SetVideoMode(ConsoleVideoInfo);
  492. {$ifdef USE_GRAPH_SWITCH}
  493. restored:=false;
  494. if assigned(GraphBuffer) then
  495. begin
  496. if VesaSetMode(ConsoleVideoInfo.Mode) then
  497. begin
  498. if ConsoleVideoInfo.Mode>=$100 then
  499. begin
  500. GraphDriver:=Graph.Vesa;
  501. GraphMode:=ConsoleVideoInfo.Mode and $fff;
  502. end
  503. else
  504. begin
  505. GraphDriver:=Graph.VGA;
  506. case ConsoleVideoInfo.Mode of
  507. $E : GraphMode:=VGALo;
  508. $10 : GraphMode:=VGAMed;
  509. $12 : GraphMode:=VGAHi;
  510. $13 : begin
  511. GraphDriver:=Graph.LowRes;
  512. GraphMode:=0;
  513. end;
  514. end;
  515. end;
  516. if (ConsoleGraphDriver<>GraphDriver) or
  517. (ConsoleGraphMode<>GraphMode) then
  518. Graph.InitGraph(GraphDriver,GraphMode,'');
  519. if graphresult=grOk then
  520. begin
  521. PutImage(0,0,GraphBuffer^,CopyPut);
  522. FreeMem(GraphBuffer,GraphImageSize);
  523. GraphBuffer:=nil;
  524. GraphImageSize:=0;
  525. restored:=true;
  526. end;
  527. end;
  528. end;
  529. { mode < $100 so use standard Save code }
  530. if not restored then
  531. {$endif USE_GRAPH_SWITCH}
  532. begin
  533. if ConsoleVideoInfo.Mode=7 then
  534. VSeg:=SegB000
  535. else
  536. VSeg:=SegB800;
  537. SOfs:=MemW[Seg0040:$4e];
  538. DosmemPut(VSeg,SOfs,VBuffer^,ConsoleVideoInfo.ScreenSize);
  539. djgpp_set_ctrl_c(Ctrl_c_state);
  540. end;
  541. end;
  542. procedure TDOSScreen.SwitchBackToIDEScreen;
  543. var
  544. VSeg,SOfs: word;
  545. begin
  546. SetVideoMode(IDEVideoInfo);
  547. if ConsoleVideoInfo.Mode=7 then
  548. VSeg:=SegB000
  549. else
  550. VSeg:=SegB800;
  551. SOfs:=MemW[Seg0040:$4e];
  552. if assigned(VIDEBuffer) then
  553. DosmemPut(VSeg,SOfs,VIDEBuffer^,IDEVideoInfo.ScreenSize);
  554. Ctrl_c_state := djgpp_set_ctrl_c(false);
  555. { Its difficult to know
  556. the state of the mouse
  557. so simply show it always
  558. fixes bug 2253 PM }
  559. ShowMouse;
  560. end;
  561. function TDOSScreen.GetLineStartOfs(Line: integer): word;
  562. begin
  563. GetLineStartOfs:=(ConsoleVideoInfo.Cols*Line)*2;
  564. end;
  565. procedure TDOSScreen.GetBuffer(Size: word);
  566. begin
  567. if (VBuffer<>nil) and (VBufferSize=Size) then Exit;
  568. if VBuffer<>nil then FreeBuffer;
  569. VBufferSize:=Size;
  570. GetMem(VBuffer,VBufferSize);
  571. end;
  572. procedure TDOSScreen.FreeBuffer;
  573. begin
  574. if (VBuffer<>nil) and (VBufferSize>0) then FreeMem(VBuffer,VBufferSize);
  575. VBuffer:=nil;
  576. end;
  577. procedure TDOSScreen.GetVideoMode(var MI: TDOSVideoInfo);
  578. var
  579. r: registers;
  580. begin
  581. if (MI.StateSize>0) and (MI.StateBuf<>nil) then
  582. begin FreeMem(MI.StateBuf,MI.StateSize); MI.StateBuf:=nil; end;
  583. MI.ScreenSize:=MemW[Seg0040:$4c];
  584. r.ah:=$0f;
  585. intr($10,r);
  586. MI.Mode:=r.al;
  587. MI.Page:=r.bh;
  588. MI.Cols:=r.ah;
  589. {$ifdef VESA}
  590. VESAGetMode(MI.Mode);
  591. MI.Mode:=MI.Mode and $fff;
  592. {$endif}
  593. MI.Rows:=MI.ScreenSize div (MI.Cols*2);
  594. if MI.Rows=51 then MI.Rows:=50;
  595. r.ah:=$03;
  596. r.bh:=MI.Page;
  597. intr($10,r);
  598. with MI do
  599. begin
  600. CurPos.X:=r.dl; CurPos.Y:=r.dh;
  601. CurShapeT:=r.ch; CurShapeB:=r.cl;
  602. end;
  603. end;
  604. procedure TDOSScreen.SetVideoMode(MI: TDOSVideoInfo);
  605. var r: registers;
  606. CM: TDOSVideoInfo;
  607. begin
  608. FillChar(CM,sizeof(CM),0);
  609. GetVideoMode(CM);
  610. if (CM.Mode<>MI.Mode) or (CM.Cols<>MI.Cols) or (CM.Rows<>MI.Rows) then
  611. begin
  612. {$ifdef VESA}
  613. if MI.Mode>=$100 then
  614. VESASetMode(MI.Mode)
  615. else
  616. {$endif}
  617. begin
  618. r.ah:=$00; r.al:=MI.Mode; intr($10,r);
  619. end;
  620. if (MI.Mode=3) and (MI.Cols=80) and (MI.Rows=50) then
  621. begin
  622. r.ax:=$1112; r.bx:=$0;
  623. intr($10,r);
  624. end;
  625. end;
  626. r.ah:=$05; r.al:=MI.Page; intr($10,r);
  627. r.ah:=$02; r.bh:=MI.Page; r.dl:=MI.CurPos.X; r.dh:=MI.CurPos.Y; intr($10,r);
  628. r.ah:=$01; r.ch:=MI.CurShapeT; r.cl:=MI.CurShapeB; intr($10,r);
  629. end;
  630. {$endif}
  631. {****************************************************************************
  632. TLinuxScreen
  633. ****************************************************************************}
  634. {$ifdef Unix}
  635. constructor TLinuxScreen.Init;
  636. var
  637. ThisTTY: string[30];
  638. FName: string;
  639. WS: packed record
  640. ws_row, ws_col, ws_xpixel, ws_ypixel: Word;
  641. end;
  642. begin
  643. inherited Init;
  644. IdeScreen := nil;
  645. TTYFd:=-1;
  646. IsXterm:=getenv('TERM')='xterm';
  647. ThisTTY:=TTYName(stdinputhandle);
  648. if Not IsXterm and (IsATTY(stdinputhandle)<>-1) then
  649. begin
  650. Console:=TTyNetwork; {Default: Network or other vtxxx tty}
  651. if (Copy(ThisTTY, 1, 8) = '/dev/tty') and (ThisTTY[9]<>'p') Then
  652. begin
  653. Case ThisTTY[9] of
  654. '0'..'9' :
  655. begin { running Linux on native console or native-emulation }
  656. FName:='/dev/vcsa' + ThisTTY[9];
  657. TTYFd:=fpOpen(FName, &666, O_RdWr); { open console }
  658. If TTYFd <>-1 Then
  659. Console:=ttyLinux;
  660. end;
  661. 'v' : { check for (Free?)BSD native}
  662. If (ThisTTY[10]>='0') and (ThisTTY[10]<='9') Then
  663. Console:=ttyFreeBSD; {TTYFd ?}
  664. end;
  665. end;
  666. If Copy(GetEnv('TERM'),1,6)='cons25' Then
  667. Console:=ttyFreeBSD;
  668. fpioctl(stdinputhandle, TIOCGWINSZ, @WS);
  669. if WS.ws_Col=0 then
  670. WS.ws_Col:=80;
  671. if WS.ws_Row=0 then
  672. WS.ws_Row:=25;
  673. ConsWidth:=WS.ws_Col;
  674. ConsHeight:=WS.ws_row;
  675. end;
  676. Capture;
  677. end;
  678. destructor TLinuxScreen.Done;
  679. begin
  680. if assigned(IdeScreen) then
  681. freemem(IdeScreen,IdeSize);
  682. if assigned(ConsVideoBuf) then
  683. freemem(ConsVideoBuf,ConsVideoBufSize);
  684. inherited Done;
  685. end;
  686. function TLinuxScreen.GetWidth: integer;
  687. begin
  688. GetWidth:=ConsWidth;
  689. end;
  690. function TLinuxScreen.GetHeight: integer;
  691. begin
  692. GetHeight:=ConsHeight;
  693. end;
  694. procedure TLinuxScreen.GetLine(Line: integer; var Text, Attr: string);
  695. var
  696. X, W : longint;
  697. begin
  698. Text:='';
  699. Attr:='';
  700. if (TtyFd<>-1) and assigned(ConsVideoBuf) then
  701. begin
  702. if Line<GetHeight then
  703. begin
  704. W:=(ConsWidth*Line)*Sizeof(word);
  705. for X:=0 to GetWidth-1 do
  706. begin
  707. {Text:=Text+chr(VBuffer^[W+X*2]);
  708. Attr:=Attr+chr(VBuffer^[W+X*2+1]);}
  709. System.Insert(chr(ConsVideoBuf^[W+X*2]),Text,Length(Text)+1);
  710. System.Insert(chr(ConsVideoBuf^[W+X*2+1]),Attr,Length(Attr)+1);
  711. end;
  712. end;
  713. end;
  714. end;
  715. procedure TLinuxScreen.GetCursorPos(var P: TPoint);
  716. begin
  717. P.X:=ConsCursorX+1;
  718. P.Y:=ConsCursorY+1;
  719. end;
  720. procedure TLinuxScreen.Capture;
  721. begin
  722. SaveConsoleScreen;
  723. end;
  724. procedure TLinuxScreen.Restore;
  725. begin
  726. SwitchToConsoleScreen;
  727. end;
  728. procedure TLinuxScreen.SaveIDEScreen;
  729. begin
  730. if assigned(IdeScreen) then
  731. freemem(IdeScreen,IdeSize);
  732. getmem(IdeScreen,videobufsize);
  733. IdeSize:=videobufsize;
  734. move(videobuf^,IdeScreen^,videobufsize);
  735. end;
  736. procedure TLinuxScreen.SaveConsoleScreen;
  737. var
  738. NewSize : longint;
  739. begin
  740. if IsXTerm then
  741. write(#27'7'#27'[?47h')
  742. else if (TTYfd<>-1) then
  743. begin
  744. fpLSeek(TTYFd, 0, Seek_Set);
  745. fpread(TTYFd,ConsHeight,sizeof(byte));
  746. fpread(TTYFd,ConsWidth,sizeof(byte));
  747. fpread(TTYFd,ConsCursorX,sizeof(byte));
  748. fpread(TTYFd,ConsCursorY,sizeof(byte));
  749. NewSize:=ConsWidth*ConsHeight*sizeof(word);
  750. if (NewSize<>ConsVideoBufSize) and
  751. assigned(ConsVideoBuf) then
  752. Begin
  753. FreeMem(ConsVideoBuf,ConsVideoBufSize);
  754. ConsVideoBuf:=nil;
  755. End;
  756. If not assigned(ConsVideoBuf) then
  757. GetMem(ConsVideoBuf,NewSize);
  758. ConsVideoBufSize:=NewSize;
  759. fpread(TTYFd,ConsVideoBuf^,ConsVideoBufSize);
  760. end
  761. else
  762. begin
  763. ConsWidth:=80;
  764. ConsHeight:=25;
  765. ConsCursorX:=0;
  766. ConsCursorY:=0;
  767. ConsVideoBuf:=nil;
  768. end;
  769. ConsTioValid:=(TCGetAttr(1,ConsTio)<>-1);
  770. end;
  771. procedure TLinuxScreen.SwitchToConsoleScreen;
  772. begin
  773. if IsXterm then
  774. begin
  775. write(#27'[0m');
  776. write(#27'[?47l'#27'8'#27'[m');
  777. end
  778. else if (TTyfd<>-1) then
  779. begin
  780. fplSeek(TTYFd, 2, Seek_Set);
  781. fpwrite(TTYFd, ConsCursorX, sizeof(byte));
  782. fpwrite(TTYFd, ConsCursorY, sizeof(byte));
  783. fpwrite(TTYFd, ConsVideoBuf^,ConsVideoBufSize);
  784. { FreeMem(ConsVideoBuf,ConsVideoBufSize);
  785. ConsVideoBuf:=nil; }
  786. end;
  787. If ConsTioValid then
  788. TCSetAttr(1,TCSANOW,ConsTio);
  789. end;
  790. procedure TLinuxScreen.SwitchBackToIDEScreen;
  791. begin
  792. if IdeScreen = nil then
  793. exit;
  794. move(IdeScreen^,videobuf^,videobufsize);
  795. freemem(IdeScreen,IdeSize);
  796. IdeScreen := nil;
  797. end;
  798. {$endif}
  799. {****************************************************************************
  800. TWindowsScreen
  801. ****************************************************************************}
  802. {$ifdef Windows}
  803. { Seems to be missing in windows unit PM }
  804. const
  805. ENABLE_INSERT_MODE = $20;
  806. ENABLE_QUICK_EDIT_MODE = $40;
  807. ENABLE_EXTENDED_FLAGS = $80;
  808. ENABLE_AUTO_POSITION = $100;
  809. procedure UpdateFileHandles;
  810. begin
  811. {StdInputHandle:=longint(GetStdHandle(STD_INPUT_HANDLE));}
  812. StdOutputHandle:=longint(GetStdHandle(cardinal(STD_OUTPUT_HANDLE)));
  813. {StdErrorHandle:=longint(GetStdHandle(STD_ERROR_HANDLE));}
  814. TextRec(Output).Handle:=StdOutputHandle;
  815. TextRec(StdOut).Handle:=StdOutputHandle;
  816. {TextRec(StdErr).Handle:=StdErrorHandle;}
  817. end;
  818. constructor TWindowsScreen.Init;
  819. var
  820. SecurityAttr : Security_attributes;
  821. BigWin : Coord;
  822. res : longbool;
  823. Error : dword;
  824. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  825. begin
  826. inherited Init;
  827. {if GetConsoleOutputCP<>437 then
  828. res:=SetConsoleOutputCP(437);}
  829. SecurityAttr.nLength:=SizeOf(Security_attributes);
  830. SecurityAttr.lpSecurityDescriptor:=nil;
  831. SecurityAttr.bInheritHandle:=true;
  832. NewScreenBufferHandle:=CreateConsoleScreenBuffer(
  833. GENERIC_READ or GENERIC_WRITE,
  834. FILE_SHARE_READ or FILE_SHARE_WRITE,SecurityAttr,
  835. CONSOLE_TEXTMODE_BUFFER,nil);
  836. DummyScreenBufferHandle:=CreateConsoleScreenBuffer(
  837. GENERIC_READ or GENERIC_WRITE,
  838. FILE_SHARE_READ or FILE_SHARE_WRITE,SecurityAttr,
  839. CONSOLE_TEXTMODE_BUFFER,nil);
  840. StartScreenBufferHandle:=GetStdHandle(cardinal(STD_OUTPUT_HANDLE));
  841. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @ConsoleMode);
  842. IdeMode:=ConsoleMode;
  843. {$ifdef debug}
  844. Complain('Starting ConsoleMode is $'+hexstr(ConsoleMode,8));
  845. {define Windowsbigwin}
  846. {$endif debug}
  847. {$ifdef Windowsbigwin}
  848. GetConsoleScreenBufferInfo(StartScreenBufferHandle,
  849. @ConsoleScreenBufferInfo);
  850. BigWin.X:=ConsoleScreenBufferInfo.dwSize.X;
  851. BigWin.Y:=200;
  852. { Try to allow to store more info }
  853. res:=SetConsoleScreenBufferSize(NewScreenBufferHandle,BigWin);
  854. if not res then
  855. error:=GetLastError;
  856. res:=SetConsoleScreenBufferSize(StartScreenBufferHandle,BigWin);
  857. if not res then
  858. error:=GetLastError;
  859. {$endif Windowsbigwin}
  860. GetConsoleScreenBufferInfo(StartScreenBufferHandle,
  861. @ConsoleScreenBufferInfo);
  862. { make sure that the IDE Screen Handle has the maximum display size
  863. this removes the scroll bars if it is maximized }
  864. res:=SetConsoleScreenBufferSize(NewScreenBufferHandle,
  865. ConsoleScreenBufferInfo.dwMaximumWindowSize);
  866. if not res then
  867. error:=GetLastError;
  868. IDEScreenBufferHandle:=NewScreenBufferHandle;
  869. DosScreenBufferHandle:=StartScreenBufferHandle;
  870. Capture;
  871. IdeScreenMode.row:=0;
  872. SwitchBackToIDEScreen;
  873. end;
  874. destructor TWindowsScreen.Done;
  875. begin
  876. { copy the Dos buffer content into the original ScreenBuffer
  877. which remains the startup std_output_handle PM }
  878. {if StartScreenBufferHandle=IDEScreenBufferHandle then}
  879. BufferCopy(DosScreenBufferHandle,IDEScreenBufferHandle);
  880. SetConsoleActiveScreenBuffer(StartScreenBufferHandle);
  881. SetStdHandle(cardinal(Std_Output_Handle),StartScreenBufferHandle);
  882. UpdateFileHandles;
  883. CloseHandle(NewScreenBufferHandle);
  884. CloseHandle(DummyScreenBufferHandle);
  885. inherited Done;
  886. end;
  887. function TWindowsScreen.GetWidth: integer;
  888. var
  889. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  890. begin
  891. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  892. @ConsoleScreenBufferInfo);
  893. GetWidth:=ConsoleScreenBufferInfo.dwSize.X;
  894. end;
  895. function TWindowsScreen.GetHeight: integer;
  896. var
  897. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  898. begin
  899. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  900. @ConsoleScreenBufferInfo);
  901. GetHeight:=ConsoleScreenBufferInfo.dwSize.Y;
  902. end;
  903. function TWindowsScreen.CanScroll : boolean;
  904. var
  905. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  906. BufferLines : longint;
  907. WindowLines : longint;
  908. begin
  909. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  910. @ConsoleScreenBufferInfo);
  911. WindowLines:=ConsoleScreenBufferInfo.srWindow.Bottom-
  912. ConsoleScreenBufferInfo.srWindow.Top;
  913. BufferLines:= ConsoleScreenBufferInfo.dwSize.Y-1;
  914. CanScroll:=(BufferLines>WindowLines);
  915. end;
  916. function TWindowsScreen.Scroll(i : integer) : integer;
  917. var
  918. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  919. ConsoleWindow : Small_rect;
  920. begin
  921. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  922. @ConsoleScreenBufferInfo);
  923. if (ConsoleScreenBufferInfo.srWindow.Top + i < 0) then
  924. i:= -ConsoleScreenBufferInfo.srWindow.Top;
  925. if (ConsoleScreenBufferInfo.srWindow.Bottom + i > ConsoleScreenBufferInfo.dwSize.Y) then
  926. i:= ConsoleScreenBufferInfo.dwSize.Y - ConsoleScreenBufferInfo.srWindow.Bottom;
  927. if i<>0 then
  928. begin
  929. ConsoleWindow.Left:=ConsoleScreenBufferInfo.srWindow.Left;
  930. ConsoleWindow.Right:=ConsoleScreenBufferInfo.srWindow.Right;
  931. ConsoleWindow.Top:=ConsoleScreenBufferInfo.srWindow.Top+i;
  932. ConsoleWindow.Bottom:=ConsoleScreenBufferInfo.srWindow.Bottom+i;
  933. SetConsoleWindowInfo(DosScreenBufferHandle,true,ConsoleWindow);
  934. Scroll:=i;
  935. end
  936. else
  937. Scroll:=0;
  938. end;
  939. procedure TWindowsScreen.GetLine(Line: integer; var Text, Attr: string);
  940. type
  941. CharInfoArray = Array [0..255] of Char_Info;
  942. var
  943. LineBuf : ^CharInfoArray;
  944. BufSize,BufCoord : Coord;
  945. i,LineSize : longint;
  946. WriteRegion : SMALL_RECT;
  947. begin
  948. GetMem(LineBuf,SizeOf(CharInfoArray));
  949. LineSize:=ScreenWidth;
  950. If LineSize>256 then
  951. LineSize:=256;
  952. BufSize.X:=LineSize;
  953. BufSize.Y:=1;
  954. BufCoord.X:=0;
  955. BufCoord.Y:=0;
  956. with WriteRegion do
  957. begin
  958. Top :=Line;
  959. Left :=0;
  960. Bottom := Line+1;
  961. Right := LineSize-1;
  962. end;
  963. ReadConsoleOutput(DosScreenBufferHandle, PChar_info(LineBuf),
  964. BufSize, BufCoord, @WriteRegion);
  965. for i:=1 to LineSize do
  966. begin
  967. Text[i]:=LineBuf^[i-1].AsciiChar;
  968. Attr[i]:=char(byte(LineBuf^[i-1].Attributes));
  969. end;
  970. FreeMem(LineBuf,SizeOf(CharInfoArray));
  971. Text[0]:=char(byte(LineSize));
  972. Attr[0]:=char(byte(LineSize));
  973. end;
  974. procedure TWindowsScreen.GetCursorPos(var P: TPoint);
  975. var
  976. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  977. begin
  978. GetConsoleScreenBufferInfo(DosScreenBufferHandle,
  979. @ConsoleScreenBufferInfo);
  980. P.X:=ConsoleScreenBufferInfo.dwCursorPosition.X;
  981. P.Y:=ConsoleScreenBufferInfo.dwCursorPosition.Y;
  982. end;
  983. procedure TWindowsScreen.BufferCopy(Src, Dest : THandle);
  984. type
  985. CharInfoArray = Array [0..256*255-1] of Char_Info;
  986. var
  987. LineBuf : ^CharInfoArray;
  988. BufSize,BufCoord : Coord;
  989. Error, LineSize,
  990. Part, OnePartY: longint;
  991. res : boolean;
  992. WriteRegion : SMALL_RECT;
  993. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  994. DestConsoleScreenBufferInfo : Console_screen_buffer_info;
  995. begin
  996. GetConsoleScreenBufferInfo(Src,
  997. @ConsoleScreenBufferInfo);
  998. GetConsoleScreenBufferInfo(Dest,
  999. @DestConsoleScreenBufferInfo);
  1000. GetMem(LineBuf,SizeOf(CharInfoArray));
  1001. FillChar(LineBuf^,SizeOf(CharInfoArray),#0);
  1002. LineSize:=ConsoleScreenBufferInfo.dwSize.X;
  1003. If LineSize>256 then
  1004. LineSize:=256;
  1005. BufSize.X:=LineSize;
  1006. BufSize.Y:=ConsoleScreenBufferInfo.dwSize.Y;
  1007. BufCoord.X:=0;
  1008. BufCoord.Y:=0;
  1009. with WriteRegion do
  1010. begin
  1011. Top :=0;
  1012. Left :=0;
  1013. Bottom := ConsoleScreenBufferInfo.dwSize.Y-1;
  1014. Right := LineSize-1;
  1015. end;
  1016. if BufSize.X*BufSize.Y*Sizeof(CHAR_INFO) >= $8000 then
  1017. begin
  1018. OnePartY := ($8000 -1) div (BufSize.X * SizeOf(Char_Info) );
  1019. BufSize.Y:=OnePartY;
  1020. Part:=0;
  1021. while ((Part+1)*OnePartY < ConsoleScreenBufferInfo.dwSize.Y) do
  1022. begin
  1023. WriteRegion.Top := Part*OnePartY;
  1024. WriteRegion.Bottom := (Part+1)*OnePartY-1;
  1025. res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
  1026. BufSize, BufCoord, @WriteRegion);
  1027. if not res then
  1028. Error:=GetLastError;
  1029. res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
  1030. BufSize, BufCoord, @WriteRegion);
  1031. if not res then
  1032. Error:=GetLastError;
  1033. Inc(Part);
  1034. end;
  1035. BufSize.Y:=ConsoleScreenBufferInfo.dwSize.Y - Part*OnePartY;
  1036. WriteRegion.Top := Part*OnePartY;
  1037. WriteRegion.Bottom := ConsoleScreenBufferInfo.dwSize.Y-1;
  1038. res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
  1039. BufSize, BufCoord, @WriteRegion);
  1040. if not res then
  1041. Error:=GetLastError;
  1042. res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
  1043. BufSize, BufCoord, @WriteRegion);
  1044. if not res then
  1045. Error:=GetLastError;
  1046. end
  1047. else
  1048. begin
  1049. res:=ReadConsoleOutput(Src, PChar_info(LineBuf),
  1050. BufSize, BufCoord, @WriteRegion);
  1051. if not res then
  1052. Error:=GetLastError;
  1053. res:=WriteConsoleOutput(Dest, PChar_info(LineBuf),
  1054. BufSize, BufCoord, @WriteRegion);
  1055. if not res then
  1056. Error:=GetLastError;
  1057. end;
  1058. FreeMem(LineBuf,SizeOf(CharInfoArray));
  1059. SetConsoleCursorPosition(Dest, ConsoleScreenBufferInfo.dwCursorPosition);
  1060. end;
  1061. procedure TWindowsScreen.Capture;
  1062. begin
  1063. {if StartScreenBufferHandle=IdeScreenBufferHandle then
  1064. BufferCopy(IDEScreenBufferHandle,DosScreenBufferHandle)
  1065. else
  1066. BufferCopy(DosScreenBufferHandle,IDEScreenBufferHandle);}
  1067. SaveConsoleScreen;
  1068. end;
  1069. procedure TWindowsScreen.Restore;
  1070. begin
  1071. SwitchToConsoleScreen;
  1072. end;
  1073. { dummy for Windows as the Buffer screen
  1074. do hold all the info }
  1075. procedure TWindowsScreen.SaveIDEScreen;
  1076. var
  1077. NowIdeMode : Dword;
  1078. begin
  1079. IdeScreenMode:=ScreenMode;
  1080. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @NowIdeMode);
  1081. {$ifdef debug}
  1082. Complain('IDE ConsoleMode is $'+hexstr(NowIdeMode,8));
  1083. if NowIdeMode<>IdeMode then
  1084. Complain('is not equal to IDEMode $'+hexstr(IdeMode,8));
  1085. {$endif debug}
  1086. IdeMode:=NowIdeMode;
  1087. { set the dummy buffer as active already now PM }
  1088. SetStdHandle(cardinal(Std_Output_Handle),DummyScreenBufferHandle);
  1089. UpdateFileHandles;
  1090. end;
  1091. { dummy for Windows as the Buffer screen
  1092. do hold all the info }
  1093. procedure TWindowsScreen.SaveConsoleScreen;
  1094. begin
  1095. GetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), @ConsoleMode);
  1096. {$ifdef debug}
  1097. Complain('ConsoleMode now is $'+hexstr(ConsoleMode,8));
  1098. {$endif debug}
  1099. { set the dummy buffer as active already now PM }
  1100. SetStdHandle(cardinal(Std_Output_Handle),DummyScreenBufferHandle);
  1101. UpdateFileHandles;
  1102. end;
  1103. procedure TWindowsScreen.SwitchToConsoleScreen;
  1104. begin
  1105. SetConsoleActiveScreenBuffer(DosScreenBufferHandle);
  1106. SetStdHandle(cardinal(Std_Output_Handle),DosScreenBufferHandle);
  1107. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), ConsoleMode);
  1108. UpdateFileHandles;
  1109. IDEActive:=false;
  1110. end;
  1111. procedure TWindowsScreen.SwitchBackToIDEScreen;
  1112. var
  1113. ConsoleScreenBufferInfo : Console_screen_buffer_info;
  1114. WindowPos : Small_rect;
  1115. res : boolean;
  1116. error : longint;
  1117. begin
  1118. SetStdHandle(cardinal(Std_Output_Handle),IDEScreenBufferHandle);
  1119. UpdateFileHandles;
  1120. GetConsoleScreenBufferInfo(IDEScreenBufferHandle,
  1121. @ConsoleScreenBufferInfo);
  1122. SetConsoleActiveScreenBuffer(IDEScreenBufferHandle);
  1123. { Needed to force InitSystemMsg to use the right console handle }
  1124. DoneEvents;
  1125. InitEvents;
  1126. IdeMode:=({IdeMode or }ENABLE_MOUSE_INPUT or
  1127. ENABLE_WINDOW_INPUT or
  1128. ENABLE_EXTENDED_FLAGS)
  1129. and not (ENABLE_PROCESSED_INPUT or
  1130. ENABLE_LINE_INPUT or
  1131. ENABLE_ECHO_INPUT or
  1132. ENABLE_INSERT_MODE or
  1133. ENABLE_QUICK_EDIT_MODE);
  1134. SetConsoleMode(GetStdHandle(cardinal(Std_Input_Handle)), IdeMode);
  1135. WindowPos.left:=0;
  1136. WindowPos.right:=ConsoleScreenBufferInfo.srWindow.right
  1137. -ConsoleScreenBufferInfo.srWindow.left;
  1138. WindowPos.top:=0;
  1139. WindowPos.bottom:=ConsoleScreenBufferInfo.srWindow.bottom
  1140. -ConsoleScreenBufferInfo.srWindow.top;
  1141. with ConsoleScreenBufferInfo.dwMaximumWindowSize do
  1142. begin
  1143. if WindowPos.Right<X-1 then
  1144. WindowPos.right:=X-1;
  1145. if WindowPos.Bottom<Y-1 then
  1146. WindowPos.Bottom:=Y-1;
  1147. end;
  1148. res:=SetConsoleWindowInfo(IDEScreenBufferHandle,true,WindowPos);
  1149. if not res then
  1150. error:=GetLastError;
  1151. {$ifdef DEBUG}
  1152. IdeScreenMode.row:=WindowPos.bottom+1;
  1153. IdeScreenMode.col:=WindowPos.right+1;
  1154. {$endif DEBUG}
  1155. { needed to force the correct size for videobuf }
  1156. if Assigned(Application) and (IdeScreenMode.row<>0)then
  1157. Application^.SetScreenVideoMode(IdeScreenMode);
  1158. IDEActive:=true;
  1159. end;
  1160. {$ifdef debug}
  1161. procedure TWindowsScreen.Complain(St : string);
  1162. begin
  1163. if IDEActive then
  1164. DebugMessage('',St,0,0)
  1165. else
  1166. Writeln(stderr,St);
  1167. end;
  1168. procedure TWindowsScreen.SetConsoleMode(FH : Handle;Mode: DWord);
  1169. var
  1170. Test: DWord;
  1171. begin
  1172. If not Windows.SetConsoleMode(FH,Mode) then
  1173. begin
  1174. Complain('SetConsoleMode call failed GetLastError='+IntToStr(GetLastError));
  1175. end
  1176. else
  1177. begin
  1178. if not GetConsoleMode(FH,Test) then
  1179. begin
  1180. Complain('GetConsoleMode call failed GetLastError='+IntToStr(GetLastError));
  1181. end
  1182. else if (Test<>Mode) then
  1183. begin
  1184. Complain('GetConsoleMode result '+IntToStr(Test)+' <> '+
  1185. IntToStr(Mode));
  1186. end;
  1187. end;
  1188. end;
  1189. {$endif DEBUG}
  1190. {$endif}
  1191. {****************************************************************************
  1192. TOS2Screen
  1193. ****************************************************************************}
  1194. {$ifdef OS2}
  1195. function TOS2Screen.GetWidth: integer;
  1196. begin
  1197. GetWidth:=80;
  1198. end;
  1199. function TOS2Screen.GetHeight: integer;
  1200. begin
  1201. GetHeight:=25;
  1202. end;
  1203. procedure TOS2Screen.GetLine(Line: integer; var Text, Attr: string);
  1204. begin
  1205. Text:=' ';
  1206. Attr:=' ';
  1207. end;
  1208. procedure TOS2Screen.GetCursorPos(var P: TPoint);
  1209. begin
  1210. P.X:=1;
  1211. P.Y:=1;
  1212. end;
  1213. { remember the initial video screen }
  1214. procedure TOS2Screen.Capture;
  1215. begin
  1216. end;
  1217. { restore the initial video mode }
  1218. procedure TOS2Screen.Restore;
  1219. begin
  1220. end;
  1221. { move up or down if supported by OS }
  1222. function TOS2Screen.Scroll(i : integer) : integer;
  1223. begin
  1224. end;
  1225. { saves the current IDE screen }
  1226. procedure TOS2Screen.SaveIDEScreen;
  1227. begin
  1228. end;
  1229. { saves the current console screen }
  1230. procedure TOS2Screen.SaveConsoleScreen;
  1231. begin
  1232. end;
  1233. { restores the saved console screen }
  1234. procedure TOS2Screen.SwitchToConsoleScreen;
  1235. begin
  1236. end;
  1237. { restores the saved IDE screen }
  1238. procedure TOS2Screen.SwitchBackToIDEScreen;
  1239. begin
  1240. end;
  1241. constructor TOS2Screen.Init;
  1242. begin
  1243. end;
  1244. destructor TOS2Screen.Done;
  1245. begin
  1246. end;
  1247. {$ENDIF}
  1248. {****************************************************************************
  1249. TNWLScreen
  1250. ****************************************************************************}
  1251. {$ifdef netwlibc}
  1252. function TNWLScreen.GetWidth: integer;
  1253. begin
  1254. GetWidth:=80;
  1255. end;
  1256. function TNWLScreen.GetHeight: integer;
  1257. begin
  1258. GetHeight:=25;
  1259. end;
  1260. procedure TNWLScreen.GetLine(Line: integer; var Text, Attr: string);
  1261. begin
  1262. Text:=' ';
  1263. Attr:=' ';
  1264. end;
  1265. procedure TNWLScreen.GetCursorPos(var P: TPoint);
  1266. begin
  1267. P.X:=1;
  1268. P.Y:=1;
  1269. end;
  1270. { remember the initial video screen }
  1271. procedure TNWLScreen.Capture;
  1272. begin
  1273. end;
  1274. { restore the initial video mode }
  1275. procedure TNWLScreen.Restore;
  1276. begin
  1277. end;
  1278. { saves the current IDE screen }
  1279. procedure TNWLScreen.SaveIDEScreen;
  1280. begin
  1281. end;
  1282. { saves the current console screen }
  1283. procedure TNWLScreen.SaveConsoleScreen;
  1284. begin
  1285. end;
  1286. { restores the saved console screen }
  1287. procedure TNWLScreen.SwitchToConsoleScreen;
  1288. begin
  1289. end;
  1290. { restores the saved IDE screen }
  1291. procedure TNWLScreen.SwitchBackToIDEScreen;
  1292. begin
  1293. end;
  1294. {$ENDIF}
  1295. {****************************************************************************
  1296. Initialize
  1297. ****************************************************************************}
  1298. procedure InitUserScreen;
  1299. begin
  1300. {$ifdef DOS}
  1301. UserScreen:=New(PDOSScreen, Init);
  1302. {$else}
  1303. {$ifdef Unix}
  1304. UserScreen:=New(PLinuxScreen, Init);
  1305. {$else}
  1306. {$ifdef Windows}
  1307. UserScreen:=New(PWindowsScreen, Init);
  1308. {$else}
  1309. {$ifdef OS2}
  1310. UserScreen:=New(POS2Screen, Init);
  1311. {$else}
  1312. {$ifdef netwlibc}
  1313. UserScreen:=New(PNWLScreen, Init);
  1314. {$else}
  1315. UserScreen:=New(PScreen, Init);
  1316. {$endif netwlibc}
  1317. {$endif OS2}
  1318. {$endif Windows}
  1319. {$endif Unix}
  1320. {$endif Dos}
  1321. end;
  1322. procedure DoneUserScreen;
  1323. begin
  1324. if UserScreen<>nil then
  1325. begin
  1326. UserScreen^.Restore;
  1327. Dispose(UserScreen, Done);
  1328. UserScreen:=nil;
  1329. end;
  1330. end;
  1331. end.