GriffinInput.mesa
Maureen Stone February 2, 1983 5:53 pm
Last Edited by: Stone, June 18, 1984 11:11:14 am PDT
DIRECTORY
Process USING [Detach],
ProcessProps USING [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],
Rope USING [ROPE],
List USING [PutAssoc],
GriffinInputDefs;
GriffinInput: MONITOR
IMPORTS Process, MenuDefs, CursorDefs, GriffinDefs, OpDefs, GriffinViewer, List, ProcessProps
EXPORTS GriffinInputDefs =
BEGIN OPEN GriffinInputDefs;
StartInputHandler: PUBLIC PROC[wd: Rope.ROPE] RETURNS [InputEventProc] = {
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: Rope.ROPE] = {
[] ← List.PutAssoc[key: $WorkingDirectory, val: wd, aList: ProcessProps.GetPropList[]];
DO
HandleInputEvent[WaitAndCopy[]]; --WaitAndCopy is monitored
ENDLOOP;
};
Does real work  
downStroke: GriffinInputDefs.InputEvent;
item: MenuDefs.MenuItemHandle ← NIL;
mouseDown: BOOLEANFALSE;
overSameItem: BOOLEANFALSE;
aborted: BOOLEANFALSE;
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]
THENBEGIN
IF ~ overSameItem THEN MenuDefs.HighlightMenuItem[item];
overSameItem ← TRUE;
END
ELSEBEGIN
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.