DIRECTORY AMEvents USING [Debugging], ClassIncreek USING [Increek], Cursors USING [CursorType, GetCursor, SetCursor], IconManager USING [IconModify, IconNotify, iconTIP], ImplErrors USING [UserErrorQuery], InputFocus USING [Focus, FocusRec], 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, NotifyViewer], ViewerClasses USING [Viewer, ModifyAction, NotifyProc], ViewersStallNotifier USING [], 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 InputFocus; Viewer: TYPE = ViewerClasses.Viewer; inputEnabled: PUBLIC BOOL _ FALSE; -- procs below will ignore TIP input while FALSE WindowManagerTIPTable: PUBLIC TIPUser.TIPTable _ NIL; focusTIP: PUBLIC TIPUser.TIPClient _ NIL; currentFocus: Focus _ NEW[FocusRec]; -- this is the head of the focus stack parseInfo: TIPUser.TIPParseInfo _ TIPUser.CreateParseInfo[]; captureProc: ViewerClasses.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] = { ENABLE UNWIND => { --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]; }; ModifyInputFocus: PROC[action: ViewerClasses.ModifyAction] = { 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 { 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]; }; IF action=set THEN [] _ ViewerEvents.ProcessEvent[setInputFocus, currentFocus.owner, FALSE]; IF action=kill THEN [] _ ViewerEvents.ProcessEvent[killInputFocus, currentFocus.owner, FALSE]; }; GetInputFocus: PUBLIC PROC RETURNS[Focus] = { RETURN[currentFocus] }; PushInputFocus: PUBLIC ENTRY PROC[self: Viewer _ NIL, info: REF _ NIL] = { ENABLE UNWIND => { --release lock-- }; ModifyInputFocus[push]; currentFocus _ NEW[FocusRec _ [owner: self, info: info, link: currentFocus]]; ModifyInputFocus[set]; ChangeTIPContext[currentFocus.owner]; }; PopInputFocus: PUBLIC ENTRY PROC = { ENABLE UNWIND => { --release lock-- }; IF currentFocus.link=NIL THEN RETURN; ModifyInputFocus[kill]; currentFocus _ currentFocus.link; ModifyInputFocus[pop]; ChangeTIPContext[currentFocus.owner]; }; ChangeTIPContext: PROC [self: Viewer, interrupt: BOOLEAN _ FALSE] = { tipTable: TIPUser.TIPTable _ NIL; IF self#NIL THEN tipTable _ (IF self.iconic THEN IconManager.iconTIP ELSE self.tipTable); TIPUser.ResetTIPContext[focusTIP, tipTable, MasterNotifyProc, interrupt] }; CaptureButtons: PUBLIC ENTRY PROC[proc: ViewerClasses.NotifyProc, tip: TIPUser.TIPTable, viewer: Viewer _ NIL] = { ENABLE UNWIND => { --release lock-- }; captureProc _ proc; captureTIP _ tip; captureViewer _ viewer; }; ReleaseButtons: PUBLIC ENTRY PROC = { ENABLE UNWIND => { --release lock-- }; captureProc _ NIL; captureTIP _ NIL; captureViewer _ NIL; }; MapCoordinateResults: PROC[results: LIST OF REF ANY, coords: TIPUser.TIPScreenCoords _ NIL] = { 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; }; MasterNotifyProc: TIPUser.TIPNotifyProc -- [results: LIST OF REF ANY] -- = { ENABLE AMEvents.Debugging => PrivateUnWedgeNotifier[]; IF inputEnabled AND currentFocus.owner#NIL THEN { ENABLE ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE}; IF currentFocus.owner.iconic THEN [] _ IconManager.IconNotify[currentFocus.owner, results] ELSE { MapCoordinateResults[results]; ViewerOps.NotifyViewer[currentFocus.owner, results]; }; }; }; MasterButtonProc: TIPUser.TIPButtonProc = { ENABLE AMEvents.Debugging => PrivateUnWedgeNotifier[]; results: LIST OF REF ANY; viewer: ViewerClasses.Viewer; client: BOOL; TIPParse: PROC [table: TIPUser.TIPTable, mapCoords: BOOLEAN _ TRUE] = { parseInfo.inCreek _ state; -- OK since we only ever do one parse parseInfo.tableHead _ table; results _ TIPUser.ParseOneEvent[parseInfo]; IF mapCoords THEN MapCoordinateResults[results, screenXY]; }; IF ~inputEnabled THEN RETURN; IF captureProc#NIL THEN { TIPParse[captureTIP, FALSE]; IF results#NIL THEN [] _ captureProc[captureViewer, results ! ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE}]; RETURN[TRUE]; }; [viewer, client] _ ViewerOps.MouseInViewer[screenXY]; IF viewer=NIL THEN { IF WindowManager.waitCount=0 AND Cursors.GetCursor[]#textPointer THEN Cursors.SetCursor[textPointer]; TIPParse[NIL, FALSE] -- consume event } ELSE IF viewer.iconic THEN { TIPParse[IconManager.iconTIP, FALSE]; IF results#NIL THEN [] _ IconManager.IconNotify[viewer, results ! ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE}]; } ELSE IF client THEN { IF WindowManager.waitCount=0 AND viewer.class.cursor#Cursors.GetCursor[] THEN Cursors.SetCursor[viewer.class.cursor]; TIPParse[viewer.tipTable]; IF results#NIL THEN ViewerOps.NotifyViewer[viewer, results ! ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE}]; } ELSE { TIPParse[WindowManagerTIPTable]; IF results#NIL THEN [] _ WindowManagerPrivate.ProcessWindowResults[viewer, results ! ANY => {IF ImplErrors.UserErrorQuery[] THEN CONTINUE}]; }; RETURN[TRUE]; }; UnWedgeNotifier: PUBLIC PROC [process: PROCESS, kind: ATOM] = { }; PrivateUnWedgeNotifier: PROC = { TRUSTED {UserTerminal.BlinkDisplay[]}; currentFocus _ NEW[FocusRec]; TIPUser.DestroyClient[focusTIP]; -- destroy old notifier StartTIP[]; -- make a new notifier }; EnableInput: PUBLIC PROC = { TIPUser.DiscardTypeAhead[focusTIP]; inputEnabled _ TRUE; }; StartTIP: PROC = TRUSTED { 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]; }; WindowManagerTIPTable _ TIPUser.InstantiateNewTIPTable["WindowMgr.tip"]; 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 Last Edited by: Wyatt, November 10, 1983 4:55 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šœ0™0J˜šΟk ˜ Jšœ žœ ˜Jšœ žœ ˜Jšœžœ$˜1Jšœ žœ#˜4Jšœ žœ˜"Jšœ žœ˜#Jšœžœ&˜3šœžœA˜NJ˜BJ˜R—Jšœ žœ˜"Jšœ žœ˜"Jšœ žœ˜.Jšœžœ$˜7Jšœžœ˜Jšœžœ ˜ Jšœžœ&˜@J˜—Jšœž ˜Jšžœ‰˜Jšžœ!˜(Jšžœ"˜(Jšœžœžœ ˜J˜Jšœžœ˜$J˜Jšœžœžœžœ0˜SJšœžœžœ˜5Jšœ žœžœ˜)J˜Jšœžœ &˜KJ˜Jš žœžœžœžœžœ˜=šžœ žœ˜Jšžœ>žœžœžœ˜R—šžœ žœ˜Jšžœ?žœžœžœ˜S—šžœžœžœ˜"Jšžœžœ3˜Tšžœžœ!žœž˜0J˜=—Jšœ˜—šžœ ž˜JšœBžœ˜I—šžœ ž˜JšœCžœ˜J—Jšœ˜J˜—Jš Ÿ œžœžœžœ žœ˜EJ˜šŸœžœžœžœžœžœžœ˜JJšžœžœœ˜&J˜Jšœžœ;˜MJ˜J˜%Jšœ˜J˜—šŸ œžœžœžœ˜$Jšžœžœœ˜&Jšžœžœžœžœ˜%J˜J˜!J˜J˜%Jšœ˜J˜—šŸœžœžœžœ˜EJšœžœ˜!Jš žœžœžœ žœ žœžœ˜YJšœH˜Hšœ˜J˜——šŸœžœžœžœ7˜XJšœžœ˜Jšžœžœœ˜&J˜J˜J˜Jšœ˜J˜—šŸœžœžœžœ˜%Jšžœžœœ˜&Jšœžœ˜Jšœ žœ˜Jšœžœ˜Jšœ˜J˜—šŸœžœ žœžœžœžœ$žœ˜]Jšœ˜šžœžœžœžœžœžœžœž˜?šžœ ž˜šœžœžœžœ˜DJšžœ1˜5—Jšžœ˜—Jšžœ˜—Jšœ˜J˜—šŸœ œ˜LJš-™-Jšžœ0˜6šžœžœžœžœ˜1Jš žœžœžœžœžœ˜=Jšžœžœ9˜Zšžœ˜J˜J˜4Jšœ˜—Jšœ˜—Jšœ˜J˜—šŸœ˜+JšT™TJš™Jšžœ0˜6Jš œ žœžœžœžœ˜J˜Jšœžœ˜ J˜šŸœžœ&žœžœ˜GJšœ%˜@J˜J˜+Jšžœ žœ)˜:Jšœ˜J˜—Jšžœžœžœ˜J˜šžœ žœžœ˜Jšœžœ˜šžœ žœžœ(˜;Jš œžœžœžœžœ˜9—Jšžœžœ˜ Jšœ˜J˜—J˜5J˜šžœžœžœ˜šžœžœ!ž˜EJ˜—Jšœ žœžœ˜%Jšœ˜—šžœžœžœ˜Jšœžœ˜%šžœ žœžœ,˜?Jš œžœžœžœžœ˜9—Jšœ˜—šžœžœžœ˜šžœžœ)ž˜MJ˜'—J˜šžœ žœžœ'˜:Jš œžœžœžœžœ˜9—Jšœ˜—šžœ˜J˜ šžœ žœžœ?˜RJš œžœžœžœžœ˜9—Jšœ˜J˜—Jšžœžœ˜ Jšœ˜J˜—š Ÿœžœžœ žœžœ˜?JšžœN™QJšœ˜J˜—šŸœžœ˜ Jš7™7Jšžœ˜&Jšœžœ ˜Jšœ!˜8Jšœ ˜"Jšœ˜J˜—šŸ œžœžœ˜J˜#Jšœžœ˜Jšœ˜J˜—šŸœžœžœ˜J˜6Jšœ8 ˜XJ˜UJ˜#J˜!Jšœ˜J˜—JšœH˜HJ˜ J˜Jšžœ˜J˜J˜J˜—…—θ&»