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.