FastTRAPDeviceImpl.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Bier, November 6, 1991 10:43 am PST
Contents: Routines for creating instances of the FastTRAP trackball and representing the state of such a device.
DIRECTORY
DeviceClassTypes, DeviceTypes, FastTRAPDevice, Rope;
FastTRAPDeviceImpl: CEDAR PROGRAM
IMPORTS
EXPORTS FastTRAPDevice, DeviceTypes = BEGIN
Device: TYPE = DeviceTypes.Device;
DeviceObj: TYPE = DeviceTypes.DeviceObj;
DeviceClass: PUBLIC TYPE = DeviceClassTypes.DeviceClass;
DeviceClassObj: PUBLIC TYPE = DeviceClassTypes.DeviceClassObj;
DeviceState: TYPE = DeviceTypes.DeviceState;
DeviceStateObj: TYPE = DeviceTypes.DeviceStateObj;
DeviceStateChange: TYPE = DeviceTypes.DeviceStateChange;
DeviceStateChangeObj: TYPE = DeviceTypes.DeviceStateChangeObj;
KeyName: TYPE = FastTRAPDevice.KeyName;
ROPE: TYPE = Rope.ROPE;
FastTRAPData: TYPE = REF FastTRAPDataObj;
FastTRAPDataObj: TYPE = RECORD [
name: ROPE
];
FastTRAPState: TYPE = REF FastTRAPStateObj;
FastTRAPStateObj: TYPE = RECORD [
wheel: INTEGER,
x, y: INTEGER, -- trackball coordinates
buttonDown: ARRAY KeyName OF BOOL
];
fastTRAPClass: DeviceClass ¬ NEW[DeviceClassObj ¬ [$FastTRAP, GetFastTRAPState]];
Class Routines
GetFastTRAPState: DeviceClassTypes.GetDeviceStateProc = {
PROC [device: Device] RETURNS [state: DeviceState];
state ¬ AllocateState[device];
};
CreateFastTRAP: PUBLIC PROC [name: Rope.ROPE] RETURNS [device: Device] = {
Create a data structure representing a particular physical FastTRAP. Calls class.create[class].
data: FastTRAPData ¬ NEW[FastTRAPDataObj ¬ [name: name]];
device ¬ NEW[DeviceObj];
device.class ¬ fastTRAPClass;
device.data ¬ data;
device.name ¬ name;
};
AllocateState: PUBLIC PROC [device: Device] RETURNS [deviceState: DeviceState] = {
Allocates storage representing the state of this keyboard when all of its keys are up, the trackball is at 0,0, and the thumbwheel is at 0. Each DeviceState is immutable, so they may be freely stored in long-term storage.
state: FastTRAPState ¬ NEW[FastTRAPStateObj ¬ [wheel: 0, x: 0, y: 0, buttonDown: [FALSE, FALSE, FALSE]]];
deviceState ¬ NEW[DeviceStateObj];
deviceState.class ¬ device.class;
deviceState.state ¬ state;
};
CopyState: PROC [deviceState: DeviceState] RETURNS [copy: DeviceState] = {
old: FastTRAPState ¬ NARROW[deviceState.state];
state: FastTRAPState ¬ NEW[FastTRAPStateObj ¬ [wheel: old.wheel, x: old.x, y: old.y, buttonDown: old.buttonDown]];
copy ¬ NEW[DeviceStateObj];
copy.class ¬ deviceState.class;
copy.state ¬ state;
};
Representing FastTRAP State Changes
buttonDownChange: ARRAY KeyName OF ARRAY BOOL OF DeviceStateChange;
trackballChange: ARRAY [-4..4] OF ARRAY [-4..4] OF DeviceStateChange;
wheelChange: ARRAY [-4..4] OF DeviceStateChange;
Init: PROC = {
buttonDownChange[left][FALSE] ¬ KeyChangeCreate[left, FALSE];
buttonDownChange[left][TRUE] ¬ KeyChangeCreate[left, TRUE];
buttonDownChange[middle][FALSE] ¬ KeyChangeCreate[middle, FALSE];
buttonDownChange[middle][TRUE] ¬ KeyChangeCreate[middle, TRUE];
buttonDownChange[right][FALSE] ¬ KeyChangeCreate[right, FALSE];
buttonDownChange[right][TRUE] ¬ KeyChangeCreate[right, TRUE];
FOR i: INT IN [-4..4] DO
FOR j: INT IN [-4..4] DO
trackballChange[i][j] ¬ TrackballChangeCreate[i, j];
ENDLOOP;
wheelChange[i] ¬ WheelChangeCreate[i];
ENDLOOP;
};
KeyChange: PUBLIC PROC [key: KeyName, down: BOOL] RETURNS [change: DeviceStateChange] = {
change ¬ buttonDownChange[key][down];
};
TrackballChange: PUBLIC PROC [deltaX, deltaY: INTEGER] RETURNS [change: DeviceStateChange] = {
IF deltaX IN [-4..4] AND deltaY IN [-4..4] THEN change ¬ trackballChange[deltaX][deltaY]
ELSE {
change ¬ TrackballChangeCreate[deltaX, deltaY];
};
};
ThumbwheelChange: PUBLIC PROC [delta: INTEGER] RETURNS [change: DeviceStateChange] = {
IF delta IN [-4..4] THEN change ¬ wheelChange[delta]
ELSE {
change ¬ WheelChangeCreate[delta];
};
};
KeyChangeCreate: PROC [key: KeyName, down: BOOL] RETURNS [dsChange: DeviceStateChange] ~ {
change: FastTRAPChange ¬ NEW[FastTRAPChangeObj];
change.type ¬ key;
change.key ¬ key;
change.down ¬ down;
dsChange ¬ NEW[DeviceStateChangeObj];
dsChange.class ¬ fastTRAPClass;
dsChange.change ¬ change;
};
TrackballChangeCreate: PROC [deltaX, deltaY: INTEGER] RETURNS [dsChange: DeviceStateChange] ~ {
change: FastTRAPChange ¬ NEW[FastTRAPChangeObj];
change.type ¬ trackball;
change.deltaX ¬ deltaX;
change.deltaY ¬ deltaY;
dsChange ¬ NEW[DeviceStateChangeObj];
dsChange.class ¬ fastTRAPClass;
dsChange.change ¬ change;
};
WheelChangeCreate: PROC [delta: INTEGER] RETURNS [dsChange: DeviceStateChange] ~ {
change: FastTRAPChange ¬ NEW[FastTRAPChangeObj];
change.type ¬ wheel;
change.deltaX ¬ delta;
dsChange ¬ NEW[DeviceStateChangeObj];
dsChange.class ¬ fastTRAPClass;
dsChange.change ¬ change;
};
FastTRAPChange: TYPE = REF FastTRAPChangeObj;
FastTRAPChangeObj: TYPE = RECORD [
type: ChangeType,
key: KeyName ¬ left,
down: BOOL,
deltaX, deltaY: INTEGER ¬ 0
];
ChangeType: TYPE = {key, trackball, wheel};
StateAfterChange: PUBLIC PROC [deviceState: DeviceState, change: DeviceStateChange] RETURNS [newDeviceState: DeviceState] = {
ftChange: FastTRAPChange ¬ NARROW[change.change];
SELECT ftChange.type FROM
key => newDeviceState ¬ KeyMotion[deviceState, ftChange.key, ftChange.down];
trackball => newDeviceState ¬ TrackballMotion[deviceState, ftChange.deltaX, ftChange.deltaY];
wheel => newDeviceState ¬ ThumbwheelMotion[deviceState, ftChange.deltaX];
ENDCASE => ERROR;
};
ExpandedChange: TYPE = FastTRAPDevice.ExpandedChange;
UnpackChange: PUBLIC PROC [change: DeviceStateChange] RETURNS [expanded: ExpandedChange] = {
ftChange: FastTRAPChange ¬ NARROW[change.change];
SELECT ftChange.type FROM
key => expanded ¬ [key[ftChange.key, ftChange.down]];
trackball => expanded ¬ [trackball[ftChange.deltaX, ftChange.deltaY]];
wheel => expanded ¬ [wheel[ftChange.deltaX]];
ENDCASE => ERROR;
};
Changing FastTRAP State
KeyMotion: PUBLIC PROC [deviceState: DeviceState, key: KeyName, down: BOOL] RETURNS [newDeviceState: DeviceState] = {
newDeviceState ¬ CopyState[deviceState];
NARROW[newDeviceState.state, FastTRAPState].buttonDown[key] ¬ down;
};
TrackballMotion: PUBLIC PROC [deviceState: DeviceState, deltaX, deltaY: INTEGER] RETURNS [newDeviceState: DeviceState] = {
newState, oldState: FastTRAPState;
newDeviceState ¬ CopyState[deviceState];
newState ¬ NARROW[newDeviceState.state];
oldState ¬ NARROW[deviceState.state];
newState.x ¬ oldState.x + deltaX;
newState.y ¬ oldState.y + deltaY;
};
ThumbwheelMotion: PUBLIC PROC [deviceState: DeviceState, delta: INTEGER] RETURNS [newDeviceState: DeviceState] = {
newDeviceState ¬ CopyState[deviceState];
NARROW[newDeviceState.state, FastTRAPState].wheel ¬ NARROW[deviceState.state, FastTRAPState].wheel + delta;
};
Inspecting State
IsDown: PUBLIC PROC [deviceState: DeviceState, key: KeyName] RETURNS [BOOL] = {
state: FastTRAPState ¬ NARROW[deviceState.state];
RETURN[state.buttonDown[key]];
};
GetTrackball: PUBLIC PROC [deviceState: DeviceState] RETURNS [x, y: INTEGER] = {
state: FastTRAPState ¬ NARROW[deviceState.state];
x ¬ state.x;
y ¬ state.y;
};
GetThumbwheel: PUBLIC PROC [deviceState: DeviceState] RETURNS [wheel: INTEGER] = {
state: FastTRAPState ¬ NARROW[deviceState.state];
wheel ¬ state.wheel;
};
Init[];
END.