RFC 177

Device independent graphical display description

πŸ“… published June 1971, from ietf

A DEVICE INDEPENDENT GRAPHICAL DISPLAY DESCRIPTION πŸ’–

okay so bestie, this is RFC 177 πŸŽ€, and it's from the Network Working Group. J. McConnell wrote it at Ames Research Center, Moffet Field, CA, and it's dated 15 June 1971. It obsoletes none and updates RFC 125. The NIC number is 7102 πŸ¦‹

As more nodes got plugged into the ARPA network, people were using all kinds of graphics display processors, and they were super different from each other 🌈 So this RFC describes a device independent way to describe a display, to make it easier to send graphical info over the network πŸ’… The using host can do whatever conversions it needs to actually draw the picture on its specific device ✨ You can also put a form machine in between, like Heafner and Harslem proposed in RFC #94 🧚 Some of the stuff here was first talked about by Steve Crocker in RFC #86 🫢

The target is a refresh display that can do points, vectors, and characters πŸ“Ί That covers devices like the IBM 2250, IMLAC PDS-1, DEC 338, DEC 340, and the Evans and Sutherland LDS-1. Direct video storage tube devices, like the ARDS, Tektronix, and Computer devices, can also work as clumsy interactive devices πŸ™ˆ Hard copy devices, like microfilm or plotters, can be used too, if the using host wants πŸ’œ

Before we get into the specifics, there are a few key terms you need to know πŸ‘‘

  1. The network standard graphics description stream (NGDS) has the description, data, and operators needed to make a display.
  2. The network standard stream interpreter (NGSI) parses the NGDS into its components.
  3. The network standard display list (NGDL) is the basic entity that, when executed, causes graphical information to be displayed.
  4. The network standard list interpreter (NGLI) is the entity that executes the NGDL and controls beam movement to generate the graphical info.
  5. The network standard screen (NGS) is where the info gets displayed. It can be divided into image areas, which will be defined later.
  6. The network standard graphics list pointer (NGLP) and the network standard graphics execution stack (NGES) describe the state of the NGLI at any given time, and give the NGLI what it needs to work as a recursive interpreter πŸ”₯

Figure 1 sums up the stuff above in a picture, which is appropriate πŸŽ€ (the figure itself isn't in this copy, so you'll have to imagine it, bestie πŸ™ˆ)

The network standard graphics screen is rectangular 🌸 Positions on it are given as an ordered pair of fractions: the horizontal distance from the left edge, then the vertical distance from the bottom edge. These are called the (x,y) coordinates, as is standard ✨ There's no fixed resolution, so the picture gets worse on a poor device and gets better on a higher resolution one πŸ¦‹ Coordinate values are 16 bit unsigned fractions with the binary point to the left of the most significant bit. That makes a normalized screen with coordinates from 0.0 to .999...9 πŸ’–

The NGS can be split into rectangular image areas, and each one can have its own unique display 🌈 An image area has three attributes: a 16 bit integer name, an x,y pair for the lower left corner, and an x,y pair for the upper right corner. Image areas can overlap, but one can't be completely inside another one ✨ The main image space is named 0 and lines up with the NGS. Image areas let you manipulate part of the NGS's contents and redefine the coordinate space, which is lowkey iconic πŸ‘‘ Inside an image area, coordinate values are fractional displacements from its lower left corner. So an image area from (0.0, 0.0) to (0.5, 0.5) would hold a picture one-fourth the size of what it would be on the full NGS 🧚

Character strings can be shown at any point in an image area πŸ’… Lots of devices have hardware character generators that only make one or a few sizes, so character scaling inside an image area isn't expected πŸ™ˆ Characters are assumed to be .014 screen width wide and .025 screen height high, including spacing. That gives a screen capacity of 72 characters and 40 lines πŸ“ When the beam moves to a screen position before drawing a character, it's assumed to be at the center of the rectangle for that character space. The beam position after drawing a character, or a string of characters, is undefined πŸ’€

Now the NGDS format πŸŽ€ The NGSI parses the NGDS into commands. The commands use prefix format: an eight bit command followed by its parameters. The descriptions go in numerical order of the command codes πŸ’œ

ERASE (commands = 0) is just a command byte with no parameters. It erases the full NGS 🧹

DEFINE LIST (commands = 1) has three parameters. First is a 16 bit integer for the list name. If that name was already used, this command redefines the list. Next is the count of items in the list, also a 16 bit integer, giving the list's length in items. The list items come after the count, ending with an end list item 🌸

The items control the NGLI and the beam movement when drawing pictures πŸ¦‹ They're also prefix format, with an eight bit item code followed by its parameters. All names are 16 bit integers, and coordinate data are 16 bit unsigned fractions, like we said before. Any other parameters have their type and size spelled out in their own descriptions ✨

  • a. OPEN IMAGE AREA (name) (item type = 0) tells the NGLI that the list commands after it should be adjusted so they stay inside the named area. A nonexistent area name is treated as a NOP. If no image area is set for the NGLI, the default is area 0, the NGS. This stays in effect until the NGLI hits another type 0 item πŸ’–
  • b. RESET IMAGE AREA (name) (item type = 1) makes the NGLI move the beam to the lower left corner of the image area. A nonexistent name is again treated as a NOP 🌈
  • c. CLEAR IMAGE AREA (name) (item type = 2) makes the NGLI erase all the graphical info in the specified area, then do a reset command 🧚

The next items are display items, the ones that actually move the beam through the NGLI πŸ‘‘ Coordinate data are relative to the origin of the current image area, and they're taken as fractional displacements inside that area ✨

  • d. MOVE BEAM (x,y) (item type = 3) makes the NGLI move the beam to (x,y), relative to the current origin 🫢
  • e. DISPLAY CURRENT POSITION (item type = 4) makes the NGLI display the current point on the NGS πŸ¦‹
  • f. DISPLAY VECTOR (x,y) (item type = 5) draws a vector from the current point to (x,y). After that, (x,y) becomes the current point πŸ”₯
  • g. DISPLAY CHARACTERS (n, 'C1, C2...Cn') (item type = 6) displays the n characters, starting from the current point. N is the character count, and it's an eight bit byte πŸ’…

The character set the NGLI recognizes is made of eight bit bytes, read in the following ways 🌸 Any character with the most significant bit set to zero is read as an ASCII character. Some non-graphic ASCII characters can have special jobs inside a string:

  1. Line feed (LF) moves the beam one line spacing downward.
  2. Carriage return (CR) moves the beam to the leftmost character position in the current line.
  3. Backspace (BS) moves the beam one character position to the left in the current line.
  4. Tab moves the beam a predetermined number of character positions to the right in the current line. The number follows the tab character in the string, but it may not exceed the capacity of the current line.
  5. Vertical tab (VT) moves the beam down a predetermined number of line spacings. The number of spacings follows the VT character, and it may not exceed the line capacity of the screen. It's expanded as multiple line feeds πŸ’œ
  6. Any other non-graphic character could make a space character appear in its place on the display, or it can be used for any purpose the two processes agree on 🧚

Characters with the most significant bit set to one are for an extended character set, if the device supports one 🌈 They can also act as an implicit stroke table, where calling them means using the names of special graphic lists that can be defined in the NGDS. If no eight bit list name exists, the character is a space πŸ“

  • h. EXECUTE LIST (name, x, y) (item type =7) makes the NGLI pause interpreting the current list and interpret the named list instead. It works like a subroutine call. The (x,y) pair sets the origin of the new list, relative to the current origin. The actions the NGLI takes are described in the next section πŸŽ€
  • i. COPY LIST (name, x,y) (item type = 8) copies the items in the named list into the place of this item, with the origin of the list at (x,y), relative to the current origin. It's like item (h) is to a subroutine, what this is to a macro πŸ’–
  • j. EXECUTE TABLE (name, mode, length) (item = 9) makes the NGLI treat the named list as a special entity. It can only contain coordinate pairs. It can run in either point or vector mode, set by the mode parameter: 1 = vector, 0 = point. The length of the list is a 16 bit integer parameter 🌸
  • k. END LIST (item type = 10) has no parameters, and tells the NGLI that the end of a list has been reached 🫢
  • l. TABLE (n) (item type = 11) says there are (x,y) pairs in this list. N is a 16 bit integer πŸ¦‹
  • m. Set vector mode (mode) (item type = 12) πŸ”₯
  • n. Set character mode (mode) (item type 13) πŸ’…

Some items also control the display mode of the items above, where that applies πŸ‘‘ There are two mode items: one governs the vector modes, and the other governs the character modes. The quantities they set include brightness, blinking, color selection, and mode dependent descriptions ✨ For vector modes, you can specify the texture of vectors, like dashed, solid, or dotted 🌈 For characters, you can also specify size and orientation 🧚 A mode item's scope runs until the next mode item of the same type shows up πŸ“ The mode items could have been part of the display items instead, but that would mean more parameters and possibly more data to send πŸ’œ The mode specification is two eight bit bytes, laid out like this πŸŽ€

1    4         3            2                     2    3
 +-----------------------+  +-----------------+   +-------------------+
 |    |    |             |  |     |           |   |     |     |       |
 |  B | BL |     CLR     |  | TX  |           |   | OR  |  SZ |       |
 |    |    |             |  |     |           |   |     |     |       |
 +-----------------------+  +-----------------+   +-------------------+
 BYTEO - both modes         BYTE 1- vector        BYTE 1- Character mode
                            mode

 Where      B     Blink if set

            BL    Brightness level - 0 = invisible, IIII brightness

            CLR   Color          One bit for each primary

            TX    Texture        OO = solid

                                 01 = dashed

                                 10 = dotted

                                 11 = dot - dash

           OR     Orientation binary value x 90deg

           SZ     Size

Okay bestie, that table up there is the byte layout for both modes, vector mode and character mode, and it's giving organized πŸŽ€ B makes things blink, BL is the brightness level (0 is invisible, and IIII is the brightest), CLR picks the color with one bit per primary, TX is the texture with four options (OO solid, 01 dashed, 10 dotted, 11 dot-dash), OR is an orientation as a binary value times 90 degrees, and SZ is the size πŸ’…

If the device will not support these enhanced functions, or doesn't provide subroutines to perform them, they're treated as NOPs. No drama, it just gets ignored πŸ¦‹

So ngl, the NGDL ends up being a set of named lists 🌸 Iconic.

DEFINE IMAGE AREA (command = 2) takes three parameters: a 16-bit area name, an (x,y) pair for the lower left corner of the area, and an (x,y) pair for the upper right corner. If the name has already been used to define an area, this command is a re-definition of that area. If the two (x,y) information displayed in it. If X1 is greater than Xr or Y1 is greater than Yr, then the definition is treated as a NOP πŸ™ˆ

Next up, the commands that help you avoid retransmitting a whole list when you only need a tiny tweak. Main character energy πŸ‘‘ Here's the deal: all instances of a list (an instance is a command to execute the list) get affected by these. But if a list was copied into another list, the copied list doesn't change at all 🫢

TRANSLATE LIST (command = 3) moves all instances of a list within every image space it shows up in. The parameters are the 16-bit list name and two 16-bit fractions for the coordinate values of the translation 🧚

SCALE LIST (command = 4) can change the size of the picture a list creates, in all image spaces. The parameters are the 16-bit list name, followed by two 16-bit (X,Y) unsigned fractions. Each of those has eight bits of exponent followed by eight bits of mantissa. Together they change the scale factors in the X and Y directions ✨

ROTATE LIST (command = 5) rotates all instances of a list. The parameters are the 16-bit list name and a 16-bit value for the rotational angle in degrees. Counter-clockwise is the direction for increasing values, and the possible axis is zero degrees 🌈

Now the NGLI, which is giving loop energy πŸ” It takes items from the main list, and when it hits the end of the main list, it goes right back to the top. At any point, the NGLP gives the NGLI the positional displacement of the next display item it's processing. When it runs into a display item of type h., the current list's execution gets suspended. The list name, the current origin, and the NGLP all get saved in the NGES. Then the NGLP gets reset to zero, the next current origin is calculated, and the new list starts running. When the end of that list is reached, the old values are restored from the NGES, and the suspended list picks right back up πŸ’– That's why the NGLI is a recursive interpreter, periodt πŸ’œ

Also, whenever a new image area is opened, its name gets stored in the current image area name 🌸

Okay now the interaction stuff, which is honestly the messier part 😭 The problem of interacting with the displayed picture hasn't been addressed yet, because it's a more complicated area. There are two ways interaction can happen. The first, and the easiest to handle, is events that are separate from the picture itself. Think keyboards and function-key type devices. These can be handled as standard messages from the graphics device to the serving host 🎹 The second kind is interaction with the picture itself, and that's harder, because you have to figure out what the selected point actually means, like which list it belongs to. That association can probably only be made by the serving host. The using host, or a Form Machine, may have transformed the NGDS in unknown ways, so the NGDS may not even exist at the using host's site anymore πŸ’€

There are basically two classes of devices that can interact with the picture. Synchronous devices only cause attention while a given display item is being executed. Light pens are synchronous devices ✏️ Asynchronous devices can interact regardless of which display item is being executed, or even when none is being executed. Those make associations harder, since you can't easily infer a relationship the way you can with synchronous devices πŸ™ˆ

The NGES is created for interacting with the picture. For synchronous devices, the current values for the list name, origin, and NGLP, along with the contents of the NGES, give you a hierarchical structure where associations can be made πŸͺœ For asynchronous devices, that structure probably isn't as necessary. The name and the coordinates within the image space where the interaction happened are what matter more. The using host needs to understand which types of devices are available, and then supply the proper type of interaction information to the serving host 🫢

The form of the interaction information for synchronous devices is:

INTERACTION (type, cia, cln, cor, clp, n, l1, or1, lp1, ...ln, orn, lpn)

Where:

type describes the interaction type 0=synchronous
cia     current image area name
cln     current list name
cor     current origin value
clp     current NGLP value
n       number of entries in NGES, higher value of n is older entry
li      list name of the i th entry
ori     origin of the i th entry
lpi     NGLP of the i th entry

The form for asynchronous interaction is:

INTERACTION (type, cia, iax, iay, sx, sy)

Where:

type = 1 for asynchronous interactions
cia     current image name
iax     image area x coordinate
iay     image area y coordinate
sx,sy   screen x,y coordinates

Here's the big-picture diagram, the whole NETWORK / Using Host setup, with the NGDS, NGDL, IMAGE AREA DEFINITIONS, NGLI, NGS, and NGLES & NGLP all connected πŸ¦‹

NETWORK  |    Using Host
         |                +-------+
         |                |       |
         |                | NGDL  |          +--------+       +-------+
         +--------+       |       |--------->|        |       |       |
         |        |------>|       |          |  NGLI  |------>|  NGS  |
         |  NGDS  |       +-------+          |        |       |       |
         |        |       +-------+          |        |       |       |
         |        |------>|       |--------->|        |       +-------+
         +--------+       |IMAGE  |          +--------+
         |                |AREA   |              ^
         |                |DEFINI-|              |
         |                |TIONS  |              V
         |                +-------+          *--------+
         |                                   |  NGLES |
         |                                   |    &   |
         |                                   |  NGLP  |
         |                                   +--------+

[This RFC was put into machine readable form for entry] [into the online RFC archives by Kelly Tardif, Viag�nie 12/1999] 🌸

πŸ“¦ where this page comes from