| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734 |
- (* Release 3.10 *)
- (*-------------------------------------------------------------------------*
- * *
- * WINDOW.MOD - Clipping text windows *
- * *
- * COPYRIGHT (C) 1987..1992 Clarion Software Corporation. *
- * All Rights Reserved *
- * *
- *--------------------------------------------------------------------------*)
- (*%F _fdata *)
- (*# call(seg_name => null) *)
- (*# data(seg_name => null) *)
- (*%E *)
- (*# module(implementation=>off) *)
- (*# call(o_a_copy=>off) *)
- (*# check(stack=>off,
- index=>off,
- range=>off,
- overflow=>off,
- nil_ptr=>off) *)
- IMPLEMENTATION MODULE Window;
- (*%F _OS2 *)
- IMPORT SYSTEM, Str, Lib, IO, CoreSig;
- (*%E *)
- (*%T _OS2 *)
- IMPORT SYSTEM, Str, Lib, Vio, Dos, IO, CoreSig;
- (*%E *)
- (*%T _mthread *)
- IMPORT Process;
- (*%E *)
- FROM Storage IMPORT ALLOCATE,DEALLOCATE;
- TYPE
- UseListPtr = POINTER TO UseListLink;
- UseListLink = RECORD
- Next : UseListPtr;
- Proc : ADDRESS;
- Wind : WinType;
- END;
- VAR
- (*%T _mthread *)
- Lock,Unlock : LockProc;
- (*%E *)
- CONST
- GuardConst = 4A4EH;
- PROCEDURE CheckWindow(W:WinType);
- BEGIN
- IF W^.Guard - Seg(W^) # GuardConst THEN
- Lib.RunTimeError(CoreSig._FatalErrorPos(),30H,'Invalid Window');
- END; (*IF*)
- END CheckWindow;
- PROCEDURE ClipFrame ( W : WinType );
- VAR
- i : CARDINAL;
- BEGIN
- WITH W^ DO
- IF WDef.FrameOn THEN i := 1 ELSE i := 0 END;
- IF XA < WDef.X1+i THEN
- XA := WDef.X1+i
- ELSIF XA > WDef.X2-i THEN
- XA := WDef.X2-i
- END;
- IF XB > WDef.X2-i THEN
- XB := WDef.X2-i
- ELSIF XB < WDef.X1+i THEN
- XB := WDef.X1+i
- END;
- IF YA < WDef.Y1+i THEN
- YA := WDef.Y1+i
- ELSIF YA > WDef.Y2-i THEN
- YA := WDef.Y2-i
- END;
- IF YB > WDef.Y2-i THEN
- YB := WDef.Y2-i
- ELSIF YB < WDef.Y1+i THEN
- YB := WDef.Y1+i
- END;
- Width := XB-XA+1; Depth := YB-YA+1;
- END;
- END ClipFrame;
- PROCEDURE ClipXY ( W : WinType; VAR X,Y : RelCoord );
- VAR
- mw,md : CARDINAL;
- BEGIN
- WITH W^ DO
- mw := Width; md := Depth;
- IF WDef.FrameOn AND NOT WDef.WrapOn THEN
- INC(md); INC(mw)
- ELSE
- IF X=0 THEN X := 1 END;
- IF Y=0 THEN Y := 1 END;
- END;
- IF X>mw THEN X := mw END;
- IF Y>md THEN Y := md END;
- END;
- END ClipXY;
- PROCEDURE BufferSpaceFill ( W : WinType; pos : CARDINAL; len : CARDINAL );
- BEGIN
- WITH W^ DO
- IF IsPalette THEN
- Lib.WordFill(ADR(Buffer^[pos]),len,32
- +VAL(CARDINAL,CurPalColor)*256);
- ELSE
- Lib.WordFill(ADR(Buffer^[pos]),len,32+
- ORD(WDef.Foreground)*256+ORD(WDef.Background)*4096);
- END;
- END;
- END BufferSpaceFill;
- PROCEDURE CurWin () : WinType;
- (* Returns The current window being used for output for this process *)
- (* If no window assigned by Use then returns Top. *)
- (* NB Locks window system and leaves locked if _mthread set. *)
- VAR
- u : UseListPtr;
- p : ADDRESS;
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- IF CoreWind._multip THEN
- (*%T _mthread *)
- p := SYSTEM.CurrentProcess();
- (*%E *)
- (*%F _mthread *)
- p := NIL;
- (*%E *)
- u := UseListPtr(CoreWind._uselist)^.Next;
- LOOP
- IF u = NIL THEN
- RETURN WinType(CoreWind._windowstack); (* Top() *)
- ELSIF p = u^.Proc THEN
- RETURN u^.Wind;
- END; (*IF*)
- u := u^.Next;
- END; (*LOOP*)
- END; (*IF*)
- u := UseListPtr(CoreWind._uselist)^.Next;
- IF u = NIL THEN
- RETURN WinType(CoreWind._windowstack); (* Top() *)
- END; (*IF*)
- RETURN u^.Wind;
- END CurWin;
- (*%F _OS2 *)
- PROCEDURE ResetCursor;
- VAR
- R : SYSTEM.Registers;
- mode : CARDINAL;
- BEGIN
- IF (CoreWind._cursorstack = NIL) OR
- ObscuredAt(WinType(CoreWind._cursorstack),WinType(CoreWind._cursorstack)^.CurrentX,WinType(CoreWind._cursorstack)^.CurrentY) THEN
- mode := 2000H;
- ELSE
- WITH WinType(CoreWind._cursorstack)^ DO
- WITH R DO
- AH := 2;
- BH := SHORTCARD(CoreWind._activepage());
- DL := SHORTCARD(XA+CurrentX-1);
- DH := SHORTCARD(YA+CurrentY-1);
- END;
- Lib.Intr(R,10H);
- END;
- mode := CoreWind._cursorlines;
- END;
- R.AH := 1;
- R.CX := mode;
- Lib.Intr(R,10H);
- END ResetCursor;
- (*%E *)
- (*%T _OS2 *)
- VAR
- CursorInfo : Vio.CURSORINFO;
- RealMode : BOOLEAN;
- PROCEDURE ResetCursor;
- VAR r : CARDINAL;
- BEGIN
- IF (CoreWind._cursorstack = NIL) OR
- ObscuredAt(WinType(CoreWind._cursorstack),WinType(CoreWind._cursorstack)^.CurrentX,WinType(CoreWind._cursorstack)^.CurrentY) THEN
- CursorInfo.attr := MAX(CARDINAL);
- ELSE
- WITH WinType(CoreWind._cursorstack)^ DO
- r := Vio.SetCurPos(YA+CurrentY-1,XA+CurrentX-1,0 );
- END;
- CursorInfo.attr := 0;
- END;
- r := Vio.SetCurType( CursorInfo,0);
- END ResetCursor;
- (*%E *)
- PROCEDURE UnlinkCursor ( W : WinType );
- VAR
- w : WinType;
- BEGIN
- w := WinType(CoreWind._cursorstack);
- IF w = W THEN CoreWind._cursorstack := w^.CursorChain END;
- LOOP
- IF w = NIL THEN RETURN END;
- IF w^.CursorChain = W THEN
- w^.CursorChain := W^.CursorChain;
- RETURN;
- END;
- w := w^.CursorChain;
- END;
- END UnlinkCursor;
- (* ------------------------- *)
- (* Cursor Control *)
- (* ------------------------- *)
- PROCEDURE CursorOn;
- VAR
- w,cw : WinType;
- BEGIN
- cw := CurWin();
- UnlinkCursor(cw);
- cw^.WDef.CursorOn := TRUE;
- IF NOT cw^.WDef.Hidden THEN
- cw^.CursorChain := WinType(CoreWind._cursorstack);
- CoreWind._cursorstack := cw;
- END;
- ResetCursor;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END CursorOn;
- PROCEDURE CursorOff;
- VAR
- w,cw : WinType;
- BEGIN
- cw := CurWin();
- UnlinkCursor(cw);
- cw^.WDef.CursorOn := FALSE;
- ResetCursor;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END CursorOff;
- (* ------------------------- *)
- (* Window creation *)
- (* ------------------------- *)
- PROCEDURE MakeWindow ( VAR WD : WinDef ) : WinType;
- (*
- Creates a new Window descriptor
- The size is Inclusive of frame if needed
- does not allocate buffer
- *)
- VAR W : WinType; min : CARDINAL;
- BEGIN
- NEW(W);
- WITH W^ DO
- WITH WD DO
- IF X2 >= ScreenWidth THEN X2:=ScreenWidth-1 END;
- IF Y2 >= CurrentScreenDepth THEN Y2:=CurrentScreenDepth-1 END;
- IF WD.FrameOn THEN min := 2 ELSE min := 0 END;
- IF (X1+min>X2) THEN X2 := X1+min END;
- IF (Y1+min>Y2) THEN Y2 := Y1+min END;
- XA := X1; YA := Y1; XB := X2; YB := Y2;
- Width := X2-X1+1; Depth := Y2-Y1+1;
- END;
- WDef := WD;
- OWidth := Width; ODepth := Depth;
- CurrentX := 1;
- CurrentY := 1;
- Next := NIL;
- Buffer := NIL;
- UserRecord := NIL;
- IsPalette := FALSE;
- CurPalColor := NormalPaletteColor;
- TMode := NoTitle;
- Guard := GuardConst+CARDINAL(Seg(W^));
- CursorChain := NIL;
- Title := NIL;
- END;
- ClipFrame(W);
- RETURN W;
- END MakeWindow;
- PROCEDURE Open ( WD : WinDef ) : WinType;
- (*
- Opens a window on the screen ready for use
- *)
- VAR
- W : WinType;
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- W := MakeWindow (WD);
- WITH W^ DO
- ALLOCATE ( Buffer,OWidth*ODepth*2);
- BufferSpaceFill(W,0,OWidth*ODepth);
- IF WD.FrameOn THEN
- SetFrame(W,WDef.FrameDef,WDef.FrameFore,WDef.FrameBack);
- END;
- END;
- IF WD.Hidden THEN
- Use ( W )
- ELSE
- PutOnTop ( W )
- END;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- RETURN W;
- END Open;
- (* ------------------------- *)
- (* Window stack manipulation *)
- (* and screen redraw *)
- (* ------------------------- *)
- PROCEDURE Use ( W : WinType );
- (*
- Causes all subsequent output (by the current process)
- to appear in the specified Window
- NB does not have to be Top Window (or in fact on the screen at all)
- UseListPtr(CoreWind._uselist) is the MRU window
- *)
- VAR
- p : ADDRESS;
- u : UseListPtr;
- up : UseListPtr;
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- CheckWindow(W);
- (*%T _mthread *)
- p := SYSTEM.CurrentProcess();
- (*%E *)
- (*%F _mthread *)
- p := NIL;
- (*%E *)
- up := UseListPtr(CoreWind._uselist);
- u := up^.Next;
- LOOP
- IF u = NIL THEN NEW(u); u^.Proc := p; EXIT END;
- IF p = u^.Proc THEN up^.Next := u^.Next; EXIT END;
- up := u; u := u^.Next;
- END;
- u^.Next := UseListPtr(CoreWind._uselist)^.Next;
- UseListPtr(CoreWind._uselist)^.Next := u;
- u^.Wind := W;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END Use;
- PROCEDURE TakeOffStack ( W : WinType ); (* Private *)
- VAR pw : WinType;
- BEGIN
- IF W = WinType(CoreWind._windowstack) THEN
- CoreWind._windowstack := W^.Next;
- ELSE
- pw := WinType(CoreWind._windowstack);
- IF W # pw THEN
- LOOP
- IF (pw = NIL) THEN EXIT END;
- IF (pw^.Next = W) THEN pw^.Next := W^.Next; EXIT END;
- pw := pw^.Next;
- END;
- END;
- END;
- W^.Next := NIL;
- END TakeOffStack;
- PROCEDURE UpdateScreen ( W : WinType; X,Y : AbsCoord; Len : CARDINAL );
- (* Updates the screen from the window buffer *)
- VAR
- NextLen,
- NextX : AbsCoord;
- w : WinType;
- oxa,oxb,ax,bx : AbsCoord;
- buff : ARRAY[0..ScreenWidth-1] OF CARDINAL;
- a : ADDRESS;
- BEGIN
- IF W^.WDef.Hidden THEN RETURN END;
- WHILE Len#0 DO
- (* adjust co ordinates for crossing windows *)
- NextLen := 0;
- w := WinType(CoreWind._windowstack);
- ax := X; bx := X+Len-1;
- LOOP
- IF (w = W)OR(w=NIL) THEN EXIT END;
- WITH w^ DO
- IF (Y>=WDef.Y1) AND (Y<=WDef.Y2) THEN
- oxa := WDef.X1; oxb := WDef.X2;
- IF (ax>=oxa) AND (bx<=oxb) THEN (* wiped out *)
- ax := bx+1; EXIT;
- ELSIF (ax<=oxb) AND (bx>=oxa) THEN (* some interaction *)
- IF (ax<oxa) AND (bx>oxb) THEN (* cut into two *)
- bx := oxa-1;
- NextX := oxb+1;
- NextLen := X+Len-NextX;
- ELSIF (bx>oxb) THEN (* left edge cut off *)
- ax := oxb+1;
- ELSIF (ax<oxa) THEN (* right edge cut off *)
- bx := oxa-1;
- END;
- END;
- END;
- w := Next;
- END;
- END;
- Len := bx-ax+1;
- IF Len # 0 THEN
- WITH W^ DO
- a := ADR(Buffer^[(ax-WDef.X1)+(Y-WDef.Y1)*OWidth]);
- IF IsPalette THEN
- CoreWind._palxlat(ADR(buff),a,Len,ADR(PalAttr));
- a := ADR(buff);
- END;
- CoreWind._buffertoscreen ( ax,Y,a,Len);
- END;
- END;
- X := NextX;
- Len := NextLen;
- END;
- END UpdateScreen;
- PROCEDURE RedrawSection ( W : WinType;
- X1,Y1,X2,Y2 : AbsCoord ); (* Private *)
- (* redraws rectangular portion of the window from the buffer *)
- VAR
- Y : AbsCoord;
- BEGIN
- FOR Y := Y1 TO Y2 DO
- UpdateScreen(W,X1,Y,X2-X1+1);
- END;
- END RedrawSection;
- PROCEDURE RedrawWindow ( W : WinType ); (* Private *)
- BEGIN
- WITH W^ DO
- RedrawSection ( W,WDef.X1,WDef.Y1,WDef.X2,WDef.Y2 );
- END;
- END RedrawWindow;
- PROCEDURE RedrawWindowPane ( W : WinType ); (* Private *)
- BEGIN
- WITH W^ DO
- RedrawSection ( W,XA,YA,XB,YB );
- END;
- END RedrawWindowPane;
- PROCEDURE DisplayBeneath ( W : WinType; NW : WinType ); (* Private *)
- (* Re-displays windows Obscured by W from NW *)
- VAR
- x1,x2,y1,y2 : AbsCoord;
- BEGIN
- WITH W^ DO
- WHILE NW#NIL DO
- IF ((WDef.X2>=NW^.WDef.X1)AND(NW^.WDef.X2>=WDef.X1) AND
- (WDef.Y2>=NW^.WDef.Y1)AND(NW^.WDef.Y2>=WDef.Y1)) THEN (* windows cross *)
- (* calculate Intersection *)
- IF WDef.X1>NW^.WDef.X1 THEN
- x1 := WDef.X1
- ELSE
- x1 := NW^.WDef.X1
- END;
- IF WDef.X2<NW^.WDef.X2 THEN
- x2 := WDef.X2
- ELSE
- x2 := NW^.WDef.X2
- END;
- IF WDef.Y1>NW^.WDef.Y1 THEN
- y1 := WDef.Y1
- ELSE
- y1 := NW^.WDef.Y1
- END;
- IF WDef.Y2<NW^.WDef.Y2 THEN
- y2 := WDef.Y2
- ELSE
- y2 := NW^.WDef.Y2
- END;
- RedrawSection (NW, x1,y1,x2,y2 );
- END;
- NW := NW^.Next;
- END;
- END;
- END DisplayBeneath;
- PROCEDURE PutOnTop ( W : WinType );
- (*
- Puts the specified window on the top of the window stack
- Ensuring that it is fully visible.
- If this results in other windows becoming obscured then a buffer
- is allocated for each of these windows.
- All otherwise undirected output (ie with no Use) will appear
- within this window.
- *)
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- CheckWindow(W);
- IF W # WinType(CoreWind._windowstack) THEN
- TakeOffStack( W );
- W^.Next := WinType(CoreWind._windowstack);
- CoreWind._windowstack := W;
- WITH W^ DO
- WDef.Hidden := FALSE;
- RedrawWindow ( W );
- IF WDef.CursorOn THEN
- Use ( W );
- CursorOn;
- END;
- END;
- END;
- Use ( W );
- ResetCursor;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END PutOnTop;
- PROCEDURE Hide ( W : WinType );
- (*
- Removes window from the Window stack and also the screen
- Placing the windows contents in a buffer for possible re-display later
- Uncovers obscured windows
- *)
- VAR
- p : WinType;
- w : WinType;
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- CheckWindow(W);
- WITH W^ DO
- IF NOT WDef.Hidden THEN
- w := W^.Next;
- TakeOffStack ( W );
- DisplayBeneath ( W, w );
- IF WDef.CursorOn THEN CursorOff; WDef.CursorOn := TRUE; END;
- WDef.Hidden := TRUE;
- END;
- END;
- ResetCursor;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END Hide;
- PROCEDURE PutBeneath ( W : WinType; WA : WinType );
- (*
- Puts window W beneath window WA
- *)
- VAR
- p : WinType;
- w : WinType;
- BEGIN
- Hide(W);
- (*%T _mthread *)
- Lock();
- (*%E *)
- CheckWindow(WA);
- WITH WA^ DO
- IF NOT WDef.Hidden THEN
- w := Next;
- Next := W;
- W^.Next := w;
- W^.WDef.Hidden := FALSE;
- RedrawWindow ( W );
- END;
- END;
- ResetCursor;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END PutBeneath;
- PROCEDURE SnapShot;
- (* Updates the Window buffer from the screen *)
- (* only works with non palette windows *)
- VAR
- W : WinType;
- y : CARDINAL;
- p : CARDINAL;
- BEGIN
- W := CurWin();
- WITH W^ DO
- WITH WDef DO
- IF NOT IsPalette THEN
- p := 0;
- FOR y := Y1 TO Y2 DO
- CoreWind._screentobuffer(X1,y,ADR(Buffer^[p]),OWidth);
- INC(p,OWidth);
- END;
- END;
- END;
- END;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END SnapShot;
- (* ------------------------- *)
- (* Window disposal *)
- (* ------------------------- *)
- PROCEDURE DisposeTitle ( W : WinType );
- BEGIN
- WITH W^ DO
- IF TMode # NoTitle THEN
- DEALLOCATE(Title,Str.Length(Title^)+1);
- TMode := NoTitle;
- END;
- END;
- END DisposeTitle;
- PROCEDURE Close ( VAR W : WinType );
- (*
- removes the specified window from the screen
- deletes window descriptor and
- de-allocates any buffers previously allocated.
- *)
- VAR
- w : WinType;
- u,up,un : UseListPtr;
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- Hide ( W );
- TakeOffStack (W);
- UnlinkCursor(W);
- WITH W^ DO
- IF (Buffer # NIL) THEN DEALLOCATE(Buffer,OWidth * ODepth * 2); END;
- END;
- up := UseListPtr(CoreWind._uselist);
- u := up^.Next;
- WHILE (u#NIL) DO
- un := u^.Next;
- IF (u^.Wind = W) THEN
- up^.Next := un;
- DISPOSE(u);
- ELSE
- up := u;
- END;
- u := un;
- END;
- DisposeTitle(W);
- W^.Guard := GuardConst; (* Invalidate guard *)
- DISPOSE(W);
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END Close;
- PROCEDURE Used () : WinType;
- (*
- Returns The current window being used for output for this process
- If no window assigned by Use then returns Top
- *)
- VAR
- w : WinType;
- BEGIN
- w := CurWin();
- (*%T _mthread *)
- Unlock();
- (*%E *)
- RETURN w;
- END Used;
- PROCEDURE Top () : WinType;
- (*
- Returns The current top Window
- *)
- VAR w : WinType;
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- w := WinType(CoreWind._windowstack);
- (*%T _mthread *)
- Unlock();
- (*%E *)
- RETURN w;
- END Top;
- PROCEDURE At (X,Y : AbsCoord) : WinType;
- (*
- Returns the window displayed at the absolute position X,Y
- *)
- VAR
- W : WinType;
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- W := WinType(CoreWind._windowstack);
- LOOP
- IF W = NIL THEN EXIT END;
- WITH W^ DO
- IF (Y >= WDef.Y1) AND (Y <= WDef.Y2) AND
- (X >= WDef.X1) AND (X <= WDef.X2) THEN
- EXIT
- END;
- W := Next;
- END;
- END;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- RETURN W;
- END At;
- PROCEDURE ObscuredAt (W : WinType; X,Y : RelCoord ) : BOOLEAN;
- (*
- Returns if the specified window is obscured at the specified position
- *)
- VAR
- b : BOOLEAN;
- w : WinType;
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- CheckWindow(W);
- WITH W^ DO
- IF WDef.Hidden THEN
- b:= TRUE;
- ELSE
- INC(X,XA-1); INC(Y,YA-1);
- w := WinType(CoreWind._windowstack);
- LOOP
- IF w = W THEN b := FALSE; EXIT END;
- IF w = NIL THEN b := TRUE; EXIT END;
- WITH w^ DO
- IF (Y>=WDef.Y1) AND (Y<=WDef.Y2) AND
- (X>=WDef.X1) AND (X<=WDef.X2) THEN
- b := TRUE;
- EXIT
- END;
- w := Next;
- END;
- END;
- END;
- END;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- RETURN b;
- END ObscuredAt;
- PROCEDURE WindowWrite ( W : WinType;
- x,y : RelCoord;
- Len : CARDINAL;
- str : ADDRESS;
- frame : BOOLEAN ); (* Private *)
- VAR
- Attr : CARDINAL;
- X,Y : AbsCoord;
- BEGIN
- IF Len>0 THEN
- WITH W^ DO
- IF IsPalette THEN
- IF frame THEN
- Attr := VAL(CARDINAL,FramePaletteColor);
- ELSE
- Attr := VAL(CARDINAL,CurPalColor);
- END;
- ELSIF frame THEN
- Attr := ORD(WDef.FrameFore)+ORD(WDef.FrameBack)*16;
- ELSE
- Attr := ORD(WDef.Foreground)+ORD(WDef.Background)*16;
- END;
- X := x+XA-1; Y := y+YA-1;
- IF Len+X-1 > WDef.X2 THEN Len := WDef.X2+1-X END;
- CoreWind._bufferwrite (ADR(Buffer^[X-WDef.X1+(Y-WDef.Y1)*OWidth]),str,Len,Attr);
- UpdateScreen(W,X,Y,Len);
- END;
- END;
- END WindowWrite;
- PROCEDURE DrawFrame ( W : WinType );
- VAR
- s : ARRAY[0..81] OF CHAR;
- w,l,tl : CARDINAL;
- i : CARDINAL;
- PROCEDURE PutTitle ( mode : CARDINAL; row : CARDINAL );
- VAR
- i,j : CARDINAL;
- BEGIN
- WITH W^ DO
- CASE mode OF
- 0 : i := 1 |
- 1 : i := (Width-tl) DIV 2 + 1; |
- 2 : i := Width+1-tl |
- ELSE
- i := MAX(CARDINAL);
- END;
- j := 0;
- WHILE (i<=Width)AND(j<tl) DO
- s[i] := Title^[j]; INC(i); INC(j)
- END;
- WindowWrite (W,0,row,OWidth,ADR(s),TRUE);
- END;
- END PutTitle;
- BEGIN
- WITH W^ DO
- IF NOT WDef.FrameOn THEN
- IF (OWidth<3)OR(ODepth<3) THEN RETURN END; (* No Room *)
- WDef.FrameOn := TRUE;
- ClipFrame(W);
- ResetCursor;
- END;
- s[0] := WDef.FrameDef[0];
- Lib.Fill(ADR(s[1]),Width,WDef.FrameDef[1]);
- s[Width+1] := WDef.FrameDef[2];
- IF TMode # NoTitle THEN
- tl := Str.Length(Title^);
- IF tl>Width THEN tl := Width END;
- END;
- PutTitle(ORD(TMode-LeftUpperTitle),0);
- (* Sides *)
- FOR i := 1 TO Depth DO
- WindowWrite(W,0,i,1,ADR(WDef.FrameDef[3]),TRUE);
- WindowWrite(W,Width+1,i,1,ADR(WDef.FrameDef[4]),TRUE);
- END;
- s[0] := WDef.FrameDef[5];
- Lib.Fill(ADR(s[1]),Width,WDef.FrameDef[6]);
- s[Width+1] := WDef.FrameDef[7];
- PutTitle(ORD(TMode-LeftLowerTitle),Depth+1);
- END;
- END DrawFrame;
- PROCEDURE SetFrame ( W : WinType;
- Frame : FrameStr;
- Fore, Back : Color );
- (*
- Put a frame around the specified window
- With Title String and border definition (see above)
- having specified fore/background colours for the border
- *)
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- CheckWindow(W);
- WITH W^ DO
- WDef.FrameDef := Frame;
- WDef.FrameFore := Fore;
- WDef.FrameBack := Back;
- END;
- DrawFrame(W);
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END SetFrame;
- PROCEDURE MergeWindows ( s,d : WinType );
- (* slightly complicated procedure to merge two windows
- s is new (hidden) window
- d is old window to be merged into
- *)
- VAR
- w : WinDescriptor;
- r,wd : CARDINAL;
- sw,sd,so,sp : CARDINAL;
- dw,dd,do,dp : CARDINAL;
- BEGIN
- s^.CurrentX := d^.CurrentX;
- s^.CurrentY := d^.CurrentY;
- s^.CursorChain := d^.CursorChain;
- s^.UserRecord := d^.UserRecord;
- s^.CurPalColor := d^.CurPalColor;
- s^.Title := d^.Title;
- s^.TMode := d^.TMode;
- d^.TMode := NoTitle;
- d^.WDef.CursorOn := FALSE;
- w := d^; d^ := s^; s^ := w;
- WITH s^ DO
- sw := OWidth; sd := ODepth;
- IF WDef.FrameOn THEN
- DEC(sw,2); DEC(sd,2);
- sp := (OWidth+1);
- ELSE
- sp := 0;
- END;
- Guard := GuardConst+CARDINAL(Seg(s^));
- END;
- WITH d^ DO
- dw := OWidth; dd := ODepth;
- IF WDef.FrameOn THEN
- DEC(dw,2); DEC(dd,2);
- dp := OWidth+1;
- ELSE
- dp := 0;
- END;
- Guard := GuardConst+CARDINAL(Seg(d^));
- END;
- IF sd < dd THEN wd := sd ELSE wd := dd END;
- FOR r := 0 TO wd-1 DO
- IF sw>=dw THEN
- Lib.WordMove(ADR(s^.Buffer^[sp]),ADR(d^.Buffer^[dp]),dw);
- ELSE
- Lib.WordMove(ADR(s^.Buffer^[sp]),ADR(d^.Buffer^[dp]),sw);
- BufferSpaceFill(d,dp+sw,dw-sw);
- END;
- INC(sp,s^.OWidth); INC(dp,d^.OWidth);
- END;
- (* now fill rest *)
- IF wd<dd THEN
- FOR r := wd TO dd-1 DO
- BufferSpaceFill(d,dp,dw);
- INC(dp,d^.OWidth);
- END
- END;
- IF d^.WDef.FrameOn THEN DrawFrame(d) END;
- IF NOT s^.WDef.Hidden THEN
- d^.Next := s;
- d^.WDef.Hidden := FALSE;
- RedrawWindow(d);
- END;
- Close(s);
- END MergeWindows;
- PROCEDURE IGotoXY ( W : WinType; X,Y : RelCoord );
- (*
- Sets the current X Y position of the pane currently being used
- *)
- BEGIN
- WITH W^ DO CurrentX := X; CurrentY := Y END;
- IF WinType(CoreWind._cursorstack) = W THEN ResetCursor END;
- END IGotoXY;
- (* ------------------------- *)
- (* Palette procedures *)
- (* ------------------------- *)
- PROCEDURE GetPal ( W : WinType; VAR Pal : PaletteDef );
- VAR
- i : PaletteRange;
- BEGIN
- CheckWindow(W);
- WITH W^ DO
- FOR i := 0 TO PaletteMax DO
- Pal[i].Fore := Color(PalAttr[i] MOD 16);
- Pal[i].Back := Color(PalAttr[i] DIV 16);
- END;
- END;
- END GetPal;
- PROCEDURE SetPal ( W : WinType; VAR Pal : PaletteDef );
- VAR
- i : PaletteRange;
- BEGIN
- CheckWindow(W);
- WITH W^ DO
- FOR i := 0 TO PaletteMax DO
- PalAttr[i] := VAL(SHORTCARD,ORD(Pal[i].Fore)+ORD(Pal[i].Back)*16);
- END;
- IsPalette := TRUE;
- END;
- END SetPal;
- PROCEDURE PaletteOpen(WD: WinDef; Pal: PaletteDef) : WinType;
- (*
- Opens a window on the screen ready for use
- *)
- VAR
- W : WinType;
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- W := MakeWindow (WD);
- SetPal(W,Pal);
- WITH W^ DO
- ALLOCATE ( Buffer,OWidth*ODepth*2);
- BufferSpaceFill(W,0,OWidth*ODepth);
- IF WD.FrameOn THEN
- SetFrame(W,WDef.FrameDef,WDef.FrameFore,WDef.FrameBack);
- END;
- END;
- IF WD.Hidden THEN
- Use ( W )
- ELSE
- PutOnTop ( W )
- END;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- RETURN W;
- END PaletteOpen;
- PROCEDURE SetPaletteColor ( c : PaletteRange );
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- W^.CurPalColor := c;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END SetPaletteColor;
- PROCEDURE PaletteColor() : PaletteRange;
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- (*%T _mthread *)
- Unlock();
- (*%E *)
- RETURN W^.CurPalColor;
- END PaletteColor;
- PROCEDURE SetPalette(W: WinType; Pal: PaletteDef);
- (*
- Changes the Palette of the specified window,
- redisplaying the changed colors
- *)
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- SetPal(W,Pal);
- RedrawWindow(W);
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END SetPalette;
- PROCEDURE PaletteColorUsed(W: WinType; pc: PaletteRange) : BOOLEAN;
- (*
- Returns if color in use anywhere in the window
- *)
- VAR
- p : CARDINAL;
- l : CARDINAL;
- m : CARDINAL;
- ba : POINTER TO ARRAY[0..MAX(CARDINAL)-1] OF SHORTCARD;
- BEGIN
- CheckWindow(W);
- WITH W^ DO
- ba := ADR(Buffer^);
- p := 0;
- m := OWidth*ODepth*2;
- LOOP
- l := m-p;
- p := p+Lib.ScanR(ADR(ba^[p]),l,pc);
- IF p >= m THEN RETURN FALSE END;
- IF ODD(p) THEN RETURN TRUE END;
- INC(p);
- END;
- END;
- END PaletteColorUsed;
- (* ------------------------- *)
- (* Move resize procedure *)
- (* ------------------------- *)
- PROCEDURE Change(W:WinType;X1,Y1,X2,Y2:AbsCoord);
- (* Changes the size and/or position of the specified window The *)
- (* contents of the window will be moved with it *)
- VAR
- nw : WinType;
- wd : WinDef;
- pal : PaletteDef;
- save : WinType;
- min : CARDINAL;
- BEGIN
- CheckWindow(W);
- save := CurWin();
- WITH W^ DO
- IF X2 >= ScreenWidth THEN
- X2 := ScreenWidth - 1;
- END; (*IF*)
- IF Y2 >= CurrentScreenDepth THEN
- Y2 := CurrentScreenDepth - 1;
- END; (*IF*)
- wd := WDef;
- IF wd.FrameOn THEN
- min := 2;
- ELSE
- min := 0;
- END; (*IF*)
- IF (X1 + min > X2) OR (Y1 + min > Y2) THEN
- (*%T _mthread *)
- Unlock();
- (*%E *)
- RETURN;
- END; (*IF*)
- wd.X1 := X1;
- wd.Y1 := Y1;
- wd.X2 := X2;
- wd.Y2 := Y2;
- wd.Hidden := TRUE;
- IF IsPalette THEN
- GetPal(W,pal);
- nw := PaletteOpen(wd,pal);
- ELSE
- nw := Open(wd);
- END; (*IF*)
- MergeWindows(nw,W);
- ClipFrame (W);
- IF CurrentX > Width THEN
- CurrentX := Width;
- END; (*IF*)
- IF CurrentY > Depth THEN
- CurrentY := Depth;
- END; (*IF*)
- ResetCursor;
- END; (*WITH*)
- Use(save); (* restore used window *)
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END Change;
- (* ------------------------- *)
- (* Multi process support *)
- (* ------------------------- *)
- PROCEDURE NullProc;
- BEGIN
- END NullProc;
- PROCEDURE SetProcessLocks ( LockProc,UnlockProc : LockProc );
- BEGIN
- (*%T _mthread *)
- Lock := LockProc;
- Unlock := UnlockProc;
- CoreWind._multip := TRUE;
- (*%E *)
- END SetProcessLocks;
- (* ------------------------- *)
- (* Window output *)
- (* ------------------------- *)
- PROCEDURE DeleteLine ( W : WinType; Y : RelCoord );
- VAR
- r,p : CARDINAL;
- BEGIN
- CheckWindow(W);
- WITH W^ DO
- p := XA-WDef.X1+(YA-WDef.Y1+Y-1)*OWidth;
- FOR r := Y TO Depth-1 DO
- Lib.Move(ADR(Buffer^[p+OWidth]),ADR(Buffer^[p]),Width*2);
- INC(p,OWidth);
- END;
- BufferSpaceFill(W,p,Width);
- RedrawSection ( W,XA,Y+YA-1,XB,YB );
- END;
- END DeleteLine;
- PROCEDURE Clear;
- (*
- clears the current window
- *)
- VAR
- r,p : CARDINAL;
- W : WinType;
- BEGIN
- W := CurWin();
- WITH W^ DO
- p := XA-WDef.X1+(YA-WDef.Y1)*OWidth;
- FOR r := 1 TO Depth DO
- BufferSpaceFill(W,p,Width);
- INC(p,OWidth);
- END;
- RedrawWindowPane(W);
- END;
- IGotoXY(W,1,1);
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END Clear;
- PROCEDURE ClrEol;
- (*
- clears from the cursor to the end of line
- *)
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- WITH W^ DO
- BufferSpaceFill(W,XA-WDef.X1+CurrentX-1+(YA-WDef.Y1+CurrentY-1)*OWidth,
- Width-CurrentX+1);
- RedrawSection ( W,XA-1+CurrentX,YA-1+CurrentY,XB,YA-1+CurrentY );
- END;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END ClrEol;
- (*%F _OS2 *)
- PROCEDURE Bell;
- VAR
- R : SYSTEM.Registers;
- BEGIN
- WITH R DO
- AX := 0E07H;
- BL := 0;
- Lib.Intr(R,10H);
- END;
- END Bell;
- (*%E *)
- (*%T _OS2 *)
- PROCEDURE Bell;
- BEGIN
- Dos.Beep(1000,300);
- END Bell;
- (*%E *)
- PROCEDURE WriteC ( W : WinType; C : CHAR);
- VAR
- nx : CARDINAL;
- BEGIN
- WITH W^ DO
- CASE C OF
- CHR(12) : Clear;
- IGotoXY(W,1,1);
- | CHR(10) : IF CurrentY=Depth THEN
- DeleteLine ( W, 1 );
- ELSE
- IGotoXY(W,CurrentX,CurrentY+1);
- END;
- | CHR(13) : (*ClrEol; change 1/7/88*) IGotoXY(W,1,CurrentY);
- | CHR(08) : IF CurrentX>1 THEN
- IGotoXY(W,CurrentX-1,CurrentY); WriteC(W,' ');
- IGotoXY(W,CurrentX-1,CurrentY);
- END;
- | CHR(7) : Bell;
- ELSE
- IF CurrentX > Width THEN RETURN END;
- WindowWrite(W,CurrentX,CurrentY,1,ADR(C),FALSE);
- IF (CurrentX#Width)OR NOT WDef.WrapOn THEN
- IGotoXY(W,CurrentX+1,CurrentY);
- ELSE
- IF CurrentY=Depth THEN
- DeleteLine ( W, 1 );
- IGotoXY(W,1,CurrentY);
- ELSE
- IGotoXY(W,1,CurrentY+1);
- END;
- END;
- END;
- END;
- END WriteC;
- PROCEDURE WriteOut (S : ARRAY OF CHAR);
- VAR
- W : WinType;
- p,q,m : CARDINAL;
- ss : CARDINAL;
- BEGIN
- W := CurWin();
- WITH W^ DO
- ss := HIGH(S)+1;
- p := 0;
- q := 0;
- LOOP
- (* first accumulate normal chars on same line *)
- m := Width+p-CurrentX;
- IF NOT W^.WDef.WrapOn THEN INC(m) END; (* can fit another char in *)
- IF m > ss THEN m := ss END;
- WHILE (q<m)AND(S[q]>=' ') DO INC(q) END;
- (* now output the line *)
- IF q > p THEN
- WindowWrite(W,CurrentX,CurrentY,q-p,ADR(S[p]),FALSE);
- IGotoXY(W,CurrentX+q-p,CurrentY);
- END;
- (* now output the special char *)
- IF (S[q] = CHR(0)) OR (q > HIGH(S)) THEN EXIT ELSE WriteC(W,S[q]);
- END;
- INC(q);
- p := q;
- END;
- END;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END WriteOut;
- PROCEDURE DirectWrite ( X,Y : RelCoord; (* start co-ords *)
- A : ADDRESS; (* address of char array *)
- Len : CARDINAL ); (* length to be written *)
- (*
- writes directly to current window at the specified X,Y coordinates
- with no check for special (ie control) chars or eol wrap
- *)
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- WindowWrite(W,X,Y,Len,A,FALSE);
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END DirectWrite;
- PROCEDURE GotoXY ( X,Y : RelCoord );
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- ClipXY(W,X,Y);
- IGotoXY(W,X,Y);
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END GotoXY;
- PROCEDURE WhereX ( ) : RelCoord;
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- (*%T _mthread *)
- Unlock();
- (*%E *)
- RETURN W^.CurrentX;
- END WhereX;
- PROCEDURE WhereY ( ) : RelCoord;
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- (*%T _mthread *)
- Unlock();
- (*%E *)
- RETURN W^.CurrentY;
- END WhereY;
- PROCEDURE ConvertCoords ( W : WinType ;
- X,Y : RelCoord;
- VAR XO,YO : AbsCoord );
- BEGIN
- CheckWindow(W);
- XO := X+W^.XA-1; YO := Y+W^.YA-1;
- END ConvertCoords;
- PROCEDURE InsLine;
- VAR
- W : WinType;
- r,p,p1 : CARDINAL;
- BEGIN
- W := CurWin();
- WITH W^ DO
- p := XA-WDef.X1+(YA-WDef.Y1+Depth-1)*OWidth;
- FOR r := CurrentY TO Depth-1 DO
- DEC(p,OWidth);
- Lib.Move(ADR(Buffer^[p]),ADR(Buffer^[p+OWidth]),Width*2);
- END;
- BufferSpaceFill(W,p,Width);
- RedrawSection ( W,XA,CurrentY+YA-1,XB,YB );
- END;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END InsLine;
- PROCEDURE DelLine;
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- DeleteLine(W,W^.CurrentY);
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END DelLine;
- PROCEDURE TextColor ( c : Color );
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- W^.WDef.Foreground := c;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END TextColor;
- PROCEDURE TextBackground ( c : Color );
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- W^.WDef.Background := c;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END TextBackground;
- PROCEDURE SetWrap ( on : BOOLEAN );
- VAR
- W : WinType;
- BEGIN
- W := CurWin();
- W^.WDef.WrapOn := on;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END SetWrap;
- PROCEDURE Info ( W : WinType; VAR WD : WinDef );
- (* gets information for specified window *)
- BEGIN
- (*%T _mthread *)
- Lock();
- (*%E *)
- WD := W^.WDef;
- (*%T _mthread *)
- Unlock();
- (*%E *)
- END Info;
- (* ------------------------- *)
- (* Title procedure *)
- (* ------------------------- *)
- PROCEDURE SetTitle ( W : WinType;
- NewTitle : ARRAY OF CHAR;
- Mode : TitleMode );
- (*
- updates the window title within the window frame,
- positioning it in the position defined by the title mode
- *)
- VAR
- l : CARDINAL;
- BEGIN
- CheckWindow(W);
- (*%T _mthread *)
- Lock();
- (*%E *)
- DisposeTitle(W);
- WITH W^ DO
- IF Mode # NoTitle THEN
- l := Str.Length(NewTitle);
- ALLOCATE(Title,l+1);
- Lib.Move(ADR(NewTitle),ADR(Title^),l);
- Title^[l] := CHR(0);
- END;
- TMode := Mode;
- END;
- DrawFrame(W);
- (*%T _mthread *)
- Unlock;
- (*%E *)
- END SetTitle;
- PROCEDURE ReadString ( VAR string : ARRAY OF CHAR );
- VAR
- c : CHAR;
- line: ARRAY[0..82] OF CHAR;
- p,H : CARDINAL;
- W : WinType;
- con : BOOLEAN;
- BEGIN
- W := CurWin();
- PutOnTop(W);
- con := W^.WDef.CursorOn;
- CursorOn;
- H := HIGH(string);
- IF H>79 THEN H := 79 END;
- p := 0;
- LOOP
- c := IO.RdKey();
- IF (c=CHR(8))OR(c=CHR(127)) THEN
- IF p>0 THEN DEC(p); IO.WrChar(CHR(8)) END;
- ELSIF (c>=' ') THEN
- IF p<=H THEN
- IO.WrChar(c);
- line[p] := c;
- INC(p);
- END;
- ELSIF c=CHR(13) THEN
- EXIT;
- END;
- END;
- line[p] := CHR(0);
- Str.Copy(string,line);
- IF NOT con THEN CursorOff END;
- (*%T _mthread *)
- Unlock;
- (*%E *)
- IO.WrLn;
- END ReadString;
- (* Low level routines to read and write to the window buffer direct *)
- PROCEDURE RdBufferLn ( W : WinType; (* Source window *)
- X,Y : RelCoord; (* start co-ords *)
- Dest : ADDRESS; (* address of buffer *)
- Len : CARDINAL ); (* length in WORDs *)
- VAR
- AX,AY : AbsCoord;
- BEGIN
- WITH W^ DO
- AX := X+XA-1; AY := Y+YA-1;
- Lib.WordMove(ADR(Buffer^[AX-WDef.X1+(AY-WDef.Y1)*OWidth]),Dest,Len);
- END;
- END RdBufferLn;
- PROCEDURE WrBufferLn ( W : WinType; (* Dest window *)
- X,Y : RelCoord; (* start co-ords *)
- Src : ADDRESS; (* address of buffer *)
- Len : CARDINAL ); (* length in WORDs *)
- VAR
- AX,AY : AbsCoord;
- BEGIN
- WITH W^ DO
- AX := X+XA-1; AY := Y+YA-1;
- Lib.WordMove(Src,ADR(Buffer^[AX-WDef.X1+(AY-WDef.Y1)*OWidth]),Len);
- UpdateScreen(W,AX,AY,Len);
- END;
- END WrBufferLn;
- PROCEDURE InputStr ( VAR S : ARRAY OF CHAR );
- VAR
- ins : BOOLEAN;
- k : CHAR;
- x,y,p,l : CARDINAL;
- BEGIN
- x := WhereX(); y := WhereY();
- p := MAX(CARDINAL);
- p := 0;
- ins := TRUE; (* Insert mode *)
- LOOP
- l := Str.Length(S);
- IF p>l THEN p := l END;
- IO.WrStr(S); ClrEol;
- GotoXY(x+p,y);
- k := IO.RdCharDirect();
- IF k = 0C THEN (* Extended character *)
- CASE IO.RdCharDirect() OF
- | CHR(75) : k := CHR(19); (* LeftArr -> ^S *)
- | CHR(77) : k := CHR(4) ; (* RightArr -> ^D *)
- | CHR(71) : k := CHR(1) ; (* Home -> ^A *)
- | CHR(79) : k := CHR(6) ; (* End -> ^F *)
- | CHR(83) : k := CHR(7) ; (* Del -> ^G *)
- | CHR(82) : k := CHR(22); (* Ins -> ^V *)
- END;
- END;
- CASE k OF
- | ' '..'~' : IF ins THEN Str.Insert(S,k,p);
- ELSIF p=l THEN Str.Append(S,k);
- ELSE S[p] := k;
- END;
- INC(p);
- | CHR(1) : p := 0; (* Home *)
- | CHR(6) : p := l; (* End *)
- | CHR(19) : IF p>0 THEN DEC(p) END; (* Left *)
- | CHR(4) : IF p<l THEN INC(p) END; (* Right *)
- | CHR(7) : IF p<l THEN (* Del *)
- Str.Delete(S,p,1);
- END;
- | CHR(8) : IF p>0 THEN (* BackSpace *)
- DEC(p); Str.Delete(S,p,1);
- END;
- | CHR(22) : ins := NOT ins; (* Toggle Ins/Ovr *)
- | CHR(13) : RETURN; (* Enter *)
- END;
- GotoXY(x,y);
- END;
- END InputStr;
- (* ------------------------- *)
- (* Main initialization *)
- (* ------------------------- *)
- CONST
- ClearOnEntry = TRUE; (* Change to FALSE if automatic clear *)
- (*%F _OS2 *)
- VAR
- R : SYSTEM.Registers;
- WD : WinDef;
- BEGIN
- (*%T _mthread *)
- Lock := NullProc;
- Unlock := NullProc;
- (*%E *)
- CoreWind._multip := FALSE;
- IO.WrStrRedirect := WriteOut;
- IO.RdStrRedirect := ReadString;
- CurrentScreenDepth := AbsCoord(CoreWind._getscreendepth());
- IF NOT CoreWind._winsetup THEN
- CoreWind._initscreentype(CGASnow);
- R.AH := 3;
- R.BH := SHORTCARD(CoreWind._activepage());
- Lib.Intr(R,10H);
- IF (R.CH<20H)AND(R.CL>0) THEN
- CoreWind._cursorlines := R.CX;
- ELSE
- CoreWind._cursorlines := 0607H;
- END;
- CoreWind._windowstack := NIL;
- NEW(UseListPtr(CoreWind._uselist));
- UseListPtr(CoreWind._uselist)^.Next := NIL; (* dummy *)
- CoreWind._cursorstack := NIL;
- WD := FullScreenDef;
- WD.Y2 := CurrentScreenDepth;
- IF ClearOnEntry THEN
- FullScreen := Open(WD);
- ELSE
- WD.Hidden := TRUE;
- FullScreen := Open(WD);
- SnapShot;
- PutOnTop(FullScreen);
- GotoXY(ORD(R.DL)+1,ORD(R.DH)+1);
- END;
- ELSE
- FullScreen:=CoreWind._fullscreen;
- END;
- (*%E *)
- (*%T _OS2 *)
- VAR
- Row, Col: CARDINAL;
- WD: WinDef;
- BEGIN
- (*%T _mthread *)
- Lock := Process.Lock;
- Unlock := Process.Unlock;
- (*%E *)
- IO.WrStrRedirect := WriteOut;
- IO.RdStrRedirect := ReadString;
- CurrentScreenDepth := AbsCoord(CoreWind._getscreendepth());
- IF NOT CoreWind._winsetup THEN
- RealMode := NOT Lib.ProtectedMode();
- IF Vio.GetCurType( CursorInfo, 0 ) = 0 THEN END;
- CoreWind._initscreentype(CGASnow);
- CoreWind._windowstack := NIL;
- NEW(UseListPtr(CoreWind._uselist));
- UseListPtr(CoreWind._uselist)^.Next := NIL; (* dummy *)
- CoreWind._cursorstack := NIL;
- WD := FullScreenDef;
- WD.Y2 := CurrentScreenDepth;
- IF ClearOnEntry THEN
- FullScreen := Open(WD);
- ELSE
- WD.Hidden := TRUE;
- FullScreen := Open(WD);
- SnapShot;
- PutOnTop(FullScreen);
- Vio.GetCurPos(Row, Col, 0);
- GotoXY(Col+1, Row+1);
- END;
- ELSE
- FullScreen := CoreWind._fullscreen;
- END;
- (*%E *)
- END Window.
|