-- File CIFDevicesControl.mesa
-- Written by Martin Newell, March 1980
-- Last updated: March 27, 1981 5:33 PM
-- Provides multiple implementations of Trapezoid for different devices
DIRECTORY
CIFDevicesDefs: FROM "CIFDevicesDefs" USING [DeviceDescriptor,
DeviceDescriptorRecord, MaxLENGTHLayerArray],
CIFOutDevice: FROM "CIFOutDevice" USING [MakeCIFOutDevice, SetCurrentDevice],
CIFScreenDefs: FROM "CIFScreenDefs" USING [CIFScreen],
CIFUtilitiesDefs: FROM "CIFUtilitiesDefs" USING [Rectangle],
Graphics USING [DeviceContext],
IODefs: FROM "IODefs" USING [SP, WriteString, WriteLine],
OpaqueDevice: FROM "OpaqueDevice" USING [DeviceContext],
ParserErrorDefs: FROM "ParserErrorDefs" USING [ErrorType, Report],
StringDefs: FROM "StringDefs" USING [EqualString],
SystemDefs: FROM "SystemDefs" USING [AllocateHeapNode, FreeHeapNode];
CIFDevicesControl: PROGRAM
IMPORTS CIFOutDevice, CIFScreenDefs, IODefs, ParserErrorDefs, StringDefs, SystemDefs
EXPORTS CIFDevicesDefs =
BEGIN OPEN CIFDevicesDefs, CIFOutDevice, CIFScreenDefs, CIFUtilitiesDefs, IODefs, OpaqueDevice, ParserErrorDefs, StringDefs, SystemDefs;
SelectDevice: PUBLIC PROCEDURE [deviceName: STRING] RETURNS[ok: BOOLEAN] =
BEGIN
device: DeviceDescriptor ← LookupDevice[deviceName];
IF device=NIL THEN
BEGIN
WriteString["Unknown device in SelectDevice: "];
WriteLine[deviceName];
RETURN[FALSE];
END;
IF (ok←device.deviceSelect[]) THEN SelectedDevice ← device;
END;
DrawFrame: PUBLIC PROCEDURE =
BEGIN
SelectedDevice.deviceDrawFrame[];
END;
SetScale: PUBLIC PROCEDURE [factor: REAL] =
BEGIN
SelectedDevice.deviceSetScale[factor];
END;
SetClipRegion: PUBLIC PROCEDURE [rt: Rectangle] =
BEGIN
SelectedDevice.deviceSetClipRegion[rt];
END;
OutputDevice: PUBLIC PROCEDURE =
BEGIN
CurrentDevice ← SelectedDevice;
SetCurrentDevice[CurrentDevice];
LayerString ← [SP,SP,SP,SP];
CurrentDevice.deviceOutput[];
CurrentDevice ← ScreenDevice;
END;
Draw: PUBLIC PROCEDURE =
BEGIN
ScreenDevice.deviceOutput[];
SelectedDevice.deviceDrawFrame[];
END;
LookupLayer: PUBLIC PROCEDURE [s: PACKED ARRAY [0..4) OF CHARACTER]
RETURNS[CARDINAL] =
-- Looks up layer number - makes new entry if necessary
BEGIN
i: CARDINAL;
IF s=LayerString THEN RETURN[LayerIndex];
FOR i IN [0..LENGTHLayerArray) DO
IF s=LayerArray[i] THEN
BEGIN
LayerString ← s;
LayerIndex ← i;
RETURN[LayerIndex];
END;
ENDLOOP;
--No such layer - make one
--Report["New Layer",Advisory];
IF LENGTHLayerArray=MaxLENGTHLayerArray THEN
BEGIN
Report["Too many layers",Fatal];
RETURN[0];
END;
LayerString ← s;
LayerIndex ← LENGTHLayerArray;
LayerArray[LayerIndex] ← s;
LENGTHLayerArray ← LENGTHLayerArray + 1;
RETURN[LayerIndex];
END;
LookupLayerString: PUBLIC PROCEDURE[layerName: STRING] RETURNS[CARDINAL] =
BEGIN
sa: PACKED ARRAY [0..4) OF CHARACTER ← [SP,SP,SP,SP];
i: CARDINAL;
FOR i IN [0..MIN[4,layerName.length]) DO sa[i] ← layerName[i]; ENDLOOP;
RETURN[LookupLayer[sa]];
END;
SetLayer: PUBLIC PROCEDURE [layer: CARDINAL] =
BEGIN
CurrentDevice.deviceLayer[layer];
END;
LoadLayer: PUBLIC PROCEDURE[layer: CARDINAL, v0,v1,v2,v3: CARDINAL] =
BEGIN
SelectedDevice.deviceLoadLayer[layer, v0,v1,v2,v3];
END;
SetLayerVisible: PUBLIC PROCEDURE[layer: CARDINAL, visible: BOOLEAN] =
BEGIN
VisibleArray[layer] ← visible;
END;
LayerVisible: PUBLIC PROCEDURE[layer: CARDINAL] RETURNS[visible: BOOLEAN] =
BEGIN
RETURN[VisibleArray[layer]];
END;
OutputText: PUBLIC PROCEDURE[text: STRING, x,y: REAL] =
BEGIN
CurrentDevice.deviceText[text,x,y];
END;
RegisterDevice: PUBLIC PROCEDURE[device: DeviceDescriptor] =
BEGIN
dev: DeviceDescriptor ← AllocateHeapNode[SIZE[DeviceDescriptorRecord]];
dev↑ ← device↑;
dev.next ← DeviceList;
DeviceList ← dev;
END;
UnRegisterDevice: PUBLIC PROCEDURE[deviceName: STRING] =
BEGIN
deviceptr: POINTER TO DeviceDescriptor;
FOR deviceptr ← @DeviceList, @deviceptr.next UNTIL deviceptr↑=NIL DO
IF EqualString[deviceName,deviceptr.name] THEN
BEGIN
dev: DeviceDescriptor ← deviceptr↑;
deviceptr↑ ← deviceptr.next;
FreeHeapNode[dev];
RETURN;
END;
ENDLOOP;
END;
GetCIFOutDevice: PUBLIC PROCEDURE RETURNS[device: Graphics.DeviceContext] =
BEGIN
RETURN[DC];
END;
--Private procedures--
LookupDevice: PROCEDURE[deviceName: STRING] RETURNS[device: DeviceDescriptor] =
BEGIN
FOR device ← DeviceList, device.next UNTIL device=NIL DO
IF EqualString[deviceName,device.name] THEN RETURN;
ENDLOOP;
END;
DeviceList: DeviceDescriptor ← NIL;
SelectedDevice: DeviceDescriptor;
CurrentDevice: DeviceDescriptor;
ScreenDevice: DeviceDescriptor;
--Make the CedarGraphics CIFOutDevice for all devices other than the Screen
DC: OpaqueDevice.DeviceContext ← MakeCIFOutDevice[];
-- Data for LookupLayer
LayerIndex: CARDINAL ← 0;
LayerString: PACKED ARRAY [0..4) OF CHARACTER ← [SP,SP,SP,SP];
LENGTHLayerArray: PUBLIC CARDINAL ← 8;
LayerArray: ARRAY [0..MaxLENGTHLayerArray) OF PACKED ARRAY [0..4) OF CHARACTER;
VisibleArray: ARRAY [0..MaxLENGTHLayerArray) OF BOOLEAN ← ALL[TRUE];
--Set up default layer names
LayerArray[0] ← [’N,’I,SP,SP];
LayerArray[1] ← [’N,’D,SP,SP];
LayerArray[2] ← [’N,’P,SP,SP];
LayerArray[3] ← [’N,’C,SP,SP];
LayerArray[4] ← [’N,’M,SP,SP];
LayerArray[5] ← [’N,’B,SP,SP];
LayerArray[6] ← [’N,’G,SP,SP];
LayerArray[7] ← [’N,’X,SP,SP];
--Always have Screen device
START CIFScreen;
[] ← SelectDevice["screen"];
ScreenDevice ← SelectedDevice;
CurrentDevice ← SelectedDevice;
END.