GriffinInput.mesa
Maureen Stone February 2, 1983 5:53 pm
Last Edited by: Stone, June 19, 1984 4:28:47 pm PDT
DIRECTORY
Process USING [Detach],
List USING [Assoc, PutAssoc, AList],
ProcessProps USING [AddPropList, GetPropList],
MenuDefs USING [OverWhichItem, HighlightMenuItem, ClearMenuItem, IsOverItem, BugItem, MenuItemHandle],
CursorDefs USING [SetCursor],
OpDefs USING [CopyObjects, MoveObjects, DeleteControlPoint, PlaceControlPoint, DeselectObjects, SelectObjects],
GriffinDefs USING [ShowUserMessage, TypeIn, EndTypeIn, Grid, UserMessage],
ViewerClasses USING [Viewer],
GriffinViewer USING [GetViewer],
PointDefs USING [ScrPt],
GriffinInputDefs;
GriffinInput:
MONITOR
IMPORTS Process, MenuDefs, CursorDefs, GriffinDefs, OpDefs, GriffinViewer, List, ProcessProps
EXPORTS GriffinInputDefs =
BEGIN OPEN GriffinInputDefs;
StartInputHandler:
PUBLIC
PROC
RETURNS [InputEventProc] = {
wd: REF ANY ← List.Assoc[key: $WorkingDirectory, aList: ProcessProps.GetPropList[]];
viewer ← GriffinViewer.GetViewer[];
Process.Detach[FORK WorkingProcess[wd]];
RETURN[NewEventProc]};
InputEventRef: TYPE = REF InputEventRec;
InputEventRec: TYPE = RECORD[next: InputEventRef, input: InputEvent];
events: RECORD [first,last: InputEventRef ← NIL]; --incoming events
condition: CONDITION;
NewEventProc:
ENTRY InputEventProc = {
new: InputEventRef ← NEW[InputEventRec ← [next: NIL, input: event]];
IF events.last=NIL THEN events.first← new ELSE events.last.next ← new;
events.last ← new;
NOTIFY condition;
};
WaitAndCopy:
ENTRY
PROCEDURE
RETURNS [InputEvent] = {
copy: InputEvent;
IF events.first=NIL THEN WAIT condition;
copy ← events.first.input;
events.first ← events.first.next;
IF events.first = NIL THEN events.last ← NIL;
RETURN[copy];
};
WorkingProcess:
PROCEDURE[wd:
REF
ANY] = {
inner:
SAFE PROC =
TRUSTED {
DO
HandleInputEvent[WaitAndCopy[]]; --WaitAndCopy is monitored
ENDLOOP;
};
list: List.AList ~ List.PutAssoc[key: $WorkingDirectory, val: wd, aList: NIL];
ProcessProps.AddPropList[list, inner];
};
Does real work
downStroke: GriffinInputDefs.InputEvent;
item: MenuDefs.MenuItemHandle ← NIL;
mouseDown: BOOLEAN ← FALSE;
overSameItem: BOOLEAN ← FALSE;
aborted: BOOLEAN ← FALSE;
viewer: ViewerClasses.Viewer;
HandleInputEvent: InputEventProc =
BEGIN
ENABLE GriffinDefs.UserMessage =>
BEGIN
GriffinDefs.ShowUserMessage[string];
AbortCleanup;
CONTINUE;
END;
up,down: PointDefs.ScrPt;
SELECT event.type FROM
red,yellow,blue =>
BEGIN
GriffinDefs.EndTypeIn[];
InputFocus.SetInputFocus[viewer];
downStroke ← event;
mouseDown ← TRUE;
overSameItem ← TRUE;
item ← MenuDefs.OverWhichItem[event.pt];
IF item # NIL THEN MenuDefs.HighlightMenuItem[item];
END;
abort =>
BEGIN
aborted←TRUE;
AbortCleanup;
CursorDefs.SetCursor[abortCursor];
END;
up=>
BEGIN
IF aborted
THEN
BEGIN
aborted←FALSE;
AbortCleanup;
RETURN
END;
CursorDefs.SetCursor[busyCursor];
mouseDown ← FALSE;
overSameItem ← FALSE;
down ← downStroke.pt;
up ← event.pt;
InputFocus.SetInputFocus[viewer];
IF item #
NIL
THEN
--downstroke was over menu
BEGIN
IF MenuDefs.IsOverItem[up, item]
THEN MenuDefs.BugItem[item];
MenuDefs.ClearMenuItem[item];
CursorDefs.SetCursor[pointingCursor];
item ← NIL;
RETURN
END;
SELECT downStroke.type FROM
red =>
BEGIN
down ← GriffinDefs.Grid[down];
up ← GriffinDefs.Grid[up];
IF event.shifted
THEN OpDefs.CopyObjects[down,up]
ELSE OpDefs.MoveObjects[down,up];
END;
yellow =>
BEGIN
down ← GriffinDefs.Grid[down];
up ← GriffinDefs.Grid[up];
IF item =
NIL
THEN
IF event.shifted
THEN OpDefs.DeleteControlPoint[down,up]
ELSE OpDefs.PlaceControlPoint[up];
END;
blue =>
IF item =
NIL
THEN
IF event.shifted
THEN OpDefs.DeselectObjects[down,up]
ELSE OpDefs.SelectObjects[down,up];
ENDCASE;
item ← NIL;
CursorDefs.SetCursor[pointingCursor];
END;
newPosition =>
IF mouseDown
AND item #
NIL
THEN
IF MenuDefs.IsOverItem[event.pt, item]
THEN
BEGIN
IF ~ overSameItem THEN MenuDefs.HighlightMenuItem[item];
overSameItem ← TRUE;
END
ELSE
BEGIN
IF overSameItem THEN MenuDefs.ClearMenuItem[item];
overSameItem ← FALSE;
END;
keyStroke =>
BEGIN
GriffinDefs.TypeIn[event.key];
END;
ENDCASE;
END;
AbortCleanup: PROCEDURE =
BEGIN
CursorDefs.SetCursor[pointingCursor];
IF item #
NIL
THEN MenuDefs.ClearMenuItem[item];
item ← NIL;
mouseDown ← FALSE;
overSameItem ← FALSE;
END;
END.