-- ColorDisplay.mesa -- Last edit by Maureen Stone, June 9, 1982 4:04 pm -- Last edit by Doug Wyatt, 10-Jul-81 0:50:42 DIRECTORY Inline USING [LongMult], UserTerminal USING [CursorArray]; ColorDisplay: DEFINITIONS IMPORTS Inline = { -- Processor-independent interface to color display. -- Types Mode: TYPE = RECORD[full: BOOLEAN, bitsPerPixelA,bitsPerPixelB: [0..8]]; -- Mode encodes the possible color display modes. -- full=TRUE specifies 24 bit per pixel mode; the other fields are ignored -- full=FALSE specifies a mapped mode with one or two bitmaps, each with the given -- number of bits per pixel. Acceptable values are 0 (no bitmap), 1, 2, 4, or 8. -- Not all modes are implemented on a particular processor; see HasMode, below. disconnected: Mode = [FALSE,0,0]; -- The initial mode, with the color display entirely disabled. -- Setting this mode releases the resources used by the color display. -- Processors lacking color displays have only this mode. Byte: TYPE = [0..256); Pair: TYPE = MACHINE DEPENDENT RECORD[r,g: Byte]; ByteSeq: TYPE = RECORD[PACKED SEQUENCE COMPUTED CARDINAL OF Byte]; PairSeq: TYPE = RECORD[PACKED SEQUENCE COMPUTED CARDINAL OF Pair]; CursorArray: TYPE = UserTerminal.CursorArray; Coordinate: TYPE = MACHINE DEPENDENT RECORD [x, y: INTEGER]; -- The cursor mode indicates whether, given a bit=1 in the cursor array, -- the corresponding pixel value is set to all ones or all zeros. For 24 bpp mode -- and the conventional color maps, the correspondence is ones=white and zeros=black. CursorMode: TYPE = {ones,zeros}; -- Interface variables pixelsPerInch: READONLY CARDINAL; -- size of a pixel displayType: READONLY CARDINAL; -- display type; 0 means display not available mixedRG: READONLY BOOLEAN; -- red and green interleaved in 24 bit mode -- The following variables may be changed by SetMode! curmode: READONLY Mode; -- the current mode width,height: READONLY CARDINAL; -- size of raster in current mode baseA,baseB,baseC: READONLY LONG POINTER; -- bitmap address wplA,wplB,wplC: READONLY CARDINAL; -- bitmap words per line cursorPosition: READONLY LONG POINTER TO Coordinate; cursorWidth: READONLY INTEGER; --defined as 16 for now cursorHeight: READONLY INTEGER; --defined as 16 for now -- Procedures HasMode: PROCEDURE[mode: Mode] RETURNS[BOOLEAN]; -- Return TRUE if the specified mode is available. GetMode: PROCEDURE RETURNS[Mode] = INLINE { RETURN[curmode] }; -- Return the current mode. SetMode: PROCEDURE[mode: Mode] RETURNS[BOOLEAN]; -- Establish the specified mode. Allocate bitmap and colormap storage as necessary. -- Return TRUE if successful, FALSE if mode is not available. -- Subsequent bitmap or colormap changes will affect the color image, -- but the image will not appear on the screen until TurnOn is called. -- If mode=disconnected, disable the color display, releasing all storage. -- All following procedures should be used only when GetMode[]#disconnected. TurnOn: PROCEDURE; -- Turn the display on, causing an image to appear on the screen. TurnOff: PROCEDURE; -- Turn the display off, causing the screen to be dark. -- The display's storage is retained; the image will reappear if TurnOn is called. Show: PROCEDURE[a,b,c: BOOLEAN ← TRUE]; -- Make the specified bitmap visible (TRUE) or invisible (FALSE). -- Procedures for mapped modes (mode.full=FALSE) GetColor: PROCEDURE[pixelA,pixelB: CARDINAL ← 0] RETURNS[r,g,b: Byte]; -- Return the current color map entry for the given pixel value(s). SetColor: PROCEDURE[pixelA,pixelB: CARDINAL ← 0, r,g,b: Byte]; -- Set the color map entry for the given pixel value(s). -- If the display is 'on', the screen will show the change by the next frame time. -- Procedures for manipulating the cursor SetCursorPattern: PROC [cursorPattern: CursorArray]; GetCursorPattern: PROCEDURE RETURNS [cursorPattern: CursorArray]; SetCursorPosition: PROCEDURE [newMousePosition: Coordinate]; SetCursorMode: PROC [color: CursorMode]; --the cursor must be hidden and restored when the area of the --framebuffer occupied by the cursor is changed. HideCursor: PROC; --restore the frame buffer RestoreCursor: PROC; --draw the cursor at its last position --the cursor must be locked while a scanline is being drawn --ONLY ColorDeviceImpl should call these two procedures SetLock: PROC; ClearLock: PROC; --called ONLY by ColorDisplayImpl to indicate that the display mode changed NotifyCursor: PROC; -- Procedures for 24 bit per pixel mode (mode.full=TRUE) InBounds: PROC[x,y: CARDINAL] RETURNS[BOOLEAN] = INLINE { RETURN[curmode.full AND x<width AND y<height] }; GetR: PRIVATE PROC[x,y: CARDINAL] RETURNS[Byte] = INLINE { IF mixedRG THEN RETURN[LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO PairSeq][x].r] ELSE RETURN[LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO ByteSeq][x]] }; GetG: PRIVATE PROC[x,y: CARDINAL] RETURNS[Byte] = INLINE { IF mixedRG THEN RETURN[LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO PairSeq][x].g] ELSE RETURN[LOOPHOLE[baseB + Inline.LongMult[wplB,y],LONG POINTER TO ByteSeq][x]] }; GetB: PRIVATE PROC[x,y: CARDINAL] RETURNS[Byte] = INLINE { IF mixedRG THEN RETURN[LOOPHOLE[baseB + Inline.LongMult[wplB,y],LONG POINTER TO ByteSeq][x]] ELSE RETURN[LOOPHOLE[baseC + Inline.LongMult[wplC,y],LONG POINTER TO ByteSeq][x]] }; SetR: PRIVATE PROC[x,y: CARDINAL, r: Byte] = INLINE { IF mixedRG THEN LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO PairSeq][x].r ← r ELSE LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO ByteSeq][x] ← r }; SetG: PRIVATE PROC[x,y: CARDINAL, g: Byte] = INLINE { IF mixedRG THEN LOOPHOLE[baseA + Inline.LongMult[wplA,y],LONG POINTER TO PairSeq][x].g ← g ELSE LOOPHOLE[baseB + Inline.LongMult[wplB,y],LONG POINTER TO ByteSeq][x] ← g }; SetB: PRIVATE PROC[x,y: CARDINAL, b: Byte] = INLINE { IF mixedRG THEN LOOPHOLE[baseB + Inline.LongMult[wplB,y],LONG POINTER TO ByteSeq][x] ← b ELSE LOOPHOLE[baseC + Inline.LongMult[wplC,y],LONG POINTER TO ByteSeq][x] ← b }; GetPixel: PUBLIC PROC[x,y: CARDINAL] RETURNS[r,g,b: Byte] = INLINE { IF InBounds[x,y] THEN RETURN[r: GetR[x,y], g: GetG[x,y], b: GetB[x,y]] ELSE RETURN[0,0,0] }; -- Return the color of the pixel at coordinates (x,y). -- The pixel with coordinates (0,0) is at the upper left corner of the screen. -- Returns [0,0,0] if x or y is out of range. SetPixel: PUBLIC PROC[x,y: CARDINAL, r,g,b: Byte] = INLINE { IF InBounds[x,y] THEN { SetR[x,y,r]; SetG[x,y,g]; SetB[x,y,b] } }; -- Set the pixel at coordinates (x,y) to the specified color. -- The pixel with coordinates (0,0) is at the upper left corner of the screen. -- Ignored if x or y is out of range. SetRed: PUBLIC PROC[x,y: CARDINAL, value: Byte] = INLINE { IF InBounds[x,y] THEN SetR[x,y,value] }; SetGreen: PUBLIC PROC[x,y: CARDINAL, value: Byte] = INLINE { IF InBounds[x,y] THEN SetG[x,y,value] }; SetBlue: PUBLIC PROC[x,y: CARDINAL, value: Byte] = INLINE { IF InBounds[x,y] THEN SetB[x,y,value] }; -- Set red, green, or blue value for a pixel independently. GetRedMap,GetGreenMap,GetBlueMap: PROCEDURE[in: Byte] RETURNS[out: Byte]; -- Return the current entry from the red, green, or blue map. SetRedMap,SetGreenMap,SetBlueMap: PROCEDURE[in,out: Byte]; -- Set an entry in the red, green, or blue map. -- If the display is 'on', the screen will show the change by the next frame time. }.