WINDOW.MOD 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734
  1. (* Release 3.10 *)
  2. (*-------------------------------------------------------------------------*
  3. * *
  4. * WINDOW.MOD - Clipping text windows *
  5. * *
  6. * COPYRIGHT (C) 1987..1992 Clarion Software Corporation. *
  7. * All Rights Reserved *
  8. * *
  9. *--------------------------------------------------------------------------*)
  10. (*%F _fdata *)
  11. (*# call(seg_name => null) *)
  12. (*# data(seg_name => null) *)
  13. (*%E *)
  14. (*# module(implementation=>off) *)
  15. (*# call(o_a_copy=>off) *)
  16. (*# check(stack=>off,
  17. index=>off,
  18. range=>off,
  19. overflow=>off,
  20. nil_ptr=>off) *)
  21. IMPLEMENTATION MODULE Window;
  22. (*%F _OS2 *)
  23. IMPORT SYSTEM, Str, Lib, IO, CoreSig;
  24. (*%E *)
  25. (*%T _OS2 *)
  26. IMPORT SYSTEM, Str, Lib, Vio, Dos, IO, CoreSig;
  27. (*%E *)
  28. (*%T _mthread *)
  29. IMPORT Process;
  30. (*%E *)
  31. FROM Storage IMPORT ALLOCATE,DEALLOCATE;
  32. TYPE
  33. UseListPtr = POINTER TO UseListLink;
  34. UseListLink = RECORD
  35. Next : UseListPtr;
  36. Proc : ADDRESS;
  37. Wind : WinType;
  38. END;
  39. VAR
  40. (*%T _mthread *)
  41. Lock,Unlock : LockProc;
  42. (*%E *)
  43. CONST
  44. GuardConst = 4A4EH;
  45. PROCEDURE CheckWindow(W:WinType);
  46. BEGIN
  47. IF W^.Guard - Seg(W^) # GuardConst THEN
  48. Lib.RunTimeError(CoreSig._FatalErrorPos(),30H,'Invalid Window');
  49. END; (*IF*)
  50. END CheckWindow;
  51. PROCEDURE ClipFrame ( W : WinType );
  52. VAR
  53. i : CARDINAL;
  54. BEGIN
  55. WITH W^ DO
  56. IF WDef.FrameOn THEN i := 1 ELSE i := 0 END;
  57. IF XA < WDef.X1+i THEN
  58. XA := WDef.X1+i
  59. ELSIF XA > WDef.X2-i THEN
  60. XA := WDef.X2-i
  61. END;
  62. IF XB > WDef.X2-i THEN
  63. XB := WDef.X2-i
  64. ELSIF XB < WDef.X1+i THEN
  65. XB := WDef.X1+i
  66. END;
  67. IF YA < WDef.Y1+i THEN
  68. YA := WDef.Y1+i
  69. ELSIF YA > WDef.Y2-i THEN
  70. YA := WDef.Y2-i
  71. END;
  72. IF YB > WDef.Y2-i THEN
  73. YB := WDef.Y2-i
  74. ELSIF YB < WDef.Y1+i THEN
  75. YB := WDef.Y1+i
  76. END;
  77. Width := XB-XA+1; Depth := YB-YA+1;
  78. END;
  79. END ClipFrame;
  80. PROCEDURE ClipXY ( W : WinType; VAR X,Y : RelCoord );
  81. VAR
  82. mw,md : CARDINAL;
  83. BEGIN
  84. WITH W^ DO
  85. mw := Width; md := Depth;
  86. IF WDef.FrameOn AND NOT WDef.WrapOn THEN
  87. INC(md); INC(mw)
  88. ELSE
  89. IF X=0 THEN X := 1 END;
  90. IF Y=0 THEN Y := 1 END;
  91. END;
  92. IF X>mw THEN X := mw END;
  93. IF Y>md THEN Y := md END;
  94. END;
  95. END ClipXY;
  96. PROCEDURE BufferSpaceFill ( W : WinType; pos : CARDINAL; len : CARDINAL );
  97. BEGIN
  98. WITH W^ DO
  99. IF IsPalette THEN
  100. Lib.WordFill(ADR(Buffer^[pos]),len,32
  101. +VAL(CARDINAL,CurPalColor)*256);
  102. ELSE
  103. Lib.WordFill(ADR(Buffer^[pos]),len,32+
  104. ORD(WDef.Foreground)*256+ORD(WDef.Background)*4096);
  105. END;
  106. END;
  107. END BufferSpaceFill;
  108. PROCEDURE CurWin () : WinType;
  109. (* Returns The current window being used for output for this process *)
  110. (* If no window assigned by Use then returns Top. *)
  111. (* NB Locks window system and leaves locked if _mthread set. *)
  112. VAR
  113. u : UseListPtr;
  114. p : ADDRESS;
  115. BEGIN
  116. (*%T _mthread *)
  117. Lock();
  118. (*%E *)
  119. IF CoreWind._multip THEN
  120. (*%T _mthread *)
  121. p := SYSTEM.CurrentProcess();
  122. (*%E *)
  123. (*%F _mthread *)
  124. p := NIL;
  125. (*%E *)
  126. u := UseListPtr(CoreWind._uselist)^.Next;
  127. LOOP
  128. IF u = NIL THEN
  129. RETURN WinType(CoreWind._windowstack); (* Top() *)
  130. ELSIF p = u^.Proc THEN
  131. RETURN u^.Wind;
  132. END; (*IF*)
  133. u := u^.Next;
  134. END; (*LOOP*)
  135. END; (*IF*)
  136. u := UseListPtr(CoreWind._uselist)^.Next;
  137. IF u = NIL THEN
  138. RETURN WinType(CoreWind._windowstack); (* Top() *)
  139. END; (*IF*)
  140. RETURN u^.Wind;
  141. END CurWin;
  142. (*%F _OS2 *)
  143. PROCEDURE ResetCursor;
  144. VAR
  145. R : SYSTEM.Registers;
  146. mode : CARDINAL;
  147. BEGIN
  148. IF (CoreWind._cursorstack = NIL) OR
  149. ObscuredAt(WinType(CoreWind._cursorstack),WinType(CoreWind._cursorstack)^.CurrentX,WinType(CoreWind._cursorstack)^.CurrentY) THEN
  150. mode := 2000H;
  151. ELSE
  152. WITH WinType(CoreWind._cursorstack)^ DO
  153. WITH R DO
  154. AH := 2;
  155. BH := SHORTCARD(CoreWind._activepage());
  156. DL := SHORTCARD(XA+CurrentX-1);
  157. DH := SHORTCARD(YA+CurrentY-1);
  158. END;
  159. Lib.Intr(R,10H);
  160. END;
  161. mode := CoreWind._cursorlines;
  162. END;
  163. R.AH := 1;
  164. R.CX := mode;
  165. Lib.Intr(R,10H);
  166. END ResetCursor;
  167. (*%E *)
  168. (*%T _OS2 *)
  169. VAR
  170. CursorInfo : Vio.CURSORINFO;
  171. RealMode : BOOLEAN;
  172. PROCEDURE ResetCursor;
  173. VAR r : CARDINAL;
  174. BEGIN
  175. IF (CoreWind._cursorstack = NIL) OR
  176. ObscuredAt(WinType(CoreWind._cursorstack),WinType(CoreWind._cursorstack)^.CurrentX,WinType(CoreWind._cursorstack)^.CurrentY) THEN
  177. CursorInfo.attr := MAX(CARDINAL);
  178. ELSE
  179. WITH WinType(CoreWind._cursorstack)^ DO
  180. r := Vio.SetCurPos(YA+CurrentY-1,XA+CurrentX-1,0 );
  181. END;
  182. CursorInfo.attr := 0;
  183. END;
  184. r := Vio.SetCurType( CursorInfo,0);
  185. END ResetCursor;
  186. (*%E *)
  187. PROCEDURE UnlinkCursor ( W : WinType );
  188. VAR
  189. w : WinType;
  190. BEGIN
  191. w := WinType(CoreWind._cursorstack);
  192. IF w = W THEN CoreWind._cursorstack := w^.CursorChain END;
  193. LOOP
  194. IF w = NIL THEN RETURN END;
  195. IF w^.CursorChain = W THEN
  196. w^.CursorChain := W^.CursorChain;
  197. RETURN;
  198. END;
  199. w := w^.CursorChain;
  200. END;
  201. END UnlinkCursor;
  202. (* ------------------------- *)
  203. (* Cursor Control *)
  204. (* ------------------------- *)
  205. PROCEDURE CursorOn;
  206. VAR
  207. w,cw : WinType;
  208. BEGIN
  209. cw := CurWin();
  210. UnlinkCursor(cw);
  211. cw^.WDef.CursorOn := TRUE;
  212. IF NOT cw^.WDef.Hidden THEN
  213. cw^.CursorChain := WinType(CoreWind._cursorstack);
  214. CoreWind._cursorstack := cw;
  215. END;
  216. ResetCursor;
  217. (*%T _mthread *)
  218. Unlock();
  219. (*%E *)
  220. END CursorOn;
  221. PROCEDURE CursorOff;
  222. VAR
  223. w,cw : WinType;
  224. BEGIN
  225. cw := CurWin();
  226. UnlinkCursor(cw);
  227. cw^.WDef.CursorOn := FALSE;
  228. ResetCursor;
  229. (*%T _mthread *)
  230. Unlock();
  231. (*%E *)
  232. END CursorOff;
  233. (* ------------------------- *)
  234. (* Window creation *)
  235. (* ------------------------- *)
  236. PROCEDURE MakeWindow ( VAR WD : WinDef ) : WinType;
  237. (*
  238. Creates a new Window descriptor
  239. The size is Inclusive of frame if needed
  240. does not allocate buffer
  241. *)
  242. VAR W : WinType; min : CARDINAL;
  243. BEGIN
  244. NEW(W);
  245. WITH W^ DO
  246. WITH WD DO
  247. IF X2 >= ScreenWidth THEN X2:=ScreenWidth-1 END;
  248. IF Y2 >= CurrentScreenDepth THEN Y2:=CurrentScreenDepth-1 END;
  249. IF WD.FrameOn THEN min := 2 ELSE min := 0 END;
  250. IF (X1+min>X2) THEN X2 := X1+min END;
  251. IF (Y1+min>Y2) THEN Y2 := Y1+min END;
  252. XA := X1; YA := Y1; XB := X2; YB := Y2;
  253. Width := X2-X1+1; Depth := Y2-Y1+1;
  254. END;
  255. WDef := WD;
  256. OWidth := Width; ODepth := Depth;
  257. CurrentX := 1;
  258. CurrentY := 1;
  259. Next := NIL;
  260. Buffer := NIL;
  261. UserRecord := NIL;
  262. IsPalette := FALSE;
  263. CurPalColor := NormalPaletteColor;
  264. TMode := NoTitle;
  265. Guard := GuardConst+CARDINAL(Seg(W^));
  266. CursorChain := NIL;
  267. Title := NIL;
  268. END;
  269. ClipFrame(W);
  270. RETURN W;
  271. END MakeWindow;
  272. PROCEDURE Open ( WD : WinDef ) : WinType;
  273. (*
  274. Opens a window on the screen ready for use
  275. *)
  276. VAR
  277. W : WinType;
  278. BEGIN
  279. (*%T _mthread *)
  280. Lock();
  281. (*%E *)
  282. W := MakeWindow (WD);
  283. WITH W^ DO
  284. ALLOCATE ( Buffer,OWidth*ODepth*2);
  285. BufferSpaceFill(W,0,OWidth*ODepth);
  286. IF WD.FrameOn THEN
  287. SetFrame(W,WDef.FrameDef,WDef.FrameFore,WDef.FrameBack);
  288. END;
  289. END;
  290. IF WD.Hidden THEN
  291. Use ( W )
  292. ELSE
  293. PutOnTop ( W )
  294. END;
  295. (*%T _mthread *)
  296. Unlock();
  297. (*%E *)
  298. RETURN W;
  299. END Open;
  300. (* ------------------------- *)
  301. (* Window stack manipulation *)
  302. (* and screen redraw *)
  303. (* ------------------------- *)
  304. PROCEDURE Use ( W : WinType );
  305. (*
  306. Causes all subsequent output (by the current process)
  307. to appear in the specified Window
  308. NB does not have to be Top Window (or in fact on the screen at all)
  309. UseListPtr(CoreWind._uselist) is the MRU window
  310. *)
  311. VAR
  312. p : ADDRESS;
  313. u : UseListPtr;
  314. up : UseListPtr;
  315. BEGIN
  316. (*%T _mthread *)
  317. Lock();
  318. (*%E *)
  319. CheckWindow(W);
  320. (*%T _mthread *)
  321. p := SYSTEM.CurrentProcess();
  322. (*%E *)
  323. (*%F _mthread *)
  324. p := NIL;
  325. (*%E *)
  326. up := UseListPtr(CoreWind._uselist);
  327. u := up^.Next;
  328. LOOP
  329. IF u = NIL THEN NEW(u); u^.Proc := p; EXIT END;
  330. IF p = u^.Proc THEN up^.Next := u^.Next; EXIT END;
  331. up := u; u := u^.Next;
  332. END;
  333. u^.Next := UseListPtr(CoreWind._uselist)^.Next;
  334. UseListPtr(CoreWind._uselist)^.Next := u;
  335. u^.Wind := W;
  336. (*%T _mthread *)
  337. Unlock();
  338. (*%E *)
  339. END Use;
  340. PROCEDURE TakeOffStack ( W : WinType ); (* Private *)
  341. VAR pw : WinType;
  342. BEGIN
  343. IF W = WinType(CoreWind._windowstack) THEN
  344. CoreWind._windowstack := W^.Next;
  345. ELSE
  346. pw := WinType(CoreWind._windowstack);
  347. IF W # pw THEN
  348. LOOP
  349. IF (pw = NIL) THEN EXIT END;
  350. IF (pw^.Next = W) THEN pw^.Next := W^.Next; EXIT END;
  351. pw := pw^.Next;
  352. END;
  353. END;
  354. END;
  355. W^.Next := NIL;
  356. END TakeOffStack;
  357. PROCEDURE UpdateScreen ( W : WinType; X,Y : AbsCoord; Len : CARDINAL );
  358. (* Updates the screen from the window buffer *)
  359. VAR
  360. NextLen,
  361. NextX : AbsCoord;
  362. w : WinType;
  363. oxa,oxb,ax,bx : AbsCoord;
  364. buff : ARRAY[0..ScreenWidth-1] OF CARDINAL;
  365. a : ADDRESS;
  366. BEGIN
  367. IF W^.WDef.Hidden THEN RETURN END;
  368. WHILE Len#0 DO
  369. (* adjust co ordinates for crossing windows *)
  370. NextLen := 0;
  371. w := WinType(CoreWind._windowstack);
  372. ax := X; bx := X+Len-1;
  373. LOOP
  374. IF (w = W)OR(w=NIL) THEN EXIT END;
  375. WITH w^ DO
  376. IF (Y>=WDef.Y1) AND (Y<=WDef.Y2) THEN
  377. oxa := WDef.X1; oxb := WDef.X2;
  378. IF (ax>=oxa) AND (bx<=oxb) THEN (* wiped out *)
  379. ax := bx+1; EXIT;
  380. ELSIF (ax<=oxb) AND (bx>=oxa) THEN (* some interaction *)
  381. IF (ax<oxa) AND (bx>oxb) THEN (* cut into two *)
  382. bx := oxa-1;
  383. NextX := oxb+1;
  384. NextLen := X+Len-NextX;
  385. ELSIF (bx>oxb) THEN (* left edge cut off *)
  386. ax := oxb+1;
  387. ELSIF (ax<oxa) THEN (* right edge cut off *)
  388. bx := oxa-1;
  389. END;
  390. END;
  391. END;
  392. w := Next;
  393. END;
  394. END;
  395. Len := bx-ax+1;
  396. IF Len # 0 THEN
  397. WITH W^ DO
  398. a := ADR(Buffer^[(ax-WDef.X1)+(Y-WDef.Y1)*OWidth]);
  399. IF IsPalette THEN
  400. CoreWind._palxlat(ADR(buff),a,Len,ADR(PalAttr));
  401. a := ADR(buff);
  402. END;
  403. CoreWind._buffertoscreen ( ax,Y,a,Len);
  404. END;
  405. END;
  406. X := NextX;
  407. Len := NextLen;
  408. END;
  409. END UpdateScreen;
  410. PROCEDURE RedrawSection ( W : WinType;
  411. X1,Y1,X2,Y2 : AbsCoord ); (* Private *)
  412. (* redraws rectangular portion of the window from the buffer *)
  413. VAR
  414. Y : AbsCoord;
  415. BEGIN
  416. FOR Y := Y1 TO Y2 DO
  417. UpdateScreen(W,X1,Y,X2-X1+1);
  418. END;
  419. END RedrawSection;
  420. PROCEDURE RedrawWindow ( W : WinType ); (* Private *)
  421. BEGIN
  422. WITH W^ DO
  423. RedrawSection ( W,WDef.X1,WDef.Y1,WDef.X2,WDef.Y2 );
  424. END;
  425. END RedrawWindow;
  426. PROCEDURE RedrawWindowPane ( W : WinType ); (* Private *)
  427. BEGIN
  428. WITH W^ DO
  429. RedrawSection ( W,XA,YA,XB,YB );
  430. END;
  431. END RedrawWindowPane;
  432. PROCEDURE DisplayBeneath ( W : WinType; NW : WinType ); (* Private *)
  433. (* Re-displays windows Obscured by W from NW *)
  434. VAR
  435. x1,x2,y1,y2 : AbsCoord;
  436. BEGIN
  437. WITH W^ DO
  438. WHILE NW#NIL DO
  439. IF ((WDef.X2>=NW^.WDef.X1)AND(NW^.WDef.X2>=WDef.X1) AND
  440. (WDef.Y2>=NW^.WDef.Y1)AND(NW^.WDef.Y2>=WDef.Y1)) THEN (* windows cross *)
  441. (* calculate Intersection *)
  442. IF WDef.X1>NW^.WDef.X1 THEN
  443. x1 := WDef.X1
  444. ELSE
  445. x1 := NW^.WDef.X1
  446. END;
  447. IF WDef.X2<NW^.WDef.X2 THEN
  448. x2 := WDef.X2
  449. ELSE
  450. x2 := NW^.WDef.X2
  451. END;
  452. IF WDef.Y1>NW^.WDef.Y1 THEN
  453. y1 := WDef.Y1
  454. ELSE
  455. y1 := NW^.WDef.Y1
  456. END;
  457. IF WDef.Y2<NW^.WDef.Y2 THEN
  458. y2 := WDef.Y2
  459. ELSE
  460. y2 := NW^.WDef.Y2
  461. END;
  462. RedrawSection (NW, x1,y1,x2,y2 );
  463. END;
  464. NW := NW^.Next;
  465. END;
  466. END;
  467. END DisplayBeneath;
  468. PROCEDURE PutOnTop ( W : WinType );
  469. (*
  470. Puts the specified window on the top of the window stack
  471. Ensuring that it is fully visible.
  472. If this results in other windows becoming obscured then a buffer
  473. is allocated for each of these windows.
  474. All otherwise undirected output (ie with no Use) will appear
  475. within this window.
  476. *)
  477. BEGIN
  478. (*%T _mthread *)
  479. Lock();
  480. (*%E *)
  481. CheckWindow(W);
  482. IF W # WinType(CoreWind._windowstack) THEN
  483. TakeOffStack( W );
  484. W^.Next := WinType(CoreWind._windowstack);
  485. CoreWind._windowstack := W;
  486. WITH W^ DO
  487. WDef.Hidden := FALSE;
  488. RedrawWindow ( W );
  489. IF WDef.CursorOn THEN
  490. Use ( W );
  491. CursorOn;
  492. END;
  493. END;
  494. END;
  495. Use ( W );
  496. ResetCursor;
  497. (*%T _mthread *)
  498. Unlock();
  499. (*%E *)
  500. END PutOnTop;
  501. PROCEDURE Hide ( W : WinType );
  502. (*
  503. Removes window from the Window stack and also the screen
  504. Placing the windows contents in a buffer for possible re-display later
  505. Uncovers obscured windows
  506. *)
  507. VAR
  508. p : WinType;
  509. w : WinType;
  510. BEGIN
  511. (*%T _mthread *)
  512. Lock();
  513. (*%E *)
  514. CheckWindow(W);
  515. WITH W^ DO
  516. IF NOT WDef.Hidden THEN
  517. w := W^.Next;
  518. TakeOffStack ( W );
  519. DisplayBeneath ( W, w );
  520. IF WDef.CursorOn THEN CursorOff; WDef.CursorOn := TRUE; END;
  521. WDef.Hidden := TRUE;
  522. END;
  523. END;
  524. ResetCursor;
  525. (*%T _mthread *)
  526. Unlock();
  527. (*%E *)
  528. END Hide;
  529. PROCEDURE PutBeneath ( W : WinType; WA : WinType );
  530. (*
  531. Puts window W beneath window WA
  532. *)
  533. VAR
  534. p : WinType;
  535. w : WinType;
  536. BEGIN
  537. Hide(W);
  538. (*%T _mthread *)
  539. Lock();
  540. (*%E *)
  541. CheckWindow(WA);
  542. WITH WA^ DO
  543. IF NOT WDef.Hidden THEN
  544. w := Next;
  545. Next := W;
  546. W^.Next := w;
  547. W^.WDef.Hidden := FALSE;
  548. RedrawWindow ( W );
  549. END;
  550. END;
  551. ResetCursor;
  552. (*%T _mthread *)
  553. Unlock();
  554. (*%E *)
  555. END PutBeneath;
  556. PROCEDURE SnapShot;
  557. (* Updates the Window buffer from the screen *)
  558. (* only works with non palette windows *)
  559. VAR
  560. W : WinType;
  561. y : CARDINAL;
  562. p : CARDINAL;
  563. BEGIN
  564. W := CurWin();
  565. WITH W^ DO
  566. WITH WDef DO
  567. IF NOT IsPalette THEN
  568. p := 0;
  569. FOR y := Y1 TO Y2 DO
  570. CoreWind._screentobuffer(X1,y,ADR(Buffer^[p]),OWidth);
  571. INC(p,OWidth);
  572. END;
  573. END;
  574. END;
  575. END;
  576. (*%T _mthread *)
  577. Unlock();
  578. (*%E *)
  579. END SnapShot;
  580. (* ------------------------- *)
  581. (* Window disposal *)
  582. (* ------------------------- *)
  583. PROCEDURE DisposeTitle ( W : WinType );
  584. BEGIN
  585. WITH W^ DO
  586. IF TMode # NoTitle THEN
  587. DEALLOCATE(Title,Str.Length(Title^)+1);
  588. TMode := NoTitle;
  589. END;
  590. END;
  591. END DisposeTitle;
  592. PROCEDURE Close ( VAR W : WinType );
  593. (*
  594. removes the specified window from the screen
  595. deletes window descriptor and
  596. de-allocates any buffers previously allocated.
  597. *)
  598. VAR
  599. w : WinType;
  600. u,up,un : UseListPtr;
  601. BEGIN
  602. (*%T _mthread *)
  603. Lock();
  604. (*%E *)
  605. Hide ( W );
  606. TakeOffStack (W);
  607. UnlinkCursor(W);
  608. WITH W^ DO
  609. IF (Buffer # NIL) THEN DEALLOCATE(Buffer,OWidth * ODepth * 2); END;
  610. END;
  611. up := UseListPtr(CoreWind._uselist);
  612. u := up^.Next;
  613. WHILE (u#NIL) DO
  614. un := u^.Next;
  615. IF (u^.Wind = W) THEN
  616. up^.Next := un;
  617. DISPOSE(u);
  618. ELSE
  619. up := u;
  620. END;
  621. u := un;
  622. END;
  623. DisposeTitle(W);
  624. W^.Guard := GuardConst; (* Invalidate guard *)
  625. DISPOSE(W);
  626. (*%T _mthread *)
  627. Unlock();
  628. (*%E *)
  629. END Close;
  630. PROCEDURE Used () : WinType;
  631. (*
  632. Returns The current window being used for output for this process
  633. If no window assigned by Use then returns Top
  634. *)
  635. VAR
  636. w : WinType;
  637. BEGIN
  638. w := CurWin();
  639. (*%T _mthread *)
  640. Unlock();
  641. (*%E *)
  642. RETURN w;
  643. END Used;
  644. PROCEDURE Top () : WinType;
  645. (*
  646. Returns The current top Window
  647. *)
  648. VAR w : WinType;
  649. BEGIN
  650. (*%T _mthread *)
  651. Lock();
  652. (*%E *)
  653. w := WinType(CoreWind._windowstack);
  654. (*%T _mthread *)
  655. Unlock();
  656. (*%E *)
  657. RETURN w;
  658. END Top;
  659. PROCEDURE At (X,Y : AbsCoord) : WinType;
  660. (*
  661. Returns the window displayed at the absolute position X,Y
  662. *)
  663. VAR
  664. W : WinType;
  665. BEGIN
  666. (*%T _mthread *)
  667. Lock();
  668. (*%E *)
  669. W := WinType(CoreWind._windowstack);
  670. LOOP
  671. IF W = NIL THEN EXIT END;
  672. WITH W^ DO
  673. IF (Y >= WDef.Y1) AND (Y <= WDef.Y2) AND
  674. (X >= WDef.X1) AND (X <= WDef.X2) THEN
  675. EXIT
  676. END;
  677. W := Next;
  678. END;
  679. END;
  680. (*%T _mthread *)
  681. Unlock();
  682. (*%E *)
  683. RETURN W;
  684. END At;
  685. PROCEDURE ObscuredAt (W : WinType; X,Y : RelCoord ) : BOOLEAN;
  686. (*
  687. Returns if the specified window is obscured at the specified position
  688. *)
  689. VAR
  690. b : BOOLEAN;
  691. w : WinType;
  692. BEGIN
  693. (*%T _mthread *)
  694. Lock();
  695. (*%E *)
  696. CheckWindow(W);
  697. WITH W^ DO
  698. IF WDef.Hidden THEN
  699. b:= TRUE;
  700. ELSE
  701. INC(X,XA-1); INC(Y,YA-1);
  702. w := WinType(CoreWind._windowstack);
  703. LOOP
  704. IF w = W THEN b := FALSE; EXIT END;
  705. IF w = NIL THEN b := TRUE; EXIT END;
  706. WITH w^ DO
  707. IF (Y>=WDef.Y1) AND (Y<=WDef.Y2) AND
  708. (X>=WDef.X1) AND (X<=WDef.X2) THEN
  709. b := TRUE;
  710. EXIT
  711. END;
  712. w := Next;
  713. END;
  714. END;
  715. END;
  716. END;
  717. (*%T _mthread *)
  718. Unlock();
  719. (*%E *)
  720. RETURN b;
  721. END ObscuredAt;
  722. PROCEDURE WindowWrite ( W : WinType;
  723. x,y : RelCoord;
  724. Len : CARDINAL;
  725. str : ADDRESS;
  726. frame : BOOLEAN ); (* Private *)
  727. VAR
  728. Attr : CARDINAL;
  729. X,Y : AbsCoord;
  730. BEGIN
  731. IF Len>0 THEN
  732. WITH W^ DO
  733. IF IsPalette THEN
  734. IF frame THEN
  735. Attr := VAL(CARDINAL,FramePaletteColor);
  736. ELSE
  737. Attr := VAL(CARDINAL,CurPalColor);
  738. END;
  739. ELSIF frame THEN
  740. Attr := ORD(WDef.FrameFore)+ORD(WDef.FrameBack)*16;
  741. ELSE
  742. Attr := ORD(WDef.Foreground)+ORD(WDef.Background)*16;
  743. END;
  744. X := x+XA-1; Y := y+YA-1;
  745. IF Len+X-1 > WDef.X2 THEN Len := WDef.X2+1-X END;
  746. CoreWind._bufferwrite (ADR(Buffer^[X-WDef.X1+(Y-WDef.Y1)*OWidth]),str,Len,Attr);
  747. UpdateScreen(W,X,Y,Len);
  748. END;
  749. END;
  750. END WindowWrite;
  751. PROCEDURE DrawFrame ( W : WinType );
  752. VAR
  753. s : ARRAY[0..81] OF CHAR;
  754. w,l,tl : CARDINAL;
  755. i : CARDINAL;
  756. PROCEDURE PutTitle ( mode : CARDINAL; row : CARDINAL );
  757. VAR
  758. i,j : CARDINAL;
  759. BEGIN
  760. WITH W^ DO
  761. CASE mode OF
  762. 0 : i := 1 |
  763. 1 : i := (Width-tl) DIV 2 + 1; |
  764. 2 : i := Width+1-tl |
  765. ELSE
  766. i := MAX(CARDINAL);
  767. END;
  768. j := 0;
  769. WHILE (i<=Width)AND(j<tl) DO
  770. s[i] := Title^[j]; INC(i); INC(j)
  771. END;
  772. WindowWrite (W,0,row,OWidth,ADR(s),TRUE);
  773. END;
  774. END PutTitle;
  775. BEGIN
  776. WITH W^ DO
  777. IF NOT WDef.FrameOn THEN
  778. IF (OWidth<3)OR(ODepth<3) THEN RETURN END; (* No Room *)
  779. WDef.FrameOn := TRUE;
  780. ClipFrame(W);
  781. ResetCursor;
  782. END;
  783. s[0] := WDef.FrameDef[0];
  784. Lib.Fill(ADR(s[1]),Width,WDef.FrameDef[1]);
  785. s[Width+1] := WDef.FrameDef[2];
  786. IF TMode # NoTitle THEN
  787. tl := Str.Length(Title^);
  788. IF tl>Width THEN tl := Width END;
  789. END;
  790. PutTitle(ORD(TMode-LeftUpperTitle),0);
  791. (* Sides *)
  792. FOR i := 1 TO Depth DO
  793. WindowWrite(W,0,i,1,ADR(WDef.FrameDef[3]),TRUE);
  794. WindowWrite(W,Width+1,i,1,ADR(WDef.FrameDef[4]),TRUE);
  795. END;
  796. s[0] := WDef.FrameDef[5];
  797. Lib.Fill(ADR(s[1]),Width,WDef.FrameDef[6]);
  798. s[Width+1] := WDef.FrameDef[7];
  799. PutTitle(ORD(TMode-LeftLowerTitle),Depth+1);
  800. END;
  801. END DrawFrame;
  802. PROCEDURE SetFrame ( W : WinType;
  803. Frame : FrameStr;
  804. Fore, Back : Color );
  805. (*
  806. Put a frame around the specified window
  807. With Title String and border definition (see above)
  808. having specified fore/background colours for the border
  809. *)
  810. BEGIN
  811. (*%T _mthread *)
  812. Lock();
  813. (*%E *)
  814. CheckWindow(W);
  815. WITH W^ DO
  816. WDef.FrameDef := Frame;
  817. WDef.FrameFore := Fore;
  818. WDef.FrameBack := Back;
  819. END;
  820. DrawFrame(W);
  821. (*%T _mthread *)
  822. Unlock();
  823. (*%E *)
  824. END SetFrame;
  825. PROCEDURE MergeWindows ( s,d : WinType );
  826. (* slightly complicated procedure to merge two windows
  827. s is new (hidden) window
  828. d is old window to be merged into
  829. *)
  830. VAR
  831. w : WinDescriptor;
  832. r,wd : CARDINAL;
  833. sw,sd,so,sp : CARDINAL;
  834. dw,dd,do,dp : CARDINAL;
  835. BEGIN
  836. s^.CurrentX := d^.CurrentX;
  837. s^.CurrentY := d^.CurrentY;
  838. s^.CursorChain := d^.CursorChain;
  839. s^.UserRecord := d^.UserRecord;
  840. s^.CurPalColor := d^.CurPalColor;
  841. s^.Title := d^.Title;
  842. s^.TMode := d^.TMode;
  843. d^.TMode := NoTitle;
  844. d^.WDef.CursorOn := FALSE;
  845. w := d^; d^ := s^; s^ := w;
  846. WITH s^ DO
  847. sw := OWidth; sd := ODepth;
  848. IF WDef.FrameOn THEN
  849. DEC(sw,2); DEC(sd,2);
  850. sp := (OWidth+1);
  851. ELSE
  852. sp := 0;
  853. END;
  854. Guard := GuardConst+CARDINAL(Seg(s^));
  855. END;
  856. WITH d^ DO
  857. dw := OWidth; dd := ODepth;
  858. IF WDef.FrameOn THEN
  859. DEC(dw,2); DEC(dd,2);
  860. dp := OWidth+1;
  861. ELSE
  862. dp := 0;
  863. END;
  864. Guard := GuardConst+CARDINAL(Seg(d^));
  865. END;
  866. IF sd < dd THEN wd := sd ELSE wd := dd END;
  867. FOR r := 0 TO wd-1 DO
  868. IF sw>=dw THEN
  869. Lib.WordMove(ADR(s^.Buffer^[sp]),ADR(d^.Buffer^[dp]),dw);
  870. ELSE
  871. Lib.WordMove(ADR(s^.Buffer^[sp]),ADR(d^.Buffer^[dp]),sw);
  872. BufferSpaceFill(d,dp+sw,dw-sw);
  873. END;
  874. INC(sp,s^.OWidth); INC(dp,d^.OWidth);
  875. END;
  876. (* now fill rest *)
  877. IF wd<dd THEN
  878. FOR r := wd TO dd-1 DO
  879. BufferSpaceFill(d,dp,dw);
  880. INC(dp,d^.OWidth);
  881. END
  882. END;
  883. IF d^.WDef.FrameOn THEN DrawFrame(d) END;
  884. IF NOT s^.WDef.Hidden THEN
  885. d^.Next := s;
  886. d^.WDef.Hidden := FALSE;
  887. RedrawWindow(d);
  888. END;
  889. Close(s);
  890. END MergeWindows;
  891. PROCEDURE IGotoXY ( W : WinType; X,Y : RelCoord );
  892. (*
  893. Sets the current X Y position of the pane currently being used
  894. *)
  895. BEGIN
  896. WITH W^ DO CurrentX := X; CurrentY := Y END;
  897. IF WinType(CoreWind._cursorstack) = W THEN ResetCursor END;
  898. END IGotoXY;
  899. (* ------------------------- *)
  900. (* Palette procedures *)
  901. (* ------------------------- *)
  902. PROCEDURE GetPal ( W : WinType; VAR Pal : PaletteDef );
  903. VAR
  904. i : PaletteRange;
  905. BEGIN
  906. CheckWindow(W);
  907. WITH W^ DO
  908. FOR i := 0 TO PaletteMax DO
  909. Pal[i].Fore := Color(PalAttr[i] MOD 16);
  910. Pal[i].Back := Color(PalAttr[i] DIV 16);
  911. END;
  912. END;
  913. END GetPal;
  914. PROCEDURE SetPal ( W : WinType; VAR Pal : PaletteDef );
  915. VAR
  916. i : PaletteRange;
  917. BEGIN
  918. CheckWindow(W);
  919. WITH W^ DO
  920. FOR i := 0 TO PaletteMax DO
  921. PalAttr[i] := VAL(SHORTCARD,ORD(Pal[i].Fore)+ORD(Pal[i].Back)*16);
  922. END;
  923. IsPalette := TRUE;
  924. END;
  925. END SetPal;
  926. PROCEDURE PaletteOpen(WD: WinDef; Pal: PaletteDef) : WinType;
  927. (*
  928. Opens a window on the screen ready for use
  929. *)
  930. VAR
  931. W : WinType;
  932. BEGIN
  933. (*%T _mthread *)
  934. Lock();
  935. (*%E *)
  936. W := MakeWindow (WD);
  937. SetPal(W,Pal);
  938. WITH W^ DO
  939. ALLOCATE ( Buffer,OWidth*ODepth*2);
  940. BufferSpaceFill(W,0,OWidth*ODepth);
  941. IF WD.FrameOn THEN
  942. SetFrame(W,WDef.FrameDef,WDef.FrameFore,WDef.FrameBack);
  943. END;
  944. END;
  945. IF WD.Hidden THEN
  946. Use ( W )
  947. ELSE
  948. PutOnTop ( W )
  949. END;
  950. (*%T _mthread *)
  951. Unlock();
  952. (*%E *)
  953. RETURN W;
  954. END PaletteOpen;
  955. PROCEDURE SetPaletteColor ( c : PaletteRange );
  956. VAR
  957. W : WinType;
  958. BEGIN
  959. W := CurWin();
  960. W^.CurPalColor := c;
  961. (*%T _mthread *)
  962. Unlock();
  963. (*%E *)
  964. END SetPaletteColor;
  965. PROCEDURE PaletteColor() : PaletteRange;
  966. VAR
  967. W : WinType;
  968. BEGIN
  969. W := CurWin();
  970. (*%T _mthread *)
  971. Unlock();
  972. (*%E *)
  973. RETURN W^.CurPalColor;
  974. END PaletteColor;
  975. PROCEDURE SetPalette(W: WinType; Pal: PaletteDef);
  976. (*
  977. Changes the Palette of the specified window,
  978. redisplaying the changed colors
  979. *)
  980. BEGIN
  981. (*%T _mthread *)
  982. Lock();
  983. (*%E *)
  984. SetPal(W,Pal);
  985. RedrawWindow(W);
  986. (*%T _mthread *)
  987. Unlock();
  988. (*%E *)
  989. END SetPalette;
  990. PROCEDURE PaletteColorUsed(W: WinType; pc: PaletteRange) : BOOLEAN;
  991. (*
  992. Returns if color in use anywhere in the window
  993. *)
  994. VAR
  995. p : CARDINAL;
  996. l : CARDINAL;
  997. m : CARDINAL;
  998. ba : POINTER TO ARRAY[0..MAX(CARDINAL)-1] OF SHORTCARD;
  999. BEGIN
  1000. CheckWindow(W);
  1001. WITH W^ DO
  1002. ba := ADR(Buffer^);
  1003. p := 0;
  1004. m := OWidth*ODepth*2;
  1005. LOOP
  1006. l := m-p;
  1007. p := p+Lib.ScanR(ADR(ba^[p]),l,pc);
  1008. IF p >= m THEN RETURN FALSE END;
  1009. IF ODD(p) THEN RETURN TRUE END;
  1010. INC(p);
  1011. END;
  1012. END;
  1013. END PaletteColorUsed;
  1014. (* ------------------------- *)
  1015. (* Move resize procedure *)
  1016. (* ------------------------- *)
  1017. PROCEDURE Change(W:WinType;X1,Y1,X2,Y2:AbsCoord);
  1018. (* Changes the size and/or position of the specified window The *)
  1019. (* contents of the window will be moved with it *)
  1020. VAR
  1021. nw : WinType;
  1022. wd : WinDef;
  1023. pal : PaletteDef;
  1024. save : WinType;
  1025. min : CARDINAL;
  1026. BEGIN
  1027. CheckWindow(W);
  1028. save := CurWin();
  1029. WITH W^ DO
  1030. IF X2 >= ScreenWidth THEN
  1031. X2 := ScreenWidth - 1;
  1032. END; (*IF*)
  1033. IF Y2 >= CurrentScreenDepth THEN
  1034. Y2 := CurrentScreenDepth - 1;
  1035. END; (*IF*)
  1036. wd := WDef;
  1037. IF wd.FrameOn THEN
  1038. min := 2;
  1039. ELSE
  1040. min := 0;
  1041. END; (*IF*)
  1042. IF (X1 + min > X2) OR (Y1 + min > Y2) THEN
  1043. (*%T _mthread *)
  1044. Unlock();
  1045. (*%E *)
  1046. RETURN;
  1047. END; (*IF*)
  1048. wd.X1 := X1;
  1049. wd.Y1 := Y1;
  1050. wd.X2 := X2;
  1051. wd.Y2 := Y2;
  1052. wd.Hidden := TRUE;
  1053. IF IsPalette THEN
  1054. GetPal(W,pal);
  1055. nw := PaletteOpen(wd,pal);
  1056. ELSE
  1057. nw := Open(wd);
  1058. END; (*IF*)
  1059. MergeWindows(nw,W);
  1060. ClipFrame (W);
  1061. IF CurrentX > Width THEN
  1062. CurrentX := Width;
  1063. END; (*IF*)
  1064. IF CurrentY > Depth THEN
  1065. CurrentY := Depth;
  1066. END; (*IF*)
  1067. ResetCursor;
  1068. END; (*WITH*)
  1069. Use(save); (* restore used window *)
  1070. (*%T _mthread *)
  1071. Unlock();
  1072. (*%E *)
  1073. END Change;
  1074. (* ------------------------- *)
  1075. (* Multi process support *)
  1076. (* ------------------------- *)
  1077. PROCEDURE NullProc;
  1078. BEGIN
  1079. END NullProc;
  1080. PROCEDURE SetProcessLocks ( LockProc,UnlockProc : LockProc );
  1081. BEGIN
  1082. (*%T _mthread *)
  1083. Lock := LockProc;
  1084. Unlock := UnlockProc;
  1085. CoreWind._multip := TRUE;
  1086. (*%E *)
  1087. END SetProcessLocks;
  1088. (* ------------------------- *)
  1089. (* Window output *)
  1090. (* ------------------------- *)
  1091. PROCEDURE DeleteLine ( W : WinType; Y : RelCoord );
  1092. VAR
  1093. r,p : CARDINAL;
  1094. BEGIN
  1095. CheckWindow(W);
  1096. WITH W^ DO
  1097. p := XA-WDef.X1+(YA-WDef.Y1+Y-1)*OWidth;
  1098. FOR r := Y TO Depth-1 DO
  1099. Lib.Move(ADR(Buffer^[p+OWidth]),ADR(Buffer^[p]),Width*2);
  1100. INC(p,OWidth);
  1101. END;
  1102. BufferSpaceFill(W,p,Width);
  1103. RedrawSection ( W,XA,Y+YA-1,XB,YB );
  1104. END;
  1105. END DeleteLine;
  1106. PROCEDURE Clear;
  1107. (*
  1108. clears the current window
  1109. *)
  1110. VAR
  1111. r,p : CARDINAL;
  1112. W : WinType;
  1113. BEGIN
  1114. W := CurWin();
  1115. WITH W^ DO
  1116. p := XA-WDef.X1+(YA-WDef.Y1)*OWidth;
  1117. FOR r := 1 TO Depth DO
  1118. BufferSpaceFill(W,p,Width);
  1119. INC(p,OWidth);
  1120. END;
  1121. RedrawWindowPane(W);
  1122. END;
  1123. IGotoXY(W,1,1);
  1124. (*%T _mthread *)
  1125. Unlock();
  1126. (*%E *)
  1127. END Clear;
  1128. PROCEDURE ClrEol;
  1129. (*
  1130. clears from the cursor to the end of line
  1131. *)
  1132. VAR
  1133. W : WinType;
  1134. BEGIN
  1135. W := CurWin();
  1136. WITH W^ DO
  1137. BufferSpaceFill(W,XA-WDef.X1+CurrentX-1+(YA-WDef.Y1+CurrentY-1)*OWidth,
  1138. Width-CurrentX+1);
  1139. RedrawSection ( W,XA-1+CurrentX,YA-1+CurrentY,XB,YA-1+CurrentY );
  1140. END;
  1141. (*%T _mthread *)
  1142. Unlock();
  1143. (*%E *)
  1144. END ClrEol;
  1145. (*%F _OS2 *)
  1146. PROCEDURE Bell;
  1147. VAR
  1148. R : SYSTEM.Registers;
  1149. BEGIN
  1150. WITH R DO
  1151. AX := 0E07H;
  1152. BL := 0;
  1153. Lib.Intr(R,10H);
  1154. END;
  1155. END Bell;
  1156. (*%E *)
  1157. (*%T _OS2 *)
  1158. PROCEDURE Bell;
  1159. BEGIN
  1160. Dos.Beep(1000,300);
  1161. END Bell;
  1162. (*%E *)
  1163. PROCEDURE WriteC ( W : WinType; C : CHAR);
  1164. VAR
  1165. nx : CARDINAL;
  1166. BEGIN
  1167. WITH W^ DO
  1168. CASE C OF
  1169. CHR(12) : Clear;
  1170. IGotoXY(W,1,1);
  1171. | CHR(10) : IF CurrentY=Depth THEN
  1172. DeleteLine ( W, 1 );
  1173. ELSE
  1174. IGotoXY(W,CurrentX,CurrentY+1);
  1175. END;
  1176. | CHR(13) : (*ClrEol; change 1/7/88*) IGotoXY(W,1,CurrentY);
  1177. | CHR(08) : IF CurrentX>1 THEN
  1178. IGotoXY(W,CurrentX-1,CurrentY); WriteC(W,' ');
  1179. IGotoXY(W,CurrentX-1,CurrentY);
  1180. END;
  1181. | CHR(7) : Bell;
  1182. ELSE
  1183. IF CurrentX > Width THEN RETURN END;
  1184. WindowWrite(W,CurrentX,CurrentY,1,ADR(C),FALSE);
  1185. IF (CurrentX#Width)OR NOT WDef.WrapOn THEN
  1186. IGotoXY(W,CurrentX+1,CurrentY);
  1187. ELSE
  1188. IF CurrentY=Depth THEN
  1189. DeleteLine ( W, 1 );
  1190. IGotoXY(W,1,CurrentY);
  1191. ELSE
  1192. IGotoXY(W,1,CurrentY+1);
  1193. END;
  1194. END;
  1195. END;
  1196. END;
  1197. END WriteC;
  1198. PROCEDURE WriteOut (S : ARRAY OF CHAR);
  1199. VAR
  1200. W : WinType;
  1201. p,q,m : CARDINAL;
  1202. ss : CARDINAL;
  1203. BEGIN
  1204. W := CurWin();
  1205. WITH W^ DO
  1206. ss := HIGH(S)+1;
  1207. p := 0;
  1208. q := 0;
  1209. LOOP
  1210. (* first accumulate normal chars on same line *)
  1211. m := Width+p-CurrentX;
  1212. IF NOT W^.WDef.WrapOn THEN INC(m) END; (* can fit another char in *)
  1213. IF m > ss THEN m := ss END;
  1214. WHILE (q<m)AND(S[q]>=' ') DO INC(q) END;
  1215. (* now output the line *)
  1216. IF q > p THEN
  1217. WindowWrite(W,CurrentX,CurrentY,q-p,ADR(S[p]),FALSE);
  1218. IGotoXY(W,CurrentX+q-p,CurrentY);
  1219. END;
  1220. (* now output the special char *)
  1221. IF (S[q] = CHR(0)) OR (q > HIGH(S)) THEN EXIT ELSE WriteC(W,S[q]);
  1222. END;
  1223. INC(q);
  1224. p := q;
  1225. END;
  1226. END;
  1227. (*%T _mthread *)
  1228. Unlock();
  1229. (*%E *)
  1230. END WriteOut;
  1231. PROCEDURE DirectWrite ( X,Y : RelCoord; (* start co-ords *)
  1232. A : ADDRESS; (* address of char array *)
  1233. Len : CARDINAL ); (* length to be written *)
  1234. (*
  1235. writes directly to current window at the specified X,Y coordinates
  1236. with no check for special (ie control) chars or eol wrap
  1237. *)
  1238. VAR
  1239. W : WinType;
  1240. BEGIN
  1241. W := CurWin();
  1242. WindowWrite(W,X,Y,Len,A,FALSE);
  1243. (*%T _mthread *)
  1244. Unlock();
  1245. (*%E *)
  1246. END DirectWrite;
  1247. PROCEDURE GotoXY ( X,Y : RelCoord );
  1248. VAR
  1249. W : WinType;
  1250. BEGIN
  1251. W := CurWin();
  1252. ClipXY(W,X,Y);
  1253. IGotoXY(W,X,Y);
  1254. (*%T _mthread *)
  1255. Unlock();
  1256. (*%E *)
  1257. END GotoXY;
  1258. PROCEDURE WhereX ( ) : RelCoord;
  1259. VAR
  1260. W : WinType;
  1261. BEGIN
  1262. W := CurWin();
  1263. (*%T _mthread *)
  1264. Unlock();
  1265. (*%E *)
  1266. RETURN W^.CurrentX;
  1267. END WhereX;
  1268. PROCEDURE WhereY ( ) : RelCoord;
  1269. VAR
  1270. W : WinType;
  1271. BEGIN
  1272. W := CurWin();
  1273. (*%T _mthread *)
  1274. Unlock();
  1275. (*%E *)
  1276. RETURN W^.CurrentY;
  1277. END WhereY;
  1278. PROCEDURE ConvertCoords ( W : WinType ;
  1279. X,Y : RelCoord;
  1280. VAR XO,YO : AbsCoord );
  1281. BEGIN
  1282. CheckWindow(W);
  1283. XO := X+W^.XA-1; YO := Y+W^.YA-1;
  1284. END ConvertCoords;
  1285. PROCEDURE InsLine;
  1286. VAR
  1287. W : WinType;
  1288. r,p,p1 : CARDINAL;
  1289. BEGIN
  1290. W := CurWin();
  1291. WITH W^ DO
  1292. p := XA-WDef.X1+(YA-WDef.Y1+Depth-1)*OWidth;
  1293. FOR r := CurrentY TO Depth-1 DO
  1294. DEC(p,OWidth);
  1295. Lib.Move(ADR(Buffer^[p]),ADR(Buffer^[p+OWidth]),Width*2);
  1296. END;
  1297. BufferSpaceFill(W,p,Width);
  1298. RedrawSection ( W,XA,CurrentY+YA-1,XB,YB );
  1299. END;
  1300. (*%T _mthread *)
  1301. Unlock();
  1302. (*%E *)
  1303. END InsLine;
  1304. PROCEDURE DelLine;
  1305. VAR
  1306. W : WinType;
  1307. BEGIN
  1308. W := CurWin();
  1309. DeleteLine(W,W^.CurrentY);
  1310. (*%T _mthread *)
  1311. Unlock();
  1312. (*%E *)
  1313. END DelLine;
  1314. PROCEDURE TextColor ( c : Color );
  1315. VAR
  1316. W : WinType;
  1317. BEGIN
  1318. W := CurWin();
  1319. W^.WDef.Foreground := c;
  1320. (*%T _mthread *)
  1321. Unlock();
  1322. (*%E *)
  1323. END TextColor;
  1324. PROCEDURE TextBackground ( c : Color );
  1325. VAR
  1326. W : WinType;
  1327. BEGIN
  1328. W := CurWin();
  1329. W^.WDef.Background := c;
  1330. (*%T _mthread *)
  1331. Unlock();
  1332. (*%E *)
  1333. END TextBackground;
  1334. PROCEDURE SetWrap ( on : BOOLEAN );
  1335. VAR
  1336. W : WinType;
  1337. BEGIN
  1338. W := CurWin();
  1339. W^.WDef.WrapOn := on;
  1340. (*%T _mthread *)
  1341. Unlock();
  1342. (*%E *)
  1343. END SetWrap;
  1344. PROCEDURE Info ( W : WinType; VAR WD : WinDef );
  1345. (* gets information for specified window *)
  1346. BEGIN
  1347. (*%T _mthread *)
  1348. Lock();
  1349. (*%E *)
  1350. WD := W^.WDef;
  1351. (*%T _mthread *)
  1352. Unlock();
  1353. (*%E *)
  1354. END Info;
  1355. (* ------------------------- *)
  1356. (* Title procedure *)
  1357. (* ------------------------- *)
  1358. PROCEDURE SetTitle ( W : WinType;
  1359. NewTitle : ARRAY OF CHAR;
  1360. Mode : TitleMode );
  1361. (*
  1362. updates the window title within the window frame,
  1363. positioning it in the position defined by the title mode
  1364. *)
  1365. VAR
  1366. l : CARDINAL;
  1367. BEGIN
  1368. CheckWindow(W);
  1369. (*%T _mthread *)
  1370. Lock();
  1371. (*%E *)
  1372. DisposeTitle(W);
  1373. WITH W^ DO
  1374. IF Mode # NoTitle THEN
  1375. l := Str.Length(NewTitle);
  1376. ALLOCATE(Title,l+1);
  1377. Lib.Move(ADR(NewTitle),ADR(Title^),l);
  1378. Title^[l] := CHR(0);
  1379. END;
  1380. TMode := Mode;
  1381. END;
  1382. DrawFrame(W);
  1383. (*%T _mthread *)
  1384. Unlock;
  1385. (*%E *)
  1386. END SetTitle;
  1387. PROCEDURE ReadString ( VAR string : ARRAY OF CHAR );
  1388. VAR
  1389. c : CHAR;
  1390. line: ARRAY[0..82] OF CHAR;
  1391. p,H : CARDINAL;
  1392. W : WinType;
  1393. con : BOOLEAN;
  1394. BEGIN
  1395. W := CurWin();
  1396. PutOnTop(W);
  1397. con := W^.WDef.CursorOn;
  1398. CursorOn;
  1399. H := HIGH(string);
  1400. IF H>79 THEN H := 79 END;
  1401. p := 0;
  1402. LOOP
  1403. c := IO.RdKey();
  1404. IF (c=CHR(8))OR(c=CHR(127)) THEN
  1405. IF p>0 THEN DEC(p); IO.WrChar(CHR(8)) END;
  1406. ELSIF (c>=' ') THEN
  1407. IF p<=H THEN
  1408. IO.WrChar(c);
  1409. line[p] := c;
  1410. INC(p);
  1411. END;
  1412. ELSIF c=CHR(13) THEN
  1413. EXIT;
  1414. END;
  1415. END;
  1416. line[p] := CHR(0);
  1417. Str.Copy(string,line);
  1418. IF NOT con THEN CursorOff END;
  1419. (*%T _mthread *)
  1420. Unlock;
  1421. (*%E *)
  1422. IO.WrLn;
  1423. END ReadString;
  1424. (* Low level routines to read and write to the window buffer direct *)
  1425. PROCEDURE RdBufferLn ( W : WinType; (* Source window *)
  1426. X,Y : RelCoord; (* start co-ords *)
  1427. Dest : ADDRESS; (* address of buffer *)
  1428. Len : CARDINAL ); (* length in WORDs *)
  1429. VAR
  1430. AX,AY : AbsCoord;
  1431. BEGIN
  1432. WITH W^ DO
  1433. AX := X+XA-1; AY := Y+YA-1;
  1434. Lib.WordMove(ADR(Buffer^[AX-WDef.X1+(AY-WDef.Y1)*OWidth]),Dest,Len);
  1435. END;
  1436. END RdBufferLn;
  1437. PROCEDURE WrBufferLn ( W : WinType; (* Dest window *)
  1438. X,Y : RelCoord; (* start co-ords *)
  1439. Src : ADDRESS; (* address of buffer *)
  1440. Len : CARDINAL ); (* length in WORDs *)
  1441. VAR
  1442. AX,AY : AbsCoord;
  1443. BEGIN
  1444. WITH W^ DO
  1445. AX := X+XA-1; AY := Y+YA-1;
  1446. Lib.WordMove(Src,ADR(Buffer^[AX-WDef.X1+(AY-WDef.Y1)*OWidth]),Len);
  1447. UpdateScreen(W,AX,AY,Len);
  1448. END;
  1449. END WrBufferLn;
  1450. PROCEDURE InputStr ( VAR S : ARRAY OF CHAR );
  1451. VAR
  1452. ins : BOOLEAN;
  1453. k : CHAR;
  1454. x,y,p,l : CARDINAL;
  1455. BEGIN
  1456. x := WhereX(); y := WhereY();
  1457. p := MAX(CARDINAL);
  1458. p := 0;
  1459. ins := TRUE; (* Insert mode *)
  1460. LOOP
  1461. l := Str.Length(S);
  1462. IF p>l THEN p := l END;
  1463. IO.WrStr(S); ClrEol;
  1464. GotoXY(x+p,y);
  1465. k := IO.RdCharDirect();
  1466. IF k = 0C THEN (* Extended character *)
  1467. CASE IO.RdCharDirect() OF
  1468. | CHR(75) : k := CHR(19); (* LeftArr -> ^S *)
  1469. | CHR(77) : k := CHR(4) ; (* RightArr -> ^D *)
  1470. | CHR(71) : k := CHR(1) ; (* Home -> ^A *)
  1471. | CHR(79) : k := CHR(6) ; (* End -> ^F *)
  1472. | CHR(83) : k := CHR(7) ; (* Del -> ^G *)
  1473. | CHR(82) : k := CHR(22); (* Ins -> ^V *)
  1474. END;
  1475. END;
  1476. CASE k OF
  1477. | ' '..'~' : IF ins THEN Str.Insert(S,k,p);
  1478. ELSIF p=l THEN Str.Append(S,k);
  1479. ELSE S[p] := k;
  1480. END;
  1481. INC(p);
  1482. | CHR(1) : p := 0; (* Home *)
  1483. | CHR(6) : p := l; (* End *)
  1484. | CHR(19) : IF p>0 THEN DEC(p) END; (* Left *)
  1485. | CHR(4) : IF p<l THEN INC(p) END; (* Right *)
  1486. | CHR(7) : IF p<l THEN (* Del *)
  1487. Str.Delete(S,p,1);
  1488. END;
  1489. | CHR(8) : IF p>0 THEN (* BackSpace *)
  1490. DEC(p); Str.Delete(S,p,1);
  1491. END;
  1492. | CHR(22) : ins := NOT ins; (* Toggle Ins/Ovr *)
  1493. | CHR(13) : RETURN; (* Enter *)
  1494. END;
  1495. GotoXY(x,y);
  1496. END;
  1497. END InputStr;
  1498. (* ------------------------- *)
  1499. (* Main initialization *)
  1500. (* ------------------------- *)
  1501. CONST
  1502. ClearOnEntry = TRUE; (* Change to FALSE if automatic clear *)
  1503. (*%F _OS2 *)
  1504. VAR
  1505. R : SYSTEM.Registers;
  1506. WD : WinDef;
  1507. BEGIN
  1508. (*%T _mthread *)
  1509. Lock := NullProc;
  1510. Unlock := NullProc;
  1511. (*%E *)
  1512. CoreWind._multip := FALSE;
  1513. IO.WrStrRedirect := WriteOut;
  1514. IO.RdStrRedirect := ReadString;
  1515. CurrentScreenDepth := AbsCoord(CoreWind._getscreendepth());
  1516. IF NOT CoreWind._winsetup THEN
  1517. CoreWind._initscreentype(CGASnow);
  1518. R.AH := 3;
  1519. R.BH := SHORTCARD(CoreWind._activepage());
  1520. Lib.Intr(R,10H);
  1521. IF (R.CH<20H)AND(R.CL>0) THEN
  1522. CoreWind._cursorlines := R.CX;
  1523. ELSE
  1524. CoreWind._cursorlines := 0607H;
  1525. END;
  1526. CoreWind._windowstack := NIL;
  1527. NEW(UseListPtr(CoreWind._uselist));
  1528. UseListPtr(CoreWind._uselist)^.Next := NIL; (* dummy *)
  1529. CoreWind._cursorstack := NIL;
  1530. WD := FullScreenDef;
  1531. WD.Y2 := CurrentScreenDepth;
  1532. IF ClearOnEntry THEN
  1533. FullScreen := Open(WD);
  1534. ELSE
  1535. WD.Hidden := TRUE;
  1536. FullScreen := Open(WD);
  1537. SnapShot;
  1538. PutOnTop(FullScreen);
  1539. GotoXY(ORD(R.DL)+1,ORD(R.DH)+1);
  1540. END;
  1541. ELSE
  1542. FullScreen:=CoreWind._fullscreen;
  1543. END;
  1544. (*%E *)
  1545. (*%T _OS2 *)
  1546. VAR
  1547. Row, Col: CARDINAL;
  1548. WD: WinDef;
  1549. BEGIN
  1550. (*%T _mthread *)
  1551. Lock := Process.Lock;
  1552. Unlock := Process.Unlock;
  1553. (*%E *)
  1554. IO.WrStrRedirect := WriteOut;
  1555. IO.RdStrRedirect := ReadString;
  1556. CurrentScreenDepth := AbsCoord(CoreWind._getscreendepth());
  1557. IF NOT CoreWind._winsetup THEN
  1558. RealMode := NOT Lib.ProtectedMode();
  1559. IF Vio.GetCurType( CursorInfo, 0 ) = 0 THEN END;
  1560. CoreWind._initscreentype(CGASnow);
  1561. CoreWind._windowstack := NIL;
  1562. NEW(UseListPtr(CoreWind._uselist));
  1563. UseListPtr(CoreWind._uselist)^.Next := NIL; (* dummy *)
  1564. CoreWind._cursorstack := NIL;
  1565. WD := FullScreenDef;
  1566. WD.Y2 := CurrentScreenDepth;
  1567. IF ClearOnEntry THEN
  1568. FullScreen := Open(WD);
  1569. ELSE
  1570. WD.Hidden := TRUE;
  1571. FullScreen := Open(WD);
  1572. SnapShot;
  1573. PutOnTop(FullScreen);
  1574. Vio.GetCurPos(Row, Col, 0);
  1575. GotoXY(Col+1, Row+1);
  1576. END;
  1577. ELSE
  1578. FullScreen := CoreWind._fullscreen;
  1579. END;
  1580. (*%E *)
  1581. END Window.
  1582.