WacomDeviceImpl.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Kenneth A. Pier, January 10, 1992 11:08 am PST
Contents: Routines for creating instances of the Wacom pressure-sensitive tablet and representing the state of such a device.
DIRECTORY
DeviceClassTypes, DeviceTypes, WacomDevice, Rope;
WacomDeviceImpl: CEDAR PROGRAM
IMPORTS
EXPORTS WacomDevice, 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;
ROPE: TYPE = Rope.ROPE;
WacomData: TYPE = REF WacomDataObj;
WacomDataObj: TYPE = RECORD [
name: ROPE
];
WacomState: TYPE = REF WacomStateObj;
WacomStateObj: TYPE = RECORD [
x, y: INTEGER, -- pen coordinates
xValid, yValid: BOOL ¬ FALSE,
p: INTEGER -- pressure IN approximately [-32 .. 32]
];
wacomClass: DeviceClass ¬ NEW[DeviceClassObj ¬ [$Wacom, GetWacomState]];
Class Routines
GetWacomState: DeviceClassTypes.GetDeviceStateProc = {
PROC [device: Device] RETURNS [state: DeviceState];
state ¬ AllocateState[device];
};
CreateWacom: PUBLIC PROC [name: Rope.ROPE] RETURNS [device: Device] = {
Create a data structure representing a particular physical Wacom. Calls class.create[class].
data: WacomData ¬ NEW[WacomDataObj ¬ [name: name]];
device ¬ NEW[DeviceObj];
device.class ¬ wacomClass;
device.data ¬ data;
device.name ¬ name;
};
AllocateState: PUBLIC PROC [device: Device] RETURNS [deviceState: DeviceState] = {
Allocates storage representing the state of device with invalid coordinates and minimum pressure. Each DeviceState is immutable, so they may be freely stored in long-term storage.
state: WacomState ¬ NEW[WacomStateObj ¬ [p: minPressure, x: 0, xValid: FALSE, y: 0, yValid: FALSE]];
deviceState ¬ NEW[DeviceStateObj];
deviceState.class ¬ device.class;
deviceState.state ¬ state;
};
CopyState: PROC [deviceState: DeviceState] RETURNS [copy: DeviceState] = {
old: WacomState ¬ NARROW[deviceState.state];
state: WacomState ¬ NEW[WacomStateObj ¬ [p: old.p, x: old.x, xValid: old.xValid, y: old.y, yValid: old.yValid]];
copy ¬ NEW[DeviceStateObj];
copy.class ¬ deviceState.class;
copy.state ¬ state;
};
Representing Wacom State Changes
PenXChange: PUBLIC PROC [x: INTEGER] RETURNS [change: DeviceStateChange] = {
change ¬ PenXChangeCreate[x];
};
PenYChange: PUBLIC PROC [y: INTEGER] RETURNS [change: DeviceStateChange] = {
change ¬ PenYChangeCreate[y];
};
PressureChange: PUBLIC PROC [p: INTEGER] RETURNS [change: DeviceStateChange] = {
change ¬ IF p <= minPressure THEN minPChange ELSE IF p >= maxPressure THEN maxPChange ELSE PressureChangeCreate[p];
};
PenXChangeCreate: PROC [x: INTEGER] RETURNS [dsChange: DeviceStateChange] ~ {
change: WacomChange ¬ NEW[WacomChangeObj];
change.type ¬ penX;
change.x ¬ x;
dsChange ¬ NEW[DeviceStateChangeObj];
dsChange.class ¬ wacomClass;
dsChange.change ¬ change;
};
PenYChangeCreate: PROC [y: INTEGER] RETURNS [dsChange: DeviceStateChange] ~ {
change: WacomChange ¬ NEW[WacomChangeObj];
change.type ¬ penY;
change.y ¬ y;
dsChange ¬ NEW[DeviceStateChangeObj];
dsChange.class ¬ wacomClass;
dsChange.change ¬ change;
};
PressureChangeCreate: PROC [p: INTEGER] RETURNS [dsChange: DeviceStateChange] ~ {
change: WacomChange ¬ NEW[WacomChangeObj];
change.type ¬ pressure;
change.p ¬ p;
dsChange ¬ NEW[DeviceStateChangeObj];
dsChange.class ¬ wacomClass;
dsChange.change ¬ change;
};
WacomChange: TYPE = REF WacomChangeObj;
WacomChangeObj: TYPE = RECORD [
type: ChangeType,
x, y: INTEGER ¬ 0,
p: INTEGER ¬ minPressure
];
ChangeType: TYPE = {penX, penY, pressure};
StateAfterChange: PUBLIC PROC [deviceState: DeviceState, change: DeviceStateChange] RETURNS [newDeviceState: DeviceState] = {
ftChange: WacomChange ¬ NARROW[change.change];
SELECT ftChange.type FROM
penX => newDeviceState ¬ PenXMotion[deviceState, ftChange.x];
penY => newDeviceState ¬ PenYMotion[deviceState, ftChange.y];
pressure => newDeviceState ¬ PressureMotion[deviceState, ftChange.p];
ENDCASE => ERROR;
};
ExpandedChange: TYPE = WacomDevice.ExpandedChange;
UnpackChange: PUBLIC PROC [change: DeviceStateChange] RETURNS [expanded: ExpandedChange] = {
ftChange: WacomChange ¬ NARROW[change.change];
SELECT ftChange.type FROM
penX => expanded ¬ [penX[ftChange.x]];
penY => expanded ¬ [penY[ftChange.y]];
pressure => expanded ¬ [pressure[ftChange.p]];
ENDCASE => ERROR;
};
Changing Wacom State
PenXMotion: PROC [deviceState: DeviceState, x: INTEGER] RETURNS [newDeviceState: DeviceState] = {
newState: WacomState;
newDeviceState ¬ CopyState[deviceState];
newState ¬ NARROW[newDeviceState.state];
newState.x ¬ x;
newState.xValid ¬ TRUE;
};
PenYMotion: PROC [deviceState: DeviceState, y: INTEGER] RETURNS [newDeviceState: DeviceState] = {
newState: WacomState;
newDeviceState ¬ CopyState[deviceState];
newState ¬ NARROW[newDeviceState.state];
newState.y ¬ y;
newState.yValid ¬ TRUE;
};
PressureMotion: PROC [deviceState: DeviceState, p: INTEGER] RETURNS [newDeviceState: DeviceState] = {
newState: WacomState;
newDeviceState ¬ CopyState[deviceState];
newState ¬ NARROW[newDeviceState.state];
newState.p ¬ p;
};
Inspecting State
IsComplete: PUBLIC PROC [deviceState: DeviceState] RETURNS [BOOL] = {
state: WacomState ¬ NARROW[deviceState.state];
RETURN[state.xValid AND state.yValid];
};
GetPen: PUBLIC PROC [deviceState: DeviceState] RETURNS [x, y, p: INTEGER] = {
state: WacomState ¬ NARROW[deviceState.state];
x ¬ state.x;
y ¬ state.y;
p ¬ state.p;
};
Cached change values for minPressure and maxPressure
minPressure: INT = -30; -- or less means no pressure
maxPressure: INT = 30; -- or greater means maximum pressure
minPChange: DeviceStateChange = PressureChangeCreate[minPressure];
maxPChange: DeviceStateChange = PressureChangeCreate[maxPressure];
END.