DIRECTORY AMEvents USING [Debugging], CedarProcess USING [DoWithPriority], ClassIncreek USING [Increek], Cursors USING [CursorType, GetCursor, SetCursor], InputFocus USING [Focus, FocusRec], Process USING [Detach, Pause, MsecToTicks, Ticks], TIPPrivate, TIPUser, ViewerEvents USING [ProcessEvent], ViewerOps USING [BlinkDisplay, MouseInViewer], ViewerClasses USING [Viewer, ModifyAction, NotifyProc], ViewerPrivate, WindowManager USING [RestoreCursor, waitCount]; InputFocusImpl: CEDAR MONITOR IMPORTS AMEvents, CedarProcess, Cursors, Process, TIPPrivate, TIPUser, ViewerEvents, ViewerOps, ViewerPrivate, WindowManager EXPORTS InputFocus, ViewerPrivate SHARES ViewerEvents = BEGIN OPEN ViewerClasses, InputFocus; forkNewNotifier: BOOL _ TRUE; 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] = { 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]; }; ModifyInputFocus: PROC [action: ViewerClasses.ModifyAction] = { 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 ViewerPrivate.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 => NULL; -- release lock ModifyInputFocus[push]; currentFocus _ NEW[FocusRec _ [owner: self, info: info, link: currentFocus]]; ModifyInputFocus[set]; ChangeTIPContext[currentFocus.owner]; }; CaptureButtons: PUBLIC ENTRY PROC [proc: NotifyProc, tip: TIPUser.TIPTable, viewer: Viewer _ NIL] = { ENABLE UNWIND => NULL; -- release lock captureProc _ proc; captureTIP _ tip; captureViewer _ viewer; }; PopInputFocus: PUBLIC ENTRY PROC = { ENABLE UNWIND => NULL; -- release lock IF currentFocus.link = NIL THEN RETURN; ModifyInputFocus[kill]; currentFocus _ currentFocus.link; ModifyInputFocus[pop]; ChangeTIPContext[currentFocus.owner]; }; ChangeTIPContext: PROC [self: Viewer, interrupt: BOOL _ FALSE] = { TIPPrivate.ResetTIPContext[focusTIP, IF self=NIL THEN NIL ELSE IF self.iconic THEN ViewerPrivate.iconTIP ELSE self.tipTable, MasterNotifyProc, interrupt]; }; 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 TIPPrivate.stdCoords => IF coords#NIL THEN TIPPrivate.stdCoords^ _ coords^ ELSE [] _ ViewerOps.MouseInViewer[TIPPrivate.stdCoords]; ENDCASE; ENDLOOP; }; MasterNotifyProc: TIPPrivate.TIPNotifyProc ~ { InnerMasterNotifyProc: PROC ~ { IF currentFocus.owner.iconic THEN ViewerPrivate.IconNotify[currentFocus.owner, results] ELSE { MapCoordinateResults[results]; currentFocus.owner.class.notify[currentFocus.owner, results]; }; }; IF inputEnabled AND currentFocus.owner#NIL THEN InnerMasterNotifyProc[! AMEvents.Debugging => IF forkNewNotifier THEN PrivateUnWedgeNotifier[] ]; }; MasterButtonProc: TIPPrivate.TIPButtonProc ~ { InnerMasterButtonProc: PROC RETURNS [consume: BOOL _ FALSE] ~ { results: LIST OF REF ANY; viewer: ViewerClasses.Viewer; client: BOOL; TIPParse: PROC [table: TIPUser.TIPTable, mapCoords: BOOL _ TRUE] = { parseInfo.inCreek _ state; -- OK since we only ever do one parse parseInfo.tableHead _ table; results _ TIPPrivate.ParseOneEvent[parseInfo]; IF mapCoords THEN MapCoordinateResults[results, screenXY]; }; IF NOT inputEnabled THEN RETURN[FALSE]; IF captureProc#NIL THEN { TIPParse[captureTIP, FALSE]; IF results#NIL THEN captureProc[captureViewer, results]; 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[ViewerPrivate.iconTIP, FALSE]; IF results#NIL THEN ViewerPrivate.IconNotify[viewer, results]; } 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 viewer.class.notify[viewer, results]; } ELSE { TIPParse[WindowManagerTIPTable]; IF results#NIL THEN ViewerPrivate.ProcessWindowResults[viewer, results]; }; RETURN[TRUE]; }; consume _ InnerMasterButtonProc[! AMEvents.Debugging => IF forkNewNotifier THEN PrivateUnWedgeNotifier[] ]; }; PrivateUnWedgeNotifier: PROC = { ViewerOps.BlinkDisplay[]; currentFocus _ NEW[FocusRec]; TIPPrivate.DestroyClient[focusTIP]; -- destroy old notifier StartTIP[]; -- make a new notifier }; EnableInput: PUBLIC PROC = { TIPPrivate.DiscardTypeAhead[focusTIP]; inputEnabled _ TRUE; }; inputEnabled: PUBLIC BOOL _ FALSE; -- procs above will ignore TIP input while FALSE parseInfo: TIPPrivate.TIPParseInfo _ TIPPrivate.CreateParseInfo[]; currentFocus: Focus _ NEW[FocusRec]; -- this is the head of the focus stack WindowManagerTIPTable: PUBLIC TIPUser.TIPTable _ TIPUser.InstantiateNewTIPTable["WindowMgr.tip"]; focusTIP: PUBLIC TIPPrivate.TIPClient; StartTIP: PROC = { inner: PROC = { focusTIP _ TIPPrivate.CreateClient[buttons: MasterButtonProc, notify: MasterNotifyProc]; TIPPrivate.DiscardTypeAhead[focusTIP]; }; CedarProcess.DoWithPriority[LOOPHOLE[ViewerPrivate.VMgrPriority], inner]; }; WaitingCursor: PROC = BEGIN OPEN ViewerPrivate; aWhile: Process.Ticks = Process.MsecToTicks[100]; InitializeHourglass[56]; UNTIL ViewerPrivate.inputEnabled DO TickHourglass[]; Process.Pause[aWhile]; ENDLOOP; WindowManager.RestoreCursor[]; END; TRUSTED { Process.Detach[FORK WaitingCursor]; }; StartTIP[]; END. LInputFocusImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Doug Wyatt, May 24, 1985 10:12:10 am PDT Russ Atkinson (RRA) April 8, 1986 8:43:37 pm PST If forkNewNotifier=TRUE, MasterNotifyProc and MasterButtonProc will fork a new notifier (and destroy the old one) when they detect AMEvents.Debugging. ENABLE ANY => {IF ViewerPrivate.UserErrorQuery[] THEN CONTINUE}; convert a TIPNotify into an InputFocusNotify. ENABLE ANY => {IF ViewerPrivate.UserErrorQuery[] THEN CONTINUE}; ! ANY => {IF ViewerPrivate.UserErrorQuery[] THEN CONTINUE}]; ! ANY => {IF ViewerPrivate.UserErrorQuery[] THEN CONTINUE}]; ! ANY => {IF ViewerPrivate.UserErrorQuery[] THEN CONTINUE}]; ! ANY => {IF ViewerPrivate.UserErrorQuery[] THEN CONTINUE}]; exciting code to make a new notifier when ours is dying cursor for amusement during start-up Κ³– "Mesa" style˜codešœ™Kšœ Οmœ1™žœžœžœ˜R—šžœ žœ˜Kšžœ?žœžœžœ˜S—šžœžœžœ˜"Kšžœžœ5˜Všžœžœ!žœž˜0K˜=—Kšœ˜—Kšžœ žœCžœ˜\Kšžœ žœDžœ˜^Kšœ˜K˜—Kš ‘ œžœžœžœ žœ˜DK˜š‘œžœžœžœžœžœžœ˜KKšžœžœžœ ˜&K˜Kšœžœ;˜MK˜K˜%Kšœ˜K˜—š ‘œžœžœžœ=žœ˜fKšžœžœžœ ˜&K˜K˜K˜Kšœ˜K˜—š‘ œžœžœžœ˜$Kšžœžœžœ ˜&Kšžœžœžœžœ˜'K˜K˜!K˜K˜%Kšœ˜K˜—š‘œžœžœžœ˜BKšœ&žœžœžœžœžœžœ žœžœ.˜œšœ˜K˜——š‘œžœ žœžœžœžœ%žœ˜`šžœžœžœžœžœžœžœž˜?šžœ ž˜šœžœžœžœ ˜JKšžœ4˜8—Kšžœ˜—Kšžœ˜—Kšœ˜K˜—š‘œ˜.Kšœ-™-š‘œžœ˜Kšœ@™@Kšžœžœ6˜Wšžœ˜K˜K˜=Kšœ˜—K˜—šžœžœžœžœ˜GKšœžœžœ˜FKšœ˜—Kšœ˜K˜—š‘œ˜.š ‘œžœžœ žœžœ˜?Kš œ žœžœžœžœ˜K˜Kšœžœ˜ K˜š‘œžœ&žœžœ˜DKšœ %˜@K˜K˜.Kšžœ žœ)˜:Kšœ˜K˜—Kš žœžœžœžœžœ˜'K˜šžœ žœžœ˜Kšœžœ˜šžœ žœžœ%˜8Kš œžœžœ žœžœ™<—Kšžœžœ˜ Kšœ˜K˜—K˜5K˜šžœžœžœ˜šžœžœ!ž˜EK˜—Kšœ žœžœ ˜%Kšœ˜—šžœžœžœ˜Kšœ žœ˜'šžœ žœžœ+˜>Kš œžœžœ žœžœ™<—Kšœ˜—šžœžœžœ˜šžœžœ)ž˜MK˜'—K˜šžœ žœžœ&˜9Kš œžœžœ žœžœ™<—Kšœ˜—šžœ˜K˜ šžœ žœžœ5˜HKš œžœžœ žœžœ™<—Kšœ˜—Kšžœžœ˜ K˜—šœ!˜!Kšœžœžœ˜FKšœ˜—Kšœ˜K˜—š‘œžœ˜ Kšœ7™7Kšœ˜Kšœžœ ˜Kšœ$ ˜;Kšœ  ˜"Kšœ˜K˜—š‘ œžœžœ˜K˜&Kšœžœ˜Kšœ˜K˜—Kšœžœžœžœ 0˜SK˜BKšœžœ  &˜Kšœžœ˜0K˜0—Kšœ žœ˜&K˜š‘œžœ˜šœžœ˜K˜XK˜&K˜—Kšœžœ%˜IKšœ˜K˜—š‘ œžœžœžœ˜/K˜1K˜Kšžœžœ)žœ˜TK˜Kšžœ˜K˜—šžœ˜ Kšœ$™$Kšœžœ˜#Kšœ˜—K˜ K˜Kšžœ˜—…—@%?