DIRECTORY Buttons USING [Button, SetDisplayStyle], ActionQueue USING [], ActionQueuePrivate USING [Action, Event, MyClickInfo, Queue, QueueObj], Menus USING [ClickProc], Process USING [Detach, GetPriority, SetPriority], Rope USING [ROPE], ViewerClasses USING [Viewer, ViewerRec], ViewerOps USING [FetchProp]; ActionQueuePrivateImpl: CEDAR MONITOR LOCKS qPart USING qPart: REF QueueObj IMPORTS Buttons, Process, ViewerOps EXPORTS ActionQueuePrivate ~ BEGIN OPEN ActionQueuePrivate; QueueObj: PUBLIC TYPE ~ ActionQueuePrivate.QueueObj; -- export concrete type to ActionQueue Viewer: TYPE = ViewerClasses.Viewer; ROPE: TYPE = Rope.ROPE; ClientProgrammingError: ERROR = CODE; InternalProgrammingError: ERROR = CODE; Enqueue: PUBLIC ENTRY PROC [qPart: REF QueueObj, e: Event] = { IF qPart.firstEvent=NIL THEN qPart.firstEvent_ e ELSE { qEnd: Event; FOR qEnd_ qPart.firstEvent, qEnd.rest UNTIL qEnd.rest=NIL DO ENDLOOP; qEnd.rest_ e }; IF qPart.pushModel THEN { IF qPart.notifierRunning THEN RETURN; qPart.notifierRunning_ TRUE; TRUSTED {Process.Detach[FORK Notifier[qPart]]}; } ELSE NOTIFY qPart.newEvent }; Notifier: PROC [q: REF QueueObj] = { DO ENABLE ABORTED => {q.firstEvent _ NIL; LOOP}; -- flush queue on abort event: Event _ Dequeue[q]; IF event = NIL THEN EXIT; IF Process.GetPriority[] >= 2 THEN Process.SetPriority[2]; WITH event.first SELECT FROM e1: Action.user => { viewer: ViewerClasses.Viewer _ NIL; parent: REF _ e1.parent; WITH parent SELECT FROM v: ViewerClasses.Viewer => viewer _ v; ENDCASE; IF viewer # NIL AND viewer.class.flavor = $Button THEN IF ViewerOps.FetchProp[viewer, $DisableMBFeedback] = NIL THEN Buttons.SetDisplayStyle[viewer, $BlackOnGrey]; e1.proc[parent, e1.clientData, e1.mouseButton, e1.shift, e1.control]; IF viewer # NIL AND viewer.class.flavor = $Button THEN IF ViewerOps.FetchProp[viewer, $DisableMBFeedback] = NIL THEN Buttons.SetDisplayStyle[viewer, $BlackOnWhite]}; e2: Action.client => e2.proc[e2.data]; ENDCASE => ERROR; ENDLOOP; }; Dequeue: ENTRY PROC [qPart: REF QueueObj] RETURNS [event: Event] = { IF NOT qPart.pushModel THEN RETURN WITH ERROR InternalProgrammingError; IF qPart.firstEvent=NIL THEN {qPart.notifierRunning_ FALSE; RETURN[NIL]}; event_ qPart.firstEvent; qPart.firstEvent_ qPart.firstEvent.rest; }; UserClick: PUBLIC Menus.ClickProc = { mci: MyClickInfo _ NARROW[clientData]; newEvent: Event _ CONS[ first: [user[mci.proc, parent, mci.clientData, mouseButton, shift, control]], rest: NIL]; IF mci.immediate THEN { mci.q.std.firstEvent _ NIL; -- flush standard queue, if immediate Enqueue[mci.q.panic, newEvent]; -- action on panic queue for immediate attention } ELSE Enqueue[mci.q.std, newEvent]; }; END. nActionQueuePrivateImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Created by Cattell and Haugeland October 20, 1982 4:20 pm Cattell on October 25, 1982 1:54 pm Willie-Sue on October 25, 1982 4:04 pm Doug Wyatt, May 9, 1985 10:26:55 am PDT Russ Atkinson (RRA) June 18, 1985 6:07:16 pm PDT Crow, September 16, 1986 7:20:10 pm PDT Private procedures Adds another event e to the end of q's event list, and set a notifier running again if there wasn't one. Note that the caller of this procedure does the NEW of the Event, outside the monitor, but leaves the rest field NIL to be assigned by this procedure. This process is not under the queue monitor. There are exactly one or zero notifiers per queue, so that no more than one event happens at a time. FORKed from Enqueue. Setting action to normal priority gets buttons enqueued before action starts RRA sez: we need some better way to keep from doing this RRA sez: we need some better way to keep from doing this Removes the first event on q's event list, returning NIL if list empty. Called from Notifier. Adds another event to the end of q's event list Κd˜codešœ™Kšœ Οmœ1™KšœS™SKšœW™WKšœT™Tšžœž˜Kšžœ˜šžœ˜K˜ Kš žœ#žœ žœžœžœ˜EK˜ K˜——šžœ˜šžœ˜Kšžœžœžœ˜%Kšœžœ˜Kšžœžœ˜/K˜—Kšžœžœ˜—K˜K˜—š œžœžœ˜$KšœY™YKšœ8™8Kšœ™šž˜Kš žœžœžœžœŸ˜FKšœ˜šžœ žœžœžœ˜KšœL™L—Kšžœžœ˜:šžœ žœž˜˜Kšœžœ˜#Kšœžœ ˜šžœžœž˜Kšœ&˜&Kšžœ˜—šžœ žœžœž˜6Kšžœ5™8šžœ3žœž˜=K˜.——KšœE˜Ešžœ žœžœž˜6Kšžœ5™8šžœ3žœž˜=K˜0———K˜&Kšžœžœ˜—Kšžœ˜—K˜K˜—š  œžœžœ žœ žœ˜DKšœG™GKšœ™Kš žœžœžœžœžœžœ˜GKš žœžœžœžœžœžœ˜IKšœ˜Kšœ(˜(Kšœ˜K˜—š  œžœ˜%Kšœ/™/Kšœžœ ˜&šœžœ˜KšœTžœ˜Y—šžœ˜šžœ˜KšœžœŸ%˜AKšœ Ÿ0˜PK˜—Kšžœ˜"—K˜K˜—Kšžœ˜K˜—…— |N