DIRECTORY
AMEvents USING [Debugging],
ClassIncreek USING [Increek],
Cursors USING [CursorType, GetCursor, SetCursor],
IconManager USING [IconModify, IconNotify, iconTIP],
ImplErrors USING [UserErrorQuery],
InputFocus,
Process USING [GetPriority, Priority, SetPriority],
TIPUser USING [CreateParseInfo, CreateClient, DestroyClient, DiscardTypeAhead,
InstantiateNewTIPTable, ParseOneEvent, ResetTIPContext, stdCoords,
TIPButtonProc, TIPClient, TIPNotifyProc, TIPParseInfo, TIPScreenCoords, TIPTable],
UserTerminal USING [BlinkDisplay],
ViewerEvents USING [ProcessEvent],
ViewerOps USING [MouseInViewer],
ViewerClasses USING [Viewer, ModifyAction, NotifyProc],
ViewersStallNotifier,
WindowManager USING [waitCount],
WindowManagerPrivate USING [ProcessWindowResults, VMgrPriority];

InputFocusImpl: CEDAR MONITOR
IMPORTS AMEvents, Cursors, IconManager, ImplErrors, Process, TIPUser, UserTerminal, ViewerEvents,
ViewerOps, WindowManager, WindowManagerPrivate
EXPORTS InputFocus, ViewersStallNotifier
SHARES InputFocus, TIPUser, ViewerEvents =

BEGIN OPEN ViewerClasses, InputFocus;

captureProc: NotifyProc _ NIL;		-- client preempting all button events
captureTIP: TIPUser.TIPTable _ NIL;	-- TIP Table associated with the capture.
captureViewer: Viewer _ NIL;		-- focus data private to the capture.

SetInputFocus: PUBLIC ENTRY PROC [self: Viewer _ NIL, info: REF _ NIL] =
BEGIN
ENABLE UNWIND => NULL;	-- release lock
ModifyInputFocus[kill];
currentFocus.owner _ self;	-- note that we don't flush any CaptureButtons!
currentFocus.info _ info;
currentFocus.link _ NIL;
ModifyInputFocus[set];
IF currentFocus.owner#NIL THEN ChangeTIPContext[currentFocus.owner];
END;

ModifyInputFocus: PROC [action: ViewerClasses.ModifyAction] =
BEGIN
ENABLE ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE};
IF action=set THEN  
IF ViewerEvents.ProcessEvent[setInputFocus, currentFocus.owner, TRUE] THEN RETURN;
IF action=kill THEN 
IF ViewerEvents.ProcessEvent[killInputFocus, currentFocus.owner, TRUE] THEN RETURN;
IF currentFocus.owner # NIL THEN BEGIN
IF currentFocus.owner.iconic THEN IconManager.IconModify[currentFocus.owner, action]
ELSE IF currentFocus.owner.class.modify#NIL THEN
currentFocus.owner.class.modify [currentFocus.owner, action];
END;
IF action=set THEN [] _ ViewerEvents.ProcessEvent[setInputFocus, currentFocus.owner, FALSE];
IF action=kill THEN [] _ ViewerEvents.ProcessEvent[killInputFocus, currentFocus.owner, FALSE];
END;

GetInputFocus: PUBLIC PROC RETURNS [Focus] = {RETURN[currentFocus]} ;

PushInputFocus: PUBLIC ENTRY PROC [self: Viewer _ NIL, info: REF _ NIL] = BEGIN
ENABLE UNWIND => NULL;	-- release lock
ModifyInputFocus[push];
currentFocus _ NEW[FocusRec _ [owner: self, info: info, link: currentFocus]];
ModifyInputFocus[set];
ChangeTIPContext[currentFocus.owner];
END;

CaptureButtons: PUBLIC ENTRY PROC [proc: NotifyProc, tip: TIPUser.TIPTable, viewer: Viewer _ NIL] =
BEGIN
ENABLE UNWIND => NULL;	-- release lock
captureProc _ proc;
captureTIP _ tip;
captureViewer _ viewer;
END;

PopInputFocus: PUBLIC ENTRY PROC = BEGIN
ENABLE UNWIND => NULL;	-- release lock
IF currentFocus.link = NIL THEN RETURN;
ModifyInputFocus[kill];
currentFocus _ currentFocus.link;
ModifyInputFocus[pop];
ChangeTIPContext[currentFocus.owner];
END;

ChangeTIPContext: PROC [self: Viewer, interrupt: BOOLEAN _ FALSE] =
{TIPUser.ResetTIPContext[focusTIP,
IF self=NIL THEN NIL ELSE IF self.iconic THEN IconManager.iconTIP ELSE self.tipTable,
MasterNotifyProc, interrupt]};

MapCoordinateResults: PROC[results: LIST OF REF ANY, coords: TIPUser.TIPScreenCoords _ NIL] =
BEGIN
FOR lst: LIST OF REF ANY _ results, lst.rest UNTIL lst = NIL DO
SELECT lst.first FROM
TIPUser.stdCoords => IF coords#NIL THEN TIPUser.stdCoords^ _ coords^
ELSE [] _ ViewerOps.MouseInViewer[TIPUser.stdCoords];
ENDCASE;
ENDLOOP;
END;

MasterNotifyProc: TIPUser.TIPNotifyProc -- [results: LIST OF REF ANY] -- = BEGIN
ENABLE AMEvents.Debugging => PrivateUnWedgeNotifier[];
IF inputEnabled AND currentFocus.owner#NIL THEN BEGIN
ENABLE ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE};
IF currentFocus.owner.iconic THEN IconManager.IconNotify[currentFocus.owner, results]
ELSE BEGIN
MapCoordinateResults[results];
currentFocus.owner.class.notify[currentFocus.owner, results];
END;
END;
END;

MasterButtonProc: TIPUser.TIPButtonProc = BEGIN
ENABLE AMEvents.Debugging => PrivateUnWedgeNotifier[];
results: LIST OF REF ANY;
viewer: ViewerClasses.Viewer;
client: BOOL;

TIPParse: PROC [table: TIPUser.TIPTable, mapCoords: BOOLEAN _ TRUE] = BEGIN
parseInfo.inCreek _ state;	-- OK since we only ever do one parse
parseInfo.tableHead _ table;
results _ TIPUser.ParseOneEvent[parseInfo];
IF mapCoords THEN MapCoordinateResults[results, screenXY];
END;

IF ~inputEnabled THEN RETURN;

IF captureProc#NIL THEN BEGIN
TIPParse[captureTIP, FALSE];
IF results#NIL THEN captureProc[captureViewer, results
! ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE}];
RETURN[TRUE];
END;

[viewer, client] _ ViewerOps.MouseInViewer[screenXY];

IF viewer=NIL THEN BEGIN
IF WindowManager.waitCount=0 AND Cursors.GetCursor[]#textPointer THEN
Cursors.SetCursor[textPointer];
TIPParse[NIL, FALSE]	-- consume event
END
ELSE IF viewer.iconic THEN BEGIN
TIPParse[IconManager.iconTIP, FALSE];
IF results#NIL THEN IconManager.IconNotify[viewer, results
! ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE}];
END
ELSE IF client THEN BEGIN
IF WindowManager.waitCount=0 AND viewer.class.cursor#Cursors.GetCursor[] THEN
Cursors.SetCursor[viewer.class.cursor];
TIPParse[viewer.tipTable];
IF results#NIL THEN viewer.class.notify[viewer, results
! ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE}];
END
ELSE BEGIN
TIPParse[WindowManagerTIPTable];
IF results#NIL THEN WindowManagerPrivate.ProcessWindowResults[viewer, results
! ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE}];
END;

RETURN[TRUE];
END;

UnWedgeNotifier: PUBLIC PROC [process: PROCESS, kind: ATOM] = BEGIN
END;

PrivateUnWedgeNotifier: PROC = BEGIN
TRUSTED {UserTerminal.BlinkDisplay[]};
currentFocus _ NEW[FocusRec];
TIPUser.DestroyClient[focusTIP];	-- destroy old notifier
StartTIP[];	-- make a new notifier
END;

EnableInput: PUBLIC PROC = BEGIN
TIPUser.DiscardTypeAhead[focusTIP];
inputEnabled _ TRUE;
END;

inputEnabled: PUBLIC BOOLEAN _ FALSE;	-- procs above will ignore TIP input while FALSE
parseInfo: TIPUser.TIPParseInfo _ TIPUser.CreateParseInfo[];
currentFocus: Focus _ NEW[FocusRec];	-- this is the head of the focus stack
WindowManagerTIPTable: PUBLIC TIPUser.TIPTable _
TIPUser.InstantiateNewTIPTable["/Indigo/CedarViewers/Viewers/WindowMgr.tip"];
focusTIP: PUBLIC TIPUser.TIPClient;

StartTIP: PROC = TRUSTED BEGIN
oldPriority: Process.Priority = Process.GetPriority[];
Process.SetPriority[WindowManagerPrivate.VMgrPriority];	-- so TIP forked at VMgrPriority
focusTIP _ TIPUser.CreateClient[buttons: MasterButtonProc, notify: MasterNotifyProc];
TIPUser.DiscardTypeAhead[focusTIP];
Process.SetPriority[oldPriority];
END;

StartTIP[];

END.



���À��InputFocusImpl.mesa; written by S. McGregor
Last Edited by McGregor, June 3, 1983 3:48 pm
Last Edited by: Maxwell, January 24, 1983 3:06 pm
convert a TIPNotify into an InputFocusNotify.
[screenXY: TIPScreenCoords, button: Interminal.KeyName, state: ClassIncreek.Increek]
RETURNS [consume: BOOL _ FALSE]
NOP since handled by informational signals in MasterNotify and MasterButton procs
exciting code to make a new notifier when ours is dying
�Ê›��–
"cedar" style˜�JšÏc+™+Jš-™-Jšœ1™1J˜�šÏk	˜	Jšœ˜Jšœ
žœ˜Jšœžœ$˜1Jšœžœ#˜4Jšœžœ˜"J˜Jšœžœ&˜3šœžœA˜NJ˜BJ˜R—Jšœ
žœ˜"Jšœ
žœ˜"Jšœ
žœ˜ Jšœžœ$˜7J˜Jšœžœ
˜ Jšœžœ&˜@J˜�—šœž
˜šžœZ˜aJ˜.—Jšžœ!˜(Jšžœ$˜*J˜�—Jšžœžœ˜%J˜�Jšœžœ&˜FJšœžœ)˜MJšœžœ%˜CJ˜�šÏn
œžœžœžœžœžœžœ˜HJšž˜Jšžœžœžœ˜&J˜Jšœ/˜JJ˜Jšœžœ˜J˜Jšžœžœžœ&˜DJšžœ˜J˜�—šŸœžœ'˜=Jšž˜Jš
žœžœžœžœžœ˜=šžœžœ˜Jšžœ>žœžœžœ˜R—šžœ
žœ˜Jšžœ?žœžœžœ˜S—šžœžœžœž˜&Jšžœžœ3˜Tšžœžœ!žœž˜0J˜=—Jšžœ˜—JšžœžœCžœ˜\Jšžœ
žœDžœ˜^Jšžœ˜J˜�—Jš
Ÿ
œžœžœžœžœ˜EJ˜�šŸœžœžœžœžœžœžœž˜OJšžœžœžœ˜&J˜Jšœžœ;˜MJ˜J˜%Jšžœ˜J˜�—š
Ÿœžœžœžœ<žœ˜cJšž˜Jšžœžœžœ˜&J˜J˜J˜Jšžœ˜J˜�—š	Ÿ
œžœžœžœž˜(Jšžœžœžœ˜&Jšžœžœžœžœ˜'J˜J˜!J˜J˜%Jšžœ˜J˜�—šŸœžœžœžœ˜C˜"Jšžœžœžœžœžœžœ
žœžœ˜UJ˜J˜�——šŸœžœ
žœžœžœžœ$žœ˜]Jšž˜šžœžœžœžœžœžœžœž˜?šžœž˜šœžœžœžœ˜DJšžœ1˜5—Jšžœ˜—Jšžœ˜—Jšžœ˜J˜�—šœ( œž˜PJš-™-Jšžœ0˜6š	žœžœžœžœž˜5Jš
žœžœžœžœžœ˜=Jšžœžœ4˜Ušžœž˜
J˜J˜=Jšžœ˜—Jšžœ˜—Jšžœ˜J˜�—šœ*ž˜/JšT™TJš™Jšžœ0˜6Jš	œ	žœžœžœžœ˜J˜Jšœžœ˜
J˜�š	Ÿœžœ&žœžœž˜KJšœ%˜@J˜J˜+Jšžœžœ)˜:Jšžœ˜J˜�—Jšžœžœžœ˜J˜�šžœ
žœžœž˜Jšœžœ˜šžœ	žœžœ#˜6Jš	œžœžœžœžœ˜9—Jšžœžœ˜
Jšžœ˜J˜�—J˜5J˜�šžœžœžœž˜šžœžœ!ž˜EJ˜—Jšœ	žœžœ˜%Jšž˜—šžœžœžœž˜ Jšœžœ˜%šžœ	žœžœ'˜:Jš	œžœžœžœžœ˜9—Jšž˜—šžœžœžœž˜šžœžœ)ž˜MJ˜'—J˜šžœ	žœžœ$˜7Jš	œžœžœžœžœ˜9—Jšž˜—šžœž˜
J˜ šžœ	žœžœ:˜MJš	œžœžœžœžœ˜9—Jšžœ˜J˜�—Jšžœžœ˜
Jšžœ˜J˜�—šŸœžœžœžœžœž˜CJšžœN™QJšžœ˜J˜�—šŸœžœž˜$Jš7™7Jšžœ˜&Jšœžœ˜Jšœ!˜8Jšœ˜"Jšžœ˜J˜�—šŸœžœžœž˜ J˜#Jšœžœ˜Jšžœ˜J˜�—Jšœžœžœžœ0˜VJ˜<Jšœžœ&˜Kšœžœ˜0J˜M—Jšœ
žœ˜#J˜�šŸœžœž
˜J˜6Jšœ8 ˜XJ˜UJ˜#J˜!Jšžœ˜J˜�—J˜J˜�Jšžœ˜J˜�J˜�J˜�—�…—����>��%™��